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<>();
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 CompositeByteArray cba = new CompositeByteArray();
148 cba.addLast(ba1);
149 cba.addLast(ba2);
150 cba.addLast(ba3);
151
152 CursorListener cl = mc.createMock(CursorListener.class);
153
154 mc.reset();
155 mc.replay();
156 Cursor cursor = cba.cursor(cl);
157 mc.verify();
158
159 mc.reset();
160 cl.enteredFirstComponent(0, ba1);
161 mc.replay();
162 cursor.get();
163 mc.verify();
164
165 mc.reset();
166 mc.replay();
167 cursor.setIndex(10);
168 mc.verify();
169
170 mc.reset();
171 cl.enteredNextComponent(10, ba2);
172 mc.replay();
173 cursor.put((byte) 55);
174 mc.verify();
175
176 mc.reset();
177 mc.replay();
178 cursor.setIndex(9);
179 mc.verify();
180
181 mc.reset();
182 cl.enteredPreviousComponent(0, ba1);
183 cl.enteredNextComponent(10, ba2);
184 mc.replay();
185 cursor.putInt(66);
186 mc.verify();
187
188 mc.reset();
189 cl.enteredNextComponent(20, ba3);
190 mc.replay();
191 cursor.setIndex(29);
192 cursor.get();
193 mc.verify();
194
195 cba.removeLast();
196
197 mc.reset();
198 cl.enteredLastComponent(10, ba2);
199 mc.replay();
200 cursor.setIndex(15);
201 cursor.get();
202 mc.verify();
203
204 mc.reset();
205 cl.enteredPreviousComponent(0, ba1);
206 mc.replay();
207 cursor.setIndex(0);
208 cursor.get();
209 mc.verify();
210 }
211
212 @Test
213 public void testCompositeByteArray() throws Exception {
214 CompositeByteArray ba = new CompositeByteArray();
215 for (int i = 0; i < 1000; i += 100) {
216 ba.addLast(getByteArrayFactory().create(100));
217 }
218 resetOperations();
219 testAbsoluteReaderAndWriter(0, 1000, ba, ba);
220 testAbsoluteReaderAndWriter(0, 1000, ba, ba);
221 assertOperationCountEquals(0);
222 Cursor readCursor = ba.cursor();
223 Cursor writeCursor = ba.cursor();
224 testRelativeReaderAndWriter(1000, readCursor, writeCursor);
225 assertOperationCountEquals(0);
226 }
227
228 @Test
229 public void testCompositeByteArrayRelativeReaderAndWriter() throws Exception {
230 CompositeByteArray cba = new CompositeByteArray();
231 CompositeByteArrayRelativeReader cbarr = new CompositeByteArrayRelativeReader(cba, true);
232 CompositeByteArrayRelativeWriter cbarw = new CompositeByteArrayRelativeWriter(cba, getExpander(100),
233 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),
256 getFlusher(), true);
257 resetOperations();
258 testRelativeReaderAndWriter(10, cbarr, cbarw);
259 assertOperationCountEquals(2);
260 resetOperations();
261 testRelativeReaderAndWriter(100, cbarr, cbarw);
262 assertOperationCountEquals(4);
263 resetOperations();
264 testRelativeReaderAndWriter(1000, cbarr, cbarw);
265 assertOperationCountEquals(40);
266 resetOperations();
267 testRelativeReaderAndWriter(10000, cbarr, cbarw);
268 assertOperationCountEquals(400);
269 resetOperations();
270 testRelativeReaderAndWriter(90, cbarr, cbarw);
271 assertOperationCountEquals(0);
272 }
273
274 @Test
275 public void testCompositeRemoveTo() throws Exception {
276 CompositeByteArray cba = new CompositeByteArray();
277 {
278
279 resetOperations();
280 ByteArray removed = cba.removeTo(0);
281 assertEquals(0, removed.first());
282 assertEquals(0, removed.last());
283 assertEquals(0, cba.first());
284 assertEquals(0, cba.last());
285 removed.free();
286 assertOperationCountEquals(0);
287 }
288 cba.addLast(getByteArrayFactory().create(100));
289 {
290
291 resetOperations();
292 ByteArray removed = cba.removeTo(0);
293 assertEquals(0, removed.first());
294 assertEquals(0, removed.last());
295 assertEquals(0, cba.first());
296 assertEquals(100, cba.last());
297 removed.free();
298 assertOperationCountEquals(0);
299 }
300 {
301
302 resetOperations();
303 ByteArray removed = cba.removeTo(100);
304 assertEquals(0, removed.first());
305 assertEquals(100, removed.last());
306 assertEquals(100, cba.first());
307 assertEquals(100, cba.last());
308 removed.free();
309 assertOperationCountEquals(1);
310 }
311 {
312
313 resetOperations();
314 ByteArray removed = cba.removeTo(100);
315 assertEquals(0, removed.first());
316 assertEquals(0, removed.last());
317 assertEquals(100, cba.first());
318 assertEquals(100, cba.last());
319 removed.free();
320 assertOperationCountEquals(0);
321 }
322 cba.addLast(getByteArrayFactory().create(100));
323 {
324
325 resetOperations();
326 ByteArray removed = cba.removeTo(100);
327 assertEquals(0, removed.first());
328 assertEquals(0, removed.last());
329 assertEquals(100, cba.first());
330 assertEquals(200, cba.last());
331 removed.free();
332 assertOperationCountEquals(0);
333 }
334 {
335
336 resetOperations();
337 ByteArray removed = cba.removeTo(150);
338 assertEquals(0, removed.first());
339 assertEquals(50, removed.last());
340 assertEquals(150, cba.first());
341 assertEquals(200, cba.last());
342 removed.free();
343 assertOperationCountEquals(0);
344 }
345 {
346
347 resetOperations();
348 ByteArray removed = cba.removeTo(150);
349 assertEquals(0, removed.first());
350 assertEquals(0, removed.last());
351 assertEquals(150, cba.first());
352 assertEquals(200, cba.last());
353 removed.free();
354 assertOperationCountEquals(0);
355 }
356 {
357
358 resetOperations();
359 ByteArray removed = cba.removeTo(200);
360 assertEquals(0, removed.first());
361 assertEquals(50, removed.last());
362 assertEquals(200, cba.first());
363 assertEquals(200, cba.last());
364 removed.free();
365 assertOperationCountEquals(1);
366 }
367 }
368
369 @Test
370 public void testCompositeByteArraySlicing() {
371 CompositeByteArray cba = new CompositeByteArray();
372 cba.addLast(getByteArrayFactory().create(10));
373 cba.addLast(getByteArrayFactory().create(10));
374 cba.addLast(getByteArrayFactory().create(10));
375 testByteArraySlicing(cba, 0, 30);
376 testByteArraySlicing(cba, 5, 10);
377 testByteArraySlicing(cba, 10, 20);
378 testByteArraySlicing(cba, 1, 28);
379 testByteArraySlicing(cba, 19, 2);
380 }
381
382 @Test
383 public void testBufferByteArraySlicing() {
384 ByteArray bba = getByteArrayFactory().create(30);
385 testByteArraySlicing(bba, 0, 30);
386 testByteArraySlicing(bba, 5, 10);
387 testByteArraySlicing(bba, 10, 20);
388 testByteArraySlicing(bba, 1, 28);
389 testByteArraySlicing(bba, 19, 2);
390
391 }
392
393 private void testByteArraySlicing(ByteArray ba, int start, int length) {
394 ByteArray slice = ba.slice(start, length);
395 for (int i = 0; i < length; i++) {
396 byte b1 = (byte) (i % 67);
397 byte b2 = (byte) (i % 36);
398 int sourceIndex = i + start;
399 int sliceIndex = i;
400 ba.put(sourceIndex, b1);
401 assertEquals(b1, ba.get(sourceIndex));
402 assertEquals(b1, slice.get(sliceIndex));
403 slice.put(sliceIndex, b2);
404 assertEquals(b2, ba.get(sourceIndex));
405 assertEquals(b2, slice.get(sliceIndex));
406 }
407 }
408
409 private ChunkedExpander getExpander(final int chunkSize) {
410 return new ChunkedExpander(getByteArrayFactory(), chunkSize) {
411 @Override
412 public void expand(CompositeByteArray cba, int minSize) {
413 addOperation("ChunkedExpander(" + chunkSize + ").expand(" + cba + "," + minSize + ")");
414 super.expand(cba, minSize);
415 }
416 };
417 }
418
419 private Flusher getFlusher() {
420 return new CompositeByteArrayRelativeWriter.Flusher() {
421
422 public void flush(ByteArray ba) {
423 addOperation("Flusher().flush(" + ba + ")");
424 ba.free();
425 }
426
427 };
428 }
429
430 private SimpleByteArrayFactory getByteArrayFactory() {
431 return new SimpleByteArrayFactory() {
432 @Override
433 public ByteArray create(final int size) {
434 if (size < 0) {
435 throw new IllegalArgumentException("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),
530 new CompositeByteArrayRelativeReader(cbaBig, true));
531
532 CompositeByteArray cbaLittle = new CompositeByteArray();
533 cbaLittle.order(ByteOrder.LITTLE_ENDIAN);
534 for (int i = 0; i < 1000; i++) {
535 ByteArray component = getByteArrayFactory().create(1);
536 component.order(ByteOrder.LITTLE_ENDIAN);
537 cbaLittle.addLast(component);
538 }
539 testPrimitiveAccess(new CompositeByteArrayRelativeWriter(cbaLittle, getExpander(10), getFlusher(), false),
540 new CompositeByteArrayRelativeReader(cbaLittle, true));
541 }
542
543 private void testPrimitiveAccess(IoRelativeWriter write, IoRelativeReader read) {
544 byte b = (byte) 0x12;
545 write.put(b);
546 assertEquals(b, read.get());
547
548 short s = (short) 0x12;
549 write.putShort(s);
550 assertEquals(s, read.getShort());
551
552 int i = 0x12345678;
553 write.putInt(i);
554 assertEquals(i, read.getInt());
555
556 long l = 0x1234567890123456L;
557 write.putLong(l);
558 assertEquals(l, read.getLong());
559
560 float f = Float.intBitsToFloat(i);
561 write.putFloat(f);
562 assertEquals(f, read.getFloat(), 0);
563
564 double d = Double.longBitsToDouble(l);
565 write.putDouble(d);
566 assertEquals(d, read.getDouble(), 0);
567
568 char c = (char) 0x1234;
569 write.putChar(c);
570 assertEquals(c, read.getChar());
571 }
572
573 }