1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 import java.nio.BufferOverflowException;
18 import java.nio.ByteBuffer;
19 import java.nio.ByteOrder;
20 import java.nio.CharBuffer;
21 import java.nio.DoubleBuffer;
22 import java.nio.FloatBuffer;
23 import java.nio.IntBuffer;
24 import java.nio.LongBuffer;
25 import java.nio.ShortBuffer;
26 
27 public class Main {
main(String[] args)28     public static void main(String[] args) {
29         ByteBuffer buf = ByteBuffer.allocateDirect(16);
30         System.out.println("Direct byte buffer has array: " + buf.hasArray());
31 
32         intFloatTest();
33         basicShortTest();
34         primTest();
35     }
36 
37     /*
38      * Create a buffer and fiddle with it.
39      */
basicShortTest()40     public static void basicShortTest() {
41         ByteBuffer directBuf = ByteBuffer.allocateDirect(64);
42         //ByteBuffer directBuf = ByteBuffer.allocateDirect(65);
43 
44         ShortBuffer shortBuf = directBuf.asShortBuffer();
45 
46         short[] myShorts = {
47             1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007,
48             1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015,
49             1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023,
50             1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031
51         };
52 
53         shortBuf.position(0);
54         shortBuf.put(myShorts, 0, 32);      // should work
55         shortBuf.position(0);
56         shortBuf.put(myShorts, 16, 16);     // should work
57         shortBuf.put(myShorts, 16, 16);     // advance to end
58 
59         try {
60             shortBuf.put(myShorts, 0, 1);     // should fail
61             System.err.println("ERROR: out-of-bounds put succeeded\n");
62         } catch (BufferOverflowException boe) {
63             System.out.println("Got expected buffer overflow exception");
64         }
65 
66         try {
67             shortBuf.position(0);
68             shortBuf.put(myShorts, 0, 33);     // should fail
69             System.err.println("ERROR: out-of-bounds put succeeded\n");
70         } catch (IndexOutOfBoundsException ioobe) {
71             System.out.println("Got expected out-of-bounds exception");
72         }
73 
74         try {
75             shortBuf.position(16);
76             shortBuf.put(myShorts, 0, 17);     // should fail
77             System.err.println("ERROR: out-of-bounds put succeeded\n");
78         } catch (BufferOverflowException boe) {
79             System.out.println("Got expected buffer overflow exception");
80         }
81     }
82 
83     /*
84      * Try this with either floats or ints; ints fail with
85      * BufferOverflowException, floats work.
86      *
87      * From http://code.google.com/p/android/issues/detail?id=1585 .
88      */
intFloatTest()89     public static void intFloatTest() {
90         ByteBuffer direct = ByteBuffer.allocateDirect(100);
91         direct.order(ByteOrder.nativeOrder());
92         IntBuffer int1 = direct.asIntBuffer();
93         int data[] = new int[25];
94         //FloatBuffer int1 = direct.asFloatBuffer();
95         //float data[] = new float[25];
96         int1.clear ();
97         int1.put (data);
98         int1.position (0);
99 
100         int1.clear ();
101         int1.put (data);
102         int1.position (0);
103     }
104 
105     /*
106      * Exercise all "view buffer" classes, in both byte orders.
107      */
primTest()108     public static void primTest() {
109         ByteBuffer directBuf = ByteBuffer.allocateDirect(36);
110         directBuf.order(ByteOrder.BIG_ENDIAN);
111         storeValues(directBuf);
112 
113         for (int i = 0; i < 36; i++) {
114             directBuf.put(i, (byte) 0xcc);
115         }
116 
117         directBuf.order(ByteOrder.LITTLE_ENDIAN);
118         storeValues(directBuf);
119     }
120 
storeValues(ByteBuffer directBuf)121     static void storeValues(ByteBuffer directBuf) {
122         directBuf.position(0);
123         ShortBuffer shortBuf = directBuf.asShortBuffer();
124         CharBuffer charBuf = directBuf.asCharBuffer();
125         IntBuffer intBuf = directBuf.asIntBuffer();
126         FloatBuffer floatBuf = directBuf.asFloatBuffer();
127         LongBuffer longBuf = directBuf.asLongBuffer();
128         DoubleBuffer doubleBuf = directBuf.asDoubleBuffer();
129 
130         final byte byteValue = -5;
131         final short shortValue = -1234;
132         final char charValue = 49200;
133         final int intValue = 0x12345678;
134         final float floatValue = 3.14159f;
135         final long longValue = 0x1122334455667788L;
136         final double doubleValue = Double.MIN_VALUE;
137 
138         if (directBuf.put(1, byteValue).get(1) != byteValue) {
139             throw new RuntimeException("byte get/store failed");
140         }
141         if (shortBuf.put(1, shortValue).get(1) != shortValue) {
142             throw new RuntimeException("short get/store failed");
143         }
144         if (charBuf.put(2, charValue).get(2) != charValue) {
145             throw new RuntimeException("char get/store failed");
146         }
147         if (intBuf.put(2, intValue).get(2) != intValue) {
148             throw new RuntimeException("int get/store failed");
149         }
150         if (floatBuf.put(3, floatValue).get(3) != floatValue) {
151             throw new RuntimeException("float get/store failed");
152         }
153         if (longBuf.put(2, longValue).get(2) != longValue) {
154             throw new RuntimeException("long get/store failed");
155         }
156         if (doubleBuf.put(3, doubleValue).get(3) != doubleValue) {
157             throw new RuntimeException("double get/store failed");
158         }
159 
160         directBuf.position(0);
161         char[] outBuf = new char[directBuf.limit() * 2];
162         for (int i = 0; i < directBuf.limit(); i++) {
163             byte b = directBuf.get();
164             outBuf[i*2] = hexChar((byte) ((b >> 4) & 0x0f));
165             outBuf[i*2+1] = hexChar((byte) (b & 0x0f));
166         }
167         System.out.println(new String(outBuf));
168     }
169 
hexChar(byte b)170     static char hexChar(byte b) {
171         if (b < 10) {
172             return (char) ('0' + b);
173         } else {
174             return (char) ('a' + b - 10);
175         }
176     }
177 }
178