1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.mina.filter.compression;
21
22 import java.io.IOException;
23
24 import org.apache.mina.core.buffer.IoBuffer;
25
26 import com.jcraft.jzlib.JZlib;
27 import com.jcraft.jzlib.ZStream;
28
29
30
31
32
33
34
35
36
37 class Zlib {
38
39 public static final int COMPRESSION_MAX = JZlib.Z_BEST_COMPRESSION;
40
41
42 public static final int COMPRESSION_MIN = JZlib.Z_BEST_SPEED;
43
44
45 public static final int COMPRESSION_NONE = JZlib.Z_NO_COMPRESSION;
46
47
48 public static final int COMPRESSION_DEFAULT = JZlib.Z_DEFAULT_COMPRESSION;
49
50
51 public static final int MODE_DEFLATER = 1;
52
53
54 public static final int MODE_INFLATER = 2;
55
56
57 private int compressionLevel;
58
59
60 private ZStream zStream = null;
61
62
63 private int mode = -1;
64
65
66
67
68
69
70
71
72
73
74
75 public Zlib(int compressionLevel, int mode) {
76 switch (compressionLevel) {
77 case COMPRESSION_MAX:
78 case COMPRESSION_MIN:
79 case COMPRESSION_NONE:
80 case COMPRESSION_DEFAULT:
81 this.compressionLevel = compressionLevel;
82 break;
83 default:
84 throw new IllegalArgumentException(
85 "invalid compression level specified");
86 }
87
88
89 zStream = new ZStream();
90
91 switch (mode) {
92 case MODE_DEFLATER:
93 zStream.deflateInit(this.compressionLevel);
94 break;
95 case MODE_INFLATER:
96 zStream.inflateInit();
97 break;
98 default:
99 throw new IllegalArgumentException("invalid mode specified");
100 }
101 this.mode = mode;
102 }
103
104
105
106
107
108
109
110
111
112
113
114 public IoBuffer inflate(IoBuffer inBuffer) throws IOException {
115 if (mode == MODE_DEFLATER) {
116 throw new IllegalStateException("not initialized as INFLATER");
117 }
118
119 byte[] inBytes = new byte[inBuffer.remaining()];
120 inBuffer.get(inBytes).flip();
121
122
123
124 byte[] outBytes = new byte[inBytes.length * 2];
125 IoBuffer outBuffer = IoBuffer.allocate(outBytes.length);
126 outBuffer.setAutoExpand(true);
127
128 zStream.next_in = inBytes;
129 zStream.next_in_index = 0;
130 zStream.avail_in = inBytes.length;
131 zStream.next_out = outBytes;
132 zStream.next_out_index = 0;
133 zStream.avail_out = outBytes.length;
134 int retval = 0;
135
136 do {
137 retval = zStream.inflate(JZlib.Z_SYNC_FLUSH);
138 switch (retval) {
139 case JZlib.Z_OK:
140
141 case JZlib.Z_BUF_ERROR:
142
143 outBuffer.put(outBytes, 0, zStream.next_out_index);
144 zStream.next_out_index = 0;
145 zStream.avail_out = outBytes.length;
146 break;
147 default:
148
149 outBuffer = null;
150 if (zStream.msg == null) {
151 throw new IOException("Unknown error. Error code : "
152 + retval);
153 } else {
154 throw new IOException("Unknown error. Error code : "
155 + retval + " and message : " + zStream.msg);
156 }
157 }
158 } while (zStream.avail_in > 0);
159
160 return outBuffer.flip();
161 }
162
163
164
165
166
167
168
169
170
171
172 public IoBuffer deflate(IoBuffer inBuffer) throws IOException {
173 if (mode == MODE_INFLATER) {
174 throw new IllegalStateException("not initialized as DEFLATER");
175 }
176
177 byte[] inBytes = new byte[inBuffer.remaining()];
178 inBuffer.get(inBytes).flip();
179
180
181
182
183 int outLen = (int) Math.round(inBytes.length * 1.001) + 1 + 12;
184 byte[] outBytes = new byte[outLen];
185
186 zStream.next_in = inBytes;
187 zStream.next_in_index = 0;
188 zStream.avail_in = inBytes.length;
189 zStream.next_out = outBytes;
190 zStream.next_out_index = 0;
191 zStream.avail_out = outBytes.length;
192
193 int retval = zStream.deflate(JZlib.Z_SYNC_FLUSH);
194 if (retval != JZlib.Z_OK) {
195 outBytes = null;
196 inBytes = null;
197 throw new IOException("Compression failed with return value : "
198 + retval);
199 }
200
201 IoBuffer outBuf = IoBuffer
202 .wrap(outBytes, 0, zStream.next_out_index);
203
204 return outBuf;
205 }
206
207
208
209
210 public void cleanUp() {
211 if (zStream != null) {
212 zStream.free();
213 }
214 }
215 }