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   */
20  package org.apache.mina.core.buffer;
21  
22  import static org.junit.Assert.assertEquals;
23  import static org.junit.Assert.assertFalse;
24  import static org.junit.Assert.assertNotSame;
25  import static org.junit.Assert.assertSame;
26  import static org.junit.Assert.assertTrue;
27  import static org.junit.Assert.fail;
28  
29  import java.nio.BufferOverflowException;
30  import java.nio.ByteBuffer;
31  import java.nio.ByteOrder;
32  import java.nio.ReadOnlyBufferException;
33  import java.nio.charset.CharacterCodingException;
34  import java.nio.charset.Charset;
35  import java.nio.charset.CharsetDecoder;
36  import java.nio.charset.CharsetEncoder;
37  import java.util.ArrayList;
38  import java.util.Date;
39  import java.util.EnumSet;
40  import java.util.List;
41  
42  import org.apache.mina.util.Bar;
43  import org.junit.Test;
44  
45  /**
46   * Tests the {@link IoBuffer} class.
47   * 
48   * @author <a href="http://mina.apache.org">Apache MINA Project</a>
49   */
50  public class IoBufferTest {
51  
52      private static interface NonserializableInterface {
53      }
54  
55      public static class NonserializableClass {
56      }
57  
58      /**
59       * Test the capacity(newCapacity) method.
60       */
61      @Test
62      public void testCapacity() {
63          IoBuffer buffer = IoBuffer.allocate(10);
64          
65          buffer.put("012345".getBytes());
66          buffer.flip();
67          
68          // See if we can decrease the capacity (we shouldn't be able to go under the minimul capacity)
69          IoBuffer newBuffer = buffer.capacity(7);
70          assertEquals(10, newBuffer.capacity());
71          assertEquals(buffer, newBuffer);
72          
73          // See if we can increase the capacity
74          buffer = IoBuffer.allocate(10);
75          
76          buffer.put("012345".getBytes());
77          buffer.flip();
78          newBuffer = buffer.capacity(14);
79          assertEquals(14, newBuffer.capacity());
80          assertEquals(buffer, newBuffer);
81          newBuffer.put(0, (byte)'9');
82          assertEquals((byte)'9', newBuffer.get(0));
83          assertEquals((byte)'9', buffer.get(0));
84          
85          // See if we can go down when the minimum capacity is below the current capacity
86          // We should not.
87          buffer = IoBuffer.allocate(10);
88          buffer.capacity(5);
89          assertEquals(10, buffer.minimumCapacity());
90          assertEquals(10, buffer.capacity());
91      }
92  
93      /**
94       * Test the expand(expectedRemaining) method.
95       */
96      @Test
97      public void testExpand() {
98          IoBuffer buffer = IoBuffer.allocate(10);
99          
100         buffer.put("012345".getBytes());
101         buffer.flip();
102         
103         assertEquals(6, buffer.remaining());
104         
105         // See if we can expand with a lower number of remaining bytes. We should not.
106         IoBuffer newBuffer = buffer.expand(2);
107         assertEquals(6, newBuffer.limit());
108         assertEquals(10, newBuffer.capacity());
109         assertEquals(0, newBuffer.position());
110         
111         // Now, let's expand the buffer above the number of current bytes but below the limit
112         buffer = IoBuffer.allocate(10);
113         
114         buffer.put("012345".getBytes());
115         buffer.flip();
116         newBuffer = buffer.expand(8);
117         assertEquals(8, newBuffer.limit());
118         assertEquals(10, newBuffer.capacity());
119         assertEquals(0, newBuffer.position());
120         
121         // Last, expand the buffer above the limit
122         buffer = IoBuffer.allocate(10);
123         
124         buffer.put("012345".getBytes());
125         buffer.flip();
126         newBuffer = buffer.expand(12);
127         assertEquals(12, newBuffer.limit());
128         assertEquals(12, newBuffer.capacity());
129         assertEquals(0, newBuffer.position());
130         
131         // Now, move forward in the buffer
132         buffer = IoBuffer.allocate(10);
133         
134         buffer.put("012345".getBytes());
135         buffer.flip();
136         buffer.position(4);
137 
138         // See if we can expand with a lower number of remaining bytes. We should not.
139         newBuffer = buffer.expand(2);
140         assertEquals(6, newBuffer.limit());
141         assertEquals(10, newBuffer.capacity());
142         assertEquals(4, newBuffer.position());
143 
144         // Expand above the current limit
145         buffer = IoBuffer.allocate(10);
146         
147         buffer.put("012345".getBytes());
148         buffer.flip();
149         buffer.position(4);
150         newBuffer = buffer.expand(3);
151         assertEquals(7, newBuffer.limit());
152         assertEquals(10, newBuffer.capacity());
153         assertEquals(4, newBuffer.position());
154 
155         // Expand above the current capacity
156         buffer = IoBuffer.allocate(10);
157         
158         buffer.put("012345".getBytes());
159         buffer.flip();
160         buffer.position(4);
161         newBuffer = buffer.expand(7);
162         assertEquals(11, newBuffer.limit());
163         assertEquals(11, newBuffer.capacity());
164         assertEquals(4, newBuffer.position());
165     }
166 
167     /**
168      * Test the expand(position, expectedRemaining) method.
169      */
170     @Test
171     public void testExpandPos() {
172         IoBuffer buffer = IoBuffer.allocate(10);
173         
174         buffer.put("012345".getBytes());
175         buffer.flip();
176         
177         assertEquals(6, buffer.remaining());
178         
179         // See if we can expand with a lower number of remaining bytes. We should not.
180         IoBuffer newBuffer = buffer.expand(3, 2);
181         assertEquals(6, newBuffer.limit());
182         assertEquals(10, newBuffer.capacity());
183         assertEquals(0, newBuffer.position());
184         
185         // Now, let's expand the buffer above the number of current bytes but below the limit
186         buffer = IoBuffer.allocate(10);
187         buffer.put("012345".getBytes());
188         buffer.flip();
189 
190         newBuffer = buffer.expand(3, 5);
191         assertEquals(8, newBuffer.limit());
192         assertEquals(10, newBuffer.capacity());
193         assertEquals(0, newBuffer.position());
194         
195         // Last, expand the buffer above the limit
196         buffer = IoBuffer.allocate(10);
197         
198         buffer.put("012345".getBytes());
199         buffer.flip();
200         newBuffer = buffer.expand(3,9);
201         assertEquals(12, newBuffer.limit());
202         assertEquals(12, newBuffer.capacity());
203         assertEquals(0, newBuffer.position());
204         
205         // Now, move forward in the buffer
206         buffer = IoBuffer.allocate(10);
207         
208         buffer.put("012345".getBytes());
209         buffer.flip();
210         buffer.position(4);
211 
212         // See if we can expand with a lower number of remaining bytes. We should not be.
213         newBuffer = buffer.expand(5, 1);
214         assertEquals(6, newBuffer.limit());
215         assertEquals(10, newBuffer.capacity());
216         assertEquals(4, newBuffer.position());
217 
218         // Expand above the current limit
219         buffer = IoBuffer.allocate(10);
220         
221         buffer.put("012345".getBytes());
222         buffer.flip();
223         buffer.position(4);
224         newBuffer = buffer.expand(5, 2);
225         assertEquals(7, newBuffer.limit());
226         assertEquals(10, newBuffer.capacity());
227         assertEquals(4, newBuffer.position());
228 
229         // Expand above the current capacity
230         buffer = IoBuffer.allocate(10);
231         
232         buffer.put("012345".getBytes());
233         buffer.flip();
234         buffer.position(4);
235         newBuffer = buffer.expand(5, 6);
236         assertEquals(11, newBuffer.limit());
237         assertEquals(11, newBuffer.capacity());
238         assertEquals(4, newBuffer.position());
239     }
240 
241     /**
242      * Test the normalizeCapacity(requestedCapacity) method.
243      */
244     @Test
245     public void testNormalizeCapacity() {
246         // A few sanity checks
247         assertEquals(Integer.MAX_VALUE, IoBufferImpl.normalizeCapacity(-10));
248         assertEquals(0, IoBufferImpl.normalizeCapacity(0));
249         assertEquals(Integer.MAX_VALUE, IoBufferImpl.normalizeCapacity(Integer.MAX_VALUE));
250         assertEquals(Integer.MAX_VALUE, IoBufferImpl.normalizeCapacity(Integer.MIN_VALUE));
251         assertEquals(Integer.MAX_VALUE, IoBufferImpl.normalizeCapacity(Integer.MAX_VALUE - 10));
252 
253         // A sanity check test for all the powers of 2
254         for (int i = 0; i < 30; i++) {
255             int n = 1 << i;
256 
257             assertEquals(n, IoBufferImpl.normalizeCapacity(n));
258 
259             if (i > 1) {
260                 // test that n - 1 will be normalized to n (notice that n = 2^i)
261                 assertEquals(n, IoBufferImpl.normalizeCapacity(n - 1));
262             }
263 
264             // test that n + 1 will be normalized to 2^(i + 1)
265             assertEquals(n << 1, IoBufferImpl.normalizeCapacity(n + 1));
266         }
267 
268         // The first performance test measures the time to normalize integers
269         // from 0 to 2^27 (it tests 2^27 integers)
270         long time = System.currentTimeMillis();
271 
272         for (int i = 0; i < 1 << 27; i++) {
273             int n = IoBufferImpl.normalizeCapacity(i);
274 
275             // do a simple superfluous test to prevent possible compiler or JVM
276             // optimizations of not executing non used code/variables
277             if (n == -1) {
278                 System.out.println("n should never be -1");
279             }
280         }
281 
282         long time2 = System.currentTimeMillis();
283         //System.out.println("Time for performance test 1: " + (time2 - time) + "ms");
284 
285         // The second performance test measures the time to normalize integers
286         // from Integer.MAX_VALUE to Integer.MAX_VALUE - 2^27 (it tests 2^27
287         // integers)
288         time = System.currentTimeMillis();
289         for (int i = Integer.MAX_VALUE; i > Integer.MAX_VALUE - (1 << 27); i--) {
290             int n = IoBufferImpl.normalizeCapacity(i);
291 
292             // do a simple superfluous test to prevent possible compiler or JVM
293             // optimizations of not executing non used code/variables
294             if (n == -1) {
295                 System.out.println("n should never be -1");
296             }
297         }
298 
299         time2 = System.currentTimeMillis();
300         //System.out.println("Time for performance test 2: " + (time2 - time) + "ms");
301     }
302 
303     @Test
304     public void autoExpand() {
305         IoBuffer buffer = IoBuffer.allocate(8, false);
306         buffer.setAutoExpand(true);
307 
308         assertTrue("Should AutoExpand", buffer.isAutoExpand());
309 
310         IoBuffer slice = buffer.slice();
311         assertFalse("Should *NOT* AutoExpand", buffer.isAutoExpand());
312         assertFalse("Should *NOT* AutoExpand", slice.isAutoExpand());
313     }
314 
315     /**
316      * This class extends the AbstractIoBuffer class to have direct access to
317      * the protected IoBuffer.normalizeCapacity() method and to expose it for
318      * the tests.
319      */
320     private static class IoBufferImpl extends AbstractIoBuffer {
321 
322         public static int normalizeCapacity(int requestedCapacity) {
323             return IoBuffer.normalizeCapacity(requestedCapacity);
324         }
325 
326         protected IoBufferImpl(AbstractIoBuffer parent) {
327             super(parent);
328         }
329 
330         protected IoBuffer asReadOnlyBuffer0() {
331             return null;
332         }
333 
334         protected void buf(ByteBuffer newBuf) {
335         }
336 
337         protected IoBuffer duplicate0() {
338             return null;
339         }
340 
341         protected IoBuffer slice0() {
342             return null;
343         }
344 
345         public byte[] array() {
346             return null;
347         }
348 
349         public int arrayOffset() {
350             return 0;
351         }
352 
353         public ByteBuffer buf() {
354             return null;
355         }
356 
357         public void free() {
358         }
359 
360         public boolean hasArray() {
361             return false;
362         }
363 
364     }
365 
366     @Test
367     public void testObjectSerialization() throws Exception {
368         IoBuffer buf = IoBuffer.allocate(16);
369         buf.setAutoExpand(true);
370         List<Object> o = new ArrayList<Object>();
371         o.add(new Date());
372         o.add(long.class);
373 
374         // Test writing an object.
375         buf.putObject(o);
376 
377         // Test reading an object.
378         buf.clear();
379         Object o2 = buf.getObject();
380         assertEquals(o, o2);
381 
382         // This assertion is just to make sure that deserialization occurred.
383         assertNotSame(o, o2);
384     }
385 
386     @Test
387     public void testNonserializableClass() throws Exception {
388         Class<?> c = NonserializableClass.class;
389 
390         IoBuffer buffer = IoBuffer.allocate(16);
391         buffer.setAutoExpand(true);
392         buffer.putObject(c);
393 
394         buffer.flip();
395         Object o = buffer.getObject();
396 
397         assertEquals(c, o);
398         assertSame(c, o);
399     }
400 
401     @Test
402     public void testNonserializableInterface() throws Exception {
403         Class<?> c = NonserializableInterface.class;
404 
405         IoBuffer buffer = IoBuffer.allocate(16);
406         buffer.setAutoExpand(true);
407         buffer.putObject(c);
408 
409         buffer.flip();
410         Object o = buffer.getObject();
411 
412         assertEquals(c, o);
413         assertSame(c, o);
414     }
415 
416     @Test
417     public void testAllocate() throws Exception {
418         for (int i = 10; i < 1048576 * 2; i = i * 11 / 10) // increase by 10%
419         {
420             IoBuffer buf = IoBuffer.allocate(i);
421             assertEquals(0, buf.position());
422             assertEquals(buf.capacity(), buf.remaining());
423             assertTrue(buf.capacity() >= i);
424             assertTrue(buf.capacity() < i * 2);
425         }
426     }
427 
428     /**
429      * Test that we can't allocate a buffser with a negative value
430      * @throws Exception
431      */
432     @Test(expected=IllegalArgumentException.class)
433     public void testAllocateNegative() throws Exception {
434         IoBuffer.allocate(-1);
435     }
436 
437     @Test
438     public void testAutoExpand() throws Exception {
439         IoBuffer buf = IoBuffer.allocate(1);
440 
441         buf.put((byte) 0);
442         try {
443             buf.put((byte) 0);
444             fail("Buffer can't auto expand, with autoExpand property set at false");
445         } catch (BufferOverflowException e) {
446             // Expected Exception as auto expand property is false
447             assertTrue(true);
448         }
449 
450         buf.setAutoExpand(true);
451         buf.put((byte) 0);
452         assertEquals(2, buf.position());
453         assertEquals(2, buf.limit());
454         assertEquals(2, buf.capacity());
455 
456         buf.setAutoExpand(false);
457         try {
458             buf.put(3, (byte) 0);
459             fail("Buffer can't auto expand, with autoExpand property set at false");
460         } catch (IndexOutOfBoundsException e) {
461             // Expected Exception as auto expand property is false
462             assertTrue(true);
463         }
464 
465         buf.setAutoExpand(true);
466         buf.put(3, (byte) 0);
467         assertEquals(2, buf.position());
468         assertEquals(4, buf.limit());
469         assertEquals(4, buf.capacity());
470 
471         // Make sure the buffer is doubled up.
472         buf = IoBuffer.allocate(1).setAutoExpand(true);
473         int lastCapacity = buf.capacity();
474         for (int i = 0; i < 1048576; i++) {
475             buf.put((byte) 0);
476             if (lastCapacity != buf.capacity()) {
477                 assertEquals(lastCapacity * 2, buf.capacity());
478                 lastCapacity = buf.capacity();
479             }
480         }
481     }
482 
483     @Test
484     public void testAutoExpandMark() throws Exception {
485         IoBuffer buf = IoBuffer.allocate(4).setAutoExpand(true);
486 
487         buf.put((byte) 0);
488         buf.put((byte) 0);
489         buf.put((byte) 0);
490 
491         // Position should be 3 when we reset this buffer.
492         buf.mark();
493 
494         // Overflow it
495         buf.put((byte) 0);
496         buf.put((byte) 0);
497 
498         assertEquals(5, buf.position());
499         buf.reset();
500         assertEquals(3, buf.position());
501     }
502 
503     @Test
504     public void testAutoShrink() throws Exception {
505         IoBuffer buf = IoBuffer.allocate(8).setAutoShrink(true);
506 
507         // Make sure the buffer doesn't shrink too much (less than the initial
508         // capacity.)
509         buf.sweep((byte) 1);
510         buf.fill(7);
511         buf.compact();
512         assertEquals(8, buf.capacity());
513         assertEquals(1, buf.position());
514         assertEquals(8, buf.limit());
515         buf.clear();
516         assertEquals(1, buf.get());
517 
518         // Expand the buffer.
519         buf.capacity(32).clear();
520         assertEquals(32, buf.capacity());
521 
522         // Make sure the buffer shrinks when only 1/4 is being used.
523         buf.sweep((byte) 1);
524         buf.fill(24);
525         buf.compact();
526         assertEquals(16, buf.capacity());
527         assertEquals(8, buf.position());
528         assertEquals(16, buf.limit());
529         buf.clear();
530         for (int i = 0; i < 8; i++) {
531             assertEquals(1, buf.get());
532         }
533 
534         // Expand the buffer.
535         buf.capacity(32).clear();
536         assertEquals(32, buf.capacity());
537 
538         // Make sure the buffer shrinks when only 1/8 is being used.
539         buf.sweep((byte) 1);
540         buf.fill(28);
541         buf.compact();
542         assertEquals(8, buf.capacity());
543         assertEquals(4, buf.position());
544         assertEquals(8, buf.limit());
545         buf.clear();
546         for (int i = 0; i < 4; i++) {
547             assertEquals(1, buf.get());
548         }
549 
550         // Expand the buffer.
551         buf.capacity(32).clear();
552         assertEquals(32, buf.capacity());
553 
554         // Make sure the buffer shrinks when 0 byte is being used.
555         buf.fill(32);
556         buf.compact();
557         assertEquals(8, buf.capacity());
558         assertEquals(0, buf.position());
559         assertEquals(8, buf.limit());
560 
561         // Expand the buffer.
562         buf.capacity(32).clear();
563         assertEquals(32, buf.capacity());
564 
565         // Make sure the buffer doesn't shrink when more than 1/4 is being used.
566         buf.sweep((byte) 1);
567         buf.fill(23);
568         buf.compact();
569         assertEquals(32, buf.capacity());
570         assertEquals(9, buf.position());
571         assertEquals(32, buf.limit());
572         buf.clear();
573         for (int i = 0; i < 9; i++) {
574             assertEquals(1, buf.get());
575         }
576     }
577 
578     @Test
579     public void testGetString() throws Exception {
580         IoBuffer buf = IoBuffer.allocate(16);
581         CharsetDecoder decoder;
582 
583         Charset charset = Charset.forName("UTF-8");
584         buf.clear();
585         buf.putString("hello", charset.newEncoder());
586         buf.put((byte) 0);
587         buf.flip();
588         assertEquals("hello", buf.getString(charset.newDecoder()));
589 
590         buf.clear();
591         buf.putString("hello", charset.newEncoder());
592         buf.flip();
593         assertEquals("hello", buf.getString(charset.newDecoder()));
594 
595         decoder = Charset.forName("ISO-8859-1").newDecoder();
596         buf.clear();
597         buf.put((byte) 'A');
598         buf.put((byte) 'B');
599         buf.put((byte) 'C');
600         buf.put((byte) 0);
601 
602         buf.position(0);
603         assertEquals("ABC", buf.getString(decoder));
604         assertEquals(4, buf.position());
605 
606         buf.position(0);
607         buf.limit(1);
608         assertEquals("A", buf.getString(decoder));
609         assertEquals(1, buf.position());
610 
611         buf.clear();
612         assertEquals("ABC", buf.getString(10, decoder));
613         assertEquals(10, buf.position());
614 
615         buf.clear();
616         assertEquals("A", buf.getString(1, decoder));
617         assertEquals(1, buf.position());
618 
619         // Test a trailing garbage
620         buf.clear();
621         buf.put((byte) 'A');
622         buf.put((byte) 'B');
623         buf.put((byte) 0);
624         buf.put((byte) 'C');
625         buf.position(0);
626         assertEquals("AB", buf.getString(4, decoder));
627         assertEquals(4, buf.position());
628 
629         buf.clear();
630         buf.fillAndReset(buf.limit());
631         decoder = Charset.forName("UTF-16").newDecoder();
632         buf.put((byte) 0);
633         buf.put((byte) 'A');
634         buf.put((byte) 0);
635         buf.put((byte) 'B');
636         buf.put((byte) 0);
637         buf.put((byte) 'C');
638         buf.put((byte) 0);
639         buf.put((byte) 0);
640 
641         buf.position(0);
642         assertEquals("ABC", buf.getString(decoder));
643         assertEquals(8, buf.position());
644 
645         buf.position(0);
646         buf.limit(2);
647         assertEquals("A", buf.getString(decoder));
648         assertEquals(2, buf.position());
649 
650         buf.position(0);
651         buf.limit(3);
652         assertEquals("A", buf.getString(decoder));
653         assertEquals(2, buf.position());
654 
655         buf.clear();
656         assertEquals("ABC", buf.getString(10, decoder));
657         assertEquals(10, buf.position());
658 
659         buf.clear();
660         assertEquals("A", buf.getString(2, decoder));
661         assertEquals(2, buf.position());
662 
663         buf.clear();
664         try {
665             buf.getString(1, decoder);
666             fail();
667         } catch (IllegalArgumentException e) {
668             // Expected an Exception, signifies test success
669             assertTrue(true);
670         }
671 
672         // Test getting strings from an empty buffer.
673         buf.clear();
674         buf.limit(0);
675         assertEquals("", buf.getString(decoder));
676         assertEquals("", buf.getString(2, decoder));
677 
678         // Test getting strings from non-empty buffer which is filled with 0x00
679         buf.clear();
680         buf.putInt(0);
681         buf.clear();
682         buf.limit(4);
683         assertEquals("", buf.getString(decoder));
684         assertEquals(2, buf.position());
685         assertEquals(4, buf.limit());
686 
687         buf.position(0);
688         assertEquals("", buf.getString(2, decoder));
689         assertEquals(2, buf.position());
690         assertEquals(4, buf.limit());
691     }
692 
693     @Test
694     public void testGetStringWithFailure() throws Exception {
695         String test = "\u30b3\u30e1\u30f3\u30c8\u7de8\u96c6";
696         IoBuffer buffer = IoBuffer.wrap(test.getBytes("Shift_JIS"));
697 
698         // Make sure the limit doesn't change when an exception arose.
699         int oldLimit = buffer.limit();
700         int oldPos = buffer.position();
701         try {
702             buffer.getString(3, Charset.forName("ASCII").newDecoder());
703             fail();
704         } catch (Exception e) {
705             assertEquals(oldLimit, buffer.limit());
706             assertEquals(oldPos, buffer.position());
707         }
708 
709         try {
710             buffer.getString(Charset.forName("ASCII").newDecoder());
711             fail();
712         } catch (Exception e) {
713             assertEquals(oldLimit, buffer.limit());
714             assertEquals(oldPos, buffer.position());
715         }
716     }
717 
718     @Test
719     public void testPutString() throws Exception {
720         CharsetEncoder encoder;
721         IoBuffer buf = IoBuffer.allocate(16);
722         encoder = Charset.forName("ISO-8859-1").newEncoder();
723 
724         buf.putString("ABC", encoder);
725         assertEquals(3, buf.position());
726         buf.clear();
727         assertEquals('A', buf.get(0));
728         assertEquals('B', buf.get(1));
729         assertEquals('C', buf.get(2));
730 
731         buf.putString("D", 5, encoder);
732         assertEquals(5, buf.position());
733         buf.clear();
734         assertEquals('D', buf.get(0));
735         assertEquals(0, buf.get(1));
736 
737         buf.putString("EFG", 2, encoder);
738         assertEquals(2, buf.position());
739         buf.clear();
740         assertEquals('E', buf.get(0));
741         assertEquals('F', buf.get(1));
742         assertEquals('C', buf.get(2)); // C may not be overwritten
743 
744         // UTF-16: We specify byte order to omit BOM.
745         encoder = Charset.forName("UTF-16BE").newEncoder();
746         buf.clear();
747 
748         buf.putString("ABC", encoder);
749         assertEquals(6, buf.position());
750         buf.clear();
751 
752         assertEquals(0, buf.get(0));
753         assertEquals('A', buf.get(1));
754         assertEquals(0, buf.get(2));
755         assertEquals('B', buf.get(3));
756         assertEquals(0, buf.get(4));
757         assertEquals('C', buf.get(5));
758 
759         buf.putString("D", 10, encoder);
760         assertEquals(10, buf.position());
761         buf.clear();
762         assertEquals(0, buf.get(0));
763         assertEquals('D', buf.get(1));
764         assertEquals(0, buf.get(2));
765         assertEquals(0, buf.get(3));
766 
767         buf.putString("EFG", 4, encoder);
768         assertEquals(4, buf.position());
769         buf.clear();
770         assertEquals(0, buf.get(0));
771         assertEquals('E', buf.get(1));
772         assertEquals(0, buf.get(2));
773         assertEquals('F', buf.get(3));
774         assertEquals(0, buf.get(4)); // C may not be overwritten
775         assertEquals('C', buf.get(5)); // C may not be overwritten
776 
777         // Test putting an emptry string
778         buf.putString("", encoder);
779         assertEquals(0, buf.position());
780         buf.putString("", 4, encoder);
781         assertEquals(4, buf.position());
782         assertEquals(0, buf.get(0));
783         assertEquals(0, buf.get(1));
784     }
785 
786     @Test
787     public void testGetPrefixedString() throws Exception {
788         IoBuffer buf = IoBuffer.allocate(16);
789         CharsetEncoder encoder;
790         CharsetDecoder decoder;
791         encoder = Charset.forName("ISO-8859-1").newEncoder();
792         decoder = Charset.forName("ISO-8859-1").newDecoder();
793 
794         buf.putShort((short) 3);
795         buf.putString("ABCD", encoder);
796         buf.clear();
797         assertEquals("ABC", buf.getPrefixedString(decoder));
798     }
799 
800     @Test
801     public void testPutPrefixedString() throws Exception {
802         CharsetEncoder encoder;
803         IoBuffer buf = IoBuffer.allocate(16);
804         buf.fillAndReset(buf.remaining());
805         encoder = Charset.forName("ISO-8859-1").newEncoder();
806 
807         // Without autoExpand
808         buf.putPrefixedString("ABC", encoder);
809         assertEquals(5, buf.position());
810         assertEquals(0, buf.get(0));
811         assertEquals(3, buf.get(1));
812         assertEquals('A', buf.get(2));
813         assertEquals('B', buf.get(3));
814         assertEquals('C', buf.get(4));
815 
816         buf.clear();
817         try {
818             buf.putPrefixedString("123456789012345", encoder);
819             fail();
820         } catch (BufferOverflowException e) {
821             // Expected an Exception, signifies test success
822             assertTrue(true);
823         }
824 
825         // With autoExpand
826         buf.clear();
827         buf.setAutoExpand(true);
828         buf.putPrefixedString("123456789012345", encoder);
829         assertEquals(17, buf.position());
830         assertEquals(0, buf.get(0));
831         assertEquals(15, buf.get(1));
832         assertEquals('1', buf.get(2));
833         assertEquals('2', buf.get(3));
834         assertEquals('3', buf.get(4));
835         assertEquals('4', buf.get(5));
836         assertEquals('5', buf.get(6));
837         assertEquals('6', buf.get(7));
838         assertEquals('7', buf.get(8));
839         assertEquals('8', buf.get(9));
840         assertEquals('9', buf.get(10));
841         assertEquals('0', buf.get(11));
842         assertEquals('1', buf.get(12));
843         assertEquals('2', buf.get(13));
844         assertEquals('3', buf.get(14));
845         assertEquals('4', buf.get(15));
846         assertEquals('5', buf.get(16));
847     }
848 
849     @Test
850     public void testPutPrefixedStringWithPrefixLength() throws Exception {
851         CharsetEncoder encoder = Charset.forName("ISO-8859-1").newEncoder();
852         IoBuffer buf = IoBuffer.allocate(16).sweep().setAutoExpand(true);
853 
854         buf.putPrefixedString("A", 1, encoder);
855         assertEquals(2, buf.position());
856         assertEquals(1, buf.get(0));
857         assertEquals('A', buf.get(1));
858 
859         buf.sweep();
860         buf.putPrefixedString("A", 2, encoder);
861         assertEquals(3, buf.position());
862         assertEquals(0, buf.get(0));
863         assertEquals(1, buf.get(1));
864         assertEquals('A', buf.get(2));
865 
866         buf.sweep();
867         buf.putPrefixedString("A", 4, encoder);
868         assertEquals(5, buf.position());
869         assertEquals(0, buf.get(0));
870         assertEquals(0, buf.get(1));
871         assertEquals(0, buf.get(2));
872         assertEquals(1, buf.get(3));
873         assertEquals('A', buf.get(4));
874     }
875 
876     @Test
877     public void testPutPrefixedStringWithPadding() throws Exception {
878         CharsetEncoder encoder = Charset.forName("ISO-8859-1").newEncoder();
879         IoBuffer buf = IoBuffer.allocate(16).sweep().setAutoExpand(true);
880 
881         buf.putPrefixedString("A", 1, 2, (byte) 32, encoder);
882         assertEquals(3, buf.position());
883         assertEquals(2, buf.get(0));
884         assertEquals('A', buf.get(1));
885         assertEquals(' ', buf.get(2));
886 
887         buf.sweep();
888         buf.putPrefixedString("A", 1, 4, (byte) 32, encoder);
889         assertEquals(5, buf.position());
890         assertEquals(4, buf.get(0));
891         assertEquals('A', buf.get(1));
892         assertEquals(' ', buf.get(2));
893         assertEquals(' ', buf.get(3));
894         assertEquals(' ', buf.get(4));
895     }
896 
897     @Test
898     public void testWideUtf8Characters() throws Exception {
899         Runnable r = new Runnable() {
900             public void run() {
901                 IoBuffer buffer = IoBuffer.allocate(1);
902                 buffer.setAutoExpand(true);
903 
904                 Charset charset = Charset.forName("UTF-8");
905 
906                 CharsetEncoder encoder = charset.newEncoder();
907 
908                 for (int i = 0; i < 5; i++) {
909                     try {
910                         buffer.putString("\u89d2", encoder);
911                         buffer.putPrefixedString("\u89d2", encoder);
912                     } catch (CharacterCodingException e) {
913                         fail(e.getMessage());
914                     }
915                 }
916             }
917         };
918 
919         Thread t = new Thread(r);
920         t.setDaemon(true);
921         t.start();
922 
923         for (int i = 0; i < 50; i++) {
924             Thread.sleep(100);
925             if (!t.isAlive()) {
926                 break;
927             }
928         }
929 
930         if (t.isAlive()) {
931             t.interrupt();
932 
933             fail("Went into endless loop trying to encode character");
934         }
935     }
936 
937     @Test
938     public void testInheritedObjectSerialization() throws Exception {
939         IoBuffer buf = IoBuffer.allocate(16);
940         buf.setAutoExpand(true);
941 
942         Bar expected = new Bar();
943         expected.setFooValue(0x12345678);
944         expected.setBarValue(0x90ABCDEF);
945 
946         // Test writing an object.
947         buf.putObject(expected);
948 
949         // Test reading an object.
950         buf.clear();
951         Bar actual = (Bar) buf.getObject();
952         assertSame(Bar.class, actual.getClass());
953         assertEquals(expected.getFooValue(), actual.getFooValue());
954         assertEquals(expected.getBarValue(), actual.getBarValue());
955 
956         // This assertion is just to make sure that deserialization occurred.
957         assertNotSame(expected, actual);
958     }
959 
960     @Test
961     public void testSweepWithZeros() throws Exception {
962         IoBuffer buf = IoBuffer.allocate(4);
963         buf.putInt(0xdeadbeef);
964         buf.clear();
965         assertEquals(0xdeadbeef, buf.getInt());
966         assertEquals(4, buf.position());
967         assertEquals(4, buf.limit());
968 
969         buf.sweep();
970         assertEquals(0, buf.position());
971         assertEquals(4, buf.limit());
972         assertEquals(0x0, buf.getInt());
973     }
974 
975     @Test
976     public void testSweepNonZeros() throws Exception {
977         IoBuffer buf = IoBuffer.allocate(4);
978         buf.putInt(0xdeadbeef);
979         buf.clear();
980         assertEquals(0xdeadbeef, buf.getInt());
981         assertEquals(4, buf.position());
982         assertEquals(4, buf.limit());
983 
984         buf.sweep((byte) 0x45);
985         assertEquals(0, buf.position());
986         assertEquals(4, buf.limit());
987         assertEquals(0x45454545, buf.getInt());
988     }
989 
990     @Test
991     public void testWrapNioBuffer() throws Exception {
992         ByteBuffer nioBuf = ByteBuffer.allocate(10);
993         nioBuf.position(3);
994         nioBuf.limit(7);
995 
996         IoBuffer buf = IoBuffer.wrap(nioBuf);
997         assertEquals(3, buf.position());
998         assertEquals(7, buf.limit());
999         assertEquals(10, buf.capacity());
1000     }
1001 
1002     @Test
1003     public void testWrapSubArray() throws Exception {
1004         byte[] array = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
1005 
1006         IoBuffer buf = IoBuffer.wrap(array, 3, 4);
1007         assertEquals(3, buf.position());
1008         assertEquals(7, buf.limit());
1009         assertEquals(10, buf.capacity());
1010 
1011         buf.clear();
1012         assertEquals(0, buf.position());
1013         assertEquals(10, buf.limit());
1014         assertEquals(10, buf.capacity());
1015     }
1016 
1017     @Test
1018     public void testDuplicate() throws Exception {
1019         IoBuffer original;
1020         IoBuffer duplicate;
1021 
1022         // Test if the buffer is duplicated correctly.
1023         original = IoBuffer.allocate(16).sweep();
1024         original.position(4);
1025         original.limit(10);
1026         duplicate = original.duplicate();
1027         original.put(4, (byte) 127);
1028         assertEquals(4, duplicate.position());
1029         assertEquals(10, duplicate.limit());
1030         assertEquals(16, duplicate.capacity());
1031         assertNotSame(original.buf(), duplicate.buf());
1032         assertSame(original.buf().array(), duplicate.buf().array());
1033         assertEquals(127, duplicate.get(4));
1034 
1035         // Test a duplicate of a duplicate.
1036         original = IoBuffer.allocate(16);
1037         duplicate = original.duplicate().duplicate();
1038         assertNotSame(original.buf(), duplicate.buf());
1039         assertSame(original.buf().array(), duplicate.buf().array());
1040 
1041         // Try to expand.
1042         original = IoBuffer.allocate(16);
1043         original.setAutoExpand(true);
1044         duplicate = original.duplicate();
1045         assertFalse(original.isAutoExpand());
1046 
1047         try {
1048             original.setAutoExpand(true);
1049             fail("Derived buffers and their parent can't be expanded");
1050         } catch (IllegalStateException e) {
1051             // Expected an Exception, signifies test success
1052             assertTrue(true);
1053         }
1054 
1055         try {
1056             duplicate.setAutoExpand(true);
1057             fail("Derived buffers and their parent can't be expanded");
1058         } catch (IllegalStateException e) {
1059             // Expected an Exception, signifies test success
1060             assertTrue(true);
1061         }
1062     }
1063 
1064     @Test
1065     public void testSlice() throws Exception {
1066         IoBuffer original;
1067         IoBuffer slice;
1068 
1069         // Test if the buffer is sliced correctly.
1070         original = IoBuffer.allocate(16).sweep();
1071         original.position(4);
1072         original.limit(10);
1073         slice = original.slice();
1074         original.put(4, (byte) 127);
1075         assertEquals(0, slice.position());
1076         assertEquals(6, slice.limit());
1077         assertEquals(6, slice.capacity());
1078         assertNotSame(original.buf(), slice.buf());
1079         assertEquals(127, slice.get(0));
1080     }
1081 
1082     @Test
1083     public void testReadOnlyBuffer() throws Exception {
1084         IoBuffer original;
1085         IoBuffer duplicate;
1086 
1087         // Test if the buffer is duplicated correctly.
1088         original = IoBuffer.allocate(16).sweep();
1089         original.position(4);
1090         original.limit(10);
1091         duplicate = original.asReadOnlyBuffer();
1092         original.put(4, (byte) 127);
1093         assertEquals(4, duplicate.position());
1094         assertEquals(10, duplicate.limit());
1095         assertEquals(16, duplicate.capacity());
1096         assertNotSame(original.buf(), duplicate.buf());
1097         assertEquals(127, duplicate.get(4));
1098 
1099         // Try to expand.
1100         try {
1101             original = IoBuffer.allocate(16);
1102             duplicate = original.asReadOnlyBuffer();
1103             duplicate.putString("A very very very very looooooong string", Charset.forName("ISO-8859-1").newEncoder());
1104             fail("ReadOnly buffer's can't be expanded");
1105         } catch (ReadOnlyBufferException e) {
1106             // Expected an Exception, signifies test success
1107             assertTrue(true);
1108         }
1109     }
1110 
1111     @Test
1112     public void testGetUnsigned() throws Exception {
1113         IoBuffer buf = IoBuffer.allocate(16);
1114         buf.put((byte) 0xA4);
1115         buf.put((byte) 0xD0);
1116         buf.put((byte) 0xB3);
1117         buf.put((byte) 0xCD);
1118         buf.flip();
1119 
1120         buf.order(ByteOrder.LITTLE_ENDIAN);
1121 
1122         buf.mark();
1123         assertEquals(0xA4, buf.getUnsigned());
1124         buf.reset();
1125         assertEquals(0xD0A4, buf.getUnsignedShort());
1126         buf.reset();
1127         assertEquals(0xCDB3D0A4L, buf.getUnsignedInt());
1128     }
1129 
1130     @Test
1131     public void testIndexOf() throws Exception {
1132         boolean direct = false;
1133         for (int i = 0; i < 2; i++, direct = !direct) {
1134             IoBuffer buf = IoBuffer.allocate(16, direct);
1135             buf.put((byte) 0x1);
1136             buf.put((byte) 0x2);
1137             buf.put((byte) 0x3);
1138             buf.put((byte) 0x4);
1139             buf.put((byte) 0x1);
1140             buf.put((byte) 0x2);
1141             buf.put((byte) 0x3);
1142             buf.put((byte) 0x4);
1143             buf.position(2);
1144             buf.limit(5);
1145 
1146             assertEquals(4, buf.indexOf((byte) 0x1));
1147             assertEquals(-1, buf.indexOf((byte) 0x2));
1148             assertEquals(2, buf.indexOf((byte) 0x3));
1149             assertEquals(3, buf.indexOf((byte) 0x4));
1150         }
1151     }
1152 
1153     // We need an enum with 64 values
1154     private static enum TestEnum {
1155         E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13, E14, E15, E16, E17, E18, E19, E20, E21, E22, E23, E24, E25, E26, E27, E28, E29, E30, E31, E32, E33, E34, E35, E36, E37, E38, E39, E40, E41, E42, E43, E44, E45, E46, E77, E48, E49, E50, E51, E52, E53, E54, E55, E56, E57, E58, E59, E60, E61, E62, E63, E64
1156     }
1157 
1158     private static enum TooBigEnum {
1159         E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13, E14, E15, E16, E17, E18, E19, E20, E21, E22, E23, E24, E25, E26, E27, E28, E29, E30, E31, E32, E33, E34, E35, E36, E37, E38, E39, E40, E41, E42, E43, E44, E45, E46, E77, E48, E49, E50, E51, E52, E53, E54, E55, E56, E57, E58, E59, E60, E61, E62, E63, E64, E65
1160     }
1161 
1162     @Test
1163     public void testPutEnumSet() {
1164         IoBuffer buf = IoBuffer.allocate(8);
1165 
1166         // Test empty set
1167         buf.putEnumSet(EnumSet.noneOf(TestEnum.class));
1168         buf.flip();
1169         assertEquals(0, buf.get());
1170 
1171         buf.clear();
1172         buf.putEnumSetShort(EnumSet.noneOf(TestEnum.class));
1173         buf.flip();
1174         assertEquals(0, buf.getShort());
1175 
1176         buf.clear();
1177         buf.putEnumSetInt(EnumSet.noneOf(TestEnum.class));
1178         buf.flip();
1179         assertEquals(0, buf.getInt());
1180 
1181         buf.clear();
1182         buf.putEnumSetLong(EnumSet.noneOf(TestEnum.class));
1183         buf.flip();
1184         assertEquals(0, buf.getLong());
1185 
1186         // Test complete set
1187         buf.clear();
1188         buf.putEnumSet(EnumSet.range(TestEnum.E1, TestEnum.E8));
1189         buf.flip();
1190         assertEquals((byte) -1, buf.get());
1191 
1192         buf.clear();
1193         buf.putEnumSetShort(EnumSet.range(TestEnum.E1, TestEnum.E16));
1194         buf.flip();
1195         assertEquals((short) -1, buf.getShort());
1196 
1197         buf.clear();
1198         buf.putEnumSetInt(EnumSet.range(TestEnum.E1, TestEnum.E32));
1199         buf.flip();
1200         assertEquals(-1, buf.getInt());
1201 
1202         buf.clear();
1203         buf.putEnumSetLong(EnumSet.allOf(TestEnum.class));
1204         buf.flip();
1205         assertEquals(-1L, buf.getLong());
1206 
1207         // Test high bit set
1208         buf.clear();
1209         buf.putEnumSet(EnumSet.of(TestEnum.E8));
1210         buf.flip();
1211         assertEquals(Byte.MIN_VALUE, buf.get());
1212 
1213         buf.clear();
1214         buf.putEnumSetShort(EnumSet.of(TestEnum.E16));
1215         buf.flip();
1216         assertEquals(Short.MIN_VALUE, buf.getShort());
1217 
1218         buf.clear();
1219         buf.putEnumSetInt(EnumSet.of(TestEnum.E32));
1220         buf.flip();
1221         assertEquals(Integer.MIN_VALUE, buf.getInt());
1222 
1223         buf.clear();
1224         buf.putEnumSetLong(EnumSet.of(TestEnum.E64));
1225         buf.flip();
1226         assertEquals(Long.MIN_VALUE, buf.getLong());
1227 
1228         // Test high low bits set
1229         buf.clear();
1230         buf.putEnumSet(EnumSet.of(TestEnum.E1, TestEnum.E8));
1231         buf.flip();
1232         assertEquals(Byte.MIN_VALUE + 1, buf.get());
1233 
1234         buf.clear();
1235         buf.putEnumSetShort(EnumSet.of(TestEnum.E1, TestEnum.E16));
1236         buf.flip();
1237         assertEquals(Short.MIN_VALUE + 1, buf.getShort());
1238 
1239         buf.clear();
1240         buf.putEnumSetInt(EnumSet.of(TestEnum.E1, TestEnum.E32));
1241         buf.flip();
1242         assertEquals(Integer.MIN_VALUE + 1, buf.getInt());
1243 
1244         buf.clear();
1245         buf.putEnumSetLong(EnumSet.of(TestEnum.E1, TestEnum.E64));
1246         buf.flip();
1247         assertEquals(Long.MIN_VALUE + 1, buf.getLong());
1248     }
1249 
1250     @Test
1251     public void testGetEnumSet() {
1252         IoBuffer buf = IoBuffer.allocate(8);
1253 
1254         // Test empty set
1255         buf.put((byte) 0);
1256         buf.flip();
1257         assertEquals(EnumSet.noneOf(TestEnum.class), buf.getEnumSet(TestEnum.class));
1258 
1259         buf.clear();
1260         buf.putShort((short) 0);
1261         buf.flip();
1262         assertEquals(EnumSet.noneOf(TestEnum.class), buf.getEnumSet(TestEnum.class));
1263 
1264         buf.clear();
1265         buf.putInt(0);
1266         buf.flip();
1267         assertEquals(EnumSet.noneOf(TestEnum.class), buf.getEnumSet(TestEnum.class));
1268 
1269         buf.clear();
1270         buf.putLong(0L);
1271         buf.flip();
1272         assertEquals(EnumSet.noneOf(TestEnum.class), buf.getEnumSet(TestEnum.class));
1273 
1274         // Test complete set
1275         buf.clear();
1276         buf.put((byte) -1);
1277         buf.flip();
1278         assertEquals(EnumSet.range(TestEnum.E1, TestEnum.E8), buf.getEnumSet(TestEnum.class));
1279 
1280         buf.clear();
1281         buf.putShort((short) -1);
1282         buf.flip();
1283         assertEquals(EnumSet.range(TestEnum.E1, TestEnum.E16), buf.getEnumSetShort(TestEnum.class));
1284 
1285         buf.clear();
1286         buf.putInt(-1);
1287         buf.flip();
1288         assertEquals(EnumSet.range(TestEnum.E1, TestEnum.E32), buf.getEnumSetInt(TestEnum.class));
1289 
1290         buf.clear();
1291         buf.putLong(-1L);
1292         buf.flip();
1293         assertEquals(EnumSet.allOf(TestEnum.class), buf.getEnumSetLong(TestEnum.class));
1294 
1295         // Test high bit set
1296         buf.clear();
1297         buf.put(Byte.MIN_VALUE);
1298         buf.flip();
1299         assertEquals(EnumSet.of(TestEnum.E8), buf.getEnumSet(TestEnum.class));
1300 
1301         buf.clear();
1302         buf.putShort(Short.MIN_VALUE);
1303         buf.flip();
1304         assertEquals(EnumSet.of(TestEnum.E16), buf.getEnumSetShort(TestEnum.class));
1305 
1306         buf.clear();
1307         buf.putInt(Integer.MIN_VALUE);
1308         buf.flip();
1309         assertEquals(EnumSet.of(TestEnum.E32), buf.getEnumSetInt(TestEnum.class));
1310 
1311         buf.clear();
1312         buf.putLong(Long.MIN_VALUE);
1313         buf.flip();
1314         assertEquals(EnumSet.of(TestEnum.E64), buf.getEnumSetLong(TestEnum.class));
1315 
1316         // Test high low bits set
1317         buf.clear();
1318         byte b = Byte.MIN_VALUE + 1;
1319         buf.put(b);
1320         buf.flip();
1321         assertEquals(EnumSet.of(TestEnum.E1, TestEnum.E8), buf.getEnumSet(TestEnum.class));
1322 
1323         buf.clear();
1324         short s = Short.MIN_VALUE + 1;
1325         buf.putShort(s);
1326         buf.flip();
1327         assertEquals(EnumSet.of(TestEnum.E1, TestEnum.E16), buf.getEnumSetShort(TestEnum.class));
1328 
1329         buf.clear();
1330         buf.putInt(Integer.MIN_VALUE + 1);
1331         buf.flip();
1332         assertEquals(EnumSet.of(TestEnum.E1, TestEnum.E32), buf.getEnumSetInt(TestEnum.class));
1333 
1334         buf.clear();
1335         buf.putLong(Long.MIN_VALUE + 1);
1336         buf.flip();
1337         assertEquals(EnumSet.of(TestEnum.E1, TestEnum.E64), buf.getEnumSetLong(TestEnum.class));
1338     }
1339 
1340     @Test
1341     public void testBitVectorOverFlow() {
1342         IoBuffer buf = IoBuffer.allocate(8);
1343         try {
1344             buf.putEnumSet(EnumSet.of(TestEnum.E9));
1345             fail("Should have thrown IllegalArgumentException");
1346         } catch (IllegalArgumentException e) {
1347             // Expected an Exception, signifies test success
1348             assertTrue(true);
1349         }
1350 
1351         try {
1352             buf.putEnumSetShort(EnumSet.of(TestEnum.E17));
1353             fail("Should have thrown IllegalArgumentException");
1354         } catch (IllegalArgumentException e) {
1355             // Expected an Exception, signifies test success
1356             assertTrue(true);
1357         }
1358 
1359         try {
1360             buf.putEnumSetInt(EnumSet.of(TestEnum.E33));
1361             fail("Should have thrown IllegalArgumentException");
1362         } catch (IllegalArgumentException e) {
1363             // Expected an Exception, signifies test success
1364             assertTrue(true);
1365         }
1366 
1367         try {
1368             buf.putEnumSetLong(EnumSet.of(TooBigEnum.E65));
1369             fail("Should have thrown IllegalArgumentException");
1370         } catch (IllegalArgumentException e) {
1371             // Expected an Exception, signifies test success
1372             assertTrue(true);
1373         }
1374     }
1375 
1376     @Test
1377     public void testGetPutEnum() {
1378         IoBuffer buf = IoBuffer.allocate(4);
1379 
1380         buf.putEnum(TestEnum.E64);
1381         buf.flip();
1382         assertEquals(TestEnum.E64, buf.getEnum(TestEnum.class));
1383 
1384         buf.clear();
1385         buf.putEnumShort(TestEnum.E64);
1386         buf.flip();
1387         assertEquals(TestEnum.E64, buf.getEnumShort(TestEnum.class));
1388 
1389         buf.clear();
1390         buf.putEnumInt(TestEnum.E64);
1391         buf.flip();
1392         assertEquals(TestEnum.E64, buf.getEnumInt(TestEnum.class));
1393     }
1394 
1395     @Test
1396     public void testGetMediumInt() {
1397         IoBuffer buf = IoBuffer.allocate(3);
1398 
1399         buf.put((byte) 0x01);
1400         buf.put((byte) 0x02);
1401         buf.put((byte) 0x03);
1402         assertEquals(3, buf.position());
1403 
1404         buf.flip();
1405         assertEquals(0x010203, buf.getMediumInt());
1406         assertEquals(0x010203, buf.getMediumInt(0));
1407         buf.flip();
1408         assertEquals(0x010203, buf.getUnsignedMediumInt());
1409         assertEquals(0x010203, buf.getUnsignedMediumInt(0));
1410         buf.flip();
1411         assertEquals(0x010203, buf.getUnsignedMediumInt());
1412         buf.flip().order(ByteOrder.LITTLE_ENDIAN);
1413         assertEquals(0x030201, buf.getMediumInt());
1414         assertEquals(0x030201, buf.getMediumInt(0));
1415 
1416         // Test max medium int
1417         buf.flip().order(ByteOrder.BIG_ENDIAN);
1418         buf.put((byte) 0x7f);
1419         buf.put((byte) 0xff);
1420         buf.put((byte) 0xff);
1421         buf.flip();
1422         assertEquals(0x7fffff, buf.getMediumInt());
1423         assertEquals(0x7fffff, buf.getMediumInt(0));
1424 
1425         // Test negative number
1426         buf.flip().order(ByteOrder.BIG_ENDIAN);
1427         buf.put((byte) 0xff);
1428         buf.put((byte) 0x02);
1429         buf.put((byte) 0x03);
1430         buf.flip();
1431 
1432         assertEquals(0xffff0203, buf.getMediumInt());
1433         assertEquals(0xffff0203, buf.getMediumInt(0));
1434         buf.flip();
1435 
1436         assertEquals(0x00ff0203, buf.getUnsignedMediumInt());
1437         assertEquals(0x00ff0203, buf.getUnsignedMediumInt(0));
1438     }
1439 
1440     @Test
1441     public void testPutMediumInt() {
1442         IoBuffer buf = IoBuffer.allocate(3);
1443 
1444         checkMediumInt(buf, 0);
1445         checkMediumInt(buf, 1);
1446         checkMediumInt(buf, -1);
1447         checkMediumInt(buf, 0x7fffff);
1448     }
1449 
1450     private void checkMediumInt(IoBuffer buf, int x) {
1451         buf.putMediumInt(x);
1452         assertEquals(3, buf.position());
1453         buf.flip();
1454         assertEquals(x, buf.getMediumInt());
1455         assertEquals(3, buf.position());
1456 
1457         buf.putMediumInt(0, x);
1458         assertEquals(3, buf.position());
1459         assertEquals(x, buf.getMediumInt(0));
1460 
1461         buf.flip();
1462     }
1463 
1464     @Test
1465     public void testPutUnsigned() {
1466         IoBuffer buf = IoBuffer.allocate(4);
1467         byte b = (byte) 0x80; // We should get 0x0080
1468         short s = (short) 0x8F81; // We should get 0x0081
1469         int i = 0x8FFFFF82; // We should get 0x0082
1470         long l = 0x8FFFFFFFFFFFFF83L; // We should get 0x0083
1471 
1472         buf.mark();
1473 
1474         // Put the unsigned bytes
1475         buf.putUnsigned(b);
1476         buf.putUnsigned(s);
1477         buf.putUnsigned(i);
1478         buf.putUnsigned(l);
1479 
1480         buf.reset();
1481 
1482         // Read back the unsigned bytes
1483         assertEquals(0x0080, buf.getUnsigned());
1484         assertEquals(0x0081, buf.getUnsigned());
1485         assertEquals(0x0082, buf.getUnsigned());
1486         assertEquals(0x0083, buf.getUnsigned());
1487     }
1488 
1489     @Test
1490     public void testPutUnsignedIndex() {
1491         IoBuffer buf = IoBuffer.allocate(4);
1492         byte b = (byte) 0x80; // We should get 0x0080
1493         short s = (short) 0x8F81; // We should get 0x0081
1494         int i = 0x8FFFFF82; // We should get 0x0082
1495         long l = 0x8FFFFFFFFFFFFF83L; // We should get 0x0083
1496 
1497         buf.mark();
1498 
1499         // Put the unsigned bytes
1500         buf.putUnsigned(3, b);
1501         buf.putUnsigned(2, s);
1502         buf.putUnsigned(1, i);
1503         buf.putUnsigned(0, l);
1504 
1505         buf.reset();
1506 
1507         // Read back the unsigned bytes
1508         assertEquals(0x0083, buf.getUnsigned());
1509         assertEquals(0x0082, buf.getUnsigned());
1510         assertEquals(0x0081, buf.getUnsigned());
1511         assertEquals(0x0080, buf.getUnsigned());
1512     }
1513 
1514     @Test
1515     public void testPutUnsignedShort() {
1516         IoBuffer buf = IoBuffer.allocate(8);
1517         byte b = (byte) 0x80; // We should get 0x0080
1518         short s = (short) 0x8181; // We should get 0x8181
1519         int i = 0x82828282; // We should get 0x8282
1520         long l = 0x8383838383838383L; // We should get 0x8383
1521 
1522         buf.mark();
1523 
1524         // Put the unsigned bytes
1525         buf.putUnsignedShort(b);
1526         buf.putUnsignedShort(s);
1527         buf.putUnsignedShort(i);
1528         buf.putUnsignedShort(l);
1529 
1530         buf.reset();
1531 
1532         // Read back the unsigned bytes
1533         assertEquals(0x0080L, buf.getUnsignedShort());
1534         assertEquals(0x8181L, buf.getUnsignedShort());
1535         assertEquals(0x8282L, buf.getUnsignedShort());
1536         assertEquals(0x8383L, buf.getUnsignedShort());
1537     }
1538 
1539     @Test
1540     public void testPutUnsignedShortIndex() {
1541         IoBuffer buf = IoBuffer.allocate(8);
1542         byte b = (byte) 0x80; // We should get 0x00000080
1543         short s = (short) 0x8181; // We should get 0x00008181
1544         int i = 0x82828282; // We should get 0x82828282
1545         long l = 0x8383838383838383L; // We should get 0x83838383
1546 
1547         buf.mark();
1548 
1549         // Put the unsigned shorts
1550         buf.putUnsignedShort(6, b);
1551         buf.putUnsignedShort(4, s);
1552         buf.putUnsignedShort(2, i);
1553         buf.putUnsignedShort(0, l);
1554 
1555         buf.reset();
1556 
1557         // Read back the unsigned bytes
1558         assertEquals(0x8383L, buf.getUnsignedShort());
1559         assertEquals(0x8282L, buf.getUnsignedShort());
1560         assertEquals(0x8181L, buf.getUnsignedShort());
1561         assertEquals(0x0080L, buf.getUnsignedShort());
1562     }
1563 
1564     @Test
1565     public void testPutUnsignedInt() {
1566         IoBuffer buf = IoBuffer.allocate(16);
1567         byte b = (byte) 0x80; // We should get 0x00000080
1568         short s = (short) 0x8181; // We should get 0x00008181
1569         int i = 0x82828282; // We should get 0x82828282
1570         long l = 0x8383838383838383L; // We should get 0x83838383
1571 
1572         buf.mark();
1573 
1574         // Put the unsigned bytes
1575         buf.putUnsignedInt(b);
1576         buf.putUnsignedInt(s);
1577         buf.putUnsignedInt(i);
1578         buf.putUnsignedInt(l);
1579 
1580         buf.reset();
1581 
1582         // Read back the unsigned bytes
1583         assertEquals(0x0000000000000080L, buf.getUnsignedInt());
1584         assertEquals(0x0000000000008181L, buf.getUnsignedInt());
1585         assertEquals(0x0000000082828282L, buf.getUnsignedInt());
1586         assertEquals(0x0000000083838383L, buf.getUnsignedInt());
1587     }
1588 
1589     /**
1590      * Test the IoBuffer.putUnsignedInIndex() method.
1591      */
1592     @Test
1593     public void testPutUnsignedIntIndex() {
1594         IoBuffer buf = IoBuffer.allocate(16);
1595         byte b = (byte) 0x80; // We should get 0x00000080
1596         short s = (short) 0x8181; // We should get 0x00008181
1597         int i = 0x82828282; // We should get 0x82828282
1598         long l = 0x8383838383838383L; // We should get 0x83838383
1599 
1600         buf.mark();
1601 
1602         // Put the unsigned bytes
1603         buf.putUnsignedInt(12, b);
1604         buf.putUnsignedInt(8, s);
1605         buf.putUnsignedInt(4, i);
1606         buf.putUnsignedInt(0, l);
1607 
1608         buf.reset();
1609 
1610         // Read back the unsigned bytes
1611         assertEquals(0x0000000083838383L, buf.getUnsignedInt());
1612         assertEquals(0x0000000082828282L, buf.getUnsignedInt());
1613         assertEquals(0x0000000000008181L, buf.getUnsignedInt());
1614         assertEquals(0x0000000000000080L, buf.getUnsignedInt());
1615     }
1616 
1617     /**
1618      * Test the getSlice method (even if we haven't flipped the buffer)
1619      */
1620     @Test
1621     public void testGetSlice() {
1622         IoBuffer buf = IoBuffer.allocate(36);
1623 
1624         for (byte i = 0; i < 36; i++) {
1625             buf.put(i);
1626         }
1627 
1628         IoBuffer res = buf.getSlice(1, 3);
1629 
1630         // The limit should be 3, the pos should be 0 and the bytes read
1631         // should be 0x01, 0x02 and 0x03
1632         assertEquals(0, res.position());
1633         assertEquals(3, res.limit());
1634         assertEquals(0x01, res.get());
1635         assertEquals(0x02, res.get());
1636         assertEquals(0x03, res.get());
1637 
1638         // Now test after a flip
1639         buf.flip();
1640 
1641         res = buf.getSlice(1, 3);
1642         // The limit should be 3, the pos should be 0 and the bytes read
1643         // should be 0x01, 0x02 and 0x03
1644         assertEquals(0, res.position());
1645         assertEquals(3, res.limit());
1646         assertEquals(0x01, res.get());
1647         assertEquals(0x02, res.get());
1648         assertEquals(0x03, res.get());
1649     }
1650 
1651     /**
1652      * Test the IoBuffer.shrink() method.
1653      */
1654     @Test
1655     public void testShrink() {
1656         IoBuffer buf = IoBuffer.allocate(36);
1657         buf.put( "012345".getBytes());
1658         buf.flip();
1659         buf.position(4);
1660         buf.minimumCapacity(8);
1661 
1662         IoBuffer newBuf = buf.shrink();
1663         assertEquals(4, newBuf.position());
1664         assertEquals(6, newBuf.limit());
1665         assertEquals(9, newBuf.capacity());
1666         assertEquals(8, newBuf.minimumCapacity());
1667 
1668         buf = IoBuffer.allocate(6);
1669         buf.put( "012345".getBytes());
1670         buf.flip();
1671         buf.position(4);
1672 
1673         newBuf = buf.shrink();
1674         assertEquals(4, newBuf.position());
1675         assertEquals(6, newBuf.limit());
1676         assertEquals(6, newBuf.capacity());
1677         assertEquals(6, newBuf.minimumCapacity());
1678     }
1679     
1680     
1681     /**
1682      * Test the IoBuffer.position(newPosition) method.
1683      */
1684     @Test
1685     public void testSetPosition()
1686     {
1687         
1688     }
1689 }