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