All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bridj.PointerIO Maven / Gradle / Ivy

package org.bridj;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;
import java.nio.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicReference;
import org.bridj.util.Utils;

/**
 * Helper class that knows how to read/write data from/to a {@link Pointer}.
* End users don't need to use this class directly as ({@link Pointer} lets you work with {@link java.lang.reflect.Type} and {@link Class}). * @author Olivier */ public abstract class PointerIO { final Type targetType; final Class typedPointerClass; final int targetSize, targetAlignment = -1; public PointerIO(Type targetType, int targetSize, Class typedPointerClass) { this.targetType = targetType; this.targetSize = targetSize; this.typedPointerClass = typedPointerClass; } abstract T get(Pointer pointer, long index); abstract void set(Pointer pointer, long index, T value); public Object getArray(Pointer pointer, long byteOffset, int length) { return pointer.offset(byteOffset).toArray(length); } public B getBuffer(Pointer pointer, long byteOffset, int length) { throw new UnsupportedOperationException("Cannot create a Buffer instance of elements of type " + getTargetType()); } public void setArray(Pointer pointer, long byteOffset, Object array) { Object[] a = (Object[])array; for (int i = 0, n = a.length; i < n; i++) set(pointer, i, (T)a[i]); } public T castTarget(long peer) { throw new UnsupportedOperationException("Cannot cast pointer to " + targetType); } PointerIO> getReferenceIO() { return new CommonPointerIOs.PointerPointerIO(this); } public long getTargetSize() { return targetSize; } public long getTargetAlignment() { return targetAlignment < 0 ? getTargetSize() : targetAlignment; } public boolean isTypedPointer() { return typedPointerClass != null; } public Class getTypedPointerClass() { return typedPointerClass; } public Type getTargetType() { return targetType; } static Class getClass(Type type) { if (type instanceof Class) return (Class)type; if (type instanceof ParameterizedType) return getClass(((ParameterizedType)type).getRawType()); return null; } public static PointerIO> getPointerInstance(Type target) { return getPointerInstance((PointerIO)getInstance(target)); } public static PointerIO> getPointerInstance(PointerIO targetIO) { return new CommonPointerIOs.PointerPointerIO(targetIO); } public static PointerIO> getArrayInstance(PointerIO targetIO, long[] dimensions, int iDimension) { return new CommonPointerIOs.PointerArrayIO(targetIO, dimensions, iDimension); } static PointerIO getArrayIO(Object array) { if (array instanceof int[]) return (PointerIO)PointerIO.getIntInstance(); if (array instanceof long[]) return (PointerIO)PointerIO.getLongInstance(); if (array instanceof short[]) return (PointerIO)PointerIO.getShortInstance(); if (array instanceof byte[]) return (PointerIO)PointerIO.getByteInstance(); if (array instanceof char[]) return (PointerIO)PointerIO.getCharInstance(); if (array instanceof float[]) return (PointerIO)PointerIO.getFloatInstance(); if (array instanceof double[]) return (PointerIO)PointerIO.getDoubleInstance(); if (array instanceof boolean[]) return (PointerIO)PointerIO.getBooleanInstance(); return PointerIO.getInstance(array.getClass().getComponentType()); } private static final ConcurrentHashMap> structIOs = new ConcurrentHashMap>(); public static PointerIO getInstance(StructIO s) { PointerIO io = structIOs.get(s); if (io == null) { io = new CommonPointerIOs.StructPointerIO(s); PointerIO previousIO = structIOs.putIfAbsent(s, io); if (previousIO != null) io = previousIO; } return io; } private static final ConcurrentHashMap> ios = new ConcurrentHashMap>(); public static

PointerIO

getInstance(Type type) { if (type == null) return null; PointerIO io = ios.get(type); if (io == null) { final Class cl = Utils.getClass(type); if (type == Integer.TYPE || type == Integer.class) io = CommonPointerIOs.intIO; else if (type == Long.TYPE || type == Long.class) io = CommonPointerIOs.longIO; else if (type == Short.TYPE || type == Short.class) io = CommonPointerIOs.shortIO; else if (type == Byte.TYPE || type == Byte.class) io = CommonPointerIOs.byteIO; else if (type == Character.TYPE || type == Character.class) io = CommonPointerIOs.charIO; else if (type == Float.TYPE || type == Float.class) io = CommonPointerIOs.floatIO; else if (type == Double.TYPE || type == Double.class) io = CommonPointerIOs.doubleIO; else if (type == Boolean.TYPE || type == Boolean.class) io = CommonPointerIOs.booleanIO; else if (cl != null) { if (TypedPointer.class.isAssignableFrom(cl)) io = new CommonPointerIOs.TypedPointerPointerIO((Class)cl); else if (Pointer.class.isAssignableFrom(cl)) { if (Pointer.class.equals(type) || !(type instanceof ParameterizedType)) io = getPointerInstance((PointerIO)null); else io = getPointerInstance(((ParameterizedType)type).getActualTypeArguments()[0]); } else if (SizeT.class.isAssignableFrom(cl)) io = CommonPointerIOs.sizeTIO; else if (TimeT.class.isAssignableFrom(cl)) io = CommonPointerIOs.timeTIO; else if (CLong.class.isAssignableFrom(cl)) io = CommonPointerIOs.clongIO; else if (StructObject.class.isAssignableFrom(cl)) io = getInstance(StructIO.getInstance((Class)cl, type)); else if (Callback.class.isAssignableFrom(cl)) io = new CommonPointerIOs.CallbackPointerIO(cl); else if (NativeObject.class.isAssignableFrom(cl)) io = new CommonPointerIOs.NativeObjectPointerIO(type); else if (IntValuedEnum.class.isAssignableFrom(cl)) { if (type instanceof ParameterizedType) { Type enumType = ((ParameterizedType)type).getActualTypeArguments()[0]; if (enumType instanceof Class) io = new CommonPointerIOs.IntValuedEnumPointerIO((Class)enumType); } } } //else //throw new UnsupportedOperationException("Cannot create pointer io to type " + type + ((type instanceof Class) && ((Class)type).getSuperclass() != null ? " (parent type : " + ((Class)type).getSuperclass().getName() + ")" : "")); //return null; // TODO throw here ? //if (io == null) // throw new RuntimeException("Failed to create pointer io to type " + type); if (io != null) { PointerIO previousIO = ios.putIfAbsent(type, io); if (previousIO != null) io = previousIO; // created io twice : not important in general (expecially not compared to cost of contention on non-concurrent map) } } return io; } private static PointerIO atomicInstance(AtomicReference ref, Type type) { PointerIO io = (PointerIO)ref.get(); if (io != null) return io; if (ref.compareAndSet(null, io = getInstance(type))) return io; return (PointerIO)ref.get(); } private static final AtomicReference> intInstance = new AtomicReference>(); public static PointerIO getIntInstance() { return atomicInstance(intInstance, Integer.class); } /* PointerIO io = intInstance.get(); if (io != null) return io; if (intInstance.compareAndSet(null, io = getInstance(Integer.class))) return io; return intInstance.get(); }*/ private static final AtomicReference> longInstance = new AtomicReference>(); public static PointerIO getLongInstance() { return atomicInstance(longInstance, Long.class); } /* PointerIO io = longInstance.get(); if (io != null) return io; if (longInstance.compareAndSet(null, io = getInstance(Long.class))) return io; return longInstance.get(); }*/ private static final AtomicReference> shortInstance = new AtomicReference>(); public static PointerIO getShortInstance() { return atomicInstance(shortInstance, Short.class); } /* PointerIO io = shortInstance.get(); if (io != null) return io; if (shortInstance.compareAndSet(null, io = getInstance(Short.class))) return io; return shortInstance.get(); }*/ private static final AtomicReference> byteInstance = new AtomicReference>(); public static PointerIO getByteInstance() { return atomicInstance(byteInstance, Byte.class); } /* PointerIO io = byteInstance.get(); if (io != null) return io; if (byteInstance.compareAndSet(null, io = getInstance(Byte.class))) return io; return byteInstance.get(); }*/ private static final AtomicReference> charInstance = new AtomicReference>(); public static PointerIO getCharInstance() { return atomicInstance(charInstance, Character.class); } /* PointerIO io = charInstance.get(); if (io != null) return io; if (charInstance.compareAndSet(null, io = getInstance(Character.class))) return io; return charInstance.get(); }*/ private static final AtomicReference> floatInstance = new AtomicReference>(); public static PointerIO getFloatInstance() { return atomicInstance(floatInstance, Float.class); } /* PointerIO io = floatInstance.get(); if (io != null) return io; if (floatInstance.compareAndSet(null, io = getInstance(Float.class))) return io; return floatInstance.get(); }*/ private static final AtomicReference> doubleInstance = new AtomicReference>(); public static PointerIO getDoubleInstance() { return atomicInstance(doubleInstance, Double.class); } /* PointerIO io = doubleInstance.get(); if (io != null) return io; if (doubleInstance.compareAndSet(null, io = getInstance(Double.class))) return io; return doubleInstance.get(); }*/ private static final AtomicReference> booleanInstance = new AtomicReference>(); public static PointerIO getBooleanInstance() { return atomicInstance(booleanInstance, Boolean.class); } /* PointerIO io = booleanInstance.get(); if (io != null) return io; if (booleanInstance.compareAndSet(null, io = getInstance(Boolean.class))) return io; return booleanInstance.get(); }*/ private static final AtomicReference> CLongInstance = new AtomicReference>(); public static PointerIO getCLongInstance() { return atomicInstance(CLongInstance, CLong.class); } /* PointerIO io = CLongInstance.get(); if (io != null) return io; if (CLongInstance.compareAndSet(null, io = getInstance(CLong.class))) return io; return CLongInstance.get(); }*/ private static final AtomicReference> SizeTInstance = new AtomicReference>(); public static PointerIO getSizeTInstance() { return atomicInstance(SizeTInstance, SizeT.class); } /* PointerIO io = SizeTInstance.get(); if (io != null) return io; if (SizeTInstance.compareAndSet(null, io = getInstance(SizeT.class))) return io; return SizeTInstance.get(); }*/ private static final AtomicReference> PointerInstance = new AtomicReference>(); public static PointerIO getPointerInstance() { return atomicInstance(PointerInstance, Pointer.class); } /* PointerIO io = PointerInstance.get(); if (io != null) return io; if (PointerInstance.compareAndSet(null, io = getInstance(Pointer.class))) return io; return PointerInstance.get(); }*/ public static

PointerIO

getBufferPrimitiveInstance(Buffer buffer) { if (buffer instanceof IntBuffer) return (PointerIO

)getIntInstance(); if (buffer instanceof LongBuffer) return (PointerIO

)getLongInstance(); if (buffer instanceof ShortBuffer) return (PointerIO

)getShortInstance(); if (buffer instanceof ByteBuffer) return (PointerIO

)getByteInstance(); if (buffer instanceof CharBuffer) return (PointerIO

)getCharInstance(); if (buffer instanceof FloatBuffer) return (PointerIO

)getFloatInstance(); if (buffer instanceof DoubleBuffer) return (PointerIO

)getDoubleInstance(); throw new UnsupportedOperationException(); } private static final AtomicReference stringInstance = new AtomicReference(); public static PointerIO getStringInstance() { return atomicInstance(stringInstance, String.class);/* PointerIO io = stringInstance.get(); if (io != null) return io; if (stringInstance.compareAndSet(null, io = getInstance(String.class))) return io; return stringInstance.get();*/ } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy