示例#1
0
 public ZOutputStream(System.IO.Stream out_Renamed, int level) : base()
 {
     InitBlock();
     this.out_Renamed = out_Renamed;
     z.deflateInit(level);
     compress = true;
 }
示例#2
0
        public ZlibStream(Stream innerStream)
        {
            _innerStream = innerStream;

            if(_innerStream.CanRead)
            {
                _in = new ZStream();
                int ret = _in.inflateInit();
                if (ret != zlibConst.Z_OK)
                    throw new ZStreamException("Unable to initialize inflate");
                _inBuff = new byte[_buffSize];
                _in.avail_in = 0;
                _in.next_in = _inBuff;
                _in.next_in_index = 0;
            }

            if(_innerStream.CanWrite)
            {
                _out = new ZStream();
                int ret = _out.deflateInit(zlibConst.Z_DEFAULT_COMPRESSION);
                if (ret != zlibConst.Z_OK)
                    throw new ZStreamException("Unable to initialize deflate");
                _outBuff = new byte[_buffSize];
                _out.next_out = _outBuff;
            }
        }
示例#3
0
 public ZInputStream(System.IO.Stream in_Renamed, int level) : base(in_Renamed)
 {
     InitBlock();
     this.in_Renamed = in_Renamed;
     z.deflateInit(level);
     compress        = true;
     z.next_in       = buf;
     z.next_in_index = 0;
     z.avail_in      = 0;
 }
