1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.mina.proxy.utils;
21
22 import org.apache.mina.core.buffer.IoBuffer;
23 import org.apache.mina.filter.codec.textline.LineDelimiter;
24
25
26
27
28
29
30
31
32
33
34 public class IoBufferDecoder {
35
36
37
38
39 public class DecodingContext {
40
41
42
43
44 private IoBuffer decodedBuffer;
45
46
47
48
49 private IoBuffer delimiter;
50
51
52
53
54 private int matchCount = 0;
55
56
57
58
59
60 private int contentLength = -1;
61
62
63
64
65 public void reset() {
66 contentLength = -1;
67 matchCount = 0;
68 decodedBuffer = null;
69 }
70
71
72
73
74
75 public int getContentLength() {
76 return contentLength;
77 }
78
79
80
81
82
83
84 public void setContentLength(int contentLength) {
85 this.contentLength = contentLength;
86 }
87
88
89
90
91 public int getMatchCount() {
92 return matchCount;
93 }
94
95
96
97
98
99
100 public void setMatchCount(int matchCount) {
101 this.matchCount = matchCount;
102 }
103
104
105
106
107 public IoBuffer getDecodedBuffer() {
108 return decodedBuffer;
109 }
110
111
112
113
114
115
116 public void setDecodedBuffer(IoBuffer decodedBuffer) {
117 this.decodedBuffer = decodedBuffer;
118 }
119
120
121
122
123 public IoBuffer getDelimiter() {
124 return delimiter;
125 }
126
127
128
129
130
131
132 public void setDelimiter(IoBuffer delimiter) {
133 this.delimiter = delimiter;
134 }
135 }
136
137
138
139
140 private DecodingContext ctx = new DecodingContext();
141
142
143
144
145
146
147
148 public IoBufferDecoder(byte[] delimiter) {
149 setDelimiter(delimiter, true);
150 }
151
152
153
154
155
156
157 public IoBufferDecoder(int contentLength) {
158 setContentLength(contentLength, false);
159 }
160
161
162
163
164
165
166
167
168
169
170 public void setContentLength(int contentLength, boolean resetMatchCount) {
171 if (contentLength <= 0) {
172 throw new IllegalArgumentException("contentLength: " + contentLength);
173 }
174
175 ctx.setContentLength(contentLength);
176 if (resetMatchCount) {
177 ctx.setMatchCount(0);
178 }
179 }
180
181
182
183
184
185
186
187
188
189
190
191
192 public void setDelimiter(byte[] delim, boolean resetMatchCount) {
193 if (delim == null) {
194 throw new IllegalArgumentException("Null delimiter not allowed");
195 }
196
197
198 IoBuffer delimiter = IoBuffer.allocate(delim.length);
199 delimiter.put(delim);
200 delimiter.flip();
201
202 ctx.setDelimiter(delimiter);
203 ctx.setContentLength(-1);
204 if (resetMatchCount) {
205 ctx.setMatchCount(0);
206 }
207 }
208
209
210
211
212
213
214
215
216
217
218 public IoBuffer./../../../org/apache/mina/core/buffer/IoBuffer.html#IoBuffer">IoBuffer decodeFully(IoBuffer in) {
219 int contentLength = ctx.getContentLength();
220 IoBuffer decodedBuffer = ctx.getDecodedBuffer();
221
222 int oldLimit = in.limit();
223
224
225 if (contentLength > -1) {
226 if (decodedBuffer == null) {
227 decodedBuffer = IoBuffer.allocate(contentLength).setAutoExpand(true);
228 }
229
230
231 if (in.remaining() < contentLength) {
232 int readBytes = in.remaining();
233 decodedBuffer.put(in);
234 ctx.setDecodedBuffer(decodedBuffer);
235 ctx.setContentLength(contentLength - readBytes);
236 return null;
237
238 }
239
240 int newLimit = in.position() + contentLength;
241 in.limit(newLimit);
242 decodedBuffer.put(in);
243 decodedBuffer.flip();
244 in.limit(oldLimit);
245 ctx.reset();
246
247 return decodedBuffer;
248 }
249
250
251 int oldPos = in.position();
252 int matchCount = ctx.getMatchCount();
253 IoBuffer delimiter = ctx.getDelimiter();
254
255 while (in.hasRemaining()) {
256 byte b = in.get();
257
258 if (delimiter.get(matchCount) == b) {
259 matchCount++;
260
261 if (matchCount == delimiter.limit()) {
262
263 int pos = in.position();
264 in.position(oldPos);
265
266 in.limit(pos);
267
268 if (decodedBuffer == null) {
269 decodedBuffer = IoBuffer.allocate(in.remaining()).setAutoExpand(true);
270 }
271
272 decodedBuffer.put(in);
273 decodedBuffer.flip();
274
275 in.limit(oldLimit);
276 ctx.reset();
277
278 return decodedBuffer;
279 }
280 } else {
281 in.position(Math.max(0, in.position() - matchCount));
282 matchCount = 0;
283 }
284 }
285
286
287 if (in.remaining() > 0) {
288 in.position(oldPos);
289 decodedBuffer.put(in);
290 in.position(in.limit());
291 }
292
293
294 ctx.setMatchCount(matchCount);
295 ctx.setDecodedBuffer(decodedBuffer);
296
297 return decodedBuffer;
298 }
299 }