1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18package org.apache.harmony.tests.java.nio;
19
20import java.nio.BufferOverflowException;
21import java.nio.BufferUnderflowException;
22import java.nio.ByteBuffer;
23import java.nio.ByteOrder;
24import java.nio.DoubleBuffer;
25import java.nio.InvalidMarkException;
26
27/**
28 * Tests java.nio.DoubleBuffer
29 */
30public class DoubleBufferTest extends AbstractBufferTest {
31
32    protected static final int SMALL_TEST_LENGTH = 5;
33
34    protected static final int BUFFER_LENGTH = 20;
35
36    protected DoubleBuffer buf;
37
38    protected void setUp() throws Exception {
39        buf = DoubleBuffer.allocate(BUFFER_LENGTH);
40        loadTestData1(buf);
41        baseBuf = buf;
42    }
43
44    protected void tearDown() throws Exception {
45        buf = null;
46        baseBuf = null;
47    }
48
49    /*
50     * Test with bit sequences that represent the IEEE754 doubles Positive
51     * infinity, negative infinity, and NaN.
52     */
53    public void testNaNs() {
54        long[] nans = new long[] { 0x7ff0000000000000L, 0xfff0000000000000L,
55                0x7ff8000000000000L };
56        for (int i = 0; i < nans.length; i++) {
57            long longBitsIn = nans[i];
58            double dbl = Double.longBitsToDouble(longBitsIn);
59            long longBitsOut = Double.doubleToRawLongBits(dbl);
60            // Sanity check
61            assertTrue(longBitsIn == longBitsOut);
62
63            // Store the double and retrieve it
64            ByteBuffer buffer = ByteBuffer.allocate(8);
65            buffer.putDouble(dbl);
66            double bufDoubleOut = buffer.getDouble(0);
67
68            // Check the bits sequence was not normalized
69            long bufLongOut = Double.doubleToRawLongBits(bufDoubleOut);
70            assertTrue(longBitsIn == bufLongOut);
71        }
72    }
73
74    public void testArray() {
75        double array[] = buf.array();
76        assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
77
78        loadTestData1(array, buf.arrayOffset(), buf.capacity());
79        assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
80
81        loadTestData2(array, buf.arrayOffset(), buf.capacity());
82        assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
83
84        loadTestData1(buf);
85        assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
86
87        loadTestData2(buf);
88        assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
89    }
90
91    public void testArrayOffset() {
92        double array[] = buf.array();
93        assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
94
95        loadTestData1(array, buf.arrayOffset(), buf.capacity());
96        assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
97
98        loadTestData2(array, buf.arrayOffset(), buf.capacity());
99        assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
100
101        loadTestData1(buf);
102        assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
103
104        loadTestData2(buf);
105        assertContentEquals(buf, array, buf.arrayOffset(), buf.capacity());
106    }
107
108    public void testAsReadOnlyBuffer() {
109        buf.clear();
110        buf.mark();
111        buf.position(buf.limit());
112
113        // readonly's contents should be the same as buf
114        DoubleBuffer readonly = buf.asReadOnlyBuffer();
115        assertNotSame(buf, readonly);
116        assertTrue(readonly.isReadOnly());
117        assertEquals(buf.position(), readonly.position());
118        assertEquals(buf.limit(), readonly.limit());
119        assertEquals(buf.isDirect(), readonly.isDirect());
120        assertEquals(buf.order(), readonly.order());
121        assertContentEquals(buf, readonly);
122
123        // readonly's position, mark, and limit should be independent to buf
124        readonly.reset();
125        assertEquals(readonly.position(), 0);
126        readonly.clear();
127        assertEquals(buf.position(), buf.limit());
128        buf.reset();
129        assertEquals(buf.position(), 0);
130    }
131
132    public void testCompact() {
133        // case: buffer is full
134        buf.clear();
135        buf.mark();
136        loadTestData1(buf);
137        DoubleBuffer ret = buf.compact();
138        assertSame(ret, buf);
139        assertEquals(buf.position(), buf.capacity());
140        assertEquals(buf.limit(), buf.capacity());
141        assertContentLikeTestData1(buf, 0, 0.0, buf.capacity());
142        try {
143            buf.reset();
144            fail("Should throw Exception"); //$NON-NLS-1$
145        } catch (InvalidMarkException e) {
146            // expected
147        }
148
149        // case: buffer is empty
150        buf.position(0);
151        buf.limit(0);
152        buf.mark();
153        ret = buf.compact();
154        assertSame(ret, buf);
155        assertEquals(buf.position(), 0);
156        assertEquals(buf.limit(), buf.capacity());
157        assertContentLikeTestData1(buf, 0, 0.0, buf.capacity());
158        try {
159            buf.reset();
160            fail("Should throw Exception"); //$NON-NLS-1$
161        } catch (InvalidMarkException e) {
162            // expected
163        }
164
165        // case: normal
166        assertTrue(buf.capacity() > 5);
167        buf.position(1);
168        buf.limit(5);
169        buf.mark();
170        ret = buf.compact();
171        assertSame(ret, buf);
172        assertEquals(buf.position(), 4);
173        assertEquals(buf.limit(), buf.capacity());
174        assertContentLikeTestData1(buf, 0, 1.0, 4);
175        try {
176            buf.reset();
177            fail("Should throw Exception"); //$NON-NLS-1$
178        } catch (InvalidMarkException e) {
179            // expected
180        }
181    }
182
183    public void testCompareTo() {
184        DoubleBuffer other = DoubleBuffer.allocate(buf.capacity());
185        loadTestData1(other);
186        assertEquals(0, buf.compareTo(other));
187        assertEquals(0, other.compareTo(buf));
188        buf.position(1);
189        assertTrue(buf.compareTo(other) > 0);
190        assertTrue(other.compareTo(buf) < 0);
191        other.position(2);
192        assertTrue(buf.compareTo(other) < 0);
193        assertTrue(other.compareTo(buf) > 0);
194        buf.position(2);
195        other.limit(5);
196        assertTrue(buf.compareTo(other) > 0);
197        assertTrue(other.compareTo(buf) < 0);
198
199        DoubleBuffer dbuffer1 = DoubleBuffer.wrap(new double[] { Double.NaN });
200        DoubleBuffer dbuffer2 = DoubleBuffer.wrap(new double[] { Double.NaN });
201        DoubleBuffer dbuffer3 = DoubleBuffer.wrap(new double[] { 42d });
202
203        assertEquals("Failed equal comparison with NaN entry", 0, dbuffer1
204                .compareTo(dbuffer2));
205        assertEquals("Failed greater than comparison with NaN entry", -1, dbuffer3
206                .compareTo(dbuffer1));
207        assertEquals("Failed greater than comparison with NaN entry", 1, dbuffer1
208                .compareTo(dbuffer3));
209    }
210
211    public void testDuplicate() {
212        buf.clear();
213        buf.mark();
214        buf.position(buf.limit());
215
216        // duplicate's contents should be the same as buf
217        DoubleBuffer duplicate = buf.duplicate();
218        assertNotSame(buf, duplicate);
219        assertEquals(buf.position(), duplicate.position());
220        assertEquals(buf.limit(), duplicate.limit());
221        assertEquals(buf.isReadOnly(), duplicate.isReadOnly());
222        assertEquals(buf.isDirect(), duplicate.isDirect());
223        assertEquals(buf.order(), duplicate.order());
224        assertContentEquals(buf, duplicate);
225
226        // duplicate's position, mark, and limit should be independent to buf
227        duplicate.reset();
228        assertEquals(duplicate.position(), 0);
229        duplicate.clear();
230        assertEquals(buf.position(), buf.limit());
231        buf.reset();
232        assertEquals(buf.position(), 0);
233
234        // duplicate share the same content with buf
235        // FIXME
236        if (!duplicate.isReadOnly()) {
237            loadTestData1(buf);
238            assertContentEquals(buf, duplicate);
239            loadTestData2(duplicate);
240            assertContentEquals(buf, duplicate);
241        }
242    }
243
244    public void testEquals() {
245        // equal to self
246        assertTrue(buf.equals(buf));
247        DoubleBuffer readonly = buf.asReadOnlyBuffer();
248        assertTrue(buf.equals(readonly));
249        DoubleBuffer duplicate = buf.duplicate();
250        assertTrue(buf.equals(duplicate));
251
252        // always false, if type mismatch
253        assertFalse(buf.equals(Boolean.TRUE));
254
255        assertTrue(buf.capacity() > 5);
256
257        buf.limit(buf.capacity()).position(0);
258        readonly.limit(readonly.capacity()).position(1);
259        assertFalse(buf.equals(readonly));
260
261        buf.limit(buf.capacity() - 1).position(0);
262        duplicate.limit(duplicate.capacity()).position(0);
263        assertFalse(buf.equals(duplicate));
264    }
265
266    /*
267     * Class under test for double get()
268     */
269    public void testGet() {
270        buf.clear();
271        for (int i = 0; i < buf.capacity(); i++) {
272            assertEquals(buf.position(), i);
273            assertEquals(buf.get(), buf.get(i), 0.01);
274        }
275        try {
276            buf.get();
277            fail("Should throw Exception"); //$NON-NLS-1$
278        } catch (BufferUnderflowException e) {
279            // expected
280        }
281    }
282
283    /*
284     * Class under test for java.nio.DoubleBuffer get(double[])
285     */
286    public void testGetdoubleArray() {
287        double array[] = new double[1];
288        buf.clear();
289        for (int i = 0; i < buf.capacity(); i++) {
290            assertEquals(buf.position(), i);
291            DoubleBuffer ret = buf.get(array);
292            assertEquals(array[0], buf.get(i), 0.01);
293            assertSame(ret, buf);
294        }
295        try {
296            buf.get(array);
297            fail("Should throw Exception"); //$NON-NLS-1$
298        } catch (BufferUnderflowException e) {
299            // expected
300        }
301    }
302
303    /*
304     * Class under test for java.nio.DoubleBuffer get(double[], int, int)
305     */
306    public void testGetdoubleArrayintint() {
307        buf.clear();
308        double array[] = new double[buf.capacity()];
309
310        try {
311            buf.get(new double[buf.capacity() + 1], 0, buf.capacity() + 1);
312            fail("Should throw Exception"); //$NON-NLS-1$
313        } catch (BufferUnderflowException e) {
314            // expected
315        }
316        assertEquals(buf.position(), 0);
317        try {
318            buf.get(array, -1, array.length);
319            fail("Should throw Exception"); //$NON-NLS-1$
320        } catch (IndexOutOfBoundsException e) {
321            // expected
322        }
323        buf.get(array, array.length, 0);
324        try {
325            buf.get(array, array.length + 1, 1);
326            fail("Should throw Exception"); //$NON-NLS-1$
327        } catch (IndexOutOfBoundsException e) {
328            // expected
329        }
330        assertEquals(buf.position(), 0);
331        try {
332            buf.get(array, 2, -1);
333            fail("Should throw Exception"); //$NON-NLS-1$
334        } catch (IndexOutOfBoundsException e) {
335            // expected
336        }
337        try {
338            buf.get((double[])null, 0, -1);
339            fail("Should throw Exception"); //$NON-NLS-1$
340        } catch (NullPointerException e) {
341            // expected
342        }
343        try {
344            buf.get(array, 2, array.length);
345            fail("Should throw Exception"); //$NON-NLS-1$
346        } catch (IndexOutOfBoundsException e) {
347            // expected
348        }
349        try {
350            buf.get(array, 1, Integer.MAX_VALUE);
351            fail("Should throw Exception"); //$NON-NLS-1$
352        } catch (BufferUnderflowException expected) {
353        } catch (IndexOutOfBoundsException expected) {
354        }
355        try {
356            buf.get(array, Integer.MAX_VALUE, 1);
357            fail("Should throw Exception"); //$NON-NLS-1$
358        } catch (IndexOutOfBoundsException e) {
359            // expected
360        }
361        assertEquals(buf.position(), 0);
362
363        buf.clear();
364        DoubleBuffer ret = buf.get(array, 0, array.length);
365        assertEquals(buf.position(), buf.capacity());
366        assertContentEquals(buf, array, 0, array.length);
367        assertSame(ret, buf);
368    }
369
370    /*
371     * Class under test for double get(int)
372     */
373    public void testGetint() {
374        buf.clear();
375        for (int i = 0; i < buf.capacity(); i++) {
376            assertEquals(buf.position(), i);
377            assertEquals(buf.get(), buf.get(i), 0.01);
378        }
379        try {
380            buf.get(-1);
381            fail("Should throw Exception"); //$NON-NLS-1$
382        } catch (IndexOutOfBoundsException e) {
383            // expected
384        }
385        try {
386            buf.get(buf.limit());
387            fail("Should throw Exception"); //$NON-NLS-1$
388        } catch (IndexOutOfBoundsException e) {
389            // expected
390        }
391    }
392
393    public void testHasArray() {
394        assertTrue(buf.hasArray());
395    }
396
397    public void testHashCode() {
398        buf.clear();
399        DoubleBuffer readonly = buf.asReadOnlyBuffer();
400        DoubleBuffer duplicate = buf.duplicate();
401        assertTrue(buf.hashCode() == readonly.hashCode());
402
403        assertTrue(buf.capacity() > 5);
404        duplicate.position(buf.capacity() / 2);
405        assertTrue(buf.hashCode() != duplicate.hashCode());
406    }
407
408    public void testIsDirect() {
409        assertFalse(buf.isDirect());
410    }
411
412    public void testOrder() {
413        assertEquals(ByteOrder.nativeOrder(), buf.order());
414    }
415
416    /*
417     * Class under test for java.nio.DoubleBuffer put(double)
418     */
419    public void testPutdouble() {
420
421        buf.clear();
422        for (int i = 0; i < buf.capacity(); i++) {
423            assertEquals(buf.position(), i);
424            DoubleBuffer ret = buf.put((double) i);
425            assertEquals(buf.get(i), (double) i, 0.0);
426            assertSame(ret, buf);
427        }
428        try {
429            buf.put(0);
430            fail("Should throw Exception"); //$NON-NLS-1$
431        } catch (BufferOverflowException e) {
432            // expected
433        }
434    }
435
436    /*
437     * Class under test for java.nio.DoubleBuffer put(double[])
438     */
439    public void testPutdoubleArray() {
440        double array[] = new double[1];
441
442        buf.clear();
443        for (int i = 0; i < buf.capacity(); i++) {
444            assertEquals(buf.position(), i);
445            array[0] = (double) i;
446            DoubleBuffer ret = buf.put(array);
447            assertEquals(buf.get(i), (double) i, 0.0);
448            assertSame(ret, buf);
449        }
450        try {
451            buf.put(array);
452            fail("Should throw Exception"); //$NON-NLS-1$
453        } catch (BufferOverflowException e) {
454            // expected
455        }
456    }
457
458    /*
459     * Class under test for java.nio.DoubleBuffer put(double[], int, int)
460     */
461    public void testPutdoubleArrayintint() {
462        buf.clear();
463        double array[] = new double[buf.capacity()];
464
465        try {
466            buf.put(new double[buf.capacity() + 1], 0, buf.capacity() + 1);
467            fail("Should throw Exception"); //$NON-NLS-1$
468        } catch (BufferOverflowException e) {
469            // expected
470        }
471        assertEquals(buf.position(), 0);
472        try {
473            buf.put(array, -1, array.length);
474            fail("Should throw Exception"); //$NON-NLS-1$
475        } catch (IndexOutOfBoundsException e) {
476            // expected
477        }
478        try {
479            buf.put(array, array.length + 1, 0);
480            fail("Should throw Exception"); //$NON-NLS-1$
481        } catch (IndexOutOfBoundsException e) {
482            // expected
483        }
484        buf.put(array, array.length, 0);
485        assertEquals(buf.position(), 0);
486        try {
487            buf.put(array, 0, -1);
488            fail("Should throw Exception"); //$NON-NLS-1$
489        } catch (IndexOutOfBoundsException e) {
490            // expected
491        }
492        try {
493            buf.put((double[])null, 0, -1);
494            fail("Should throw Exception"); //$NON-NLS-1$
495        } catch (NullPointerException e) {
496            // expected
497        }
498        try {
499            buf.put(array, 2, array.length);
500            fail("Should throw Exception"); //$NON-NLS-1$
501        } catch (IndexOutOfBoundsException e) {
502            // expected
503        }
504        try {
505            buf.put(array, Integer.MAX_VALUE, 1);
506            fail("Should throw Exception"); //$NON-NLS-1$
507        } catch (IndexOutOfBoundsException e) {
508            // expected
509        }
510        try {
511            buf.put(array, 1, Integer.MAX_VALUE);
512            fail("Should throw Exception"); //$NON-NLS-1$
513        } catch (BufferOverflowException expected) {
514        } catch (IndexOutOfBoundsException expected) {
515        }
516        assertEquals(buf.position(), 0);
517
518        loadTestData2(array, 0, array.length);
519        DoubleBuffer ret = buf.put(array, 0, array.length);
520        assertEquals(buf.position(), buf.capacity());
521        assertContentEquals(buf, array, 0, array.length);
522        assertSame(ret, buf);
523    }
524
525    /*
526     * Class under test for java.nio.DoubleBuffer put(java.nio.DoubleBuffer)
527     */
528    public void testPutDoubleBuffer() {
529        DoubleBuffer other = DoubleBuffer.allocate(buf.capacity());
530
531        try {
532            buf.put(buf);
533            fail("Should throw Exception"); //$NON-NLS-1$
534        } catch (IllegalArgumentException e) {
535            // expected
536        }
537        try {
538            buf.put(DoubleBuffer.allocate(buf.capacity() + 1));
539            fail("Should throw Exception"); //$NON-NLS-1$
540        } catch (BufferOverflowException e) {
541            // expected
542        }
543
544        loadTestData2(other);
545        other.clear();
546        buf.clear();
547        DoubleBuffer ret = buf.put(other);
548        assertEquals(other.position(), other.capacity());
549        assertEquals(buf.position(), buf.capacity());
550        assertContentEquals(other, buf);
551        assertSame(ret, buf);
552    }
553
554    /*
555     * Class under test for java.nio.DoubleBuffer put(int, double)
556     */
557    public void testPutintdouble() {
558        buf.clear();
559        for (int i = 0; i < buf.capacity(); i++) {
560            assertEquals(buf.position(), 0);
561            DoubleBuffer ret = buf.put(i, (double) i);
562            assertEquals(buf.get(i), (double) i, 0.0);
563            assertSame(ret, buf);
564        }
565        try {
566            buf.put(-1, 0);
567            fail("Should throw Exception"); //$NON-NLS-1$
568        } catch (IndexOutOfBoundsException e) {
569            // expected
570        }
571        try {
572            buf.put(buf.limit(), 0);
573            fail("Should throw Exception"); //$NON-NLS-1$
574        } catch (IndexOutOfBoundsException e) {
575            // expected
576        }
577    }
578
579    public void testSlice() {
580        assertTrue(buf.capacity() > 5);
581        buf.position(1);
582        buf.limit(buf.capacity() - 1);
583
584        DoubleBuffer slice = buf.slice();
585        assertEquals(buf.isReadOnly(), slice.isReadOnly());
586        assertEquals(buf.isDirect(), slice.isDirect());
587        assertEquals(buf.order(), slice.order());
588        assertEquals(slice.position(), 0);
589        assertEquals(slice.limit(), buf.remaining());
590        assertEquals(slice.capacity(), buf.remaining());
591        try {
592            slice.reset();
593            fail("Should throw Exception"); //$NON-NLS-1$
594        } catch (InvalidMarkException e) {
595            // expected
596        }
597
598        // slice share the same content with buf
599        // FIXME:
600        if (!slice.isReadOnly()) {
601            loadTestData1(slice);
602            assertContentLikeTestData1(buf, 1, 0, slice.capacity());
603            buf.put(2, 500);
604            assertEquals(slice.get(1), 500, 0.0);
605        }
606    }
607
608    public void testToString() {
609        String str = buf.toString();
610        assertTrue(str.indexOf("Double") >= 0 || str.indexOf("double") >= 0);
611        assertTrue(str.indexOf("" + buf.position()) >= 0);
612        assertTrue(str.indexOf("" + buf.limit()) >= 0);
613        assertTrue(str.indexOf("" + buf.capacity()) >= 0);
614    }
615
616    void loadTestData1(double array[], int offset, int length) {
617        for (int i = 0; i < length; i++) {
618            array[offset + i] = (double) i;
619        }
620    }
621
622    void loadTestData2(double array[], int offset, int length) {
623        for (int i = 0; i < length; i++) {
624            array[offset + i] = (double) length - i;
625        }
626    }
627
628    void loadTestData1(DoubleBuffer buf) {
629        buf.clear();
630        for (int i = 0; i < buf.capacity(); i++) {
631            buf.put(i, (double) i);
632        }
633    }
634
635    void loadTestData2(DoubleBuffer buf) {
636        buf.clear();
637        for (int i = 0; i < buf.capacity(); i++) {
638            buf.put(i, (double) buf.capacity() - i);
639        }
640    }
641
642    private void assertContentEquals(DoubleBuffer buf, double array[],
643            int offset, int length) {
644        for (int i = 0; i < length; i++) {
645            assertEquals(buf.get(i), array[offset + i], 0.01);
646        }
647    }
648
649    private void assertContentEquals(DoubleBuffer buf, DoubleBuffer other) {
650        assertEquals(buf.capacity(), other.capacity());
651        for (int i = 0; i < buf.capacity(); i++) {
652            assertEquals(buf.get(i), other.get(i), 0.01);
653        }
654    }
655
656    private void assertContentLikeTestData1(DoubleBuffer buf, int startIndex,
657            double startValue, int length) {
658        double value = startValue;
659        for (int i = 0; i < length; i++) {
660            assertEquals(buf.get(startIndex + i), value, 0.01);
661            value = value + 1.0;
662        }
663    }
664}
665