示例#4
0
            IEnumerable<WebSocketsFrame> IExtension.ApplyOutgoing(NetContext context, WebSocketConnection connection, WebSocketsFrame frame)
            {
                if (!frame.IsControlFrame && frame.PayloadLength > parent.compressMessagesLargerThanBytes)
                {
                    if (frame.Reserved1)
                    {
                        throw new InvalidOperationException("Reserved1 flag is already set; extension conflict?");
                    }

                    int headerBytes = 0;
                    if (outbound == null)
                    {
                        outbound = new ZStream();
                        const int BITS = 12; // 4096 byte outbound buffer (instead of full 32k=15)
                        outbound.deflateInit(zlibConst.Z_BEST_COMPRESSION, BITS);
                        headerBytes = 2;
                    }
                    BufferStream tmp = null;
                    var payload = frame.Payload;
                    payload.Position = 0;
                    byte[] inBuffer = null, outBuffer = null;
                    try
                    {
                        inBuffer = context.GetBuffer();
                        outBuffer = context.GetBuffer();
                        tmp = new BufferStream(context, 0);

                        outbound.next_out = outBuffer;
                        outbound.next_in = inBuffer;

                        int remaining = frame.PayloadLength;
                        while (remaining > 0)
                        {
                            int readCount = payload.Read(inBuffer, 0, inBuffer.Length);
                            if (readCount <= 0) break;
                            remaining -= readCount;

                            outbound.next_in_index = 0;
                            outbound.avail_in = readCount;

                            do
                            {
                                outbound.next_out_index = 0;
                                outbound.avail_out = outBuffer.Length;
                                long priorOut = outbound.total_out;
                                int err = outbound.deflate(remaining == 0 ? zlibConst.Z_SYNC_FLUSH : zlibConst.Z_NO_FLUSH);
                                if (err != zlibConst.Z_OK && err != zlibConst.Z_STREAM_END)
                                    throw new ZStreamException("deflating: " + outbound.msg);

                                int outCount = (int)(outbound.total_out - priorOut);
                                if (outCount > 0)
                                {
                                    if (headerBytes == 0)
                                    {
                                        tmp.Write(outBuffer, 0, outCount);
                                    }
                                    else
                                    {
                                        if (outCount < headerBytes)
                                        {
                                            throw new InvalidOperationException("Failed to write entire header");
                                        }
                                        // check the generated header meets our expectations
                                        // CMF is very specific - CM must be 8, and CINFO must be <=7 (for 32k window)
                                        if ((outBuffer[0] & 15) != 8)
                                        {
                                            throw new InvalidOperationException("Zlib CM header was incorrect");
                                        }
                                        if ((outBuffer[0] & 128) != 0) // if msb set, is > 7 - invalid
                                        {
                                            throw new InvalidOperationException("Zlib CINFO header was incorrect");
                                        }

                                        // FLG is less important; FCHECK is irrelevent, FLEVEL doesn't matter; but
                                        // FDICT must be zero, to ensure that we aren't expecting a an initialization dictionary
                                        if ((outBuffer[1] & 32) != 0)
                                        {
                                            throw new InvalidOperationException("Zlib FLG.FDICT header was set (must not be)");
                                        }

                                        // skip the header, and write anything else
                                        outCount -= headerBytes;
                                        if (outCount > 0)
                                        {
                                            tmp.Write(outBuffer, headerBytes, outCount);
                                        }
                                        headerBytes = 0; // all written now
                                    }
                                }
                            } while (outbound.avail_in > 0 || outbound.avail_out == 0);
                        }
                        if (remaining != 0) throw new EndOfStreamException();
                        if (headerBytes != 0) throw new InvalidOperationException("Zlib header was not written");

                        // verify the last 4 bytes, then drop them
                        tmp.Position = tmp.Length - 4;
                        NetContext.Fill(tmp, outBuffer, 4);
                        if (!(outBuffer[0] == 0x00 && outBuffer[1] == 0x00 && outBuffer[2] == 0xFF && outBuffer[3] == 0xFF))
                        {
                            throw new InvalidOperationException("expectation failed: 0000FFFF in the tail");
                        }

                        if (parent.disableContextTakeover && tmp.Length >= frame.PayloadLength)
                        { // compressing it didn't do anything useful; since we're going to discard
                          // the compression context, we might as well stick with the original data
                            payload.Position = 0;
                            payload = null; // so that it doesn't get disposed
                        }
                        else
                        {
                            // set our final output
                            tmp.Position = 0;
                            tmp.SetLength(tmp.Length - 4);
                            long bytesSaved = frame.PayloadLength - tmp.Length;
                            frame.Payload = tmp;
                            frame.PayloadLength = (int)tmp.Length;
                            frame.Reserved1 = true;
                            tmp = payload as BufferStream;
                            parent.RegisterOutboundBytesSaved(bytesSaved);
                        }
                    }
#if DEBUG
                    catch (Exception ex)
                    {
                        Debug.WriteLine(ex);
                        throw;
                    }
#endif
                    finally
                    {
                        if (outbound != null)
                        {
                            outbound.next_out = null;
                            outbound.next_in = null;
                        }
                        if (tmp != null) tmp.Dispose();
                        if (inBuffer != null) context.Recycle(inBuffer);
                        if (outBuffer != null) context.Recycle(outBuffer);
                        if (parent.disableContextTakeover) ClearContext(false, true);
                    }
                }
                yield return frame;
            }
示例#5
0
 protected override int InitZlibOperation(ZStream zs)
 {
     // -MAX_WBITS stands for absense of Zlib header and trailer (needed for GZIP compression and decompression)
     return zs.deflateInit(_level, -Zlib.MAX_WBITS);
 }
示例#6
0
        private void init(Stream innerStream)
        {
            m_stream = innerStream;
            if (m_stream.CanRead)
            {
                m_in = new ZStream();
                int ret = m_in.inflateInit();
                if (ret != zlibConst.Z_OK)
                    throw new CompressionFailedException("Unable to initialize zlib for deflate: " + ret);
                m_inbuf = new byte[bufsize];
                m_in.avail_in = 0;
                m_in.next_in = m_inbuf;
                m_in.next_in_index = 0;
            }

            if (m_stream.CanWrite)
            {
                m_out = new ZStream();
                int ret = m_out.deflateInit(zlibConst.Z_DEFAULT_COMPRESSION);
                if (ret != zlibConst.Z_OK)
                    throw new CompressionFailedException("Unable to initialize zlib for inflate: " + ret);
                m_outbuf = new byte[bufsize];
                m_out.next_out = m_outbuf;
            }
        }
