View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.mina.codec;
20  
21  import static org.hamcrest.CoreMatchers.is;
22  import static org.hamcrest.CoreMatchers.not;
23  import static org.junit.Assert.assertEquals;
24  import static org.junit.Assert.assertFalse;
25  import static org.junit.Assert.assertNotNull;
26  import static org.junit.Assert.assertTrue;
27  import static org.junit.Assert.fail;
28  
29  import java.io.IOException;
30  import java.io.InputStream;
31  import java.nio.BufferUnderflowException;
32  import java.nio.ByteBuffer;
33  import java.nio.ByteOrder;
34  import java.nio.InvalidMarkException;
35  import java.util.Arrays;
36  
37  import org.junit.Assert;
38  import org.junit.Test;
39  
40  /**
41   * 
42   * @author <a href="http://mina.apache.org">Apache MINA Project</a>
43   */
44  public class IoBufferTest {
45      /**
46       * Test the addition of 3 heap buffers with data
47       */
48      @Test
49      public void testAddHeapBuffers() {
50          ByteBuffer bb1 = ByteBuffer.allocate(5);
51          bb1.put("012".getBytes());
52          bb1.flip();
53  
54          ByteBuffer bb2 = ByteBuffer.allocate(5);
55          bb2.put("345".getBytes());
56          bb2.flip();
57  
58          ByteBuffer bb3 = ByteBuffer.allocate(5);
59          bb3.put("6789".getBytes());
60          bb3.flip();
61  
62          IoBuffer ioBuffer = IoBuffer.newInstance();
63          ioBuffer.add(bb1, bb2).add(bb3);
64  
65          assertEquals(0, ioBuffer.position());
66          assertEquals(10, ioBuffer.limit());
67          assertEquals(10, ioBuffer.capacity());
68          assertTrue(ioBuffer.hasRemaining());
69  
70          for (int i = 0; i < 10; i++) {
71              assertTrue(ioBuffer.hasRemaining());
72              assertEquals("0123456789".charAt(i), ioBuffer.get());
73          }
74  
75          try {
76              assertFalse(ioBuffer.hasRemaining());
77              ioBuffer.get();
78              fail();
79          } catch (BufferUnderflowException bufe) {
80              assertTrue(true);
81          }
82      }
83  
84      /**
85       * Test the addition of 3 heap buffers, one being empty
86       */
87      @Test
88      public void testAddHeapBuffersOneEmpty() {
89          ByteBuffer bb1 = ByteBuffer.allocate(5);
90          bb1.put("012".getBytes());
91          bb1.flip();
92  
93          ByteBuffer bb2 = ByteBuffer.allocate(0);
94  
95          ByteBuffer bb3 = ByteBuffer.allocate(5);
96          bb3.put("3456".getBytes());
97          bb3.flip();
98  
99          IoBuffer ioBuffer = IoBuffer.newInstance();
100         ioBuffer.add(bb1, bb2).add(bb3);
101 
102         assertEquals(0, ioBuffer.position());
103         assertEquals(7, ioBuffer.limit());
104         assertEquals(7, ioBuffer.capacity());
105 
106         for (int i = 0; i < 7; i++) {
107             assertTrue(ioBuffer.hasRemaining());
108             assertEquals("0123456".charAt(i), ioBuffer.get());
109         }
110 
111         try {
112             ioBuffer.get();
113             fail();
114         } catch (BufferUnderflowException bufe) {
115             assertTrue(true);
116         }
117     }
118 
119     /**
120      * Test the addition of mixed type buffers
121      */
122     @Test
123     public void testAddMixedTypeBuffers() {
124         ByteBuffer bb1 = ByteBuffer.allocate(5);
125         bb1.put("012".getBytes());
126         bb1.flip();
127 
128         ByteBuffer bb2 = ByteBuffer.allocateDirect(5);
129         bb2.put("3456".getBytes());
130         bb2.flip();
131 
132         IoBuffer ioBuffer = IoBuffer.newInstance();
133         ioBuffer.add(bb1, bb2);
134     }
135 
136     /**
137      * Test the addition of mixed order buffers
138      */
139     @Test
140     public void testAddMixedOrderBuffers() {
141         ByteBuffer bb1 = ByteBuffer.allocate(5);
142         bb1.order(ByteOrder.LITTLE_ENDIAN);
143         bb1.put("012".getBytes());
144         bb1.flip();
145 
146         ByteBuffer bb2 = ByteBuffer.allocateDirect(5);
147         bb1.order(ByteOrder.BIG_ENDIAN);
148         bb2.put("3456".getBytes());
149         bb2.flip();
150 
151         IoBuffer ioBuffer = IoBuffer.newInstance();
152         ioBuffer.add(bb1, bb2);
153     }
154 
155     //-------------------------------------------------------------------------
156     // Test the allocate(int) method
157     // 1) allocation with a negative value
158     // 2) allocation with a 0 length
159     // 3) allocation with a 1024 value
160     //-------------------------------------------------------------------------
161     /**
162      * Test the allocation of a new heap IoBuffer with a negative value
163      */
164     @Test(expected = IllegalArgumentException.class)
165     public void testAllocateNegative() {
166         IoBuffer.allocate(-1);
167     }
168 
169     /**
170      * Test the allocation of a new heap IoBuffer with no byte in it
171      */
172     @Test
173     public void testAllocate0() {
174         IoBuffer ioBuffer = IoBuffer.allocate(0);
175 
176         assertFalse(ioBuffer.isDirect());
177         assertEquals(0, ioBuffer.capacity());
178         assertEquals(0, ioBuffer.limit());
179         assertEquals(0, ioBuffer.position());
180         assertFalse(ioBuffer.hasRemaining());
181     }
182 
183     /**
184      * Test the allocation of a new heap IoBuffer with 1024 bytes
185      */
186     @Test
187     public void testAllocate1024() {
188         IoBuffer ioBuffer = IoBuffer.allocate(1024);
189 
190         assertFalse(ioBuffer.isDirect());
191         assertEquals(1024, ioBuffer.capacity());
192         assertEquals(1024, ioBuffer.limit());
193         assertEquals(0, ioBuffer.position());
194         assertTrue(ioBuffer.hasRemaining());
195     }
196 
197     //-------------------------------------------------------------------------
198     // Test the allocateDirect(int) method. We check :
199     // 1) allocation with a negative value
200     // 2) allocation with a 0 length
201     // 3) allocation with a 1024 value
202     //-------------------------------------------------------------------------
203     /**
204      * Test the allocation of a new heap IoBuffer with a negative value
205      */
206     @Test(expected = IllegalArgumentException.class)
207     public void testAllocateDirectNegative() {
208         IoBuffer.allocate(-1);
209     }
210 
211     /**
212      * Test the allocation of a new direct IoBuffer with no byte in it
213      */
214     @Test
215     public void testAllocateDirect0() {
216         IoBuffer ioBuffer = IoBuffer.allocateDirect(0);
217 
218         assertTrue(ioBuffer.isDirect());
219         assertEquals(0, ioBuffer.capacity());
220         assertEquals(0, ioBuffer.limit());
221         assertEquals(0, ioBuffer.position());
222         assertFalse(ioBuffer.hasRemaining());
223     }
224 
225     /**
226      * Test the allocation of a new direct IoBuffer with 1024 bytes
227      */
228     @Test
229     public void testAllocateDirect1024() {
230         IoBuffer ioBuffer = IoBuffer.allocateDirect(1024);
231 
232         assertTrue(ioBuffer.isDirect());
233         assertEquals(1024, ioBuffer.capacity());
234         assertEquals(1024, ioBuffer.limit());
235         assertEquals(0, ioBuffer.position());
236         assertTrue(ioBuffer.hasRemaining());
237     }
238 
239     /**
240      * Test the get() method on a IoBuffer containing one ByteBuffer with 3 bytes
241      */
242     @Test
243     public void testGetOneBuffer3Bytes() {
244         ByteBuffer bb = ByteBuffer.allocate(5);
245         bb.put("012".getBytes());
246         bb.flip();
247 
248         IoBuffer ioBuffer = IoBuffer.wrap(bb);
249         assertEquals(0, ioBuffer.position());
250         assertEquals(3, ioBuffer.limit());
251 
252         assertTrue(ioBuffer.hasRemaining());
253         assertEquals('0', ioBuffer.get());
254         assertTrue(ioBuffer.hasRemaining());
255         assertEquals('1', ioBuffer.get());
256         assertTrue(ioBuffer.hasRemaining());
257         assertEquals('2', ioBuffer.get());
258 
259         try {
260             assertFalse(ioBuffer.hasRemaining());
261             ioBuffer.get();
262             fail();
263         } catch (BufferUnderflowException bufe) {
264             // expected
265             assertEquals(3, ioBuffer.position());
266         }
267     }
268 
269     /**
270      * Test the get() method on a IoBuffer containing one ByteBuffer with 0 bytes
271      */
272     @Test
273     public void testGetOneBuffer0Bytes() {
274         ByteBuffer bb = ByteBuffer.allocate(0);
275 
276         IoBuffer ioBuffer = IoBuffer.wrap(bb);
277         assertEquals(0, ioBuffer.position());
278         assertEquals(0, ioBuffer.limit());
279 
280         try {
281             assertFalse(ioBuffer.hasRemaining());
282             ioBuffer.get();
283             fail();
284         } catch (BufferUnderflowException bufe) {
285             // expected
286             assertEquals(0, ioBuffer.position());
287         }
288     }
289 
290     /**
291      * Test the get() method on a IoBuffer containing two ByteBuffer with 3 bytes
292      */
293     @Test
294     public void testGetTwoBuffer3Bytes() {
295         ByteBuffer bb1 = ByteBuffer.allocate(5);
296         bb1.put("012".getBytes());
297         bb1.flip();
298 
299         ByteBuffer bb2 = ByteBuffer.allocate(5);
300         bb2.put("345".getBytes());
301         bb2.flip();
302 
303         IoBuffer ioBuffer = IoBuffer.wrap(bb1, bb2);
304 
305         assertEquals(0, ioBuffer.position());
306         assertEquals(6, ioBuffer.limit());
307         assertTrue(ioBuffer.hasRemaining());
308 
309         assertEquals('0', ioBuffer.get());
310         assertTrue(ioBuffer.hasRemaining());
311         assertEquals('1', ioBuffer.get());
312         assertTrue(ioBuffer.hasRemaining());
313         assertEquals('2', ioBuffer.get());
314         assertTrue(ioBuffer.hasRemaining());
315         assertEquals('3', ioBuffer.get());
316         assertTrue(ioBuffer.hasRemaining());
317         assertEquals('4', ioBuffer.get());
318         assertTrue(ioBuffer.hasRemaining());
319         assertEquals('5', ioBuffer.get());
320 
321         try {
322             assertFalse(ioBuffer.hasRemaining());
323             ioBuffer.get();
324             fail();
325         } catch (BufferUnderflowException bufe) {
326             // expected
327             assertEquals(6, ioBuffer.position());
328         }
329     }
330 
331     //-------------------------------------------------------------------------
332     // Test the array() method. We will check those cases :
333     // 1) array over an empty buffer: we should get an empty byte array
334     // 2) array over a buffer with one single empty ByteBuffer 
335     // 3) array over a buffer with one single ByteBuffer with data
336     // 4) array over a buffer containing many ByteBuffers 
337     //-------------------------------------------------------------------------
338     /**
339      * Test the array method for a IoBuffer containing one empty ByteBuffer
340      */
341     @Test
342     public void testArrayEmptyByteBuffer() {
343         IoBuffer ioBuffer = IoBuffer.newInstance();
344 
345         byte[] array = ioBuffer.array();
346         assertNotNull(array);
347         assertEquals(0, array.length);
348         assertTrue(Arrays.equals(new byte[] {}, array));
349     }
350 
351     /**
352      * Test the array method for a IoBuffer containing one ByteBuffer (cases 2 and 3)
353      */
354     @Test
355     public void testArrayOneByteBuffer() {
356         ByteBuffer bb1 = ByteBuffer.allocate(5);
357         IoBuffer ioBuffer = IoBuffer.wrap(bb1);
358 
359         // Empty buffer first
360         byte[] array = ioBuffer.array();
361         assertNotNull(array);
362         assertEquals(5, array.length);
363         assertTrue(Arrays.equals(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00 }, array));
364 
365         // Buffer with data
366         bb1.put("012".getBytes());
367         bb1.flip();
368 
369         ioBuffer = IoBuffer.wrap(bb1);
370 
371         assertNotNull(array);
372         assertEquals(5, array.length);
373         assertTrue(Arrays.equals(new byte[] { '0', '1', '2', 0, 0 }, array));
374     }
375 
376     /**
377      * Test the array method for a IoBuffer containing one ByteBuffer not initialized
378      */
379     @Test
380     public void testArrayByteBufferNotInitialized() {
381         ByteBuffer bb = ByteBuffer.allocate(3);
382         IoBuffer ioBuffer = IoBuffer.wrap(bb);
383 
384         byte[] array = ioBuffer.array();
385         assertNotNull(array);
386         assertEquals(3, array.length);
387         assertTrue(Arrays.equals(new byte[] { 0x00, 0x00, 0x00 }, array));
388     }
389 
390     /**
391      * Test the getInt() method, on a buffer containing 2 ints in one ByteBuffer
392      */
393     @Test
394     public void testGetInt2IntsOneBB() {
395         ByteBuffer bb = ByteBuffer.allocate(8);
396         bb.putInt(12345);
397         bb.putInt(67890);
398         bb.flip();
399 
400         IoBuffer ioBuffer = IoBuffer.wrap(bb);
401         assertEquals(12345, ioBuffer.getInt());
402         assertEquals(67890, ioBuffer.getInt());
403     }
404 
405     /**
406      * Test the getInt() method, on a buffer containing 2 ints in two ByteBuffers
407      */
408     @Test
409     public void testGetInt2Ints2BBs() {
410         ByteBuffer bb1 = ByteBuffer.allocate(4);
411         bb1.putInt(12345);
412         bb1.flip();
413 
414         ByteBuffer bb2 = ByteBuffer.allocate(4);
415         bb2.putInt(67890);
416         bb2.flip();
417 
418         IoBuffer ioBuffer = IoBuffer.wrap(bb1, bb2);
419 
420         assertEquals(12345, ioBuffer.getInt());
421         assertEquals(67890, ioBuffer.getInt());
422     }
423 
424     /**
425      * Test the getInt() method, on a buffer containing 2 ints in two ByteBuffers
426      * with LittleInidan order
427      */
428     @Test
429     public void testGetInt2Ints2BBsLittleIndian() {
430         ByteBuffer bb1 = ByteBuffer.allocate(4);
431         bb1.order(ByteOrder.LITTLE_ENDIAN);
432         bb1.putInt(12345);
433         bb1.flip();
434 
435         ByteBuffer bb2 = ByteBuffer.allocate(4);
436         bb2.order(ByteOrder.LITTLE_ENDIAN);
437         bb2.putInt(67890);
438         bb2.flip();
439 
440         IoBuffer ioBuffer = IoBuffer.wrap(bb1, bb2);
441         ioBuffer.order(ByteOrder.LITTLE_ENDIAN);
442 
443         assertEquals(12345, ioBuffer.getInt());
444         assertEquals(67890, ioBuffer.getInt());
445     }
446 
447     /**
448      * Test the getInt() method, on a buffer containing 1 int spread in two ByteBuffers
449      */
450     @Test
451     public void testGetInt1Int2BBs() {
452         ByteBuffer bb1 = ByteBuffer.allocate(1);
453         bb1.put((byte) 0x01);
454         bb1.flip();
455 
456         ByteBuffer bb2 = ByteBuffer.allocate(3);
457         bb2.put(new byte[] { 0x02, 0x03, 0x04 });
458         bb2.flip();
459 
460         IoBuffer ioBuffer = IoBuffer.wrap(bb1, bb2);
461 
462         assertEquals(0x01020304, ioBuffer.getInt());
463     }
464 
465     /**
466      * Test the getInt() method, on a buffer containing 1 incomplet int spread in two ByteBuffers
467      */
468     @Test(expected = BufferUnderflowException.class)
469     public void testGetIntIncompletInt2BBs() {
470         ByteBuffer bb1 = ByteBuffer.allocate(1);
471         bb1.put((byte) 0x01);
472         bb1.flip();
473 
474         ByteBuffer bb2 = ByteBuffer.allocate(2);
475         bb2.put(new byte[] { 0x02, 0x03 });
476         bb2.flip();
477 
478         IoBuffer ioBuffer = IoBuffer.wrap(bb1, bb2);
479 
480         ioBuffer.getInt();
481     }
482 
483     /**
484      * test the get(int) method on one buffer
485      */
486     @Test
487     public void testGetIntOneBuffer() {
488         ByteBuffer bb = ByteBuffer.allocate(4);
489         bb.put("0123".getBytes());
490         bb.flip();
491 
492         IoBuffer ioBuffer = IoBuffer.wrap(bb);
493 
494         assertEquals('0', ioBuffer.get());
495         assertEquals('1', ioBuffer.get());
496         assertEquals('0', ioBuffer.get(0));
497         assertEquals('3', ioBuffer.get(3));
498         assertEquals('1', ioBuffer.get(1));
499         assertEquals('2', ioBuffer.get(2));
500         assertEquals('2', ioBuffer.get());
501 
502         try {
503             ioBuffer.get(4);
504             fail();
505         } catch (IndexOutOfBoundsException ioobe) {
506             // expected
507             assertTrue(true);
508         }
509     }
510 
511     /**
512      * test the get(int) method on two buffers
513      */
514     @Test
515     public void testGetIntTwoBuffer() {
516         ByteBuffer bb1 = ByteBuffer.allocate(4);
517         bb1.put("0123".getBytes());
518         bb1.flip();
519 
520         ByteBuffer bb2 = ByteBuffer.allocate(4);
521         bb2.put("4567".getBytes());
522         bb2.flip();
523 
524         IoBuffer ioBuffer = IoBuffer.wrap(bb1, bb2);
525 
526         assertEquals('0', ioBuffer.get());
527         assertEquals('1', ioBuffer.get());
528         assertEquals('0', ioBuffer.get(0));
529         assertEquals('4', ioBuffer.get(4));
530         assertEquals('7', ioBuffer.get(7));
531         assertEquals('2', ioBuffer.get(2));
532         assertEquals('2', ioBuffer.get());
533         assertEquals('3', ioBuffer.get());
534         assertEquals('4', ioBuffer.get());
535 
536         try {
537             ioBuffer.get(8);
538             fail();
539         } catch (IndexOutOfBoundsException ioobe) {
540             // expected
541             assertTrue(true);
542         }
543     }
544 
545     //-------------------------------------------------------------------------
546     // The the clear method. It will erase all the data in all the inner
547     // ByteBuffer, thus the buffer size might increase.
548     // We will check those case :
549     // 1) clear an empty buffer
550     // 2) clear a buffer with one ByteBuffer
551     // 3) clear a buffer with numerous ByteBuffers
552     //-------------------------------------------------------------------------
553     /**
554      * Test the clear() method
555      */
556     @Test
557     public void testClearEmptyBuffer() {
558         ByteBuffer bb1 = ByteBuffer.allocate(4);
559         bb1.put("012".getBytes());
560         bb1.flip();
561 
562         ByteBuffer bb2 = ByteBuffer.allocate(4);
563         bb2.put("345".getBytes());
564         bb2.flip();
565 
566         IoBuffer ioBuffer = IoBuffer.wrap(bb1, bb2);
567 
568         assertEquals(6, ioBuffer.limit());
569 
570         // Move forward a bit
571         ioBuffer.get();
572         ioBuffer.get();
573 
574         ioBuffer.limit(3);
575 
576         // Clear
577         ioBuffer.clear();
578 
579         // We should be back to the origin
580         assertEquals(0, ioBuffer.position());
581 
582         // The limit must back to the available size
583         assertEquals(6, ioBuffer.limit());
584     }
585 
586     /**
587      * Test the mark() method
588      */
589     @Test
590     public void testMark() {
591         ByteBuffer bb1 = ByteBuffer.allocate(4);
592         bb1.put("0123".getBytes());
593         bb1.flip();
594 
595         ByteBuffer bb2 = ByteBuffer.allocate(4);
596         bb2.put("4567".getBytes());
597         bb2.flip();
598 
599         IoBuffer ioBuffer = IoBuffer.wrap(bb1, bb2);
600 
601         ioBuffer.position(3);
602         ioBuffer.mark();
603 
604         ioBuffer.position(6);
605         ioBuffer.reset();
606 
607         ioBuffer.position(6);
608         ioBuffer.mark();
609 
610         // we go backward, the mark should be discarded
611         ioBuffer.position(3);
612 
613         try {
614             ioBuffer.reset();
615             fail("An InvalidMarkException should have been thrown");
616         } catch (InvalidMarkException ime) {
617             // 
618         }
619     }
620 
621     /**
622      * Test the flip() method
623      */
624     @Test
625     public void testFlip() {
626         ByteBuffer bb1 = ByteBuffer.allocate(4);
627         bb1.put("0123".getBytes());
628         bb1.flip();
629 
630         ByteBuffer bb2 = ByteBuffer.allocate(4);
631         bb2.put("4567".getBytes());
632         bb2.flip();
633 
634         IoBuffer ioBuffer = IoBuffer.wrap(bb1, bb2);
635 
636         // Move forward a bit
637         ioBuffer.get();
638         ioBuffer.get();
639 
640         // Clear
641         ioBuffer.clear();
642 
643         // We should be back to the origin
644         assertEquals(0, ioBuffer.position());
645         assertEquals(8, ioBuffer.limit());
646     }
647 
648     //-------------------------------------------------------------------------
649     // Test the position() method
650     // We will test that the position() metho returns the correct result in 
651     // those cases :
652     // 1) the buffer is empty : must return 0
653     // 2) must return a value between 0 and limit()
654     //-------------------------------------------------------------------------
655     /**
656      * Test the position method over an emptyIoBuffer
657      */
658     @Test
659     public void testPositionEmptyBuffer() {
660         IoBuffer ioBuffer = IoBuffer.newInstance();
661 
662         assertEquals(0, ioBuffer.position());
663     }
664 
665     /**
666      * Test the position method over a buffer
667      */
668     @Test
669     public void testPositionBuffer() {
670         ByteBuffer bb1 = ByteBuffer.allocate(4);
671         bb1.put("012".getBytes());
672         bb1.flip();
673 
674         ByteBuffer bb2 = ByteBuffer.allocate(4);
675         bb2.put("3456".getBytes());
676         bb2.flip();
677 
678         ByteBuffer bb3 = ByteBuffer.allocate(4);
679         bb3.put("789".getBytes());
680         bb3.flip();
681 
682         // The resulting buffer will be seen as "0123456789"
683         IoBuffer ioBuffer = IoBuffer.wrap(bb1, bb2, bb3);
684 
685         // Iterate and check the position
686         for (int i = 0; i < ioBuffer.limit(); i++) {
687             assertEquals(i, ioBuffer.position());
688             ioBuffer.get();
689         }
690     }
691 
692     /**
693      * Test set position method over a buffer
694      */
695     @Test
696     public void testSetPositionBuffer() {
697         ByteBuffer bb1 = ByteBuffer.allocate(4);
698         bb1.put("012".getBytes());
699         bb1.flip();
700 
701         ByteBuffer bb2 = ByteBuffer.allocate(4);
702         bb2.put("3456".getBytes());
703         bb2.flip();
704 
705         ByteBuffer bb3 = ByteBuffer.allocate(4);
706         bb3.put("789".getBytes());
707         bb3.flip();
708 
709         // The resulting buffer will be seen as "0123456789"
710         IoBuffer ioBuffer = IoBuffer.wrap(bb1, bb2, bb3);
711 
712         // Check with random positions
713         for (int i : new int[] { 4, 6, 7, 8, 3, 9, 1, 5, 0, 2 }) {
714             ioBuffer.position(i);
715             assertEquals('0' + i, ioBuffer.get());
716         }
717     }
718 
719     //-------------------------------------------------------------------------
720     // Test the position(int) method
721     // We will test many different cases
722     // 1) a position() in an empty buffer
723     // 2) a position() with a negative value
724     // 3) a position() with a value above the limit
725     // 4) a position() within the current buffer
726     //  4-1) at the beginning of the current buffer
727     //  4-2) at the end of the current buffer
728     //  4-3) in the middle of the current buffer
729     // 5) a position() before the current buffer
730     // 6) a position() after the current buffer
731     //-------------------------------------------------------------------------
732     /**
733      * Test the position method over an emptyIoBuffer
734      */
735     @Test
736     public void testPositionIntEmptyBuffer() {
737         IoBuffer ioBuffer = IoBuffer.newInstance();
738 
739         ioBuffer.position(0);
740     }
741 
742     /**
743      * Test the position method with a negative value
744      */
745     @Test(expected = IllegalArgumentException.class)
746     public void testPositionNegativeValue() {
747         ByteBuffer bb1 = ByteBuffer.allocate(4);
748         bb1.put("0123".getBytes());
749         bb1.flip();
750 
751         ByteBuffer bb2 = ByteBuffer.allocate(4);
752         bb2.put("4567".getBytes());
753         bb2.flip();
754 
755         ByteBuffer bb3 = ByteBuffer.allocate(4);
756         bb3.put("89".getBytes());
757         bb3.flip();
758 
759         IoBuffer ioBuffer = IoBuffer.wrap(bb1, bb2, bb3);
760 
761         ioBuffer.position(-1);
762     }
763 
764     /**
765      * Test the position method with a value above the buffer size
766      */
767     @Test(expected = IllegalArgumentException.class)
768     public void testPositionAboveValue() {
769         ByteBuffer bb1 = ByteBuffer.allocate(4);
770         bb1.put("012".getBytes());
771         bb1.flip();
772 
773         ByteBuffer bb2 = ByteBuffer.allocate(4);
774         bb2.put("3456".getBytes());
775         bb2.flip();
776 
777         ByteBuffer bb3 = ByteBuffer.allocate(4);
778         bb3.put("789".getBytes());
779         bb3.flip();
780 
781         // The resulting buffer will be seen as "0123456789"
782         IoBuffer ioBuffer = IoBuffer.wrap(bb1, bb2, bb3);
783 
784         ioBuffer.position(11);
785     }
786 
787     /**
788      * Test the position method in the current buffer
789      */
790     @Test
791     public void testPositionCurrentBuffer() {
792         ByteBuffer bb1 = ByteBuffer.allocate(4);
793         bb1.put("012".getBytes());
794         bb1.flip();
795 
796         ByteBuffer bb2 = ByteBuffer.allocate(4);
797         bb2.put("3456".getBytes());
798         bb2.flip();
799 
800         ByteBuffer bb3 = ByteBuffer.allocate(4);
801         bb3.put("789".getBytes());
802         bb3.flip();
803 
804         // The resulting buffer will be seen as "0123456789"
805         IoBuffer ioBuffer = IoBuffer.wrap(bb1, bb2, bb3);
806 
807         // Set the position in the middle of bb2 (4-3)
808         ioBuffer.position(5);
809 
810         assertEquals('5', ioBuffer.get());
811 
812         // Set the position at the beginning of bb2 (4-1)
813         ioBuffer.position(3);
814 
815         assertEquals('3', ioBuffer.get());
816 
817         // Set the position at the end of bb2 (4-2)
818         ioBuffer.position(6);
819 
820         assertEquals('6', ioBuffer.get());
821 
822         // Set a position before the current buffer (5)
823         ioBuffer.position(2);
824         assertEquals('2', ioBuffer.get());
825 
826         // Set a position after the current buffer (6)
827         ioBuffer.position(7);
828         assertEquals('7', ioBuffer.get());
829 
830         // Now, let's see if we can get all the elements correctly
831         // if we set the position from 0 to end
832         for (int i = 0; i < ioBuffer.limit(); i++) {
833             ioBuffer.position(i);
834             assertEquals('0' + i, ioBuffer.get());
835         }
836 
837         // Same, in revert order
838         for (int i = ioBuffer.limit() - 1; i >= 0; i--) {
839             ioBuffer.position(i);
840             assertEquals('0' + i, ioBuffer.get());
841         }
842     }
843 
844     @Test
845     public void testSlice() {
846         ByteBuffer bb1 = ByteBuffer.allocate(5);
847         bb1.put("012".getBytes());
848         bb1.flip();
849 
850         ByteBuffer bb2 = ByteBuffer.allocate(5);
851         bb2.put("345".getBytes());
852         bb2.flip();
853 
854         ByteBuffer bb3 = ByteBuffer.allocate(5);
855         bb3.put("6789".getBytes());
856         bb3.flip();
857 
858         IoBuffer ioBuffer = IoBuffer.newInstance();
859         ioBuffer.add(bb1, bb2).add(bb3);
860 
861         ioBuffer.position(2);
862         ioBuffer.limit(8);
863 
864         IoBuffer slice = ioBuffer.slice();
865 
866         assertEquals(6, slice.remaining());
867         assertEquals(0, slice.position());
868         assertEquals(6, slice.limit());
869 
870         byte seg[] = "234567".getBytes();
871         for (int i = 0; i < 6; i++) {
872             assertEquals(seg[i], slice.get(i));
873         }
874     }
875 
876     @Test
877     public void testShort() {
878         for (ByteOrder bo : new ByteOrder[] { ByteOrder.BIG_ENDIAN, ByteOrder.LITTLE_ENDIAN }) {
879             ByteBuffer bb = (ByteBuffer) ByteBuffer.allocate(3).order(bo).putShort((short) 12345).rewind();
880             IoBuffer ioBuffer = IoBuffer.wrap(bb).order(bo);
881             assertEquals(3, ioBuffer.capacity());
882             ioBuffer.extend(1);
883             ioBuffer.position(2);
884             assertEquals(4, ioBuffer.capacity());
885             ioBuffer.putShort((short) -23456);
886             ioBuffer.rewind();
887             assertEquals(12345, ioBuffer.getShort());
888             assertEquals(-23456, ioBuffer.getShort());
889             ioBuffer.rewind();
890 
891             ioBuffer.putShort(1, (short) 12345);
892             assertEquals((short) 12345, ioBuffer.getShort(1));
893 
894             try {
895                 ioBuffer.putShort(3, (short) 1);
896                 fail("Not enough place on the buffer");
897             } catch (BufferUnderflowException e) {
898                 // Should come here
899             }
900 
901             try {
902                 ioBuffer.getShort(3);
903                 fail("Not enough place on the buffer");
904             } catch (BufferUnderflowException e) {
905                 // Should come here
906             }
907         }
908     }
909 
910     @Test
911     public void testInt() {
912         for (ByteOrder bo : new ByteOrder[] { ByteOrder.BIG_ENDIAN, ByteOrder.LITTLE_ENDIAN }) {
913             ByteBuffer bb = (ByteBuffer) ByteBuffer.allocate(5).order(bo).putInt(123456).rewind();
914             IoBuffer ioBuffer = IoBuffer.wrap(bb).order(bo);
915             assertEquals(5, ioBuffer.capacity());
916             ioBuffer.extend(3);
917             ioBuffer.position(4);
918             assertEquals(8, ioBuffer.capacity());
919             ioBuffer.putInt(-23456789);
920             ioBuffer.rewind();
921             assertEquals(123456, ioBuffer.getInt());
922             assertEquals(-23456789, ioBuffer.getInt());
923             ioBuffer.rewind();
924 
925             ioBuffer.putInt(2, 1234567890);
926             assertEquals(1234567890, ioBuffer.getInt(2));
927 
928             try {
929                 ioBuffer.putInt(5, 1);
930                 fail("Not enough place on the buffer");
931             } catch (BufferUnderflowException e) {
932                 // Should come here
933             }
934 
935             try {
936                 ioBuffer.getInt(5);
937                 fail("Not enough place on the buffer");
938             } catch (BufferUnderflowException e) {
939                 // Should come here
940             }
941         }
942     }
943 
944     @Test
945     public void testLong() {
946         for (ByteOrder bo : new ByteOrder[] { ByteOrder.BIG_ENDIAN, ByteOrder.LITTLE_ENDIAN }) {
947             ByteBuffer bb = (ByteBuffer) ByteBuffer.allocate(9).order(bo).putLong(123456789012l).rewind();
948             IoBuffer ioBuffer = IoBuffer.wrap(bb).order(bo);
949             assertEquals(9, ioBuffer.capacity());
950             ioBuffer.extend(7);
951 
952             ioBuffer.position(8);
953             assertEquals(16, ioBuffer.capacity());
954             ioBuffer.putLong(-23456789023l);
955             ioBuffer.rewind();
956             assertEquals(123456789012l, ioBuffer.getLong());
957             assertEquals(-23456789023l, ioBuffer.getLong());
958 
959             ioBuffer.rewind();
960             ioBuffer.putLong(4, 1234567890);
961             assertEquals(1234567890, ioBuffer.getLong(4));
962 
963             try {
964                 ioBuffer.putLong(9, 1);
965                 fail("Not enough place on the buffer");
966             } catch (BufferUnderflowException e) {
967                 // Should come here
968             }
969 
970             try {
971                 ioBuffer.getLong(9);
972                 fail("Not enough place on the buffer");
973             } catch (BufferUnderflowException e) {
974                 // Should come here
975             }
976         }
977     }
978 
979     @Test
980     public void testFloat() {
981         for (ByteOrder bo : new ByteOrder[] { ByteOrder.BIG_ENDIAN, ByteOrder.LITTLE_ENDIAN }) {
982             ByteBuffer bb = (ByteBuffer) ByteBuffer.allocate(5).order(bo).putFloat(-0.68f).rewind();
983             IoBuffer ioBuffer = IoBuffer.wrap(bb).order(bo);
984             assertEquals(5, ioBuffer.capacity());
985             ioBuffer.extend(3);
986             ioBuffer.position(4);
987             assertEquals(8, ioBuffer.capacity());
988             ioBuffer.putFloat(3.14f);
989             ioBuffer.rewind();
990             assertEquals(-0.68f, ioBuffer.getFloat(), 0.001f);
991             assertEquals(3.14f, ioBuffer.getFloat(), 0.001f);
992             ioBuffer.rewind();
993 
994             ioBuffer.putFloat(2, -12.34f);
995             assertEquals(-12.34f, ioBuffer.getFloat(2), 0.001f);
996         }
997     }
998 
999     @Test
1000     public void testDouble() {
1001         for (ByteOrder bo : new ByteOrder[] { ByteOrder.BIG_ENDIAN, ByteOrder.LITTLE_ENDIAN }) {
1002             ByteBuffer bb = (ByteBuffer) ByteBuffer.allocate(9).order(bo).putDouble(Math.PI).rewind();
1003             IoBuffer ioBuffer = IoBuffer.wrap(bb).order(bo);
1004             assertEquals(9, ioBuffer.capacity());
1005             ioBuffer.extend(7);
1006 
1007             ioBuffer.position(8);
1008             assertEquals(16, ioBuffer.capacity());
1009             ioBuffer.putDouble(-Math.E);
1010             ioBuffer.rewind();
1011             assertEquals(Math.PI, ioBuffer.getDouble(), 1E-10);
1012             assertEquals(-Math.E, ioBuffer.getDouble(), 1E-10);
1013 
1014             ioBuffer.rewind();
1015             ioBuffer.putDouble(4, 12.34);
1016             assertEquals(12.34, ioBuffer.getDouble(4), 1E-10);
1017         }
1018     }
1019 
1020     @Test
1021     public void testChar() {
1022         for (ByteOrder bo : new ByteOrder[] { ByteOrder.BIG_ENDIAN, ByteOrder.LITTLE_ENDIAN }) {
1023             ByteBuffer bb = (ByteBuffer) ByteBuffer.allocate(3).order(bo).putChar('ë').rewind();
1024             IoBuffer ioBuffer = IoBuffer.wrap(bb).order(bo);
1025 
1026             assertEquals(3, ioBuffer.capacity());
1027 
1028             ioBuffer.extend(1);
1029             ioBuffer.order(bo);
1030             ioBuffer.position(2);
1031             assertEquals(4, ioBuffer.capacity());
1032             ioBuffer.putChar('ü');
1033             ioBuffer.rewind();
1034 
1035             assertEquals('ë', ioBuffer.getChar());
1036             assertEquals('ü', ioBuffer.getChar());
1037             ioBuffer.rewind();
1038 
1039             ioBuffer.putChar(1, 'ç');
1040             assertEquals('ç', ioBuffer.getChar(1));
1041 
1042             try {
1043                 ioBuffer.putChar(3, 'ñ');
1044                 fail("Not enough place on the buffer");
1045             } catch (BufferUnderflowException e) {
1046                 // Should come here                
1047             }
1048 
1049             try {
1050                 ioBuffer.getChar(3);
1051                 fail("Not enough place on the buffer");
1052             } catch (BufferUnderflowException e) {
1053                 // Should come here
1054             }
1055         }
1056     }
1057 
1058     @Test
1059     public void testGet() {
1060         ByteBuffer bb1 = ByteBuffer.allocate(5);
1061         bb1.put("012".getBytes());
1062         bb1.flip();
1063 
1064         ByteBuffer bb2 = ByteBuffer.allocate(5);
1065         bb2.put("345".getBytes());
1066         bb2.flip();
1067 
1068         ByteBuffer bb3 = ByteBuffer.allocate(5);
1069         bb3.put("6789".getBytes());
1070         bb3.flip();
1071 
1072         IoBuffer ioBuffer = IoBuffer.newInstance();
1073         ioBuffer.add(bb1, bb2).add(bb3);
1074 
1075         ioBuffer.position(2);
1076         ioBuffer.limit(8);
1077 
1078         byte block[] = new byte[6];
1079         ioBuffer.get(block);
1080         byte seg[] = "234567".getBytes();
1081         for (int i = 0; i < 6; i++) {
1082             assertEquals(seg[i], block[i]);
1083         }
1084     }
1085 
1086     @Test
1087     public void testPut() {
1088         ByteBuffer bb1 = ByteBuffer.allocate(5);
1089         bb1.put("012".getBytes());
1090         bb1.flip();
1091 
1092         ByteBuffer bb2 = ByteBuffer.allocate(5);
1093         bb2.put("345".getBytes());
1094         bb2.flip();
1095 
1096         ByteBuffer bb3 = ByteBuffer.allocate(5);
1097         bb3.put("6789".getBytes());
1098         bb3.flip();
1099 
1100         IoBuffer ioBuffer = IoBuffer.newInstance();
1101         ioBuffer.add(bb1, bb2).add(bb3);
1102 
1103         byte seq[] = "abcdefghij".getBytes();
1104         ioBuffer.position(2);
1105         ioBuffer.put(seq, 3, 3);
1106         ioBuffer.rewind();
1107         byte expected[] = "01def56789".getBytes();
1108         for (int i = 0; i < 6; i++) {
1109             assertEquals(expected[i], ioBuffer.get(i));
1110         }
1111     }
1112 
1113     @Test
1114     public void testCompact() {
1115         ByteBuffer bb1 = ByteBuffer.allocate(5);
1116         bb1.put("012".getBytes());
1117         bb1.flip();
1118 
1119         ByteBuffer bb2 = ByteBuffer.allocate(5);
1120         bb2.put("345".getBytes());
1121         bb2.flip();
1122 
1123         ByteBuffer bb3 = ByteBuffer.allocate(5);
1124         bb3.put("6789".getBytes());
1125         bb3.flip();
1126 
1127         IoBuffer ioBuffer = IoBuffer.newInstance();
1128         ioBuffer.add(bb1, bb2).add(bb3);
1129 
1130         ioBuffer.position(2);
1131         ioBuffer.limit(8);
1132 
1133         ioBuffer.compact();
1134         assertEquals(ioBuffer.capacity(), ioBuffer.limit());
1135         assertEquals(6, ioBuffer.position());
1136 
1137         byte seg[] = "234567".getBytes();
1138         for (int i = 0; i < 6; i++) {
1139             assertEquals(seg[i], ioBuffer.get(i));
1140         }
1141     }
1142 
1143     @Test
1144     public void testInputStreamGetByte() throws IOException {
1145         String hw = "HelloWorld";
1146         IoBuffer bb = IoBuffer.wrap(hw.getBytes());
1147         InputStream is = bb.asInputStream();
1148         for (int i = 0; i < 10; i++) {
1149             assertEquals(i, bb.position());
1150             assertEquals(hw.getBytes()[i], is.read());
1151         }
1152         assertEquals(-1, is.read());
1153     }
1154 
1155     @Test
1156     public void testInputStreamGetByteArray() throws IOException {
1157         String hw = "HelloWorld";
1158         IoBuffer bb = IoBuffer.wrap(hw.getBytes());
1159         InputStream is = bb.asInputStream();
1160         byte array[] = new byte[15];
1161 
1162         assertEquals(5, is.read(array, 0, 5));
1163         assertEquals(5, bb.position());
1164         assertEquals(5, is.read(array, 5, 10));
1165         assertEquals(10, bb.position());
1166 
1167         for (int i = 0; i < 10; i++) {
1168             assertEquals(hw.getBytes()[i], array[i]);
1169         }
1170     }
1171 
1172     @Test
1173     public void testEquals() {
1174         String h = "Hello";
1175         String w = "World";
1176         IoBuffer hw1b = IoBuffer.wrap((h + w).getBytes());
1177         IoBuffer wh1b = IoBuffer.wrap((w + h).getBytes());
1178         IoBuffer hw2b = IoBuffer.newInstance();
1179         hw2b.add(ByteBuffer.wrap(h.getBytes()));
1180         hw2b.add(ByteBuffer.wrap(w.getBytes()));
1181         assertEquals(hw2b, hw1b);
1182         Assert.assertThat(wh1b, is(not(hw1b)));
1183     }
1184 }