001/* 002 * To change this template, choose Tools | Templates 003 * and open the template in the editor. 004 */ 005 006package com.nativelibs4java.util; 007import java.nio.*; 008/** 009 * NIO Buffer util methods 010 * @author ochafik 011 */ 012public class NIOUtils 013{ 014 015 public static Class<? extends Buffer> getBufferClass(Class<?> primitiveClass) { 016 if (primitiveClass == Byte.class || primitiveClass == byte.class) 017 return ByteBuffer.class; 018 if (primitiveClass == Short.class || primitiveClass == short.class) 019 return ShortBuffer.class; 020 if (primitiveClass == Character.class || primitiveClass == char.class) 021 return CharBuffer.class; 022 if (primitiveClass == Integer.class || primitiveClass == int.class) 023 return IntBuffer.class; 024 if (primitiveClass == Long.class || primitiveClass == long.class) 025 return LongBuffer.class; 026 if (primitiveClass == Float.class || primitiveClass == float.class) 027 return FloatBuffer.class; 028 if (primitiveClass == Double.class || primitiveClass == double.class) 029 return DoubleBuffer.class; 030 throw new UnsupportedOperationException("Unhandled primitive type : " + primitiveClass.getName()); 031 } 032 public static Class<?> getPrimitiveClass(Class<? extends Buffer> bufferClass) { 033 if (ByteBuffer.class.isAssignableFrom(bufferClass)) return Byte.class; 034 if (ShortBuffer.class.isAssignableFrom(bufferClass)) return Short.class; 035 if (CharBuffer.class.isAssignableFrom(bufferClass)) return Character.class; 036 if (IntBuffer.class.isAssignableFrom(bufferClass)) return Integer.class; 037 if (LongBuffer.class.isAssignableFrom(bufferClass)) return Long.class; 038 if (FloatBuffer.class.isAssignableFrom(bufferClass)) return Float.class; 039 if (DoubleBuffer.class.isAssignableFrom(bufferClass)) return Double.class; 040 throw new UnsupportedOperationException("Unhandled buffer type : " + bufferClass.getName()); 041 } 042 043 /** 044 * Bulk-copy all of the input buffer into the output buffer 045 * @param input 046 * @param output 047 */ 048 public static void put(Buffer input, Buffer output) { 049 if (input instanceof ByteBuffer) 050 put((ByteBuffer)input, output); 051 else if (output instanceof ByteBuffer) 052 put(input, (ByteBuffer)output); 053 else if (input instanceof IntBuffer && output instanceof IntBuffer) 054 ((IntBuffer)output).duplicate().put((IntBuffer)input); 055 else if (input instanceof LongBuffer && output instanceof LongBuffer) 056 ((LongBuffer)output).duplicate().put((LongBuffer)input); 057 else if (input instanceof ShortBuffer && output instanceof ShortBuffer) 058 ((ShortBuffer)output).duplicate().put((ShortBuffer)input); 059 else if (input instanceof CharBuffer && output instanceof CharBuffer) 060 ((CharBuffer)output).duplicate().put((CharBuffer)input); 061 else if (input instanceof DoubleBuffer && output instanceof DoubleBuffer) 062 ((DoubleBuffer)output).duplicate().put((DoubleBuffer)input); 063 else if (input instanceof FloatBuffer && output instanceof FloatBuffer) 064 ((FloatBuffer)output).duplicate().put((FloatBuffer)input); 065 else 066 throw new UnsupportedOperationException("Unhandled buffer type : " + input.getClass().getName()); 067 } 068 069 /** 070 * Bulk-copy all of the input buffer into the output buffer 071 * @param input 072 * @param outputBytes 073 */ 074 public static void put(Buffer input, ByteBuffer outputBytes) { 075 076 if (input instanceof ByteBuffer) 077 outputBytes.duplicate().put(((ByteBuffer)input).duplicate()); 078 else if (input instanceof IntBuffer) 079 outputBytes.asIntBuffer().put(((IntBuffer)input).duplicate()); 080 else if (input instanceof LongBuffer) 081 outputBytes.asLongBuffer().put(((LongBuffer)input).duplicate()); 082 else if (input instanceof ShortBuffer) 083 outputBytes.asShortBuffer().put(((ShortBuffer)input).duplicate()); 084 else if (input instanceof CharBuffer) 085 outputBytes.asCharBuffer().put(((CharBuffer)input).duplicate()); 086 else if (input instanceof DoubleBuffer) 087 outputBytes.asDoubleBuffer().put(((DoubleBuffer)input).duplicate()); 088 else if (input instanceof FloatBuffer) 089 outputBytes.asFloatBuffer().put(((FloatBuffer)input).duplicate()); 090 else 091 throw new UnsupportedOperationException("Unhandled buffer type : " + input.getClass().getName()); 092 093 } 094 095 /** 096 * Bulk-copy all input bytes into output buffer 097 * @param inputBytes 098 * @param output 099 */ 100 public static void put(ByteBuffer inputBytes, Buffer output) { 101 102 if (output instanceof IntBuffer) 103 ((IntBuffer)output).put(inputBytes.asIntBuffer()); 104 else if (output instanceof LongBuffer) 105 ((LongBuffer)output).put(inputBytes.asLongBuffer()); 106 else if (output instanceof ShortBuffer) 107 ((ShortBuffer)output).put(inputBytes.asShortBuffer()); 108 else if (output instanceof CharBuffer) 109 ((CharBuffer)output).put(inputBytes.asCharBuffer()); 110 else if (output instanceof ByteBuffer) 111 ((ByteBuffer)output).put(inputBytes); 112 else if (output instanceof DoubleBuffer) 113 ((DoubleBuffer)output).put(inputBytes.asDoubleBuffer()); 114 else if (output instanceof FloatBuffer) 115 ((FloatBuffer)output).put(inputBytes.asFloatBuffer()); 116 else if (output instanceof CharBuffer) 117 ((CharBuffer)output).put(inputBytes.asCharBuffer()); 118 else 119 throw new UnsupportedOperationException("Unhandled buffer type : " + output.getClass().getName()); 120 121 } 122 123 public static IntBuffer directCopy(IntBuffer b, ByteOrder order) { 124 return directCopy((Buffer)b, order).asIntBuffer(); 125 } 126 public static LongBuffer directCopy(LongBuffer b, ByteOrder order) { 127 return directCopy((Buffer)b, order).asLongBuffer(); 128 } 129 public static ShortBuffer directCopy(ShortBuffer b, ByteOrder order) { 130 return directCopy((Buffer)b, order).asShortBuffer(); 131 } 132 public static CharBuffer directCopy(CharBuffer b, ByteOrder order) { 133 return directCopy((Buffer)b, order).asCharBuffer(); 134 } 135 public static DoubleBuffer directCopy(DoubleBuffer b, ByteOrder order) { 136 return directCopy((Buffer)b, order).asDoubleBuffer(); 137 } 138 public static FloatBuffer directCopy(FloatBuffer b, ByteOrder order) { 139 return directCopy((Buffer)b, order).asFloatBuffer(); 140 } 141 public static ByteBuffer directCopy(Buffer b, ByteOrder order) { 142 ByteBuffer copy = ByteBuffer.allocateDirect((int)getSizeInBytes(b)).order(order == null ? ByteOrder.nativeOrder() : order); 143 put(b, copy); 144 return copy; 145 } 146 147 /** 148 * Creates a direct int buffer of the specified size (in elements) and a native byte order 149 * @param size size of the buffer in elements 150 * @param order byte order of the direct buffer 151 * @return view on new direct buffer 152 */ 153 public static IntBuffer directInts(int size, ByteOrder order) { 154 return ByteBuffer.allocateDirect(size * 4).order(order == null ? ByteOrder.nativeOrder() : order).asIntBuffer(); 155 } 156 157 /** 158 * Creates a direct lpng buffer of the specified size (in elements) and a native byte order 159 * @param size size of the buffer in elements 160 * @param order byte order of the direct buffer 161 * @return view on new direct buffer 162 */ 163 public static LongBuffer directLongs(int size, ByteOrder order) { 164 return ByteBuffer.allocateDirect(size * 8).order(order == null ? ByteOrder.nativeOrder() : order).asLongBuffer(); 165 } 166 167 /** 168 * Creates a direct short buffer of the specified size (in elements) and a native byte order 169 * @param size size of the buffer in elements 170 * @param order byte order of the direct buffer 171 * @return view on new direct buffer 172 */ 173 public static ShortBuffer directShorts(int size, ByteOrder order) { 174 return ByteBuffer.allocateDirect(size * 2).order(order == null ? ByteOrder.nativeOrder() : order).asShortBuffer(); 175 } 176 177 /** 178 * Creates a direct byte buffer of the specified size (in elements) and a native byte order 179 * @param size size of the buffer in elements 180 * @param order byte order of the direct buffer 181 * @return new direct buffer 182 */ 183 public static ByteBuffer directBytes(int size, ByteOrder order) { 184 return ByteBuffer.allocateDirect(size).order(order == null ? ByteOrder.nativeOrder() : order); 185 } 186 187 /** 188 * Creates a direct float buffer of the specified size (in elements) and a native byte order 189 * @param size size of the buffer in elements 190 * @param order byte order of the direct buffer 191 * @return view on new direct buffer 192 */ 193 public static FloatBuffer directFloats(int size, ByteOrder order) { 194 return ByteBuffer.allocateDirect(size * 4).order(order == null ? ByteOrder.nativeOrder() : order).asFloatBuffer(); 195 } 196 197 /** 198 * Creates a direct char buffer of the specified size (in elements) and a native byte order 199 * @param size size of the buffer in elements 200 * @param order byte order of the direct buffer 201 * @return view on new direct buffer 202 */ 203 public static CharBuffer directChars(int size, ByteOrder order) { 204 return ByteBuffer.allocateDirect(size * 4).order(order == null ? ByteOrder.nativeOrder() : order).asCharBuffer(); 205 } 206 207 /** 208 * Creates a direct double buffer of the specified size (in elements) and a native byte order 209 * @param size size of the buffer in elements 210 * @param order byte order of the direct buffer 211 * @return view on new direct buffer 212 */ 213 public static DoubleBuffer directDoubles(int size, ByteOrder order) { 214 return ByteBuffer.allocateDirect(size * 8).order(order == null ? ByteOrder.nativeOrder() : order).asDoubleBuffer(); 215 } 216 217 /** 218 * Creates a direct buffer of the specified size (in elements) and type.. 219 * @param size size of the buffer in elements 220 * @param order byte order of the direct buffer 221 * @param bufferClass type of the buffer. Must be one of IntBuffer.class, LongBuffer.class, ShortBuffer.class, ByteBuffer.class, DoubleBuffer.class, FloatBuffer.class 222 * @return view on new direct buffer 223 */ 224 @SuppressWarnings("unchecked") 225 public static <B extends Buffer> B directBuffer(int size, ByteOrder order, Class<B> bufferClass) { 226 if (IntBuffer.class.isAssignableFrom(bufferClass)) 227 return (B)directInts(size, order); 228 if (LongBuffer.class.isAssignableFrom(bufferClass)) 229 return (B)directLongs(size, order); 230 if (ShortBuffer.class.isAssignableFrom(bufferClass)) 231 return (B)directShorts(size, order); 232 if (ByteBuffer.class.isAssignableFrom(bufferClass)) 233 return (B)directBytes(size, order); 234 if (DoubleBuffer.class.isAssignableFrom(bufferClass)) 235 return (B)directDoubles(size, order); 236 if (FloatBuffer.class.isAssignableFrom(bufferClass)) 237 return (B)directFloats(size, order); 238 if (CharBuffer.class.isAssignableFrom(bufferClass)) 239 return (B)directChars(size, order); 240 241 throw new UnsupportedOperationException("Cannot create direct buffers of type " + bufferClass.getName()); 242 } 243 /** 244 * Creates a indirect buffer of the specified size (in elements) and type.. 245 * @param size size of the buffer in elements 246 * @param bufferClass type of the buffer. Must be one of IntBuffer.class, LongBuffer.class, ShortBuffer.class, ByteBuffer.class, DoubleBuffer.class, FloatBuffer.class 247 * @return view on new direct buffer 248 */ 249 @SuppressWarnings("unchecked") 250 public static <B extends Buffer> B indirectBuffer(int size, Class<B> bufferClass) { 251 if (IntBuffer.class.isAssignableFrom(bufferClass)) 252 return (B)IntBuffer.allocate(size); 253 if (LongBuffer.class.isAssignableFrom(bufferClass)) 254 return (B)LongBuffer.allocate(size); 255 if (ShortBuffer.class.isAssignableFrom(bufferClass)) 256 return (B)ShortBuffer.allocate(size); 257 if (ByteBuffer.class.isAssignableFrom(bufferClass)) 258 return (B)ByteBuffer.allocate(size); 259 if (DoubleBuffer.class.isAssignableFrom(bufferClass)) 260 return (B)DoubleBuffer.allocate(size); 261 if (FloatBuffer.class.isAssignableFrom(bufferClass)) 262 return (B)FloatBuffer.allocate(size); 263 if (CharBuffer.class.isAssignableFrom(bufferClass)) 264 return (B)CharBuffer.allocate(size); 265 266 throw new UnsupportedOperationException("Cannot create indirect buffers of type " + bufferClass.getName()); 267 } 268 /** 269 * Get the size in bytes of a buffer 270 */ 271 public static long getSizeInBytes(Buffer b) { 272 int c = b.capacity(); 273 return getComponentSizeInBytes(b) * c; 274 } 275 276 /** 277 * Get the size in bytes of a primitive component of a buffer 278 */ 279 public static int getComponentSizeInBytes(Buffer b) { 280 if (b instanceof IntBuffer || b instanceof FloatBuffer) 281 return 4; 282 if (b instanceof LongBuffer || b instanceof DoubleBuffer) 283 return 8; 284 if (b instanceof ShortBuffer || b instanceof CharBuffer) 285 return 2; 286 if (b instanceof ByteBuffer) 287 return 1; 288 throw new UnsupportedOperationException("Cannot guess byte size of buffers of type " + b.getClass().getName()); 289 } 290 291 public static <B extends Buffer, V> void put(B buffer, int position, V value) { 292 if (buffer instanceof IntBuffer) 293 ((IntBuffer)buffer).put(position, ((Number)value).intValue()); 294 else if (buffer instanceof LongBuffer) 295 ((LongBuffer)buffer).put(position, ((Number)value).longValue()); 296 else if (buffer instanceof ShortBuffer) 297 ((ShortBuffer)buffer).put(position, ((Number)value).shortValue()); 298 else if (buffer instanceof ByteBuffer) 299 ((ByteBuffer)buffer).put(position, ((Number)value).byteValue()); 300 else if (buffer instanceof DoubleBuffer) 301 ((DoubleBuffer)buffer).put(position, ((Number)value).doubleValue()); 302 else if (buffer instanceof FloatBuffer) 303 ((FloatBuffer)buffer).put(position, ((Number)value).floatValue()); 304 else if (buffer instanceof CharBuffer) 305 ((CharBuffer)buffer).put(position, (char)((Number)value).shortValue()); 306 else 307 throw new UnsupportedOperationException(); 308 } 309 310 @SuppressWarnings("unchecked") 311 public static <B extends Buffer, V> V get(B buffer, int position) { 312 if (buffer instanceof IntBuffer) 313 return (V)(Integer)((IntBuffer)buffer).get(position); 314 else if (buffer instanceof LongBuffer) 315 return (V)(Long)((LongBuffer)buffer).get(position); 316 else if (buffer instanceof ShortBuffer) 317 return (V)(Short)((ShortBuffer)buffer).get(position); 318 else if (buffer instanceof ByteBuffer) 319 return (V)(Byte)((ByteBuffer)buffer).get(position); 320 else if (buffer instanceof DoubleBuffer) 321 return (V)(Double)((DoubleBuffer)buffer).get(position); 322 else if (buffer instanceof FloatBuffer) 323 return (V)(Float)((FloatBuffer)buffer).get(position); 324 else if (buffer instanceof CharBuffer) 325 return (V)(Character)((CharBuffer)buffer).get(position); 326 else 327 throw new UnsupportedOperationException(); 328 } 329 330 @SuppressWarnings("unchecked") 331 public static <B extends Buffer> Object getArray(B buffer) { 332 int length = buffer.capacity(); 333 if (buffer instanceof IntBuffer) { 334 int[] a = new int[length]; 335 ((IntBuffer)buffer).duplicate().get(a); 336 return a; 337 } else if (buffer instanceof LongBuffer) { 338 long[] a = new long[length]; 339 ((LongBuffer)buffer).duplicate().get(a); 340 return a; 341 } else if (buffer instanceof ShortBuffer) { 342 short[] a = new short[length]; 343 ((ShortBuffer)buffer).duplicate().get(a); 344 return a; 345 } else if (buffer instanceof ByteBuffer) { 346 byte[] a = new byte[length]; 347 ((ByteBuffer)buffer).duplicate().get(a); 348 return a; 349 } else if (buffer instanceof DoubleBuffer) { 350 double[] a = new double[length]; 351 ((DoubleBuffer)buffer).duplicate().get(a); 352 return a; 353 } else if (buffer instanceof FloatBuffer) { 354 float[] a = new float[length]; 355 ((FloatBuffer)buffer).duplicate().get(a); 356 return a; 357 } else 358 throw new UnsupportedOperationException(); 359 } 360 public static <B extends Buffer> B wrapArray(Object a) { 361 if (a instanceof int[]) 362 return (B)IntBuffer.wrap((int[])a); 363 if (a instanceof long[]) 364 return (B)LongBuffer.wrap((long[])a); 365 if (a instanceof short[]) 366 return (B)ShortBuffer.wrap((short[])a); 367 if (a instanceof byte[]) 368 return (B)ByteBuffer.wrap((byte[])a); 369 if (a instanceof float[]) 370 return (B)FloatBuffer.wrap((float[])a); 371 if (a instanceof double[]) 372 return (B)DoubleBuffer.wrap((double[])a); 373 throw new UnsupportedOperationException("Cannot wrap primitive arrays of type " + a.getClass().getName()); 374 } 375 @SuppressWarnings("unchecked") 376 public static ByteOrder getByteOrder(Buffer buffer) { 377 if (buffer instanceof IntBuffer) { 378 return ((IntBuffer)buffer).order(); 379 } else if (buffer instanceof LongBuffer) { 380 return ((LongBuffer)buffer).order(); 381 } else if (buffer instanceof ShortBuffer) { 382 return ((ShortBuffer)buffer).order(); 383 } else if (buffer instanceof ByteBuffer) { 384 return ((ByteBuffer)buffer).order(); 385 } else if (buffer instanceof DoubleBuffer) { 386 return ((DoubleBuffer)buffer).order(); 387 } else if (buffer instanceof FloatBuffer) { 388 return ((FloatBuffer)buffer).order(); 389 } else 390 throw new UnsupportedOperationException(); 391 } 392 393}