示例#7
0
        public static PhpBytes GzEncode(PhpBytes data, int level, int encoding_mode)
        {
            if ((level < -1) || (level > 9))
            {
                PhpException.Throw(PhpError.Warning, String.Format("compression level ({0}) must be within -1..9", level));
                return null;
            }

            ZStream zs = new ZStream();
            int status = zlibConst.Z_OK;

            zs.next_in = data.ReadonlyData;
            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 null;
			        }
                    break;
                case (int)ForceConstants.FORCE_DEFLATE:
                    if ((status = zs.deflateInit(level)) != zlibConst.Z_OK)
                    {
                        PhpException.Throw(PhpError.Warning, zError(status));
                        return null;
                    }
                    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();
            }

			z_error = zs.msg;

            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 PHP.Library.CRC32();
                    byte[] crc = crc_algo.ComputeHash(data.ReadonlyData, 0, data.Length);
                    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 PhpBytes(output);
            }
            else
            {
                PhpException.Throw(PhpError.Warning, zError(status));
                return null;
            }
        }
示例#8
0
        public static PhpBytes GzDeflate(PhpBytes data, int level)
        {
            if ((level < -1) || (level > 9))
            {
                PhpException.Throw(PhpError.Warning, String.Format("compression level ({0}) must be within -1..9", level));
                return null;
            }

            ZStream zs = new ZStream();

            zs.next_in = data.ReadonlyData;
            zs.avail_in = data.Length;

            // heuristic for max data length
            zs.avail_out = data.Length + data.Length / PHP_ZLIB_MODIFIER + 15 + 1;
            zs.next_out = new byte[zs.avail_out];

            // -15 omits the header (undocumented feature of zlib)
            int status = zs.deflateInit(level, -MAX_WBITS);

            if (status == zlibConst.Z_OK)
            {
                status = zs.deflate(zlibConst.Z_FINISH);
                if (status != zlibConst.Z_STREAM_END)
                {
                    zs.deflateEnd();
                    if (status == zlibConst.Z_OK)
                    {
                        status = zlibConst.Z_BUF_ERROR;
                    }
                }
                else
                {
                    status = zs.deflateEnd();
                }
            }

            if (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 PhpBytes(result);
            }
            else
            {
                PhpException.Throw(PhpError.Warning, zError(status));
                return null;
            }
        }
示例#9
0
        /// <summary>
        /// Reimplements function from zlib (compress2) that is not present in ZLIB.NET.
        /// </summary>
        /// <param name="dest">Destination array of bytes. May be trimmed if necessary.</param>
        /// <param name="source">Source array of bytes.</param>
        /// <param name="level">Level of compression.</param>
        /// <returns>Zlib status code.</returns>
        private static int ZlibCompress(ref byte[] dest, byte[] source, int level)
        {
            ZStream stream = new ZStream();
            int err;

            stream.next_in = source;
            stream.avail_in = source.Length;
            stream.next_out = dest;
            stream.avail_out = dest.Length;

            err = stream.deflateInit(level);
            if (err != zlibConst.Z_OK) return err;

            err = stream.deflate(zlibConst.Z_FINISH);
            if (err != zlibConst.Z_STREAM_END)
            {
                stream.deflateEnd();
                return err == zlibConst.Z_OK ? zlibConst.Z_BUF_ERROR : err;
            }

            if (stream.total_out != dest.Length)
            {
                byte[] output = new byte[stream.total_out];
                Buffer.BlockCopy(stream.next_out, 0, output, 0, (int)stream.total_out);
                dest = output;
            }

            return stream.deflateEnd();
        }