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 { 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 */ 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 */ 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 */ 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 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 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