internal int inflateEnd(ZStream z) { if (blocks != null) blocks.free(z); blocks = null; // ZFREE(z, z->state); return Z_OK; }
public static Int32 ZInflateEnd(ZStream zStream) { GCHandle zStreamGCHandle = GCHandle.Alloc(zStream, GCHandleType.Pinned); Int32 result = ZInflateEnd(zStreamGCHandle.AddrOfPinnedObject()); zStreamGCHandle.Free(); return result; }
public static Int32 ZInflateInit2(ZStream zStream, Int32 windowBits) { GCHandle zStreamGCHandle = GCHandle.Alloc(zStream, GCHandleType.Pinned); IntPtr zStreamIntPtr = zStreamGCHandle.AddrOfPinnedObject(); Int32 result = ZInflateInit2(zStreamIntPtr, windowBits); zStreamGCHandle.Free(); return result; }
internal int wbits; // log2(window size) (8..15, defaults to 15) internal int inflateReset(ZStream z) { if (z == null || z.istate == null) return Z_STREAM_ERROR; z.total_in = z.total_out = 0; z.msg = null; z.istate.mode = z.istate.nowrap != 0 ? BLOCKS : METHOD; z.istate.blocks.reset(z, null); return Z_OK; }
internal int deflateSetDictionary(ZStream strm, byte[] dictionary, int dictLength) { int length = dictLength; int index=0; if(dictionary == null || status != INIT_STATE) return Z_STREAM_ERROR; strm.adler=strm._adler.adler32(strm.adler, dictionary, 0, dictLength); if(length < MIN_MATCH) return Z_OK; if(length > w_size-MIN_LOOKAHEAD){ length = w_size-MIN_LOOKAHEAD; index=dictLength-length; // use the tail of the dictionary } Array.Copy(dictionary, index, window, 0, length); strstart = length; block_start = length; // Insert all strings in the hash table (except for the last two bytes). // s->lookahead stays null, so s->ins_h will be recomputed at the next // call of fill_window. ins_h = window[0]&0xff; ins_h=(((ins_h)<<hash_shift)^(window[1]&0xff))&hash_mask; for(int n=0; n<=length-MIN_MATCH; n++){ ins_h=(((ins_h)<<hash_shift)^(window[(n)+(MIN_MATCH-1)]&0xff))&hash_mask; prev[n&w_mask]=head[ins_h]; head[ins_h]=(short)n; } return Z_OK; }
internal int deflateParams(ZStream strm, int _level, int _strategy) { int err=Z_OK; if(_level == Z_DEFAULT_COMPRESSION){ _level = 6; } if(_level < 0 || _level > 9 || _strategy < 0 || _strategy > Z_HUFFMAN_ONLY) { return Z_STREAM_ERROR; } if(config_table[level].func!=config_table[_level].func && strm.total_in != 0) { // Flush the last buffer: err = strm.deflate(Z_PARTIAL_FLUSH); } if(level != _level) { level = _level; max_lazy_match = config_table[level].max_lazy; good_match = config_table[level].good_length; nice_match = config_table[level].nice_length; max_chain_length = config_table[level].max_chain; } strategy = _strategy; return err; }
internal int deflateInit(ZStream strm, int level) { return deflateInit(strm, level, MAX_WBITS); }
/// <summary> /// Ends the Zlib operation. /// </summary> /// <param name="zs">Zlib stream.</param> /// <returns>Zlib status.</returns> protected abstract int EndZlibOperation(ZStream zs);
internal void free(ZStream z) { // ZFREE(z, c); }
internal int inflateSetDictionary(ZStream z, byte[] dictionary, int dictLength) { int index = 0; int length = dictLength; if (z == null || z.istate == null || z.istate.mode != DICT0) return Z_STREAM_ERROR; if (z._adler.adler32(1L, dictionary, 0, dictLength) != z.adler) { return Z_DATA_ERROR; } z.adler = z._adler.adler32(0, null, 0, 0); if (length >= (1 << z.istate.wbits)) { length = (1 << z.istate.wbits) - 1; index = dictLength - length; } z.istate.blocks.set_dictionary(dictionary, index, length); z.istate.mode = BLOCKS; return Z_OK; }
private static extern int inflateInit2_(ref ZStream sz, int windowbits, string vs, int size);
public PacketStream(List <byte[]> inPack, IStreamCipher Decryptor, ZStream Inflater) { Packets = new List <Packet>(); byte[] inBuff = inPack[0]; byte[] decData = new byte[inBuff.Length]; Decryptor.ProcessBytes(inBuff, 0, inBuff.Length, decData, 0); MemoryStream IStream = new MemoryStream(decData); EndianBinaryReader IReader = new EndianBinaryReader(MiscUtil.Conversion.BigEndianBitConverter.Little, IStream); int remLength = decData.Length; do { byte Module = IReader.ReadByte(); int pLength = IReader.ReadInt32(); int pChecksum = IReader.ReadByte(); if (VerifyChecksum(decData, pChecksum, (int)IReader.BaseStream.Position - 6)) { byte[] Data; if (inPack.Count > 1) { // Multipart packet byte[] NewBuff = new byte[pLength - 6]; int curIndex = remLength - 6; Array.Copy(IReader.ReadBytes(remLength - 6), 0, NewBuff, 0, remLength - 6); for (int i = 1; i < inPack.Count; i++) { byte[] packDec = new byte[inPack[i].Length]; Decryptor.ProcessBytes(inPack[i], 0, inPack[i].Length, packDec, 0); Array.Copy(packDec, 0, NewBuff, curIndex, packDec.Length); curIndex += packDec.Length; } Data = NewBuff; } else { Data = IReader.ReadBytes(pLength - 6); } Packet iPacket = new Packet(); iPacket.Module = Module; iPacket.Data = Decompress(Data, Inflater); iPacket.Stream = new MemoryStream(iPacket.Data); iPacket.Reader = new EndianBinaryReader(MiscUtil.Conversion.EndianBitConverter.Little, iPacket.Stream); iPacket.PacketID = iPacket.Reader.ReadUInt32(); //if (iPacket.PacketID == 0x34287945) // Console.WriteLine(decData.ToHEX()); iPacket.Reader.ReadUInt32(); //iPacket.IsValid = true; Packets.Add(iPacket); } else { Console.WriteLine("Failure!!!!", inBuff.ToHEX(), decData.ToHEX()); break; } remLength -= pLength; }while (remLength > 0); IReader.Close(); IStream.Close(); }
/// <summary> /// Performs the generic zlib stream filter operation. /// </summary> /// <param name="input">Input chunk of bytes.</param> /// <param name="inputOffset">Current position within the chunk.</param> /// <param name="closing">Value indicating whether the stream will be closed.</param> /// <returns>Array of available bytes (even empty one). Null on non-critical error.</returns> protected byte[] FilterInner(byte[] input, ref int inputOffset, bool closing) { if (_state == ZlibState.Finished) { //if stream already ended, throw an error PhpException.Throw(PhpError.Warning, "using zlib stream that is already finished"); return(null); } if (_state == ZlibState.Failed) { //if stream already ended, throw an error PhpException.Throw(PhpError.Warning, "using zlib stream that failed"); return(null); } List <(byte[] Data, int Length)> subchunks = null; int status = zlibConst.Z_OK; // initialize if necessary if (_state == ZlibState.NotStarted) { _stream = new ZStream(); // init algorithm status = InitZlibOperation(_stream); // check for error if (status != zlibConst.Z_OK) { _state = ZlibState.Failed; PhpException.Throw(PhpError.Error, Zlib.zError(status)); return(null); } _state = ZlibState.Data; } if (_state == ZlibState.Data) { // input chunk _stream.next_in = input; _stream.next_in_index = inputOffset; _stream.avail_in = input.Length - inputOffset; long initial_total_out = _stream.total_out; long initial_total_in = _stream.total_in; int nextBufferSize = 8; int bufferSizeMax = 65536; // do while operation does some progress do { _stream.next_out = new byte[nextBufferSize]; _stream.next_out_index = 0; _stream.avail_out = _stream.next_out.Length; if (nextBufferSize < bufferSizeMax) { nextBufferSize *= 2; } long previous_total_out = _stream.total_out; status = PerformZlibOperation(_stream, GetFlushFlags(closing)); if (_stream.total_out - previous_total_out > 0) { // if the list was not initialize, do so if (subchunks == null) { subchunks = new List <(byte[], int)>(); } // add the subchunk to the list only when it contains some data subchunks.Add((_stream.next_out, (int)(_stream.total_out - previous_total_out))); } } // we continue only when progress was made and there is input available while ((status == zlibConst.Z_OK || status == zlibConst.Z_BUF_ERROR) && (_stream.avail_in > 0 || (_stream.avail_in == 0 && _stream.avail_out == 0))); // if the last op wasn't the end of stream (this happens only with Z_FINISH) or general success, return error if (status != zlibConst.Z_STREAM_END && status != zlibConst.Z_OK) { _state = ZlibState.Failed; PhpException.Throw(PhpError.Warning, Zlib.zError(status)); return(null); } // end the algorithm if requested if (closing || status == zlibConst.Z_STREAM_END) { _state = ZlibState.Finished; status = EndZlibOperation(_stream); if (status != zlibConst.Z_OK) { _state = ZlibState.Failed; PhpException.Throw(PhpError.Warning, Zlib.zError(status)); return(null); } } inputOffset = _stream.next_in_index; // if the chunk ended or everything is OK, connect the subchunks and return if (subchunks != null && subchunks.Count > 0) { byte[] result = new byte[_stream.total_out - initial_total_out]; long resultPos = 0; for (int i = 0; i < subchunks.Count; i++) { Buffer.BlockCopy( subchunks[i].Data, 0, result, (int)resultPos, (int)Math.Min(subchunks[i].Length, _stream.total_out - resultPos)); resultPos += subchunks[i].Length; } return(result); } else { return(new byte[0]); } } Debug.Fail(null); return(null); }
protected override int EndZlibOperation(ZStream zs) { return(zs.inflateEnd()); }
protected override int PerformZlibOperation(ZStream zs, int flush) { return(zs.inflate(flush)); }
protected override int InitZlibOperation(ZStream zs) { // -MAX_WBITS stands for absense of Zlib header and trailer (needed for GZIP compression and decompression) return(zs.inflateInit(-Zlib.MAX_WBITS)); }
/// <summary> /// Initializes the Zlib operation. /// </summary> /// <param name="zs">Zlib stream.</param> /// <returns>Zlib status.</returns> protected abstract int InitZlibOperation(ZStream zs);
/// <summary> /// Performs the Zlib operation. /// </summary> /// <param name="zs">Zlib stream.</param> /// <param name="flush">Flush flags.</param> /// <returns>Zlib status.</returns> protected abstract int PerformZlibOperation(ZStream zs, int flush);
public override byte[] Decompress(byte[] data, bool isLast) { // Detect uncompressed, copied block if (data.Length == 32775 && data[2] == 1) { tmp = new byte[32768]; Array.Copy(data, 7, tmp, 0, 32768); return tmp; } if (!bInited) { zstream = new ZStream(); if (inflateInit2_(ref zstream, -15, "1.2.7", Marshal.SizeOf(zstream)) != 0) throw new ApplicationException("Couldn't initialize ZLIB library!"); bInited = true; } zstream.next_in = Marshal.UnsafeAddrOfPinnedArrayElement(data, 2); // Discard CK marker zstream.total_in = 0; zstream.avail_in = (uint)data.Length - 2; zstream.next_out = Marshal.UnsafeAddrOfPinnedArrayElement(Buffer, 0); zstream.total_out = 0; zstream.avail_out = 32768 + 6144; //int err = inflate(ref zstream, isLast ? 4 : 2); // Z_FINISH : Z_SYNC_FLUSH int err = inflate(ref zstream, 2); // Z_FINISH : Z_SYNC_FLUSH if (err != 0 && err != 1) // Z_OK || Z_STREAM_END { Console.WriteLine("Error inflating MS-ZIP data!"); Environment.Exit(1); } tmp = new byte[zstream.total_out]; Array.Copy(Buffer, tmp, zstream.total_out); // Technically speaking, the last chunk is at FOLDER'S END! //if (isLast) //{ // inflateEnd(ref zstream); // bInited = false; //} return tmp; }
private static extern int inflate(ref ZStream sz, int flush);
internal int inflate_fast(int bl, int bd, int[] tl, int tlIndex, int[] td, int tdIndex, InfBlocks s, ZStream z) { int t; // temporary pointer int[] tp; // temporary pointer int tpIndex; // temporary pointer int e; // extra bits or operation int b; // bit buffer int k; // bits in bit buffer int p; // input data pointer int n; // bytes available there int q; // output window write pointer int m; // bytes to end of window or read pointer int ml; // mask for literal/length tree int md; // mask for distance tree int c; // bytes to copy int d; // distance back to copy from int r; // copy source pointer int tpIndexT3; // (tp_index+t)*3 // load input, output, bit values p = z.NextInIndex; n = z.AvailIn; b = s.Bitb; k = s.Bitk; q = s.Write; m = q < s.Read ? s.Read - q - 1 : s.End - q; // initialize masks ml = _inflateMask[bl]; md = _inflateMask[bd]; // do until not enough input or output space for fast loop do { // assume called with m >= 258 && n >= 10 // get literal/length code while (k < (20)) { // max bits for literal/length code n--; b |= (z.NextIn[p++] & 0xff) << k; k += 8; } t = b & ml; tp = tl; tpIndex = tlIndex; tpIndexT3 = (tpIndex + t) * 3; if ((e = tp[tpIndexT3]) == 0) { b >>= (tp[tpIndexT3 + 1]); k -= (tp[tpIndexT3 + 1]); s.Window[q++] = (byte)tp[tpIndexT3 + 2]; m--; continue; } do { b >>= (tp[tpIndexT3 + 1]); k -= (tp[tpIndexT3 + 1]); if ((e & 16) != 0) { e &= 15; c = tp[tpIndexT3 + 2] + (b & _inflateMask[e]); b >>= e; k -= e; // decode distance base of block to copy while (k < (15)) { // max bits for distance code n--; b |= (z.NextIn[p++] & 0xff) << k; k += 8; } t = b & md; tp = td; tpIndex = tdIndex; tpIndexT3 = (tpIndex + t) * 3; e = tp[tpIndexT3]; do { b >>= (tp[tpIndexT3 + 1]); k -= (tp[tpIndexT3 + 1]); if ((e & 16) != 0) { // get extra bits to add to distance base e &= 15; while (k < (e)) { // get extra bits (up to 13) n--; b |= (z.NextIn[p++] & 0xff) << k; k += 8; } d = tp[tpIndexT3 + 2] + (b & _inflateMask[e]); b >>= (e); k -= (e); // do the copy m -= c; if (q >= d) { // offset before dest // just copy r = q - d; if (q - r > 0 && 2 > (q - r)) { s.Window[q++] = s.Window[r++]; // minimum count is three, s.Window[q++] = s.Window[r++]; // so unroll loop a little c -= 2; } else { Array.Copy(s.Window, r, s.Window, q, 2); q += 2; r += 2; c -= 2; } } else { // else offset after destination r = q - d; do { r += s.End; // force pointer in window } while (r < 0); // covers invalid distances e = s.End - r; if (c > e) { // if source crosses, c -= e; // wrapped copy if (q - r > 0 && e > (q - r)) { do { s.Window[q++] = s.Window[r++]; }while (--e != 0); } else { Array.Copy(s.Window, r, s.Window, q, e); q += e; r += e; e = 0; } r = 0; // copy rest from start of window } } // copy all or what's left if (q - r > 0 && c > (q - r)) { do { s.Window[q++] = s.Window[r++]; }while (--c != 0); } else { Array.Copy(s.Window, r, s.Window, q, c); q += c; r += c; c = 0; } break; } else if ((e & 64) == 0) { t += tp[tpIndexT3 + 2]; t += (b & _inflateMask[e]); tpIndexT3 = (tpIndex + t) * 3; e = tp[tpIndexT3]; } else { z.Msg = "invalid distance code"; c = z.AvailIn - n; c = (k >> 3) < c ? k >> 3 : c; n += c; p -= c; k -= c << 3; s.Bitb = b; s.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; s.Write = q; return(ZDataError); } }while (true); break; } if ((e & 64) == 0) { t += tp[tpIndexT3 + 2]; t += (b & _inflateMask[e]); tpIndexT3 = (tpIndex + t) * 3; if ((e = tp[tpIndexT3]) == 0) { b >>= (tp[tpIndexT3 + 1]); k -= (tp[tpIndexT3 + 1]); s.Window[q++] = (byte)tp[tpIndexT3 + 2]; m--; break; } } else if ((e & 32) != 0) { c = z.AvailIn - n; c = (k >> 3) < c ? k >> 3 : c; n += c; p -= c; k -= c << 3; s.Bitb = b; s.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; s.Write = q; return(ZStreamEnd); } else { z.Msg = "invalid literal/length code"; c = z.AvailIn - n; c = (k >> 3) < c ? k >> 3 : c; n += c; p -= c; k -= c << 3; s.Bitb = b; s.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; s.Write = q; return(ZDataError); } }while (true); }while (m >= 258 && n >= 10); // not enough input or output--restore pointers and return c = z.AvailIn - n; c = (k >> 3) < c ? k >> 3 : c; n += c; p -= c; k -= c << 3; s.Bitb = b; s.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; s.Write = q; return(ZOk); }
internal int inflate(ZStream z, int f) { int r; int b; if (z == null || z.istate == null || z.next_in == null) return Z_STREAM_ERROR; f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK; r = Z_BUF_ERROR; while (true) { //System.out.println("mode: "+z.istate.mode); switch (z.istate.mode) { case METHOD: if (z.avail_in == 0) return r; r = f; z.avail_in--; z.total_in++; if (((z.istate.method = z.next_in[z.next_in_index++]) & 0xf) != Z_DEFLATED) { z.istate.mode = BAD; z.msg = "unknown compression method"; z.istate.marker = 5; // can't try inflateSync break; } if ((z.istate.method >> 4) + 8 > z.istate.wbits) { z.istate.mode = BAD; z.msg = "invalid window size"; z.istate.marker = 5; // can't try inflateSync break; } z.istate.mode = FLAG; goto case FLAG; case FLAG: if (z.avail_in == 0) return r; r = f; z.avail_in--; z.total_in++; b = (z.next_in[z.next_in_index++]) & 0xff; if ((((z.istate.method << 8) + b) % 31) != 0) { z.istate.mode = BAD; z.msg = "incorrect header check"; z.istate.marker = 5; // can't try inflateSync break; } if ((b & PRESET_DICT) == 0) { z.istate.mode = BLOCKS; break; } z.istate.mode = DICT4; goto case DICT4; case DICT4: if (z.avail_in == 0) return r; r = f; z.avail_in--; z.total_in++; z.istate.need = ((z.next_in[z.next_in_index++] & 0xff) << 24) & unchecked((int)0xff000000L); z.istate.mode = DICT3; goto case DICT3; case DICT3: if (z.avail_in == 0) return r; r = f; z.avail_in--; z.total_in++; z.istate.need += (((z.next_in[z.next_in_index++] & 0xff) << 16) & 0xff0000L); z.istate.mode = DICT2; goto case DICT2; case DICT2: if (z.avail_in == 0) return r; r = f; z.avail_in--; z.total_in++; z.istate.need += (((z.next_in[z.next_in_index++] & 0xff) << 8) & 0xff00L); z.istate.mode = DICT1; goto case DICT1; case DICT1: if (z.avail_in == 0) return r; r = f; z.avail_in--; z.total_in++; z.istate.need += (z.next_in[z.next_in_index++] & 0xffL); z.adler = z.istate.need; z.istate.mode = DICT0; return Z_NEED_DICT; case DICT0: z.istate.mode = BAD; z.msg = "need dictionary"; z.istate.marker = 0; // can try inflateSync return Z_STREAM_ERROR; case BLOCKS: r = z.istate.blocks.proc(z, r); if (r == Z_DATA_ERROR) { z.istate.mode = BAD; z.istate.marker = 0; // can try inflateSync break; } if (r == Z_OK) { r = f; } if (r != Z_STREAM_END) { return r; } r = f; z.istate.blocks.reset(z, z.istate.was); if (z.istate.nowrap != 0) { z.istate.mode = DONE; break; } z.istate.mode = CHECK4; goto case CHECK4; case CHECK4: if (z.avail_in == 0) return r; r = f; z.avail_in--; z.total_in++; z.istate.need = ((z.next_in[z.next_in_index++] & 0xff) << 24) & unchecked((int)0xff000000L); z.istate.mode = CHECK3; goto case CHECK3; case CHECK3: if (z.avail_in == 0) return r; r = f; z.avail_in--; z.total_in++; z.istate.need += (((z.next_in[z.next_in_index++] & 0xff) << 16) & 0xff0000L); z.istate.mode = CHECK2; goto case CHECK2; case CHECK2: if (z.avail_in == 0) return r; r = f; z.avail_in--; z.total_in++; z.istate.need += (((z.next_in[z.next_in_index++] & 0xff) << 8) & 0xff00L); z.istate.mode = CHECK1; goto case CHECK1; case CHECK1: if (z.avail_in == 0) return r; r = f; z.avail_in--; z.total_in++; z.istate.need += (z.next_in[z.next_in_index++] & 0xffL); if (((int)(z.istate.was[0])) != ((int)(z.istate.need))) { z.istate.mode = BAD; z.msg = "incorrect data check"; z.istate.marker = 5; // can't try inflateSync break; } z.istate.mode = DONE; goto case DONE; case DONE: return Z_STREAM_END; case BAD: return Z_DATA_ERROR; default: return Z_STREAM_ERROR; } } }
public static extern int inflate(ref ZStream stream , int flush);
// Returns true if inflate is currently at the end of a block generated // by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP // implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH // but removes the length bytes of the resulting empty stored block. When // decompressing, PPP checks that at the end of input packet, inflate is // waiting for these length bytes. internal int inflateSyncPoint(ZStream z) { if (z == null || z.istate == null || z.istate.blocks == null) return Z_STREAM_ERROR; return z.istate.blocks.sync_point(); }
// bits needed // bits to get for extra // distance back to copy from // literal/length/eob tree // distance tree internal void Free(ZStream z) { // ZFREE(z, c); }
internal void init(int bl, int bd, int[] tl, int tl_index, int[] td, int td_index, ZStream z) { mode=START; lbits=(byte)bl; dbits=(byte)bd; ltree=tl; ltree_index=tl_index; dtree = td; dtree_index=td_index; tree=null; }
internal int Proc(InfBlocks s, ZStream z, int r) { int j; // temporary storage int tindex; // temporary pointer int e; // extra bits or operation var b = 0; // bit buffer var k = 0; // bits in bit buffer var p = 0; // input data pointer int n; // bytes available there int q; // output window write pointer int m; // bytes to end of window or read pointer int f; // pointer to copy strings from // copy input/output information to locals (UPDATE macro restores) p = z.NextInIndex; n = z.AvailIn; b = s.Bitb; k = s.Bitk; q = s.Write; m = q < s.Read ? s.Read - q - 1 : s.End - q; // process input and output based on current state while (true) { switch (_mode) { // waiting for "i:"=input, "o:"=output, "x:"=nothing case Start: // x: set up for LEN if (m >= 258 && n >= 10) { s.Bitb = b; s.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; s.Write = q; r = inflate_fast(_lbits, _dbits, _ltree, _ltreeIndex, _dtree, _dtreeIndex, s, z); p = z.NextInIndex; n = z.AvailIn; b = s.Bitb; k = s.Bitk; q = s.Write; m = q < s.Read ? s.Read - q - 1 : s.End - q; if (r != ZOk) { _mode = r == ZStreamEnd ? Wash : Badcode; break; } } _need = _lbits; _tree = _ltree; _treeIndex = _ltreeIndex; _mode = Len; goto case Len; case Len: // i: get length/literal/eob next j = _need; while (k < (j)) { if (n != 0) { r = ZOk; } else { s.Bitb = b; s.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; s.Write = q; return(s.inflate_flush(z, r)); } n--; b |= (z.NextIn[p++] & 0xff) << k; k += 8; } tindex = (_treeIndex + (b & _inflateMask[j])) * 3; b >>= (_tree[tindex + 1]); k -= (_tree[tindex + 1]); e = _tree[tindex]; if (e == 0) { // literal _lit = _tree[tindex + 2]; _mode = Lit; break; } if ((e & 16) != 0) { // length _get = e & 15; _len = _tree[tindex + 2]; _mode = Lenext; break; } if ((e & 64) == 0) { // next table _need = e; _treeIndex = tindex / 3 + _tree[tindex + 2]; break; } if ((e & 32) != 0) { // end of block _mode = Wash; break; } _mode = Badcode; // invalid code z.Msg = "invalid literal/length code"; r = ZDataError; s.Bitb = b; s.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; s.Write = q; return(s.inflate_flush(z, r)); case Lenext: // i: getting length extra (have base) j = _get; while (k < (j)) { if (n != 0) { r = ZOk; } else { s.Bitb = b; s.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; s.Write = q; return(s.inflate_flush(z, r)); } n--; b |= (z.NextIn[p++] & 0xff) << k; k += 8; } _len += (b & _inflateMask[j]); b >>= j; k -= j; _need = _dbits; _tree = _dtree; _treeIndex = _dtreeIndex; _mode = Dist; goto case Dist; case Dist: // i: get distance next j = _need; while (k < (j)) { if (n != 0) { r = ZOk; } else { s.Bitb = b; s.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; s.Write = q; return(s.inflate_flush(z, r)); } n--; b |= (z.NextIn[p++] & 0xff) << k; k += 8; } tindex = (_treeIndex + (b & _inflateMask[j])) * 3; b >>= _tree[tindex + 1]; k -= _tree[tindex + 1]; e = (_tree[tindex]); if ((e & 16) != 0) { // distance _get = e & 15; _dist = _tree[tindex + 2]; _mode = Distext; break; } if ((e & 64) == 0) { // next table _need = e; _treeIndex = tindex / 3 + _tree[tindex + 2]; break; } _mode = Badcode; // invalid code z.Msg = "invalid distance code"; r = ZDataError; s.Bitb = b; s.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; s.Write = q; return(s.inflate_flush(z, r)); case Distext: // i: getting distance extra j = _get; while (k < (j)) { if (n != 0) { r = ZOk; } else { s.Bitb = b; s.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; s.Write = q; return(s.inflate_flush(z, r)); } n--; b |= (z.NextIn[p++] & 0xff) << k; k += 8; } _dist += (b & _inflateMask[j]); b >>= j; k -= j; _mode = Copy; goto case Copy; case Copy: // o: copying bytes in window, waiting for space f = q - _dist; while (f < 0) { // modulo window size-"while" instead f += s.End; // of "if" handles invalid distances } while (_len != 0) { if (m == 0) { if (q == s.End && s.Read != 0) { q = 0; m = q < s.Read ? s.Read - q - 1 : s.End - q; } if (m == 0) { s.Write = q; r = s.inflate_flush(z, r); q = s.Write; m = q < s.Read ? s.Read - q - 1 : s.End - q; if (q == s.End && s.Read != 0) { q = 0; m = q < s.Read ? s.Read - q - 1 : s.End - q; } if (m == 0) { s.Bitb = b; s.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; s.Write = q; return(s.inflate_flush(z, r)); } } } s.Window[q++] = s.Window[f++]; m--; if (f == s.End) { f = 0; } _len--; } _mode = Start; break; case Lit: // o: got literal, waiting for output space if (m == 0) { if (q == s.End && s.Read != 0) { q = 0; m = q < s.Read ? s.Read - q - 1 : s.End - q; } if (m == 0) { s.Write = q; r = s.inflate_flush(z, r); q = s.Write; m = q < s.Read ? s.Read - q - 1 : s.End - q; if (q == s.End && s.Read != 0) { q = 0; m = q < s.Read ? s.Read - q - 1 : s.End - q; } if (m == 0) { s.Bitb = b; s.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; s.Write = q; return(s.inflate_flush(z, r)); } } } r = ZOk; s.Window[q++] = (byte)_lit; m--; _mode = Start; break; case Wash: // o: got eob, possibly more output if (k > 7) { // return unused byte, if any k -= 8; n++; p--; // can always return one } s.Write = q; r = s.inflate_flush(z, r); q = s.Write; m = q < s.Read ? s.Read - q - 1 : s.End - q; if (s.Read != s.Write) { s.Bitb = b; s.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; s.Write = q; return(s.inflate_flush(z, r)); } _mode = End; goto case End; case End: r = ZStreamEnd; s.Bitb = b; s.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; s.Write = q; return(s.inflate_flush(z, r)); case Badcode: // x: got error r = ZDataError; s.Bitb = b; s.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; s.Write = q; return(s.inflate_flush(z, r)); default: r = ZStreamError; s.Bitb = b; s.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; s.Write = q; return(s.inflate_flush(z, r)); } } }
public static int inflateInit2(ref ZStream stream , int windowBits) { return inflateInit2_(ref stream , windowBits , ZLIB_VERSION , Marshal.SizeOf(stream)); }
public static void main(String[] arg) { int err; int comprLen = 40000; int uncomprLen = comprLen; byte[] compr = new byte[comprLen]; byte[] uncompr = new byte[uncomprLen]; ZStream c_stream = new ZStream(); err = c_stream.deflateInit(JZlib.Z_BEST_SPEED); CHECK_ERR(c_stream, err, "deflateInit"); c_stream.next_out = compr; c_stream.next_out_index = 0; c_stream.avail_out = comprLen; // At this point, uncompr is still mostly zeroes, so it should compress // very well: c_stream.next_in = uncompr; c_stream.avail_in = uncomprLen; err = c_stream.deflate(JZlib.Z_NO_FLUSH); CHECK_ERR(c_stream, err, "deflate"); if (c_stream.avail_in != 0) { java.lang.SystemJ.outJ.println("deflate not greedy"); java.lang.SystemJ.exit(1); } // Feed in already compressed data and switch to no compression: c_stream.deflateParams(JZlib.Z_NO_COMPRESSION, JZlib.Z_DEFAULT_STRATEGY); c_stream.next_in = compr; c_stream.next_in_index = 0; c_stream.avail_in = comprLen / 2; err = c_stream.deflate(JZlib.Z_NO_FLUSH); CHECK_ERR(c_stream, err, "deflate"); // Switch back to compressing mode: c_stream.deflateParams(JZlib.Z_BEST_COMPRESSION, JZlib.Z_FILTERED); c_stream.next_in = uncompr; c_stream.next_in_index = 0; c_stream.avail_in = uncomprLen; err = c_stream.deflate(JZlib.Z_NO_FLUSH); CHECK_ERR(c_stream, err, "deflate"); err = c_stream.deflate(JZlib.Z_FINISH); if (err != JZlib.Z_STREAM_END) { java.lang.SystemJ.outJ.println("deflate should report Z_STREAM_END"); java.lang.SystemJ.exit(1); } err = c_stream.deflateEnd(); CHECK_ERR(c_stream, err, "deflateEnd"); ZStream d_stream = new ZStream(); d_stream.next_in = compr; d_stream.next_in_index = 0; d_stream.avail_in = comprLen; err = d_stream.inflateInit(); CHECK_ERR(d_stream, err, "inflateInit"); while (true) { d_stream.next_out = uncompr; d_stream.next_out_index = 0; d_stream.avail_out = uncomprLen; err = d_stream.inflate(JZlib.Z_NO_FLUSH); if (err == JZlib.Z_STREAM_END) { break; } CHECK_ERR(d_stream, err, "inflate large"); } err = d_stream.inflateEnd(); CHECK_ERR(d_stream, err, "inflateEnd"); if (d_stream.total_out != 2 * uncomprLen + comprLen / 2) { java.lang.SystemJ.outJ.println("bad large inflate: " + d_stream.total_out); java.lang.SystemJ.exit(1); } else { java.lang.SystemJ.outJ.println("large_inflate(): OK"); } }
/// <summary> /// Pack the folder pointed by the path (source) in a package pointed by the other path (destination). /// </summary> public static void Pack(String Source, String Destination) { if (!Destination.EndsWith(".tpi")) { Destination += ".tpi"; } var DI = new DirectoryInfo(Source); var Files = DI.GetFiles("*.*", SearchOption.AllDirectories); Header *pHeader = stackalloc Header[1]; TPI_IDENTIFIER.ToPointer(pHeader->Identifier); pHeader->Number = (UInt32)Files.Length; pHeader->Version = TPI_VERSION; pHeader->Unknown1 = TPI_UNKNOWN_1; pHeader->Unknown2 = TPI_UNKNOWN_2; pHeader->Unknown3 = TPI_UNKNOWN_3; pHeader->Reserved = 0x00; var Encoding = Encoding.GetEncoding("Windows-1252"); var Buffer = new Byte[Kernel.MAX_BUFFER_SIZE]; var Tmp = new Byte[Kernel.MAX_BUFFER_SIZE]; using (var TpiStream = new FileStream(Destination, FileMode.Create, FileAccess.Write, FileShare.Read)) using (var TpdStream = new FileStream(Destination.Replace(".tpi", ".tpd"), FileMode.Create, FileAccess.Write, FileShare.Read)) { using (var Writer = new BinaryWriter(TpiStream, Encoding)) { Console.Write("Writing header... "); Kernel.memcpy(Buffer, pHeader, sizeof(TPI.Header)); TpiStream.Write(Buffer, 0, sizeof(TPI.Header)); TpdStream.Write(Buffer, 0, sizeof(TPD.Header)); Console.WriteLine("Ok!"); Console.Write("Writing data... "); var CompressedSizes = new UInt32[Files.Length]; var Offsets = new UInt32[Files.Length]; var Offset = (UInt32)sizeof(TPD.Header); for (var i = 0; i < pHeader->Number; i++) { Console.Write("\rWriting data... {0}%", i * 100 / pHeader->Number); using (var Input = new FileStream(Files[i].FullName, FileMode.Open, FileAccess.Read, FileShare.Read)) { var Stream = new ZStream(); Stream.deflateInit(9); //TQ use lvl 3 var Param = zlibConst.Z_NO_FLUSH; var Length = 0; do { Length = Input.Read(Buffer, 0, Kernel.MAX_BUFFER_SIZE); Param = Length == 0 ? zlibConst.Z_FINISH : zlibConst.Z_NO_FLUSH; Stream.avail_in = Length; Stream.next_in = Buffer; Stream.next_in_index = 0; do { Stream.avail_out = Kernel.MAX_BUFFER_SIZE; Stream.next_out = Tmp; Stream.next_out_index = 0; var Result = Stream.deflate(Param); var Len = Kernel.MAX_BUFFER_SIZE - Stream.avail_out; TpdStream.Write(Tmp, 0, Len); }while (Stream.avail_out == 0); }while (Param != zlibConst.Z_FINISH); Stream.deflateEnd(); CompressedSizes[i] = (UInt32)Stream.total_out; Offsets[i] = Offset; Offset += CompressedSizes[i]; } } Console.WriteLine("\b\b\bOk!"); Console.Write("Writing entries... "); UInt32 LastOffset = 0; for (var i = 0; i < pHeader->Number; i++) { Console.Write("\rWriting entries... {0}%", i * 100 / pHeader->Number); var RelativePath = Files[i].FullName.Replace(DI.Parent.FullName + "\\", ""); RelativePath = RelativePath.ToLowerInvariant(); RelativePath = RelativePath.Replace('\\', '/'); LastOffset = (UInt32)Writer.BaseStream.Position; Writer.Write((Byte)RelativePath.Length); Writer.Write(Encoding.GetBytes(RelativePath.ToCharArray(), 0, (Byte)RelativePath.Length)); Writer.Write((Int16)TPI_UNKNOWN_1); Writer.Write((UInt32)Files[i].Length); Writer.Write((UInt32)CompressedSizes[i]); Writer.Write((UInt32)CompressedSizes[i]); Writer.Write((UInt32)Files[i].Length); Writer.Write((UInt32)Offsets[i]); } Console.WriteLine("\b\b\bOk!"); Console.Write("Updating header... "); TpiStream.Seek(0, SeekOrigin.Begin); pHeader->Offset = LastOffset; Kernel.memcpy(Buffer, pHeader, sizeof(TPI.Header)); TpiStream.Write(Buffer, 0, sizeof(TPI.Header)); Console.WriteLine("Ok!"); } } }
internal int inflate(ZStream z, int f) { int r; int b; if (z == null || z.istate == null || z.next_in == null) { return(Z_STREAM_ERROR); } f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK; r = Z_BUF_ERROR; while (true) { //System.out.println("mode: "+z.istate.mode); switch (z.istate.mode) { case METHOD: if (z.avail_in == 0) { return(r); } r = f; z.avail_in--; z.total_in++; if (((z.istate.method = z.next_in[z.next_in_index++]) & 0xf) != Z_DEFLATED) { z.istate.mode = BAD; z.msg = "unknown compression method"; z.istate.marker = 5; // can't try inflateSync break; } if ((z.istate.method >> 4) + 8 > z.istate.wbits) { z.istate.mode = BAD; z.msg = "invalid window size"; z.istate.marker = 5; // can't try inflateSync break; } z.istate.mode = FLAG; goto case FLAG; case FLAG: if (z.avail_in == 0) { return(r); } r = f; z.avail_in--; z.total_in++; b = z.next_in[z.next_in_index++] & 0xff; if (((z.istate.method << 8) + b) % 31 != 0) { z.istate.mode = BAD; z.msg = "incorrect header check"; z.istate.marker = 5; // can't try inflateSync break; } if ((b & PRESET_DICT) == 0) { z.istate.mode = BLOCKS; break; } z.istate.mode = DICT4; goto case DICT4; case DICT4: if (z.avail_in == 0) { return(r); } r = f; z.avail_in--; z.total_in++; z.istate.need = ((z.next_in[z.next_in_index++] & 0xff) << 24) & unchecked ((int)0xff000000L); z.istate.mode = DICT3; goto case DICT3; case DICT3: if (z.avail_in == 0) { return(r); } r = f; z.avail_in--; z.total_in++; z.istate.need += ((z.next_in[z.next_in_index++] & 0xff) << 16) & 0xff0000L; z.istate.mode = DICT2; goto case DICT2; case DICT2: if (z.avail_in == 0) { return(r); } r = f; z.avail_in--; z.total_in++; z.istate.need += ((z.next_in[z.next_in_index++] & 0xff) << 8) & 0xff00L; z.istate.mode = DICT1; goto case DICT1; case DICT1: if (z.avail_in == 0) { return(r); } r = f; z.avail_in--; z.total_in++; z.istate.need += z.next_in[z.next_in_index++] & 0xffL; z.adler = z.istate.need; z.istate.mode = DICT0; return(Z_NEED_DICT); case DICT0: z.istate.mode = BAD; z.msg = "need dictionary"; z.istate.marker = 0; // can try inflateSync return(Z_STREAM_ERROR); case BLOCKS: r = z.istate.blocks.proc(z, r); if (r == Z_DATA_ERROR) { z.istate.mode = BAD; z.istate.marker = 0; // can try inflateSync break; } if (r == Z_OK) { r = f; } if (r != Z_STREAM_END) { return(r); } r = f; z.istate.blocks.reset(z, z.istate.was); if (z.istate.nowrap != 0) { z.istate.mode = DONE; break; } z.istate.mode = CHECK4; goto case CHECK4; case CHECK4: if (z.avail_in == 0) { return(r); } r = f; z.avail_in--; z.total_in++; z.istate.need = ((z.next_in[z.next_in_index++] & 0xff) << 24) & unchecked ((int)0xff000000L); z.istate.mode = CHECK3; goto case CHECK3; case CHECK3: if (z.avail_in == 0) { return(r); } r = f; z.avail_in--; z.total_in++; z.istate.need += ((z.next_in[z.next_in_index++] & 0xff) << 16) & 0xff0000L; z.istate.mode = CHECK2; goto case CHECK2; case CHECK2: if (z.avail_in == 0) { return(r); } r = f; z.avail_in--; z.total_in++; z.istate.need += ((z.next_in[z.next_in_index++] & 0xff) << 8) & 0xff00L; z.istate.mode = CHECK1; goto case CHECK1; case CHECK1: if (z.avail_in == 0) { return(r); } r = f; z.avail_in--; z.total_in++; z.istate.need += z.next_in[z.next_in_index++] & 0xffL; if ((int)z.istate.was[0] != (int)z.istate.need) { z.istate.mode = BAD; z.msg = "incorrect data check"; z.istate.marker = 5; // can't try inflateSync break; } z.istate.mode = DONE; goto case DONE; case DONE: return(Z_STREAM_END); case BAD: return(Z_DATA_ERROR); default: return(Z_STREAM_ERROR); } } }
internal int inflateSync(ZStream z) { int n; // number of bytes to look at int p; // pointer to bytes int m; // number of marker bytes found in a row long r, w; // temporaries to save total_in and total_out // set up if (z == null || z.istate == null) { return(Z_STREAM_ERROR); } if (z.istate.mode != BAD) { z.istate.mode = BAD; z.istate.marker = 0; } if ((n = z.avail_in) == 0) { return(Z_BUF_ERROR); } p = z.next_in_index; m = z.istate.marker; // search while (n != 0 && m < 4) { if (z.next_in[p] == mark[m]) { m++; } else if (z.next_in[p] != 0) { m = 0; } else { m = 4 - m; } p++; n--; } // restore z.total_in += p - z.next_in_index; z.next_in_index = p; z.avail_in = n; z.istate.marker = m; // return no joy or set up to restart on a new block if (m != 4) { return(Z_DATA_ERROR); } r = z.total_in; w = z.total_out; inflateReset(z); z.total_in = r; z.total_out = w; z.istate.mode = BLOCKS; return(Z_OK); }
internal int inflate_trees_dynamic(int nl, int nd, int[] c, int[] bl, int[] bd, int[] tl, int[] td, int[] hp, ZStream z) { initWorkArea(288); hn[0] = 0; int num = huft_build(c, 0, nl, 257, cplens, cplext, tl, bl, hp, hn, v); if (num != 0 || bl[0] == 0) { switch (num) { case -3: z.msg = "oversubscribed literal/length tree"; break; default: z.msg = "incomplete literal/length tree"; num = -3; break; case -4: break; } return(num); } initWorkArea(288); num = huft_build(c, nl, nd, 0, cpdist, cpdext, td, bd, hp, hn, v); if (num != 0 || (bd[0] == 0 && nl > 257)) { switch (num) { case -3: z.msg = "oversubscribed distance tree"; break; case -5: z.msg = "incomplete distance tree"; num = -3; break; default: z.msg = "empty distance tree with lengths"; num = -3; break; case -4: break; } return(num); } return(0); }
internal int deflateInit2(ZStream strm, int level, int method, int windowBits, int memLevel, int strategy) { int noheader = 0; // byte[] my_version=ZLIB_VERSION; // // if (version == null || version[0] != my_version[0] // || stream_size != sizeof(z_stream)) { // return Z_VERSION_ERROR; // } strm.msg = null; if (level == Z_DEFAULT_COMPRESSION) level = 6; if (windowBits < 0) { // undocumented feature: suppress zlib header noheader = 1; windowBits = -windowBits; } if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || windowBits < 9 || windowBits > 15 || level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) { return Z_STREAM_ERROR; } strm.dstate = (Deflate)this; this.noheader = noheader; w_bits = windowBits; w_size = 1 << w_bits; w_mask = w_size - 1; hash_bits = memLevel + 7; hash_size = 1 << hash_bits; hash_mask = hash_size - 1; hash_shift = ((hash_bits+MIN_MATCH-1)/MIN_MATCH); window = new byte[w_size*2]; prev = new short[w_size]; head = new short[hash_size]; lit_bufsize = 1 << (memLevel + 6); // 16K elements by default // We overlay pending_buf and d_buf+l_buf. This works since the average // output size for (length,distance) codes is <= 24 bits. pending_buf = new byte[lit_bufsize*4]; pending_buf_size = lit_bufsize*4; d_buf = lit_bufsize/2; l_buf = (1+2)*lit_bufsize; this.level = level; //System.out.println("level="+level); this.strategy = strategy; this.method = (byte)method; return deflateReset(strm); }
internal static int inflate_trees_fixed(int[] bl, int[] bd, int[][] tl, int[][] td, ZStream z) { bl[0] = 9; bd[0] = 5; tl[0] = fixed_tl; td[0] = fixed_td; return(0); }
internal int deflateReset(ZStream strm) { strm.total_in = strm.total_out = 0; strm.msg = null; // strm.data_type = Z_UNKNOWN; pending = 0; pending_out = 0; if(noheader < 0) { noheader = 0; // was set to -1 by deflate(..., Z_FINISH); } status = (noheader!=0) ? BUSY_STATE : INIT_STATE; strm.adler=strm._adler.adler32(0, null, 0, 0); last_flush = Z_NO_FLUSH; tr_init(); lm_init(); return Z_OK; }
internal static byte[] Decompress(byte[] input, int wbits = MAX_WBITS, int bufsize = DEFAULTALLOC) { byte[] outputBuffer = new byte[bufsize]; byte[] output = new byte[bufsize]; int outputOffset = 0; ZStream zst = new ZStream(); zst.next_in = input; zst.avail_in = input.Length; zst.next_out = outputBuffer; zst.avail_out = outputBuffer.Length; int err = zst.inflateInit(wbits); if (err != Z_OK) { zst.inflateEnd(); throw zlib_error(zst, err, "while preparing to decompress data"); } do { err = zst.inflate(FlushStrategy.Z_FINISH); if (err != Z_STREAM_END) { if (err == Z_BUF_ERROR && zst.avail_out > 0) { zst.inflateEnd(); throw zlib_error(zst, err, "while decompressing data"); } else if (err == Z_OK || (err == Z_BUF_ERROR && zst.avail_out == 0)) { // copy to the output and reset the buffer if (outputOffset + outputBuffer.Length > output.Length) { Array.Resize(ref output, output.Length * 2); } Array.Copy(outputBuffer, 0, output, outputOffset, outputBuffer.Length); outputOffset += outputBuffer.Length; zst.next_out = outputBuffer; zst.avail_out = outputBuffer.Length; zst.next_out_index = 0; } else { zst.inflateEnd(); throw zlib_error(zst, err, "while decompressing data"); } } } while(err != Z_STREAM_END); err = zst.inflateEnd(); if (err != Z_OK) { throw zlib_error(zst, err, "while finishing data decompression"); } if (outputOffset + outputBuffer.Length - zst.avail_out > output.Length) { Array.Resize(ref output, output.Length * 2); } Array.Copy(outputBuffer, 0, output, outputOffset, outputBuffer.Length - zst.avail_out); outputOffset += outputBuffer.Length - zst.avail_out; return(output.Take(outputOffset).ToArray()); }
public override byte[] Compress(byte[] data, bool isLast) { if (!bInited) { zstream = new ZStream(); // memlevel=8 is equivalent to deflateInit_ // note that with a Python27 folder, DECREASING memlevel gives better results!!! // 9 is worse than 8, and 6 is the best (~14KiB better than 8, and 1 KiB better than CabArc 5.2) if (deflateInit2_(ref zstream, 5, 8, -15, 8, 0, "1.2.7", Marshal.SizeOf(zstream)) != 0) throw new ApplicationException("Couldn't initialize ZLIB library!"); bInited = true; } zstream.next_in = Marshal.UnsafeAddrOfPinnedArrayElement(data, 0); zstream.total_in = 0; zstream.avail_in = (uint)data.Length; zstream.next_out = Marshal.UnsafeAddrOfPinnedArrayElement(Buffer, 0); zstream.total_out = 0; zstream.avail_out = 32768 + 6144; // zlib compress is equivalent to deflate with Z_FINISH (4) + deflateEnd // we use deflate with Z_SYNC_FLUSH (2), and never reset // Z_FINISH is required (from CabArc) to mark the last block deflate(ref zstream, isLast ? 4 : 2); //if (deflate(ref zstream, isLast ? 4 : 2) != 0) // throw new ApplicationException("Error deflating data with MS-ZIP!"); if (isLast) { Console.WriteLine("DEBUG: isLast == true"); deflateEnd(ref zstream); bInited = false; } // To be extracted by MS CabArc, a block MUST be <=32780 bytes! // But Cabarc emits copied blocks of 32775, so we do the same if (zstream.total_out > 32768) { // Create a Deflate uncompressed block (32775 bytes), copying the raw input tmp = new byte[32775]; // "CK", 01, 0x8000, 0x7FFF, 32KiB raw data tmp[2] = 1; tmp[3] = 0; tmp[4] = 0x80; tmp[5] = 0xFF; tmp[6] = 0x7F; Array.Copy(data, 0, tmp, 7, 32768); } else { tmp = new byte[zstream.total_out + 2]; Array.Copy(Buffer, 0, tmp, 2, zstream.total_out); } tmp[0] = 67; tmp[1] = 75; // CK return tmp; }
public static void main(String[] arg) { int err; int comprLen = 40000; int uncomprLen = comprLen; byte[] compr = new byte[comprLen]; byte[] uncompr = new byte[uncomprLen]; int len = hello.Length; ZStream c_stream = new ZStream(); err = c_stream.deflateInit(JZlib.Z_DEFAULT_COMPRESSION); CHECK_ERR(c_stream, err, "deflate"); c_stream.next_in = hello; c_stream.next_in_index = 0; c_stream.next_out = compr; c_stream.next_out_index = 0; c_stream.avail_in = 3; c_stream.avail_out = comprLen; err = c_stream.deflate(JZlib.Z_FULL_FLUSH); CHECK_ERR(c_stream, err, "deflate"); compr[3]++; // force an error in first compressed block c_stream.avail_in = len - 3; err = c_stream.deflate(JZlib.Z_FINISH); if (err != JZlib.Z_STREAM_END) { CHECK_ERR(c_stream, err, "deflate"); } err = c_stream.deflateEnd(); CHECK_ERR(c_stream, err, "deflateEnd"); comprLen = (int)(c_stream.total_out); ZStream d_stream = new ZStream(); d_stream.next_in = compr; d_stream.next_in_index = 0; d_stream.avail_in = 2; err = d_stream.inflateInit(); CHECK_ERR(d_stream, err, "inflateInit"); d_stream.next_out = uncompr; d_stream.next_out_index = 0; d_stream.avail_out = uncomprLen; err = d_stream.inflate(JZlib.Z_NO_FLUSH); CHECK_ERR(d_stream, err, "inflate"); d_stream.avail_in = comprLen - 2; err = d_stream.inflateSync(); CHECK_ERR(d_stream, err, "inflateSync"); err = d_stream.inflate(JZlib.Z_FINISH); if (err != JZlib.Z_DATA_ERROR) { java.lang.SystemJ.outJ.println("inflate should report DATA_ERROR"); /* Because of incorrect adler32 */ java.lang.SystemJ.exit(1); } err = d_stream.inflateEnd(); CHECK_ERR(d_stream, err, "inflateEnd"); int j = 0; for (; j < uncompr.Length; j++) { if (uncompr[j] == 0) { break; } } java.lang.SystemJ.outJ.println("after inflateSync(): hel" + new java.lang.StringJ(uncompr, 0, j)); }
private static extern int deflateInit2_(ref ZStream sz, int level, int method, int windowbits, int memlevel, int strategy, string vs, int size);
/// <summary> /// copy as much as possible from the sliding window to the output area /// </summary> internal int inflate_flush(ZStream z, int r) { int n; int p; int q; // local copies of source and destination pointers p = z.NextOutIndex; q = Read; // compute number of bytes to copy as far as end of window n = (q <= Write ? Write : End) - q; if (n > z.AvailOut) { n = z.AvailOut; } if (n != 0 && r == ZBufError) { r = ZOk; } // update counters z.AvailOut -= n; z.TotalOut += n; // update check information if (Checkfn != null) { z.Adler = Check = z._adler.adler32(Check, Window, q, n); } // copy as far as end of window Array.Copy(Window, q, z.NextOut, p, n); p += n; q += n; // see if more to copy at beginning of window if (q == End) { // wrap pointers q = 0; if (Write == End) { Write = 0; } // compute bytes to copy n = Write - q; if (n > z.AvailOut) { n = z.AvailOut; } if (n != 0 && r == ZBufError) { r = ZOk; } // update counters z.AvailOut -= n; z.TotalOut += n; // update check information if (Checkfn != null) { z.Adler = Check = z._adler.adler32(Check, Window, q, n); } // copy Array.Copy(Window, q, z.NextOut, p, n); p += n; q += n; } // update pointers z.NextOutIndex = p; Read = q; // done return(r); }
private static extern int inflateEnd(ref ZStream sz);
internal int Proc(ZStream z, int r) { int t; // temporary storage int b; // bit buffer int k; // bits in bit buffer int p; // input data pointer int n; // bytes available there int q; // output window write pointer int m; { // bytes to end of window or read pointer // copy input/output information to locals (UPDATE macro restores) p = z.NextInIndex; n = z.AvailIn; b = Bitb; k = Bitk; } { q = Write; m = q < Read ? Read - q - 1 : End - q; } // process input based on current state while (true) { switch (Mode) { case Type: while (k < (3)) { if (n != 0) { r = ZOk; } else { Bitb = b; Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; Write = q; return(inflate_flush(z, r)); } n--; b |= (z.NextIn[p++] & 0xff) << k; k += 8; } t = b & 7; _last = t & 1; switch (t >> 1) { case 0: { // stored b >>= (3); k -= (3); } t = k & 7; { // go to byte boundary b >>= (t); k -= (t); } Mode = Lens; // get length of stored block break; case 1: { // fixed var bl = new int[1]; var bd = new int[1]; var tl = new int[1][]; var td = new int[1][]; InfTree.inflate_trees_fixed(bl, bd, tl, td, z); codes.Init(bl[0], bd[0], tl[0], 0, td[0], 0, z); } { b >>= (3); k -= (3); } Mode = Codes; break; case 2: { // dynamic b >>= (3); k -= (3); } Mode = Table; break; case 3: { // illegal b >>= (3); k -= (3); } Mode = Bad; z.Msg = "invalid block type"; r = ZDataError; Bitb = b; Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; Write = q; return(inflate_flush(z, r)); } break; case Lens: while (k < (32)) { if (n != 0) { r = ZOk; } else { Bitb = b; Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; Write = q; return(inflate_flush(z, r)); }; n--; b |= (z.NextIn[p++] & 0xff) << k; k += 8; } if ((((~b) >> 16) & 0xffff) != (b & 0xffff)) { Mode = Bad; z.Msg = "invalid stored block lengths"; r = ZDataError; Bitb = b; Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; Write = q; return(inflate_flush(z, r)); } Left = (b & 0xffff); b = k = 0; // dump bits Mode = Left != 0 ? Stored : (_last != 0 ? Dry : Type); break; case Stored: if (n == 0) { Bitb = b; Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; Write = q; return(inflate_flush(z, r)); } if (m == 0) { if (q == End && Read != 0) { q = 0; m = q < Read ? Read - q - 1 : End - q; } if (m == 0) { Write = q; r = inflate_flush(z, r); q = Write; m = q < Read ? Read - q - 1 : End - q; if (q == End && Read != 0) { q = 0; m = q < Read ? Read - q - 1 : End - q; } if (m == 0) { Bitb = b; Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; Write = q; return(inflate_flush(z, r)); } } } r = ZOk; t = Left; if (t > n) { t = n; } if (t > m) { t = m; } Array.Copy(z.NextIn, p, Window, q, t); p += t; n -= t; q += t; m -= t; if ((Left -= t) != 0) { break; } Mode = _last != 0 ? Dry : Type; break; case Table: while (k < (14)) { if (n != 0) { r = ZOk; } else { Bitb = b; Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; Write = q; return(inflate_flush(z, r)); }; n--; b |= (z.NextIn[p++] & 0xff) << k; k += 8; } table = t = (b & 0x3fff); if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) { Mode = Bad; z.Msg = "too many length or distance symbols"; r = ZDataError; Bitb = b; Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; Write = q; return(inflate_flush(z, r)); } t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); if (Blens == null || Blens.Length < t) { Blens = new int[t]; } else { for (var i = 0; i < t; i++) { Blens[i] = 0; } } { b >>= (14); k -= (14); } Index = 0; Mode = Btree; goto case Btree; case Btree: while (Index < 4 + (table >> 10)) { while (k < (3)) { if (n != 0) { r = ZOk; } else { Bitb = b; Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; Write = q; return(inflate_flush(z, r)); } n--; b |= (z.NextIn[p++] & 0xff) << k; k += 8; } Blens[_border[Index++]] = b & 7; { b >>= (3); k -= (3); } } while (Index < 19) { Blens[_border[Index++]] = 0; } Bb[0] = 7; t = Inftree.inflate_trees_bits(Blens, Bb, Tb, Hufts, z); if (t != ZOk) { r = t; if (r == ZDataError) { Blens = null; Mode = Bad; } Bitb = b; Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; Write = q; return(inflate_flush(z, r)); } Index = 0; Mode = Dtree; goto case Dtree; case Dtree: while (true) { t = table; if (!(Index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))) { break; } int i, j, c; t = Bb[0]; while (k < (t)) { if (n != 0) { r = ZOk; } else { Bitb = b; Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; Write = q; return(inflate_flush(z, r)); } n--; b |= (z.NextIn[p++] & 0xff) << k; k += 8; } if (Tb[0] == -1) { //System.err.println("null..."); } t = Hufts[(Tb[0] + (b & _inflateMask[t])) * 3 + 1]; c = Hufts[(Tb[0] + (b & _inflateMask[t])) * 3 + 2]; if (c < 16) { b >>= (t); k -= (t); Blens[Index++] = c; } else { // c == 16..18 i = c == 18 ? 7 : c - 14; j = c == 18 ? 11 : 3; while (k < (t + i)) { if (n != 0) { r = ZOk; } else { Bitb = b; Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; Write = q; return(inflate_flush(z, r)); } n--; b |= (z.NextIn[p++] & 0xff) << k; k += 8; } b >>= (t); k -= (t); j += (b & _inflateMask[i]); b >>= (i); k -= (i); i = Index; t = table; if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || (c == 16 && i < 1)) { Blens = null; Mode = Bad; z.Msg = "invalid bit length repeat"; r = ZDataError; Bitb = b; Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; Write = q; return(inflate_flush(z, r)); } c = c == 16 ? Blens[i - 1] : 0; do { Blens[i++] = c; }while (--j != 0); Index = i; } } Tb[0] = -1; { var bl = new int[1]; var bd = new int[1]; var tl = new int[1]; var td = new int[1]; bl[0] = 9; // must be <= 9 for lookahead assumptions bd[0] = 6; // must be <= 9 for lookahead assumptions t = table; t = Inftree.inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), Blens, bl, bd, tl, td, Hufts, z); if (t != ZOk) { if (t == ZDataError) { Blens = null; Mode = Bad; } r = t; Bitb = b; Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; Write = q; return(inflate_flush(z, r)); } codes.Init(bl[0], bd[0], Hufts, tl[0], Hufts, td[0], z); } Mode = Codes; goto case Codes; case Codes: Bitb = b; Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; Write = q; if ((r = codes.Proc(this, z, r)) != ZStreamEnd) { return(inflate_flush(z, r)); } r = ZOk; codes.Free(z); p = z.NextInIndex; n = z.AvailIn; b = Bitb; k = Bitk; q = Write; m = q < Read ? Read - q - 1 : End - q; if (_last == 0) { Mode = Type; break; } Mode = Dry; goto case Dry; case Dry: Write = q; r = inflate_flush(z, r); q = Write; m = q < Read ? Read - q - 1 : End - q; if (Read != Write) { Bitb = b; Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; Write = q; return(inflate_flush(z, r)); } Mode = Done; goto case Done; case Done: r = ZStreamEnd; Bitb = b; Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; Write = q; return(inflate_flush(z, r)); case Bad: r = ZDataError; Bitb = b; Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; Write = q; return(inflate_flush(z, r)); default: r = ZStreamError; Bitb = b; Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; Write = q; return(inflate_flush(z, r)); } } }
public virtual void end() { if (compress) { z.deflateEnd(); } else { z.inflateEnd(); } z.free(); z = null; }
internal int InflateSync(ZStream z) { int n; // number of bytes to look at int p; // pointer to bytes int m; // number of marker bytes found in a row long r, w; // temporaries to save total_in and total_out // set up if (z == null || z.Istate == null) { return(ZStreamError); } if (z.Istate.Mode != Bad) { z.Istate.Mode = Bad; z.Istate.Marker = 0; } if ((n = z.AvailIn) == 0) { return(ZBufError); } p = z.NextInIndex; m = z.Istate.Marker; // search while (n != 0 && m < 4) { if (z.NextIn[p] == _mark[m]) { m++; } else if (z.NextIn[p] != 0) { m = 0; } else { m = 4 - m; } p++; n--; } // restore z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; z.AvailIn = n; z.Istate.Marker = m; // return no joy or set up to restart on a new block if (m != 4) { return(ZDataError); } r = z.TotalIn; w = z.TotalOut; InflateReset(z); z.TotalIn = r; z.TotalOut = w; z.Istate.Mode = Blocks; return(ZOk); }
internal int inflateInit(ZStream z, int w) { z.msg = null; blocks = null; // handle undocumented nowrap option (no zlib header or check) nowrap = 0; if (w < 0) { w = -w; nowrap = 1; } // set window size if (w < 8 || w > 15) { inflateEnd(z); return Z_STREAM_ERROR; } wbits = w; z.istate.blocks = new InfBlocks(z, z.istate.nowrap != 0 ? null : this, 1 << w); // reset state inflateReset(z); return Z_OK; }
internal int inflate(ZStream z, int f) { int r; int b; if (z == null || z.Istate == null || z.NextIn == null) { return(ZStreamError); } f = f == Z_FINISH ? ZBufError : ZOk; r = ZBufError; while (true) { //System.out.println("mode: "+z.istate.mode); switch (z.Istate.Mode) { case Method: if (z.AvailIn == 0) { return(r); } r = f; z.AvailIn--; z.TotalIn++; if (((z.Istate.method = z.NextIn[z.NextInIndex++]) & 0xf) != ZDeflated) { z.Istate.Mode = Bad; z.Msg = "unknown compression method"; z.Istate.Marker = 5; // can't try inflateSync break; } if ((z.Istate.method >> 4) + 8 > z.Istate.Wbits) { z.Istate.Mode = Bad; z.Msg = "invalid window size"; z.Istate.Marker = 5; // can't try inflateSync break; } z.Istate.Mode = Flag; goto case Flag; case Flag: if (z.AvailIn == 0) { return(r); } r = f; z.AvailIn--; z.TotalIn++; b = (z.NextIn[z.NextInIndex++]) & 0xff; if ((((z.Istate.method << 8) + b) % 31) != 0) { z.Istate.Mode = Bad; z.Msg = "incorrect header check"; z.Istate.Marker = 5; // can't try inflateSync break; } if ((b & PresetDict) == 0) { z.Istate.Mode = Blocks; break; } z.Istate.Mode = Dict4; goto case Dict4; case Dict4: if (z.AvailIn == 0) { return(r); } r = f; z.AvailIn--; z.TotalIn++; z.Istate.Need = ((z.NextIn[z.NextInIndex++] & 0xff) << 24) & 0xff000000L; z.Istate.Mode = Dict3; goto case Dict3; case Dict3: if (z.AvailIn == 0) { return(r); } r = f; z.AvailIn--; z.TotalIn++; z.Istate.Need += ((z.NextIn[z.NextInIndex++] & 0xff) << 16) & 0xff0000L; z.Istate.Mode = Dict2; goto case Dict2; case Dict2: if (z.AvailIn == 0) { return(r); } r = f; z.AvailIn--; z.TotalIn++; z.Istate.Need += ((z.NextIn[z.NextInIndex++] & 0xff) << 8) & 0xff00L; z.Istate.Mode = Dict1; goto case Dict1; case Dict1: if (z.AvailIn == 0) { return(r); } r = f; z.AvailIn--; z.TotalIn++; z.Istate.Need += (z.NextIn[z.NextInIndex++] & 0xffL); z.Adler = z.Istate.Need; z.Istate.Mode = Dict0; return(ZNeedDict); case Dict0: z.Istate.Mode = Bad; z.Msg = "need dictionary"; z.Istate.Marker = 0; // can try inflateSync return(ZStreamError); case Blocks: r = z.Istate.blocks.Proc(z, r); if (r == ZDataError) { z.Istate.Mode = Bad; z.Istate.Marker = 0; // can try inflateSync break; } if (r == ZOk) { r = f; } if (r != ZStreamEnd) { return(r); } r = f; z.Istate.blocks.Reset(z, z.Istate.Was); if (z.Istate.Nowrap != 0) { z.Istate.Mode = Done; break; } z.Istate.Mode = Check4; goto case Check4; case Check4: if (z.AvailIn == 0) { return(r); } r = f; z.AvailIn--; z.TotalIn++; z.Istate.Need = ((z.NextIn[z.NextInIndex++] & 0xff) << 24) & 0xff000000L; z.Istate.Mode = Check3; goto case Check3; case Check3: if (z.AvailIn == 0) { return(r); } r = f; z.AvailIn--; z.TotalIn++; z.Istate.Need += ((z.NextIn[z.NextInIndex++] & 0xff) << 16) & 0xff0000L; z.Istate.Mode = Check2; goto case Check2; case Check2: if (z.AvailIn == 0) { return(r); } r = f; z.AvailIn--; z.TotalIn++; z.Istate.Need += ((z.NextIn[z.NextInIndex++] & 0xff) << 8) & 0xff00L; z.Istate.Mode = Check1; goto case Check1; case Check1: if (z.AvailIn == 0) { return(r); } r = f; z.AvailIn--; z.TotalIn++; z.Istate.Need += (z.NextIn[z.NextInIndex++] & 0xffL); if (((int)(z.Istate.Was[0])) != ((int)(z.Istate.Need))) { z.Istate.Mode = Bad; z.Msg = "incorrect data check"; z.Istate.Marker = 5; // can't try inflateSync break; } z.Istate.Mode = Done; goto case Done; case Done: return(ZStreamEnd); case Bad: return(ZDataError); default: return(ZStreamError); } } }
internal int inflateSync(ZStream z) { int n; // number of bytes to look at int p; // pointer to bytes int m; // number of marker bytes found in a row long r, w; // temporaries to save total_in and total_out // set up if (z == null || z.istate == null) return Z_STREAM_ERROR; if (z.istate.mode != BAD) { z.istate.mode = BAD; z.istate.marker = 0; } if ((n = z.avail_in) == 0) return Z_BUF_ERROR; p = z.next_in_index; m = z.istate.marker; // search while (n != 0 && m < 4) { if (z.next_in[p] == mark[m]) { m++; } else if (z.next_in[p] != 0) { m = 0; } else { m = 4 - m; } p++; n--; } // restore z.total_in += p - z.next_in_index; z.next_in_index = p; z.avail_in = n; z.istate.marker = m; // return no joy or set up to restart on a new block if (m != 4) { return Z_DATA_ERROR; } r = z.total_in; w = z.total_out; inflateReset(z); z.total_in = r; z.total_out = w; z.istate.mode = BLOCKS; return Z_OK; }
public static void main(String[] arg) { int err; int comprLen = 40000; int uncomprLen = comprLen; byte[] uncompr = new byte[uncomprLen]; byte[] compr = new byte[comprLen]; long dictId; ZStream c_stream = new ZStream(); err = c_stream.deflateInit(JZlib.Z_BEST_COMPRESSION); CHECK_ERR(c_stream, err, "deflateInit"); err = c_stream.deflateSetDictionary(dictionary, dictionary.Length); CHECK_ERR(c_stream, err, "deflateSetDictionary"); dictId = c_stream.adler; c_stream.next_out = compr; c_stream.next_out_index = 0; c_stream.avail_out = comprLen; c_stream.next_in = hello; c_stream.next_in_index = 0; c_stream.avail_in = hello.Length; err = c_stream.deflate(JZlib.Z_FINISH); if (err != JZlib.Z_STREAM_END) { java.lang.SystemJ.outJ.println("deflate should report Z_STREAM_END"); java.lang.SystemJ.exit(1); } err = c_stream.deflateEnd(); CHECK_ERR(c_stream, err, "deflateEnd"); ZStream d_stream = new ZStream(); d_stream.next_in = compr; d_stream.next_in_index = 0; d_stream.avail_in = comprLen; err = d_stream.inflateInit(); CHECK_ERR(d_stream, err, "inflateInit"); d_stream.next_out = uncompr; d_stream.next_out_index = 0; d_stream.avail_out = uncomprLen; while (true) { err = d_stream.inflate(JZlib.Z_NO_FLUSH); if (err == JZlib.Z_STREAM_END) { break; } if (err == JZlib.Z_NEED_DICT) { if ((int)d_stream.adler != (int)dictId) { java.lang.SystemJ.outJ.println("unexpected dictionary"); java.lang.SystemJ.exit(1); } err = d_stream.inflateSetDictionary(dictionary, dictionary.Length); } CHECK_ERR(d_stream, err, "inflate with dict"); } err = d_stream.inflateEnd(); CHECK_ERR(d_stream, err, "inflateEnd"); int j = 0; for (; j < uncompr.Length; j++) { if (uncompr[j] == 0) { break; } } java.lang.SystemJ.outJ.println("after inflateSync(): hel" + new java.lang.StringJ(uncompr, 0, j)); }
public ZLibStreamHandle() : base(new IntPtr(-1), true) { _zStream = new ZStream(); _zStream.Init(); _initializationState = State.NotInitialized; this.SetHandle(IntPtr.Zero); }
public PacketStream(byte[] mpBuffer, int mpLength, IStreamCipher mpDecryptor, ZStream iStream, bool IsHandshake = false) { Packets = new List <Packet>(); if (IsHandshake) { MemoryStream Stream = new MemoryStream(mpBuffer); EndianBinaryReader Reader = new EndianBinaryReader(MiscUtil.Conversion.BigEndianBitConverter.Little, Stream); Reader.ReadByte(); int Length = Reader.ReadInt32(); Reader.ReadBytes(5); byte[] Data = Reader.ReadBytes(Length - 10); string RSAStr = Encoding.ASCII.GetString(Data); Packet iPacket = new Packet(); iPacket.RSAData = new byte[RSAStr.Length / 2]; for (int i = 0; i < RSAStr.Length; i += 2) { iPacket.RSAData[i / 2] = byte.Parse(RSAStr.Substring(i, 2), NumberStyles.HexNumber); } Reader.Close(); Stream.Close(); Packets.Add(iPacket); } else { Packets = new List <Packet>(); byte[] dBuffer = new byte[mpLength]; mpDecryptor.ProcessBytes(mpBuffer, 0, mpLength, dBuffer, 0); MemoryStream Stream = new MemoryStream(dBuffer); EndianBinaryReader Reader = new EndianBinaryReader(MiscUtil.Conversion.BigEndianBitConverter.Little, Stream); int remLength = mpLength; do { Packet iPacket = new Packet(); iPacket.Module = Reader.ReadByte(); int pLength = Reader.ReadInt32(); int pChecksum = Reader.ReadByte(); try { if (iPacket.VerifyChecksum(dBuffer, pChecksum, (int)Reader.BaseStream.Position - 6)) { byte[] iData = Reader.ReadBytes(pLength - 6); //Console.WriteLine("#########################################\n{0}", iData.ToHEX()); byte[] Data = Decompress(iData, iStream); if (Data.Length >= 4) { iPacket.Stream = new MemoryStream(Data); iPacket.Reader = new EndianBinaryReader(MiscUtil.Conversion.EndianBitConverter.Little, iPacket.Stream); iPacket.PacketID = (CPacketType)iPacket.Reader.ReadUInt32(); iPacket.Reader.ReadUInt32(); iPacket.IsValid = true; byte[] cData = new byte[pLength]; Array.Copy(dBuffer, 0, cData, 0, pLength); iPacket.Data = Data; Packets.Add(iPacket); } } } catch { } remLength -= pLength; }while (remLength > 0); Reader.Close(); Stream.Close(); } }
// Called with number of bytes left to write in window at least 258 // (the maximum string length) and number of input bytes available // at least ten. The ten bytes are six bytes for the longest length/ // distance pair plus four bytes for overloading the bit buffer. internal int inflate_fast(int bl, int bd, int[] tl, int tl_index, int[] td, int td_index, InfBlocks s, ZStream z) { int t; // temporary pointer int[] tp; // temporary pointer int tp_index; // temporary pointer int e; // extra bits or operation int b; // bit buffer int k; // bits in bit buffer int p; // input data pointer int n; // bytes available there int q; // output window write pointer int m; // bytes to end of window or read pointer int ml; // mask for literal/length tree int md; // mask for distance tree int c; // bytes to copy int d; // distance back to copy from int r; // copy source pointer int tp_index_t_3; // (tp_index+t)*3 // load input, output, bit values p=z.next_in_index;n=z.avail_in;b=s.bitb;k=s.bitk; q=s.write;m=q<s.read?s.read-q-1:s.end-q; // initialize masks ml = inflate_mask[bl]; md = inflate_mask[bd]; // do until not enough input or output space for fast loop do { // assume called with m >= 258 && n >= 10 // get literal/length code while(k<(20)){ // max bits for literal/length code n--; b|=(z.next_in[p++]&0xff)<<k;k+=8; } t= b&ml; tp=tl; tp_index=tl_index; tp_index_t_3=(tp_index+t)*3; if ((e = tp[tp_index_t_3]) == 0){ b>>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); s.window[q++] = (byte)tp[tp_index_t_3+2]; m--; continue; } do { b>>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); if((e&16)!=0){ e &= 15; c = tp[tp_index_t_3+2] + ((int)b & inflate_mask[e]); b>>=e; k-=e; // decode distance base of block to copy while(k<(15)){ // max bits for distance code n--; b|=(z.next_in[p++]&0xff)<<k;k+=8; } t= b&md; tp=td; tp_index=td_index; tp_index_t_3=(tp_index+t)*3; e = tp[tp_index_t_3]; do { b>>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); if((e&16)!=0){ // get extra bits to add to distance base e &= 15; while(k<(e)){ // get extra bits (up to 13) n--; b|=(z.next_in[p++]&0xff)<<k;k+=8; } d = tp[tp_index_t_3+2] + (b&inflate_mask[e]); b>>=(e); k-=(e); // do the copy m -= c; if (q >= d){ // offset before dest // just copy r=q-d; if(q-r>0 && 2>(q-r)){ s.window[q++]=s.window[r++]; // minimum count is three, s.window[q++]=s.window[r++]; // so unroll loop a little c-=2; } else{ Array.Copy(s.window, r, s.window, q, 2); q+=2; r+=2; c-=2; } } else{ // else offset after destination r=q-d; do{ r+=s.end; // force pointer in window }while(r<0); // covers invalid distances e=s.end-r; if(c>e){ // if source crosses, c-=e; // wrapped copy if(q-r>0 && e>(q-r)){ do{s.window[q++] = s.window[r++];} while(--e!=0); } else{ Array.Copy(s.window, r, s.window, q, e); q+=e; r+=e; e=0; } r = 0; // copy rest from start of window } } // copy all or what's left if(q-r>0 && c>(q-r)){ do{s.window[q++] = s.window[r++];} while(--c!=0); } else{ Array.Copy(s.window, r, s.window, q, c); q+=c; r+=c; c=0; } break; } else if((e&64)==0){ t+=tp[tp_index_t_3+2]; t+=(b&inflate_mask[e]); tp_index_t_3=(tp_index+t)*3; e=tp[tp_index_t_3]; } else{ z.msg = "invalid distance code"; c=z.avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3; s.bitb=b;s.bitk=k; z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; s.write=q; return Z_DATA_ERROR; } } while(true); break; } if((e&64)==0){ t+=tp[tp_index_t_3+2]; t+=(b&inflate_mask[e]); tp_index_t_3=(tp_index+t)*3; if((e=tp[tp_index_t_3])==0){ b>>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); s.window[q++]=(byte)tp[tp_index_t_3+2]; m--; break; } } else if((e&32)!=0){ c=z.avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3; s.bitb=b;s.bitk=k; z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; s.write=q; return Z_STREAM_END; } else{ z.msg="invalid literal/length code"; c=z.avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3; s.bitb=b;s.bitk=k; z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; s.write=q; return Z_DATA_ERROR; } } while(true); } while(m>=258 && n>= 10); // not enough input or output--restore pointers and return c=z.avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3; s.bitb=b;s.bitk=k; z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; s.write=q; return Z_OK; }
public static PhpString gzinflate(byte[] data, long length = 0) { uint factor = 1, maxfactor = 16; long ilength; var zs = new ZStream(); zs.avail_in = data.Length; zs.next_in = data; zs.total_out = 0; // -15 omits the header (undocumented feature of zlib) int status = zs.inflateInit(-15); if (status != zlibConst.Z_OK) { PhpException.Throw(PhpError.Warning, zError(status)); return(default(PhpString)); } do { ilength = length != 0 ? length : data.Length * (1 << (int)(factor++)); try { byte[] newOutput = new byte[ilength]; if (zs.next_out != null) { Buffer.BlockCopy(zs.next_out, 0, newOutput, 0, zs.next_out.Length); } zs.next_out = newOutput; } catch (OutOfMemoryException) { zs.inflateEnd(); return(default(PhpString)); } zs.next_out_index = (int)zs.total_out; zs.avail_out = unchecked ((int)(ilength - zs.total_out)); status = zs.inflate(zlibConst.Z_NO_FLUSH); }while ((status == zlibConst.Z_BUF_ERROR || (status == zlibConst.Z_OK && (zs.avail_in != 0 || zs.avail_out == 0))) && length == 0 && factor < maxfactor); zs.inflateEnd(); if ((length != 0 && status == zlibConst.Z_OK) || factor >= maxfactor) { status = zlibConst.Z_MEM_ERROR; } if (status == zlibConst.Z_STREAM_END || status == zlibConst.Z_OK) { byte[] result = new byte[zs.total_out]; Buffer.BlockCopy(zs.next_out, 0, result, 0, (int)zs.total_out); return(new PhpString(result)); } else { PhpException.Throw(PhpError.Warning, zError(status) ?? zs.msg); return(default(PhpString)); } }
internal int proc(InfBlocks s, ZStream z, int r) { int j; // temporary storage int tindex; // temporary pointer int e; // extra bits or operation int b=0; // bit buffer int k=0; // bits in bit buffer int p=0; // input data pointer int n; // bytes available there int q; // output window write pointer int m; // bytes to end of window or read pointer int f; // pointer to copy strings from // copy input/output information to locals (UPDATE macro restores) p=z.next_in_index;n=z.avail_in;b=s.bitb;k=s.bitk; q=s.write;m=q<s.read?s.read-q-1:s.end-q; // process input and output based on current state while (true){ switch (mode){ // waiting for "i:"=input, "o:"=output, "x:"=nothing case START: // x: set up for LEN if (m >= 258 && n >= 10){ s.bitb=b;s.bitk=k; z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; s.write=q; r = inflate_fast(lbits, dbits, ltree, ltree_index, dtree, dtree_index, s, z); p=z.next_in_index;n=z.avail_in;b=s.bitb;k=s.bitk; q=s.write;m=q<s.read?s.read-q-1:s.end-q; if (r != Z_OK){ mode = r == Z_STREAM_END ? WASH : BADCODE; break; } } need = lbits; tree = ltree; tree_index=ltree_index; mode = LEN; goto case LEN; case LEN: // i: get length/literal/eob next j = need; while(k<(j)){ if(n!=0)r=Z_OK; else{ s.bitb=b;s.bitk=k; z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; s.write=q; return s.inflate_flush(z,r); } n--; b|=(z.next_in[p++]&0xff)<<k; k+=8; } tindex=(tree_index+(b&inflate_mask[j]))*3; b>>=(tree[tindex+1]); k-=(tree[tindex+1]); e=tree[tindex]; if(e == 0){ // literal lit = tree[tindex+2]; mode = LIT; break; } if((e & 16)!=0 ){ // length get = e & 15; len = tree[tindex+2]; mode = LENEXT; break; } if ((e & 64) == 0){ // next table need = e; tree_index = tindex/3+tree[tindex+2]; break; } if ((e & 32)!=0){ // end of block mode = WASH; break; } mode = BADCODE; // invalid code z.msg = "invalid literal/length code"; r = Z_DATA_ERROR; s.bitb=b;s.bitk=k; z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; s.write=q; return s.inflate_flush(z,r); case LENEXT: // i: getting length extra (have base) j = get; while(k<(j)){ if(n!=0)r=Z_OK; else{ s.bitb=b;s.bitk=k; z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; s.write=q; return s.inflate_flush(z,r); } n--; b|=(z.next_in[p++]&0xff)<<k; k+=8; } len += (b & inflate_mask[j]); b>>=j; k-=j; need = dbits; tree = dtree; tree_index=dtree_index; mode = DIST; goto case DIST; case DIST: // i: get distance next j = need; while(k<(j)){ if(n!=0)r=Z_OK; else{ s.bitb=b;s.bitk=k; z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; s.write=q; return s.inflate_flush(z,r); } n--; b|=(z.next_in[p++]&0xff)<<k; k+=8; } tindex=(tree_index+(b & inflate_mask[j]))*3; b>>=tree[tindex+1]; k-=tree[tindex+1]; e = (tree[tindex]); if((e & 16)!=0){ // distance get = e & 15; dist = tree[tindex+2]; mode = DISTEXT; break; } if ((e & 64) == 0){ // next table need = e; tree_index = tindex/3 + tree[tindex+2]; break; } mode = BADCODE; // invalid code z.msg = "invalid distance code"; r = Z_DATA_ERROR; s.bitb=b;s.bitk=k; z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; s.write=q; return s.inflate_flush(z,r); case DISTEXT: // i: getting distance extra j = get; while(k<(j)){ if(n!=0)r=Z_OK; else{ s.bitb=b;s.bitk=k; z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; s.write=q; return s.inflate_flush(z,r); } n--; b|=(z.next_in[p++]&0xff)<<k; k+=8; } dist += (b & inflate_mask[j]); b>>=j; k-=j; mode = COPY; goto case COPY; case COPY: // o: copying bytes in window, waiting for space f = q - dist; while(f < 0){ // modulo window size-"while" instead f += s.end; // of "if" handles invalid distances } while (len!=0){ if(m==0){ if(q==s.end&&s.read!=0){q=0;m=q<s.read?s.read-q-1:s.end-q;} if(m==0){ s.write=q; r=s.inflate_flush(z,r); q=s.write;m=q<s.read?s.read-q-1:s.end-q; if(q==s.end&&s.read!=0){q=0;m=q<s.read?s.read-q-1:s.end-q;} if(m==0){ s.bitb=b;s.bitk=k; z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; s.write=q; return s.inflate_flush(z,r); } } } s.window[q++]=s.window[f++]; m--; if (f == s.end) f = 0; len--; } mode = START; break; case LIT: // o: got literal, waiting for output space if(m==0){ if(q==s.end&&s.read!=0){q=0;m=q<s.read?s.read-q-1:s.end-q;} if(m==0){ s.write=q; r=s.inflate_flush(z,r); q=s.write;m=q<s.read?s.read-q-1:s.end-q; if(q==s.end&&s.read!=0){q=0;m=q<s.read?s.read-q-1:s.end-q;} if(m==0){ s.bitb=b;s.bitk=k; z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; s.write=q; return s.inflate_flush(z,r); } } } r=Z_OK; s.window[q++]=(byte)lit; m--; mode = START; break; case WASH: // o: got eob, possibly more output if (k > 7){ // return unused byte, if any k -= 8; n++; p--; // can always return one } s.write=q; r=s.inflate_flush(z,r); q=s.write;m=q<s.read?s.read-q-1:s.end-q; if (s.read != s.write){ s.bitb=b;s.bitk=k; z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; s.write=q; return s.inflate_flush(z,r); } mode = END; goto case END; case END: r = Z_STREAM_END; s.bitb=b;s.bitk=k; z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; s.write=q; return s.inflate_flush(z,r); case BADCODE: // x: got error r = Z_DATA_ERROR; s.bitb=b;s.bitk=k; z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; s.write=q; return s.inflate_flush(z,r); default: r = Z_STREAM_ERROR; s.bitb=b;s.bitk=k; z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; s.write=q; return s.inflate_flush(z,r); } } }
public static PhpString gzencode(byte[] data, int level = -1, int encoding_mode = FORCE_GZIP) { if ((level < -1) || (level > 9)) { PhpException.Throw(PhpError.Warning, "compression level ({0}) must be within -1..9", level.ToString()); return(default(PhpString)); } ZStream zs = new ZStream(); int status = zlibConst.Z_OK; zs.next_in = data; zs.avail_in = data.Length; // heuristic for max data length zs.avail_out = data.Length + data.Length / Zlib.PHP_ZLIB_MODIFIER + 15 + 1; zs.next_out = new byte[zs.avail_out]; switch (encoding_mode) { case (int)ForceConstants.FORCE_GZIP: if ((status = zs.deflateInit(level, -MAX_WBITS)) != zlibConst.Z_OK) { PhpException.Throw(PhpError.Warning, zError(status)); return(default(PhpString)); } break; case (int)ForceConstants.FORCE_DEFLATE: if ((status = zs.deflateInit(level)) != zlibConst.Z_OK) { PhpException.Throw(PhpError.Warning, zError(status)); return(default(PhpString)); } break; } status = zs.deflate(zlibConst.Z_FINISH); if (status != zlibConst.Z_STREAM_END) { zs.deflateEnd(); if (status == zlibConst.Z_OK) { status = zlibConst.Z_STREAM_ERROR; } } else { status = zs.deflateEnd(); } if (status == zlibConst.Z_OK) { long output_length = zs.total_out + (encoding_mode == (int)ForceConstants.FORCE_GZIP ? GZIP_HEADER_LENGTH + GZIP_FOOTER_LENGTH : GZIP_HEADER_LENGTH); long output_offset = GZIP_HEADER_LENGTH; byte[] output = new byte[output_length]; Buffer.BlockCopy(zs.next_out, 0, output, (int)output_offset, (int)zs.total_out); // fill the header output[0] = GZIP_HEADER[0]; output[1] = GZIP_HEADER[1]; output[2] = Z_DEFLATED; // zlib constant (private in ZLIB.NET) output[3] = 0; // reserved flag bits (this function puts invalid flags in here) // 4-8 represent time and are set to zero output[9] = OS_CODE; // php constant if (encoding_mode == (int)ForceConstants.FORCE_GZIP) { var crc_algo = new PhpHash.HashPhpResource.CRC32(); byte[] crc = crc_algo.ComputeHash(data); crc_algo.Dispose(); output[output_length - 8] = crc[0]; output[output_length - 7] = crc[1]; output[output_length - 6] = crc[2]; output[output_length - 5] = crc[3]; output[output_length - 4] = (byte)(zs.total_in & 0xFF); output[output_length - 3] = (byte)((zs.total_in >> 8) & 0xFF); output[output_length - 2] = (byte)((zs.total_in >> 16) & 0xFF); output[output_length - 1] = (byte)((zs.total_in >> 24) & 0xFF); } return(new PhpString(output)); } else { PhpException.Throw(PhpError.Warning, zError(status) ?? zs.msg); return(default(PhpString)); } }
public static extern int inflateEnd(ref ZStream stream);
/// <summary> /// Get the data of the entry linked by the specified path. /// All the data will be allocated in memory. It may fail. /// /// Return false if the entry does not exist. /// </summary> public Boolean GetEntryData(String Path, Byte **pData, Int32 *pLength) { *pData = null; if (Path.StartsWith("/") || Path.StartsWith("\\")) { return(false); } Entry Entry; lock (Entries) { if (!Entries.TryGetValue(Path.ToLowerInvariant().Replace('\\', '/'), out Entry)) { return(false); } } *pData = (Byte *)Kernel.malloc((Int32)Entry.UncompressedSize); *pLength = (Int32)Entry.UncompressedSize; using (var Input = new FileStream(TpdFile.GetFilename(), FileMode.Open, FileAccess.Read, FileShare.Read)) { var Buffer = new Byte[Kernel.MAX_BUFFER_SIZE]; var Tmp = new Byte[Kernel.MAX_BUFFER_SIZE]; var Pos = 0; Input.Seek(Entry.Offset, SeekOrigin.Begin); { var Stream = new ZStream(); Stream.inflateInit(); var Result = 0; var Length = 0; do { Stream.avail_in = Input.Read(Buffer, 0, Kernel.MAX_BUFFER_SIZE); Stream.next_in = Buffer; Stream.next_in_index = 0; if (Stream.avail_in == 0) { break; } do { Stream.avail_out = Kernel.MAX_BUFFER_SIZE; Stream.next_out = Tmp; Stream.next_out_index = 0; Result = Stream.inflate(zlibConst.Z_NO_FLUSH); Length = Kernel.MAX_BUFFER_SIZE - Stream.avail_out; Kernel.memcpy((*pData) + Pos, Tmp, Length); Pos += Length; }while (Stream.avail_out == 0); }while (Result != zlibConst.Z_STREAM_END); Stream.inflateEnd(); } } return(true); }
private static extern int inflateInit2_(ref ZStream stream , int windowBits , string version , int streamSize);
/// <summary> /// Get the data of the entry linked by the specified path. /// All the data will be allocated in memory. It may fail. /// /// Return false if the entry does not exist. /// </summary> public Boolean GetEntryData(String Path, out Byte[] Data) { Data = null; if (Path.StartsWith("/") || Path.StartsWith("\\")) { return(false); } Entry Entry; lock (Entries) { if (!Entries.TryGetValue(Path.ToLowerInvariant().Replace('\\', '/'), out Entry)) { return(false); } } Data = new Byte[(Int32)Entry.UncompressedSize]; using (FileStream Input = new FileStream(TpdFile.GetFilename(), FileMode.Open, FileAccess.Read, FileShare.Read)) { Byte[] Buffer = new Byte[Kernel.MAX_BUFFER_SIZE]; Byte[] Tmp = new Byte[Kernel.MAX_BUFFER_SIZE]; Int32 Pos = 0; Input.Seek(Entry.Offset, SeekOrigin.Begin); { ZStream Stream = new ZStream(); Stream.inflateInit(); Int32 Result = 0; Int32 Length = 0; do { Stream.avail_in = Input.Read(Buffer, 0, Kernel.MAX_BUFFER_SIZE); Stream.next_in = Buffer; Stream.next_in_index = 0; if (Stream.avail_in == 0) { break; } do { Stream.avail_out = Kernel.MAX_BUFFER_SIZE; Stream.next_out = Tmp; Stream.next_out_index = 0; Result = Stream.inflate(zlibConst.Z_NO_FLUSH); Length = Kernel.MAX_BUFFER_SIZE - Stream.avail_out; Array.Copy(Tmp, 0, Data, Pos, Length); Pos += Length; }while (Stream.avail_out == 0); }while (Result != zlibConst.Z_STREAM_END); Stream.inflateEnd(); } } return(true); }