예제 #1
0
파일: PhpZlib.cs 프로젝트: jiahao42/weverca
        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();
            }

            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);
            }
        }
예제 #2
0
파일: PhpZlib.cs 프로젝트: proff/Phalanger
        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();
            }

            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;
            }
        }