1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.mina.util.byteaccess;
21
22 import static org.easymock.EasyMock.createStrictControl;
23
24 import java.nio.ByteOrder;
25 import java.util.ArrayList;
26 import java.util.List;
27
28 import junit.framework.TestCase;
29
30 import org.apache.mina.core.buffer.IoBuffer;
31 import org.apache.mina.util.byteaccess.ByteArray.Cursor;
32 import org.apache.mina.util.byteaccess.CompositeByteArray.CursorListener;
33 import org.apache.mina.util.byteaccess.CompositeByteArrayRelativeWriter.ChunkedExpander;
34 import org.apache.mina.util.byteaccess.CompositeByteArrayRelativeWriter.Flusher;
35 import org.easymock.IMocksControl;
36
37
38
39
40
41
42
43 public class ByteAccessTest extends TestCase {
44
45 private List<String> operations = new ArrayList<String>();
46
47 private void resetOperations() {
48 operations.clear();
49 }
50
51 private void assertOperationCountEquals(int expectedCount) {
52 assertEquals("Operations: " + operations, expectedCount, operations.size());
53 }
54
55 private void addOperation(String description) {
56 operations.add(description);
57 }
58
59 public void testBufferByteArray() throws Exception {
60 ByteArray ba = getByteArrayFactory().create(1000);
61 testAbsoluteReaderAndWriter(0, 1000, ba, ba);
62 testAbsoluteReaderAndWriter(0, 1000, ba, ba);
63 Cursor readCursor = ba.cursor();
64 Cursor writeCursor = ba.cursor();
65 testRelativeReaderAndWriter(1000, readCursor, writeCursor);
66 }
67
68 public void testCompositeAddAndRemove() throws Exception {
69 CompositeByteArray cba = new CompositeByteArray();
70 assertEquals(0, cba.first());
71 assertEquals(0, cba.last());
72 cba.addFirst(getByteArrayFactory().create(100));
73 assertEquals(-100, cba.first());
74 assertEquals(0, cba.last());
75 cba.addFirst(getByteArrayFactory().create(100));
76 assertEquals(-200, cba.first());
77 assertEquals(0, cba.last());
78 cba.addLast(getByteArrayFactory().create(100));
79 assertEquals(-200, cba.first());
80 assertEquals(100, cba.last());
81 cba.removeFirst();
82 assertEquals(-100, cba.first());
83 assertEquals(100, cba.last());
84 cba.addLast(getByteArrayFactory().create(100));
85 assertEquals(-100, cba.first());
86 assertEquals(200, cba.last());
87 cba.removeLast();
88 assertEquals(-100, cba.first());
89 assertEquals(100, cba.last());
90 cba.removeFirst();
91 assertEquals(0, cba.first());
92 assertEquals(100, cba.last());
93 cba.removeFirst();
94 assertEquals(100, cba.first());
95 assertEquals(100, cba.last());
96 cba.addLast(getByteArrayFactory().create(100));
97 assertEquals(100, cba.first());
98 assertEquals(200, cba.last());
99 }
100
101 private BufferByteArray wrapString(String string) {
102 byte[] bytes = string.getBytes();
103 IoBuffer bb = IoBuffer.wrap(bytes);
104 BufferByteArray ba = new BufferByteArray(bb) {
105
106 @Override
107 public void free() {
108 addOperation(this + ".free()");
109
110 }
111
112 };
113 return ba;
114 }
115
116 private String toString(ByteArray ba) {
117 IoBuffer bb = IoBuffer.allocate(ba.length());
118 ba.get(0, bb);
119 byte[] bytes = bb.array();
120 String string = new String(bytes);
121 return string;
122 }
123
124 public void testCompositeStringJoin() throws Exception {
125 ByteArray ba1 = wrapString("Hello");
126 ByteArray ba2 = wrapString("MINA");
127 ByteArray ba3 = wrapString("World");
128
129 CompositeByteArray cba = new CompositeByteArray();
130 cba.addLast(ba1);
131 cba.addLast(ba2);
132 cba.addLast(ba3);
133
134 assertEquals("HelloMINAWorld", toString(cba));
135 }
136
137 public void testCompositeCursor() throws Exception {
138 IMocksControl mc = createStrictControl();
139
140 ByteArray ba1 = getByteArrayFactory().create(10);
141 ByteArray ba2 = getByteArrayFactory().create(10);
142 ByteArray ba3 = getByteArrayFactory().create(10);
143
144
145 CompositeByteArray cba = new CompositeByteArray();
146 cba.addLast(ba1);
147 cba.addLast(ba2);
148 cba.addLast(ba3);
149
150 CursorListener cl = mc.createMock(CursorListener.class);
151
152 mc.reset();
153 mc.replay();
154 Cursor cursor = cba.cursor(cl);
155 mc.verify();
156
157 mc.reset();
158 cl.enteredFirstComponent(0, ba1);
159 mc.replay();
160 cursor.get();
161 mc.verify();
162
163 mc.reset();
164 mc.replay();
165 cursor.setIndex(10);
166 mc.verify();
167
168 mc.reset();
169 cl.enteredNextComponent(10, ba2);
170 mc.replay();
171 cursor.put((byte) 55);
172 mc.verify();
173
174 mc.reset();
175 mc.replay();
176 cursor.setIndex(9);
177 mc.verify();
178
179 mc.reset();
180 cl.enteredPreviousComponent(0, ba1);
181 cl.enteredNextComponent(10, ba2);
182 mc.replay();
183 cursor.putInt(66);
184 mc.verify();
185
186 mc.reset();
187 cl.enteredNextComponent(20, ba3);
188 mc.replay();
189 cursor.setIndex(29);
190 cursor.get();
191 mc.verify();
192
193 cba.removeLast();
194
195 mc.reset();
196 cl.enteredLastComponent(10, ba2);
197 mc.replay();
198 cursor.setIndex(15);
199 cursor.get();
200 mc.verify();
201
202 mc.reset();
203 cl.enteredPreviousComponent(0, ba1);
204 mc.replay();
205 cursor.setIndex(0);
206 cursor.get();
207 mc.verify();
208 }
209
210 public void testCompositeByteArray() throws Exception {
211 CompositeByteArray ba = new CompositeByteArray();
212 for (int i = 0; i < 1000; i += 100) {
213 ba.addLast(getByteArrayFactory().create(100));
214 }
215 resetOperations();
216 testAbsoluteReaderAndWriter(0, 1000, ba, ba);
217 testAbsoluteReaderAndWriter(0, 1000, ba, ba);
218 assertOperationCountEquals(0);
219 Cursor readCursor = ba.cursor();
220 Cursor writeCursor = ba.cursor();
221 testRelativeReaderAndWriter(1000, readCursor, writeCursor);
222 assertOperationCountEquals(0);
223 }
224
225 public void testCompositeByteArrayRelativeReaderAndWriter() throws Exception {
226 CompositeByteArray cba = new CompositeByteArray();
227 CompositeByteArrayRelativeReader cbarr = new CompositeByteArrayRelativeReader(cba, true);
228 CompositeByteArrayRelativeWriter cbarw = new CompositeByteArrayRelativeWriter(cba, getExpander(100), getFlusher(), false);
229 resetOperations();
230 testRelativeReaderAndWriter(10, cbarr, cbarw);
231 assertOperationCountEquals(2);
232 resetOperations();
233 testRelativeReaderAndWriter(100, cbarr, cbarw);
234 assertOperationCountEquals(3);
235 resetOperations();
236 testRelativeReaderAndWriter(1000, cbarr, cbarw);
237 assertOperationCountEquals(30);
238 resetOperations();
239 testRelativeReaderAndWriter(10000, cbarr, cbarw);
240 assertOperationCountEquals(300);
241 resetOperations();
242 testRelativeReaderAndWriter(90, cbarr, cbarw);
243 assertOperationCountEquals(0);
244 }
245
246 public void testCompositeByteArrayRelativeReaderAndWriterWithFlush() throws Exception {
247 CompositeByteArray cba = new CompositeByteArray();
248 CompositeByteArrayRelativeReader cbarr = new CompositeByteArrayRelativeReader(cba, true);
249 CompositeByteArrayRelativeWriter cbarw = new CompositeByteArrayRelativeWriter(cba, getExpander(100), getFlusher(), true);
250 resetOperations();
251 testRelativeReaderAndWriter(10, cbarr, cbarw);
252 assertOperationCountEquals(2);
253 resetOperations();
254 testRelativeReaderAndWriter(100, cbarr, cbarw);
255 assertOperationCountEquals(4);
256 resetOperations();
257 testRelativeReaderAndWriter(1000, cbarr, cbarw);
258 assertOperationCountEquals(40);
259 resetOperations();
260 testRelativeReaderAndWriter(10000, cbarr, cbarw);
261 assertOperationCountEquals(400);
262 resetOperations();
263 testRelativeReaderAndWriter(90, cbarr, cbarw);
264 assertOperationCountEquals(0);
265 }
266
267 public void testCompositeRemoveTo() throws Exception {
268 CompositeByteArray cba = new CompositeByteArray();
269 {
270
271 resetOperations();
272 ByteArray removed = cba.removeTo(0);
273 assertEquals(0, removed.first());
274 assertEquals(0, removed.last());
275 assertEquals(0, cba.first());
276 assertEquals(0, cba.last());
277 removed.free();
278 assertOperationCountEquals(0);
279 }
280 cba.addLast(getByteArrayFactory().create(100));
281 {
282
283 resetOperations();
284 ByteArray removed = cba.removeTo(0);
285 assertEquals(0, removed.first());
286 assertEquals(0, removed.last());
287 assertEquals(0, cba.first());
288 assertEquals(100, cba.last());
289 removed.free();
290 assertOperationCountEquals(0);
291 }
292 {
293
294 resetOperations();
295 ByteArray removed = cba.removeTo(100);
296 assertEquals(0, removed.first());
297 assertEquals(100, removed.last());
298 assertEquals(100, cba.first());
299 assertEquals(100, cba.last());
300 removed.free();
301 assertOperationCountEquals(1);
302 }
303 {
304
305 resetOperations();
306 ByteArray removed = cba.removeTo(100);
307 assertEquals(0, removed.first());
308 assertEquals(0, removed.last());
309 assertEquals(100, cba.first());
310 assertEquals(100, cba.last());
311 removed.free();
312 assertOperationCountEquals(0);
313 }
314 cba.addLast(getByteArrayFactory().create(100));
315 {
316
317 resetOperations();
318 ByteArray removed = cba.removeTo(100);
319 assertEquals(0, removed.first());
320 assertEquals(0, removed.last());
321 assertEquals(100, cba.first());
322 assertEquals(200, cba.last());
323 removed.free();
324 assertOperationCountEquals(0);
325 }
326 {
327
328 resetOperations();
329 ByteArray removed = cba.removeTo(150);
330 assertEquals(0, removed.first());
331 assertEquals(50, removed.last());
332 assertEquals(150, cba.first());
333 assertEquals(200, cba.last());
334 removed.free();
335 assertOperationCountEquals(0);
336 }
337 {
338
339 resetOperations();
340 ByteArray removed = cba.removeTo(150);
341 assertEquals(0, removed.first());
342 assertEquals(0, removed.last());
343 assertEquals(150, cba.first());
344 assertEquals(200, cba.last());
345 removed.free();
346 assertOperationCountEquals(0);
347 }
348 {
349
350 resetOperations();
351 ByteArray removed = cba.removeTo(200);
352 assertEquals(0, removed.first());
353 assertEquals(50, removed.last());
354 assertEquals(200, cba.first());
355 assertEquals(200, cba.last());
356 removed.free();
357 assertOperationCountEquals(1);
358 }
359 }
360
361 public void testCompositeByteArraySlicing() {
362 CompositeByteArray cba = new CompositeByteArray();
363 cba.addLast(getByteArrayFactory().create(10));
364 cba.addLast(getByteArrayFactory().create(10));
365 cba.addLast(getByteArrayFactory().create(10));
366 testByteArraySlicing(cba, 0, 30);
367 testByteArraySlicing(cba, 5, 10);
368 testByteArraySlicing(cba, 10, 20);
369 testByteArraySlicing(cba, 1, 28);
370 testByteArraySlicing(cba, 19, 2);
371 }
372
373 public void testBufferByteArraySlicing() {
374 ByteArray bba = getByteArrayFactory().create(30);
375 testByteArraySlicing(bba, 0, 30);
376 testByteArraySlicing(bba, 5, 10);
377 testByteArraySlicing(bba, 10, 20);
378 testByteArraySlicing(bba, 1, 28);
379 testByteArraySlicing(bba, 19, 2);
380
381 }
382
383 private void testByteArraySlicing(ByteArray ba, int start, int length) {
384 ByteArray slice = ba.slice(start, length);
385 for (int i = 0; i < length; i++) {
386 byte b1 = (byte) (i % 67);
387 byte b2 = (byte) (i % 36);
388 int sourceIndex = i + start;
389 int sliceIndex = i;
390 ba.put(sourceIndex, b1);
391 assertEquals(b1, ba.get(sourceIndex));
392 assertEquals(b1, slice.get(sliceIndex));
393 slice.put(sliceIndex, b2);
394 assertEquals(b2, ba.get(sourceIndex));
395 assertEquals(b2, slice.get(sliceIndex));
396 }
397 }
398
399 private ChunkedExpander getExpander(final int chunkSize) {
400 return new ChunkedExpander(getByteArrayFactory(), chunkSize) {
401 @Override
402 public void expand(CompositeByteArray cba, int minSize) {
403 addOperation("ChunkedExpander(" + chunkSize + ").expand(" + cba + "," + minSize + ")");
404 super.expand(cba, minSize);
405 }
406 };
407 }
408
409 private Flusher getFlusher() {
410 return new CompositeByteArrayRelativeWriter.Flusher() {
411
412 public void flush(ByteArray ba) {
413 addOperation("Flusher().flush(" + ba + ")");
414 ba.free();
415 }
416
417 };
418 }
419
420 private SimpleByteArrayFactory getByteArrayFactory() {
421 return new SimpleByteArrayFactory() {
422 @Override
423 public ByteArray create(final int size) {
424 if (size < 0) {
425 throw new IllegalArgumentException(
426 "Buffer size must not be negative:" + size);
427 }
428 IoBuffer bb = IoBuffer.allocate(size);
429 ByteArray ba = new BufferByteArray(bb) {
430
431 @Override
432 public void free() {
433 addOperation(this + ".free()");
434
435 }
436
437 };
438 addOperation("SimpleByteArrayFactory().create(" + size + ") = " + ba);
439 return ba;
440 }
441 };
442 }
443
444 private void testRelativeReaderAndWriter(int length, IoRelativeReader reader, IoRelativeWriter writer) {
445 for (int i = 0; i < length; i++) {
446 byte b = (byte) (i % 67);
447 writer.put(b);
448 assertEquals(b, reader.get());
449 }
450 }
451
452 private void testAbsoluteReaderAndWriter(int start, int length, IoAbsoluteReader reader, IoAbsoluteWriter writer) {
453 for (int i = start; i < length; i++) {
454 byte b = (byte) (i % 67);
455 writer.put(i, b);
456 assertEquals(b, reader.get(i));
457 }
458 }
459
460 public void testByteArrayPrimitiveAccess() {
461 ByteArray bbaBig = getByteArrayFactory().create(1000);
462 bbaBig.order(ByteOrder.BIG_ENDIAN);
463 testPrimitiveAccess(bbaBig.cursor(), bbaBig.cursor());
464
465 ByteArray bbaLittle = getByteArrayFactory().create(1000);
466 bbaLittle.order(ByteOrder.LITTLE_ENDIAN);
467 testPrimitiveAccess(bbaLittle.cursor(), bbaLittle.cursor());
468 }
469
470 public void testByteArrayBufferAccess() {
471 ByteArray ba = getByteArrayFactory().create(1);
472 ba.put(0, (byte) 99);
473 IoBuffer bb = IoBuffer.allocate(2);
474
475 bb.clear();
476 Cursor cursor = ba.cursor();
477 assertEquals(0, cursor.getIndex());
478 assertEquals(1, cursor.getRemaining());
479 assertEquals(0, bb.position());
480 assertEquals(2, bb.remaining());
481 cursor.get(bb);
482 assertEquals(1, cursor.getIndex());
483 assertEquals(0, cursor.getRemaining());
484 assertEquals(1, bb.position());
485 assertEquals(1, bb.remaining());
486 }
487
488 public void testCompositeByteArrayPrimitiveAccess() {
489 CompositeByteArray cbaBig = new CompositeByteArray();
490 cbaBig.order(ByteOrder.BIG_ENDIAN);
491 for (int i = 0; i < 1000; i++) {
492 ByteArray component = getByteArrayFactory().create(1);
493 component.order(ByteOrder.BIG_ENDIAN);
494 cbaBig.addLast(component);
495 }
496 testPrimitiveAccess(cbaBig.cursor(), cbaBig.cursor());
497
498 CompositeByteArray cbaLittle = new CompositeByteArray();
499 cbaLittle.order(ByteOrder.LITTLE_ENDIAN);
500 for (int i = 0; i < 1000; i++) {
501 ByteArray component = getByteArrayFactory().create(1);
502 component.order(ByteOrder.LITTLE_ENDIAN);
503 cbaLittle.addLast(component);
504 }
505 testPrimitiveAccess(cbaLittle.cursor(), cbaLittle.cursor());
506 }
507
508 public void testCompositeByteArrayWrapperPrimitiveAccess() {
509 CompositeByteArray cbaBig = new CompositeByteArray();
510 cbaBig.order(ByteOrder.BIG_ENDIAN);
511 for (int i = 0; i < 1000; i++) {
512 ByteArray component = getByteArrayFactory().create(1);
513 component.order(ByteOrder.BIG_ENDIAN);
514 cbaBig.addLast(component);
515 }
516 testPrimitiveAccess(new CompositeByteArrayRelativeWriter(cbaBig, getExpander(10), getFlusher(), false), new CompositeByteArrayRelativeReader(cbaBig, true));
517
518 CompositeByteArray cbaLittle = new CompositeByteArray();
519 cbaLittle.order(ByteOrder.LITTLE_ENDIAN);
520 for (int i = 0; i < 1000; i++) {
521 ByteArray component = getByteArrayFactory().create(1);
522 component.order(ByteOrder.LITTLE_ENDIAN);
523 cbaLittle.addLast(component);
524 }
525 testPrimitiveAccess(new CompositeByteArrayRelativeWriter(cbaLittle, getExpander(10), getFlusher(), false), new CompositeByteArrayRelativeReader(cbaLittle, true));
526 }
527
528 private void testPrimitiveAccess(IoRelativeWriter write, IoRelativeReader read) {
529 byte b = (byte) 0x12;
530 write.put(b);
531 assertEquals(b, read.get());
532
533 short s = (short) 0x12;
534 write.putShort(s);
535 assertEquals(s, read.getShort());
536
537 int i = 0x12345678;
538 write.putInt(i);
539 assertEquals(i, read.getInt());
540
541 long l = 0x1234567890123456L;
542 write.putLong(l);
543 assertEquals(l, read.getLong());
544
545 float f = Float.intBitsToFloat(i);
546 write.putFloat(f);
547 assertEquals(f, read.getFloat());
548
549 double d = Double.longBitsToDouble(l);
550 write.putDouble(d);
551 assertEquals(d, read.getDouble());
552
553 char c = (char) 0x1234;
554 write.putChar(c);
555 assertEquals(c, read.getChar());
556 }
557
558 }