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