001/*
002 *  Licensed to the Apache Software Foundation (ASF) under one
003 *  or more contributor license agreements.  See the NOTICE file
004 *  distributed with this work for additional information
005 *  regarding copyright ownership.  The ASF licenses this file
006 *  to you under the Apache License, Version 2.0 (the
007 *  "License"); you may not use this file except in compliance
008 *  with the License.  You may obtain a copy of the License at
009 *
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *
012 *  Unless required by applicable law or agreed to in writing,
013 *  software distributed under the License is distributed on an
014 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 *  KIND, either express or implied.  See the License for the
016 *  specific language governing permissions and limitations
017 *  under the License.
018 *
019 */
020package org.apache.mina.core.buffer;
021
022import static org.junit.Assert.assertEquals;
023import static org.junit.Assert.assertFalse;
024import static org.junit.Assert.assertNotSame;
025import static org.junit.Assert.assertSame;
026import static org.junit.Assert.assertTrue;
027import static org.junit.Assert.fail;
028
029import java.nio.BufferOverflowException;
030import java.nio.ByteBuffer;
031import java.nio.ByteOrder;
032import java.nio.ReadOnlyBufferException;
033import java.nio.charset.CharacterCodingException;
034import java.nio.charset.Charset;
035import java.nio.charset.CharsetDecoder;
036import java.nio.charset.CharsetEncoder;
037import java.util.ArrayList;
038import java.util.Date;
039import java.util.EnumSet;
040import java.util.List;
041
042import org.apache.mina.util.Bar;
043import org.junit.Test;
044
045/**
046 * Tests the {@link IoBuffer} class.
047 * 
048 * @author <a href="http://mina.apache.org">Apache MINA Project</a>
049 */
050public class IoBufferTest {
051
052    private static interface NonserializableInterface {
053    }
054
055    public static class NonserializableClass {
056    }
057
058    /**
059     * Test the capacity(newCapacity) method.
060     */
061    @Test
062    public void testCapacity() {
063        IoBuffer buffer = IoBuffer.allocate(10);
064        
065        buffer.put("012345".getBytes());
066        buffer.flip();
067        
068        // See if we can decrease the capacity (we shouldn't be able to go under the minimul capacity)
069        IoBuffer newBuffer = buffer.capacity(7);
070        assertEquals(10, newBuffer.capacity());
071        assertEquals(buffer, newBuffer);
072        
073        // See if we can increase the capacity
074        buffer = IoBuffer.allocate(10);
075        
076        buffer.put("012345".getBytes());
077        buffer.flip();
078        newBuffer = buffer.capacity(14);
079        assertEquals(14, newBuffer.capacity());
080        assertEquals(buffer, newBuffer);
081        newBuffer.put(0, (byte)'9');
082        assertEquals((byte)'9', newBuffer.get(0));
083        assertEquals((byte)'9', buffer.get(0));
084        
085        // See if we can go down when the minimum capacity is below the current capacity
086        // We should not.
087        buffer = IoBuffer.allocate(10);
088        buffer.capacity(5);
089        assertEquals(10, buffer.minimumCapacity());
090        assertEquals(10, buffer.capacity());
091    }
092
093    /**
094     * Test the expand(expectedRemaining) method.
095     */
096    @Test
097    public void testExpand() {
098        IoBuffer buffer = IoBuffer.allocate(10);
099        
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
1690    
1691    @Test
1692    public void testFillByteSize()
1693    {
1694        int length = 1024*1020;
1695        IoBuffer buffer = IoBuffer.allocate(length);
1696        buffer.fill((byte)0x80, length);
1697        
1698        buffer.flip();
1699        for (int i=0; i<length; i++) {
1700            assertEquals((byte)0x80, buffer.get());
1701        }
1702    }
1703}