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.common;
21  
22  import java.nio.BufferOverflowException;
23  import java.nio.ByteOrder;
24  import java.nio.ReadOnlyBufferException;
25  import java.nio.charset.CharacterCodingException;
26  import java.nio.charset.Charset;
27  import java.nio.charset.CharsetDecoder;
28  import java.nio.charset.CharsetEncoder;
29  import java.util.ArrayList;
30  import java.util.Date;
31  import java.util.List;
32  
33  import junit.framework.Assert;
34  import junit.framework.TestCase;
35  
36  /**
37   * Tests {@link ByteBuffer}.
38   *
39   * @author The Apache Directory Project (mina-dev@directory.apache.org)
40   * @version $Rev: 595517 $, $Date: 2007-11-16 10:31:56 +0900 (금, 16 11월 2007) $
41   */
42  public class ByteBufferTest extends TestCase {
43  
44      public static void main(String[] args) {
45          junit.textui.TestRunner.run(ByteBufferTest.class);
46      }
47  
48      @Override
49      protected void setUp() throws Exception {
50      }
51  
52      @Override
53      protected void tearDown() throws Exception {
54      }
55  
56      public void testAllocate() throws Exception {
57          for (int i = 10; i < 1048576 * 2; i = i * 11 / 10) // increase by 10%
58          {
59              ByteBuffer buf = ByteBuffer.allocate(i);
60              Assert.assertEquals(0, buf.position());
61              Assert.assertEquals(buf.capacity(), buf.remaining());
62              Assert.assertTrue(buf.capacity() >= i);
63              Assert.assertTrue(buf.capacity() < i * 2);
64          }
65      }
66  
67      public void testRelease() throws Exception {
68          for (int i = 10; i < 1048576 * 2; i = i * 11 / 10) // increase by 10%
69          {
70              ByteBuffer buf = ByteBuffer.allocate(i);
71              Assert.assertEquals(0, buf.position());
72              Assert.assertEquals(buf.capacity(), buf.remaining());
73              Assert.assertTrue(buf.capacity() >= i);
74              Assert.assertTrue(buf.capacity() < i * 2);
75              buf.release();
76          }
77      }
78  
79      public void testLeakageDetection() throws Exception {
80          ByteBuffer buf = ByteBuffer.allocate(1024);
81          buf.release();
82          try {
83              buf.release();
84              Assert.fail("Releasing a buffer twice should fail.");
85          } catch (IllegalStateException e) {
86  
87          }
88      }
89  
90      public void testAcquireRelease() throws Exception {
91          ByteBuffer buf = ByteBuffer.allocate(1024);
92          buf.acquire();
93          buf.release();
94          buf.acquire();
95          buf.acquire();
96          buf.release();
97          buf.release();
98          buf.release();
99          try {
100             buf.release();
101             Assert.fail("Releasing a buffer twice should fail.");
102         } catch (IllegalStateException e) {
103         }
104     }
105 
106     public void testAutoExpand() throws Exception {
107         ByteBuffer buf = ByteBuffer.allocate(1);
108 
109         buf.put((byte) 0);
110         try {
111             buf.put((byte) 0);
112             Assert.fail();
113         } catch (BufferOverflowException e) {
114             // ignore
115         }
116 
117         buf.setAutoExpand(true);
118         buf.put((byte) 0);
119         Assert.assertEquals(2, buf.position());
120         Assert.assertEquals(2, buf.limit());
121         Assert.assertEquals(2, buf.capacity());
122 
123         buf.setAutoExpand(false);
124         try {
125             buf.put(3, (byte) 0);
126             Assert.fail();
127         } catch (IndexOutOfBoundsException e) {
128             // ignore
129         }
130 
131         buf.setAutoExpand(true);
132         buf.put(3, (byte) 0);
133         Assert.assertEquals(2, buf.position());
134         Assert.assertEquals(4, buf.limit());
135         Assert.assertEquals(4, buf.capacity());
136     }
137 
138     public void testAutoExpandMark() throws Exception {
139         ByteBuffer buf = ByteBuffer.allocate(4).setAutoExpand(true);
140 
141         buf.put((byte) 0);
142         buf.put((byte) 0);
143         buf.put((byte) 0);
144 
145         // Position should be 3 when we reset this buffer.
146         buf.mark();
147 
148         // Overflow it
149         buf.put((byte) 0);
150         buf.put((byte) 0);
151 
152         Assert.assertEquals(5, buf.position());
153         buf.reset();
154         Assert.assertEquals(3, buf.position());
155     }
156 
157     public void testPooledProperty() throws Exception {
158         ByteBuffer buf = ByteBuffer.allocate(16);
159         java.nio.ByteBuffer nioBuf = buf.buf();
160         buf.release();
161         buf = ByteBuffer.allocate(16);
162         Assert.assertSame(nioBuf, buf.buf());
163         buf.setPooled(false);
164         buf.release();
165         Assert.assertNotSame(nioBuf, ByteBuffer.allocate(16).buf());
166     }
167 
168     public void testGetString() throws Exception {
169         ByteBuffer buf = ByteBuffer.allocate(16);
170         CharsetDecoder decoder;
171 
172         Charset charset = Charset.forName("UTF-8");
173         buf.clear();
174         buf.putString("hello", charset.newEncoder());
175         buf.put((byte) 0);
176         buf.flip();
177         Assert.assertEquals("hello", buf.getString(charset.newDecoder()));
178 
179         buf.clear();
180         buf.putString("hello", charset.newEncoder());
181         buf.flip();
182         Assert.assertEquals("hello", buf.getString(charset.newDecoder()));
183 
184         decoder = Charset.forName("ISO-8859-1").newDecoder();
185         buf.clear();
186         buf.put((byte) 'A');
187         buf.put((byte) 'B');
188         buf.put((byte) 'C');
189         buf.put((byte) 0);
190 
191         buf.position(0);
192         Assert.assertEquals("ABC", buf.getString(decoder));
193         Assert.assertEquals(4, buf.position());
194 
195         buf.position(0);
196         buf.limit(1);
197         Assert.assertEquals("A", buf.getString(decoder));
198         Assert.assertEquals(1, buf.position());
199 
200         buf.clear();
201         Assert.assertEquals("ABC", buf.getString(10, decoder));
202         Assert.assertEquals(10, buf.position());
203 
204         buf.clear();
205         Assert.assertEquals("A", buf.getString(1, decoder));
206         Assert.assertEquals(1, buf.position());
207 
208         // Test a trailing garbage
209         buf.clear();
210         buf.put((byte) 'A');
211         buf.put((byte) 'B');
212         buf.put((byte) 0);
213         buf.put((byte) 'C');
214         buf.position(0);
215         Assert.assertEquals("AB", buf.getString(4, decoder));
216         Assert.assertEquals(4, buf.position());
217 
218         buf.clear();
219         buf.fillAndReset(buf.limit());
220         decoder = Charset.forName("UTF-16").newDecoder();
221         buf.put((byte) 0);
222         buf.put((byte) 'A');
223         buf.put((byte) 0);
224         buf.put((byte) 'B');
225         buf.put((byte) 0);
226         buf.put((byte) 'C');
227         buf.put((byte) 0);
228         buf.put((byte) 0);
229 
230         buf.position(0);
231         Assert.assertEquals("ABC", buf.getString(decoder));
232         Assert.assertEquals(8, buf.position());
233 
234         buf.position(0);
235         buf.limit(2);
236         Assert.assertEquals("A", buf.getString(decoder));
237         Assert.assertEquals(2, buf.position());
238 
239         buf.position(0);
240         buf.limit(3);
241         Assert.assertEquals("A", buf.getString(decoder));
242         Assert.assertEquals(2, buf.position());
243 
244         buf.clear();
245         Assert.assertEquals("ABC", buf.getString(10, decoder));
246         Assert.assertEquals(10, buf.position());
247 
248         buf.clear();
249         Assert.assertEquals("A", buf.getString(2, decoder));
250         Assert.assertEquals(2, buf.position());
251 
252         buf.clear();
253         try {
254             buf.getString(1, decoder);
255             Assert.fail();
256         } catch (IllegalArgumentException e) {
257             // ignore
258         }
259 
260         // Test getting strings from an empty buffer.
261         buf.clear();
262         buf.limit(0);
263         Assert.assertEquals("", buf.getString(decoder));
264         Assert.assertEquals("", buf.getString(2, decoder));
265 
266         // Test getting strings from non-empty buffer which is filled with 0x00
267         buf.clear();
268         buf.putInt(0);
269         buf.clear();
270         buf.limit(4);
271         Assert.assertEquals("", buf.getString(decoder));
272         Assert.assertEquals(2, buf.position());
273         Assert.assertEquals(4, buf.limit());
274 
275         buf.position(0);
276         Assert.assertEquals("", buf.getString(2, decoder));
277         Assert.assertEquals(2, buf.position());
278         Assert.assertEquals(4, buf.limit());
279     }
280 
281     public void testGetStringWithFailure() throws Exception {
282         String test = "\u30b3\u30e1\u30f3\u30c8\u7de8\u96c6";
283         ByteBuffer buffer = ByteBuffer.wrap(test.getBytes("Shift_JIS"));
284 
285         // Make sure the limit doesn't change when an exception arose.
286         int oldLimit = buffer.limit();
287         int oldPos = buffer.position();
288         try {
289             buffer.getString(3, Charset.forName("ASCII").newDecoder());
290             Assert.fail();
291         } catch (Exception e) {
292             Assert.assertEquals(oldLimit, buffer.limit());
293             Assert.assertEquals(oldPos, buffer.position());
294         }
295 
296         try {
297             buffer.getString(Charset.forName("ASCII").newDecoder());
298             Assert.fail();
299         } catch (Exception e) {
300             Assert.assertEquals(oldLimit, buffer.limit());
301             Assert.assertEquals(oldPos, buffer.position());
302         }
303     }
304 
305     public void testPutString() throws Exception {
306         CharsetEncoder encoder;
307         ByteBuffer buf = ByteBuffer.allocate(16);
308         encoder = Charset.forName("ISO-8859-1").newEncoder();
309 
310         buf.putString("ABC", encoder);
311         Assert.assertEquals(3, buf.position());
312         buf.clear();
313         Assert.assertEquals('A', buf.get(0));
314         Assert.assertEquals('B', buf.get(1));
315         Assert.assertEquals('C', buf.get(2));
316 
317         buf.putString("D", 5, encoder);
318         Assert.assertEquals(5, buf.position());
319         buf.clear();
320         Assert.assertEquals('D', buf.get(0));
321         Assert.assertEquals(0, buf.get(1));
322 
323         buf.putString("EFG", 2, encoder);
324         Assert.assertEquals(2, buf.position());
325         buf.clear();
326         Assert.assertEquals('E', buf.get(0));
327         Assert.assertEquals('F', buf.get(1));
328         Assert.assertEquals('C', buf.get(2)); // C may not be overwritten
329 
330         // UTF-16: We specify byte order to omit BOM.
331         encoder = Charset.forName("UTF-16BE").newEncoder();
332         buf.clear();
333 
334         buf.putString("ABC", encoder);
335         Assert.assertEquals(6, buf.position());
336         buf.clear();
337 
338         Assert.assertEquals(0, buf.get(0));
339         Assert.assertEquals('A', buf.get(1));
340         Assert.assertEquals(0, buf.get(2));
341         Assert.assertEquals('B', buf.get(3));
342         Assert.assertEquals(0, buf.get(4));
343         Assert.assertEquals('C', buf.get(5));
344 
345         buf.putString("D", 10, encoder);
346         Assert.assertEquals(10, buf.position());
347         buf.clear();
348         Assert.assertEquals(0, buf.get(0));
349         Assert.assertEquals('D', buf.get(1));
350         Assert.assertEquals(0, buf.get(2));
351         Assert.assertEquals(0, buf.get(3));
352 
353         buf.putString("EFG", 4, encoder);
354         Assert.assertEquals(4, buf.position());
355         buf.clear();
356         Assert.assertEquals(0, buf.get(0));
357         Assert.assertEquals('E', buf.get(1));
358         Assert.assertEquals(0, buf.get(2));
359         Assert.assertEquals('F', buf.get(3));
360         Assert.assertEquals(0, buf.get(4)); // C may not be overwritten
361         Assert.assertEquals('C', buf.get(5)); // C may not be overwritten
362 
363         // Test putting an emptry string
364         buf.putString("", encoder);
365         Assert.assertEquals(0, buf.position());
366         buf.putString("", 4, encoder);
367         Assert.assertEquals(4, buf.position());
368         Assert.assertEquals(0, buf.get(0));
369         Assert.assertEquals(0, buf.get(1));
370     }
371 
372     public void testGetPrefixedString() throws Exception {
373         ByteBuffer buf = ByteBuffer.allocate(16);
374         CharsetEncoder encoder;
375         CharsetDecoder decoder;
376         encoder = Charset.forName("ISO-8859-1").newEncoder();
377         decoder = Charset.forName("ISO-8859-1").newDecoder();
378 
379         buf.putShort((short) 3);
380         buf.putString("ABCD", encoder);
381         buf.clear();
382         Assert.assertEquals("ABC", buf.getPrefixedString(decoder));
383     }
384 
385     public void testPutPrefixedString() throws Exception {
386         CharsetEncoder encoder;
387         ByteBuffer buf = ByteBuffer.allocate(16);
388         buf.fillAndReset(buf.remaining());
389         encoder = Charset.forName("ISO-8859-1").newEncoder();
390 
391         // Without autoExpand
392         buf.putPrefixedString("ABC", encoder);
393         Assert.assertEquals(5, buf.position());
394         Assert.assertEquals(0, buf.get(0));
395         Assert.assertEquals(3, buf.get(1));
396         Assert.assertEquals('A', buf.get(2));
397         Assert.assertEquals('B', buf.get(3));
398         Assert.assertEquals('C', buf.get(4));
399 
400         buf.clear();
401         try {
402             buf.putPrefixedString("123456789012345", encoder);
403             Assert.fail();
404         } catch (BufferOverflowException e) {
405             // OK
406         }
407 
408         // With autoExpand
409         buf.clear();
410         buf.setAutoExpand(true);
411         buf.putPrefixedString("123456789012345", encoder);
412         Assert.assertEquals(17, buf.position());
413         Assert.assertEquals(0, buf.get(0));
414         Assert.assertEquals(15, buf.get(1));
415         Assert.assertEquals('1', buf.get(2));
416         Assert.assertEquals('2', buf.get(3));
417         Assert.assertEquals('3', buf.get(4));
418         Assert.assertEquals('4', buf.get(5));
419         Assert.assertEquals('5', buf.get(6));
420         Assert.assertEquals('6', buf.get(7));
421         Assert.assertEquals('7', buf.get(8));
422         Assert.assertEquals('8', buf.get(9));
423         Assert.assertEquals('9', buf.get(10));
424         Assert.assertEquals('0', buf.get(11));
425         Assert.assertEquals('1', buf.get(12));
426         Assert.assertEquals('2', buf.get(13));
427         Assert.assertEquals('3', buf.get(14));
428         Assert.assertEquals('4', buf.get(15));
429         Assert.assertEquals('5', buf.get(16));
430     }
431 
432     public void testPutPrefixedStringWithPrefixLength() throws Exception {
433         CharsetEncoder encoder = Charset.forName("ISO-8859-1").newEncoder();
434         ByteBuffer buf = ByteBuffer.allocate(16).sweep().setAutoExpand(true);
435 
436         buf.putPrefixedString("A", 1, encoder);
437         Assert.assertEquals(2, buf.position());
438         Assert.assertEquals(1, buf.get(0));
439         Assert.assertEquals('A', buf.get(1));
440 
441         buf.sweep();
442         buf.putPrefixedString("A", 2, encoder);
443         Assert.assertEquals(3, buf.position());
444         Assert.assertEquals(0, buf.get(0));
445         Assert.assertEquals(1, buf.get(1));
446         Assert.assertEquals('A', buf.get(2));
447 
448         buf.sweep();
449         buf.putPrefixedString("A", 4, encoder);
450         Assert.assertEquals(5, buf.position());
451         Assert.assertEquals(0, buf.get(0));
452         Assert.assertEquals(0, buf.get(1));
453         Assert.assertEquals(0, buf.get(2));
454         Assert.assertEquals(1, buf.get(3));
455         Assert.assertEquals('A', buf.get(4));
456     }
457 
458     public void testPutPrefixedStringWithPadding() throws Exception {
459         CharsetEncoder encoder = Charset.forName("ISO-8859-1").newEncoder();
460         ByteBuffer buf = ByteBuffer.allocate(16).sweep().setAutoExpand(true);
461 
462         buf.putPrefixedString("A", 1, 2, (byte) 32, encoder);
463         Assert.assertEquals(3, buf.position());
464         Assert.assertEquals(2, buf.get(0));
465         Assert.assertEquals('A', buf.get(1));
466         Assert.assertEquals(' ', buf.get(2));
467 
468         buf.sweep();
469         buf.putPrefixedString("A", 1, 4, (byte) 32, encoder);
470         Assert.assertEquals(5, buf.position());
471         Assert.assertEquals(4, buf.get(0));
472         Assert.assertEquals('A', buf.get(1));
473         Assert.assertEquals(' ', buf.get(2));
474         Assert.assertEquals(' ', buf.get(3));
475         Assert.assertEquals(' ', buf.get(4));
476     }
477 
478     public void testWideUtf8Characters() throws Exception {
479         Runnable r = new Runnable() {
480             public void run() {
481                 ByteBuffer buffer = ByteBuffer.allocate(1);
482                 buffer.setAutoExpand(true);
483 
484                 Charset charset = Charset.forName("UTF-8");
485 
486                 CharsetEncoder encoder = charset.newEncoder();
487 
488                 for (int i = 0; i < 5; i++) {
489                     try {
490                         buffer.putString("\u89d2", encoder);
491                     } catch (CharacterCodingException e) {
492                         fail(e.getMessage());
493                     }
494                 }
495             }
496         };
497 
498         Thread t = new Thread(r);
499         t.setDaemon(true);
500         t.start();
501 
502         for (int i = 0; i < 50; i++) {
503             Thread.sleep(100);
504             if (!t.isAlive()) {
505                 break;
506             }
507         }
508 
509         if (t.isAlive()) {
510             t.interrupt();
511 
512             fail("Went into endless loop trying to encode character");
513         }
514     }
515 
516     public void testObjectSerialization() throws Exception {
517         ByteBuffer buf = ByteBuffer.allocate(16);
518         buf.setAutoExpand(true);
519         List<Object> o = new ArrayList<Object>();
520         o.add(new Date());
521         o.add(long.class);
522 
523         // Test writing an object.
524         buf.putObject(o);
525 
526         // Test reading an object.
527         buf.clear();
528         Object o2 = buf.getObject();
529         Assert.assertEquals(o, o2);
530 
531         // This assertion is just to make sure that deserialization occurred.
532         Assert.assertNotSame(o, o2);
533     }
534 
535     public void testSweepWithZeros() throws Exception {
536         ByteBuffer buf = ByteBuffer.allocate(4);
537         buf.putInt(0xdeadbeef);
538         buf.clear();
539         Assert.assertEquals(0xdeadbeef, buf.getInt());
540         Assert.assertEquals(4, buf.position());
541         Assert.assertEquals(4, buf.limit());
542 
543         buf.sweep();
544         Assert.assertEquals(0, buf.position());
545         Assert.assertEquals(4, buf.limit());
546         Assert.assertEquals(0x0, buf.getInt());
547     }
548 
549     public void testSweepNonZeros() throws Exception {
550         ByteBuffer buf = ByteBuffer.allocate(4);
551         buf.putInt(0xdeadbeef);
552         buf.clear();
553         Assert.assertEquals(0xdeadbeef, buf.getInt());
554         Assert.assertEquals(4, buf.position());
555         Assert.assertEquals(4, buf.limit());
556 
557         buf.sweep((byte) 0x45);
558         Assert.assertEquals(0, buf.position());
559         Assert.assertEquals(4, buf.limit());
560         Assert.assertEquals(0x45454545, buf.getInt());
561     }
562 
563     public void testWrapNioBuffer() throws Exception {
564         java.nio.ByteBuffer nioBuf = java.nio.ByteBuffer.allocate(10);
565         nioBuf.position(3);
566         nioBuf.limit(7);
567 
568         ByteBuffer buf = ByteBuffer.wrap(nioBuf);
569         Assert.assertEquals(3, buf.position());
570         Assert.assertEquals(7, buf.limit());
571         Assert.assertEquals(10, buf.capacity());
572     }
573 
574     public void testWrapSubArray() throws Exception {
575         byte[] array = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
576 
577         ByteBuffer buf = ByteBuffer.wrap(array, 3, 4);
578         Assert.assertEquals(3, buf.position());
579         Assert.assertEquals(7, buf.limit());
580         Assert.assertEquals(10, buf.capacity());
581 
582         buf.clear();
583         Assert.assertEquals(0, buf.position());
584         Assert.assertEquals(10, buf.limit());
585         Assert.assertEquals(10, buf.capacity());
586     }
587 
588     public void testPoolExpiration() throws Exception {
589         PooledByteBufferAllocator allocator = (PooledByteBufferAllocator) ByteBuffer
590                 .getAllocator();
591 
592         // Make a buffer pooled.
593         ByteBuffer buf = ByteBuffer.allocate(16);
594         buf.release();
595 
596         // Let everything flushed.
597         allocator.setTimeout(1);
598         Thread.sleep(2000);
599 
600         // Make sure old buffers are flushed.
601         Assert.assertNotSame(buf, ByteBuffer.allocate(16));
602 
603         // Make sure new buffers are not flushed.
604         allocator.setTimeout(10);
605         buf = ByteBuffer.allocate(16);
606         buf.release();
607         Thread.sleep(2000);
608         Assert.assertSame(buf.buf(), ByteBuffer.allocate(16).buf());
609 
610         // Return to the default settings
611         allocator.setTimeout(60);
612     }
613 
614     public void testAllocatorDisposal() throws Exception {
615         PooledByteBufferAllocator allocator = (PooledByteBufferAllocator) ByteBuffer
616                 .getAllocator();
617 
618         // dispose() should fail because the allocator is in use.
619         try {
620             allocator.dispose();
621             Assert.fail();
622         } catch (IllegalStateException e) {
623             // OK
624         }
625 
626         // Change the allocator.
627         ByteBuffer.setAllocator(new PooledByteBufferAllocator());
628 
629         // Dispose the old allocator.
630         allocator.dispose();
631 
632         // Allocation request to the disposed allocator should fail.
633         try {
634             allocator.allocate(16, true);
635             Assert.fail();
636         } catch (IllegalStateException e) {
637             // OK
638         }
639     }
640 
641     public void testDuplicate() throws Exception {
642         java.nio.ByteBuffer nioBuf;
643         ByteBuffer original;
644         ByteBuffer duplicate;
645 
646         // Test if the buffer is duplicated correctly.
647         original = ByteBuffer.allocate(16).sweep();
648         nioBuf = original.buf();
649         original.position(4);
650         original.limit(10);
651         duplicate = original.duplicate();
652         original.put(4, (byte) 127);
653         Assert.assertEquals(4, duplicate.position());
654         Assert.assertEquals(10, duplicate.limit());
655         Assert.assertEquals(16, duplicate.capacity());
656         Assert.assertNotSame(original.buf(), duplicate.buf());
657         Assert.assertEquals(127, duplicate.get(4));
658         original.release();
659         duplicate.release();
660 
661         //// Check if pooled correctly.
662         original = ByteBuffer.allocate(16);
663         Assert.assertSame(nioBuf, original.buf());
664         original.release();
665 
666         // Try to release duplicate first.
667         original = ByteBuffer.allocate(16);
668         duplicate = original.duplicate();
669         duplicate.release();
670         original.release();
671 
672         //// Check if pooled correctly.
673         original = ByteBuffer.allocate(16);
674         Assert.assertSame(nioBuf, original.buf());
675         original.release();
676 
677         // Test a duplicate of a duplicate.
678         original = ByteBuffer.allocate(16);
679         duplicate = original.duplicate();
680         ByteBuffer anotherDuplicate = duplicate.duplicate();
681         anotherDuplicate.release();
682         original.release();
683         duplicate.release();
684         try {
685             duplicate.release();
686             Assert.fail();
687         } catch (IllegalStateException e) {
688             // OK
689         }
690         try {
691             anotherDuplicate.release();
692             Assert.fail();
693         } catch (IllegalStateException e) {
694             // OK
695         }
696 
697         //// Check if pooled correctly.
698         original = ByteBuffer.allocate(16);
699         Assert.assertSame(nioBuf, original.buf());
700         original.release();
701 
702         // Try to expand.
703         try {
704             original = ByteBuffer.allocate(16);
705             duplicate = original.duplicate();
706             duplicate.setAutoExpand(true);
707             duplicate.putString("A very very very very looooooong string",
708                     Charset.forName("ISO-8859-1").newEncoder());
709             Assert.fail();
710         } catch (IllegalStateException e) {
711             // OK
712         }
713     }
714 
715     public void testSlice() throws Exception {
716         ByteBuffer original;
717         ByteBuffer slice;
718 
719         // Test if the buffer is sliced correctly.
720         original = ByteBuffer.allocate(16).sweep();
721         original.position(4);
722         original.limit(10);
723         slice = original.slice();
724         original.put(4, (byte) 127);
725         Assert.assertEquals(0, slice.position());
726         Assert.assertEquals(6, slice.limit());
727         Assert.assertEquals(6, slice.capacity());
728         Assert.assertNotSame(original.buf(), slice.buf());
729         Assert.assertEquals(127, slice.get(0));
730         original.release();
731         slice.release();
732     }
733 
734     public void testReadOnlyBuffer() throws Exception {
735         ByteBuffer original;
736         ByteBuffer duplicate;
737 
738         // Test if the buffer is duplicated correctly.
739         original = ByteBuffer.allocate(16).sweep();
740         original.position(4);
741         original.limit(10);
742         duplicate = original.asReadOnlyBuffer();
743         original.put(4, (byte) 127);
744         Assert.assertEquals(4, duplicate.position());
745         Assert.assertEquals(10, duplicate.limit());
746         Assert.assertEquals(16, duplicate.capacity());
747         Assert.assertNotSame(original.buf(), duplicate.buf());
748         Assert.assertEquals(127, duplicate.get(4));
749         original.release();
750         duplicate.release();
751 
752         // Try to expand.
753         try {
754             original = ByteBuffer.allocate(16);
755             duplicate = original.asReadOnlyBuffer();
756             duplicate.putString("A very very very very looooooong string",
757                     Charset.forName("ISO-8859-1").newEncoder());
758             Assert.fail();
759         } catch (ReadOnlyBufferException e) {
760             // OK
761         }
762     }
763 
764     public void testGetUnsigned() throws Exception {
765         ByteBuffer buf = ByteBuffer.allocate(16);
766         buf.put((byte) 0xA4);
767         buf.put((byte) 0xD0);
768         buf.put((byte) 0xB3);
769         buf.put((byte) 0xCD);
770         buf.flip();
771 
772         buf.order(ByteOrder.LITTLE_ENDIAN);
773 
774         buf.mark();
775         Assert.assertEquals(0xA4, buf.getUnsigned());
776         buf.reset();
777         Assert.assertEquals(0xD0A4, buf.getUnsignedShort());
778         buf.reset();
779         Assert.assertEquals(0xCDB3D0A4L, buf.getUnsignedInt());
780     }
781 }