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