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