1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.jboss.netty.handler.codec.spdy;
17
18 import static org.jboss.netty.handler.codec.spdy.SpdyCodecUtil.*;
19
20 import org.jboss.netty.buffer.ChannelBuffer;
21 import org.jboss.netty.handler.codec.compression.CompressionException;
22 import org.jboss.netty.util.internal.jzlib.JZlib;
23 import org.jboss.netty.util.internal.jzlib.ZStream;
24
25 class SpdyHeaderBlockJZlibCompressor extends SpdyHeaderBlockCompressor {
26
27 private final ZStream z = new ZStream();
28
29 public SpdyHeaderBlockJZlibCompressor(
30 int version, int compressionLevel, int windowBits, int memLevel) {
31 if (version < SPDY_MIN_VERSION || version > SPDY_MAX_VERSION) {
32 throw new IllegalArgumentException(
33 "unsupported version: " + version);
34 }
35 if (compressionLevel < 0 || compressionLevel > 9) {
36 throw new IllegalArgumentException(
37 "compressionLevel: " + compressionLevel + " (expected: 0-9)");
38 }
39 if (windowBits < 9 || windowBits > 15) {
40 throw new IllegalArgumentException(
41 "windowBits: " + windowBits + " (expected: 9-15)");
42 }
43 if (memLevel < 1 || memLevel > 9) {
44 throw new IllegalArgumentException(
45 "memLevel: " + memLevel + " (expected: 1-9)");
46 }
47
48 int resultCode = z.deflateInit(
49 compressionLevel, windowBits, memLevel, JZlib.W_ZLIB);
50 if (resultCode != JZlib.Z_OK) {
51 throw new CompressionException(
52 "failed to initialize an SPDY header block deflater: " + resultCode);
53 } else {
54 if (version < 3) {
55 resultCode = z.deflateSetDictionary(SPDY2_DICT, SPDY2_DICT.length);
56 } else {
57 resultCode = z.deflateSetDictionary(SPDY_DICT, SPDY_DICT.length);
58 }
59 if (resultCode != JZlib.Z_OK) {
60 throw new CompressionException(
61 "failed to set the SPDY dictionary: " + resultCode);
62 }
63 }
64 }
65
66 @Override
67 public void setInput(ChannelBuffer decompressed) {
68 byte[] in = new byte[decompressed.readableBytes()];
69 decompressed.readBytes(in);
70 z.next_in = in;
71 z.next_in_index = 0;
72 z.avail_in = in.length;
73 }
74
75 @Override
76 public void encode(ChannelBuffer compressed) {
77 try {
78 byte[] out = new byte[(int) Math.ceil(z.next_in.length * 1.001) + 12];
79 z.next_out = out;
80 z.next_out_index = 0;
81 z.avail_out = out.length;
82
83 int resultCode = z.deflate(JZlib.Z_SYNC_FLUSH);
84 if (resultCode != JZlib.Z_OK) {
85 throw new CompressionException("compression failure: " + resultCode);
86 }
87
88 if (z.next_out_index != 0) {
89 compressed.writeBytes(out, 0, z.next_out_index);
90 }
91 } finally {
92
93
94
95
96 z.next_in = null;
97 z.next_out = null;
98 }
99 }
100
101 @Override
102 public void end() {
103 z.deflateEnd();
104 z.next_in = null;
105 z.next_out = null;
106 }
107 }