public SpdyHeaderBlockJZlibEncoder( SpdyVersion version, int compressionLevel, int windowBits, int memLevel) { super(version); if (compressionLevel < 0 || compressionLevel > 9) { throw new IllegalArgumentException( "compressionLevel: " + compressionLevel + " (expected: 0-9)"); } if (windowBits < 9 || windowBits > 15) { throw new IllegalArgumentException("windowBits: " + windowBits + " (expected: 9-15)"); } if (memLevel < 1 || memLevel > 9) { throw new IllegalArgumentException("memLevel: " + memLevel + " (expected: 1-9)"); } int resultCode = z.deflateInit(compressionLevel, windowBits, memLevel, JZlib.W_ZLIB); if (resultCode != JZlib.Z_OK) { throw new CompressionException( "failed to initialize an SPDY header block deflater: " + resultCode); } else { resultCode = z.deflateSetDictionary(SPDY_DICT, SPDY_DICT.length); if (resultCode != JZlib.Z_OK) { throw new CompressionException("failed to set the SPDY dictionary: " + resultCode); } } }
private void setInput(ByteBuf decompressed) { byte[] in = new byte[decompressed.readableBytes()]; decompressed.readBytes(in); z.next_in = in; z.next_in_index = 0; z.avail_in = in.length; }
@Override public void end() { if (finished) { return; } finished = true; z.deflateEnd(); z.next_in = null; z.next_out = null; }
private void encode(ByteBuf compressed) { try { byte[] out = new byte[(int) Math.ceil(z.next_in.length * 1.001) + 12]; z.next_out = out; z.next_out_index = 0; z.avail_out = out.length; int resultCode = z.deflate(JZlib.Z_SYNC_FLUSH); if (resultCode != JZlib.Z_OK) { throw new CompressionException("compression failure: " + resultCode); } if (z.next_out_index != 0) { compressed.writeBytes(out, 0, z.next_out_index); } } finally { // Deference the external references explicitly to tell the VM that // the allocated byte arrays are temporary so that the call stack // can be utilized. // I'm not sure if the modern VMs do this optimization though. z.next_in = null; z.next_out = null; } }