001 /*
002 * To change this template, choose Tools | Templates
003 * and open the template in the editor.
004 */
005
006 package com.nativelibs4java.util;
007 import java.nio.*;
008 /**
009 * NIO Buffer util methods
010 * @author ochafik
011 */
012 public 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 (bufferClass == ByteBuffer.class) return Byte.class;
034 if (bufferClass == ShortBuffer.class) return Short.class;
035 if (bufferClass == CharBuffer.class) return Character.class;
036 if (bufferClass == IntBuffer.class) return Integer.class;
037 if (bufferClass == LongBuffer.class) return Long.class;
038 if (bufferClass == FloatBuffer.class) return Float.class;
039 if (bufferClass == DoubleBuffer.class) 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 }