From 201d7b97fc3440bb8d75320ad03b27a88b96fcfd Mon Sep 17 00:00:00 2001 From: Timofey Solomko Date: Mon, 1 May 2017 21:16:38 +0300 Subject: [PATCH] out array is now a property of LZMATestDecoder. --- Sources/LZMA.swift | 3 ++- Sources/LZMATestDecoder.swift | 32 ++++++++++++++++---------------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/Sources/LZMA.swift b/Sources/LZMA.swift index 16648002..cff386f5 100644 --- a/Sources/LZMA.swift +++ b/Sources/LZMA.swift @@ -84,7 +84,8 @@ public final class LZMA: DecompressionAlgorithm { let lzmaDecoder = try LZMATestDecoder(&pointerData, lc, pb, lp, dictionarySize) - return try lzmaDecoder.decodeLZMA(&uncompressedSize) + try lzmaDecoder.decodeLZMA(&uncompressedSize) + return lzmaDecoder.out } } diff --git a/Sources/LZMATestDecoder.swift b/Sources/LZMATestDecoder.swift index d56393f7..02276cc7 100644 --- a/Sources/LZMATestDecoder.swift +++ b/Sources/LZMATestDecoder.swift @@ -52,6 +52,13 @@ final class LZMATestDecoder { /// Is used to select exact variable from 'IsRep', 'IsRepG0', 'IsRepG1' and 'IsRepG2' arrays. private var state: Int = 0 + /// An array for storing output data + var out: [UInt8] = [] + // This array will also serve as dictionary and out window. + private var dictStart = 0 + private var dictEnd = 0 + + init(_ pointerData: inout DataWithPointer, _ lc: UInt8, _ pb: UInt8, _ lp: UInt8, _ dictionarySize: Int) throws { self.pointerData = pointerData @@ -80,18 +87,13 @@ final class LZMATestDecoder { self.repLenDecoder = LZMALenDecoder(&self.pointerData) } - func decodeLZMA(_ uncompressedSize: inout Int) throws -> [UInt8] { + func decodeLZMA(_ uncompressedSize: inout Int) throws { // First, we need to initialize Rande Decoder. guard let rD = LZMARangeDecoder(&self.pointerData) else { throw LZMAError.RangeDecoderInitError } self.rangeDecoder = rD - /// An array for storing output data - var out: [UInt8] = [] - var dictStart = 0 - var dictEnd = 0 - // Main decoding cycle. while true { // If uncompressed size was defined and everything is unpacked then stop. @@ -107,7 +109,7 @@ final class LZMATestDecoder { // DECODE LITERAL: /// Previous literal (zero, if there was none). - let prevByte = dictEnd == 0 ? 0 : out[1 <= dictEnd ? dictEnd - 1 : self.dictionarySize - 1 + dictEnd] + let prevByte = dictEnd == 0 ? 0 : out[1 <= dictEnd ? dictEnd - 1 : dictionarySize - 1 + dictEnd] /// Decoded symbol. Initial value is 1. var symbol = 1 /** @@ -123,7 +125,7 @@ final class LZMATestDecoder { Byte in output at position that is the `distance` bytes before current position, where the `distance` is the distance from the latest decoded match. */ - var matchByte = out[rep0 + 1 <= dictEnd ? dictEnd - rep0 - 1 : self.dictionarySize - rep0 - 1 + dictEnd] + var matchByte = out[rep0 + 1 <= dictEnd ? dictEnd - rep0 - 1 : dictionarySize - rep0 - 1 + dictEnd] repeat { let matchBit = ((matchByte >> 7) & 1).toInt() matchByte <<= 1 @@ -142,7 +144,7 @@ final class LZMATestDecoder { out.append(byte) uncompressedSize -= 1 dictEnd += 1 - if dictEnd - dictStart == self.dictionarySize { + if dictEnd - dictStart == dictionarySize { dictStart += 1 } // END. @@ -169,11 +171,11 @@ final class LZMATestDecoder { if rangeDecoder.decode(bitWithProb: &probabilities[241 + (state << LZMAConstants.numPosBitsMax) + posState]) == 0 { // SHORT REP MATCH CASE state = state < 7 ? 9 : 11 - let byte = out[rep0 + 1 <= dictEnd ? dictEnd - rep0 - 1 : self.dictionarySize - rep0 - 1 + dictEnd] + let byte = out[rep0 + 1 <= dictEnd ? dictEnd - rep0 - 1 : dictionarySize - rep0 - 1 + dictEnd] out.append(byte) uncompressedSize -= 1 dictEnd += 1 - if dictEnd - dictStart == self.dictionarySize { + if dictEnd - dictStart == dictionarySize { dictStart += 1 } continue @@ -251,23 +253,21 @@ final class LZMATestDecoder { } if uncompressedSize == 0 { throw LZMAError.ExceededUncompressedSize } - if rep0 >= dictionarySize || (rep0 > dictEnd && dictEnd < self.dictionarySize) { throw LZMAError.NotEnoughToRepeat } + if rep0 >= dictionarySize || (rep0 > dictEnd && dictEnd < dictionarySize) { throw LZMAError.NotEnoughToRepeat } } // Converting from zero-based length of the match to the real one. len += LZMAConstants.matchMinLen if uncompressedSize > -1 && uncompressedSize < len { throw LZMAError.RepeatWillExceed } for _ in 0..