libraryOptions,
String... libraryNames);
/**
* Gets the last native error code.
*
* This returns the errno value that was set at the time of the last native
* function call.
*
* @return The errno value.
*/
public abstract int getLastError();
/**
* Sets the native error code.
*
* @param error The value to set errno to.
*/
public abstract void setLastError(int error);
public abstract Type getType(NativeType type);
private static final class SingletonHolder {
private static final FFIProvider INSTANCE = getInstance();
private static final FFIProvider getInstance() {
final boolean useJNA = Boolean.getBoolean("jaffl.usejna");
FFIProvider provider = null;
String prefix = FFIProvider.class.getPackage().getName() + ".provider";
if (!useJNA) {
try {
provider = (FFIProvider) Class.forName(prefix + ".jffi.Provider").newInstance();
} catch (Throwable ex) {
}
}
if (provider == null) {
try {
provider = (FFIProvider) Class.forName(prefix + ".jna.JNAProvider").newInstance();
} catch (Throwable ex) {
throw new RuntimeException("Could not load FFI provider", ex);
}
}
return provider;
}
}
protected FFIProvider() {}
}
jaffl-0.5.9/src/com/kenai/jaffl/LastError.java 0000664 0000000 0000000 00000001200 12017475436 0021107 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl;
/**
* Enables getting/setting of the unix errno and windows GetLastError() value
*/
public final class LastError {
private LastError() {}
/**
* Gets the value of errno from the last native call.
*
* @return An integer containing the errno value.
*/
public static final int getLastError() {
return FFIProvider.getProvider().getLastError();
}
/**
* Sets the native errno value.
*
* @param error The value to set errno to.
*/
public static final void setLastError(int error) {
FFIProvider.getProvider().setLastError(error);
}
}
jaffl-0.5.9/src/com/kenai/jaffl/Library.java 0000664 0000000 0000000 00000011176 12017475436 0020613 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl;
import java.io.File;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
/**
*
*/
public final class Library {
private static final Map> customSearchPaths
= new ConcurrentHashMap>();
/** The name of this library */
private final String name;
private Library(String libraryName) {
name = libraryName;
}
/**
* Loads a native library and links the methods defined in {@code interfaceClass}
* to native methods in the library.
*
* @param libraryName the name of the library to load
* @param interfaceClass the interface that describes the native library interface
* @return an instance of {@code interfaceclass} that will call the native methods.
*/
public static T loadLibrary(String libraryName, Class interfaceClass) {
final Map options = Collections.emptyMap();
return loadLibrary(libraryName, interfaceClass, options);
}
/**
* Loads a native library and links the methods defined in {@code interfaceClass}
* to native methods in the library.
*
* @param libraryName the name of the library to load
* @param interfaceClass the interface that describes the native library interface
* @return an instance of {@code interfaceclass} that will call the native methods.
*/
public static T loadLibrary(Class interfaceClass, String... libraryNames) {
final Map options = Collections.emptyMap();
return loadLibrary(interfaceClass, options, libraryNames);
}
/**
* Loads a native library and links the methods defined in {@code interfaceClass}
* to native methods in the library.
*
* @param libraryName the name of the library to load
* @param interfaceClass the interface that describes the native library interface
* @param libraryOptions options
* @return an instance of {@code interfaceclass} that will call the native methods.
*/
public static T loadLibrary(String libraryName, Class interfaceClass,
Map libraryOptions) {
return FFIProvider.getProvider().loadLibrary(libraryName, interfaceClass, libraryOptions);
}
/**
* Loads a native library and links the methods defined in {@code interfaceClass}
* to native methods in the library.
*
* @param libraryName the name of the library to load
* @param interfaceClass the interface that describes the native library interface
* @param libraryOptions options
* @return an instance of {@code interfaceclass} that will call the native methods.
*/
public static T loadLibrary(Class interfaceClass, Map libraryOptions,
String... libraryNames) {
return FFIProvider.getProvider().loadLibrary(interfaceClass, libraryOptions, libraryNames);
}
/**
* Adds a custom search path for a library
*
* @param libraryName the name of the library to search for
* @param path the path to search for the library in
*/
public static synchronized final void addLibraryPath(String libraryName, File path) {
List customPaths = customSearchPaths.get(libraryName);
if (customPaths == null) {
customPaths = new CopyOnWriteArrayList();
customSearchPaths.put(libraryName, customPaths);
}
customPaths.add(path.getAbsolutePath());
}
/**
* Gets the custom search path for a library.
*
* @param libraryName The library to retrieve the path for.
*
* @return A List of String instances.
*/
public static List getLibraryPath(String libraryName) {
List customPaths = customSearchPaths.get(libraryName);
if (customPaths != null) {
return customPaths;
}
return Collections.emptyList();
}
public static final Library getInstance(String libraryName) {
return new Library(libraryName);
}
/**
* Checks if a specific function exists in the library.
*
* @param function The function
* @return true if the function exists
* @deprecated this method is no longer supported.
*/
public boolean hasFunction(String function) {
return false;
}
/**
* Gets the name of this library
*
* @return The name of this library as a String
*/
public String getName() {
return name;
}
}
jaffl-0.5.9/src/com/kenai/jaffl/LibraryOption.java 0000664 0000000 0000000 00000002033 12017475436 0021774 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl;
/**
* Options that apply to a library
*/
public enum LibraryOption {
/**
* Function calls should save the errno/last error after the call.
* This option can be overridden on individual methods by use of the
* {@link com.googlecode.jffi.annotations.IgnoreError} annotation.
*/
SaveError,
/**
* Function calls should NOT save the errno/last error after the call.
* This option can be overridden on individual methods by use of the
* {@link com.googlecode.jffi.annotations.SaveError} annotation.
*/
IgnoreError,
/**
* A type mapper which maps java types to native types is present.
*/
TypeMapper,
/**
* A function mapper which maps from java function names to native function names.
*/
FunctionMapper,
/**
* The type of calling convention.
* @see CallingConvention
*/
CallingConvention,
/**
* Load the library into memory immediately, instead of lazily loading it
*/
LoadNow;
}
jaffl-0.5.9/src/com/kenai/jaffl/MemoryIO.java 0000664 0000000 0000000 00000031675 12017475436 0020715 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
/**
* Interface to reading/writing various types of memory
*/
public abstract class MemoryIO implements Pointer {
/**
* Allocates a new block of java heap memory and wraps it in a {@link MemoryIO}
* accessor.
*
* @param size The size in bytes of memory to allocate.
*
* @return A new MemoryIO instance that can access the memory.
*/
public static final MemoryIO allocate(int size) {
return FFIProvider.getProvider().getMemoryManager().allocate(size);
}
/**
* Allocates a new block of native memory and wraps it in a {@link MemoryIO}
* accessor.
*
* @param size The size in bytes of memory to allocate.
*
* @return A new MemoryIO instance that can access the memory.
*/
public static final MemoryIO allocateDirect(int size) {
return FFIProvider.getProvider().getMemoryManager().allocateDirect(size);
}
/**
* Allocates a new block of native memory and wraps it in a {@link MemoryIO}
* accessor.
*
* @param size The size in bytes of memory to allocate.
* @param clear Whether the memory contents should be cleared, or left as
* random data.
*
* @return A new MemoryIO instance that can access the memory.
*/
public static final MemoryIO allocateDirect(int size, boolean clear) {
return FFIProvider.getProvider().getMemoryManager().allocateDirect(size, clear);
}
public static final MemoryIO wrap(Pointer ptr) {
return FFIProvider.getProvider().getMemoryManager().wrap(ptr);
}
public static final MemoryIO wrap(Pointer ptr, int size) {
return FFIProvider.getProvider().getMemoryManager().wrap(ptr, size);
}
public static final MemoryIO wrap(ByteBuffer buffer) {
return FFIProvider.getProvider().getMemoryManager().wrap(buffer);
}
/**
* Reads a 8 bit integer at the given offset.
*
* @param offset The offset from which the integer will be read.
* @return The byte value at the offset.
*/
abstract public byte getByte(long offset);
/**
* Reads a 16 bit integer at the given offset.
*
* @param offset The offset from which the integer will be read.
* @return The short value at the offset.
*/
abstract public short getShort(long offset);
/**
* Reads a 32 bit integer at the given offset.
*
* @param offset The offset from which the integer will be read.
* @return The int value at the offset.
*/
abstract public int getInt(long offset);
/**
* Reads a 64 bit integer at the given offset.
*
* @param offset The offset from which the integer will be read.
* @return The long value at the offset.
*/
abstract public long getLong(long offset);
/**
* Reads a 32 bit floating point value at the given offset.
*
* @param offset The offset from which the integer will be read.
* @return The float value at the offset.
*/
abstract public float getFloat(long offset);
/**
* Reads a 64 bit floating point value at the given offset.
*
* @param offset The offset from which the integer will be read.
* @return The double value at the offset.
*/
abstract public double getDouble(long offset);
/**
* Writes an 8 bit integer value at the given offset.
*
* @param offset The offset at which the value will be written.
* @param value The value to be written.
*/
abstract public void putByte(long offset, byte value);
/**
* Writes a 16 bit integer value at the given offset.
*
* @param offset The offset at which the value will be written.
* @param value The value to be written.
*/
abstract public void putShort(long offset, short value);
/**
* Writes a 32 bit integer value at the given offset.
*
* @param offset The offset at which the value will be written.
* @param value The value to be written.
*/
abstract public void putInt(long offset, int value);
/**
* Writes a 64 bit integer value at the given offset.
*
* @param offset The offset at which the value will be written.
* @param value The value to be written.
*/
abstract public void putLong(long offset, long value);
/**
* Writes a 32 bit floating point value at the given offset.
*
* @param offset The offset at which the value will be written.
* @param value The value to be written.
*/
abstract public void putFloat(long offset, float value);
/**
* Writes a 64 bit floating point value at the given offset.
*
* @param offset The offset at which the value will be written.
* @param value The value to be written.
*/
abstract public void putDouble(long offset, double value);
/**
* Bulk byte get method.
*
* This method reads an array of bytes at the given offset into the given
* destination array.
*
* @param offset The offset at which the values will be read.
* @param dst The array into which values are to be written.
* @param idx The index within the destination array of the first value to be written.
* @param len The number of values to be written to the destination array.
*/
abstract public void get(long offset, byte[] dst, int idx, int len);
/**
* Bulk byte put method.
*
* This method writes an array of bytes at the given offset from the given
* source array.
*
* @param offset The offset at which the values will be written.
* @param src The source array from which values are to be read.
* @param idx The index within the destination array of the first value to be read.
* @param len The number of values to be read from the source array.
*/
abstract public void put(long offset, byte[] src, int idx, int len);
/**
* Bulk short get method.
*
* This method reads an array of 16 bit integers at the given offset into the given
* destination array.
*
* @param offset The offset at which the values will be read.
* @param dst The array into which values are to be written.
* @param idx The index within the destination array of the first value to be written.
* @param len The number of values to be written to the destination array.
*/
abstract public void get(long offset, short[] dst, int idx, int len);
/**
* Bulk short put method.
*
* This method writes an array of 16 bit integers at the given offset from
* the given array.
*
* @param offset The offset at which the values will be written.
* @param src The source array from which values are to be read.
* @param idx The index within the destination array of the first value to be read.
* @param len The number of values to be read from the source array.
*/
abstract public void put(long offset, short[] src, int idx, int len);
/**
* Bulk int get method.
*
* This method reads an array of 32 bit integers at the given offset into the given
* destination array.
*
* @param offset The offset at which the values will be read.
* @param dst The array into which values are to be written.
* @param idx The index within the destination array of the first value to be written.
* @param len The number of values to be written to the destination array.
*/
abstract public void get(long offset, int[] dst, int idx, int len);
/**
* Bulk int put method.
*
* This method writes an array of 32 bit integers at the given offset from
* the given array.
*
* @param offset The offset at which the values will be written.
* @param src The source array from which values are to be read.
* @param idx The index within the destination array of the first value to be read.
* @param len The number of values to be read from the source array.
*/
abstract public void put(long offset, int[] src, int idx, int len);
/**
* Bulk long get method.
*
* This method reads an array of 64 bit integers at the given offset into the given
* destination array.
*
* @param offset The offset at which the values will be read.
* @param dst The array into which values are to be written.
* @param idx The index within the destination array of the first value to be written.
* @param len The number of values to be written to the destination array.
*/
abstract public void get(long offset, long[] dst, int idx, int len);
/**
* Bulk long put method.
*
* This method writes an array of 64 bit integers at the given offset from
* the given array.
*
* @param offset The offset at which the values will be written.
* @param src The source array from which values are to be read.
* @param idx The index within the destination array of the first value to be read.
* @param len The number of values to be read from the source array.
*/
abstract public void put(long offset, long[] src, int idx, int len);
/**
* Bulk float get method.
*
* This method reads an array of 32 bit floats at the given offset into the given
* destination array.
*
* @param offset The offset at which the values will be read.
* @param dst The array into which values are to be written.
* @param idx The index within the destination array of the first value to be written.
* @param len The number of values to be written to the destination array.
*/
abstract public void get(long offset, float[] dst, int idx, int len);
/**
* Bulk float put method.
*
* This method writes an array of 32 bit floats at the given offset from
* the given array.
*
* @param offset The offset at which the values will be written.
* @param src The source array from which values are to be read.
* @param idx The index within the destination array of the first value to be read.
* @param len The number of values to be read from the source array.
*/
abstract public void put(long offset, float[] src, int idx, int len);
/**
* Bulk double get method.
*
* This method reads an array of 64 bit floats at the given offset into the given
* destination array.
*
* @param offset The offset at which the values will be read.
* @param dst The array into which values are to be written.
* @param idx The index within the destination array of the first value to be written.
* @param len The number of values to be written to the destination array.
*/
abstract public void get(long offset, double[] dst, int idx, int len);
/**
* Bulk double put method.
*
* This method writes an array of 64 bit floats at the given offset from
* the given array.
*
* @param offset The offset at which the values will be written.
* @param src The source array from which values are to be read.
* @param idx The index within the destination array of the first value to be read.
* @param len The number of values to be read from the source array.
*/
abstract public void put(long offset, double[] src, int idx, int len);
abstract public MemoryIO getMemoryIO(long offset);
abstract public MemoryIO getMemoryIO(long offset, long size);
abstract public Pointer getPointer(long offset);
abstract public void putPointer(long offset, Pointer value);
abstract public int indexOf(long offset, byte value);
abstract public int indexOf(long offset, byte value, int maxlen);
abstract public long getAddress(long offset);
abstract public void putAddress(long offset, long value);
abstract public void putAddress(long offset, Address value);
abstract public long getNativeLong(long offset);
abstract public void putNativeLong(long offset, long value);
abstract public String getString(long offset, int maxLength, Charset cs);
abstract public String getString(long offset);
abstract public void putString(long offset, String string, int maxLength, Charset cs);
abstract public MemoryIO slice(long offset);
abstract public MemoryIO slice(long offset, long size);
abstract public void transferTo(long offset, MemoryIO other, long otherOffset, long count);
abstract public void setMemory(long offset, long size, byte value);
/**
* Tells whether or not this memory object is direct.
*
* Memory objects can be either direct (representing native memory), or
* non-direct (representing java heap memory).
*
* @return true if, and only if, this memory object is direct
*/
abstract public boolean isDirect();
/**
* Gets the native address of this memory object (optional operation).
*
* @return The native address of this memory object.
* @throws UnsupportedOperationException If this memory object is not backed by native memory.
*/
abstract public long address();
}
jaffl-0.5.9/src/com/kenai/jaffl/NativeLong.java 0000664 0000000 0000000 00000011237 12017475436 0021253 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl;
/**
* Represents a C long.
*
* In C, a long can be either 32 bits or 64bits, depending on the platform.
*
* Replace any function parameters which are long in the C definition with
* a NativeLong.
*
*/
public final class NativeLong extends Number implements Comparable {
public static final int SIZE = Platform.getPlatform().longSize();
public static final int SHIFT = SIZE == 32 ? 2 : 3;
public static final long MASK = SIZE == 32 ? 0xffffffffL : 0xffffffffffffffffL;
private static final NativeLong ZERO = new NativeLong(0);
private static final NativeLong ONE = new NativeLong(1);
private static final NativeLong MINUS_ONE = new NativeLong(-1);
private final long value;
/**
* Creates a new NativeLong instance with the supplied value.
*
* @param value a long or integer.
*/
public NativeLong(long value) {
this.value = value;
}
/**
* Returns an integer representation of this NativeLong.
*
* @return an integer value for this NativeLong.
*/
@Override
public final int intValue() {
return (int) value;
}
/**
* Returns an {@code long} representation of this NativeLong.
*
* @return an {@code long} value for this NativeLong.
*/
@Override
public final long longValue() {
return value;
}
/**
* Returns an {@code float} representation of this NativeLong.
*
* @return an {@code float} value for this NativeLong.
*/
@Override
public final float floatValue() {
return (float) value;
}
/**
* Returns an {@code double} representation of this NativeLong.
*
* @return an {@code double} value for this NativeLong.
*/
@Override
public final double doubleValue() {
return (double) value;
}
/**
* Gets a hash code for this {@code NativeLong}.
*
* @return a hash code for this {@code NativeLong}.
*/
@Override
public final int hashCode() {
return (int)(value ^ (value >>> 32));
}
/**
* Compares this NativeLong to another NativeLong.
*
* @param obj the other NativeLong to compare to.
* @return {@code true} if this NativeLong is equal to the other
* NativeLong, else false.
*/
@Override
public final boolean equals(Object obj) {
return ((obj instanceof NativeLong) && value == ((NativeLong) obj).value);
}
/**
* Returns a string representation of this NativeLong.
*
* @return a string representation of this NativeLong.
*/
@Override
public String toString() {
return String.valueOf(value);
}
/**
* Compares two {@code NativeLong} instances numerically.
*
* @param other the other NativeLong to compare to.
*
* @return {@code 0} if {@code other} is equal to this instance, -1 if this
* instance is numerically less than {@code other} or 1 if this instance is
* numerically greater than {@code other}.
*/
public final int compareTo(NativeLong other) {
return value < other.value ? -1 : value > other.value ? 1 : 0;
}
/**
* Internal cache of common native long values
*/
private static final class Cache {
private Cache() {}
static final NativeLong[] cache = new NativeLong[256];
static {
for (int i = 0; i < cache.length; ++i) {
cache[i] = new NativeLong(i - 128);
}
cache[128 + 0] = ZERO;
cache[128 + 1] = ONE;
cache[128 - 1] = MINUS_ONE;
}
}
private static final NativeLong _valueOf(final long value) {
return value >= -128 && value <= 127
? Cache.cache[128 + (int) value] : new NativeLong(value);
}
/**
* Returns a NativeLong instance representing the specified long value
*
* @param value a long value
* @return a NativeLong instance representing value
*/
public static final NativeLong valueOf(final long value) {
return value == 0 ? ZERO : value == 1 ? ONE : value == -1 ? MINUS_ONE : _valueOf(value);
}
/**
* Returns a NativeLong instance representing the specified int value
*
* @param value a 32bit integer value
* @return a NativeLong instance representing value
*/
public static final NativeLong valueOf(final int value) {
return valueOf((long) value);
}
}
jaffl-0.5.9/src/com/kenai/jaffl/ParameterFlags.java 0000664 0000000 0000000 00000004471 12017475436 0022104 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl;
import com.kenai.jaffl.annotations.Direct;
import com.kenai.jaffl.annotations.In;
import com.kenai.jaffl.annotations.NulTerminate;
import com.kenai.jaffl.annotations.Out;
import com.kenai.jaffl.annotations.Pinned;
import com.kenai.jaffl.annotations.Transient;
import java.lang.annotation.Annotation;
/**
*
* @author wayne
*/
public final class ParameterFlags {
private ParameterFlags() {}
public static final int OUT = 0x01;
public static final int IN = 0x02;
public static final int PINNED = 0x04;
public static final int NULTERMINATE = 0x08;
public static final int TRANSIENT = 0x10;
public static final int DIRECT = 0x20;
public static final int parse(Annotation[] annotations) {
int flags = 0;
for (Annotation a : annotations) {
flags |= a instanceof Out ? OUT : 0;
flags |= a instanceof In ? IN : 0;
flags |= a instanceof Transient ? TRANSIENT : 0;
flags |= a instanceof Direct ? DIRECT : 0;
flags |= a instanceof Pinned ? PINNED : 0;
flags |= a instanceof NulTerminate ? NULTERMINATE : 0;
}
return flags;
}
/**
* Checks if the annotation is a recognised parameter flag.
*
* @param annotation the annotation to check.
* @return true if the annotation is a parameter flag
*/
public static final boolean isFlag(Annotation annotation) {
return annotation instanceof Pinned
|| annotation instanceof Transient
|| annotation instanceof Direct
|| annotation instanceof NulTerminate
|| annotation instanceof Out
|| annotation instanceof In;
}
public static final boolean isPinned(int flags) {
return (flags & PINNED) != 0;
}
public static final boolean isTransient(int flags) {
return (flags & TRANSIENT) != 0;
}
public static final boolean isDirect(int flags) {
return (flags & DIRECT) != 0;
}
public static final boolean isNulTerminate(int flags) {
return (flags & NULTERMINATE) != 0;
}
public static final boolean isOut(int flags) {
return (flags & (OUT | IN)) != IN;
}
public static final boolean isIn(int flags) {
return (flags & (OUT | IN)) != OUT;
}
}
jaffl-0.5.9/src/com/kenai/jaffl/Platform.java 0000664 0000000 0000000 00000030553 12017475436 0020773 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl;
import java.io.File;
import java.io.FilenameFilter;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Pattern;
public abstract class Platform {
private final OS os;
private final CPU cpu;
private final int longSize;
private final int addressSize;
private final long addressMask;
private final int javaVersionMajor;
protected final Pattern libPattern;
/**
* The common names of operating systems.
*
* Note The names of the enum values are used in other parts of the
* code to determine where to find the native stub library. Do not rename.
*/
public enum OS {
/** MacOSX */
DARWIN,
/** FreeBSD */
FREEBSD,
/** NetBSD */
NETBSD,
/** OpenBSD */
OPENBSD,
/** Linux */
LINUX,
/** Solaris (and OpenSolaris) */
SOLARIS,
/** The evil borg operating system */
WINDOWS,
/** IBM AIX */
AIX,
/** IBM zOS **/
ZLINUX,
/** No idea what the operating system is */
UNKNOWN;
@Override
public String toString() { return name().toLowerCase(); }
}
/**
* The common names of cpu architectures.
*
* Note The names of the enum values are used in other parts of the
* code to determine where to find the native stub library. Do not rename.
*/
public enum CPU {
/** Intel ia32 */
I386,
/** AMD 64 bit (aka EM64T/X64) */
X86_64,
/** Power PC 32 bit */
PPC,
/** Power PC 64 bit */
PPC64,
/** Sun sparc 32 bit */
SPARC,
/** Sun sparc 64 bit */
SPARCV9,
/** IBM zSeries S/390 64 bit */
S390X,
/** Unknown CPU */
UNKNOWN;
@Override
public String toString() { return name().toLowerCase(); }
}
private static final class SingletonHolder {
static final Platform PLATFORM = determinePlatform(determineOS());
}
/**
* Determines the operating system jffi is running on
*
* @return An member of the OS enum.
*/
private static final OS determineOS() {
String osName = System.getProperty("os.name").split(" ")[0].toLowerCase();
if (osName.startsWith("mac") || osName.startsWith("darwin")) {
return OS.DARWIN;
} else if (osName.startsWith("linux")) {
return OS.LINUX;
} else if (osName.startsWith("sunos") || osName.startsWith("solaris")) {
return OS.SOLARIS;
} else if (osName.startsWith("aix")) {
return OS.AIX;
} else if (osName.startsWith("openbsd")) {
return OS.OPENBSD;
} else if (osName.startsWith("freebsd")) {
return OS.FREEBSD;
} else if (osName.startsWith("windows")) {
return OS.WINDOWS;
} else {
return OS.UNKNOWN;
}
}
/**
* Determines the Platform that best describes the OS
*
* @param os The operating system.
* @return An instance of Platform
*/
private static final Platform determinePlatform(OS os) {
switch (os) {
case DARWIN:
return new Darwin();
case LINUX:
return new Linux();
case WINDOWS:
return new Windows();
case UNKNOWN:
return new Unsupported(os);
default:
return new Default(os);
}
}
private static final CPU determineCPU() {
String archString = System.getProperty("os.arch").toLowerCase();
if ("x86".equals(archString) || "i386".equals(archString) || "i86pc".equals(archString)) {
return CPU.I386;
} else if ("x86_64".equals(archString) || "amd64".equals(archString)) {
return CPU.X86_64;
} else if ("ppc".equals(archString) || "powerpc".equals(archString)) {
return CPU.PPC;
}
// Try to find by lookup up in the CPU list
try {
return CPU.valueOf(archString.toUpperCase());
} catch (IllegalArgumentException ex) {
return CPU.UNKNOWN;
}
}
private Platform(OS os) {
this.os = os;
this.cpu = determineCPU();
int dataModel = Integer.getInteger("sun.arch.data.model");
if (dataModel != 32 && dataModel != 64) {
switch (cpu) {
case I386:
case PPC:
case SPARC:
dataModel = 32;
break;
case X86_64:
case PPC64:
case SPARCV9:
case S390X:
dataModel = 64;
break;
default:
throw new ExceptionInInitializerError("Cannot determine cpu address size");
}
}
addressSize = dataModel;
addressMask = addressSize == 32 ? 0xffffffffL : 0xffffffffffffffffL;
longSize = os == OS.WINDOWS ? 32 : addressSize;
int version = 5;
try {
String versionString = System.getProperty("java.version");
if (versionString != null) {
String[] v = versionString.split("\\.");
version = Integer.valueOf(v[1]);
}
} catch (Exception ex) {
throw new ExceptionInInitializerError("Could not determine java version");
}
javaVersionMajor = version;
String libpattern = null;
switch (os) {
case WINDOWS:
libpattern = ".*\\.dll$";
break;
case DARWIN:
libpattern = "lib.*\\.(dylib|jnilib)$";
break;
default:
libpattern = "lib.*\\.so.*$";
break;
}
libPattern = Pattern.compile(libpattern);
}
/**
* Gets the current Platform
*
* @return The current platform.
*/
public static final Platform getPlatform() {
return SingletonHolder.PLATFORM;
}
/**
* Gets the current Operating System.
*
* @return A OS value representing the current Operating System.
*/
public final OS getOS() {
return os;
}
/**
* Gets the current processor architecture the JVM is running on.
*
* @return A CPU value representing the current processor architecture.
*/
public final CPU getCPU() {
return cpu;
}
/**
* Gets the version of the Java Virtual Machine (JVM) jffi is running on.
*
* @return A number representing the java version. e.g. 5 for java 1.5, 6 for java 1.6
*/
public final int getJavaMajorVersion() {
return javaVersionMajor;
}
public final boolean isBSD() {
return os == OS.FREEBSD || os == os.OPENBSD || os == OS.NETBSD || os == OS.DARWIN;
}
public final boolean isUnix() {
return os != OS.WINDOWS;
}
/**
* Gets the size of a C 'long' on the native platform.
*
* @return the size of a long in bits
*/
public final int longSize() {
return longSize;
}
/**
* Gets the size of a C address/pointer on the native platform.
*
* @return the size of a pointer in bits
*/
public final int addressSize() {
return addressSize;
}
/**
* Gets the 32/64bit mask of a C address/pointer on the native platform.
*
* @return the size of a pointer in bits
*/
public final long addressMask() {
return addressMask;
}
/**
* Gets the name of this Platform.
*
* @return The name of this platform.
*/
public String getName() {
return cpu + "-" + os;
}
/**
* Maps from a generic library name (e.g. "c") to the platform specific library name.
*
* @param libName The library name to map
* @return The mapped library name.
*/
public String mapLibraryName(String libName) {
//
// A specific version was requested - use as is for search
//
if (libPattern.matcher(libName).find()) {
return libName;
}
return System.mapLibraryName(libName);
}
/**
* Searches through a list of directories for a native library.
*
* @param libName the base name (e.g. "c") of the library to locate
* @param libraryPath the list of directories to search
* @return the path of the library
*/
public String locateLibrary(String libName, List libraryPath) {
String mappedName = mapLibraryName(libName);
for (String path : libraryPath) {
File libFile = new File(path, mappedName);
if (libFile.exists()) {
return libFile.getAbsolutePath();
}
}
// Default to letting the system search for it
return mappedName;
}
private static class Supported extends Platform {
public Supported(OS os) {
super(os);
}
}
private static class Unsupported extends Platform {
public Unsupported(OS os) {
super(os);
}
}
private static final class Default extends Supported {
public Default(OS os) {
super(os);
}
}
/**
* A {@link Platform} subclass representing the MacOS system.
*/
private static final class Darwin extends Supported {
public Darwin() {
super(OS.DARWIN);
}
@Override
public String mapLibraryName(String libName) {
//
// A specific version was requested - use as is for search
//
if (libPattern.matcher(libName).find()) {
return libName;
}
return "lib" + libName + ".dylib";
}
@Override
public String getName() {
return "Darwin";
}
}
/**
* A {@link Platform} subclass representing the Linux operating system.
*/
private static final class Linux extends Supported {
public Linux() {
super(OS.LINUX);
}
@Override
public String locateLibrary(final String libName, List libraryPath) {
FilenameFilter filter = new FilenameFilter() {
Pattern p = Pattern.compile("lib" + libName + "\\.so\\.[0-9]+$");
String exact = "lib" + libName + ".so";
public boolean accept(File dir, String name) {
return p.matcher(name).matches() || exact.equals(name);
}
};
List matches = new LinkedList();
for (String path : libraryPath) {
File[] files = new File(path).listFiles(filter);
if (files != null && files.length > 0) {
matches.addAll(Arrays.asList(files));
}
}
//
// Search through the results and return the highest numbered version
// i.e. libc.so.6 is preferred over libc.so.5
//
int version = 0;
String bestMatch = null;
for (File file : matches) {
String path = file.getAbsolutePath();
if (bestMatch == null && path.endsWith(".so")) {
bestMatch = path;
version = 0;
} else {
String num = path.substring(path.lastIndexOf(".so.") + 4);
try {
if (Integer.parseInt(num) >= version) {
bestMatch = path;
}
} catch (NumberFormatException e) {
} // Just skip if not a number
}
}
return bestMatch != null ? bestMatch : mapLibraryName(libName);
}
@Override
public String mapLibraryName(String libName) {
// Older JDK on linux map 'c' to 'libc.so' which doesn't work
return "c".equals(libName) || "libc.so".equals(libName)
? "libc.so.6" : super.mapLibraryName(libName);
}
}
/**
* A {@link Platform} subclass representing the Windows system.
*/
private static class Windows extends Supported {
public Windows() {
super(OS.WINDOWS);
}
}
}
jaffl-0.5.9/src/com/kenai/jaffl/Pointer.java 0000664 0000000 0000000 00000003561 12017475436 0020626 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl;
public interface Pointer {
public static final int SIZE = Platform.getPlatform().addressSize();
abstract public byte getByte(long offset);
abstract public short getShort(long offset);
abstract public int getInt(long offset);
abstract public long getLong(long offset);
abstract public float getFloat(long offset);
abstract public double getDouble(long offset);
abstract public void putByte(long offset, byte value);
abstract public void putShort(long offset, short value);
abstract public void putInt(long offset, int value);
abstract public void putLong(long offset, long value);
abstract public void putFloat(long offset, float value);
abstract public void putDouble(long offset, double value);
abstract public void get(long offset, byte[] dst, int off, int len);
abstract public void put(long offset, byte[] dst, int off, int len);
abstract public void get(long offset, short[] dst, int off, int len);
abstract public void put(long offset, short[] dst, int off, int len);
abstract public void get(long offset, int[] dst, int off, int len);
abstract public void put(long offset, int[] dst, int off, int len);
abstract public void get(long offset, long[] dst, int off, int len);
abstract public void put(long offset, long[] dst, int off, int len);
abstract public void get(long offset, float[] dst, int off, int len);
abstract public void put(long offset, float[] dst, int off, int len);
abstract public void get(long offset, double[] dst, int off, int len);
abstract public void put(long offset, double[] dst, int off, int len);
abstract public Pointer getPointer(long offset);
abstract public void putPointer(long offset, Pointer value);
abstract public String getString(long offset);
abstract public long address();
abstract public boolean isDirect();
}
jaffl-0.5.9/src/com/kenai/jaffl/Type.java 0000664 0000000 0000000 00000002755 12017475436 0020133 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl;
import com.kenai.jaffl.provider.NativeType;
public interface Type {
/**
* The size in bytes of this type.
*
* @return An integer
*/
int size();
/**
* The native alignment of this type, in bytes
*
* @return An integer
*/
int alignment();
public static final Type SCHAR = FFIProvider.getProvider().getType(NativeType.SCHAR);
public static final Type UCHAR = FFIProvider.getProvider().getType(NativeType.UCHAR);
public static final Type SSHORT = FFIProvider.getProvider().getType(NativeType.SSHORT);
public static final Type USHORT = FFIProvider.getProvider().getType(NativeType.USHORT);
public static final Type SINT = FFIProvider.getProvider().getType(NativeType.SINT);
public static final Type UINT = FFIProvider.getProvider().getType(NativeType.UINT);
public static final Type SLONG = FFIProvider.getProvider().getType(NativeType.SLONG);
public static final Type ULONG = FFIProvider.getProvider().getType(NativeType.ULONG);
public static final Type SLONGLONG = FFIProvider.getProvider().getType(NativeType.SLONGLONG);
public static final Type ULONGLONG = FFIProvider.getProvider().getType(NativeType.ULONGLONG);
public static final Type FLOAT = FFIProvider.getProvider().getType(NativeType.FLOAT);
public static final Type DOUBLE = FFIProvider.getProvider().getType(NativeType.DOUBLE);
public static final Type ADDRESS = FFIProvider.getProvider().getType(NativeType.ADDRESS);
}
jaffl-0.5.9/src/com/kenai/jaffl/annotations/ 0000775 0000000 0000000 00000000000 12017475436 0020673 5 ustar 00root root 0000000 0000000 jaffl-0.5.9/src/com/kenai/jaffl/annotations/Clear.java 0000664 0000000 0000000 00000000675 12017475436 0022574 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Indicates that the temporary native memory allocated for an @Out paramneter
* should be cleared before passing to the native function.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface Clear {
}
jaffl-0.5.9/src/com/kenai/jaffl/annotations/Direct.java 0000664 0000000 0000000 00000000755 12017475436 0022757 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Indicates that the parameter requires native memory.
*
* This means it can be backed by allocated native memory, that is freed only
* after the Struct instance goes out of scope.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface Direct {
}
jaffl-0.5.9/src/com/kenai/jaffl/annotations/IgnoreError.java 0000664 0000000 0000000 00000000511 12017475436 0023770 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.annotations;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Tags a library method as not needing any error codes as returned
* by errno on unix, or GetLastError on windows be saved.
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface IgnoreError {
}
jaffl-0.5.9/src/com/kenai/jaffl/annotations/In.java 0000664 0000000 0000000 00000001236 12017475436 0022106 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Indicates that the parameter is an IN parameter.
*
* If a parameter is tagged only as In, and a temporary native memory
* area needs to be allocated before passing the data to native memory, then
* the java data is copied from java memory to native memory, but it is not
* copied back to java from the native memory area after the call.
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface In {
}
jaffl-0.5.9/src/com/kenai/jaffl/annotations/NulTerminate.java 0000664 0000000 0000000 00000000604 12017475436 0024145 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Indicates that a byte array or ByteBuffer should be passed as a C string
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface NulTerminate {
}
jaffl-0.5.9/src/com/kenai/jaffl/annotations/Out.java 0000664 0000000 0000000 00000001240 12017475436 0022302 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Indicates that the parameter is an OUT parameter.
*
*
* If a parameter is tagged only as Out, and a temporary native memory
* area needs to be allocated before passing the data to native memory, then
* the java data is not copied to native memory before the call, but is copied
* back to java from the native memory area after the call.
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface Out {
}
jaffl-0.5.9/src/com/kenai/jaffl/annotations/Pinned.java 0000664 0000000 0000000 00000001260 12017475436 0022752 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Marks a method parameter as being pinnable.
*
* This means the data for the parameter is not copied to/from native memory.
* Instead, the JVM memory is locked and passed directly to the native code.
*
*
* IMPORTANT: This should not be used for functions that may block on
* network or filesystem access such as read(2), write(2), stat(2), etc.
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface Pinned {
}
jaffl-0.5.9/src/com/kenai/jaffl/annotations/SaveError.java 0000664 0000000 0000000 00000000505 12017475436 0023446 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.annotations;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Tags a library method as requiring any error codes as returned
* by errno on unix, or GetLastError on windows be saved.
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface SaveError {
}
jaffl-0.5.9/src/com/kenai/jaffl/annotations/StdCall.java 0000664 0000000 0000000 00000000450 12017475436 0023063 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface StdCall {
}
jaffl-0.5.9/src/com/kenai/jaffl/annotations/Synchronized.java 0000664 0000000 0000000 00000000624 12017475436 0024217 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.annotations;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Indicates that a library or a library method requires all calls to be
* synchronized.
*
* i.e. calls from multiple threads will synchronize on a monitor object,
* then call the native method.
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface Synchronized {
}
jaffl-0.5.9/src/com/kenai/jaffl/annotations/Transient.java 0000664 0000000 0000000 00000000773 12017475436 0023514 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Indicates that the parameter is transient.
*
* This means it can be backed by a temporarily allocated native memory block,
* and after the method call, the native memory can be freed again.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface Transient {
}
jaffl-0.5.9/src/com/kenai/jaffl/byref/ 0000775 0000000 0000000 00000000000 12017475436 0017445 5 ustar 00root root 0000000 0000000 jaffl-0.5.9/src/com/kenai/jaffl/byref/AbstractPrimitiveReference.java 0000664 0000000 0000000 00000001323 12017475436 0025562 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.byref;
/**
* An abstract class for common PrimitiveReference functionality
*/
abstract public class AbstractPrimitiveReference implements ByReference {
protected T value;
public AbstractPrimitiveReference(T value) {
if (value == null) {
throw new NullPointerException("Reference value cannot be null");
}
this.value = value;
}
public Class nativeType() {
return value.getClass();
}
public void setValue(T value) {
if (value == null) {
throw new NullPointerException("Reference value cannot be null");
}
this.value = value;
}
public T getValue() {
return value;
}
}
jaffl-0.5.9/src/com/kenai/jaffl/byref/AddressByReference.java 0000664 0000000 0000000 00000002062 12017475436 0024007 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.byref;
import com.kenai.jaffl.Address;
import com.kenai.jaffl.util.BufferUtil;
import java.nio.ByteBuffer;
/**
*
*/
public class AddressByReference extends AbstractPrimitiveReference {
/**
* Creates a new reference to an address value
*
* @param value the initial native value
*/
public AddressByReference(Address value) {
super(value);
}
/**
* Copies the address value to native memory
*
* @param buffer the native memory buffer
*/
public void marshal(ByteBuffer buffer) {
BufferUtil.putAddress(buffer, 0, value.nativeAddress());
}
/**
* Copies the address value from native memory
*
* @param buffer the native memory buffer.
*/
public void unmarshal(ByteBuffer buffer) {
value = new Address(BufferUtil.getAddress(buffer, 0));
}
/**
* Gets the native size of type of reference
*
* @return Integer.SIZE
*/
public int nativeSize() {
return Address.SIZE / 8;
}
}
jaffl-0.5.9/src/com/kenai/jaffl/byref/ByReference.java 0000664 0000000 0000000 00000001136 12017475436 0022502 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.byref;
import java.nio.ByteBuffer;
public interface ByReference {
/**
* Gets the size of the native buffer required to store the value
*
* @return the size in bytes of the native type
*/
int nativeSize();
/**
* Copies the java value to native memory
*
* @param buffer the native memory buffer.
*/
void marshal(ByteBuffer buffer);
/**
* Copies the java value from native memory
*
* @param buffer the native memory buffer.
*/
void unmarshal(ByteBuffer buffer);
T getValue();
}
jaffl-0.5.9/src/com/kenai/jaffl/byref/ByteByReference.java 0000664 0000000 0000000 00000001662 12017475436 0023332 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.byref;
import java.nio.ByteBuffer;
/**
*
*/
public class ByteByReference extends AbstractPrimitiveReference {
/**
* Creates a new reference to a byte value
*
* @param value the initial native value
*/
public ByteByReference(Byte value) {
super(value);
}
/**
* Copies the Byte value to native memory
*
* @param buffer the native memory buffer
*/
public void marshal(ByteBuffer buffer) {
buffer.put(0, value);
}
/**
* Copies the Byte value from native memory
*
* @param buffer the native memory buffer.
*/
public void unmarshal(ByteBuffer buffer) {
value = buffer.get(0);
}
/**
* Gets the native size of type of reference in bytes.
*
* @return the size of a byte in bytes
*/
public final int nativeSize() {
return Byte.SIZE / 8;
}
}
jaffl-0.5.9/src/com/kenai/jaffl/byref/DoubleByReference.java 0000664 0000000 0000000 00000001716 12017475436 0023641 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.byref;
import java.nio.ByteBuffer;
/**
*
*/
public class DoubleByReference extends AbstractPrimitiveReference {
/**
* Creates a new reference to a double value
*
* @param value the initial native value
*/
public DoubleByReference(Double value) {
super(value);
}
/**
* Copies the double value to native memory
*
* @param buffer the native memory buffer
*/
public void marshal(ByteBuffer buffer) {
buffer.putDouble(0, value);
}
/**
* Copies the double value from native memory
*
* @param buffer the native memory buffer.
*/
public void unmarshal(ByteBuffer buffer) {
value = buffer.getDouble(0);
}
/**
* Gets the native size of type of reference in bytes.
*
* @return the size of a byte in bytes
*/
public final int nativeSize() {
return Double.SIZE / 8;
}
}
jaffl-0.5.9/src/com/kenai/jaffl/byref/FloatByReference.java 0000664 0000000 0000000 00000001704 12017475436 0023471 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.byref;
import java.nio.ByteBuffer;
/**
*
*/
public class FloatByReference extends AbstractPrimitiveReference {
/**
* Creates a new reference to a float value
*
* @param value the initial native value
*/
public FloatByReference(Float value) {
super(value);
}
/**
* Copies the float value to native memory
*
* @param buffer the native memory buffer
*/
public void marshal(ByteBuffer buffer) {
buffer.putFloat(0, value);
}
/**
* Copies the float value from native memory
*
* @param buffer the native memory buffer.
*/
public void unmarshal(ByteBuffer buffer) {
value = buffer.getFloat(0);
}
/**
* Gets the native size of type of reference in bytes.
*
* @return the size of a byte in bytes
*/
public final int nativeSize() {
return Float.SIZE / 8;
}
}
jaffl-0.5.9/src/com/kenai/jaffl/byref/IntByReference.java 0000664 0000000 0000000 00000002247 12017475436 0023161 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.byref;
import java.nio.ByteBuffer;
/**
* A class to pass a reference (or address of) an Integer to a method.
*/
public final class IntByReference extends AbstractPrimitiveReference {
/**
* Creates a new reference to a integer value
*
* @param value the initial native value
*/
public IntByReference(Integer value) {
super(value);
}
/**
* Copies the integer value to native memory
*
* @param buffer the native memory buffer
*/
public void marshal(ByteBuffer buffer) {
buffer.putInt(0, value);
}
/**
* Copies the integer value from native memory
*
* @param buffer the native memory buffer.
*/
public void unmarshal(ByteBuffer buffer) {
value = buffer.getInt(0);
}
/**
* Gets the native size of type of reference
*
* @return Integer.SIZE
*/
public int nativeSize() {
return Integer.SIZE / 8;
}
/**
* Gets the native type of the reference
*
* @return Integer.class
*/
@Override
public Class nativeType() {
return Integer.class;
}
}
jaffl-0.5.9/src/com/kenai/jaffl/byref/LongLongByReference.java 0000664 0000000 0000000 00000001715 12017475436 0024145 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.byref;
import java.nio.ByteBuffer;
/**
*
*/
public class LongLongByReference extends AbstractPrimitiveReference {
/**
* Creates a new reference to a native longlong value
*
* @param value the initial native value
*/
public LongLongByReference(Long value) {
super(value);
}
/**
* Copies the Byte value to native memory
*
* @param buffer the native memory buffer
*/
public void marshal(ByteBuffer buffer) {
buffer.putLong(0, value);
}
/**
* Copies the Byte value from native memory
*
* @param buffer the native memory buffer.
*/
public void unmarshal(ByteBuffer buffer) {
value = buffer.getLong(0);
}
/**
* Gets the native size of type of reference in bytes.
*
* @return the size of a byte in bytes
*/
public final int nativeSize() {
return Long.SIZE / 8;
}
}
jaffl-0.5.9/src/com/kenai/jaffl/byref/ShortByReference.java 0000664 0000000 0000000 00000001704 12017475436 0023523 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.byref;
import java.nio.ByteBuffer;
/**
*
*/
public class ShortByReference extends AbstractPrimitiveReference {
/**
* Creates a new reference to a short value
*
* @param value the initial native value
*/
public ShortByReference(Short value) {
super(value);
}
/**
* Copies the short value to native memory
*
* @param buffer the native memory buffer
*/
public void marshal(ByteBuffer buffer) {
buffer.putShort(0, value);
}
/**
* Copies the short value from native memory
*
* @param buffer the native memory buffer.
*/
public void unmarshal(ByteBuffer buffer) {
value = buffer.getShort(0);
}
/**
* Gets the native size of type of reference in bytes.
*
* @return the size of a byte in bytes
*/
public final int nativeSize() {
return Short.SIZE / 8;
}
}
jaffl-0.5.9/src/com/kenai/jaffl/mapper/ 0000775 0000000 0000000 00000000000 12017475436 0017622 5 ustar 00root root 0000000 0000000 jaffl-0.5.9/src/com/kenai/jaffl/mapper/FromNativeContext.java 0000664 0000000 0000000 00000000250 12017475436 0024101 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.mapper;
/**
* Context for a native->java type conversion.
*/
public interface FromNativeContext {
// Nothing here, just a placeholder
}
jaffl-0.5.9/src/com/kenai/jaffl/mapper/FromNativeConverter.java 0000664 0000000 0000000 00000000361 12017475436 0024427 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.mapper;
/**
* Converts data from a native type to a java type
*/
public interface FromNativeConverter {
public J fromNative(N nativeValue, FromNativeContext context);
public Class nativeType();
}
jaffl-0.5.9/src/com/kenai/jaffl/mapper/FunctionMapper.java 0000664 0000000 0000000 00000000364 12017475436 0023422 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.mapper;
import com.kenai.jaffl.Library;
public interface FunctionMapper {
static interface Context {
Library getLibrary();
}
public String mapFunctionName(String functionName, Context context);
}
jaffl-0.5.9/src/com/kenai/jaffl/mapper/MethodParameterContext.java 0000664 0000000 0000000 00000001336 12017475436 0025116 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.mapper;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
/**
* Holds context for a method parameter java->native conversion.
*/
public final class MethodParameterContext implements ToNativeContext {
private final Method method;
private final int parameterIndex;
private final Annotation[] annotations;
public MethodParameterContext(Method method, int parameterIndex) {
this.method = method;
this.parameterIndex = parameterIndex;
this.annotations = method.getParameterAnnotations()[parameterIndex];
}
public Method getMethod() {
return method;
}
public int getParameterIndex() {
return parameterIndex;
}
}
jaffl-0.5.9/src/com/kenai/jaffl/mapper/MethodResultContext.java 0000664 0000000 0000000 00000000503 12017475436 0024447 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.mapper;
import java.lang.reflect.Method;
/**
*
*/
public class MethodResultContext implements FromNativeContext {
private final Method method;
public MethodResultContext(Method method) {
this.method = method;
}
public Method getMethod() {
return method;
}
}
jaffl-0.5.9/src/com/kenai/jaffl/mapper/ToNativeContext.java 0000664 0000000 0000000 00000000110 12017475436 0023553 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.mapper;
public interface ToNativeContext {
}
jaffl-0.5.9/src/com/kenai/jaffl/mapper/ToNativeConverter.java 0000664 0000000 0000000 00000000252 12017475436 0024105 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.mapper;
public interface ToNativeConverter {
public N toNative(J value, ToNativeContext context);
public Class nativeType();
}
jaffl-0.5.9/src/com/kenai/jaffl/mapper/TypeMapper.java 0000664 0000000 0000000 00000000304 12017475436 0022550 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.mapper;
public interface TypeMapper {
public FromNativeConverter getFromNativeConverter(Class type);
public ToNativeConverter getToNativeConverter(Class type);
}
jaffl-0.5.9/src/com/kenai/jaffl/provider/ 0000775 0000000 0000000 00000000000 12017475436 0020170 5 ustar 00root root 0000000 0000000 jaffl-0.5.9/src/com/kenai/jaffl/provider/AbstractArrayMemoryIO.java 0000664 0000000 0000000 00000034700 12017475436 0025222 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.provider;
import com.kenai.jaffl.Platform;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.Charset;
import java.util.Arrays;
public abstract class AbstractArrayMemoryIO extends AbstractMemoryIO {
protected static final ArrayIO IO = getArrayIO();
protected static final int LONG_SIZE = Platform.getPlatform().longSize();
protected final byte[] buffer;
protected final int offset, length;
public AbstractArrayMemoryIO(byte[] buffer, int offset, int length) {
this.buffer = buffer;
this.offset = offset;
this.length = length;
}
public AbstractArrayMemoryIO(byte[] buffer) {
this(buffer, 0, buffer.length);
}
public AbstractArrayMemoryIO(int size) {
this(new byte[size], 0, size);
}
public final byte[] array() {
return buffer;
}
public final int offset() {
return offset;
}
public final int length() {
return length;
}
@Override
public final boolean isDirect() {
return false;
}
@Override
public long address() {
throw new UnsupportedOperationException("Not a direct memory object");
}
private static final ArrayIO getArrayIO() {
if (ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN)) {
return Platform.getPlatform().addressSize() == 64
? newBE64ArrayIO() : newBE32ArrayIO();
} else {
return Platform.getPlatform().addressSize() == 64
? newLE64ArrayIO() : newLE32ArrayIO();
}
}
private static final ArrayIO newBE64ArrayIO() {
return new BE64ArrayIO();
}
private static final ArrayIO newBE32ArrayIO() {
return new BE32ArrayIO();
}
private static final ArrayIO newLE64ArrayIO() {
return new LE64ArrayIO();
}
private static final ArrayIO newLE32ArrayIO() {
return new LE32ArrayIO();
}
protected final int index(long off) {
return this.offset + (int) off;
}
public final boolean isNull() {
return false;
}
@Override
public String getString(long offset) {
ByteBuffer tmp = ByteBuffer.wrap(buffer, index(offset), length - (int) offset);
return StringIO.getStringIO().fromNative(tmp, length - (int) offset).toString();
}
@Override
public String getString(long offset, int maxLength, Charset cs) {
ByteBuffer tmp = ByteBuffer.wrap(buffer, index(offset), length - (int) offset);
return StringIO.getStringIO().fromNative(tmp, Math.min(maxLength, length - (int) offset)).toString();
}
@Override
public void putString(long offset, String string, int maxLength, Charset cs) {
StringIO.getStringIO().toNative(string,
ByteBuffer.wrap(buffer, index(offset), Math.min(maxLength, length - (int) offset)));
}
public final byte getByte(long offset) {
return (byte) (buffer[index(offset)] & 0xff);
}
public final short getShort(long offset) {
return IO.getInt16(buffer, index(offset));
}
public final int getInt(long offset) {
return IO.getInt32(buffer, index(offset));
}
public final long getLong(long offset) {
return IO.getInt64(buffer, index(offset));
}
@Override
public final long getAddress(long offset) {
return IO.getAddress(buffer, index(offset));
}
public final float getFloat(long offset) {
return IO.getFloat32(buffer, index(offset));
}
public final double getDouble(long offset) {
return IO.getFloat64(buffer, index(offset));
}
public final void putByte(long offset, byte value) {
buffer[index(offset)] = value;
}
public final void putShort(long offset, short value) {
IO.putInt16(buffer, index(offset), value);
}
public final void putInt(long offset, int value) {
IO.putInt32(buffer, index(offset), value);
}
public final void putLong(long offset, long value) {
IO.putInt64(buffer, index(offset), value);
}
@Override
public final void putAddress(long offset, long value) {
IO.putAddress(buffer, index(offset), value);
}
public final void putFloat(long offset, float value) {
IO.putFloat32(buffer, index(offset), value);
}
public final void putDouble(long offset, double value) {
IO.putFloat64(buffer, index(offset), value);
}
public final void get(long offset, byte[] dst, int off, int len) {
System.arraycopy(buffer, index(offset), dst, off, len);
}
public final void put(long offset, byte[] src, int off, int len) {
System.arraycopy(src, off, buffer, index(offset), len);
}
public final void get(long offset, short[] dst, int off, int len) {
int begin = index(offset);
for (int i = 0; i < len; ++i) {
dst[off + i] = IO.getInt16(buffer, begin + (i << 1));
}
}
public final void put(long offset, short[] src, int off, int len) {
int begin = index(offset);
for (int i = 0; i < len; ++i) {
IO.putInt16(buffer, begin + (i << 1), src[off + i]);
}
}
public final void get(long offset, int[] dst, int off, int len) {
int begin = index(offset);
for (int i = 0; i < len; ++i) {
dst[off + i] = IO.getInt32(buffer, begin + (i << 2));
}
}
public final void put(long offset, int[] src, int off, int len) {
int begin = index(offset);
for (int i = 0; i < len; ++i) {
IO.putInt32(buffer, begin + (i << 2), src[off + i]);
}
}
public final void get(long offset, long[] dst, int off, int len) {
int begin = index(offset);
for (int i = 0; i < len; ++i) {
dst[off + i] = IO.getInt64(buffer, begin + (i << 3));
}
}
public final void put(long offset, long[] src, int off, int len) {
int begin = index(offset);
for (int i = 0; i < len; ++i) {
IO.putInt64(buffer, begin + (i << 3), src[off + i]);
}
}
public final void get(long offset, float[] dst, int off, int len) {
int begin = index(offset);
for (int i = 0; i < len; ++i) {
dst[off + i] = IO.getFloat32(buffer, begin + (i << 2));
}
}
public final void put(long offset, float[] src, int off, int len) {
int begin = index(offset);
for (int i = 0; i < len; ++i) {
IO.putFloat32(buffer, begin + (i << 2), src[off + i]);
}
}
public final void get(long offset, double[] dst, int off, int len) {
int begin = index(offset);
for (int i = 0; i < len; ++i) {
dst[off + i] = IO.getFloat64(buffer, begin + (i << 3));
}
}
public final void put(long offset, double[] src, int off, int len) {
int begin = index(offset);
for (int i = 0; i < len; ++i) {
IO.putFloat64(buffer, begin + (i << 3), src[off + i]);
}
}
@Override
public final int indexOf(long offset, byte value) {
int off = index(offset);
for (int i = 0; i < length; ++i) {
if (buffer[off + i] == value) {
return i;
}
}
return -1;
}
public final int indexOf(long offset, byte value, int maxlen) {
int off = index(offset);
for (int i = 0; i < Math.min(length, maxlen); ++i) {
if (buffer[off + i] == value) {
return i;
}
}
return -1;
}
public final void setMemory(long offset, long size, byte value) {
Arrays.fill(buffer, index(offset), (int) size, value);
}
public final void clear() {
Arrays.fill(buffer, offset, length, (byte) 0);
}
protected static abstract class ArrayIO {
public abstract short getInt16(byte[] buffer, int offset);
public abstract int getInt32(byte[] buffer, int offset);
public abstract long getInt64(byte[] buffer, int offset);
public abstract long getAddress(byte[] buffer, int offset);
public abstract void putInt16(byte[] buffer, int offset, int value);
public abstract void putInt32(byte[] buffer, int offset, int value);
public abstract void putInt64(byte[] buffer, int offset, long value);
public abstract void putAddress(byte[] buffer, int offset, long value);
public final float getFloat32(byte[] buffer, int offset) {
return Float.intBitsToFloat(getInt32(buffer, offset));
}
public final void putFloat32(byte[] buffer, int offset, float value) {
putInt32(buffer, offset, Float.floatToRawIntBits(value));
}
public final double getFloat64(byte[] buffer, int offset) {
return Double.longBitsToDouble(getInt64(buffer, offset));
}
public final void putFloat64(byte[] buffer, int offset, double value) {
putInt64(buffer, offset, Double.doubleToRawLongBits(value));
}
}
private static abstract class LittleEndianArrayIO extends ArrayIO {
public final short getInt16(byte[] array, int offset) {
return (short) ((array[offset] & 0xff) | ((array[offset + 1] & 0xff) << 8));
}
public final int getInt32(byte[] array, int offset) {
return ((array[offset + 0] & 0xff) << 0)
| ((array[offset + 1] & 0xff) << 8)
| ((array[offset + 2] & 0xff) << 16)
| ((array[offset + 3] & 0xff) << 24);
}
public final long getInt64(byte[] array, int offset) {
return (((long)array[offset + 0] & 0xff) << 0)
| (((long)array[offset + 1] & 0xff) << 8)
| (((long)array[offset + 2] & 0xff) << 16)
| (((long)array[offset + 3] & 0xff) << 24)
| (((long)array[offset + 4] & 0xff) << 32)
| (((long)array[offset + 5] & 0xff) << 40)
| (((long)array[offset + 6] & 0xff) << 48)
| (((long)array[offset + 7] & 0xff) << 56);
}
public final void putInt16(byte[] buffer, int offset, int value) {
buffer[offset + 0] = (byte) (value >> 0);
buffer[offset + 1] = (byte) (value >> 8);
}
public final void putInt32(byte[] buffer, int offset, int value) {
buffer[offset + 0] = (byte) (value >> 0);
buffer[offset + 1] = (byte) (value >> 8);
buffer[offset + 2] = (byte) (value >> 16);
buffer[offset + 3] = (byte) (value >> 24);
}
public final void putInt64(byte[] buffer, int offset, long value) {
buffer[offset + 0] = (byte) (value >> 0);
buffer[offset + 1] = (byte) (value >> 8);
buffer[offset + 2] = (byte) (value >> 16);
buffer[offset + 3] = (byte) (value >> 24);
buffer[offset + 4] = (byte) (value >> 32);
buffer[offset + 5] = (byte) (value >> 40);
buffer[offset + 6] = (byte) (value >> 48);
buffer[offset + 7] = (byte) (value >> 56);
}
}
private static abstract class BigEndianArrayIO extends ArrayIO {
public short getInt16(byte[] array, int offset) {
return (short) (((array[offset + 0] & 0xff) << 8)
| (array[offset + 1] & 0xff));
}
public int getInt32(byte[] array, int offset) {
return ((array[offset + 0] & 0xff) << 24)
| ((array[offset + 1] & 0xff) << 16)
| ((array[offset + 2] & 0xff) << 8)
| ((array[offset + 3] & 0xff) << 0);
}
public long getInt64(byte[] array, int offset) {
return (((long)array[offset + 0] & 0xff) << 56)
| (((long)array[offset + 1] & 0xff) << 48)
| (((long)array[offset + 2] & 0xff) << 40)
| (((long)array[offset + 3] & 0xff) << 32)
| (((long)array[offset + 4] & 0xff) << 24)
| (((long)array[offset + 5] & 0xff) << 16)
| (((long)array[offset + 6] & 0xff) << 8)
| (((long)array[offset + 7] & 0xff) << 0);
}
public final void putInt16(byte[] buffer, int offset, int value) {
buffer[offset + 0] = (byte) (value >> 8);
buffer[offset + 1] = (byte) (value >> 0);
}
public final void putInt32(byte[] buffer, int offset, int value) {
buffer[offset + 0] = (byte) (value >> 24);
buffer[offset + 1] = (byte) (value >> 16);
buffer[offset + 2] = (byte) (value >> 8);
buffer[offset + 3] = (byte) (value >> 0);
}
public final void putInt64(byte[] buffer, int offset, long value) {
buffer[offset + 0] = (byte) (value >> 56);
buffer[offset + 1] = (byte) (value >> 48);
buffer[offset + 2] = (byte) (value >> 40);
buffer[offset + 3] = (byte) (value >> 32);
buffer[offset + 4] = (byte) (value >> 24);
buffer[offset + 5] = (byte) (value >> 16);
buffer[offset + 6] = (byte) (value >> 8);
buffer[offset + 7] = (byte) (value >> 0);
}
}
private static final class LE32ArrayIO extends LittleEndianArrayIO {
public final long getAddress(byte[] buffer, int offset) {
return ((long) getInt32(buffer, offset)) & 0xffffffffL;
}
public final void putAddress(byte[] buffer, int offset, long value) {
putInt32(buffer, offset, (int) value);
}
}
private static final class LE64ArrayIO extends LittleEndianArrayIO {
public final long getAddress(byte[] buffer, int offset) {
return getInt64(buffer, offset);
}
public final void putAddress(byte[] buffer, int offset, long value) {
putInt64(buffer, offset, value);
}
}
private static final class BE32ArrayIO extends BigEndianArrayIO {
public final long getAddress(byte[] buffer, int offset) {
return ((long) getInt32(buffer, offset)) & 0xffffffffL;
}
public final void putAddress(byte[] buffer, int offset, long value) {
putInt32(buffer, offset, (int) value);
}
}
private static final class BE64ArrayIO extends BigEndianArrayIO {
public final long getAddress(byte[] buffer, int offset) {
return getInt64(buffer, offset);
}
public final void putAddress(byte[] buffer, int offset, long value) {
putInt64(buffer, offset, value);
}
}
}
jaffl-0.5.9/src/com/kenai/jaffl/provider/AbstractBufferMemoryIO.java 0000664 0000000 0000000 00000012411 12017475436 0025350 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.provider;
import com.kenai.jaffl.util.BufferUtil;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
/**
*
*/
abstract public class AbstractBufferMemoryIO extends AbstractMemoryIO {
protected final ByteBuffer buffer;
public AbstractBufferMemoryIO(ByteBuffer buffer) {
this.buffer = buffer;
}
public final boolean isDirect() {
return buffer.isDirect();
}
@Override
public long address() {
throw new UnsupportedOperationException("Not a direct memory object.");
}
public final ByteBuffer getByteBuffer() {
return buffer;
}
public byte getByte(long offset) {
return buffer.get((int) offset);
}
public short getShort(long offset) {
return buffer.getShort((int) offset);
}
public int getInt(long offset) {
return buffer.getInt((int) offset);
}
public long getLong(long offset) {
return buffer.getLong((int) offset);
}
public float getFloat(long offset) {
return buffer.getFloat((int) offset);
}
public double getDouble(long offset) {
return buffer.getDouble((int) offset);
}
public void putByte(long offset, byte value) {
buffer.put((int) offset, value);
}
public void putShort(long offset, short value) {
buffer.putShort((int) offset, value);
}
public void putInt(long offset, int value) {
buffer.putInt((int) offset, value);
}
public void putLong(long offset, long value) {
buffer.putLong((int) offset, value);
}
public void putFloat(long offset, float value) {
buffer.putFloat((int) offset, value);
}
public void putDouble(long offset, double value) {
buffer.putDouble((int) offset, value);
}
public String getString(long offset, int size) {
return BufferUtil.getString(BufferUtil.slice(buffer, (int) offset), Charset.defaultCharset());
}
public void putString(long offset, String string) {
BufferUtil.putString(BufferUtil.slice(buffer, (int) offset), Charset.defaultCharset(), string);
}
@Override
public void get(long offset, byte[] dst, int off, int len) {
BufferUtil.slice(buffer, (int) offset, len).get(dst, off, len);
}
@Override
public void get(long offset, short[] dst, int off, int len) {
BufferUtil.slice(buffer, (int) offset, len * Short.SIZE / 8).asShortBuffer().get(dst, off, len);
}
@Override
public void get(long offset, int[] dst, int off, int len) {
BufferUtil.slice(buffer, (int) offset, len * Integer.SIZE / 8).asIntBuffer().get(dst, off, len);
}
@Override
public void get(long offset, long[] dst, int off, int len) {
BufferUtil.slice(buffer, (int) offset, len * Long.SIZE / 8).asLongBuffer().get(dst, off, len);
}
@Override
public void get(long offset, float[] dst, int off, int len) {
BufferUtil.slice(buffer, (int) offset, len * Float.SIZE / 8).asFloatBuffer().get(dst, off, len);
}
@Override
public void get(long offset, double[] dst, int off, int len) {
BufferUtil.slice(buffer, (int) offset, len * Double.SIZE / 8).asDoubleBuffer().get(dst, off, len);
}
@Override
public void put(long offset, byte[] dst, int off, int len) {
BufferUtil.slice(buffer, (int) offset, len).put(dst, off, len);
}
@Override
public void put(long offset, short[] dst, int off, int len) {
BufferUtil.slice(buffer, (int) offset, len * Short.SIZE / 8).asShortBuffer().put(dst, off, len);
}
@Override
public void put(long offset, int[] dst, int off, int len) {
BufferUtil.slice(buffer, (int) offset, len * Integer.SIZE / 8).asIntBuffer().put(dst, off, len);
}
@Override
public void put(long offset, long[] dst, int off, int len) {
BufferUtil.slice(buffer, (int) offset, len * Long.SIZE / 8).asLongBuffer().put(dst, off, len);
}
@Override
public void put(long offset, float[] dst, int off, int len) {
BufferUtil.slice(buffer, (int) offset, len * Float.SIZE / 8).asFloatBuffer().put(dst, off, len);
}
@Override
public void put(long offset, double[] dst, int off, int len) {
BufferUtil.slice(buffer, (int) offset, len * Double.SIZE / 8).asDoubleBuffer().put(dst, off, len);
}
@Override
public String getString(long offset) {
return BufferUtil.getString(BufferUtil.slice(buffer, (int) offset), Charset.defaultCharset());
}
@Override
public String getString(long offset, int maxLength, Charset cs) {
return BufferUtil.getString(BufferUtil.slice(buffer, (int) offset, maxLength),
cs);
}
@Override
public void putString(long offset, String string, int maxLength, Charset cs) {
BufferUtil.putString(BufferUtil.slice(buffer, (int) offset, maxLength), cs, string);
}
@Override
public int indexOf(long offset, byte value, int maxlen) {
for (; offset > -1; ++offset) {
if (buffer.get((int) offset) == value) {
return (int) offset;
}
}
return -1;
}
@Override
public void setMemory(long offset, long size, byte value) {
for (int i = 0; i < size; ++i) {
buffer.put((int) offset + i, value);
}
}
}
jaffl-0.5.9/src/com/kenai/jaffl/provider/AbstractMemoryIO.java 0000664 0000000 0000000 00000010040 12017475436 0024212 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.provider;
import com.kenai.jaffl.*;
/**
* Base implementations of some MemoryIO operations.
*/
abstract public class AbstractMemoryIO extends MemoryIO {
protected static final void checkBounds(long size, long off, long len) {
if ((off | len | (off + len) | (size - (off + len))) < 0) {
throw new IndexOutOfBoundsException();
}
}
public int indexOf(long offset, byte value) {
return indexOf(offset, value, Integer.MAX_VALUE);
}
public long getAddress(long offset) {
return AddressIO.INSTANCE.getAddress(this, offset);
}
public void putAddress(long offset, long value) {
AddressIO.INSTANCE.putAddress(this, offset, value);
}
public void putAddress(long offset, Address value) {
AddressIO.INSTANCE.putAddress(this, offset, value.longValue());
}
public final long getNativeLong(long offset) {
return NativeLongIO.INSTANCE.getLong(this, offset);
}
public MemoryIO slice(long offset) {
return new ShareMemoryIO(this, offset);
}
public MemoryIO slice(long offset, long size) {
return new BoundedMemoryIO(this, offset, size);
}
public void putNativeLong(long offset, long value) {
NativeLongIO.INSTANCE.putLong(this, offset, value);
}
public void transferTo(long offset, MemoryIO other, long otherOffset, long count) {
for (long i = 0; i < count; ++i) {
other.putByte(otherOffset + i, getByte(offset + i));
}
}
public void transferFrom(long offset, MemoryIO other, long otherOffset, long count) {
for (long i = 0; i < count; ++i) {
putByte(offset + i, other.getByte(otherOffset + i));
}
}
//
// Optimize reading/writing pointers.
//
private static interface AddressIO {
public long getAddress(MemoryIO io, long offset);
public void putAddress(MemoryIO io, long offset, long address);
public static class AddressIO32 implements AddressIO {
public static final AddressIO _INSTANCE = new AddressIO32();
public long getAddress(MemoryIO io, long offset) {
return io.getInt(offset);
}
public void putAddress(MemoryIO io, long offset, long address) {
io.putInt(offset, (int) address);
}
}
public static class AddressIO64 implements AddressIO {
public static final AddressIO _INSTANCE = new AddressIO64();
public long getAddress(MemoryIO io, long offset) {
return io.getLong(offset);
}
public void putAddress(MemoryIO io, long offset, long address) {
io.putLong(offset, address);
}
}
public static final AddressIO INSTANCE = Platform.getPlatform().addressSize() == 32
? AddressIO32._INSTANCE : AddressIO64._INSTANCE;
}
//
// Optimize reading/writing native long values.
//
private static interface NativeLongIO {
public long getLong(MemoryIO io, long offset);
public void putLong(MemoryIO io, long offset, long value);
public static class LongIO32 implements NativeLongIO {
public static final NativeLongIO _INSTANCE = new LongIO32();
public long getLong(MemoryIO io, long offset) {
return io.getInt(offset);
}
public void putLong(MemoryIO io, long offset, long value) {
io.putInt(offset, (int) value);
}
}
public static class LongIO64 implements NativeLongIO {
public static final NativeLongIO _INSTANCE = new LongIO64();
public long getLong(MemoryIO io, long offset) {
return io.getLong(offset);
}
public void putLong(MemoryIO io, long offset, long value) {
io.putLong(offset, value);
}
}
public static final NativeLongIO INSTANCE = Platform.getPlatform().longSize() == 32
? LongIO32._INSTANCE : LongIO64._INSTANCE;
}
}
jaffl-0.5.9/src/com/kenai/jaffl/provider/BoundedMemoryIO.java 0000664 0000000 0000000 00000015466 12017475436 0024050 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.provider;
import com.kenai.jaffl.Address;
import com.kenai.jaffl.MemoryIO;
import com.kenai.jaffl.Pointer;
import java.nio.charset.Charset;
public class BoundedMemoryIO extends AbstractMemoryIO implements DelegatingMemoryIO {
private final long base, size;
private final MemoryIO io;
public BoundedMemoryIO(MemoryIO parent, long offset, long size) {
this.io = parent;
this.base = offset;
this.size = size;
}
public boolean isDirect() {
return getDelegatedMemoryIO().isDirect();
}
public long address() {
return getDelegatedMemoryIO().address();
}
public MemoryIO getDelegatedMemoryIO() {
return io;
}
@Override
public byte getByte(long offset) {
checkBounds(size, offset, 1);
return io.getByte(base + offset);
}
@Override
public short getShort(long offset) {
checkBounds(size, offset, 2);
return io.getShort(base + offset);
}
@Override
public int getInt(long offset) {
checkBounds(size, offset, 4);
return io.getInt(base + offset);
}
@Override
public long getLong(long offset) {
checkBounds(size, offset, 8);
return io.getLong(base + offset);
}
@Override
public float getFloat(long offset) {
checkBounds(size, offset, 4);
return io.getFloat(base + offset);
}
@Override
public double getDouble(long offset) {
checkBounds(size, offset, 8);
return io.getDouble(base + offset);
}
public Pointer getPointer(long offset) {
checkBounds(size, offset, Address.SIZE / 8);
return io.getPointer(base + offset);
}
public MemoryIO getMemoryIO(long offset) {
checkBounds(this.size, base + offset, Address.SIZE / 8);
return io.getMemoryIO(base + offset);
}
public MemoryIO getMemoryIO(long offset, long size) {
checkBounds(this.size, base + offset, Address.SIZE / 8);
return io.getMemoryIO(base + offset, size);
}
@Override
public void putByte(long offset, byte value) {
checkBounds(size, offset, 1);
io.putByte(base + offset, value);
}
@Override
public void putShort(long offset, short value) {
checkBounds(size, offset, 2);
io.putShort(base + offset, value);
}
@Override
public void putInt(long offset, int value) {
checkBounds(size, offset, 4);
io.putInt(base + offset, value);
}
@Override
public void putLong(long offset, long value) {
checkBounds(size, offset, 8);
io.putLong(base + offset, value);
}
@Override
public void putFloat(long offset, float value) {
checkBounds(size, offset, 4);
io.putFloat(base + offset, value);
}
@Override
public void putDouble(long offset, double value) {
checkBounds(size, offset, 8);
io.putDouble(base + offset, value);
}
public void putPointer(long offset, Pointer value) {
checkBounds(size, offset, Address.SIZE / 8);
io.putPointer(base + offset, value);
}
@Override
public void get(long offset, byte[] dst, int off, int len) {
checkBounds(size, offset, len);
io.get(base + offset, dst, off, len);
}
@Override
public void put(long offset, byte[] dst, int off, int len) {
checkBounds(size, offset, len);
io.put(base + offset, dst, off, len);
}
@Override
public void get(long offset, short[] dst, int off, int len) {
checkBounds(size, offset, len * Short.SIZE / 8);
io.get(base + offset, dst, off, len);
}
@Override
public void put(long offset, short[] dst, int off, int len) {
checkBounds(size, offset, len * Short.SIZE / 8);
io.put(base + offset, dst, off, len);
}
@Override
public void get(long offset, int[] dst, int off, int len) {
checkBounds(size, offset, len * Integer.SIZE / 8);
io.get(base + offset, dst, off, len);
}
@Override
public void put(long offset, int[] dst, int off, int len) {
checkBounds(size, offset, len * Integer.SIZE / 8);
io.put(base + offset, dst, off, len);
}
@Override
public void get(long offset, long[] dst, int off, int len) {
checkBounds(size, offset, len * Long.SIZE / 8);
io.get(base + offset, dst, off, len);
}
@Override
public void put(long offset, long[] dst, int off, int len) {
checkBounds(size, offset, len * Long.SIZE / 8);
io.put(base + offset, dst, off, len);
}
@Override
public void get(long offset, float[] dst, int off, int len) {
checkBounds(size, offset, len * Float.SIZE / 8);
io.get(base + offset, dst, off, len);
}
@Override
public void put(long offset, float[] dst, int off, int len) {
checkBounds(size, offset, len * Float.SIZE / 8);
io.put(base + offset, dst, off, len);
}
@Override
public void get(long offset, double[] dst, int off, int len) {
checkBounds(size, offset, len * Double.SIZE / 8);
io.get(base + offset, dst, off, len);
}
@Override
public void put(long offset, double[] dst, int off, int len) {
checkBounds(size, offset, len * Double.SIZE / 8);
io.put(base + offset, dst, off, len);
}
@Override
public long getAddress(long offset) {
checkBounds(size, offset, Address.SIZE >> 3);
return io.getAddress(base + offset);
}
@Override
public String getString(long offset, int maxLength, Charset cs) {
checkBounds(size, offset, maxLength);
return io.getString(base + offset, maxLength, cs);
}
@Override
public String getString(long offset) {
return io.getString(base + offset, (int) size, Charset.defaultCharset());
}
@Override
public void putAddress(long offset, long value) {
checkBounds(size, offset, Address.SIZE >> 3);
io.putAddress(base + offset, value);
}
@Override
public void putAddress(long offset, Address value) {
checkBounds(size, offset, Address.SIZE >> 3);
io.putAddress(base + offset, value);
}
@Override
public void putString(long offset, String string, int maxLength, Charset cs) {
checkBounds(size, offset, maxLength);
io.putString(base + offset, string, maxLength, cs);
}
@Override
public int indexOf(long offset, byte value) {
return io.indexOf(base + offset, value, (int) size);
}
@Override
public int indexOf(long offset, byte value, int maxlen) {
checkBounds(size, offset, maxlen);
return io.indexOf(base + offset, value, maxlen);
}
@Override
public void setMemory(long offset, long size, byte value) {
checkBounds(this.size, base + offset, size);
io.setMemory(base + offset, size, value);
}
}
jaffl-0.5.9/src/com/kenai/jaffl/provider/DelegatingMemoryIO.java 0000664 0000000 0000000 00000000232 12017475436 0024514 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.provider;
import com.kenai.jaffl.MemoryIO;
public interface DelegatingMemoryIO {
public MemoryIO getDelegatedMemoryIO();
}
jaffl-0.5.9/src/com/kenai/jaffl/provider/InvocationSession.java 0000664 0000000 0000000 00000001172 12017475436 0024511 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.provider;
import java.util.ArrayList;
/**
* Holds information for each invocation of a native function
*/
public class InvocationSession {
private ArrayList list;
public InvocationSession() {
}
public static interface PostInvoke {
void postInvoke();
}
public void finish() {
if (list != null) for (PostInvoke p : list) {
p.postInvoke();
}
}
public void addPostInvoke(PostInvoke postInvoke) {
if (list == null) {
list = new ArrayList();
}
list.add(postInvoke);
}
}
jaffl-0.5.9/src/com/kenai/jaffl/provider/Invoker.java 0000664 0000000 0000000 00000000231 12017475436 0022444 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.provider;
/**
* Interface for any invocable function
*/
public interface Invoker {
Object invoke(Object[] parameters);
}
jaffl-0.5.9/src/com/kenai/jaffl/provider/Library.java 0000664 0000000 0000000 00000003512 12017475436 0022440 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.provider;
import com.kenai.jaffl.LibraryOption;
import com.kenai.jaffl.Platform;
import java.io.File;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
/**
*
*/
public abstract class Library {
private static final class StaticDataHolder {
private static final List userLibraryPath = new CopyOnWriteArrayList();
static {
userLibraryPath.addAll(getPropertyPaths("jaffl.library.path"));
// Add JNA paths for compatibility
userLibraryPath.addAll(getPropertyPaths("jna.library.path"));
}
};
public abstract Invoker getInvoker(Method method, Map options);
public abstract Object libraryLock();
public static String locateLibrary(String libraryName) {
if (new File(libraryName).isAbsolute()) {
return libraryName;
}
List searchPath = new LinkedList();
//
// Prepend any custom search paths specifically for this library
//
searchPath.addAll(0, com.kenai.jaffl.Library.getLibraryPath(libraryName));
searchPath.addAll(StaticDataHolder.userLibraryPath);
String path = Platform.getPlatform().locateLibrary(libraryName, searchPath);
return path != null ? path : null;
}
private static final List getPropertyPaths(String propName) {
String value = System.getProperty(propName);
if (value != null) {
String[] paths = value.split(File.pathSeparator);
return new ArrayList(Arrays.asList(paths));
}
return Collections.emptyList();
}
}
jaffl-0.5.9/src/com/kenai/jaffl/provider/MemoryManager.java 0000664 0000000 0000000 00000001226 12017475436 0023577 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.provider;
import com.kenai.jaffl.MemoryIO;
import com.kenai.jaffl.Pointer;
import java.nio.Buffer;
import java.nio.ByteBuffer;
/**
* Manages access to various types of java and native memory.
*/
public interface MemoryManager {
public abstract MemoryIO allocate(int size);
public abstract MemoryIO allocateDirect(int size);
public abstract MemoryIO allocateDirect(int size, boolean clear);
public abstract MemoryIO wrap(Pointer address);
public abstract MemoryIO wrap(Pointer address, int size);
public abstract MemoryIO wrap(ByteBuffer buffer);
public abstract Pointer getBufferPointer(Buffer buffer);
}
jaffl-0.5.9/src/com/kenai/jaffl/provider/NativeInvocationHandler.java 0000664 0000000 0000000 00000024767 12017475436 0025631 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.provider;
import com.kenai.jaffl.CallingConvention;
import com.kenai.jaffl.LibraryOption;
import com.kenai.jaffl.Platform;
import com.kenai.jaffl.annotations.StdCall;
import com.kenai.jaffl.annotations.Synchronized;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;
/**
* InvocationHandler used to map invocations on a java interface to the
* correct native function.
*/
public class NativeInvocationHandler implements InvocationHandler {
private final InvokerMap invokers;
private final Library library;
private final Map optionsMap;
private final Class> interfaceClass;
/**
* Creates a new InvocationHandler instance.
*
* @param library the native library to call
* @param interfaceClass the interface that defines the methods in the
* native library that will be accessed via this handler.
* @param optionsMap a dictionary of options to apply to this library.
*/
public NativeInvocationHandler(Library library, Class> interfaceClass,
Map optionsMap) {
this.library = library;
this.interfaceClass = interfaceClass;
this.optionsMap = new HashMap(optionsMap);
if (interfaceClass.getAnnotation(StdCall.class) != null) {
this.optionsMap.put(LibraryOption.CallingConvention, CallingConvention.STDCALL);
}
invokers = new InvokerMap(interfaceClass.getDeclaredMethods().length);
}
/**
* Creates a new InvocationHandler mapping methods in the interfaceClass
* to functions in the native library.
* @param the type of interfaceClass
* @param libraryName the native library to load
* @param interfaceClass the interface that contains the native method description
* @param optionsMap a dictionary of options to apply to this library.
* @return a new instance of interfaceClass that can be used to call
* functions in the native library.
*/
public static T wrapInterface(Library library, Class interfaceClass,
Map optionsMap) {
return interfaceClass.cast(Proxy.newProxyInstance(interfaceClass.getClassLoader(),
new Class[]{ interfaceClass },
new NativeInvocationHandler(library, interfaceClass, optionsMap)));
}
/**
* Gets the {@link Invoker} for a method.
*
* @param method the method defined in the interface class
* @return the Invoker to use to invoke the native function
*/
private Invoker getInvoker(Method method) {
Invoker invoker = invokers.get(method);
if (invoker != null) {
return invoker;
}
return createInvoker(method);
}
/**
* Creates a new Invoker to invoke method in the native library
* @param method the method to invoke
* @return a new Invoker
*/
private synchronized Invoker createInvoker(Method method) {
//
// Recheck in case another thread already created the same mapping
//
Invoker invoker = invokers.get(method);
if (invoker != null) {
return invoker;
}
invoker = library.getInvoker(method, optionsMap);
//
// If either the method or the library is specified as requiring
// synchronization, then wrap the raw invoker in a synchronized proxy
//
if (method.getAnnotation(Synchronized.class) != null
|| interfaceClass.getAnnotation(Synchronized.class) != null) {
//
// Synchronize on the library, so multiple different interface
// definitions for the same library synchronize on the same object.
//
invoker = new SynchronizedInvoker(invoker, library.libraryLock());
}
invokers.put(method, invoker);
return invoker;
}
public Object invoke(Object self, Method method, Object[] argArray) throws Throwable {
return getInvoker(method).invoke(argArray);
}
private static final class SynchronizedInvoker implements Invoker {
private final Object lock;
private final Invoker invoker;
public SynchronizedInvoker(Invoker invoker, Object lock) {
this.invoker = invoker;
this.lock = lock;
}
public Object invoke(Object[] parameters) {
synchronized (lock) {
return invoker.invoke(parameters);
}
}
}
/**
* A custom map-like class for fast mapping between a Method and
* an Invoker.
*
* This is not a standard Map - it does not support removing or
* replacing of elements, just gets and insertions.
*
*
* It is optimized for many-reads, minimal writes.
*
*/
private static final class InvokerMap {
//
// According to the new JMM:
// In effect, because the new memory model places stricter constraints
// on reordering of volatile field accesses with other field accesses,
// volatile or not, anything that was visible to thread A when it writes
// to volatile field f becomes visible to thread B when it reads f.
//
// Ergo, by doing copy-on-write of the entire array to a temp variable,
// then inserting into the temp array, and assigning that temp array
// to 'entries' after all writes are done, will ensure that everything
// is fully visible to readers.
//
private volatile Object[] entries;
private static final float loadFactor = 0.5f;
/**
* Creates a new Method->Invoker map
*
* @param maxEntries the maximum size of the map. No more entries than
* this can be added.
*/
public InvokerMap(final int maxEntries) {
final int capacity = (int) ((float) maxEntries / loadFactor) + 1;
int size = 1;
// Make the table power-of-2 sized so indexFor() is faster
while (size < capacity) {
size <<= 1;
}
entries = new Object[size * 2]; // write volatile
}
/**
* Creates a new mapping between a Method and an Invoker
*
* @param method the Method to create the mapping for
* @param invoker the Invoker to associate with the method.
*/
public final synchronized void put(Method method, Invoker invoker) {
Object[] tmp = new Object[entries.length];
System.arraycopy(entries, 0, tmp, 0, tmp.length);
int start = indexFor(method, tmp.length);
Loop: for (int loop = 0; loop < 2; ++loop) {
for (int i = start; i < tmp.length - 1; i += 2) {
if (tmp[i] == null) {
tmp[i] = method;
tmp[i + 1] = invoker;
break Loop;
}
}
start = 0; // wrap around
}
entries = tmp; // write volatile
}
/**
* Gets an Invoker from the map for method
*
* @param method the method to get an Invoker for
* @return an Invoker if the method is in the table, else null
*/
public final Invoker get(Method method) {
Object[] tmp = entries; // read volatile
int start = indexFor(method, tmp.length);
Loop: for (int loop = 0; loop < 2; ++loop) {
for (int i = start; i < tmp.length - 1; i += 2) {
if (tmp[i] == method) {
return (Invoker) tmp[i + 1];
}
if (tmp[i] == null) {
break Loop;
}
}
start = 0; // wrap around
}
return null;
}
/**
* Abstracts different hashing methods, depending on the underlying jvm
*/
private static interface Hasher {
public int hash(Method key);
}
/**
* Uses System.identityHashCode() to generate a hash for the method.
*
* This is fastest on JDK6+ where System.identityHashCode() is an intrinsic
* and is inlined.
*
*/
private static final class IdentityHasherSingleton {
private static final class IdentityHasher implements Hasher {
public final int hash(Method key) {
final int h = System.identityHashCode(key);
return (h << 1) - (h << 8);
}
}
public static final Hasher getInstance() { return new IdentityHasher(); }
}
/**
* Uses Method#hashCode to generate a hash for the method.
*
* This is faster than using System.identityHashCode() on JDK5, since
* System.identityHashCode() is not inlined.
*
*/
private static final class NameHasherSingleton {
private static final class NameHasher implements Hasher {
public final int hash(Method key) {
int h = key.hashCode();
h += (h << 15) ^ 0xffffcd7d;
h ^= (h >>> 10);
h += (h << 3);
h ^= (h >>> 6);
h += (h << 2) + (h << 14);
return h ^ (h >>> 16);
}
}
public static final Hasher getInstance() { return new NameHasher(); }
}
//
// On JVM6 and above, System.identityHashCode is inlined so very fast
//
private static final Hasher hasher = Platform.getPlatform().getJavaMajorVersion() >= 6
? IdentityHasherSingleton.getInstance() : NameHasherSingleton.getInstance();
/**
* Gets the index in the hash table of the method.
*
* @param key the method to locate
* @param length the length of the entries array
* @return
*/
private static final int indexFor(Method key, int length) {
return hasher.hash(key) & (length - 1);
}
}
} jaffl-0.5.9/src/com/kenai/jaffl/provider/NativeType.java 0000664 0000000 0000000 00000000343 12017475436 0023123 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.provider;
public enum NativeType {
VOID,
SCHAR,
UCHAR,
SSHORT,
USHORT,
SINT,
UINT,
SLONG,
ULONG,
SLONGLONG,
ULONGLONG,
FLOAT,
DOUBLE,
ADDRESS;
}
jaffl-0.5.9/src/com/kenai/jaffl/provider/NullMemoryIO.java 0000664 0000000 0000000 00000007017 12017475436 0023373 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.provider;
import com.kenai.jaffl.MemoryIO;
import com.kenai.jaffl.Pointer;
import java.nio.charset.Charset;
public final class NullMemoryIO extends AbstractMemoryIO {
private static final String msg = "Attempted access to a NULL memory address";
public static final MemoryIO INSTANCE = new NullMemoryIO();
private static final NullPointerException npe() {
return new NullPointerException(msg);
}
public final byte getByte(long offset) {
throw npe();
}
public final short getShort(long offset) {
throw npe();
}
public final int getInt(long offset) {
throw npe();
}
public final long getLong(long offset) {
throw npe();
}
public final float getFloat(long offset) {
throw npe();
}
public final double getDouble(long offset) {
throw npe();
}
public final void putByte(long offset, byte value) {
throw npe();
}
public final void putShort(long offset, short value) {
throw npe();
}
public final void putInt(long offset, int value) {
throw npe();
}
public final void putLong(long offset, long value) {
throw npe();
}
public final void putFloat(long offset, float value) {
throw npe();
}
public final void putDouble(long offset, double value) {
throw npe();
}
public final void get(long offset, byte[] dst, int off, int len) {
throw npe();
}
public final void put(long offset, byte[] dst, int off, int len) {
throw npe();
}
public final void get(long offset, short[] dst, int off, int len) {
throw npe();
}
public final void put(long offset, short[] dst, int off, int len) {
throw npe();
}
public final void get(long offset, int[] dst, int off, int len) {
throw npe();
}
public final void put(long offset, int[] dst, int off, int len) {
throw npe();
}
public final void get(long offset, long[] dst, int off, int len) {
throw npe();
}
public final void put(long offset, long[] dst, int off, int len) {
throw npe();
}
public final void get(long offset, float[] dst, int off, int len) {
throw npe();
}
public final void put(long offset, float[] dst, int off, int len) {
throw npe();
}
public final void get(long offset, double[] dst, int off, int len) {
throw npe();
}
public final void put(long offset, double[] dst, int off, int len) {
throw npe();
}
public final MemoryIO getMemoryIO(long offset) {
throw npe();
}
public final MemoryIO getMemoryIO(long offset, long size) {
throw npe();
}
public final Pointer getPointer(long offset) {
throw npe();
}
public final void putPointer(long offset, Pointer value) {
throw npe();
}
public String getString(long offset) {
throw npe();
}
@Override
public String getString(long offset, int maxLength, Charset cs) {
throw npe();
}
@Override
public void putString(long offset, String string, int maxLength, Charset cs) {
throw npe();
}
public final int indexOf(long offset, byte value, int maxlen) {
throw npe();
}
public final boolean isDirect() {
return true;
}
@Override
public long address() {
return 0;
}
@Override
public final void setMemory(long offset, long size, byte value) {
throw npe();
}
}
jaffl-0.5.9/src/com/kenai/jaffl/provider/ShareMemoryIO.java 0000664 0000000 0000000 00000011102 12017475436 0023511 0 ustar 00root root 0000000 0000000 package com.kenai.jaffl.provider;
import com.kenai.jaffl.MemoryIO;
import com.kenai.jaffl.Pointer;
import java.nio.charset.Charset;
/**
*
*/
public class ShareMemoryIO extends AbstractMemoryIO implements DelegatingMemoryIO {
private final MemoryIO io;
private final long base;
public ShareMemoryIO(MemoryIO parent, long offset) {
this.io = parent;
this.base = offset;
}
public final boolean isDirect() {
return io.isDirect();
}
@Override
public long address() {
return io.address() + base;
}
public final MemoryIO getDelegatedMemoryIO() {
return io;
}
@Override
public byte getByte(long offset) {
return io.getByte(base + offset);
}
@Override
public short getShort(long offset) {
return io.getShort(base + offset);
}
@Override
public int getInt(long offset) {
return io.getInt(base + offset);
}
@Override
public long getLong(long offset) {
return io.getLong(base + offset);
}
@Override
public float getFloat(long offset) {
return io.getFloat(base + offset);
}
@Override
public double getDouble(long offset) {
return io.getDouble(base + offset);
}
public MemoryIO getMemoryIO(long offset) {
return io.getMemoryIO(base + offset);
}
public MemoryIO getMemoryIO(long offset, long size) {
return io.getMemoryIO(base + offset, size);
}
public Pointer getPointer(long offset) {
return io.getPointer(base + offset);
}
@Override
public String getString(long offset) {
return io.getString(base + offset);
}
@Override
public String getString(long offset, int maxLength, Charset cs) {
return io.getString(base + offset, maxLength, cs);
}
@Override
public void putByte(long offset, byte value) {
io.putByte(base + offset, value);
}
@Override
public void putShort(long offset, short value) {
io.putShort(base + offset, value);
}
@Override
public void putInt(long offset, int value) {
io.putInt(base + offset, value);
}
@Override
public void putLong(long offset, long value) {
io.putLong(base + offset, value);
}
@Override
public void putFloat(long offset, float value) {
io.putFloat(base + offset, value);
}
@Override
public void putDouble(long offset, double value) {
io.putDouble(base + offset, value);
}
public void putPointer(long offset, Pointer value) {
io.putPointer(base + offset, value);
}
@Override
public void putString(long offset, String string, int maxLength, Charset cs) {
io.putString(base + offset, string, maxLength, cs);
}
@Override
public void get(long offset, byte[] dst, int off, int len) {
io.get(base + offset, dst, off, len);
}
@Override
public void put(long offset, byte[] dst, int off, int len) {
io.put(base + offset, dst, off, len);
}
@Override
public void get(long offset, short[] dst, int off, int len) {
io.get(base + offset, dst, off, len);
}
@Override
public void put(long offset, short[] dst, int off, int len) {
io.put(base + offset, dst, off, len);
}
@Override
public void get(long offset, int[] dst, int off, int len) {
io.get(base + offset, dst, off, len);
}
@Override
public void put(long offset, int[] dst, int off, int len) {
io.put(base + offset, dst, off, len);
}
@Override
public void get(long offset, long[] dst, int off, int len) {
io.get(base + offset, dst, off, len);
}
@Override
public void put(long offset, long[] dst, int off, int len) {
io.put(base + offset, dst, off, len);
}
@Override
public void get(long offset, float[] dst, int off, int len) {
io.get(base + offset, dst, off, len);
}
@Override
public void put(long offset, float[] dst, int off, int len) {
io.put(base + offset, dst, off, len);
}
@Override
public void get(long offset, double[] dst, int off, int len) {
io.get(base + offset, dst, off, len);
}
@Override
public void put(long offset, double[] dst, int off, int len) {
io.put(base + offset, dst, off, len);
}
@Override
public int indexOf(long offset, byte value, int maxlen) {
return io.indexOf(base + offset, value, maxlen);
}
@Override
public void setMemory(long offset, long size, byte value) {
io.setMemory(base + offset, size, value);
}
}
jaffl-0.5.9/src/com/kenai/jaffl/provider/StringIO.java 0000664 0000000 0000000 00000012265 12017475436 0022537 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.provider;
import com.kenai.jaffl.util.BufferUtil;
import java.lang.ref.SoftReference;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CodingErrorAction;
/**
*
*/
public final class StringIO {
private static final class StaticDataHolder {
static final StringIO INSTANCE = new StringIO(Charset.defaultCharset());
static final ThreadLocal> ENCODER = new ThreadLocal>();
static final ThreadLocal> DECODER = new ThreadLocal>();
}
private final Charset charset;
public static StringIO getStringIO() {
return StaticDataHolder.INSTANCE;
}
public static StringIO getStringIO(Charset charset) {
return new StringIO(charset);
}
private StringIO(Charset charset) {
this.charset = charset;
}
private static CharsetEncoder getEncoder(Charset charset) {
SoftReference ref = StaticDataHolder.ENCODER.get();
CharsetEncoder encoder;
if (ref != null && (encoder = ref.get()) != null && encoder.charset() == charset) {
return encoder;
}
return initEncoder(charset);
}
private static CharsetDecoder getDecoder(Charset charset) {
SoftReference ref = StaticDataHolder.DECODER.get();
CharsetDecoder decoder;
if (ref != null && (decoder = ref.get()) != null && decoder.charset() == charset) {
return decoder;
}
return initDecoder(charset);
}
private static CharsetEncoder initEncoder(Charset charset) {
CharsetEncoder encoder = charset.newEncoder();
encoder.onMalformedInput(CodingErrorAction.REPLACE).onUnmappableCharacter(CodingErrorAction.REPLACE);
StaticDataHolder.ENCODER.set(new SoftReference(encoder));
return encoder;
}
private static CharsetDecoder initDecoder(Charset charset) {
CharsetDecoder decoder = charset.newDecoder();
decoder.onMalformedInput(CodingErrorAction.REPLACE).onUnmappableCharacter(CodingErrorAction.REPLACE);
StaticDataHolder.DECODER.set(new SoftReference(decoder));
return decoder;
}
public final ByteBuffer toNative(final CharSequence value, final int minSize, boolean copyIn) {
return toNative(getEncoder(charset), value, minSize, copyIn);
}
public final ByteBuffer toNative(final CharSequence value, final ByteBuffer buf) {
return toNative(getEncoder(charset), value, buf);
}
private static ByteBuffer toNative(CharsetEncoder encoder, final CharSequence value, final int minSize, boolean copyIn) {
// Calculate the raw byte size required (with allowance for NUL termination)
final int len = (int) (((float)Math.max(minSize, value.length()) + 1) * encoder.maxBytesPerChar());
final ByteBuffer buf = ByteBuffer.allocate(len);
if (copyIn) {
toNative(encoder, value, buf);
}
return buf;
}
private static ByteBuffer toNative(CharsetEncoder encoder, final CharSequence value, final ByteBuffer buf) {
//
// Copy the string to native memory
//
buf.mark();
try {
encoder.reset();
encoder.encode(CharBuffer.wrap(value), buf, true);
encoder.flush(buf);
nulTerminate(encoder, buf);
} finally {
buf.reset();
}
return buf;
}
public final CharSequence fromNative(final ByteBuffer buf, final int maxSize) {
// Find the NUL terminator and limit to that, so the
// StringBuffer/StringBuilder does not have superfluous NUL chars
int end = BufferUtil.positionOf(buf, (byte) 0);
if (end < 0 || end > maxSize) {
end = maxSize;
}
final int limit = buf.limit();
buf.limit(end);
try {
return getDecoder(charset).reset().decode(buf);
} catch (CharacterCodingException ex) {
throw new Error("Illegal character data in native string", ex);
} finally {
buf.limit(limit);
}
}
public final CharSequence fromNative(final ByteBuffer buf) {
try {
return getDecoder(charset).reset().decode(buf);
} catch (CharacterCodingException ex) {
throw new Error("Illegal character data in native string", ex);
}
}
public final void nulTerminate(ByteBuffer buf) {
nulTerminate(getEncoder(charset), buf);
}
private static void nulTerminate(CharsetEncoder encoder, ByteBuffer buf) {
// NUL terminate the string
int nulSize = Math.round(encoder.maxBytesPerChar());
while (nulSize >= 4) {
buf.putInt(0);
nulSize -= 4;
}
if (nulSize >= 2) {
buf.putShort((short) 0);
nulSize -= 2;
}
if (nulSize >= 1) {
buf.put((byte) 0);
}
}
}
jaffl-0.5.9/src/com/kenai/jaffl/provider/jffi/ 0000775 0000000 0000000 00000000000 12017475436 0021106 5 ustar 00root root 0000000 0000000 jaffl-0.5.9/src/com/kenai/jaffl/provider/jffi/AbstractX86StubCompiler.java 0000664 0000000 0000000 00000007374 12017475436 0026366 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.provider.jffi;
import com.kenai.jffi.MemoryIO;
import com.kenai.jffi.NativeMethod;
import com.kenai.jffi.NativeMethods;
import com.kenai.jffi.PageManager;
import com.kenai.jnr.x86asm.Assembler;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Base class for most X86_32/X86_64 stub compilers
*/
abstract class AbstractX86StubCompiler extends StubCompiler {
private static final class StaticDataHolder {
// Keep a reference from the loaded class to the pages holding the code for that class.
static final Map PAGES
= Collections.synchronizedMap(new WeakHashMap());
}
final List stubs = new LinkedList();
final class Stub {
final String name;
final String signature;
final Assembler assembler;
public Stub(String name, String signature, Assembler assembler) {
this.name = name;
this.signature = signature;
this.assembler = assembler;
}
}
static final class PageHolder {
final PageManager pm;
final long memory;
final long pageCount;
public PageHolder(PageManager pm, long memory, long pageCount) {
this.pm = pm;
this.memory = memory;
this.pageCount = pageCount;
}
@Override
protected void finalize() throws Throwable {
try {
pm.freePages(memory, (int) pageCount);
} catch (Throwable t) {
Logger.getLogger(getClass().getName()).log(Level.WARNING,
"Exception when freeing native pages: %s", t.getLocalizedMessage());
} finally {
super.finalize();
}
}
}
@Override
void attach(Class clazz) {
if (stubs.isEmpty()) {
return;
}
long codeSize = 0;
for (Stub stub : stubs) {
// add 8 bytes for alignment
codeSize += stub.assembler.codeSize() + 8;
}
PageManager pm = PageManager.getInstance();
long npages = (codeSize + pm.pageSize() - 1) / pm.pageSize();
// Allocate some native memory for it
long code = pm.allocatePages((int) npages, PageManager.PROT_READ | PageManager.PROT_WRITE);
if (code == 0) {
throw new OutOfMemoryError("allocatePages failed for codeSize=" + codeSize);
}
PageHolder page = new PageHolder(pm, code, npages);
// Now relocate/copy all the assembler stubs into the real code area
List methods = new ArrayList(stubs.size());
long fn = code;
for (Stub stub : stubs) {
Assembler asm = stub.assembler;
// align the start of all functions on a 8 byte boundary
fn = align(fn, 8);
ByteBuffer buf = MemoryIO.getInstance().newDirectByteBuffer(fn, asm.codeSize()).order(ByteOrder.LITTLE_ENDIAN);
stub.assembler.relocCode(buf, fn);
methods.add(new NativeMethod(fn, stub.name, stub.signature));
fn += asm.codeSize();
}
pm.protectPages(code, (int) npages, PageManager.PROT_READ | PageManager.PROT_EXEC);
NativeMethods.register(clazz, methods);
StaticDataHolder.PAGES.put(clazz, page);
}
static final int align(int offset, int align) {
return align + ((offset - 1) & ~(align - 1));
}
static final long align(long offset, long align) {
return align + ((offset - 1) & ~(align - 1));
}
}
jaffl-0.5.9/src/com/kenai/jaffl/provider/jffi/AllocatedDirectMemoryIO.java 0000664 0000000 0000000 00000001206 12017475436 0026414 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.provider.jffi;
class AllocatedDirectMemoryIO extends DirectMemoryIO {
private volatile boolean allocated = true;
public AllocatedDirectMemoryIO(int size, boolean clear) {
super(IO.allocateMemory(size, clear));
if (address == 0L) {
throw new OutOfMemoryError("Failed to allocate " + size + " bytes");
}
}
@Override
protected void finalize() throws Throwable {
try {
if (allocated) {
IO.freeMemory(address);
allocated = false;
}
} finally {
super.finalize();
}
}
}
jaffl-0.5.9/src/com/kenai/jaffl/provider/jffi/ArrayMemoryIO.java 0000664 0000000 0000000 00000001455 12017475436 0024455 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.provider.jffi;
import com.kenai.jaffl.MemoryIO;
import com.kenai.jaffl.Pointer;
import com.kenai.jaffl.provider.AbstractArrayMemoryIO;
public final class ArrayMemoryIO extends AbstractArrayMemoryIO {
public ArrayMemoryIO(int size) {
super(size);
}
@Override
public MemoryIO getMemoryIO(long offset) {
return MemoryUtil.newMemoryIO(getAddress(offset));
}
@Override
public MemoryIO getMemoryIO(long offset, long size) {
return MemoryUtil.newMemoryIO(getAddress(offset), size);
}
@Override
public Pointer getPointer(long offset) {
return MemoryUtil.newPointer(getAddress(offset));
}
@Override
public void putPointer(long offset, Pointer value) {
putAddress(offset, value.address());
}
}
jaffl-0.5.9/src/com/kenai/jaffl/provider/jffi/AsmClassLoader.java 0000664 0000000 0000000 00000000600 12017475436 0024602 0 ustar 00root root 0000000 0000000 package com.kenai.jaffl.provider.jffi;
final class AsmClassLoader extends ClassLoader {
static final AsmClassLoader INSTANCE = new AsmClassLoader();
public AsmClassLoader() {
}
public AsmClassLoader(ClassLoader parent) {
super(parent);
}
public Class defineClass(String name, byte[] b) {
return defineClass(name, b, 0, b.length);
}
}
jaffl-0.5.9/src/com/kenai/jaffl/provider/jffi/AsmLibraryLoader.java 0000664 0000000 0000000 00000154327 12017475436 0025161 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.provider.jffi;
import com.kenai.jaffl.Address;
import com.kenai.jaffl.LibraryOption;
import com.kenai.jaffl.MemoryIO;
import com.kenai.jaffl.NativeLong;
import com.kenai.jaffl.ParameterFlags;
import com.kenai.jaffl.Pointer;
import com.kenai.jaffl.annotations.StdCall;
import com.kenai.jaffl.byref.ByReference;
import com.kenai.jaffl.mapper.FromNativeContext;
import com.kenai.jaffl.mapper.FromNativeConverter;
import com.kenai.jaffl.mapper.FunctionMapper;
import com.kenai.jaffl.mapper.MethodParameterContext;
import com.kenai.jaffl.mapper.MethodResultContext;
import com.kenai.jaffl.mapper.ToNativeContext;
import com.kenai.jaffl.mapper.ToNativeConverter;
import com.kenai.jaffl.mapper.TypeMapper;
import com.kenai.jaffl.provider.InvocationSession;
import com.kenai.jaffl.struct.Struct;
import com.kenai.jffi.ArrayFlags;
import com.kenai.jffi.CallingConvention;
import com.kenai.jffi.Function;
import com.kenai.jffi.HeapInvocationBuffer;
import com.kenai.jffi.InvocationBuffer;
import com.kenai.jffi.Platform;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.nio.Buffer;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Label;
import org.objectweb.asm.Opcodes;
import static com.kenai.jaffl.provider.jffi.CodegenUtils.*;
import static com.kenai.jaffl.provider.jffi.NumberUtil.*;
import static com.kenai.jaffl.provider.jffi.AsmUtil.*;
public class AsmLibraryLoader extends LibraryLoader implements Opcodes {
public final static boolean DEBUG = false || Boolean.getBoolean("jaffl.compile.dump");
private static final class SingletonHolder {
static final LibraryLoader INSTANCE = new AsmLibraryLoader();
}
private static final boolean FAST_NUMERIC_AVAILABLE = isFastNumericAvailable();
private static final boolean FAST_LONG_AVAILABLE = isFastLongAvailable();
private final AtomicLong nextClassID = new AtomicLong(0);
private final AtomicLong nextIvarID = new AtomicLong(0);
private final AtomicLong nextMethodID = new AtomicLong(0);
static final LibraryLoader getInstance() {
return SingletonHolder.INSTANCE;
}
boolean isInterfaceSupported(Class interfaceClass, Map options) {
TypeMapper typeMapper = options.containsKey(LibraryOption.TypeMapper)
? (TypeMapper) options.get(LibraryOption.TypeMapper) : NullTypeMapper.INSTANCE;
for (Method m : interfaceClass.getDeclaredMethods()) {
if (!isReturnTypeSupported(m.getReturnType()) && getResultConverter(m, typeMapper) == null) {
System.err.println("Unsupported return type: " + m.getReturnType());
return false;
}
for (Class c: m.getParameterTypes()) {
if (!isParameterTypeSupported(c) && typeMapper.getToNativeConverter(c) == null) {
System.err.println("Unsupported parameter type: " + c);
return false;
}
}
}
return true;
}
private boolean isReturnTypeSupported(Class type) {
return type.isPrimitive() || Byte.class == type
|| Short.class == type || Integer.class == type
|| Long.class == type || Float.class == type
|| Double.class == type || NativeLong.class == type
|| Pointer.class == type || Address.class == type
|| String.class == type
|| Struct.class.isAssignableFrom(type);
}
private boolean isParameterTypeSupported(Class type) {
return type.isPrimitive() || Byte.class == type
|| Short.class == type || Integer.class == type
|| Long.class == type || Float.class == type
|| Double.class == type || NativeLong.class == type
|| Pointer.class.isAssignableFrom(type) || Address.class.isAssignableFrom(type)
|| Enum.class.isAssignableFrom(type)
|| Buffer.class.isAssignableFrom(type)
|| (type.isArray() && type.getComponentType().isPrimitive())
|| Struct.class.isAssignableFrom(type)
|| (type.isArray() && Struct.class.isAssignableFrom(type.getComponentType()))
|| (type.isArray() && Pointer.class.isAssignableFrom(type.getComponentType()))
|| CharSequence.class.isAssignableFrom(type)
|| ByReference.class.isAssignableFrom(type)
|| StringBuilder.class.isAssignableFrom(type)
|| StringBuffer.class.isAssignableFrom(type);
}
@Override
T loadLibrary(Library library, Class interfaceClass, Map libraryOptions) {
return generateInterfaceImpl(library, interfaceClass, libraryOptions);
}
private final T generateInterfaceImpl(final Library library, Class interfaceClass, Map libraryOptions) {
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
ClassVisitor cv = DEBUG ? AsmUtil.newCheckClassAdapter(AsmUtil.newTraceClassVisitor(cw, System.err)) : cw;
String className = p(interfaceClass) + "$jaffl$" + nextClassID.getAndIncrement();
cv.visit(V1_5, ACC_PUBLIC | ACC_FINAL, className, null, p(AbstractNativeInterface.class),
new String[] { p(interfaceClass) });
// Create the constructor to set the 'library' & functions fields
SkinnyMethodAdapter init = new SkinnyMethodAdapter(cv.visitMethod(ACC_PUBLIC, "",
sig(void.class, Library.class, Function[].class, FromNativeConverter[].class, ToNativeConverter[][].class),
null, null));
init.start();
// Invokes the super class constructor as super(Library)
init.aload(0);
init.aload(1);
init.invokespecial(p(AbstractNativeInterface.class), "", sig(void.class, Library.class));
final Method[] methods = interfaceClass.getMethods();
Function[] functions = new Function[methods.length];
FromNativeConverter[] resultConverters = new FromNativeConverter[methods.length];
ToNativeConverter[][] parameterConverters = new ToNativeConverter[methods.length][0];
FunctionMapper functionMapper = libraryOptions.containsKey(LibraryOption.FunctionMapper)
? (FunctionMapper) libraryOptions.get(LibraryOption.FunctionMapper) : IdentityFunctionMapper.getInstance();
TypeMapper typeMapper = libraryOptions.containsKey(LibraryOption.TypeMapper)
? (TypeMapper) libraryOptions.get(LibraryOption.TypeMapper) : NullTypeMapper.INSTANCE;
com.kenai.jffi.CallingConvention libraryCallingConvention = getCallingConvention(interfaceClass, libraryOptions);
StubCompiler compiler = StubCompiler.newCompiler();
for (int i = 0; i < methods.length; ++i) {
Method m = methods[i];
final Class returnType = m.getReturnType();
final Class[] parameterTypes = m.getParameterTypes();
Class nativeReturnType = returnType;
Class[] nativeParameterTypes = new Class[parameterTypes.length];
boolean conversionRequired = false;
resultConverters[i] = getResultConverter(m, typeMapper);
if (resultConverters[i] != null) {
cv.visitField(ACC_PRIVATE | ACC_FINAL, getResultConverterFieldName(i), ci(FromNativeConverter.class), null, null);
nativeReturnType = resultConverters[i].nativeType();
conversionRequired = true;
}
parameterConverters[i] = new ToNativeConverter[parameterTypes.length];
for (int pidx = 0; pidx < parameterTypes.length; ++pidx) {
ToNativeConverter converter = typeMapper.getToNativeConverter(parameterTypes[pidx]);
if (converter != null) {
cv.visitField(ACC_PRIVATE | ACC_FINAL, getParameterConverterFieldName(i, pidx),
ci(ToNativeConverter.class), null, null);
nativeParameterTypes[pidx] = converter.nativeType();
parameterConverters[i][pidx] = new ToNativeProxy(converter,
new MethodParameterContext(m, pidx));
conversionRequired = true;
} else {
nativeParameterTypes[pidx] = parameterTypes[pidx];
}
}
// Stash the name of the function in a static field
String functionName = functionMapper.mapFunctionName(m.getName(), null);
cv.visitField(ACC_PRIVATE | ACC_FINAL | ACC_STATIC, "name_" + i, ci(String.class), null, functionName);
// Allow individual methods to set the calling convention to stdcall
CallingConvention callingConvention = m.getAnnotation(StdCall.class) != null
? CallingConvention.STDCALL : libraryCallingConvention;
try {
functions[i] = getFunction(library.findSymbolAddress(functionName),
nativeReturnType, nativeParameterTypes, InvokerUtil.requiresErrno(m),
callingConvention);
} catch (SymbolNotFoundError ex) {
cv.visitField(ACC_PRIVATE | ACC_FINAL | ACC_STATIC, "error_" + i, ci(String.class), null, ex.getMessage());
generateFunctionNotFound(cv, className, i, functionName, returnType, parameterTypes);
continue;
}
String functionFieldName = "function_" + i;
cv.visitField(ACC_PRIVATE | ACC_FINAL, functionFieldName, ci(Function.class), null, null);
final boolean ignoreErrno = !InvokerUtil.requiresErrno(m);
if (canCompile(compiler, nativeReturnType, nativeParameterTypes, callingConvention)) {
// The method can be generated via a direct java -> jni mapping
compile(compiler, functions[i], cv, className, m.getName() + (conversionRequired ? "$raw" : ""),
functionFieldName, nativeReturnType, nativeParameterTypes,
m.getParameterAnnotations(), callingConvention, ignoreErrno);
} else {
generateMethod(cv, className, m.getName() + (conversionRequired ? "$raw" : ""),
functionFieldName, nativeReturnType, nativeParameterTypes,
m.getParameterAnnotations(), callingConvention, ignoreErrno);
}
if (conversionRequired) {
generateConversionMethod(cv, className, m.getName(), i, returnType, parameterTypes, nativeReturnType, nativeParameterTypes);
}
// The Function[] array is passed in as the second param, so generate
// the constructor code to store each function in a field
init.aload(0);
init.aload(2);
init.pushInt(i);
init.aaload();
init.putfield(className, functionFieldName, ci(Function.class));
// If there is a result converter for this function, put it in a field too
if (resultConverters[i] != null) {
init.aload(0);
init.aload(3);
init.pushInt(i);
init.aaload();
init.putfield(className, getResultConverterFieldName(i), ci(FromNativeConverter.class));
}
for (int pidx = 0; pidx < parameterTypes.length; ++pidx) {
if (parameterConverters[i][pidx] != null) {
init.aload(0);
init.aload(4);
init.pushInt(i);
init.aaload();
init.pushInt(pidx);
init.aaload();
init.putfield(className, getParameterConverterFieldName(i, pidx), ci(ToNativeConverter.class));
}
}
}
init.voidreturn();
init.visitMaxs(10, 10);
init.visitEnd();
cv.visitEnd();
try {
Class implClass = new AsmClassLoader(interfaceClass.getClassLoader()).defineClass(className.replace("/", "."), cw.toByteArray());
Constructor cons = implClass.getDeclaredConstructor(Library.class, Function[].class, FromNativeConverter[].class, ToNativeConverter[][].class);
T result = cons.newInstance(library, functions, resultConverters, parameterConverters);
// Attach any native method stubs - we have to delay this until the
// implementation class is loaded for it to work.
compiler.attach(implClass);
return result;
} catch (Throwable ex) {
throw new RuntimeException(ex);
}
}
private final FromNativeConverter getResultConverter(Method m, TypeMapper typeMapper) {
Class returnType = m.getReturnType();
FromNativeConverter conv = typeMapper.getFromNativeConverter(returnType);
if (conv != null) {
return new FromNativeProxy(conv, new MethodResultContext(m));
} else if (Enum.class.isAssignableFrom(returnType)) {
return new EnumResultConverter(returnType);
} else {
return null;
}
}
private static final com.kenai.jffi.CallingConvention getCallingConvention(Class interfaceClass, Map options) {
if (interfaceClass.getAnnotation(StdCall.class) != null) {
return com.kenai.jffi.CallingConvention.STDCALL;
}
return InvokerUtil.getCallingConvention(options);
}
private final String getFunctionFieldName(int idx) {
return "function_" + idx;
}
private final String getResultConverterFieldName(int idx) {
return "resultConverter_" + idx;
}
private final String getParameterConverterFieldName(int idx, int paramIndex) {
return "parameterConverter_" + idx + "_" + paramIndex;
}
private final void generateFunctionNotFound(ClassVisitor cv, String className, int idx, String functionName,
Class returnType, Class[] parameterTypes) {
SkinnyMethodAdapter mv = new SkinnyMethodAdapter(cv.visitMethod(ACC_PUBLIC | ACC_FINAL, functionName,
sig(returnType, parameterTypes), null, null));
mv.start();
mv.getstatic(className, "error_" + idx, ci(String.class));
mv.invokestatic(AsmRuntime.class, "newUnsatisifiedLinkError", UnsatisfiedLinkError.class, String.class);
mv.athrow();
mv.visitMaxs(10, 10);
mv.visitEnd();
}
private final void generateConversionMethod(ClassVisitor cv, String className, String functionName, int idx,
Class returnType, Class[] parameterTypes, Class nativeReturnType, Class[] nativeParameterTypes) {
SkinnyMethodAdapter mv = new SkinnyMethodAdapter(cv.visitMethod(ACC_PUBLIC | ACC_FINAL, functionName,
sig(returnType, parameterTypes), null, null));
mv.start();
// If there is a result converter, retrieve it and put on the stack
if (!returnType.equals(nativeReturnType)) {
mv.aload(0);
mv.getfield(className, getResultConverterFieldName(idx), ci(FromNativeConverter.class));
}
mv.aload(0);
// Load and convert the parameters
int lvar = 1;
for (int pidx = 0; pidx < parameterTypes.length; ++pidx) {
final boolean convertParameter = !parameterTypes[pidx].equals(nativeParameterTypes[pidx]);
if (convertParameter) {
mv.aload(0);
mv.getfield(className, getParameterConverterFieldName(idx, pidx), ci(ToNativeConverter.class));
}
lvar = loadParameter(mv, parameterTypes[pidx], lvar);
if (convertParameter) {
if (parameterTypes[pidx].isPrimitive()) {
boxPrimitive(mv, parameterTypes[pidx]);
}
mv.aconst_null();
mv.invokeinterface(ToNativeConverter.class, "toNative",
Object.class, Object.class, ToNativeContext.class);
mv.checkcast(p(nativeParameterTypes[pidx]));
}
}
// Invoke the real native method
mv.invokevirtual(className, functionName + "$raw", sig(nativeReturnType, nativeParameterTypes));
if (!returnType.equals(nativeReturnType)) {
if (nativeReturnType.isPrimitive()) {
boxPrimitive(mv, nativeReturnType);
}
mv.aconst_null();
mv.invokeinterface(FromNativeConverter.class, "fromNative",
Object.class, Object.class, FromNativeContext.class);
mv.checkcast(p(returnType));
}
emitReturnOp(mv, returnType);
mv.visitMaxs(10, 10);
mv.visitEnd();
}
private final boolean canCompile(StubCompiler compiler, Class returnType, Class[] parameterTypes,
CallingConvention convention) {
Class[] nativeParameterTypes = new Class[parameterTypes.length];
for (int i = 0; i < nativeParameterTypes.length; ++i) {
nativeParameterTypes[i] = AsmUtil.unboxedType(parameterTypes[i]);
}
return compiler.canCompile(AsmUtil.unboxedReturnType(returnType), nativeParameterTypes, convention);
}
private final void compile(StubCompiler compiler, Function function,
ClassVisitor cv, String className, String functionName, String functionFieldName,
Class returnType, Class[] parameterTypes, Annotation[][] annotations,
CallingConvention convention, boolean ignoreErrno) {
Class[] nativeParameterTypes = new Class[parameterTypes.length];
boolean unboxing = false;
boolean ptrCheck = false;
for (int i = 0; i < nativeParameterTypes.length; ++i) {
nativeParameterTypes[i] = AsmUtil.unboxedType(parameterTypes[i]);
unboxing |= nativeParameterTypes[i] != parameterTypes[i];
ptrCheck |= Pointer.class.isAssignableFrom(parameterTypes[i])
|| Struct.class.isAssignableFrom(parameterTypes[i]);
}
Class nativeReturnType = AsmUtil.unboxedReturnType(returnType);
unboxing |= nativeReturnType != returnType;
String stubName = functionName + (unboxing || ptrCheck ? "$jni$" + nextMethodID.getAndIncrement() : "");
// If unboxing of parameters is required, generate a wrapper
if (unboxing || ptrCheck) {
SkinnyMethodAdapter mv = new SkinnyMethodAdapter(cv.visitMethod(ACC_PUBLIC | ACC_FINAL,
functionName, sig(returnType, parameterTypes), null, null));
mv.start();
mv.aload(0);
Label bufferInvocationLabel = emitDirectCheck(mv, parameterTypes);
// Emit the unboxing wrapper
for (int i = 0, lvar = 1; i < parameterTypes.length; ++i) {
lvar = loadParameter(mv, parameterTypes[i], lvar);
if (parameterTypes[i] != nativeParameterTypes[i]) {
if (Number.class.isAssignableFrom(parameterTypes[i])) {
unboxNumber(mv, parameterTypes[i], nativeParameterTypes[i]);
} else if (Pointer.class.isAssignableFrom(parameterTypes[i])) {
unboxPointer(mv, nativeParameterTypes[i]);
} else if (Struct.class.isAssignableFrom(parameterTypes[i])) {
unboxStruct(mv, nativeParameterTypes[i]);
}
}
}
// invoke the compiled stub
mv.invokevirtual(className, stubName, sig(nativeReturnType, nativeParameterTypes));
// emitReturn will box the return value if needed
emitReturn(mv, returnType, nativeReturnType);
String bufInvoke = null;
if (bufferInvocationLabel != null) {
// If there was a non-direct pointer in the parameters, need to
// handle it via a call to the slow buffer invocation
mv.label(bufferInvocationLabel);
bufInvoke = functionName + "$buf$" + nextMethodID.getAndIncrement();
// reload all the parameters
for (int i = 0, lvar = 1; i < parameterTypes.length; ++i) {
lvar = loadParameter(mv, parameterTypes[i], lvar);
}
mv.invokevirtual(className, bufInvoke, sig(returnType, parameterTypes));
emitReturnOp(mv, returnType);
}
mv.visitMaxs(100, calculateLocalVariableSpace(parameterTypes) + 10);
mv.visitEnd();
if (bufInvoke != null) {
SkinnyMethodAdapter bi = new SkinnyMethodAdapter(cv.visitMethod(ACC_PUBLIC | ACC_FINAL,
bufInvoke, sig(returnType, parameterTypes), null, null));
bi.start();
// Retrieve the static 'ffi' Invoker instance
bi.getstatic(p(AbstractNativeInterface.class), "ffi", ci(com.kenai.jffi.Invoker.class));
// retrieve this.function
bi.aload(0);
bi.getfield(className, functionFieldName, ci(Function.class));
generateBufferInvocation(bi, returnType, parameterTypes, annotations);
bi.visitMaxs(100, calculateLocalVariableSpace(parameterTypes) + 10);
bi.visitEnd();
}
}
cv.visitMethod(ACC_PUBLIC | ACC_FINAL | ACC_NATIVE,
stubName, sig(nativeReturnType, nativeParameterTypes), null, null);
compiler.compile(function, stubName, nativeReturnType, nativeParameterTypes,
convention, !ignoreErrno);
}
private final void generateMethod(ClassVisitor cv, String className, String functionName,
String functionFieldName,
Class returnType, Class[] parameterTypes, Annotation[][] parameterAnnotations,
CallingConvention convention, boolean ignoreErrno) {
SkinnyMethodAdapter mv = new SkinnyMethodAdapter(cv.visitMethod(ACC_PUBLIC | ACC_FINAL, functionName,
sig(returnType, parameterTypes), null, null));
mv.start();
// Retrieve the static 'ffi' Invoker instance
mv.getstatic(p(AbstractNativeInterface.class), "ffi", ci(com.kenai.jffi.Invoker.class));
// retrieve this.function
mv.aload(0);
mv.getfield(className, functionFieldName, ci(Function.class));
if (convention == CallingConvention.DEFAULT && isFastIntegerMethod(returnType, parameterTypes)) {
generateFastIntegerInvocation(mv, returnType, parameterTypes, parameterAnnotations, ignoreErrno);
} else if (convention == CallingConvention.DEFAULT && FAST_NUMERIC_AVAILABLE && isFastNumericMethod(returnType, parameterTypes)) {
generateFastNumericInvocation(mv, returnType, parameterTypes, parameterAnnotations);
} else {
generateBufferInvocation(mv, returnType, parameterTypes, parameterAnnotations);
}
mv.visitMaxs(100, calculateLocalVariableSpace(parameterTypes) + 10);
mv.visitEnd();
}
private final void generateBufferInvocation(SkinnyMethodAdapter mv, Class returnType, Class[] parameterTypes, Annotation[][] annotations) {
// [ stack contains: Invoker, Function ]
final boolean sessionRequired = isSessionRequired(parameterTypes);
final int lvarSession = sessionRequired ? calculateLocalVariableSpace(parameterTypes) + 1 : -1;
if (sessionRequired) {
mv.newobj(p(InvocationSession.class));
mv.dup();
mv.invokespecial(InvocationSession.class, "", void.class);
mv.astore(lvarSession);
}
// [ stack contains: Invoker, Function, Function ]
mv.dup();
mv.invokestatic(AsmRuntime.class, "newHeapInvocationBuffer", HeapInvocationBuffer.class, Function.class);
// [ stack contains: Invoker, Function, HeapInvocationBuffer ]
int lvar = 1;
for (int i = 0; i < parameterTypes.length; ++i) {
mv.dup(); // dup ref to HeapInvocationBuffer
if (isSessionRequired(parameterTypes[i])) {
mv.aload(lvarSession);
mv.swap();
}
lvar = loadParameter(mv, parameterTypes[i], lvar);
final int parameterFlags = DefaultInvokerFactory.getParameterFlags(annotations[i]);
final int nativeArrayFlags = DefaultInvokerFactory.getNativeArrayFlags(parameterFlags)
| ((parameterFlags & ParameterFlags.IN) != 0 ? ArrayFlags.NULTERMINATE : 0);
if (parameterTypes[i].isArray() && parameterTypes[i].getComponentType().isPrimitive()) {
mv.pushInt(nativeArrayFlags);
marshal(mv, parameterTypes[i], int.class);
} else if (Pointer.class.isAssignableFrom(parameterTypes[i])) {
mv.pushInt(nativeArrayFlags);
marshal(mv, Pointer.class, int.class);
} else if (Address.class.isAssignableFrom(parameterTypes[i])) {
marshal(mv, Pointer.class);
} else if (Enum.class.isAssignableFrom(parameterTypes[i])) {
marshal(mv, Enum.class);
} else if (Buffer.class.isAssignableFrom(parameterTypes[i])) {
mv.pushInt(nativeArrayFlags);
marshal(mv, parameterTypes[i], int.class);
} else if (ByReference.class.isAssignableFrom(parameterTypes[i])) {
mv.pushInt(nativeArrayFlags);
// stack should be: [ session, buffer, ref, flags ]
sessionmarshal(mv, ByReference.class, int.class);
} else if (StringBuilder.class.isAssignableFrom(parameterTypes[i]) || StringBuffer.class.isAssignableFrom(parameterTypes[i])) {
mv.pushInt(parameterFlags);
mv.pushInt(nativeArrayFlags);
// stack should be: [ session, buffer, ref, flags ]
sessionmarshal(mv, parameterTypes[i], int.class, int.class);
} else if (CharSequence.class.isAssignableFrom(parameterTypes[i])) {
// stack should be: [ Buffer, array, flags ]
marshal(mv, CharSequence.class);
} else if (Struct.class.isAssignableFrom(parameterTypes[i])) {
mv.pushInt(parameterFlags);
mv.pushInt(nativeArrayFlags);
marshal(mv, Struct.class, int.class, int.class);
} else if (parameterTypes[i].isArray() && Struct.class.isAssignableFrom(parameterTypes[i].getComponentType())) {
mv.pushInt(parameterFlags);
mv.pushInt(nativeArrayFlags);
marshal(mv, Struct[].class, int.class, int.class);
} else if (parameterTypes[i].isArray() && Pointer.class.isAssignableFrom(parameterTypes[i].getComponentType())) {
mv.pushInt(parameterFlags);
mv.pushInt(nativeArrayFlags);
sessionmarshal(mv, Pointer[].class, int.class, int.class);
} else if (parameterTypes[i].isPrimitive() || Number.class.isAssignableFrom(parameterTypes[i])) {
emitInvocationBufferIntParameter(mv, parameterTypes[i]);
} else {
throw new IllegalArgumentException("unsupported parameter type " + parameterTypes[i]);
}
}
String invokeMethod = null;
Class nativeReturnType = null;
if (isPrimitiveInt(returnType) || void.class == returnType
|| Byte.class == returnType || Short.class == returnType || Integer.class == returnType) {
invokeMethod = "invokeInt";
nativeReturnType = int.class;
} else if (Long.class == returnType || long.class == returnType) {
invokeMethod = "invokeLong";
nativeReturnType = long.class;
} else if (NativeLong.class == returnType) {
invokeMethod = NativeLong.SIZE == 32 ? "invokeInt" : "invokeLong";
nativeReturnType = NativeLong.SIZE == 32 ? int.class : long.class;
} else if (Pointer.class == returnType || Address.class == returnType
|| Struct.class.isAssignableFrom(returnType) || String.class.isAssignableFrom(returnType)) {
invokeMethod = "invokeAddress";
nativeReturnType = long.class;
} else if (Float.class == returnType || float.class == returnType) {
invokeMethod = "invokeFloat";
nativeReturnType = float.class;
} else if (Double.class == returnType || double.class == returnType) {
invokeMethod = "invokeDouble";
nativeReturnType = double.class;
} else {
throw new IllegalArgumentException("unsupported return type " + returnType);
}
mv.invokevirtual(com.kenai.jffi.Invoker.class, invokeMethod,
nativeReturnType, Function.class, HeapInvocationBuffer.class);
if (sessionRequired) {
mv.aload(lvarSession);
mv.invokevirtual(p(InvocationSession.class), "finish", "()V");
}
emitReturn(mv, returnType, nativeReturnType);
}
private final void generateFastIntegerInvocation(SkinnyMethodAdapter mv, Class returnType,
Class[] parameterTypes, Annotation[][] annotations, boolean ignoreErrno) {
// [ stack contains: Invoker, Function ]
Label bufferInvocationLabel = emitDirectCheck(mv, parameterTypes);
Class nativeIntType = getNativeIntType(returnType, parameterTypes);
// Emit fast-int invocation
for (int i = 0, lvar = 1; i < parameterTypes.length; ++i) {
lvar = loadParameter(mv, parameterTypes[i], lvar);
if (parameterTypes[i].isPrimitive()) {
// widen to long if needed
widen(mv, parameterTypes[i], nativeIntType);
} else if (Number.class.isAssignableFrom(parameterTypes[i])) {
unboxNumber(mv, parameterTypes[i], nativeIntType);
} else if (Pointer.class.isAssignableFrom(parameterTypes[i])) {
unboxPointer(mv, nativeIntType);
} else if (Struct.class.isAssignableFrom(parameterTypes[i])) {
unboxStruct(mv, nativeIntType);
}
}
// stack now contains [ IntInvoker, Function, int args ]
mv.invokevirtual(p(com.kenai.jffi.Invoker.class),
getFastIntInvokerMethodName(parameterTypes.length, ignoreErrno, nativeIntType),
getFastIntInvokerSignature(parameterTypes.length, nativeIntType));
emitReturn(mv, returnType, nativeIntType);
// Now emit the fall back code to handle heap-based memory
if (bufferInvocationLabel != null) {
mv.label(bufferInvocationLabel);
generateBufferInvocation(mv, returnType, parameterTypes, annotations);
}
}
private final void generateFastNumericInvocation(SkinnyMethodAdapter mv, Class returnType,
Class[] parameterTypes, Annotation[][] annotations) {
// [ stack contains: Invoker, Function ]
Label bufferInvocationLabel = emitDirectCheck(mv, parameterTypes);
// Emit fast-numeric invocation
for (int i = 0, lvar = 1; i < parameterTypes.length; ++i) {
lvar = loadParameter(mv, parameterTypes[i], lvar);
if (Pointer.class.isAssignableFrom(parameterTypes[i])) {
unboxPointer(mv, long.class);
} else if (Struct.class.isAssignableFrom(parameterTypes[i])) {
unboxStruct(mv, long.class);
} else {
if (!parameterTypes[i].isPrimitive() && Number.class.isAssignableFrom(parameterTypes[i])) {
unboxNumber(mv, parameterTypes[i], long.class);
}
if (Float.class == parameterTypes[i] || float.class == parameterTypes[i]) {
mv.invokestatic(Float.class, "floatToRawIntBits", int.class, float.class);
mv.i2l();
} else if (Double.class == parameterTypes[i] || double.class == parameterTypes[i]) {
mv.invokestatic(Double.class, "doubleToRawLongBits", long.class, double.class);
} else {
// widen to long if needed
widen(mv, parameterTypes[i], long.class);
}
}
}
// stack now contains [ IntInvoker, Function, int args ]
mv.invokevirtual(p(com.kenai.jffi.Invoker.class),
getFastNumericInvokerMethodName(parameterTypes.length, returnType),
getFastNumericInvokerSignature(parameterTypes.length));
// Convert the result from long to the correct return type
if (Float.class == returnType || float.class == returnType) {
mv.l2i();
mv.invokestatic(Float.class, "intBitsToFloat", float.class, int.class);
} else if (Double.class == returnType || double.class == returnType) {
mv.invokestatic(Double.class, "longBitsToDouble", double.class, long.class);
}
emitReturn(mv, returnType, long.class);
if (bufferInvocationLabel != null) {
// Now emit the alternate path for any parameters that might require it
mv.label(bufferInvocationLabel);
generateBufferInvocation(mv, returnType, parameterTypes, annotations);
}
}
private static final Label emitDirectCheck(SkinnyMethodAdapter mv, Class[] parameterTypes) {
// Iterate through any parameters that might require a HeapInvocationBuffer
Label notFastInt = new Label();
boolean needBufferInvocation = false;
for (int i = 0, lvar = 1; i < parameterTypes.length; ++i) {
if (Pointer.class.isAssignableFrom(parameterTypes[i])) {
mv.aload(lvar++);
mv.invokestatic(AsmRuntime.class, "isDirect", boolean.class, Pointer.class);
mv.iffalse(notFastInt);
needBufferInvocation = true;
} else if (Struct.class.isAssignableFrom(parameterTypes[i])) {
mv.aload(lvar++);
mv.invokestatic(AsmRuntime.class, "isDirect", boolean.class, Struct.class);
mv.iffalse(notFastInt);
needBufferInvocation = true;
} else {
lvar += calculateLocalVariableSpace(parameterTypes[i]);
}
}
return needBufferInvocation ? notFastInt : null;
}
private final void emitReturn(SkinnyMethodAdapter mv, Class returnType, Class nativeIntType) {
if (returnType.isPrimitive()) {
if (long.class == returnType) {
widen(mv, nativeIntType, returnType);
mv.lreturn();
} else if (float.class == returnType) {
mv.freturn();
} else if (double.class == returnType) {
mv.dreturn();
} else if (void.class == returnType) {
mv.voidreturn();
} else {
narrow(mv, nativeIntType, returnType);
mv.ireturn();
}
} else {
boxValue(mv, returnType, nativeIntType);
mv.areturn();
}
}
private final int loadParameter(SkinnyMethodAdapter mv, Class parameterType, int lvar) {
if (!parameterType.isPrimitive()) {
mv.aload(lvar++);
} else if (long.class == parameterType) {
mv.lload(lvar);
lvar += 2;
} else if (float.class == parameterType) {
mv.fload(lvar++);
} else if (double.class == parameterType) {
mv.dload(lvar);
lvar += 2;
} else {
mv.iload(lvar++);
}
return lvar;
}
private static final Class extends Number> getNativeIntType(Class returnType, Class[] parameterTypes) {
for (int i = 0; i < parameterTypes.length; ++i) {
if (requiresLong(parameterTypes[i])) {
return long.class;
}
}
return requiresLong(returnType) ? long.class : int.class;
}
static final String getFastIntInvokerMethodName(int parameterCount, boolean ignoreErrno, Class nativeParamType) {
StringBuilder sb = new StringBuilder("invoke");
if (ignoreErrno && int.class == nativeParamType) {
sb.append("NoErrno");
}
String t = int.class == nativeParamType ? "I" : "L";
if (parameterCount < 1) {
sb.append("V");
} else for (int i = 0; i < parameterCount; ++i) {
sb.append(t);
}
return sb.append("r").append(t).toString();
}
static final String getFastIntInvokerSignature(int parameterCount, Class nativeIntType) {
final String t = int.class == nativeIntType ? "I" : "J";
StringBuilder sb = new StringBuilder();
sb.append("(");
sb.append(ci(Function.class));
for (int i = 0; i < parameterCount; ++i) {
sb.append(t);
}
sb.append(")").append(t);
return sb.toString();
}
static final String getFastNumericInvokerMethodName(int parameterCount, Class nativeParamType) {
StringBuilder sb = new StringBuilder("invoke");
if (parameterCount < 1) {
sb.append("V");
} else for (int i = 0; i < parameterCount; ++i) {
sb.append("N");
}
return sb.append("r").append("N").toString();
}
static final String getFastNumericInvokerSignature(int parameterCount) {
StringBuilder sb = new StringBuilder();
sb.append("(");
sb.append(ci(Function.class));
for (int i = 0; i < parameterCount; ++i) {
sb.append("J");
}
sb.append(")").append("J");
return sb.toString();
}
private final void boxStruct(SkinnyMethodAdapter mv, Class returnType) {
mv.dup2();
Label nonnull = new Label();
Label end = new Label();
mv.lconst_0();
mv.lcmp();
mv.ifne(nonnull);
mv.pop2();
mv.aconst_null();
mv.go_to(end);
mv.label(nonnull);
// Create an instance of the struct subclass
mv.newobj(p(returnType));
mv.dup();
mv.invokespecial(returnType, "", void.class);
mv.dup_x2();
// associate the memory with the struct and return the struct
mv.invokestatic(AsmRuntime.class, "useMemory", void.class, long.class, Struct.class);
mv.label(end);
}
private final void boxPrimitive(SkinnyMethodAdapter mv, Class primitiveType) {
Class objClass = getBoxedClass(primitiveType);
mv.invokestatic(objClass, "valueOf", objClass, primitiveType);
}
private final void boxNumber(SkinnyMethodAdapter mv, Class type, Class nativeType) {
Class primitiveClass = getPrimitiveClass(type);
if (Byte.class.isAssignableFrom(type)) {
narrow(mv, nativeType, byte.class);
} else if (Character.class.isAssignableFrom(type)) {
narrow(mv, nativeType, char.class);
} else if (Short.class.isAssignableFrom(type)) {
narrow(mv, nativeType, short.class);
} else if (Integer.class.isAssignableFrom(type)) {
narrow(mv, nativeType, int.class);
} else if (Long.class.isAssignableFrom(type)) {
widen(mv, nativeType, long.class);
} else if (NativeLong.class.isAssignableFrom(type)) {
widen(mv, nativeType, long.class);
primitiveClass = long.class;
} else if (Boolean.class.isAssignableFrom(type)) {
narrow(mv, nativeType, boolean.class);
} else if (Float.class == type || Double.class == type) {
// nothing to do
} else {
throw new IllegalArgumentException("invalid Number subclass");
}
mv.invokestatic(type, "valueOf", type, primitiveClass);
}
private final void boxValue(SkinnyMethodAdapter mv, Class returnType, Class nativeReturnType) {
if (returnType == nativeReturnType) {
return;
} else if (Boolean.class.isAssignableFrom(returnType)) {
narrow(mv, nativeReturnType, boolean.class);
mv.invokestatic(Boolean.class, "valueOf", Boolean.class, boolean.class);
} else if (Pointer.class.isAssignableFrom(returnType)) {
mv.invokestatic(AsmRuntime.class, "pointerValue", Pointer.class, nativeReturnType);
} else if (Address.class == returnType) {
widen(mv, nativeReturnType, long.class);
mv.invokestatic(returnType, "valueOf", returnType, long.class);
} else if (Struct.class.isAssignableFrom(returnType)) {
widen(mv, nativeReturnType, long.class);
boxStruct(mv, returnType);
} else if (Number.class.isAssignableFrom(returnType)) {
boxNumber(mv, returnType, nativeReturnType);
} else if (String.class == returnType) {
widen(mv, nativeReturnType, long.class);
mv.invokestatic(AsmRuntime.class, "returnString", String.class, long.class);
} else {
throw new IllegalArgumentException("cannot box value of type " + nativeReturnType + " to " + returnType);
}
}
private final void emitInvocationBufferIntParameter(final SkinnyMethodAdapter mv, final Class parameterType) {
String paramMethod = null;
Class paramClass = int.class;
if (!parameterType.isPrimitive()) {
unboxNumber(mv, parameterType, null);
}
if (byte.class == parameterType || Byte.class == parameterType) {
paramMethod = "putByte";
} else if (short.class == parameterType || Short.class == parameterType) {
paramMethod = "putShort";
} else if (int.class == parameterType || Integer.class == parameterType || boolean.class == parameterType) {
paramMethod = "putInt";
} else if (long.class == parameterType || Long.class == parameterType) {
paramMethod = "putLong";
paramClass = long.class;
} else if (float.class == parameterType || Float.class == parameterType) {
paramMethod = "putFloat";
paramClass = float.class;
} else if (double.class == parameterType || Double.class == parameterType) {
paramMethod = "putDouble";
paramClass = double.class;
} else if (NativeLong.class.isAssignableFrom(parameterType) && Platform.getPlatform().longSize() == 32) {
paramMethod = "putInt";
paramClass = int.class;
} else if (NativeLong.class.isAssignableFrom(parameterType) && Platform.getPlatform().longSize() == 64) {
paramMethod = "putLong";
paramClass = long.class;
} else {
throw new IllegalArgumentException("unsupported parameter type " + parameterType);
}
mv.invokevirtual(HeapInvocationBuffer.class, paramMethod, void.class, paramClass);
}
private final void marshal(SkinnyMethodAdapter mv, Class... parameterTypes) {
mv.invokestatic(p(AsmRuntime.class), "marshal", sig(void.class, ci(InvocationBuffer.class), parameterTypes));
}
private final void sessionmarshal(SkinnyMethodAdapter mv, Class... parameterTypes) {
mv.invokestatic(p(AsmRuntime.class), "marshal",
sig(void.class, ci(InvocationSession.class) + ci(InvocationBuffer.class), parameterTypes));
}
private static final Function getFunction(long address, Class returnType, Class[] paramTypes,
boolean requiresErrno, CallingConvention convention) {
com.kenai.jffi.Type[] nativeParamTypes = new com.kenai.jffi.Type[paramTypes.length];
for (int i = 0; i < nativeParamTypes.length; ++i) {
nativeParamTypes[i] = InvokerUtil.getNativeParameterType(paramTypes[i]);
}
return new Function(address, InvokerUtil.getNativeReturnType(returnType),
nativeParamTypes, convention, requiresErrno);
}
private static boolean isSessionRequired(Class parameterType) {
return StringBuilder.class.isAssignableFrom(parameterType)
|| StringBuffer.class.isAssignableFrom(parameterType)
|| ByReference.class.isAssignableFrom(parameterType)
|| (parameterType.isArray() && Pointer.class.isAssignableFrom(parameterType.getComponentType()));
}
private static boolean isSessionRequired(Class[] parameterTypes) {
for (int i = 0; i < parameterTypes.length; ++i) {
if (isSessionRequired(parameterTypes[i])) {
return true;
}
}
return false;
}
final static boolean isFastNumericMethod(Class returnType, Class[] parameterTypes) {
if (!FAST_NUMERIC_AVAILABLE || parameterTypes.length > 6) {
return false;
}
if (!isFastNumericResult(returnType)) {
return false;
}
for (int i = 0; i < parameterTypes.length; ++i) {
if (!isFastNumericParam(parameterTypes[i])) {
return false;
}
}
return com.kenai.jffi.Platform.getPlatform().getCPU() == com.kenai.jffi.Platform.CPU.I386
|| com.kenai.jffi.Platform.getPlatform().getCPU() == com.kenai.jffi.Platform.CPU.X86_64;
}
final static boolean isFastIntegerMethod(Class returnType, Class[] parameterTypes) {
if (parameterTypes.length > 3) {
return false;
}
if (!isFastIntegerResult(returnType)) {
return false;
}
for (int i = 0; i < parameterTypes.length; ++i) {
if (!isFastIntegerParam(parameterTypes[i])) {
return false;
}
}
return com.kenai.jffi.Platform.getPlatform().getCPU() == com.kenai.jffi.Platform.CPU.I386
|| com.kenai.jffi.Platform.getPlatform().getCPU() == com.kenai.jffi.Platform.CPU.X86_64;
}
final static boolean isInt32(Class type) {
return Boolean.class.isAssignableFrom(type) || boolean.class == type
|| Byte.class.isAssignableFrom(type) || byte.class == type
|| Short.class.isAssignableFrom(type) || short.class == type
|| Integer.class.isAssignableFrom(type) || int.class == type;
}
final static boolean isInt32Result(Class type) {
return isInt32(type) || Void.class.isAssignableFrom(type) || void.class == type;
}
final static boolean isPointerResult(Class type) {
return Pointer.class.isAssignableFrom(type)
|| Struct.class.isAssignableFrom(type)
|| String.class.isAssignableFrom(type);
}
final static boolean isPointerParam(Class type) {
return Pointer.class.isAssignableFrom(type)
|| Struct.class.isAssignableFrom(type);
}
private final static boolean isFastIntegerResult(Class type) {
if (isInt32Result(type)) {
return true;
}
final boolean isPointer = isPointerResult(type);
if (isPointer && Platform.getPlatform().addressSize() == 32) {
return true;
}
if (NativeLong.class.isAssignableFrom(type) && Platform.getPlatform().longSize() == 32) {
return true;
}
// For x86_64, any args that promote up to 64bit can be accepted.
final boolean isLong = Long.class == type || long.class == type;
return Platform.getPlatform().addressSize() == 64 && FAST_LONG_AVAILABLE &&
(isPointer || NativeLong.class.isAssignableFrom(type) || isLong);
}
private final static boolean isFastIntegerParam(Class type) {
if (isInt32(type)) {
return true;
}
final boolean isPointer = isPointerParam(type);
if (isPointer && Platform.getPlatform().addressSize() == 32) {
return true;
}
if (NativeLong.class.isAssignableFrom(type) && Platform.getPlatform().longSize() == 32) {
return true;
}
// For x86_64, any args that promote up to 64bit can be accepted.
final boolean isLong = Long.class == type || long.class == type;
return Platform.getPlatform().addressSize() == 64 && FAST_LONG_AVAILABLE &&
(isPointer || NativeLong.class.isAssignableFrom(type) || isLong);
}
final static boolean isFastNumericResult(Class type) {
return isFastIntegerResult(type)
|| Long.class.isAssignableFrom(type) || long.class == type
|| NativeLong.class.isAssignableFrom(type)
|| Pointer.class.isAssignableFrom(type)
|| Struct.class.isAssignableFrom(type)
|| String.class.isAssignableFrom(type)
|| float.class == type || Float.class == type
|| double.class == type || Double.class == type;
}
final static boolean isFastNumericParam(Class type) {
return isFastIntegerParam(type)
|| Long.class.isAssignableFrom(type) || long.class == type
|| NativeLong.class.isAssignableFrom(type)
|| Pointer.class.isAssignableFrom(type)
|| Struct.class.isAssignableFrom(type)
|| float.class == type || Float.class == type
|| double.class == type || Double.class == type;
}
final static boolean isFastNumericAvailable() {
try {
com.kenai.jffi.Invoker.class.getDeclaredMethod("invokeNNNNNNrN", Function.class, long.class, long.class, long.class, long.class, long.class, long.class);
return true;
} catch (Throwable t) {
return false;
}
}
final static boolean isFastLongAvailable() {
try {
com.kenai.jffi.Invoker.class.getDeclaredMethod("invokeLLLLLLrL", Function.class, long.class, long.class, long.class, long.class, long.class, long.class);
return true;
} catch (Throwable t) {
return false;
}
}
private final static boolean requiresLong(Class type) {
return Long.class.isAssignableFrom(type) || long.class == type
|| (NativeLong.class.isAssignableFrom(type) && Platform.getPlatform().longSize() == 64)
|| (Pointer.class.isAssignableFrom(type) && Platform.getPlatform().addressSize() == 64)
|| (Struct.class.isAssignableFrom(type) && Platform.getPlatform().addressSize() == 64)
|| (String.class.isAssignableFrom(type) && Platform.getPlatform().addressSize() == 64)
;
}
public static abstract class AbstractNativeInterface {
public static final com.kenai.jffi.Invoker ffi = com.kenai.jffi.Invoker.getInstance();
// Strong ref to keep the library alive
protected final Library library;
public AbstractNativeInterface(Library library) {
this.library = library;
}
protected static final HeapInvocationBuffer newInvocationBuffer(Function f) {
return new HeapInvocationBuffer(f);
}
}
public static final class ToNativeProxy implements ToNativeConverter {
private final ToNativeConverter converter;
private final ToNativeContext ctx;
public ToNativeProxy(ToNativeConverter converter, ToNativeContext ctx) {
this.converter = converter;
this.ctx = ctx;
}
public Object toNative(Object value, ToNativeContext unused) {
return converter.toNative(value, ctx);
}
public Class nativeType() {
return converter.nativeType();
}
}
public static final class FromNativeProxy implements FromNativeConverter {
private final FromNativeConverter converter;
private final FromNativeContext ctx;
public FromNativeProxy(FromNativeConverter converter, FromNativeContext ctx) {
this.converter = converter;
this.ctx = ctx;
}
public Object fromNative(Object value, FromNativeContext unused) {
return converter.fromNative(value, ctx);
}
public Class nativeType() {
return converter.nativeType();
}
}
public static final class IntToLong implements FromNativeConverter, ToNativeConverter {
public Object fromNative(Object nativeValue, FromNativeContext context) {
return ((Number) nativeValue).longValue();
}
public Object toNative(Object value, ToNativeContext context) {
return Integer.valueOf(((Number) value).intValue());
}
public Class nativeType() {
return Integer.class;
}
};
public static interface TestLib {
static final class s8 extends Struct {
public final Signed8 s8 = new Signed8();
}
public Integer add_int32_t(Integer i1, int i2);
public Float add_float(float f1, float f2);
public Double add_double(Double f1, double f2);
// public byte add_int8_t(byte i1, byte i2);
byte ptr_ret_int8_t(s8[] s, int index);
Byte ptr_ret_int8_t(Pointer p, int index);
byte ptr_ret_int8_t(s8 s, int index);
void not_found_function();
}
public static void main(String[] args) {
System.setProperty("jaffl.compile.dump", "true");
System.out.println("cpu=" + Platform.getPlatform().getCPU());
final Map options = new HashMap();
// options.put(LibraryOption.TypeMapper, new TypeMapper() {
//
// public FromNativeConverter getFromNativeConverter(Class type) {
// if (Long.class.isAssignableFrom(type)) {
// return new IntToLong();
// }
// return null;
// }
//
// public ToNativeConverter getToNativeConverter(Class type) {
// if (Long.class.isAssignableFrom(type) || long.class == type) {
// return new IntToLong();
// }
// return null;
// }
// });
TestLib lib = AsmLibraryLoader.getInstance().loadLibrary(new Library("test"), TestLib.class, options);
Number result = lib.add_int32_t(1, 2);
System.err.println("result=" + result);
// System.err.println("adding bytes =" + lib.add_int8_t((byte) 1, (byte) 3));
System.err.println("adding floats=" + lib.add_float(1.0f, 2.0f));
System.err.println("adding doubles=" + lib.add_double(1.0, 2.0));
Pointer p = MemoryIO.allocateDirect(1024);
lib.ptr_ret_int8_t(p, 0);
lib.ptr_ret_int8_t(MemoryIO.allocate(1024), 0);
}
}
jaffl-0.5.9/src/com/kenai/jaffl/provider/jffi/AsmRuntime.java 0000664 0000000 0000000 00000034573 12017475436 0024051 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.provider.jffi;
import com.kenai.jaffl.Address;
import com.kenai.jaffl.MemoryIO;
import com.kenai.jaffl.ParameterFlags;
import com.kenai.jaffl.Pointer;
import com.kenai.jaffl.byref.ByReference;
import com.kenai.jaffl.provider.AbstractArrayMemoryIO;
import com.kenai.jaffl.provider.DelegatingMemoryIO;
import com.kenai.jaffl.provider.InvocationSession;
import com.kenai.jaffl.provider.StringIO;
import com.kenai.jaffl.struct.Struct;
import com.kenai.jaffl.struct.StructUtil;
import com.kenai.jaffl.util.EnumMapper;
import com.kenai.jffi.Function;
import com.kenai.jffi.HeapInvocationBuffer;
import com.kenai.jffi.InvocationBuffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.DoubleBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.LongBuffer;
import java.nio.ShortBuffer;
/**
* Utility methods that are used at runtime by generated code.
*/
public final class AsmRuntime {
public static final com.kenai.jffi.MemoryIO IO = com.kenai.jffi.MemoryIO.getInstance();
private AsmRuntime() {}
public static final void marshal(InvocationBuffer buffer, byte[] array, int flags) {
if (array == null) {
buffer.putAddress(0L);
} else {
buffer.putArray(array, 0, array.length, flags);
}
}
public static final void marshal(InvocationBuffer buffer, short[] array, int flags) {
if (array == null) {
buffer.putAddress(0L);
} else {
buffer.putArray(array, 0, array.length, flags);
}
}
public static final void marshal(InvocationBuffer buffer, int[] array, int flags) {
if (array == null) {
buffer.putAddress(0L);
} else {
buffer.putArray(array, 0, array.length, flags);
}
}
public static final void marshal(InvocationBuffer buffer, long[] array, int flags) {
if (array == null) {
buffer.putAddress(0L);
} else {
buffer.putArray(array, 0, array.length, flags);
}
}
public static final void marshal(InvocationBuffer buffer, float[] array, int flags) {
if (array == null) {
buffer.putAddress(0L);
} else {
buffer.putArray(array, 0, array.length, flags);
}
}
public static final void marshal(InvocationBuffer buffer, double[] array, int flags) {
if (array == null) {
buffer.putAddress(0L);
} else {
buffer.putArray(array, 0, array.length, flags);
}
}
public static final void marshal(InvocationBuffer buffer, Pointer ptr, int nativeArrayFlags) {
if (ptr == null) {
buffer.putAddress(0L);
} else if (ptr.isDirect()) {
buffer.putAddress(ptr.address());
} else if (ptr instanceof AbstractArrayMemoryIO) {
AbstractArrayMemoryIO aio = (AbstractArrayMemoryIO) ptr;
buffer.putArray(aio.array(), aio.offset(), aio.length(), nativeArrayFlags);
} else {
throw new IllegalArgumentException("unsupported argument type" + ptr.getClass());
}
}
public static final void marshal(InvocationBuffer buffer, Address ptr) {
if (ptr == null) {
buffer.putAddress(0L);
} else {
buffer.putAddress(ptr.nativeAddress());
}
}
public static final void marshal(InvocationBuffer buffer, ByteBuffer buf, int flags) {
if (buf == null) {
buffer.putAddress(0L);
} else if (buf.hasArray()) {
buffer.putArray(buf.array(), buf.arrayOffset() + buf.position(), buf.remaining(), flags);
} else {
buffer.putDirectBuffer(buf, buf.position(), buf.remaining());
}
}
public static final void marshal(InvocationBuffer buffer, ShortBuffer buf, int flags) {
if (buf == null) {
buffer.putAddress(0L);
} else if (buf.hasArray()) {
buffer.putArray(buf.array(), buf.arrayOffset() + buf.position(), buf.remaining(), flags);
} else {
buffer.putDirectBuffer(buf, buf.position() << 1, buf.remaining() << 1);
}
}
public static final void marshal(InvocationBuffer buffer, IntBuffer buf, int flags) {
if (buf == null) {
buffer.putAddress(0L);
} else if (buf.hasArray()) {
buffer.putArray(buf.array(), buf.arrayOffset() + buf.position(), buf.remaining(), flags);
} else {
buffer.putDirectBuffer(buf, buf.position() << 2, buf.remaining() << 2);
}
}
public static final void marshal(InvocationBuffer buffer, LongBuffer buf, int flags) {
if (buf == null) {
buffer.putAddress(0L);
} else if (buf.hasArray()) {
buffer.putArray(buf.array(), buf.arrayOffset() + buf.position(), buf.remaining(), flags);
} else {
buffer.putDirectBuffer(buf, buf.position() << 3, buf.remaining() << 3);
}
}
public static final void marshal(InvocationBuffer buffer, FloatBuffer buf, int flags) {
if (buf == null) {
buffer.putAddress(0L);
} else if (buf.hasArray()) {
buffer.putArray(buf.array(), buf.arrayOffset() + buf.position(), buf.remaining(), flags);
} else {
buffer.putDirectBuffer(buf, buf.position() << 2, buf.remaining() << 2);
}
}
public static final void marshal(InvocationBuffer buffer, DoubleBuffer buf, int flags) {
if (buf == null) {
buffer.putAddress(0L);
} else if (buf.hasArray()) {
buffer.putArray(buf.array(), buf.arrayOffset() + buf.position(), buf.remaining(), flags);
} else {
buffer.putDirectBuffer(buf, buf.position() << 3, buf.remaining() << 3);
}
}
public static final void marshal(InvocationBuffer buffer, CharSequence cs) {
if (cs == null) {
buffer.putAddress(0L);
} else {
ByteBuffer buf = StringIO.getStringIO().toNative(cs, cs.length(), true);
buffer.putArray(buf.array(), buf.arrayOffset(), buf.remaining(), com.kenai.jffi.ArrayFlags.IN | com.kenai.jffi.ArrayFlags.NULTERMINATE);
}
}
public static final void marshal(InvocationBuffer buffer, Struct parameter, int parameterFlags, int nativeArrayFlags) {
if (parameter == null) {
buffer.putAddress(0L);
} else {
Struct s = parameter;
MemoryIO io = StructUtil.getMemoryIO(s, parameterFlags);
if (io instanceof AbstractArrayMemoryIO) {
AbstractArrayMemoryIO aio = (AbstractArrayMemoryIO) io;
buffer.putArray(aio.array(), aio.offset(), aio.length(), nativeArrayFlags);
} else if (io.isDirect()) {
buffer.putAddress(io.address());
}
}
}
public static final void marshal(InvocationBuffer buffer, Struct[] parameter, int parameterFlags, int nativeArrayFlags) {
if (parameter == null) {
buffer.putAddress(0L);
} else {
Struct[] array = parameter;
MemoryIO io = StructUtil.getMemoryIO(array[0], parameterFlags);
if (!(io instanceof DelegatingMemoryIO)) {
throw new RuntimeException("Struct array must be backed by contiguous array");
}
io = ((DelegatingMemoryIO) io).getDelegatedMemoryIO();
if (io instanceof AbstractArrayMemoryIO) {
AbstractArrayMemoryIO aio = (AbstractArrayMemoryIO) io;
buffer.putArray(aio.array(), aio.offset(), aio.length(), nativeArrayFlags);
} else if (io.isDirect()) {
buffer.putAddress(io.address());
}
}
}
public static final void marshal(InvocationSession session, InvocationBuffer buffer, ByReference parameter, int flags) {
if (parameter == null) {
buffer.putAddress(0L);
} else {
final ByReference ref = (ByReference) parameter;
final ByteBuffer buf = ByteBuffer.allocate(ref.nativeSize()).order(ByteOrder.nativeOrder());
buf.clear();
if (com.kenai.jffi.ArrayFlags.isIn(flags)) {
ref.marshal(buf);
}
buffer.putArray(buf.array(), buf.arrayOffset() + buf.position(), buf.remaining(), flags);
if (com.kenai.jffi.ArrayFlags.isOut(flags)) {
session.addPostInvoke(new InvocationSession.PostInvoke() {
public void postInvoke() {
ref.unmarshal(buf);
}
});
}
}
}
public static final void marshal(InvocationSession session, InvocationBuffer buffer, StringBuilder parameter, int inout, int nflags) {
if (parameter == null) {
buffer.putAddress(0L);
} else {
final StringBuilder sb = parameter;
final StringIO io = StringIO.getStringIO();
final ByteBuffer buf = io.toNative(sb, sb.capacity(), ParameterFlags.isIn(inout));
buffer.putArray(buf.array(), buf.arrayOffset(), buf.remaining(), nflags);
//
// Copy the string back out if its an OUT parameter
//
if (ParameterFlags.isOut(inout)) {
session.addPostInvoke(new InvocationSession.PostInvoke() {
public void postInvoke() {
sb.delete(0, sb.length()).append(io.fromNative(buf, sb.capacity()));
}
});
}
}
}
public static final void marshal(InvocationSession session, InvocationBuffer buffer, final StringBuffer parameter, int inout, int nflags) {
if (parameter == null) {
buffer.putAddress(0L);
} else {
final StringBuffer sb = parameter;
final StringIO io = StringIO.getStringIO();
final ByteBuffer buf = io.toNative(sb, sb.capacity(), ParameterFlags.isIn(inout));
buffer.putArray(buf.array(), buf.arrayOffset(), buf.remaining(), nflags);
//
// Copy the string back out if its an OUT parameter
//
if (ParameterFlags.isOut(inout)) {
session.addPostInvoke(new InvocationSession.PostInvoke() {
public void postInvoke() {
sb.delete(0, sb.length()).append(io.fromNative(buf, sb.capacity()));
}
});
}
}
}
public static final void marshal(InvocationBuffer buffer, final Enum parameter) {
buffer.putInt(EnumMapper.getInstance().intValue(parameter));
}
public static final void marshal(InvocationSession session, InvocationBuffer buffer, Pointer[] parameter, int inout, int nativeArrayFlags) {
if (parameter == null) {
buffer.putAddress(0L);
} else {
final Pointer[] array = parameter;
if (Pointer.SIZE == 32) {
final int[] raw = new int[array.length];
for (int i = 0; i < raw.length; ++i) {
if (!array[i].isDirect()) {
throw new IllegalArgumentException("invalid pointer in array at index " + i);
}
raw[i] = (int) array[i].address();
}
buffer.putArray(raw, 0, raw.length, nativeArrayFlags);
if (ParameterFlags.isOut(inout)) {
session.addPostInvoke(new InvocationSession.PostInvoke() {
public void postInvoke() {
for (int i = 0; i < raw.length; ++i) {
array[i] = MemoryUtil.newPointer(raw[i]);
}
}
});
}
} else {
final long[] raw = new long[array.length];
for (int i = 0; i < raw.length; ++i) {
if (!array[i].isDirect()) {
throw new IllegalArgumentException("invalid pointer in array at index " + i);
}
raw[i] = array[i].address();
}
buffer.putArray(raw, 0, raw.length, nativeArrayFlags);
if (ParameterFlags.isOut(inout)) {
session.addPostInvoke(new InvocationSession.PostInvoke() {
public void postInvoke() {
for (int i = 0; i < raw.length; ++i) {
array[i] = MemoryUtil.newPointer(raw[i]);
}
}
});
}
}
}
}
public static final UnsatisfiedLinkError newUnsatisifiedLinkError(String msg) {
return new UnsatisfiedLinkError(msg);
}
public static final HeapInvocationBuffer newHeapInvocationBuffer(Function function) {
return new HeapInvocationBuffer(function);
}
public static final String returnString(long ptr) {
if (ptr == 0) {
return null;
}
final ByteBuffer buf = ByteBuffer.wrap(IO.getZeroTerminatedByteArray(ptr));
return StringIO.getStringIO().fromNative(buf).toString();
}
public static final Pointer pointerValue(long ptr) {
return ptr != 0 ? new DirectMemoryIO(ptr) : null;
}
public static final Pointer pointerValue(int ptr) {
return ptr != 0 ? new DirectMemoryIO((long) ptr & 0xffffffffL) : null;
}
public static final MemoryIO newMemoryIO(long ptr) {
return ptr == 0 ? null : new DirectMemoryIO(ptr);
}
public static final void useMemory(long ptr, Struct s) {
s.useMemory(new DirectMemoryIO(ptr));
}
public static final boolean isDirect(Pointer ptr) {
return ptr == null || ptr.isDirect();
}
public static final int intValue(Pointer ptr) {
return ptr != null ? (int) ptr.address() : 0;
}
public static final long longValue(Pointer ptr) {
return ptr != null ? ptr.address() : 0L;
}
public static final boolean isDirect(Struct s) {
return s == null || StructUtil.isDirect(s);
}
public static final boolean isDirect(Struct s, int flags) {
return s == null || StructUtil.getMemoryIO(s, flags).isDirect();
}
public static final int intValue(Struct s) {
return s != null ? (int) StructUtil.getMemoryIO(s).address() : 0;
}
public static final long longValue(Struct s) {
return s != null ? StructUtil.getMemoryIO(s).address() : 0L;
}
}
jaffl-0.5.9/src/com/kenai/jaffl/provider/jffi/AsmUtil.java 0000664 0000000 0000000 00000015436 12017475436 0023340 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.provider.jffi;
import com.kenai.jaffl.NativeLong;
import com.kenai.jaffl.Platform;
import com.kenai.jaffl.Pointer;
import com.kenai.jaffl.struct.Struct;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.lang.reflect.Constructor;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import static com.kenai.jaffl.provider.jffi.NumberUtil.*;
import static com.kenai.jaffl.provider.jffi.CodegenUtils.*;
class AsmUtil {
private AsmUtil() {}
public static final MethodVisitor newTraceMethodVisitor(MethodVisitor mv) {
try {
Class tmvClass = Class.forName("org.objectweb.asm.util.TraceMethodVisitor");
Constructor c = tmvClass.getDeclaredConstructor(MethodVisitor.class);
return (MethodVisitor) c.newInstance(mv);
} catch (Throwable t) {
return mv;
}
}
public static final ClassVisitor newTraceClassVisitor(ClassVisitor cv, OutputStream out) {
return newTraceClassVisitor(cv, new PrintWriter(out, true));
}
public static final ClassVisitor newTraceClassVisitor(ClassVisitor cv, PrintWriter out) {
try {
Class tmvClass = Class.forName("org.objectweb.asm.util.TraceClassVisitor");
Constructor c = tmvClass.getDeclaredConstructor(ClassVisitor.class, PrintWriter.class);
return (ClassVisitor) c.newInstance(cv, out);
} catch (Throwable t) {
return cv;
}
}
public static final ClassVisitor newCheckClassAdapter(ClassVisitor cv) {
try {
Class tmvClass = Class.forName("org.objectweb.asm.util.CheckClassAdapter");
Constructor c = tmvClass.getDeclaredConstructor(ClassVisitor.class);
return (ClassVisitor) c.newInstance(cv);
} catch (Throwable t) {
return cv;
}
}
public static final Class unboxedReturnType(Class type) {
if (Pointer.class.isAssignableFrom(type)
|| Struct.class.isAssignableFrom(type)
|| String.class.isAssignableFrom(type)) {
return Platform.getPlatform().longSize() == 32 ? int.class : long.class;
}
return unboxedType(type);
}
public static final Class unboxedType(Class boxedType) {
if (boxedType == Byte.class) {
return byte.class;
} else if (boxedType == Short.class) {
return short.class;
} else if (boxedType == Integer.class) {
return int.class;
} else if (boxedType == Long.class) {
return long.class;
} else if (boxedType == Float.class) {
return float.class;
} else if (boxedType == Double.class) {
return double.class;
} else if (boxedType == Boolean.class) {
return boolean.class;
} else if (boxedType == NativeLong.class) {
return Platform.getPlatform().longSize() == 32 ? int.class : long.class;
} else if (Pointer.class.isAssignableFrom(boxedType) || Struct.class.isAssignableFrom(boxedType)) {
return Platform.getPlatform().addressSize() == 32 ? int.class : long.class;
} else {
return boxedType;
}
}
public static final Class boxedType(Class type) {
if (type == byte.class) {
return Byte.class;
} else if (type == short.class) {
return Short.class;
} else if (type == int.class) {
return Integer.class;
} else if (type == long.class) {
return Long.class;
} else if (type == float.class) {
return Float.class;
} else if (type == double.class) {
return Double.class;
} else if (type == boolean.class) {
return Boolean.class;
} else {
return type;
}
}
static final void emitReturnOp(SkinnyMethodAdapter mv, Class returnType) {
if (!returnType.isPrimitive()) {
mv.areturn();
} else if (long.class == returnType) {
mv.lreturn();
} else if (float.class == returnType) {
mv.freturn();
} else if (double.class == returnType) {
mv.dreturn();
} else if (void.class == returnType) {
mv.voidreturn();
} else {
mv.ireturn();
}
}
/**
* Calculates the size of a local variable
*
* @param type The type of parameter
* @return The size in parameter units
*/
static final int calculateLocalVariableSpace(Class type) {
return long.class == type || double.class == type ? 2 : 1;
}
/**
* Calculates the size of a list of types in the local variable area.
*
* @param type The type of parameter
* @return The size in parameter units
*/
static final int calculateLocalVariableSpace(Class... types) {
int size = 0;
for (int i = 0; i < types.length; ++i) {
size += calculateLocalVariableSpace(types[i]);
}
return size;
}
private static final void unboxPointerOrStruct(final SkinnyMethodAdapter mv, final Class type, final Class nativeType) {
mv.invokestatic(p(AsmRuntime.class), long.class == nativeType ? "longValue" : "intValue",
sig(nativeType, type));
}
static final void unboxPointer(final SkinnyMethodAdapter mv, final Class nativeType) {
unboxPointerOrStruct(mv, Pointer.class, nativeType);
}
static final void unboxStruct(final SkinnyMethodAdapter mv, final Class nativeType) {
unboxPointerOrStruct(mv, Struct.class, nativeType);
}
static final void unboxNumber(final SkinnyMethodAdapter mv, final Class boxedType, final Class nativeType) {
String intValueMethod = long.class == nativeType ? "longValue" : "intValue";
String intValueSignature = long.class == nativeType ? "()J" : "()I";
if (Byte.class == boxedType || Short.class == boxedType || Integer.class == boxedType) {
mv.invokevirtual(p(boxedType), intValueMethod, intValueSignature);
} else if (Long.class == boxedType) {
mv.invokevirtual(p(boxedType), "longValue", "()J");
} else if (Float.class == boxedType) {
mv.invokevirtual(p(boxedType), "floatValue", "()F");
} else if (Double.class == boxedType) {
mv.invokevirtual(p(boxedType), "doubleValue", "()D");
} else if (NativeLong.class.isAssignableFrom(boxedType)) {
mv.invokevirtual(p(boxedType), intValueMethod, intValueSignature);
} else if (Boolean.class.isAssignableFrom(boxedType)) {
mv.invokevirtual(p(boxedType), "booleanValue", "()Z");
widen(mv, boolean.class, nativeType);
} else {
throw new IllegalArgumentException("unsupported Number subclass: " + boxedType);
}
}
}
jaffl-0.5.9/src/com/kenai/jaffl/provider/jffi/BoundedDirectMemoryIO.java 0000664 0000000 0000000 00000000554 12017475436 0026111 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.provider.jffi;
import com.kenai.jaffl.provider.BoundedMemoryIO;
class BoundedDirectMemoryIO extends BoundedMemoryIO {
BoundedDirectMemoryIO(DirectMemoryIO parent, long offset, long size) {
super(parent, offset, size);
}
@Override
public long address() {
return getDelegatedMemoryIO().address();
}
}
jaffl-0.5.9/src/com/kenai/jaffl/provider/jffi/ByteBufferMemoryIO.java 0000664 0000000 0000000 00000001440 12017475436 0025426 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.provider.jffi;
import com.kenai.jaffl.MemoryIO;
import com.kenai.jaffl.Pointer;
import com.kenai.jaffl.provider.AbstractBufferMemoryIO;
import java.nio.ByteBuffer;
public class ByteBufferMemoryIO extends AbstractBufferMemoryIO {
public ByteBufferMemoryIO(ByteBuffer buffer) {
super(buffer);
}
public MemoryIO getMemoryIO(long offset) {
return MemoryUtil.newMemoryIO(getAddress(offset));
}
public MemoryIO getMemoryIO(long offset, long size) {
return MemoryUtil.newMemoryIO(getAddress(offset), size);
}
public Pointer getPointer(long offset) {
return MemoryUtil.newPointer(getAddress(offset));
}
public void putPointer(long offset, Pointer value) {
putAddress(offset, value.address());
}
}
jaffl-0.5.9/src/com/kenai/jaffl/provider/jffi/CodegenUtils.java 0000664 0000000 0000000 00000014275 12017475436 0024347 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.provider.jffi;
import java.util.Arrays;
import java.util.Map;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Type;
public class CodegenUtils {
/**
* Creates a dotted class name from a path/package name
*/
public static String c(String p) {
return p.replace('/', '.');
}
/**
* Creates a class path name, from a Class.
*/
public static String p(Class n) {
return n.getName().replace('.','/');
}
/**
* Creates a class identifier of form Labc/abc;, from a Class.
*/
public static String ci(Class n) {
if (n.isArray()) {
n = n.getComponentType();
if (n.isPrimitive()) {
if (n == Byte.TYPE) {
return "[B";
} else if (n == Boolean.TYPE) {
return "[Z";
} else if (n == Short.TYPE) {
return "[S";
} else if (n == Character.TYPE) {
return "[C";
} else if (n == Integer.TYPE) {
return "[I";
} else if (n == Float.TYPE) {
return "[F";
} else if (n == Double.TYPE) {
return "[D";
} else if (n == Long.TYPE) {
return "[J";
} else {
throw new RuntimeException("Unrecognized type in compiler: " + n.getName());
}
} else {
return "[" + ci(n);
}
} else {
if (n.isPrimitive()) {
if (n == Byte.TYPE) {
return "B";
} else if (n == Boolean.TYPE) {
return "Z";
} else if (n == Short.TYPE) {
return "S";
} else if (n == Character.TYPE) {
return "C";
} else if (n == Integer.TYPE) {
return "I";
} else if (n == Float.TYPE) {
return "F";
} else if (n == Double.TYPE) {
return "D";
} else if (n == Long.TYPE) {
return "J";
} else if (n == Void.TYPE) {
return "V";
} else {
throw new RuntimeException("Unrecognized type in compiler: " + n.getName());
}
} else {
return "L" + p(n) + ";";
}
}
}
/**
* Creates a human-readable representation, from a Class.
*/
public static String human(Class n) {
return n.getCanonicalName();
}
/**
* Create a method signature from the given param types and return values
*/
public static String sig(Class retval, Class... params) {
return sigParams(params) + ci(retval);
}
public static String sig(Class retval, String descriptor, Class... params) {
return sigParams(descriptor, params) + ci(retval);
}
public static String sigParams(Class... params) {
StringBuilder signature = new StringBuilder("(");
for (int i = 0; i < params.length; i++) {
signature.append(ci(params[i]));
}
signature.append(")");
return signature.toString();
}
public static String sigParams(String descriptor, Class... params) {
StringBuilder signature = new StringBuilder("(");
signature.append(descriptor);
for (int i = 0; i < params.length; i++) {
signature.append(ci(params[i]));
}
signature.append(")");
return signature.toString();
}
public static String pretty(Class retval, Class... params) {
return prettyParams(params) + human(retval);
}
public static String prettyParams(Class... params) {
StringBuilder signature = new StringBuilder("(");
for (int i = 0; i < params.length; i++) {
signature.append(human(params[i]));
if (i < params.length - 1) signature.append(',');
}
signature.append(")");
return signature.toString();
}
public static Class[] params(Class... classes) {
return classes;
}
public static Class[] params(Class cls, int times) {
Class[] classes = new Class[times];
Arrays.fill(classes, cls);
return classes;
}
public static Class[] params(Class cls1, Class clsFill, int times) {
Class[] classes = new Class[times + 1];
Arrays.fill(classes, clsFill);
classes[0] = cls1;
return classes;
}
public static String getAnnotatedBindingClassName(String javaMethodName, String typeName, boolean isStatic, int required, int optional, boolean multi, boolean framed) {
String commonClassSuffix;
String marker = framed ? "$RUBYFRAMEDINVOKER$" : "$RUBYINVOKER$";
if (multi) {
commonClassSuffix = (isStatic ? "$s" : "$i" ) + "_method_multi" + marker + javaMethodName;
} else {
commonClassSuffix = (isStatic ? "$s" : "$i" ) + "_method_" + required + "_" + optional + marker + javaMethodName;
}
return typeName + commonClassSuffix;
}
public static void visitAnnotationFields(AnnotationVisitor visitor, Map fields) {
for (Map.Entry fieldEntry : fields.entrySet()) {
Object value = fieldEntry.getValue();
if (value.getClass().isArray()) {
Object[] values = (Object[]) value;
AnnotationVisitor arrayV = visitor.visitArray(fieldEntry.getKey());
for (int i = 0; i < values.length; i++) {
arrayV.visit(null, values[i]);
}
arrayV.visitEnd();
} else if (value.getClass().isEnum()) {
visitor.visitEnum(fieldEntry.getKey(), ci(value.getClass()), value.toString());
} else if (value instanceof Class) {
visitor.visit(fieldEntry.getKey(), Type.getType((Class)value));
} else {
visitor.visit(fieldEntry.getKey(), value);
}
}
}
}
jaffl-0.5.9/src/com/kenai/jaffl/provider/jffi/DefaultInvokerFactory.java 0000664 0000000 0000000 00000105225 12017475436 0026230 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.provider.jffi;
import com.kenai.jaffl.LibraryOption;
import com.kenai.jaffl.NativeLong;
import com.kenai.jaffl.ParameterFlags;
import com.kenai.jaffl.Platform;
import com.kenai.jaffl.Pointer;
import com.kenai.jaffl.annotations.StdCall;
import com.kenai.jaffl.byref.ByReference;
import com.kenai.jaffl.mapper.FromNativeContext;
import com.kenai.jaffl.mapper.FromNativeConverter;
import com.kenai.jaffl.mapper.FunctionMapper;
import com.kenai.jaffl.mapper.MethodResultContext;
import com.kenai.jaffl.mapper.ToNativeContext;
import com.kenai.jaffl.mapper.ToNativeConverter;
import com.kenai.jaffl.mapper.TypeMapper;
import com.kenai.jaffl.provider.InvocationSession;
import com.kenai.jaffl.provider.Invoker;
import com.kenai.jaffl.provider.StringIO;
import com.kenai.jaffl.struct.Struct;
import com.kenai.jaffl.util.EnumMapper;
import com.kenai.jffi.Function;
import com.kenai.jffi.HeapInvocationBuffer;
import com.kenai.jffi.InvocationBuffer;
import com.kenai.jffi.Type;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.DoubleBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.LongBuffer;
import java.nio.ShortBuffer;
import java.util.Map;
final class DefaultInvokerFactory implements InvokerFactory {
private final static class SingletonHolder {
static InvokerFactory INSTANCE = new DefaultInvokerFactory();
}
public static final InvokerFactory getInstance() {
return SingletonHolder.INSTANCE;
}
public final boolean isMethodSupported(Method method) {
return true; // The default factory supports everything
}
public final Invoker createInvoker(Method method, com.kenai.jaffl.provider.Library library, Map options) {
FunctionMapper functionMapper = options.containsKey(LibraryOption.FunctionMapper)
? (FunctionMapper) options.get(LibraryOption.FunctionMapper) : IdentityFunctionMapper.getInstance();
final long address = ((Library) library).findSymbolAddress(functionMapper.mapFunctionName(method.getName(), null));
TypeMapper typeMapper = options.containsKey(LibraryOption.TypeMapper)
? (TypeMapper) options.get(LibraryOption.TypeMapper) : NullTypeMapper.INSTANCE;
com.kenai.jffi.CallingConvention convention = method.getAnnotation(StdCall.class) != null
? com.kenai.jffi.CallingConvention.STDCALL : InvokerUtil.getCallingConvention(options);
Marshaller[] marshallers = new Marshaller[method.getParameterTypes().length];
Type[] paramTypes = new Type[marshallers.length];
for (int i = 0; i < marshallers.length; ++i) {
marshallers[i] = getMarshaller(method, i, typeMapper);
paramTypes[i] = getNativeParameterType(method, i, typeMapper);
}
Class returnType = method.getReturnType();
FromNativeConverter resultConverter = typeMapper.getFromNativeConverter(returnType);
if (resultConverter != null) {
returnType = resultConverter.nativeType();
}
Function function = new Function(address, getNativeReturnType(returnType),
paramTypes, convention, InvokerUtil.requiresErrno(method));
FunctionInvoker invoker = getFunctionInvoker(returnType);
if (resultConverter != null) {
MethodResultContext context = new MethodResultContext(method);
invoker = new ConvertingInvoker(resultConverter, context, invoker);
}
return isSessionRequired(marshallers)
? new SessionInvoker(function, invoker, marshallers)
: new DefaultInvoker(function, invoker, marshallers);
}
private static final boolean isSessionRequired(Marshaller[] marshallers) {
for (Marshaller m : marshallers) {
if (m.isSessionRequired()) {
return true;
}
}
return false;
}
private static final FunctionInvoker getFunctionInvoker(Class returnType) {
if (Void.class.isAssignableFrom(returnType) || void.class == returnType) {
return VoidInvoker.INSTANCE;
} else if (Boolean.class.isAssignableFrom(returnType) || boolean.class == returnType) {
return BooleanInvoker.INSTANCE;
} else if (Enum.class.isAssignableFrom(returnType)) {
return new EnumInvoker(returnType);
} else if (Byte.class.isAssignableFrom(returnType) || byte.class == returnType) {
return Int8Invoker.INSTANCE;
} else if (Short.class.isAssignableFrom(returnType) || short.class == returnType) {
return Int16Invoker.INSTANCE;
} else if (Integer.class.isAssignableFrom(returnType) || int.class == returnType) {
return Int32Invoker.INSTANCE;
} else if (Long.class.isAssignableFrom(returnType) || long.class == returnType) {
return Int64Invoker.INSTANCE;
} else if (NativeLong.class.isAssignableFrom(returnType)) {
return Platform.getPlatform().longSize() == 32
? NativeLong32Invoker.INSTANCE : NativeLong64Invoker.INSTANCE;
} else if (Float.class.isAssignableFrom(returnType) || float.class == returnType) {
return Float32Invoker.INSTANCE;
} else if (Double.class.isAssignableFrom(returnType) || double.class == returnType) {
return Float64Invoker.INSTANCE;
} else if (Pointer.class.isAssignableFrom(returnType)) {
return PointerInvoker.INSTANCE;
} else if (Struct.class.isAssignableFrom(returnType)) {
return new StructInvoker(returnType);
} else if (String.class.isAssignableFrom(returnType)) {
return StringInvoker.INSTANCE;
} else {
throw new IllegalArgumentException("Unknown return type: " + returnType);
}
}
private static final Type getNativeReturnType(Class type) {
if (Void.class.isAssignableFrom(type) || void.class == type) {
return Type.VOID;
} else if (Boolean.class.isAssignableFrom(type) || boolean.class == type) {
return Type.SINT32;
} else if (Byte.class.isAssignableFrom(type) || byte.class == type) {
return Type.SINT8;
} else if (Short.class.isAssignableFrom(type) || short.class == type) {
return Type.SINT16;
} else if (Integer.class.isAssignableFrom(type) || int.class == type) {
return Type.SINT32;
} else if (Long.class.isAssignableFrom(type) || long.class == type) {
return Type.SINT64;
} else if (NativeLong.class.isAssignableFrom(type)) {
return Platform.getPlatform().longSize() == 32 ? Type.SINT32: Type.SINT64;
} else if (Float.class.isAssignableFrom(type) || float.class == type) {
return Type.FLOAT;
} else if (Double.class.isAssignableFrom(type) || double.class == type) {
return Type.DOUBLE;
} else if (Enum.class.isAssignableFrom(type)) {
return Type.SINT32;
} else if (Pointer.class.isAssignableFrom(type)) {
return Type.POINTER;
} else if (Struct.class.isAssignableFrom(type)) {
return Type.POINTER;
} else if (String.class.isAssignableFrom(type)) {
return Type.POINTER;
} else {
throw new IllegalArgumentException("Unsupported return type: " + type);
}
}
private static final Type getNativeParameterType(Method method, int paramIndex, TypeMapper mapper) {
Class type = method.getParameterTypes()[paramIndex];
ToNativeConverter converter = mapper.getToNativeConverter(type);
return getNativeParameterType(converter != null ? converter.nativeType() : type);
}
private static final Type getNativeParameterType(Class type) {
if (Byte.class.isAssignableFrom(type) || byte.class == type) {
return Type.SINT8;
} else if (Short.class.isAssignableFrom(type) || short.class == type) {
return Type.SINT16;
} else if (Integer.class.isAssignableFrom(type) || int.class == type) {
return Type.SINT32;
} else if (Long.class.isAssignableFrom(type) || long.class == type) {
return Type.SINT64;
} else if (NativeLong.class.isAssignableFrom(type)) {
return Platform.getPlatform().longSize() == 32 ? Type.SINT32: Type.SINT64;
} else if (Float.class.isAssignableFrom(type) || float.class == type) {
return Type.FLOAT;
} else if (Double.class.isAssignableFrom(type) || double.class == type) {
return Type.DOUBLE;
} else if (Boolean.class.isAssignableFrom(type) || boolean.class == type) {
return Type.SINT32;
} else if (Enum.class.isAssignableFrom(type)) {
return Type.SINT32;
} else if (Pointer.class.isAssignableFrom(type)) {
return Type.POINTER;
} else if (Struct.class.isAssignableFrom(type) || type.isArray() && Struct.class.isAssignableFrom(type.getComponentType())) {
return Type.POINTER;
} else if (Buffer.class.isAssignableFrom(type)) {
return Type.POINTER;
} else if (CharSequence.class.isAssignableFrom(type)) {
return Type.POINTER;
} else if (ByReference.class.isAssignableFrom(type)) {
return Type.POINTER;
} else if (type.isArray()) {
return Type.POINTER;
} else {
throw new IllegalArgumentException("Unsupported parameter type: " + type);
}
}
static final int getParameterFlags(Method method, int paramIndex) {
return getParameterFlags(method.getParameterAnnotations()[paramIndex]);
}
static final int getParameterFlags(Annotation[] annotations) {
return ParameterFlags.parse(annotations);
}
static final int getNativeArrayFlags(int flags) {
int nflags = 0;
nflags |= ParameterFlags.isIn(flags) ? com.kenai.jffi.ArrayFlags.IN : 0;
nflags |= ParameterFlags.isOut(flags) ? com.kenai.jffi.ArrayFlags.OUT : 0;
nflags |= ParameterFlags.isNulTerminate(flags) ? com.kenai.jffi.ArrayFlags.NULTERMINATE : 0;
return nflags;
}
static final int getNativeArrayFlags(Annotation[] annotations) {
return getNativeArrayFlags(getParameterFlags(annotations));
}
static final Marshaller getMarshaller(Method method, int paramIndex, TypeMapper mapper) {
Class type = method.getParameterTypes()[paramIndex];
ToNativeConverter converter = mapper != null ? mapper.getToNativeConverter(type) : null;
if (converter != null) {
return new ToNativeConverterMarshaller(converter,
getMarshaller(converter.nativeType(), method.getParameterAnnotations()[paramIndex]));
} else {
return getMarshaller(method, paramIndex);
}
}
static final Marshaller getMarshaller(Method method, int paramIndex) {
return getMarshaller(method.getParameterTypes()[paramIndex],
method.getParameterAnnotations()[paramIndex]);
}
static final Marshaller getMarshaller(Class type, Annotation[] annotations) {
if (Byte.class.isAssignableFrom(type) || byte.class == type) {
return Int8Marshaller.INSTANCE;
} else if (Short.class.isAssignableFrom(type) || short.class == type) {
return Int16Marshaller.INSTANCE;
} else if (Integer.class.isAssignableFrom(type) || int.class == type) {
return Int32Marshaller.INSTANCE;
} else if (Long.class.isAssignableFrom(type) || long.class == type) {
return Int64Marshaller.INSTANCE;
} else if (NativeLong.class.isAssignableFrom(type)) {
return Platform.getPlatform().longSize() == 32
? Int32Marshaller.INSTANCE : Int64Marshaller.INSTANCE;
} else if (Float.class.isAssignableFrom(type) || float.class == type) {
return Float32Marshaller.INSTANCE;
} else if (Double.class.isAssignableFrom(type) || double.class == type) {
return Float64Marshaller.INSTANCE;
} else if (Boolean.class.isAssignableFrom(type) || boolean.class == type) {
return BooleanMarshaller.INSTANCE;
} else if (Enum.class.isAssignableFrom(type)) {
return EnumMarshaller.INSTANCE;
} else if (Pointer.class.isAssignableFrom(type)) {
return PointerMarshaller.INSTANCE;
} else if (StringBuffer.class.isAssignableFrom(type)) {
return new StringBufferMarshaller(getParameterFlags(annotations));
} else if (StringBuilder.class.isAssignableFrom(type)) {
return new StringBuilderMarshaller(getParameterFlags(annotations));
} else if (CharSequence.class.isAssignableFrom(type)) {
return CharSequenceMarshaller.INSTANCE;
} else if (ByReference.class.isAssignableFrom(type)) {
return new ByReferenceMarshaller(getParameterFlags(annotations));
} else if (Struct.class.isAssignableFrom(type)) {
return new StructMarshaller(getParameterFlags(annotations));
} else if (ByteBuffer.class.isAssignableFrom(type)) {
return new ByteBufferMarshaller(getParameterFlags(annotations));
} else if (ShortBuffer.class.isAssignableFrom(type)) {
return new ShortBufferMarshaller(getParameterFlags(annotations));
} else if (IntBuffer.class.isAssignableFrom(type)) {
return new IntBufferMarshaller(getParameterFlags(annotations));
} else if (LongBuffer.class.isAssignableFrom(type)) {
return new LongBufferMarshaller(getParameterFlags(annotations));
} else if (FloatBuffer.class.isAssignableFrom(type)) {
return new FloatBufferMarshaller(getParameterFlags(annotations));
} else if (DoubleBuffer.class.isAssignableFrom(type)) {
return new DoubleBufferMarshaller(getParameterFlags(annotations));
} else if (type.isArray() && type.getComponentType() == byte.class) {
return new ByteArrayMarshaller(getParameterFlags(annotations));
} else if (type.isArray() && type.getComponentType() == short.class) {
return new ShortArrayMarshaller(getParameterFlags(annotations));
} else if (type.isArray() && type.getComponentType() == int.class) {
return new IntArrayMarshaller(getParameterFlags(annotations));
} else if (type.isArray() && type.getComponentType() == long.class) {
return new LongArrayMarshaller(getParameterFlags(annotations));
} else if (type.isArray() && type.getComponentType() == float.class) {
return new FloatArrayMarshaller(getParameterFlags(annotations));
} else if (type.isArray() && type.getComponentType() == double.class) {
return new DoubleArrayMarshaller(getParameterFlags(annotations));
} else if (type.isArray() && Struct.class.isAssignableFrom(type.getComponentType())) {
return new StructArrayMarshaller(getParameterFlags(annotations));
} else {
throw new IllegalArgumentException("Unsupported parameter type: " + type);
}
}
static final class SessionInvoker implements com.kenai.jaffl.provider.Invoker {
static final com.kenai.jffi.Invoker invoker = com.kenai.jffi.Invoker.getInstance();
final Function function;
final FunctionInvoker functionInvoker;
final Marshaller[] marshallers;
SessionInvoker(Function function, FunctionInvoker invoker, Marshaller[] marshallers) {
this.function = function;
this.functionInvoker = invoker;
this.marshallers = marshallers;
}
final HeapInvocationBuffer marshal(InvocationSession session, Object[] parameters) {
HeapInvocationBuffer buffer = new HeapInvocationBuffer(function);
for (int i = 0; i < parameters.length; ++i) {
marshallers[i].marshal(session, buffer, parameters[i]);
}
return buffer;
}
public final Object invoke(Object[] parameters) {
InvocationSession session = new InvocationSession();
Object retVal = functionInvoker.invoke(function, marshal(session, parameters));
session.finish();
return retVal;
}
}
static final class DefaultInvoker implements com.kenai.jaffl.provider.Invoker {
final Function function;
final FunctionInvoker functionInvoker;
final Marshaller[] marshallers;
DefaultInvoker(Function function, FunctionInvoker invoker, Marshaller[] marshallers) {
this.function = function;
this.functionInvoker = invoker;
this.marshallers = marshallers;
}
final HeapInvocationBuffer marshal(Object[] parameters) {
HeapInvocationBuffer buffer = new HeapInvocationBuffer(function);
for (int i = 0; i < parameters.length; ++i) {
marshallers[i].marshal(buffer, parameters[i]);
}
return buffer;
}
public final Object invoke(Object[] parameters) {
return functionInvoker.invoke(function, marshal(parameters));
}
}
static interface Marshaller {
abstract boolean isSessionRequired();
abstract void marshal(InvocationSession session, InvocationBuffer buffer, Object parameter);
abstract void marshal(InvocationBuffer buffer, Object parameter);
}
static interface FunctionInvoker {
Object invoke(Function function, HeapInvocationBuffer buffer);
}
static abstract class BaseMarshaller implements Marshaller {
public boolean isSessionRequired() { return false; }
public void marshal(InvocationSession session, InvocationBuffer buffer, Object parameter) {
marshal(buffer, parameter);
}
}
static abstract class BaseInvoker implements FunctionInvoker {
static final com.kenai.jffi.Invoker invoker = com.kenai.jffi.Invoker.getInstance();
}
static final class ConvertingInvoker extends BaseInvoker {
private final FromNativeConverter converter;
private final FromNativeContext context;
private final FunctionInvoker nativeInvoker;
public ConvertingInvoker(FromNativeConverter converter, FromNativeContext context, FunctionInvoker nativeInvoker) {
this.converter = converter;
this.context = context;
this.nativeInvoker = nativeInvoker;
}
public final Object invoke(Function function, HeapInvocationBuffer buffer) {
return converter.fromNative(nativeInvoker.invoke(function, buffer), context);
}
}
static final class VoidInvoker extends BaseInvoker {
static final FunctionInvoker INSTANCE = new VoidInvoker();
public final Object invoke(Function function, HeapInvocationBuffer buffer) {
invoker.invokeInt(function, buffer);
return null;
}
}
static final class BooleanInvoker extends BaseInvoker {
static final FunctionInvoker INSTANCE = new BooleanInvoker();
public final Object invoke(Function function, HeapInvocationBuffer buffer) {
return Boolean.valueOf(invoker.invokeInt(function, buffer) != 0);
}
}
static final class EnumInvoker extends BaseInvoker {
private final Class enumClass;
private EnumInvoker(Class enumClass) {
this.enumClass = enumClass;
}
@SuppressWarnings("unchecked")
public final Object invoke(Function function, HeapInvocationBuffer buffer) {
return EnumMapper.getInstance().valueOf(invoker.invokeInt(function, buffer), enumClass);
}
}
static final class Int8Invoker extends BaseInvoker {
static final FunctionInvoker INSTANCE = new Int8Invoker();
public final Object invoke(Function function, HeapInvocationBuffer buffer) {
return Byte.valueOf((byte) invoker.invokeInt(function, buffer));
}
}
static final class Int16Invoker extends BaseInvoker {
static final FunctionInvoker INSTANCE = new Int16Invoker();
public final Object invoke(Function function, HeapInvocationBuffer buffer) {
return Short.valueOf((short) invoker.invokeInt(function, buffer));
}
}
static final class Int32Invoker extends BaseInvoker {
static final FunctionInvoker INSTANCE = new Int32Invoker();
public final Object invoke(Function function, HeapInvocationBuffer buffer) {
return Integer.valueOf(invoker.invokeInt(function, buffer));
}
}
static final class Int64Invoker extends BaseInvoker {
static final FunctionInvoker INSTANCE = new Int64Invoker();
public final Object invoke(Function function, HeapInvocationBuffer buffer) {
return Long.valueOf(invoker.invokeLong(function, buffer));
}
}
static final class NativeLong32Invoker extends BaseInvoker {
static final FunctionInvoker INSTANCE = new NativeLong32Invoker();
public final Object invoke(Function function, HeapInvocationBuffer buffer) {
return NativeLong.valueOf(invoker.invokeInt(function, buffer));
}
}
static final class NativeLong64Invoker extends BaseInvoker {
static final FunctionInvoker INSTANCE = new NativeLong64Invoker();
public final Object invoke(Function function, HeapInvocationBuffer buffer) {
return NativeLong.valueOf(invoker.invokeLong(function, buffer));
}
}
static final class Float32Invoker extends BaseInvoker {
static final FunctionInvoker INSTANCE = new Float32Invoker();
public final Object invoke(Function function, HeapInvocationBuffer buffer) {
return invoker.invokeFloat(function, buffer);
}
}
static final class Float64Invoker extends BaseInvoker {
static final FunctionInvoker INSTANCE = new Float64Invoker();
public final Object invoke(Function function, HeapInvocationBuffer buffer) {
return invoker.invokeDouble(function, buffer);
}
}
static final class PointerInvoker extends BaseInvoker {
static final FunctionInvoker INSTANCE = new PointerInvoker();
public final Object invoke(Function function, HeapInvocationBuffer buffer) {
return MemoryUtil.newPointer(invoker.invokeAddress(function, buffer));
}
}
static final class StructInvoker extends BaseInvoker {
private final Class structClass;
public StructInvoker(Class structClass) {
this.structClass = structClass;
}
public final Object invoke(Function function, HeapInvocationBuffer buffer) {
final long ptr = invoker.invokeAddress(function, buffer);
if (ptr == 0L) {
return null;
}
try {
Struct s = (Struct) structClass.newInstance();
s.useMemory(new DirectMemoryIO(ptr));
return s;
} catch (Throwable t) {
throw new RuntimeException(t);
}
}
}
static final class StringInvoker extends BaseInvoker {
com.kenai.jffi.MemoryIO IO = com.kenai.jffi.MemoryIO.getInstance();
static final FunctionInvoker INSTANCE = new StringInvoker();
public final Object invoke(Function function, HeapInvocationBuffer buffer) {
final long ptr = invoker.invokeAddress(function, buffer);
if (ptr == 0) {
return null;
}
final ByteBuffer buf = ByteBuffer.wrap(IO.getZeroTerminatedByteArray(ptr));
return StringIO.getStringIO().fromNative(buf).toString();
}
}
/* ---------------------------------------------------------------------- */
static final class BooleanMarshaller extends BaseMarshaller {
static final Marshaller INSTANCE = new BooleanMarshaller();
public void marshal(InvocationBuffer buffer, Object parameter) {
buffer.putInt(((Boolean) parameter).booleanValue() ? 1 : 0);
}
}
static final class EnumMarshaller extends BaseMarshaller {
static final Marshaller INSTANCE = new EnumMarshaller();
public void marshal(InvocationBuffer buffer, Object parameter) {
buffer.putInt(EnumMapper.getInstance().intValue((Enum) parameter));
}
}
static final class Int8Marshaller extends BaseMarshaller {
static final Marshaller INSTANCE = new Int8Marshaller();
public void marshal(InvocationBuffer buffer, Object parameter) {
buffer.putByte(((Number) parameter).intValue());
}
}
static final class Int16Marshaller extends BaseMarshaller {
static final Marshaller INSTANCE = new Int16Marshaller();
public void marshal(InvocationBuffer buffer, Object parameter) {
buffer.putShort(((Number) parameter).intValue());
}
}
static final class Int32Marshaller extends BaseMarshaller {
static final Marshaller INSTANCE = new Int32Marshaller();
public void marshal(InvocationBuffer buffer, Object parameter) {
buffer.putInt(((Number) parameter).intValue());
}
}
static final class Int64Marshaller extends BaseMarshaller {
static final Marshaller INSTANCE = new Int64Marshaller();
public void marshal(InvocationBuffer buffer, Object parameter) {
buffer.putLong(((Number) parameter).longValue());
}
}
static final class Float32Marshaller extends BaseMarshaller {
static final Marshaller INSTANCE = new Float32Marshaller();
public void marshal(InvocationBuffer buffer, Object parameter) {
buffer.putFloat(((Number) parameter).floatValue());
}
}
static final class Float64Marshaller extends BaseMarshaller {
static final Marshaller INSTANCE = new Float64Marshaller();
public void marshal(InvocationBuffer buffer, Object parameter) {
buffer.putDouble(((Number) parameter).doubleValue());
}
}
static final class PointerMarshaller extends BaseMarshaller {
static final Marshaller INSTANCE = new PointerMarshaller();
public void marshal(InvocationBuffer buffer, Object parameter) {
buffer.putAddress(((Pointer) parameter).address());
}
}
static final class CharSequenceMarshaller extends BaseMarshaller {
static final Marshaller INSTANCE = new CharSequenceMarshaller();
public void marshal(InvocationBuffer buffer, Object parameter) {
AsmRuntime.marshal(buffer, (CharSequence) parameter);
}
}
static abstract class SessionRequiredMarshaller extends BaseMarshaller {
@Override
public final boolean isSessionRequired() {
return true;
}
public void marshal(InvocationBuffer buffer, Object parameter) {
throw new UnsupportedOperationException("Cannot marshal this type without session");
}
}
static final class StringBuilderMarshaller extends SessionRequiredMarshaller {
private final int nflags, inout;
public StringBuilderMarshaller(int inout) {
this.inout = inout;
this.nflags = getNativeArrayFlags(inout | (ParameterFlags.isIn(inout) ? ParameterFlags.NULTERMINATE : 0));
}
@Override
public void marshal(InvocationSession session, InvocationBuffer buffer, Object parameter) {
AsmRuntime.marshal(session, buffer, (StringBuilder) parameter, inout, nflags);
}
}
static final class StringBufferMarshaller extends SessionRequiredMarshaller {
private final int nflags, inout;
public StringBufferMarshaller(int inout) {
this.inout = inout;
this.nflags = getNativeArrayFlags(inout | (ParameterFlags.isIn(inout) ? ParameterFlags.NULTERMINATE : 0));
}
@Override
public void marshal(InvocationSession session, InvocationBuffer buffer, Object parameter) {
AsmRuntime.marshal(session, buffer, (StringBuffer) parameter, inout, nflags);
}
}
static final class ByteArrayMarshaller extends BaseMarshaller {
private final int flags;
public ByteArrayMarshaller(int flags) {
this.flags = getNativeArrayFlags(flags | (ParameterFlags.isIn(flags) ? ParameterFlags.NULTERMINATE : 0));
}
public final void marshal(InvocationBuffer buffer, Object parameter) {
AsmRuntime.marshal(buffer, byte[].class.cast(parameter), flags);
}
}
static final class ShortArrayMarshaller extends BaseMarshaller {
private final int flags;
public ShortArrayMarshaller(int flags) {
this.flags = getNativeArrayFlags(flags);
}
public final void marshal(InvocationBuffer buffer, Object parameter) {
AsmRuntime.marshal(buffer, short[].class.cast(parameter), flags);
}
}
static final class IntArrayMarshaller extends BaseMarshaller {
private final int flags;
public IntArrayMarshaller(int flags) {
this.flags = getNativeArrayFlags(flags);
}
public final void marshal(InvocationBuffer buffer, Object parameter) {
AsmRuntime.marshal(buffer, int[].class.cast(parameter), flags);
}
}
static final class LongArrayMarshaller extends BaseMarshaller {
private final int flags;
public LongArrayMarshaller(int flags) {
this.flags = getNativeArrayFlags(flags);
}
public final void marshal(InvocationBuffer buffer, Object parameter) {
AsmRuntime.marshal(buffer, long[].class.cast(parameter), flags);
}
}
static final class FloatArrayMarshaller extends BaseMarshaller {
private final int flags;
public FloatArrayMarshaller(int flags) {
this.flags = getNativeArrayFlags(flags);
}
public final void marshal(InvocationBuffer buffer, Object parameter) {
AsmRuntime.marshal(buffer, float[].class.cast(parameter), flags);
}
}
static final class DoubleArrayMarshaller extends BaseMarshaller {
private final int flags;
public DoubleArrayMarshaller(int flags) {
this.flags = getNativeArrayFlags(flags);
}
public final void marshal(InvocationBuffer buffer, Object parameter) {
AsmRuntime.marshal(buffer, double[].class.cast(parameter), flags);
}
}
static final class ByteBufferMarshaller extends BaseMarshaller {
private final int flags;
public ByteBufferMarshaller(int flags) {
this.flags = getNativeArrayFlags(flags | (ParameterFlags.isIn(flags) ? ParameterFlags.NULTERMINATE : 0));
}
public final void marshal(InvocationBuffer buffer, Object parameter) {
AsmRuntime.marshal(buffer, (ByteBuffer) parameter, flags);
}
}
static final class ShortBufferMarshaller extends BaseMarshaller {
private final int flags;
public ShortBufferMarshaller(int flags) {
this.flags = getNativeArrayFlags(flags);
}
public final void marshal(InvocationBuffer buffer, Object parameter) {
AsmRuntime.marshal(buffer, (ShortBuffer) parameter, flags);
}
}
static final class IntBufferMarshaller extends BaseMarshaller {
private final int flags;
public IntBufferMarshaller(int flags) {
this.flags = getNativeArrayFlags(flags);
}
public final void marshal(InvocationBuffer buffer, Object parameter) {
AsmRuntime.marshal(buffer, (IntBuffer) parameter, flags);
}
}
static final class LongBufferMarshaller extends BaseMarshaller {
private final int flags;
public LongBufferMarshaller(int flags) {
this.flags = getNativeArrayFlags(flags);
}
public final void marshal(InvocationBuffer buffer, Object parameter) {
AsmRuntime.marshal(buffer, (LongBuffer) parameter, flags);
}
}
static final class FloatBufferMarshaller extends BaseMarshaller {
private final int flags;
public FloatBufferMarshaller(int flags) {
this.flags = getNativeArrayFlags(flags);
}
public final void marshal(InvocationBuffer buffer, Object parameter) {
AsmRuntime.marshal(buffer, (FloatBuffer) parameter, flags);
}
}
static final class DoubleBufferMarshaller extends BaseMarshaller {
private final int flags;
public DoubleBufferMarshaller(int flags) {
this.flags = getNativeArrayFlags(flags);
}
public final void marshal(InvocationBuffer buffer, Object parameter) {
AsmRuntime.marshal(buffer, (DoubleBuffer) parameter, flags);
}
}
static final class ByReferenceMarshaller extends SessionRequiredMarshaller {
private final int flags;
public ByReferenceMarshaller(int flags) {
this.flags = getNativeArrayFlags(flags);
}
@Override
public final void marshal(InvocationSession session, InvocationBuffer buffer, Object parameter) {
AsmRuntime.marshal(session, buffer, (ByReference) parameter, flags);
}
}
static final class StructMarshaller extends BaseMarshaller {
private final int nflags, flags;
public StructMarshaller(int flags) {
this.flags = flags;
this.nflags = getNativeArrayFlags(flags);
}
public final void marshal(InvocationBuffer buffer, Object parameter) {
AsmRuntime.marshal(buffer, (Struct) parameter, flags, nflags);
}
}
static final class StructArrayMarshaller extends BaseMarshaller {
private final int nflags, flags;
public StructArrayMarshaller(int flags) {
this.flags = flags;
this.nflags = getNativeArrayFlags(flags);
}
public final void marshal(InvocationBuffer buffer, Object parameter) {
AsmRuntime.marshal(buffer, Struct[].class.cast(parameter), flags, nflags);
}
}
static final class ToNativeConverterMarshaller extends BaseMarshaller {
private final ToNativeConverter converter;
private final ToNativeContext context = null;
private final Marshaller marshaller;
public ToNativeConverterMarshaller(ToNativeConverter converter, Marshaller marshaller) {
this.converter = converter;
this.marshaller = marshaller;
}
public void marshal(InvocationBuffer buffer, Object parameter) {
marshaller.marshal(buffer, converter.toNative(parameter, context));
}
@Override
public boolean isSessionRequired() {
return marshaller.isSessionRequired();
}
@Override
public void marshal(InvocationSession session, InvocationBuffer buffer, Object parameter) {
marshaller.marshal(session, buffer, converter.toNative(parameter, context));
}
}
}
jaffl-0.5.9/src/com/kenai/jaffl/provider/jffi/DirectMemoryIO.java 0000664 0000000 0000000 00000012347 12017475436 0024613 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.provider.jffi;
import com.kenai.jaffl.Address;
import com.kenai.jaffl.MemoryIO;
import com.kenai.jaffl.Pointer;
import com.kenai.jaffl.provider.AbstractMemoryIO;
import com.kenai.jaffl.provider.NullMemoryIO;
import com.kenai.jaffl.provider.StringIO;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
class DirectMemoryIO extends AbstractMemoryIO {
static final com.kenai.jffi.MemoryIO IO = com.kenai.jffi.MemoryIO.getInstance();
protected final long address;
DirectMemoryIO(long address) {
this.address = address & Address.MASK;
}
public final long address() {
return address;
}
public final byte getByte(long offset) {
return IO.getByte(address + offset);
}
public final short getShort(long offset) {
return IO.getShort(address + offset);
}
public final int getInt(long offset) {
return IO.getInt(address + offset);
}
public final long getLong(long offset) {
return IO.getLong(address + offset);
}
public final float getFloat(long offset) {
return IO.getFloat(address + offset);
}
public final double getDouble(long offset) {
return IO.getDouble(address + offset);
}
public final void putByte(long offset, byte value) {
IO.putByte(address + offset, value);
}
public final void putShort(long offset, short value) {
IO.putShort(address + offset, value);
}
public final void putInt(long offset, int value) {
IO.putInt(address + offset, value);
}
public final void putLong(long offset, long value) {
IO.putLong(address + offset, value);
}
public final void putFloat(long offset, float value) {
IO.putFloat(address + offset, value);
}
public final void putDouble(long offset, double value) {
IO.putDouble(address + offset, value);
}
public final void get(long offset, byte[] dst, int off, int len) {
IO.getByteArray(address + offset, dst, off, len);
}
public final void put(long offset, byte[] src, int off, int len) {
IO.putByteArray(address + offset, src, off, len);
}
public final void get(long offset, short[] dst, int off, int len) {
IO.getShortArray(address + offset, dst, off, len);
}
public final void put(long offset, short[] src, int off, int len) {
IO.putShortArray(address + offset, src, off, len);
}
public final void get(long offset, int[] dst, int off, int len) {
IO.getIntArray(address + offset, dst, off, len);
}
public final void put(long offset, int[] src, int off, int len) {
IO.putIntArray(address + offset, src, off, len);
}
public final void get(long offset, long[] dst, int off, int len) {
IO.getLongArray(address + offset, dst, off, len);
}
public final void put(long offset, long[] src, int off, int len) {
IO.putLongArray(address + offset, src, off, len);
}
public final void get(long offset, float[] dst, int off, int len) {
IO.getFloatArray(address + offset, dst, off, len);
}
public final void put(long offset, float[] src, int off, int len) {
IO.putFloatArray(address + offset, src, off, len);
}
public final void get(long offset, double[] dst, int off, int len) {
IO.getDoubleArray(address + offset, dst, off, len);
}
public final void put(long offset, double[] src, int off, int len) {
IO.putDoubleArray(address + offset, src, off, len);
}
public MemoryIO getMemoryIO(long offset) {
return MemoryUtil.newMemoryIO(IO.getAddress(address + offset));
}
public MemoryIO getMemoryIO(long offset, long size) {
final long ptr = IO.getAddress(this.address + offset);
return ptr != 0 ? new BoundedDirectMemoryIO(new DirectMemoryIO(ptr), 0, size) : new NullMemoryIO();
}
@Override
public Pointer getPointer(long offset) {
return MemoryUtil.newPointer(IO.getAddress(address + offset));
}
@Override
public void putPointer(long offset, Pointer value) {
IO.putAddress(address + offset, value.address());
}
@Override
public String getString(long offset) {
final byte[] bytes = IO.getZeroTerminatedByteArray(address + offset);
return StringIO.getStringIO().fromNative(ByteBuffer.wrap(bytes)).toString();
}
@Override
public String getString(long offset, int maxLength, Charset cs) {
byte[] bytes = IO.getZeroTerminatedByteArray(address + offset, maxLength);
final ByteBuffer buf = ByteBuffer.wrap(bytes);
return StringIO.getStringIO().fromNative(buf).toString();
}
@Override
public void putString(long offset, String string, int maxLength, Charset cs) {
ByteBuffer buf = StringIO.getStringIO().toNative(string, 0, true);
IO.putByteArray(address + offset, buf.array(), buf.arrayOffset() + buf.position(), buf.remaining());
}
public int indexOf(long offset, byte value, int maxlen) {
return (int) IO.indexOf(address + offset, value, maxlen);
}
public final boolean isDirect() {
return true;
}
public final void setMemory(long offset, long size, byte value) {
IO.setMemory(this.address + offset, size, value);
}
}
jaffl-0.5.9/src/com/kenai/jaffl/provider/jffi/EnumResultConverter.java 0000664 0000000 0000000 00000001206 12017475436 0025743 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.provider.jffi;
import com.kenai.jaffl.mapper.FromNativeContext;
import com.kenai.jaffl.mapper.FromNativeConverter;
import com.kenai.jaffl.util.EnumMapper;
public class EnumResultConverter implements FromNativeConverter {
private final Class enumClass;
EnumResultConverter(Class enumClass) {
this.enumClass = enumClass;
}
@SuppressWarnings("unchecked")
public Object fromNative(Object nativeValue, FromNativeContext context) {
return EnumMapper.getInstance().valueOf(((Integer) nativeValue), enumClass);
}
public Class nativeType() {
return Integer.class;
}
}
jaffl-0.5.9/src/com/kenai/jaffl/provider/jffi/IdentityFunctionMapper.java 0000664 0000000 0000000 00000001123 12017475436 0026412 0 ustar 00root root 0000000 0000000 package com.kenai.jaffl.provider.jffi;
import com.kenai.jaffl.mapper.FunctionMapper;
/**
* An implementation of {@link FunctionMapper} that just returns the same name as input
*/
public class IdentityFunctionMapper implements FunctionMapper {
private static final class SingletonHolder {
public static final FunctionMapper INSTANCE = new IdentityFunctionMapper();
}
public static FunctionMapper getInstance() {
return SingletonHolder.INSTANCE;
}
public String mapFunctionName(String functionName, Context context) {
return functionName;
}
}
jaffl-0.5.9/src/com/kenai/jaffl/provider/jffi/InvokerFactory.java 0000664 0000000 0000000 00000000565 12017475436 0024724 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.provider.jffi;
import com.kenai.jaffl.LibraryOption;
import com.kenai.jaffl.provider.Invoker;
import java.lang.reflect.Method;
import java.util.Map;
public interface InvokerFactory {
Invoker createInvoker(Method method, com.kenai.jaffl.provider.Library library, Map options);
boolean isMethodSupported(Method method);
}
jaffl-0.5.9/src/com/kenai/jaffl/provider/jffi/InvokerUtil.java 0000664 0000000 0000000 00000012631 12017475436 0024227 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.provider.jffi;
import com.kenai.jaffl.Address;
import com.kenai.jaffl.LibraryOption;
import com.kenai.jaffl.NativeLong;
import com.kenai.jaffl.Platform;
import com.kenai.jaffl.Pointer;
import com.kenai.jaffl.annotations.IgnoreError;
import com.kenai.jaffl.annotations.SaveError;
import com.kenai.jaffl.byref.ByReference;
import com.kenai.jaffl.struct.Struct;
import com.kenai.jffi.Type;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.nio.Buffer;
import java.util.Map;
final class InvokerUtil {
static final Type getNativeReturnType(Method method) {
return getNativeReturnType(method.getReturnType());
}
static final Type getNativeReturnType(Class type) {
if (Void.class.isAssignableFrom(type) || void.class == type) {
return Type.VOID;
} else if (Boolean.class.isAssignableFrom(type) || boolean.class == type) {
return Type.SINT32;
} else if (Byte.class.isAssignableFrom(type) || byte.class == type) {
return Type.SINT8;
} else if (Short.class.isAssignableFrom(type) || short.class == type) {
return Type.SINT16;
} else if (Integer.class.isAssignableFrom(type) || int.class == type) {
return Type.SINT32;
} else if (Long.class.isAssignableFrom(type) || long.class == type) {
return Type.SINT64;
} else if (NativeLong.class.isAssignableFrom(type)) {
return Platform.getPlatform().longSize() == 32 ? Type.SINT32: Type.SINT64;
} else if (Float.class.isAssignableFrom(type) || float.class == type) {
return Type.FLOAT;
} else if (Double.class.isAssignableFrom(type) || double.class == type) {
return Type.DOUBLE;
} else if (Enum.class.isAssignableFrom(type)) {
return Type.SINT32;
} else if (Pointer.class.isAssignableFrom(type)) {
return Type.POINTER;
} else if (Address.class.isAssignableFrom(type)) {
return Type.POINTER;
} else if (Struct.class.isAssignableFrom(type)) {
return Type.POINTER;
} else if (String.class.isAssignableFrom(type)) {
return Type.POINTER;
} else {
throw new IllegalArgumentException("Unsupported return type: " + type);
}
}
static final Type getNativeParameterType(Class type) {
if (Byte.class.isAssignableFrom(type) || byte.class == type) {
return Type.SINT8;
} else if (Short.class.isAssignableFrom(type) || short.class == type) {
return Type.SINT16;
} else if (Integer.class.isAssignableFrom(type) || int.class == type) {
return Type.SINT32;
} else if (Long.class.isAssignableFrom(type) || long.class == type) {
return Type.SINT64;
} else if (NativeLong.class.isAssignableFrom(type)) {
return Platform.getPlatform().longSize() == 32 ? Type.SINT32: Type.SINT64;
} else if (Float.class.isAssignableFrom(type) || float.class == type) {
return Type.FLOAT;
} else if (Double.class.isAssignableFrom(type) || double.class == type) {
return Type.DOUBLE;
} else if (Boolean.class.isAssignableFrom(type) || boolean.class == type) {
return Type.SINT32;
} else if (Enum.class.isAssignableFrom(type)) {
return Type.SINT32;
} else if (Pointer.class.isAssignableFrom(type)) {
return Type.POINTER;
} else if (Address.class.isAssignableFrom(type)) {
return Type.POINTER;
} else if (Struct.class.isAssignableFrom(type)) {
return Type.POINTER;
} else if (Buffer.class.isAssignableFrom(type)) {
return Type.POINTER;
} else if (CharSequence.class.isAssignableFrom(type)) {
return Type.POINTER;
} else if (ByReference.class.isAssignableFrom(type)) {
return Type.POINTER;
} else if (type.isArray()) {
return Type.POINTER;
} else {
throw new IllegalArgumentException("Unsupported parameter type: " + type);
}
}
public static final boolean requiresErrno(Method method) {
boolean saveError = true;
for (Annotation a : method.getAnnotations()) {
if (a instanceof IgnoreError) {
saveError = false;
} else if (a instanceof SaveError) {
saveError = true;
}
}
return saveError;
}
public static final com.kenai.jffi.CallingConvention getCallingConvention(Map libraryOptions) {
Object convention = (com.kenai.jaffl.CallingConvention) libraryOptions.get(LibraryOption.CallingConvention);
// If someone passed in the jffi calling convention, just use it.
if (convention instanceof com.kenai.jffi.CallingConvention) {
return (com.kenai.jffi.CallingConvention) convention;
}
if (convention instanceof com.kenai.jaffl.CallingConvention) switch ((com.kenai.jaffl.CallingConvention) convention) {
case DEFAULT:
return com.kenai.jffi.CallingConvention.DEFAULT;
case STDCALL:
return com.kenai.jffi.CallingConvention.STDCALL;
} else if (convention != null) {
throw new IllegalArgumentException("unknown calling convention: " + convention);
}
return com.kenai.jffi.CallingConvention.DEFAULT;
}
}
jaffl-0.5.9/src/com/kenai/jaffl/provider/jffi/JFFIPointer.java 0000664 0000000 0000000 00000001224 12017475436 0024027 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.provider.jffi;
final class JFFIPointer extends DirectMemoryIO {
JFFIPointer(long address) {
super(address);
}
public int intValue() {
return (int) address;
}
public long longValue() {
return address;
}
public float floatValue() {
return (float) address;
}
public double doubleValue() {
return (double) address;
}
public static final JFFIPointer valueOf(long address) {
return new JFFIPointer(address);
}
public static final JFFIPointer valueOf(int address) {
return new JFFIPointer(address & 0xffffffffL);
}
}
jaffl-0.5.9/src/com/kenai/jaffl/provider/jffi/JNIInvokeInterface.java 0000664 0000000 0000000 00000000561 12017475436 0025370 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.provider.jffi;
/**
* Indexes of JavaVM methods
*/
public class JNIInvokeInterface {
public static final int DestroyJavaVM = 3;
public static final int AttachCurrentThread = 4;
public static final int DetachCurrentThread = 5;
public static final int GetEnv = 6;
public static final int AttachCurrentThreadAsDaemon = 7;
}
jaffl-0.5.9/src/com/kenai/jaffl/provider/jffi/JNINativeInterface.java 0000664 0000000 0000000 00000031116 12017475436 0025363 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.provider.jffi;
/**
*
* WARNING: Highly experimental!!!
*
* This class contains constants that are the indexes withing the JNINativeInterface_
* struct of each of the JNIEnv functions. To invoke one of the functions, the
* index _must_ be multiplied by sizeof(void *), then used as an index into the table.
*
* These indexes are valid on both 32bit and 64bit linux and macos. Win32 also
* seems to be the same. Other platforms may be completely different.
*/
public final class JNINativeInterface {
private JNINativeInterface() {
}
public static final int GetVersion = 4;
public static final int DefineClass = 5;
public static final int FindClass = 6;
public static final int FromReflectedMethod = 7;
public static final int FromReflectedField = 8;
public static final int ToReflectedMethod = 9;
public static final int GetSuperclass = 10;
public static final int IsAssignableFrom = 11;
public static final int ToReflectedField = 12;
public static final int Throw = 13;
public static final int ThrowNew = 14;
public static final int ExceptionOccurred = 15;
public static final int ExceptionDescribe = 16;
public static final int ExceptionClear = 17;
public static final int FatalError = 18;
public static final int PushLocalFrame = 19;
public static final int PopLocalFrame = 20;
public static final int NewGlobalRef = 21;
public static final int DeleteGlobalRef = 22;
public static final int DeleteLocalRef = 23;
public static final int IsSameObject = 24;
public static final int NewLocalRef = 25;
public static final int EnsureLocalCapacity = 26;
public static final int AllocObject = 27;
public static final int NewObject = 28;
public static final int NewObjectV = 29;
public static final int NewObjectA = 30;
public static final int GetObjectClass = 31;
public static final int IsInstanceOf = 32;
public static final int GetMethodID = 33;
public static final int CallObjectMethod = 34;
public static final int CallObjectMethodV = 35;
public static final int CallObjectMethodA = 36;
public static final int CallBooleanMethod = 37;
public static final int CallBooleanMethodV = 38;
public static final int CallBooleanMethodA = 39;
public static final int CallByteMethod = 40;
public static final int CallByteMethodV = 41;
public static final int CallByteMethodA = 42;
public static final int CallCharMethod = 43;
public static final int CallCharMethodV = 44;
public static final int CallCharMethodA = 45;
public static final int CallShortMethod = 46;
public static final int CallShortMethodV = 47;
public static final int CallShortMethodA = 48;
public static final int CallIntMethod = 49;
public static final int CallIntMethodV = 50;
public static final int CallIntMethodA = 51;
public static final int CallLongMethod = 52;
public static final int CallLongMethodV = 53;
public static final int CallLongMethodA = 54;
public static final int CallFloatMethod = 55;
public static final int CallFloatMethodV = 56;
public static final int CallFloatMethodA = 57;
public static final int CallDoubleMethod = 58;
public static final int CallDoubleMethodV = 59;
public static final int CallDoubleMethodA = 60;
public static final int CallVoidMethod = 61;
public static final int CallVoidMethodV = 62;
public static final int CallVoidMethodA = 63;
public static final int CallNonvirtualObjectMethod = 64;
public static final int CallNonvirtualObjectMethodV = 65;
public static final int CallNonvirtualObjectMethodA = 66;
public static final int CallNonvirtualBooleanMethod = 67;
public static final int CallNonvirtualBooleanMethodV = 68;
public static final int CallNonvirtualBooleanMethodA = 69;
public static final int CallNonvirtualByteMethod = 70;
public static final int CallNonvirtualByteMethodV = 71;
public static final int CallNonvirtualByteMethodA = 72;
public static final int CallNonvirtualCharMethod = 73;
public static final int CallNonvirtualCharMethodV = 74;
public static final int CallNonvirtualCharMethodA = 75;
public static final int CallNonvirtualShortMethod = 76;
public static final int CallNonvirtualShortMethodV = 77;
public static final int CallNonvirtualShortMethodA = 78;
public static final int CallNonvirtualIntMethod = 79;
public static final int CallNonvirtualIntMethodV = 80;
public static final int CallNonvirtualIntMethodA = 81;
public static final int CallNonvirtualLongMethod = 82;
public static final int CallNonvirtualLongMethodV = 83;
public static final int CallNonvirtualLongMethodA = 84;
public static final int CallNonvirtualFloatMethod = 85;
public static final int CallNonvirtualFloatMethodV = 86;
public static final int CallNonvirtualFloatMethodA = 87;
public static final int CallNonvirtualDoubleMethod = 88;
public static final int CallNonvirtualDoubleMethodV = 89;
public static final int CallNonvirtualDoubleMethodA = 90;
public static final int CallNonvirtualVoidMethod = 91;
public static final int CallNonvirtualVoidMethodV = 92;
public static final int CallNonvirtualVoidMethodA = 93;
public static final int GetFieldID = 94;
public static final int GetObjectField = 95;
public static final int GetBooleanField = 96;
public static final int GetByteField = 97;
public static final int GetCharField = 98;
public static final int GetShortField = 99;
public static final int GetIntField = 100;
public static final int GetLongField = 101;
public static final int GetFloatField = 102;
public static final int GetDoubleField = 103;
public static final int SetObjectField = 104;
public static final int SetBooleanField = 105;
public static final int SetByteField = 106;
public static final int SetCharField = 107;
public static final int SetShortField = 108;
public static final int SetIntField = 109;
public static final int SetLongField = 110;
public static final int SetFloatField = 111;
public static final int SetDoubleField = 112;
public static final int GetStaticMethodID = 113;
public static final int CallStaticObjectMethod = 114;
public static final int CallStaticObjectMethodV = 115;
public static final int CallStaticObjectMethodA = 116;
public static final int CallStaticBooleanMethod = 117;
public static final int CallStaticBooleanMethodV = 118;
public static final int CallStaticBooleanMethodA = 119;
public static final int CallStaticByteMethod = 120;
public static final int CallStaticByteMethodV = 121;
public static final int CallStaticByteMethodA = 122;
public static final int CallStaticCharMethod = 123;
public static final int CallStaticCharMethodV = 124;
public static final int CallStaticCharMethodA = 125;
public static final int CallStaticShortMethod = 126;
public static final int CallStaticShortMethodV = 127;
public static final int CallStaticShortMethodA = 128;
public static final int CallStaticIntMethod = 129;
public static final int CallStaticIntMethodV = 130;
public static final int CallStaticIntMethodA = 131;
public static final int CallStaticLongMethod = 132;
public static final int CallStaticLongMethodV = 133;
public static final int CallStaticLongMethodA = 134;
public static final int CallStaticFloatMethod = 135;
public static final int CallStaticFloatMethodV = 136;
public static final int CallStaticFloatMethodA = 137;
public static final int CallStaticDoubleMethod = 138;
public static final int CallStaticDoubleMethodV = 139;
public static final int CallStaticDoubleMethodA = 140;
public static final int CallStaticVoidMethod = 141;
public static final int CallStaticVoidMethodV = 142;
public static final int CallStaticVoidMethodA = 143;
public static final int GetStaticFieldID = 144;
public static final int GetStaticObjectField = 145;
public static final int GetStaticBooleanField = 146;
public static final int GetStaticByteField = 147;
public static final int GetStaticCharField = 148;
public static final int GetStaticShortField = 149;
public static final int GetStaticIntField = 150;
public static final int GetStaticLongField = 151;
public static final int GetStaticFloatField = 152;
public static final int GetStaticDoubleField = 153;
public static final int SetStaticObjectField = 154;
public static final int SetStaticBooleanField = 155;
public static final int SetStaticByteField = 156;
public static final int SetStaticCharField = 157;
public static final int SetStaticShortField = 158;
public static final int SetStaticIntField = 159;
public static final int SetStaticLongField = 160;
public static final int SetStaticFloatField = 161;
public static final int SetStaticDoubleField = 162;
public static final int NewString = 163;
public static final int GetStringLength = 164;
public static final int GetStringChars = 165;
public static final int ReleaseStringChars = 166;
public static final int NewStringUTF = 167;
public static final int GetStringUTFLength = 168;
public static final int GetStringUTFChars = 169;
public static final int ReleaseStringUTFChars = 170;
public static final int GetArrayLength = 171;
public static final int NewObjectArray = 172;
public static final int GetObjectArrayElement = 173;
public static final int SetObjectArrayElement = 174;
public static final int NewBooleanArray = 175;
public static final int NewByteArray = 176;
public static final int NewCharArray = 177;
public static final int NewShortArray = 178;
public static final int NewIntArray = 179;
public static final int NewLongArray = 180;
public static final int NewFloatArray = 181;
public static final int NewDoubleArray = 182;
public static final int GetBooleanArrayElements = 183;
public static final int GetByteArrayElements = 184;
public static final int GetCharArrayElements = 185;
public static final int GetShortArrayElements = 186;
public static final int GetIntArrayElements = 187;
public static final int GetLongArrayElements = 188;
public static final int GetFloatArrayElements = 189;
public static final int GetDoubleArrayElements = 190;
public static final int ReleaseBooleanArrayElements = 191;
public static final int ReleaseByteArrayElements = 192;
public static final int ReleaseCharArrayElements = 193;
public static final int ReleaseShortArrayElements = 194;
public static final int ReleaseIntArrayElements = 195;
public static final int ReleaseLongArrayElements = 196;
public static final int ReleaseFloatArrayElements = 197;
public static final int ReleaseDoubleArrayElements = 198;
public static final int GetBooleanArrayRegion = 199;
public static final int GetByteArrayRegion = 200;
public static final int GetCharArrayRegion = 201;
public static final int GetShortArrayRegion = 202;
public static final int GetIntArrayRegion = 203;
public static final int GetLongArrayRegion = 204;
public static final int GetFloatArrayRegion = 205;
public static final int GetDoubleArrayRegion = 206;
public static final int SetBooleanArrayRegion = 207;
public static final int SetByteArrayRegion = 208;
public static final int SetCharArrayRegion = 209;
public static final int SetShortArrayRegion = 210;
public static final int SetIntArrayRegion = 211;
public static final int SetLongArrayRegion = 212;
public static final int SetFloatArrayRegion = 213;
public static final int SetDoubleArrayRegion = 214;
public static final int RegisterNatives = 215;
public static final int UnregisterNatives = 216;
public static final int MonitorEnter = 217;
public static final int MonitorExit = 218;
public static final int GetJavaVM = 219;
public static final int GetStringRegion = 220;
public static final int GetStringUTFRegion = 221;
public static final int GetPrimitiveArrayCritical = 222;
public static final int ReleasePrimitiveArrayCritical = 223;
public static final int GetStringCritical = 224;
public static final int ReleaseStringCritical = 225;
public static final int NewWeakGlobalRef = 226;
public static final int DeleteWeakGlobalRef = 227;
public static final int ExceptionCheck = 228;
public static final int NewDirectByteBuffer = 229;
public static final int GetDirectBufferAddress = 230;
public static final int GetDirectBufferCapacity = 231;
public static final int GetObjectRefType = 232;
};
jaffl-0.5.9/src/com/kenai/jaffl/provider/jffi/Library.java 0000664 0000000 0000000 00000005036 12017475436 0023361 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.provider.jffi;
import com.kenai.jaffl.LibraryOption;
import com.kenai.jaffl.provider.Invoker;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
public class Library extends com.kenai.jaffl.provider.Library {
private final String[] libraryNames;
private volatile List nativeLibraries = Collections.EMPTY_LIST;
Library(String name) {
this.libraryNames = new String[] { name };
}
Library(String... names) {
this.libraryNames = (String[]) names.clone();
}
public Invoker getInvoker(Method method, Map options) {
return DefaultInvokerFactory.getInstance().createInvoker(method, this, options);
}
public Object libraryLock() {
return this;
}
long getSymbolAddress(String name) {
for (com.kenai.jffi.Library l : getNativeLibraries()) {
long address = l.getSymbolAddress(name);
if (address != 0) {
return address;
}
}
return 0;
}
long findSymbolAddress(String name) {
long address = getSymbolAddress(name);
if (address == 0) {
throw new SymbolNotFoundError(com.kenai.jffi.Library.getLastError());
}
return address;
}
private synchronized List getNativeLibraries() {
if (!this.nativeLibraries.isEmpty()) {
return nativeLibraries;
}
return nativeLibraries = loadNativeLibraries();
}
private synchronized List loadNativeLibraries() {
List libs = new ArrayList();
List errors = new ArrayList(0);
for (String libraryName : libraryNames) {
com.kenai.jffi.Library lib;
lib = com.kenai.jffi.Library.getCachedInstance(libraryName, com.kenai.jffi.Library.LAZY);
if (lib == null) {
String path;
if (libraryName != null && (path = locateLibrary(libraryName)) != null && !libraryName.equals(path)) {
lib = com.kenai.jffi.Library.getCachedInstance(path, com.kenai.jffi.Library.LAZY);
}
}
if (lib == null) {
throw new UnsatisfiedLinkError(com.kenai.jffi.Library.getLastError());
}
libs.add(lib);
}
return Collections.unmodifiableList(libs);
}
}
jaffl-0.5.9/src/com/kenai/jaffl/provider/jffi/LibraryLoader.java 0000664 0000000 0000000 00000000545 12017475436 0024510 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.provider.jffi;
import com.kenai.jaffl.LibraryOption;
import java.util.Map;
public abstract class LibraryLoader {
abstract T loadLibrary(Library library, Class interfaceClass, Map libraryOptions);
abstract boolean isInterfaceSupported(Class interfaceClass, Map libraryOptions);
}
jaffl-0.5.9/src/com/kenai/jaffl/provider/jffi/MemoryManager.java 0000664 0000000 0000000 00000002653 12017475436 0024522 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.provider.jffi;
import com.kenai.jaffl.MemoryIO;
import com.kenai.jaffl.Pointer;
import java.nio.Buffer;
import java.nio.ByteBuffer;
public class MemoryManager implements com.kenai.jaffl.provider.MemoryManager {
public MemoryIO allocate(int size) {
return new ArrayMemoryIO(size);
}
public MemoryIO allocateDirect(int size) {
return new BoundedDirectMemoryIO(new AllocatedDirectMemoryIO(size, false), 0, size);
}
public MemoryIO allocateDirect(int size, boolean clear) {
return new BoundedDirectMemoryIO(new AllocatedDirectMemoryIO(size, clear), 0, size);
}
public MemoryIO wrap(Pointer ptr) {
if (ptr instanceof MemoryIO) {
return (MemoryIO) ptr;
} else if (ptr.isDirect()) {
return MemoryUtil.newMemoryIO(ptr.address());
}
throw new UnsupportedOperationException("Unsupported Pointer type: " + ptr.getClass());
}
public MemoryIO wrap(Pointer ptr, int size) {
if (ptr.isDirect()) {
return MemoryUtil.newMemoryIO(ptr.address(), size);
}
throw new UnsupportedOperationException("Unsupported Pointer type: " + ptr.getClass());
}
public MemoryIO wrap(ByteBuffer buffer) {
return new ByteBufferMemoryIO(buffer);
}
public Pointer getBufferPointer(Buffer buffer) {
throw new UnsupportedOperationException("Not supported yet.");
}
}
jaffl-0.5.9/src/com/kenai/jaffl/provider/jffi/MemoryUtil.java 0000664 0000000 0000000 00000002075 12017475436 0024063 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.provider.jffi;
import com.kenai.jaffl.MemoryIO;
import com.kenai.jaffl.provider.NullMemoryIO;
public final class MemoryUtil {
private MemoryUtil() {}
static final com.kenai.jaffl.Pointer newPointer(long ptr) {
return ptr != 0 ? new DirectMemoryIO(ptr) : null;
}
static final com.kenai.jaffl.MemoryIO newMemoryIO(long ptr) {
return ptr != 0 ? new DirectMemoryIO(ptr) : NullMemoryIO.INSTANCE;
}
static final com.kenai.jaffl.MemoryIO newMemoryIO(long ptr, long size) {
return ptr != 0 ? new BoundedDirectMemoryIO(new DirectMemoryIO(ptr), 0, size) : NullMemoryIO.INSTANCE;
}
static final long getAddress(MemoryIO ptr) {
if (ptr == null) {
return 0L;
} else if (ptr instanceof JFFIPointer) {
return ((JFFIPointer) ptr).address;
} else if (ptr instanceof DirectMemoryIO) {
return ((DirectMemoryIO) ptr).address;
}
throw new IllegalArgumentException("attempted to get address of non-direct memory. " + ptr.getClass());
}
}
jaffl-0.5.9/src/com/kenai/jaffl/provider/jffi/NullTypeMapper.java 0000664 0000000 0000000 00000001072 12017475436 0024672 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.provider.jffi;
import com.kenai.jaffl.mapper.FromNativeConverter;
import com.kenai.jaffl.mapper.ToNativeConverter;
import com.kenai.jaffl.mapper.TypeMapper;
/**
* An instance of {@link TypeMapper} which always returns null
*/
public class NullTypeMapper implements TypeMapper {
public static final TypeMapper INSTANCE = new NullTypeMapper();
public FromNativeConverter getFromNativeConverter(Class type) {
return null;
}
public ToNativeConverter getToNativeConverter(Class type) {
return null;
}
}
jaffl-0.5.9/src/com/kenai/jaffl/provider/jffi/NumberUtil.java 0000664 0000000 0000000 00000006046 12017475436 0024045 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.provider.jffi;
import com.kenai.jaffl.NativeLong;
public final class NumberUtil {
private NumberUtil() {}
static final Class getBoxedClass(Class c) {
if (!c.isPrimitive()) {
return c;
}
if (void.class == c) {
return Void.class;
} else if (byte.class == c) {
return Byte.class;
} else if (char.class == c) {
return Character.class;
} else if (short.class == c) {
return Short.class;
} else if (int.class == c) {
return Integer.class;
} else if (long.class == c) {
return Long.class;
} else if (float.class == c) {
return Float.class;
} else if (double.class == c) {
return Double.class;
} else if (boolean.class == c) {
return Boolean.class;
} else {
throw new IllegalArgumentException("unknown primitive class");
}
}
static final Class getPrimitiveClass(Class c) {
if (Void.class == c) {
return void.class;
} else if (Boolean.class == c) {
return boolean.class;
} else if (Byte.class == c) {
return byte.class;
} else if (Character.class == c) {
return char.class;
} else if (Short.class == c) {
return short.class;
} else if (Integer.class == c) {
return int.class;
} else if (Long.class == c) {
return long.class;
} else if (Float.class == c) {
return float.class;
} else if (Double.class == c) {
return double.class;
} else if (NativeLong.class == c) {
return long.class;
} else if (c.isPrimitive()) {
return c;
} else {
throw new IllegalArgumentException("unsupported number class");
}
}
public static boolean isPrimitiveInt(Class c) {
return byte.class == c || short.class == c || int.class == c || boolean.class == c;
}
public static final void widen(SkinnyMethodAdapter mv, Class from, Class to) {
if (long.class == to && long.class != from && isPrimitiveInt(from)) {
mv.i2l();
}
}
public static final void narrow(SkinnyMethodAdapter mv, Class from, Class to) {
if (!from.equals(to)) {
if (byte.class == to || short.class == to || char.class == to || int.class == to || boolean.class == to) {
if (long.class == from) {
mv.l2i();
}
if (byte.class == to) {
mv.i2b();
} else if (short.class == to) {
mv.i2s();
} else if (char.class == to) {
mv.i2c();
} else if (boolean.class == to) {
// Ensure only 0x0 and 0x1 values are used for boolean
mv.iconst_1();
mv.iand();
}
}
}
}
}
jaffl-0.5.9/src/com/kenai/jaffl/provider/jffi/Provider.java 0000664 0000000 0000000 00000007612 12017475436 0023551 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.provider.jffi;
import com.kenai.jaffl.LibraryOption;
import com.kenai.jaffl.provider.MemoryManager;
import com.kenai.jaffl.provider.NativeType;
import com.kenai.jffi.LastError;
import java.util.Map;
public class Provider extends com.kenai.jaffl.FFIProvider {
private final MemoryManager memoryManager = new com.kenai.jaffl.provider.jffi.MemoryManager();
@Override
public MemoryManager getMemoryManager() {
return memoryManager;
}
@Override
public T loadLibrary(String libraryName, Class interfaceClass, Map libraryOptions) {
return loadLibrary(new Library(libraryName), interfaceClass, libraryOptions);
}
@Override
public T loadLibrary(Class interfaceClass, Map libraryOptions, String... libraryNames) {
return loadLibrary(new Library(libraryNames), interfaceClass, libraryOptions);
}
private T loadLibrary(Library library, Class interfaceClass, Map libraryOptions) {
try {
if (AsmLibraryLoader.getInstance().isInterfaceSupported(interfaceClass, libraryOptions)) {
return AsmLibraryLoader.getInstance().loadLibrary(library, interfaceClass, libraryOptions);
}
} catch (Exception ex) {
ex.printStackTrace(System.err);
}
return ProxyLibraryLoader.getInstance().loadLibrary(library, interfaceClass, libraryOptions);
}
@Override
public int getLastError() {
return LastError.getInstance().get();
}
@Override
public void setLastError(int error) {
LastError.getInstance().set(error);
}
private static final class TypeDelegate implements com.kenai.jaffl.Type {
private final com.kenai.jffi.Type type;
public TypeDelegate(com.kenai.jffi.Type type) {
this.type = type;
}
public int alignment() {
return type.alignment();
}
public int size() {
return type.size();
}
}
private static final class BadType implements com.kenai.jaffl.Type {
private final NativeType type;
public BadType(NativeType type) {
this.type = type;
}
public int alignment() {
throw new RuntimeException("invalid type: " + type);
}
public int size() {
throw new RuntimeException("invalid type: " + type);
}
}
@Override
public com.kenai.jaffl.Type getType(NativeType type) {
switch (type) {
case VOID:
return new TypeDelegate(com.kenai.jffi.Type.VOID);
case SCHAR:
return new TypeDelegate(com.kenai.jffi.Type.SCHAR);
case UCHAR:
return new TypeDelegate(com.kenai.jffi.Type.UCHAR);
case SSHORT:
return new TypeDelegate(com.kenai.jffi.Type.SSHORT);
case USHORT:
return new TypeDelegate(com.kenai.jffi.Type.USHORT);
case SINT:
return new TypeDelegate(com.kenai.jffi.Type.SINT);
case UINT:
return new TypeDelegate(com.kenai.jffi.Type.UINT);
case SLONG:
return new TypeDelegate(com.kenai.jffi.Type.SLONG);
case ULONG:
return new TypeDelegate(com.kenai.jffi.Type.ULONG);
case SLONGLONG:
return new TypeDelegate(com.kenai.jffi.Type.SINT64);
case ULONGLONG:
return new TypeDelegate(com.kenai.jffi.Type.UINT64);
case FLOAT:
return new TypeDelegate(com.kenai.jffi.Type.FLOAT);
case DOUBLE:
return new TypeDelegate(com.kenai.jffi.Type.DOUBLE);
case ADDRESS:
return new TypeDelegate(com.kenai.jffi.Type.POINTER);
default:
return new BadType(type);
}
}
}
jaffl-0.5.9/src/com/kenai/jaffl/provider/jffi/ProxyLibraryLoader.java 0000664 0000000 0000000 00000001312 12017475436 0025543 0 ustar 00root root 0000000 0000000 package com.kenai.jaffl.provider.jffi;
import com.kenai.jaffl.LibraryOption;
import com.kenai.jaffl.provider.NativeInvocationHandler;
import java.util.Map;
class ProxyLibraryLoader extends LibraryLoader {
private static final LibraryLoader INSTANCE = new ProxyLibraryLoader();
static final LibraryLoader getInstance() {
return INSTANCE;
}
T loadLibrary(Library library, Class interfaceClass, Map libraryOptions) {
return interfaceClass.cast(NativeInvocationHandler.wrapInterface(library, interfaceClass, libraryOptions));
}
boolean isInterfaceSupported(Class interfaceClass, Map libraryOptions) {
return true;
}
}
jaffl-0.5.9/src/com/kenai/jaffl/provider/jffi/SkinnyMethodAdapter.java 0000664 0000000 0000000 00000056700 12017475436 0025676 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.provider.jffi;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.util.Map;
import static com.kenai.jaffl.provider.jffi.CodegenUtils.*;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
/**
*
* @author headius
*/
public class SkinnyMethodAdapter implements MethodVisitor, Opcodes {
private final static boolean DEBUG = Boolean.getBoolean("jaffl.compile.dump");
private MethodVisitor method;
/** Creates a new instance of SkinnyMethodAdapter */
public SkinnyMethodAdapter(MethodVisitor method) {
setMethodVisitor(method);
}
public SkinnyMethodAdapter() {
}
public MethodVisitor getMethodVisitor() {
return method;
}
public void setMethodVisitor(MethodVisitor mv) {
this.method = DEBUG ? AsmUtil.newTraceMethodVisitor(mv) : mv;
}
public void aload(int arg0) {
getMethodVisitor().visitVarInsn(ALOAD, arg0);
}
public void aload(int... args) {
for (int arg : args) {
getMethodVisitor().visitVarInsn(ALOAD, arg);
}
}
public void iload(int arg0) {
getMethodVisitor().visitVarInsn(ILOAD, arg0);
}
public void iload(int... args) {
for (int arg : args) {
getMethodVisitor().visitVarInsn(ILOAD, arg);
}
}
public void lload(int arg0) {
getMethodVisitor().visitVarInsn(LLOAD, arg0);
}
public void lload(int... args) {
for (int arg : args) {
getMethodVisitor().visitVarInsn(LLOAD, arg);
}
}
public void fload(int arg0) {
getMethodVisitor().visitVarInsn(FLOAD, arg0);
}
public void fload(int... args) {
for (int arg : args) {
getMethodVisitor().visitVarInsn(FLOAD, arg);
}
}
public void dload(int arg0) {
getMethodVisitor().visitVarInsn(DLOAD, arg0);
}
public void dload(int... args) {
for (int arg : args) {
getMethodVisitor().visitVarInsn(DLOAD, arg);
}
}
public void astore(int arg0) {
getMethodVisitor().visitVarInsn(ASTORE, arg0);
}
public void istore(int arg0) {
getMethodVisitor().visitVarInsn(ISTORE, arg0);
}
public void lstore(int arg0) {
getMethodVisitor().visitVarInsn(LSTORE, arg0);
}
public void fstore(int arg0) {
getMethodVisitor().visitVarInsn(FSTORE, arg0);
}
public void dstore(int arg0) {
getMethodVisitor().visitVarInsn(DSTORE, arg0);
}
public void ldc(Object arg0) {
getMethodVisitor().visitLdcInsn(arg0);
}
public void bipush(int arg) {
getMethodVisitor().visitIntInsn(BIPUSH, arg);
}
public void sipush(int arg) {
getMethodVisitor().visitIntInsn(SIPUSH, arg);
}
public void pushInt(int value) {
if (value <= Byte.MAX_VALUE && value >= Byte.MIN_VALUE) {
switch (value) {
case -1:
iconst_m1();
break;
case 0:
iconst_0();
break;
case 1:
iconst_1();
break;
case 2:
iconst_2();
break;
case 3:
iconst_3();
break;
case 4:
iconst_4();
break;
case 5:
iconst_5();
break;
default:
bipush(value);
break;
}
} else if (value <= Short.MAX_VALUE && value >= Short.MIN_VALUE) {
sipush(value);
} else {
ldc(value);
}
}
public void pushBoolean(boolean bool) {
if (bool) iconst_1(); else iconst_0();
}
public void invokestatic(String arg1, String arg2, String arg3) {
getMethodVisitor().visitMethodInsn(INVOKESTATIC, arg1, arg2, arg3);
}
public void invokestatic(Class recv, String methodName, Class returnType, Class... parameterTypes) {
getMethodVisitor().visitMethodInsn(INVOKESTATIC, p(recv), methodName, sig(returnType, parameterTypes));
}
public void invokespecial(String arg1, String arg2, String arg3) {
getMethodVisitor().visitMethodInsn(INVOKESPECIAL, arg1, arg2, arg3);
}
public void invokespecial(Class recv, String methodName, Class returnType, Class... parameterTypes) {
getMethodVisitor().visitMethodInsn(INVOKESPECIAL, p(recv), methodName, sig(returnType, parameterTypes));
}
public void invokevirtual(String arg1, String arg2, String arg3) {
getMethodVisitor().visitMethodInsn(INVOKEVIRTUAL, arg1, arg2, arg3);
}
public void invokevirtual(Class recv, String methodName, Class returnType, Class... parameterTypes) {
getMethodVisitor().visitMethodInsn(INVOKEVIRTUAL, p(recv), methodName, sig(returnType, parameterTypes));
}
public void invokeinterface(String arg1, String arg2, String arg3) {
getMethodVisitor().visitMethodInsn(INVOKEINTERFACE, arg1, arg2, arg3);
}
public void invokeinterface(Class recv, String methodName, Class returnType, Class... parameterTypes) {
getMethodVisitor().visitMethodInsn(INVOKEINTERFACE, p(recv), methodName, sig(returnType, parameterTypes));
}
public void invokedynamic(String arg1, String arg2, String arg3) {
getMethodVisitor().visitMethodInsn(INVOKEDYNAMIC, arg1, arg2, arg3);
}
public void aprintln() {
dup();
getstatic(p(System.class), "out", ci(PrintStream.class));
swap();
invokevirtual(p(PrintStream.class), "println", sig(void.class, params(Object.class)));
}
public void areturn() {
getMethodVisitor().visitInsn(ARETURN);
}
public void ireturn() {
getMethodVisitor().visitInsn(IRETURN);
}
public void freturn() {
getMethodVisitor().visitInsn(FRETURN);
}
public void lreturn() {
getMethodVisitor().visitInsn(LRETURN);
}
public void dreturn() {
getMethodVisitor().visitInsn(DRETURN);
}
public void newobj(String arg0) {
getMethodVisitor().visitTypeInsn(NEW, arg0);
}
public void dup() {
getMethodVisitor().visitInsn(DUP);
}
public void swap() {
getMethodVisitor().visitInsn(SWAP);
}
public void swap2() {
dup2_x2();
pop2();
}
public void getstatic(String arg1, String arg2, String arg3) {
getMethodVisitor().visitFieldInsn(GETSTATIC, arg1, arg2, arg3);
}
public void putstatic(String arg1, String arg2, String arg3) {
getMethodVisitor().visitFieldInsn(PUTSTATIC, arg1, arg2, arg3);
}
public void getfield(String arg1, String arg2, String arg3) {
getMethodVisitor().visitFieldInsn(GETFIELD, arg1, arg2, arg3);
}
public void putfield(String arg1, String arg2, String arg3) {
getMethodVisitor().visitFieldInsn(PUTFIELD, arg1, arg2, arg3);
}
public void voidreturn() {
getMethodVisitor().visitInsn(RETURN);
}
public void anewarray(String arg0) {
getMethodVisitor().visitTypeInsn(ANEWARRAY, arg0);
}
public void multianewarray(String arg0, int dims) {
getMethodVisitor().visitMultiANewArrayInsn(arg0, dims);
}
public void newarray(int arg0) {
getMethodVisitor().visitIntInsn(NEWARRAY, arg0);
}
public void iconst_m1() {
getMethodVisitor().visitInsn(ICONST_M1);
}
public void iconst_0() {
getMethodVisitor().visitInsn(ICONST_0);
}
public void iconst_1() {
getMethodVisitor().visitInsn(ICONST_1);
}
public void iconst_2() {
getMethodVisitor().visitInsn(ICONST_2);
}
public void iconst_3() {
getMethodVisitor().visitInsn(ICONST_3);
}
public void iconst_4() {
getMethodVisitor().visitInsn(ICONST_4);
}
public void iconst_5() {
getMethodVisitor().visitInsn(ICONST_5);
}
public void lconst_0() {
getMethodVisitor().visitInsn(LCONST_0);
}
public void aconst_null() {
getMethodVisitor().visitInsn(ACONST_NULL);
}
public void label(Label label) {
getMethodVisitor().visitLabel(label);
}
public void nop() {
getMethodVisitor().visitInsn(NOP);
}
public void pop() {
getMethodVisitor().visitInsn(POP);
}
public void pop2() {
getMethodVisitor().visitInsn(POP2);
}
public void arrayload() {
getMethodVisitor().visitInsn(AALOAD);
}
public void arraystore() {
getMethodVisitor().visitInsn(AASTORE);
}
public void iarrayload() {
getMethodVisitor().visitInsn(IALOAD);
}
public void barrayload() {
getMethodVisitor().visitInsn(BALOAD);
}
public void barraystore() {
getMethodVisitor().visitInsn(BASTORE);
}
public void aaload() {
getMethodVisitor().visitInsn(AALOAD);
}
public void aastore() {
getMethodVisitor().visitInsn(AASTORE);
}
public void iaload() {
getMethodVisitor().visitInsn(IALOAD);
}
public void iastore() {
getMethodVisitor().visitInsn(IASTORE);
}
public void laload() {
getMethodVisitor().visitInsn(LALOAD);
}
public void lastore() {
getMethodVisitor().visitInsn(LASTORE);
}
public void baload() {
getMethodVisitor().visitInsn(BALOAD);
}
public void bastore() {
getMethodVisitor().visitInsn(BASTORE);
}
public void saload() {
getMethodVisitor().visitInsn(SALOAD);
}
public void sastore() {
getMethodVisitor().visitInsn(SASTORE);
}
public void caload() {
getMethodVisitor().visitInsn(CALOAD);
}
public void castore() {
getMethodVisitor().visitInsn(CASTORE);
}
public void faload() {
getMethodVisitor().visitInsn(FALOAD);
}
public void fastore() {
getMethodVisitor().visitInsn(FASTORE);
}
public void daload() {
getMethodVisitor().visitInsn(DALOAD);
}
public void dastore() {
getMethodVisitor().visitInsn(DASTORE);
}
public void fcmpl() {
getMethodVisitor().visitInsn(FCMPL);
}
public void fcmpg() {
getMethodVisitor().visitInsn(FCMPG);
}
public void dcmpl() {
getMethodVisitor().visitInsn(DCMPL);
}
public void dcmpg() {
getMethodVisitor().visitInsn(DCMPG);
}
public void dup_x2() {
getMethodVisitor().visitInsn(DUP_X2);
}
public void dup_x1() {
getMethodVisitor().visitInsn(DUP_X1);
}
public void dup2_x2() {
getMethodVisitor().visitInsn(DUP2_X2);
}
public void dup2_x1() {
getMethodVisitor().visitInsn(DUP2_X1);
}
public void dup2() {
getMethodVisitor().visitInsn(DUP2);
}
public void trycatch(Label arg0, Label arg1, Label arg2,
String arg3) {
getMethodVisitor().visitTryCatchBlock(arg0, arg1, arg2, arg3);
}
public void trycatch(String type, Runnable body, Runnable catchBody) {
Label before = new Label();
Label after = new Label();
Label catchStart = new Label();
Label done = new Label();
trycatch(before, after, catchStart, type);
label(before);
body.run();
label(after);
go_to(done);
if (catchBody != null) {
label(catchStart);
catchBody.run();
}
label(done);
}
public void go_to(Label arg0) {
getMethodVisitor().visitJumpInsn(GOTO, arg0);
}
public void lookupswitch(Label arg0, int[] arg1, Label[] arg2) {
getMethodVisitor().visitLookupSwitchInsn(arg0, arg1, arg2);
}
public void athrow() {
getMethodVisitor().visitInsn(ATHROW);
}
public void instance_of(String arg0) {
getMethodVisitor().visitTypeInsn(INSTANCEOF, arg0);
}
public void ifeq(Label arg0) {
getMethodVisitor().visitJumpInsn(IFEQ, arg0);
}
public void iffalse(Label arg0) {
ifeq(arg0);
}
public void ifne(Label arg0) {
getMethodVisitor().visitJumpInsn(IFNE, arg0);
}
public void iftrue(Label arg0) {
ifne(arg0);
}
public void if_acmpne(Label arg0) {
getMethodVisitor().visitJumpInsn(IF_ACMPNE, arg0);
}
public void if_acmpeq(Label arg0) {
getMethodVisitor().visitJumpInsn(IF_ACMPEQ, arg0);
}
public void if_icmple(Label arg0) {
getMethodVisitor().visitJumpInsn(IF_ICMPLE, arg0);
}
public void if_icmpgt(Label arg0) {
getMethodVisitor().visitJumpInsn(IF_ICMPGT, arg0);
}
public void if_icmplt(Label arg0) {
getMethodVisitor().visitJumpInsn(IF_ICMPLT, arg0);
}
public void if_icmpne(Label arg0) {
getMethodVisitor().visitJumpInsn(IF_ICMPNE, arg0);
}
public void if_icmpeq(Label arg0) {
getMethodVisitor().visitJumpInsn(IF_ICMPEQ, arg0);
}
public void checkcast(String arg0) {
getMethodVisitor().visitTypeInsn(CHECKCAST, arg0);
}
public void start() {
getMethodVisitor().visitCode();
}
private final void dump() {
PrintWriter pw = new PrintWriter(System.out);
Class tmvClass = getMethodVisitor().getClass();
try {
Method print = tmvClass.getDeclaredMethod("print", PrintWriter.class);
pw.write("*** Dumping ***\n");
print.invoke(getMethodVisitor(), pw);
} catch (Exception ex) {
} finally {
pw.flush();
}
}
public void end() {
if (DEBUG) {
dump();
}
getMethodVisitor().visitMaxs(1, 1);
getMethodVisitor().visitEnd();
}
public void line(int line) {
Label label = new Label();
label(label);
visitLineNumber(line, label);
}
public void line(int line, Label label) {
visitLineNumber(line, label);
}
public void ifnonnull(Label arg0) {
getMethodVisitor().visitJumpInsn(IFNONNULL, arg0);
}
public void ifnull(Label arg0) {
getMethodVisitor().visitJumpInsn(IFNULL, arg0);
}
public void iflt(Label arg0) {
getMethodVisitor().visitJumpInsn(IFLT, arg0);
}
public void ifle(Label arg0) {
getMethodVisitor().visitJumpInsn(IFLE, arg0);
}
public void ifgt(Label arg0) {
getMethodVisitor().visitJumpInsn(IFGT, arg0);
}
public void ifge(Label arg0) {
getMethodVisitor().visitJumpInsn(IFGE, arg0);
}
public void arraylength() {
getMethodVisitor().visitInsn(ARRAYLENGTH);
}
public void ishr() {
getMethodVisitor().visitInsn(ISHR);
}
public void ishl() {
getMethodVisitor().visitInsn(ISHL);
}
public void iushr() {
getMethodVisitor().visitInsn(IUSHR);
}
public void lshr() {
getMethodVisitor().visitInsn(LSHR);
}
public void lshl() {
getMethodVisitor().visitInsn(LSHL);
}
public void lushr() {
getMethodVisitor().visitInsn(LUSHR);
}
public void lcmp() {
getMethodVisitor().visitInsn(LCMP);
}
public void iand() {
getMethodVisitor().visitInsn(IAND);
}
public void ior() {
getMethodVisitor().visitInsn(IOR);
}
public void ixor() {
getMethodVisitor().visitInsn(IXOR);
}
public void land() {
getMethodVisitor().visitInsn(LAND);
}
public void lor() {
getMethodVisitor().visitInsn(LOR);
}
public void lxor() {
getMethodVisitor().visitInsn(LXOR);
}
public void iadd() {
getMethodVisitor().visitInsn(IADD);
}
public void ladd() {
getMethodVisitor().visitInsn(LADD);
}
public void fadd() {
getMethodVisitor().visitInsn(FADD);
}
public void dadd() {
getMethodVisitor().visitInsn(DADD);
}
public void isub() {
getMethodVisitor().visitInsn(ISUB);
}
public void lsub() {
getMethodVisitor().visitInsn(LSUB);
}
public void fsub() {
getMethodVisitor().visitInsn(FSUB);
}
public void dsub() {
getMethodVisitor().visitInsn(DSUB);
}
public void idiv() {
getMethodVisitor().visitInsn(IDIV);
}
public void irem() {
getMethodVisitor().visitInsn(IREM);
}
public void ineg() {
getMethodVisitor().visitInsn(INEG);
}
public void i2d() {
getMethodVisitor().visitInsn(I2D);
}
public void i2l() {
getMethodVisitor().visitInsn(I2L);
}
public void i2f() {
getMethodVisitor().visitInsn(I2F);
}
public void i2s() {
getMethodVisitor().visitInsn(I2S);
}
public void i2c() {
getMethodVisitor().visitInsn(I2C);
}
public void i2b() {
getMethodVisitor().visitInsn(I2B);
}
public void ldiv() {
getMethodVisitor().visitInsn(LDIV);
}
public void lrem() {
getMethodVisitor().visitInsn(LREM);
}
public void lneg() {
getMethodVisitor().visitInsn(LNEG);
}
public void l2d() {
getMethodVisitor().visitInsn(L2D);
}
public void l2i() {
getMethodVisitor().visitInsn(L2I);
}
public void l2f() {
getMethodVisitor().visitInsn(L2F);
}
public void fdiv() {
getMethodVisitor().visitInsn(FDIV);
}
public void frem() {
getMethodVisitor().visitInsn(FREM);
}
public void fneg() {
getMethodVisitor().visitInsn(FNEG);
}
public void f2d() {
getMethodVisitor().visitInsn(F2D);
}
public void f2i() {
getMethodVisitor().visitInsn(F2D);
}
public void f2l() {
getMethodVisitor().visitInsn(F2L);
}
public void ddiv() {
getMethodVisitor().visitInsn(DDIV);
}
public void drem() {
getMethodVisitor().visitInsn(DREM);
}
public void dneg() {
getMethodVisitor().visitInsn(DNEG);
}
public void d2f() {
getMethodVisitor().visitInsn(D2F);
}
public void d2i() {
getMethodVisitor().visitInsn(D2I);
}
public void d2l() {
getMethodVisitor().visitInsn(D2L);
}
public void imul() {
getMethodVisitor().visitInsn(IMUL);
}
public void lmul() {
getMethodVisitor().visitInsn(LMUL);
}
public void fmul() {
getMethodVisitor().visitInsn(FMUL);
}
public void dmul() {
getMethodVisitor().visitInsn(DMUL);
}
public void iinc(int arg0, int arg1) {
getMethodVisitor().visitIincInsn(arg0, arg1);
}
public void monitorenter() {
getMethodVisitor().visitInsn(MONITORENTER);
}
public void monitorexit() {
getMethodVisitor().visitInsn(MONITOREXIT);
}
public void jsr(Label branch) {
getMethodVisitor().visitJumpInsn(JSR, branch);
}
public void ret(int arg0) {
getMethodVisitor().visitVarInsn(RET, arg0);
}
public AnnotationVisitor visitAnnotationDefault() {
return getMethodVisitor().visitAnnotationDefault();
}
public AnnotationVisitor visitAnnotation(String arg0, boolean arg1) {
return getMethodVisitor().visitAnnotation(arg0, arg1);
}
public AnnotationVisitor visitParameterAnnotation(int arg0, String arg1,
boolean arg2) {
return getMethodVisitor().visitParameterAnnotation(arg0, arg1, arg2);
}
public void visitAnnotationWithFields(String name, boolean visible, Map fields) {
AnnotationVisitor visitor = visitAnnotation(name, visible);
visitAnnotationFields(visitor, fields);
visitor.visitEnd();
}
public void visitParameterAnnotationWithFields(int param, String name, boolean visible, Map fields) {
AnnotationVisitor visitor = visitParameterAnnotation(param, name, visible);
visitAnnotationFields(visitor, fields);
visitor.visitEnd();
}
public void visitAttribute(Attribute arg0) {
getMethodVisitor().visitAttribute(arg0);
}
public void visitCode() {
getMethodVisitor().visitCode();
}
public void visitInsn(int arg0) {
getMethodVisitor().visitInsn(arg0);
}
public void visitIntInsn(int arg0, int arg1) {
getMethodVisitor().visitIntInsn(arg0, arg1);
}
public void visitVarInsn(int arg0, int arg1) {
getMethodVisitor().visitVarInsn(arg0, arg1);
}
public void visitTypeInsn(int arg0, String arg1) {
getMethodVisitor().visitTypeInsn(arg0, arg1);
}
public void visitFieldInsn(int arg0, String arg1, String arg2, String arg3) {
getMethodVisitor().visitFieldInsn(arg0, arg1, arg2, arg3);
}
public void visitMethodInsn(int arg0, String arg1, String arg2, String arg3) {
getMethodVisitor().visitMethodInsn(arg0, arg1, arg2, arg3);
}
public void visitJumpInsn(int arg0, Label arg1) {
getMethodVisitor().visitJumpInsn(arg0, arg1);
}
public void visitLabel(Label arg0) {
getMethodVisitor().visitLabel(arg0);
}
public void visitLdcInsn(Object arg0) {
getMethodVisitor().visitLdcInsn(arg0);
}
public void visitIincInsn(int arg0, int arg1) {
getMethodVisitor().visitIincInsn(arg0, arg1);
}
public void visitTableSwitchInsn(int arg0, int arg1, Label arg2,
Label[] arg3) {
getMethodVisitor().visitTableSwitchInsn(arg0, arg1, arg2, arg3);
}
public void visitLookupSwitchInsn(Label arg0, int[] arg1, Label[] arg2) {
getMethodVisitor().visitLookupSwitchInsn(arg0, arg1, arg2);
}
public void visitMultiANewArrayInsn(String arg0, int arg1) {
getMethodVisitor().visitMultiANewArrayInsn(arg0, arg1);
}
public void visitTryCatchBlock(Label arg0, Label arg1, Label arg2,
String arg3) {
getMethodVisitor().visitTryCatchBlock(arg0, arg1, arg2, arg3);
}
public void visitLocalVariable(String arg0, String arg1, String arg2,
Label arg3, Label arg4, int arg5) {
getMethodVisitor().visitLocalVariable(arg0, arg1, arg2, arg3, arg4, arg5);
}
public void visitLineNumber(int arg0, Label arg1) {
getMethodVisitor().visitLineNumber(arg0, arg1);
}
public void visitMaxs(int arg0, int arg1) {
if (DEBUG) {
dump();
}
getMethodVisitor().visitMaxs(arg0, arg1);
}
public void visitEnd() {
getMethodVisitor().visitEnd();
}
public void tableswitch(int min, int max, Label defaultLabel, Label[] cases) {
getMethodVisitor().visitTableSwitchInsn(min, max, defaultLabel, cases);
}
public void visitFrame(int arg0, int arg1, Object[] arg2, int arg3, Object[] arg4) {
getMethodVisitor().visitFrame(arg0, arg1, arg2, arg3, arg4);
}
}
jaffl-0.5.9/src/com/kenai/jaffl/provider/jffi/StubCompiler.java 0000664 0000000 0000000 00000006507 12017475436 0024371 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.provider.jffi;
import com.kenai.jaffl.Platform;
import com.kenai.jffi.CallingConvention;
import com.kenai.jffi.Function;
import com.kenai.jffi.Internals;
import com.kenai.jffi.PageManager;
import com.kenai.jnr.x86asm.Assembler;
import com.kenai.jnr.x86asm.CPU;
/**
* Compiles asm trampoline stubs for java class methods
*/
abstract class StubCompiler {
// If the version of jffi exports the jffi_save_errno function address,
// then it is recent enough to support PageManager and NativeMethods as well.
static final long errnoFunctionAddress = getErrnoSaveFunction();
static final boolean hasPageManager = hasPageManager();
static final boolean hasAssembler = hasAssembler();
public static final StubCompiler newCompiler() {
if (errnoFunctionAddress != 0 && hasPageManager && hasAssembler) {
switch (Platform.getPlatform().getCPU()) {
case I386:
if (Platform.getPlatform().getOS() != Platform.OS.WINDOWS) {
return new X86_32StubCompiler();
}
break;
case X86_64:
if (Platform.getPlatform().getOS() != Platform.OS.WINDOWS) {
return new X86_64StubCompiler();
}
break;
}
}
return new DummyStubCompiler();
}
abstract boolean canCompile(Class returnType, Class[] parameterTypes, CallingConvention convention);
abstract void compile(Function function, String name, Class returnType, Class[] parameterTypes, CallingConvention convention, boolean saveErrno);
abstract void attach(Class clazz);
static final class DummyStubCompiler extends StubCompiler {
@Override
boolean canCompile(Class returnType, Class[] parameterTypes, CallingConvention convention) {
return false;
}
@Override
void compile(Function function, String name, Class returnType, Class[] parameterTypes, CallingConvention convention, boolean saveErrno) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
void attach(Class clazz) {
// do nothing
}
}
private static final long getErrnoSaveFunction() {
try {
return Internals.getErrnoSaveFunction();
} catch (Throwable t) {
return 0;
}
}
private static final boolean hasPageManager() {
try {
// Just try and allocate/free a page to check the PageManager is working
long page = PageManager.getInstance().allocatePages(1, PageManager.PROT_READ | PageManager.PROT_WRITE);
PageManager.getInstance().freePages(page, 1);
return true;
} catch (Throwable t) {
return false;
}
}
private static final boolean hasAssembler() {
try {
switch (Platform.getPlatform().getCPU()) {
case I386:
new Assembler(CPU.X86_32);
return true;
case X86_64:
new Assembler(CPU.X86_64);
return true;
default:
return false;
}
} catch (Throwable t) {
return false;
}
}
}
jaffl-0.5.9/src/com/kenai/jaffl/provider/jffi/SymbolNotFoundError.java 0000664 0000000 0000000 00000000275 12017475436 0025711 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.provider.jffi;
public class SymbolNotFoundError extends java.lang.UnsatisfiedLinkError {
public SymbolNotFoundError(String msg) {
super(msg);
}
}
jaffl-0.5.9/src/com/kenai/jaffl/provider/jffi/X86_32StubCompiler.java 0000664 0000000 0000000 00000011407 12017475436 0025176 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.provider.jffi;
import com.kenai.jffi.CallingConvention;
import com.kenai.jffi.Function;
import com.kenai.jffi.Internals;
import static com.kenai.jnr.x86asm.Asm.*;
import com.kenai.jnr.x86asm.Assembler;
import static com.kenai.jaffl.provider.jffi.CodegenUtils.*;
/**
* Stub compiler for i386 unix
*/
final class X86_32StubCompiler extends AbstractX86StubCompiler {
@Override
boolean canCompile(Class returnType, Class[] parameterTypes, CallingConvention convention) {
if (returnType != byte.class && returnType != short.class && returnType != int.class
&& returnType != long.class && returnType != float.class && returnType != double.class
&& returnType != void.class) {
return false;
}
// There is only one calling convention; SYSV, so abort if someone tries to use stdcall
if (convention != CallingConvention.DEFAULT) {
return false;
}
int fCount = 0;
int iCount = 0;
for (Class t : parameterTypes) {
if (t == byte.class || t == short.class || t == int.class || t == long.class) {
++iCount;
} else if (t == float.class || t == double.class) {
++fCount;
} else {
// Fail on anything else
return false;
}
}
return true;
}
@Override
void compile(Function function, String name, Class returnType, Class[] parameterTypes, CallingConvention convention, boolean saveErrno) {
int psize = 0;
for (Class t : parameterTypes) {
if (t == byte.class || t == short.class || t == int.class || t == float.class) {
psize += 4;
} else if (t == long.class || t == double.class) {
psize += 8;
} else {
throw new IllegalArgumentException("invalid parameter type" + t);
}
}
int rsize = 0;
if (double.class == returnType || float.class == returnType) {
rsize = 16;
} else if (long.class == returnType) {
rsize = 8;
} else if (byte.class == returnType || short.class == returnType || int.class == returnType) {
rsize = 4;
} else if (void.class == returnType) {
rsize = 0;
} else {
throw new IllegalArgumentException("invalid return type " + returnType);
}
//
// JNI functions all look like:
// foo(JNIEnv* env, jobject self, arg...)
// We need to align the stack to 16 bytes, then copy all the old args
// into the new parameter space.
// It already has 4 bytes pushed (the return address) so we need to account for that.
//
final int stackadj = align(Math.max(psize, rsize) + 4, 16) - 4;
Assembler a = new Assembler(X86_32);
a.sub(esp, imm(stackadj));
// memcpy the parameters from the orig stack to the new location
for (int i = 0; i < psize; i += 4) {
a.mov(eax, dword_ptr(esp, stackadj + 4 + 8 + i));
a.mov(dword_ptr(esp, i), eax);
}
// Call to the actual native function
a.mov(eax, imm(function.getFunctionAddress()));
a.call(eax);
if (saveErrno) {
int save = 0;
if (float.class == returnType) {
a.fstp(dword_ptr(esp, save));
} else if (double.class == returnType) {
a.fstp(qword_ptr(esp, save));
} else if (long.class == returnType) {
a.mov(dword_ptr(esp, save), eax);
a.mov(dword_ptr(esp, save + 4), edx);
} else if (void.class == returnType) {
// Do nothing for void values
} else {
a.mov(dword_ptr(esp, save), eax);
}
// Save the errno in a thread-local variable
a.mov(eax, imm(errnoFunctionAddress));
a.call(eax);
// Retrieve return value and put it back in the appropriate return register
if (float.class == returnType) {
a.fld(dword_ptr(esp, save));
} else if (double.class == returnType) {
a.fld(qword_ptr(esp, save));
} else if (long.class == returnType) {
a.mov(eax, dword_ptr(esp, save));
a.mov(edx, dword_ptr(esp, save + 4));
} else if (void.class == returnType) {
// Do nothing for void values
} else {
a.mov(eax, dword_ptr(esp, save));
}
}
// Restore esp to the original position and return
a.add(esp, imm(stackadj));
a.ret();
stubs.add(new Stub(name, sig(returnType, parameterTypes), a));
}
}
jaffl-0.5.9/src/com/kenai/jaffl/provider/jffi/X86_64StubCompiler.java 0000664 0000000 0000000 00000012472 12017475436 0025206 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.provider.jffi;
import com.kenai.jffi.CallingConvention;
import com.kenai.jffi.Function;
import com.kenai.jffi.Internals;
import static com.kenai.jnr.x86asm.Asm.*;
import com.kenai.jnr.x86asm.Assembler;
import static com.kenai.jaffl.provider.jffi.CodegenUtils.*;
/**
* Compilers method trampoline stubs for x86_64
*/
final class X86_64StubCompiler extends AbstractX86StubCompiler {
@Override
final boolean canCompile(Class returnType, Class[] parameterTypes, CallingConvention convention) {
if (returnType != byte.class && returnType != short.class && returnType != int.class
&& returnType != long.class && returnType != float.class && returnType != double.class
&& returnType != void.class) {
return false;
}
// There is only one calling convention; SYSV, so abort if someone tries to use stdcall
if (convention != CallingConvention.DEFAULT) {
return false;
}
int fCount = 0;
int iCount = 0;
for (Class t : parameterTypes) {
if (t == byte.class || t == short.class || t == int.class || t == long.class) {
++iCount;
} else if (t == float.class || t == double.class) {
++fCount;
} else {
// Fail on anything else
return false;
}
}
// We can only safely compile methods with up to 6 integer and 8 floating point parameters
if (iCount > 6 || fCount > 8) {
return false;
}
return true;
}
@Override
final void compile(Function function, String name, Class returnType, Class[] parameterTypes,
CallingConvention convention, boolean saveErrno) {
int fCount = 0;
int iCount = 0;
for (Class t : parameterTypes) {
if (t == byte.class || t == short.class || t == int.class || t == long.class) {
++iCount;
} else if (t == float.class || t == double.class) {
++fCount;
} else {
throw new IllegalArgumentException("invalid parameter type");
}
}
Assembler a = new Assembler(X86_64);
//
// JNI functions all look like:
// foo(JNIEnv* env, jobject self, arg...)
// on AMD64, those sit in %rdi, %rsi, %rdx, %rcx, %r8 and %r9
// So we need to shuffle all the integer args up to over-write the
// env and self arguments
//
if (iCount > 0) {
a.mov(rdi, rdx);
}
if (iCount > 1) {
a.mov(rsi, rcx);
}
if (iCount > 2) {
a.mov(rdx, r8);
}
if (iCount > 3) {
a.mov(rcx, r9);
}
// For args 5 & 6 of the function, they would have been pushed on the stack
if (iCount > 4) {
a.mov(r8, qword_ptr(rsp, 8));
}
if (iCount > 5) {
a.mov(r9, qword_ptr(rsp, 16));
}
if (iCount > 6) {
throw new IllegalArgumentException("integer argument count > 6");
}
// All the integer registers are loaded; there nothing to do for the floating
// registers, as the first 8 args are already in xmm0..xmm7, so just sanity check
if (fCount > 8) {
throw new IllegalArgumentException("float argument count > 8");
}
if (saveErrno) {
// Need to align the stack to 16 bytes for function call.
// It already has 8 bytes pushed (the return address), so making space
// to save the return value from the function neatly aligns it to 16 bytes
int space = returnType == float.class || returnType == double.class
? 24 : 8;
a.sub(rsp, imm(space));
// Call to the actual native function
a.mov(rax, imm(function.getFunctionAddress()));
a.call(rax);
// Save the return on the stack
if (returnType == float.class) {
a.movss(dword_ptr(rsp, 0), xmm0);
} else if (returnType == double.class) {
a.movsd(qword_ptr(rsp, 0), xmm0);
} else {
a.mov(qword_ptr(rsp, 0), rax);
}
// Save the errno in a thread-local variable
a.mov(rax, imm(errnoFunctionAddress));
a.call(rax);
// Retrieve return value and put it back in the appropriate return register
if (returnType == float.class) {
a.movss(xmm0, dword_ptr(rsp, 0));
} else if (returnType == double.class) {
a.movsd(xmm0, qword_ptr(rsp, 0));
} else {
a.mov(rax, dword_ptr(rsp, 0));
}
// Restore rsp to original position
a.add(rsp, imm(space));
a.ret();
} else {
// Since there is no need to return here to save the errno, and the
// stack was not modified, we can just do a jmpq directly to the
// native function, and let it return back to the caller.
a.mov(rax, imm(function.getFunctionAddress()));
a.jmp(rax);
}
stubs.add(new Stub(name, sig(returnType, parameterTypes), a));
}
}
jaffl-0.5.9/src/com/kenai/jaffl/struct/ 0000775 0000000 0000000 00000000000 12017475436 0017662 5 ustar 00root root 0000000 0000000 jaffl-0.5.9/src/com/kenai/jaffl/struct/Struct.java 0000664 0000000 0000000 00000152521 12017475436 0022017 0 ustar 00root root 0000000 0000000 /*
* This file is covered by the license described in the LICENSE file in the root of
* the project, however, it incorporates some code from the javolution project,
* and that copyright is reproduced here.
*
* Copyright (C) 2006 - Javolution (http://javolution.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package com.kenai.jaffl.struct;
import com.kenai.jaffl.MemoryIO;
import com.kenai.jaffl.ParameterFlags;
import com.kenai.jaffl.Type;
import com.kenai.jaffl.util.EnumMapper;
import java.lang.reflect.Constructor;
import java.nio.charset.Charset;
/**
* Representation of C structures in java.
*
* Note: This class is not threadsafe.
*/
public abstract class Struct /*implements Marshallable */{
/**
* Various platform-dependent constants needed for Struct construction
*/
protected static final class Constants {
static final int LONG_SIZE = Type.SLONG.size() * 8;
static final int ADDRESS_SIZE = Type.ADDRESS.size() * 8;
static final long LONG_MASK = LONG_SIZE == 32 ? 0x7FFFFFFFL : 0x7FFFFFFFFFFFFFFFL;
static final int LONG_ALIGN = Type.SLONG.alignment() * 8;
static final int INT64_ALIGN = Type.SLONGLONG.alignment() * 8;
static final int DOUBLE_ALIGN = Type.DOUBLE.alignment() * 8;
static final int FLOAT_ALIGN = Type.FLOAT.alignment() * 8;;
}
static final class Info {
Struct enclosing = null;
int offset = 0; // offset within enclosing Struct
MemoryIO io;
int size = 0;
int minAlign = 1;
boolean isUnion = false;
boolean resetIndex = false;
public final MemoryIO getMemoryIO(int flags) {
return enclosing != null ? enclosing.__info.getMemoryIO(flags) : io != null ? io : (io = allocateMemory(flags));
}
public final MemoryIO getMemoryIO() {
return getMemoryIO(ParameterFlags.TRANSIENT);
}
final boolean isDirect() {
return (enclosing != null && enclosing.__info.isDirect()) || (io != null && io.isDirect());
}
final int size() {
return size;
}
final int getMinimumAlignment() {
return minAlign;
}
private final MemoryIO allocateMemory(int flags) {
if (ParameterFlags.isDirect(flags)) {
return MemoryIO.allocateDirect(size(), true);
} else {
return MemoryIO.allocate(size());
}
}
/*
public final Marshaller.Session marshal(Marshaller marshaller, MarshalContext context) {
final int flags = context.getFlags();
if (io == null) {
allocateMemory(flags);
} else if (!ParameterFlags.isTransient(flags) && !io.isDirect()) {
// Switching from heap memory to native memory
final ByteBuffer old = buffer;
allocateMemory(flags);
if (ParameterFlags.isIn(flags)) {
io.put(0, old.array(), old.arrayOffset(), old.capacity());
}
}
if (memory != null) {
marshaller.add(memory);
} else {
marshaller.add(buffer, context);
}
return Marshaller.EMPTY_SESSION;
}
*/
public final void useMemory(com.kenai.jaffl.MemoryIO io) {
this.io = io;
}
protected final int addField(int sizeBits, int alignBits, Offset offset) {
this.size = Math.max(this.size, offset.intValue() + (sizeBits >> 3));
this.minAlign = Math.max(this.minAlign, alignBits >> 3);
return offset.intValue();
}
protected final int addField(int sizeBits, int alignBits) {
final int mask = (alignBits >> 3) - 1;
int off = resetIndex ? 0 : this.size;
if ((off & mask) != 0) {
off = (off & ~mask) + (alignBits >> 3);
}
this.size = Math.max(this.size, off + (sizeBits >> 3));
this.minAlign = Math.max(this.minAlign, alignBits >> 3);
return off;
}
}
final Info __info = new Info();
/**
* Creates a new Struct.
*/
protected Struct() {}
/**
* Creates a new Struct.
*
* @param isUnion if this Struct is a Union
*/
Struct(final boolean isUnion) {
__info.resetIndex = isUnion;
}
/**
* Uses the specified memory address as the backing store for this structure.
*
* @param address the native memory area.
*/
public void useMemory(com.kenai.jaffl.MemoryIO address) {
__info.useMemory(address);
}
/**
* Uses the specified memory address as the backing store for this structure.
*
* @param address the native memory area.
*/
public void useMemory(com.kenai.jaffl.Pointer address) {
__info.useMemory(MemoryIO.wrap(address));
}
/**
* Returns a human readable {@link java.lang.String} representation of the structure.
*
* @return a String representation of this structure.
*/
@Override
public java.lang.String toString() {
StringBuilder sb = new StringBuilder();
java.lang.reflect.Field[] fields = getClass().getDeclaredFields();
sb.append(getClass().getSimpleName() + " { \n");
final java.lang.String fieldPrefix = " ";
for (java.lang.reflect.Field field : fields) {
try {
sb.append(fieldPrefix);
sb.append(field.getName()).append(" = ");
sb.append(field.get(this).toString());
sb.append("\n");
} catch (Throwable ex) {
throw new RuntimeException(ex);
}
}
sb.append("}\n");
return sb.toString();
}
public static final class Offset extends java.lang.Number {
private final int offset;
public Offset(int offset) {
this.offset = offset;
}
@Override
public int intValue() {
return offset;
}
@Override
public long longValue() {
return offset;
}
@Override
public float floatValue() {
return offset;
}
@Override
public double doubleValue() {
return offset;
}
}
/**
* Interface all Struct members must implement.
*/
protected interface Member {
/**
* Gets the Struct this Member is a member of.
*
* @return a Struct.
*/
Struct struct();
/**
* Gets the MemoryIO used to read/write this Member.
*
* @return a MemoryIO.
*/
MemoryIO getMemoryIO();
/**
* Gets the offset within the structure for this field.
*/
long offset();
}
/**
* Starts an array construction session
*/
protected final void arrayBegin() {
__info.resetIndex = false;
}
/**
* Ends an array construction session
*/
protected final void arrayEnd() {
__info.resetIndex = __info.isUnion;
}
/**
* Creates an array of Member instances.
*
* @param The type of the Member subclass to create.
* @param array the array to store the instances in
* @return the array that was passed in
*/
@SuppressWarnings("unchecked")
protected T[] array(T[] array) {
arrayBegin();
try {
Class> arrayClass = array.getClass().getComponentType();
Constructor> ctor = arrayClass.getDeclaredConstructor(new Class[] { arrayClass.getEnclosingClass() });
Object[] parameters = { Struct.this };
for (int i = 0; i < array.length; ++i) {
array[i] = (T) ctor.newInstance(parameters);
}
} catch (Exception ex) {
throw new RuntimeException(ex);
}
arrayEnd();
return array;
}
/**
* Creates an array of Signed8 instances.
*
* @param array the array to store the instances in
* @return the array that was passed in
*/
protected final Signed8[] array(Signed8[] array) {
arrayBegin();
for (int i = 0; i < array.length; ++i) {
array[i] = new Signed8();
}
arrayEnd();
return array;
}
/**
* Creates an array of Unsigned8 instances.
*
* @param array the array to store the instances in
* @return the array that was passed in
*/
protected final Unsigned8[] array(Unsigned8[] array) {
arrayBegin();
for (int i = 0; i < array.length; ++i) {
array[i] = new Unsigned8();
}
arrayEnd();
return array;
}
/**
* Creates an array of Signed16 instances.
*
* @param array the array to store the instances in
* @return the array that was passed in
*/
protected final Signed16[] array(Signed16[] array) {
arrayBegin();
for (int i = 0; i < array.length; ++i) {
array[i] = new Signed16();
}
arrayEnd();
return array;
}
/**
* Creates an array of Unsigned16 instances.
*
* @param array the array to store the instances in
* @return the array that was passed in
*/
protected final Unsigned16[] array(Unsigned16[] array) {
arrayBegin();
for (int i = 0; i < array.length; ++i) {
array[i] = new Unsigned16();
}
arrayEnd();
return array;
}
/**
* Creates an array of Signed32 instances.
*
* @param array the array to store the instances in
* @return the array that was passed in
*/
protected final Signed32[] array(Signed32[] array) {
arrayBegin();
for (int i = 0; i < array.length; ++i) {
array[i] = new Signed32();
}
arrayEnd();
return array;
}
/**
* Creates an array of Unsigned32 instances.
*
* @param array the array to store the instances in
* @return the array that was passed in
*/
protected final Unsigned32[] array(Unsigned32[] array) {
arrayBegin();
for (int i = 0; i < array.length; ++i) {
array[i] = new Unsigned32();
}
arrayEnd();
return array;
}
/**
* Creates an array of Signed64 instances.
*
* @param array the array to store the instances in
* @return the array that was passed in
*/
protected final Signed64[] array(Signed64[] array) {
arrayBegin();
for (int i = 0; i < array.length; ++i) {
array[i] = new Signed64();
}
arrayEnd();
return array;
}
/**
* Creates an array of Unsigned64 instances.
*
* @param array the array to store the instances in
* @return the array that was passed in
*/
protected final Unsigned64[] array(Unsigned64[] array) {
arrayBegin();
for (int i = 0; i < array.length; ++i) {
array[i] = new Unsigned64();
}
arrayEnd();
return array;
}
/**
* Creates an array of SignedLong instances.
*
* @param array the array to store the instances in
* @return the array that was passed in
*/
protected final SignedLong[] array(SignedLong[] array) {
arrayBegin();
for (int i = 0; i < array.length; ++i) {
array[i] = new SignedLong();
}
arrayEnd();
return array;
}
/**
* Creates an array of UnsignedLong instances.
*
* @param array the array to store the instances in
* @return the array that was passed in
*/
protected final UnsignedLong[] array(UnsignedLong[] array) {
arrayBegin();
for (int i = 0; i < array.length; ++i) {
array[i] = new UnsignedLong();
}
arrayEnd();
return array;
}
/**
* Creates an array of Float instances.
*
* @param array the array to store the instances in
* @return the array that was passed in
*/
protected final Float[] array(Float[] array) {
arrayBegin();
for (int i = 0; i < array.length; ++i) {
array[i] = new Float();
}
arrayEnd();
return array;
}
/**
* Creates an array of Double instances.
*
* @param array the array to store the instances in
* @return the array that was passed in
*/
protected final Double[] array(Double[] array) {
arrayBegin();
for (int i = 0; i < array.length; ++i) {
array[i] = new Double();
}
arrayEnd();
return array;
}
/**
* Creates an array of Address instances.
*
* @param array the array to store the instances in
* @return the array that was passed in
*/
protected final Address[] array(Address[] array) {
arrayBegin();
for (int i = 0; i < array.length; ++i) {
array[i] = new Address();
}
arrayEnd();
return array;
}
/**
* Creates an array of Pointer instances.
*
* @param array the array to store the instances in
* @return the array that was passed in
*/
protected final Pointer[] array(Pointer[] array) {
arrayBegin();
for (int i = 0; i < array.length; ++i) {
array[i] = new Pointer();
}
arrayEnd();
return array;
}
protected final T inner(Struct struct) {
int salign = struct.__info.getMinimumAlignment();
int off = salign + ((__info.size - 1) & ~(salign - 1));
struct.__info.enclosing = this;
struct.__info.offset = off;
__info.size = off + struct.__info.size;
return (T) struct;
}
/**
* Base implementation of Member
*/
public abstract class AbstractMember implements Member {
private final int offset;
protected AbstractMember(int size) {
this(size, size);
}
protected AbstractMember(int size, int align, Offset offset) {
this.offset = __info.addField(size, align, offset);
}
protected AbstractMember(int size, int align) {
this.offset = __info.addField(size, align);
}
protected AbstractMember(Type type) {
this.offset = __info.addField(type.size() * 8, type.alignment() * 8);
}
protected AbstractMember(Type type, Offset offset) {
this.offset = __info.addField(type.size() * 8, type.alignment() * 8, offset);
}
/**
* Gets the MemoryIO used to read/write this Member.
*
* @return a MemoryIO.
*/
public final MemoryIO getMemoryIO() {
return __info.getMemoryIO();
}
/**
* Gets the Struct this Member is a member of.
*
* @return a Struct.
*/
public final Struct struct() {
return Struct.this;
}
/**
* Gets the offset within the structure for this field.
*/
public final long offset() {
return offset + __info.offset;
}
}
/**
* Base class for Boolean fields
*/
public abstract class AbstractBoolean extends AbstractMember {
public AbstractBoolean(Type type) {
super(type);
}
protected AbstractBoolean(Type type, Offset offset) {
super(type, offset);
}
/**
* Gets the value for this field.
*
* @return a boolean.
*/
public abstract boolean get();
/**
* Sets the field to a new value.
*
* @param value The new value.
*/
public abstract void set(boolean value);
/**
* Returns a string representation of this Address
.
*
* @return a string representation of this Address
.
*/
@Override
public java.lang.String toString() {
return java.lang.Boolean.toString(get());
}
}
/**
* A normal C boolean - 1 byte in size
*/
public final class Boolean extends AbstractBoolean {
public Boolean() {
super(Type.SCHAR);
}
public final boolean get() {
return (getMemoryIO().getByte(offset()) & 0x1) != 0;
}
public final void set(boolean value) {
getMemoryIO().putByte(offset(), (byte) (value ? 1 : 0));
}
}
/**
* A Windows BOOL - 4 bytes
*/
public final class WBOOL extends AbstractBoolean {
public WBOOL() {
super(Type.SINT);
}
public final boolean get() {
return (getMemoryIO().getInt(offset()) & 0x1) != 0;
}
public final void set(boolean value) {
getMemoryIO().putInt(offset(), value ? 1 : 0);
}
}
/**
* Base class for all Number structure fields.
*/
protected abstract class NumberField extends java.lang.Number implements Member {
/**
* Offset from the start of the Struct memory this field is located at.
*/
private final int offset;
protected NumberField(int size) {
this(size, size);
}
protected NumberField(int size, Offset offset) {
this(size, size, offset);
}
protected NumberField(int size, int align, Offset offset) {
this.offset = __info.addField(size, align, offset);
}
protected NumberField(int size, int align) {
this.offset = __info.addField(size, align);
}
/**
* Gets the MemoryIO used to read/write this Member.
*
* @return a MemoryIO.
*/
public final MemoryIO getMemoryIO() {
return __info.getMemoryIO();
}
/**
* Gets the Struct this Member is in.
*
* @return a Struct.
*/
public final Struct struct() {
return Struct.this;
}
/**
* Gets the offset within the structure for this field.
*/
public final long offset() {
return offset + __info.offset;
}
/**
* Sets the field to a new value.
*
* @param value The new value.
*/
public abstract void set(java.lang.Number value);
/**
* Returns an {@code float} representation of this Number.
*
* @return an {@code float} value for this Number.
*/
@Override
public double doubleValue() {
return (double) longValue();
}
/**
* Returns an {@code float} representation of this Number.
*
* @return an {@code float} value for this Number.
*/
@Override
public float floatValue() {
return (float) intValue();
}
/**
* Returns an {@code long} representation of this Number.
*
* @return an {@code long} value for this Number.
*/
@Override
public long longValue() {
return intValue();
}
/**
* Returns a string representation of this Address
.
*
* @return a string representation of this Address
.
*/
@Override
public java.lang.String toString() {
return java.lang.Integer.toString(intValue(), 10);
}
}
/**
* An 8 bit signed integer
*/
public class Signed8 extends NumberField {
/**
* Creates a new 8 bit integer field.
*/
public Signed8() {
super(8);
}
/**
* Creates a new 8 bit integer field at a specific offset
*
* @param offset The offset within the memory area
*/
public Signed8(Offset offset) {
super(8, offset);
}
/**
* Gets the value for this field.
*
* @return a byte.
*/
public final byte get() {
return getMemoryIO().getByte(offset());
}
/**
* Sets the value for this field.
*
* @param value the 8 bit value to set.
*/
public final void set(byte value) {
getMemoryIO().putByte(offset(), value);
}
public void set(java.lang.Number value) {
getMemoryIO().putByte(offset(), value.byteValue());
}
/**
* Returns a java byte representation of this field.
*
* @return a java byte value for this field.
*/
@Override
public final byte byteValue() {
return get();
}
/**
* Returns a java short representation of this field.
*
* @return a java short value for this field.
*/
@Override
public final short shortValue() {
return get();
}
/**
* Returns a java int representation of this field.
*
* @return a java int value for this field.
*/
@Override
public final int intValue() {
return get();
}
}
/**
* An 8 bit unsigned integer
*/
public class Unsigned8 extends NumberField {
/**
* Creates a new 8 bit unsigned integer field.
*/
public Unsigned8() {
super(8);
}
/**
* Creates a new 8 bit unsigned integer field at a specific offset
*
* @param offset The offset within the memory area for this field.
*/
public Unsigned8(Offset offset) {
super(8, offset);
}
/**
* Gets the value for this field.
*
* @return a byte.
*/
public final short get() {
short value = getMemoryIO().getByte(offset());
return value < 0 ? (short) ((value & 0x7F) + 0x80) : value;
}
/**
* Sets the value for this field.
*
* @param value the 8 bit value to set.
*/
public final void set(short value) {
getMemoryIO().putByte(offset(), (byte) value);
}
public void set(java.lang.Number value) {
getMemoryIO().putByte(offset(), value.byteValue());
}
/**
* Returns a java short representation of this field.
*
* @return a java short value for this field.
*/
@Override
public final short shortValue() {
return get();
}
/**
* Returns a java int representation of this field.
*
* @return a java int value for this field.
*/
@Override
public final int intValue() {
return get();
}
}
/**
* A 16 bit signed integer field.
*/
public class Signed16 extends NumberField {
/**
* Creates a new 16 bit integer field.
*/
public Signed16() {
super(16);
}
/**
* Creates a new 16 bit signed integer field at a specific offset
*
* @param offset The offset within the memory area for this field.
*/
public Signed16(Offset offset) {
super(16, offset);
}
/**
* Gets the value for this field.
*
* @return a short.
*/
public final short get() {
return getMemoryIO().getShort(offset());
}
/**
* Sets the value for this field.
*
* @param value the 16 bit value to set.
*/
public final void set(short value) {
getMemoryIO().putShort(offset(), value);
}
public void set(java.lang.Number value) {
getMemoryIO().putShort(offset(), value.shortValue());
}
/**
* Returns a java short representation of this field.
*
* @return a java short value for this field.
*/
@Override
public final short shortValue() {
return get();
}
/**
* Returns a java int representation of this field.
*
* @return a java int value for this field.
*/
@Override
public final int intValue() {
return get();
}
}
/**
* A 16 bit signed integer field.
*/
public class Unsigned16 extends NumberField {
/**
* Creates a new 16 bit integer field.
*/
public Unsigned16() {
super(16);
}
/**
* Creates a new 16 bit unsigned integer field at a specific offset
*
* @param offset The offset within the memory area for this field.
*/
public Unsigned16(Offset offset) {
super(16, offset);
}
/**
* Gets the value for this field.
*
* @return a short.
*/
public final int get() {
int value = getMemoryIO().getShort(offset());
return value < 0 ? (int)((value & 0x7FFF) + 0x8000) : value;
}
/**
* Sets the value for this field.
*
* @param value the 16 bit unsigned value to set.
*/
public final void set(int value) {
getMemoryIO().putShort(offset(), (short) value);
}
public void set(Number value) {
getMemoryIO().putShort(offset(), value.shortValue());
}
/**
* Returns a java int representation of this field.
*
* @return a java int value for this field.
*/
@Override
public final int intValue() {
return get();
}
}
/**
* A 32 bit signed integer field.
*/
public class Signed32 extends NumberField {
/**
* Creates a new 32 bit integer field.
*/
public Signed32() {
super(32);
}
/**
* Creates a new 32 bit signed integer field at a specific offset
*
* @param offset The offset within the memory area for this field.
*/
public Signed32(Offset offset) {
super(32, offset);
}
/**
* Gets the value for this field.
*
* @return a int.
*/
public final int get() {
return getMemoryIO().getInt(offset());
}
/**
* Sets the value for this field.
*
* @param value the 32 bit value to set.
*/
public final void set(int value) {
getMemoryIO().putInt(offset(), value);
}
public void set(java.lang.Number value) {
getMemoryIO().putInt(offset(), value.intValue());
}
/**
* Returns a java int representation of this field.
*
* @return a java int value for this field.
*/
@Override
public final int intValue() {
return get();
}
}
/**
* A 32 bit signed integer field.
*/
public class Unsigned32 extends NumberField {
/**
* Creates a new 32 bit integer field.
*/
public Unsigned32() {
super(32);
}
/**
* Creates a new 32 bit unsigned integer field at a specific offset
*
* @param offset The offset within the memory area for this field.
*/
public Unsigned32(Offset offset) {
super(32, offset);
}
/**
* Gets the value for this field.
*
* @return a long.
*/
public final long get() {
long value = getMemoryIO().getInt(offset());
return value < 0 ? (long)((value & 0x7FFFFFFFL) + 0x80000000L) : value;
}
/**
* Sets the value for this field.
*
* @param value the 32 bit unsigned value to set.
*/
public final void set(long value) {
getMemoryIO().putInt(offset(), (int) value);
}
public void set(java.lang.Number value) {
getMemoryIO().putInt(offset(), value.intValue());
}
/**
* Returns a java int representation of this field.
*
* @return a java int value for this field.
*/
@Override
public final int intValue() {
return (int) get();
}
/**
* Returns a java long representation of this field.
*
* @return a java long value for this field.
*/
@Override
public final long longValue() {
return get();
}
}
/**
* A 64 bit signed integer field.
*/
public class Signed64 extends NumberField {
/**
* Creates a new 64 bit integer field.
*/
public Signed64() {
super(64, Constants.INT64_ALIGN);
}
/**
* Creates a new 64 bit signed integer field at a specific offset
*
* @param offset The offset within the memory area for this field.
*/
public Signed64(Offset offset) {
super(64, Constants.INT64_ALIGN, offset);
}
/**
* Gets the value for this field.
*
* @return a long.
*/
public final long get() {
return getMemoryIO().getLong(offset());
}
/**
* Sets the value for this field.
*
* @param value the 64 bit value to set.
*/
public final void set(long value) {
getMemoryIO().putLong(offset(), value);
}
public void set(java.lang.Number value) {
getMemoryIO().putLong(offset(), value.longValue());
}
/**
* Returns a java int representation of this field.
*
* @return a java int value for this field.
*/
@Override
public final int intValue() {
return (int) get();
}
/**
* Returns a java long representation of this field.
*
* @return a java long value for this field.
*/
@Override
public final long longValue() {
return get();
}
/**
* Returns a string representation of this field.
*
* @return a string representation of this field.
*/
@Override
public final java.lang.String toString() {
return java.lang.Long.toString(get());
}
}
/**
* A 64 bit unsigned integer field.
*/
public class Unsigned64 extends NumberField {
/**
* Creates a new 64 bit integer field.
*/
public Unsigned64() {
super(64, Constants.INT64_ALIGN);
}
/**
* Creates a new 64 bit unsigned integer field at a specific offset
*
* @param offset The offset within the memory area for this field.
*/
public Unsigned64(Offset offset) {
super(64, Constants.INT64_ALIGN, offset);
}
/**
* Gets the value for this field.
*
* @return a long.
*/
public final long get() {
return getMemoryIO().getLong(offset());
}
/**
* Sets the value for this field.
*
* @param value the 64 bit value to set.
*/
public final void set(long value) {
getMemoryIO().putLong(offset(), value);
}
public void set(java.lang.Number value) {
getMemoryIO().putLong(offset(), value.longValue());
}
/**
* Returns a java int representation of this field.
*
* @return a java int value for this field.
*/
@Override
public final int intValue() {
return (int) get();
}
/**
* Returns a java long representation of this field.
*
* @return a java long value for this field.
*/
@Override
public final long longValue() {
return get();
}
/**
* Returns a string representation of this field.
*
* @return a string representation of this field.
*/
@Override
public final java.lang.String toString() {
return java.lang.Long.toString(get());
}
}
/**
* A native long integer field.
*/
public class SignedLong extends NumberField {
/**
* Creates a new native long field.
*/
public SignedLong() {
super(Constants.LONG_SIZE, Constants.LONG_ALIGN);
}
/**
* Creates a new signed native long field at a specific offset
*
* @param offset The offset within the memory area for this field.
*/
public SignedLong(Offset offset) {
super(Constants.LONG_SIZE, Constants.LONG_ALIGN, offset);
}
/**
* Gets the value for this field.
*
* @return a long.
*/
public final long get() {
return getMemoryIO().getNativeLong(offset());
}
/**
* Sets the value for this field.
*
* @param value the 32/64 bit value to set.
*/
public final void set(long value) {
getMemoryIO().putNativeLong(offset(), value);
}
public void set(java.lang.Number value) {
getMemoryIO().putNativeLong(offset(), value.longValue());
}
/**
* Returns a java int representation of this field.
*
* @return a java int value for this field.
*/
@Override
public final int intValue() {
return (int) get();
}
/**
* Returns a java long representation of this field.
*
* @return a java long value for this field.
*/
@Override
public final long longValue() {
return get();
}
/**
* Returns a string representation of this field.
*
* @return a string representation of this field.
*/
@Override
public final java.lang.String toString() {
return java.lang.Long.toString(get());
}
}
/**
* A native long integer field.
*/
public class UnsignedLong extends NumberField {
/**
* Creates a new native long field.
*/
public UnsignedLong() {
super(Constants.LONG_SIZE, Constants.LONG_ALIGN);
}
/**
* Creates a new unsigned native long field at a specific offset
*
* @param offset The offset within the memory area for this field.
*/
public UnsignedLong(Offset offset) {
super(Constants.LONG_SIZE, Constants.LONG_ALIGN, offset);
}
/**
* Gets the value for this field.
*
* @return a int.
*/
public final long get() {
long value = getMemoryIO().getNativeLong(offset());
return value < 0
? (long) ((value & Constants.LONG_MASK) + Constants.LONG_MASK + 1)
: value;
}
/**
* Sets the value for this field.
*
* @param value the 32/64 bit value to set.
*/
public final void set(long value) {
getMemoryIO().putNativeLong(offset(), value);
}
public void set(java.lang.Number value) {
getMemoryIO().putNativeLong(offset(), value.longValue());
}
/**
* Returns a java int representation of this field.
*
* @return a java int value for this field.
*/
@Override
public final int intValue() {
return (int) get();
}
/**
* Returns a java long representation of this field.
*
* @return a java long value for this field.
*/
@Override
public final long longValue() {
return get();
}
/**
* Returns a string representation of this field.
*
* @return a string representation of this field.
*/
@Override
public final java.lang.String toString() {
return java.lang.Long.toString(get());
}
}
public class Float extends NumberField {
public Float() {
super(java.lang.Float.SIZE, Constants.FLOAT_ALIGN);
}
/**
* Creates a new float field at a specific offset
*
* @param offset The offset within the memory area for this field.
*/
public Float(Offset offset) {
super(java.lang.Float.SIZE, Constants.FLOAT_ALIGN, offset);
}
public final float get() {
return getMemoryIO().getFloat(offset());
}
public final void set(float value) {
getMemoryIO().putFloat(offset(), value);
}
public void set(java.lang.Number value) {
getMemoryIO().putFloat(offset(), value.floatValue());
}
@Override
public final int intValue() {
return (int) get();
}
@Override
public final double doubleValue() {
return get();
}
@Override
public final float floatValue() {
return get();
}
@Override
public final long longValue() {
return (long) get();
}
@Override
public final java.lang.String toString() {
return java.lang.String.valueOf(get());
}
}
public final class Double extends NumberField {
public Double() {
super(java.lang.Double.SIZE, Constants.DOUBLE_ALIGN);
}
public Double(Offset offset) {
super(java.lang.Double.SIZE, Constants.DOUBLE_ALIGN, offset);
}
public final double get() {
return getMemoryIO().getDouble(offset());
}
public final void set(double value) {
getMemoryIO().putDouble(offset(), value);
}
public void set(java.lang.Number value) {
getMemoryIO().putDouble(offset(), value.doubleValue());
}
@Override
public final int intValue() {
return (int) get();
}
@Override
public final long longValue() {
return (long) get();
}
@Override
public final float floatValue() {
return (float) get();
}
@Override
public final double doubleValue() {
return get();
}
@Override
public final java.lang.String toString() {
return java.lang.String.valueOf(get());
}
}
/**
* Represents a native memory address.
*/
public class Address extends NumberField {
/**
* Creates a new Address field.
*/
public Address() {
super(Constants.ADDRESS_SIZE);
}
public Address(Offset offset) {
super(Constants.ADDRESS_SIZE, offset);
}
/**
* Gets the {@link com.googlecode.jffi.Address} value from the native memory.
*
* @return a {@link com.googlecode.jffi.Address}.
*/
public final com.kenai.jaffl.Address get() {
long value = getMemoryIO().getAddress(offset());
return value != 0 ? new com.kenai.jaffl.Address(value) : null;
}
/**
* Puts a {@link jafl.Address} value into the native memory.
*/
public final void set(com.kenai.jaffl.Address value) {
getMemoryIO().putAddress(offset(), value != null ? value.nativeAddress() : 0);
}
public void set(java.lang.Number value) {
getMemoryIO().putAddress(offset(), value.longValue());
}
/**
* Returns an integer representation of this address.
*
* @return an integer value for this address.
*/
@Override
public final int intValue() {
return get().intValue();
}
/**
* Returns an {@code long} representation of this address.
*
* @return an {@code long} value for this address.
*/
@Override
public final long longValue() {
return get().longValue();
}
/**
* Returns a string representation of this Address
.
*
* @return a string representation of this Address
.
*/
@Override
public final java.lang.String toString() {
return get().toString();
}
}
/**
* Represents a native memory address.
*/
public class Pointer extends NumberField {
/**
* Creates a new Address field.
*/
public Pointer() {
super(Constants.ADDRESS_SIZE);
}
public Pointer(Offset offset) {
super(Constants.ADDRESS_SIZE, offset);
}
/**
* Gets the {@link com.googlecode.jffi.Address} value from the native memory.
*
* @return a {@link com.googlecode.jffi.Address}.
*/
public final com.kenai.jaffl.Pointer get() {
return getMemoryIO().getPointer(offset());
}
/**
* Gets the size of a Pointer in bits
*
* @return the size of the Pointer
*/
public final int size() {
return com.kenai.jaffl.Address.SIZE;
}
/**
* Puts a {@link com.googlecode.jffi.Address} value into the native memory.
*/
public final void set(com.kenai.jaffl.Pointer value) {
getMemoryIO().putPointer(offset(), value);
}
public void set(java.lang.Number value) {
getMemoryIO().putAddress(offset(), value.longValue());
}
/**
* Returns an integer representation of this Pointer
.
*
* @return an integer value for this Pointer
.
*/
@Override
public final int intValue() {
return (int) getMemoryIO().getAddress(offset());
}
/**
* Returns an {@code long} representation of this Pointer
.
*
* @return an {@code long} value for this Pointer
.
*/
@Override
public final long longValue() {
return getMemoryIO().getAddress(offset());
}
/**
* Returns a string representation of this Pointer
.
*
* @return a string representation of this Pointer
.
*/
@Override
public final java.lang.String toString() {
return get().toString();
}
}
/**
* Base for all the Enum fields.
*
* @param the type of {@link java.lang.Enum}
*/
protected abstract class EnumField extends NumberField {
protected final Class enumClass;
/**
* Constructs a new Enum field.
*
* @param size the size of the native integer.
* @param enumClass the Enum class.
*/
public EnumField(int size, Class enumClass) {
this(size, size, enumClass);
}
/**
* Constructs a new Enum field.
*
* @param size the size of the native integer.
* * @param offset the offset from the start of the struct memory area.
* @param enumClass the Enum class.
*/
public EnumField(int size, Offset offset, Class enumClass) {
this(size, size, offset, enumClass);
}
/**
* Constructs a new Enum field.
* @param size the size of the native integer.
* @param align the minimum alignment of the native integer
* @param enumClass the Enum class.
*/
public EnumField(int size, int align, Class enumClass) {
super(size, align);
this.enumClass = enumClass;
}
/**
* Constructs a new Enum field.
* @param size the size of the native integer.
* @param align the minimum alignment of the native integer
* @param offset the offset from the start of the struct memory area
* @param enumClass the Enum class.
*/
public EnumField(int size, int align, Offset offset, Class enumClass) {
super(size, align, offset);
this.enumClass = enumClass;
}
/**
* Gets a java Enum value representing the native integer value.
*
* @return a java Enum value.
*/
public abstract E get();
/**
* Returns a string representation of this field.
*
* @return a string representation of this field.
*/
@Override
public final java.lang.String toString() {
return get().toString();
}
}
/**
* An 8 bit enum field.
*
* @param the {@link java.lang.Enum} to translate to/from.
*/
public class Enum8> extends EnumField {
/**
* Creates a new 8 bit enum field.
*
* @param enumClass the class of the {@link java.lang.Enum}.
*/
public Enum8(Class enumClass) {
super(8, enumClass);
}
/**
* Gets a java Enum value representing the native integer value.
*
* @return a java Enum value.
*/
public final E get() {
return EnumMapper.getInstance().valueOf(intValue(), enumClass);
}
/**
* Sets the native integer value using a java Enum value.
*
* @param value the java Enum value.
*/
public final void set(E value) {
getMemoryIO().putByte(offset(), (byte) EnumMapper.getInstance().intValue(value));
}
public void set(java.lang.Number value) {
getMemoryIO().putByte(offset(), value.byteValue());
}
/**
* Returns an integer representation of this enum field.
*
* @return an integer value for this enum field.
*/
@Override
public final int intValue() {
return getMemoryIO().getByte(offset());
}
}
public class Enum16> extends EnumField {
public Enum16(Class enumClass) {
super(16, enumClass);
}
public final E get() {
return EnumMapper.getInstance().valueOf(intValue(), enumClass);
}
public final void set(E value) {
getMemoryIO().putShort(offset(), (short) EnumMapper.getInstance().intValue(value));
}
public void set(java.lang.Number value) {
getMemoryIO().putShort(offset(), value.shortValue());
}
@Override
public final int intValue() {
return getMemoryIO().getShort(offset());
}
}
public class Enum32> extends EnumField {
public Enum32(Class enumClass) {
super(32, enumClass);
}
public final E get() {
return EnumMapper.getInstance().valueOf(intValue(), enumClass);
}
public final void set(E value) {
getMemoryIO().putInt(offset(), EnumMapper.getInstance().intValue(value));
}
public void set(java.lang.Number value) {
getMemoryIO().putInt(offset(), value.intValue());
}
@Override
public final int intValue() {
return getMemoryIO().getInt(offset());
}
}
public class Enum64> extends EnumField {
public Enum64(Class enumClass) {
super(64, Constants.INT64_ALIGN, enumClass);
}
public final E get() {
return EnumMapper.getInstance().valueOf(intValue(), enumClass);
}
public final void set(E value) {
getMemoryIO().putLong(offset(), EnumMapper.getInstance().intValue(value));
}
public void set(java.lang.Number value) {
getMemoryIO().putLong(offset(), value.longValue());
}
@Override
public final int intValue() {
return (int) longValue();
}
@Override
public final long longValue() {
return getMemoryIO().getLong(offset());
}
}
public class EnumLong> extends EnumField {
public EnumLong(Class enumClass) {
super(Constants.LONG_SIZE, Constants.LONG_ALIGN, enumClass);
}
public final E get() {
return EnumMapper.getInstance().valueOf(intValue(), enumClass);
}
public final void set(E value) {
getMemoryIO().putNativeLong(offset(), EnumMapper.getInstance().intValue(value));
}
public void set(java.lang.Number value) {
getMemoryIO().putNativeLong(offset(), value.longValue());
}
@Override
public final int intValue() {
return (int) longValue();
}
@Override
public final long longValue() {
return getMemoryIO().getNativeLong(offset());
}
}
public class Enum> extends Enum32 {
public Enum(Class enumClass) {
super(enumClass);
}
}
abstract public class String extends AbstractMember {
private final Charset charset;
private final int length;
protected String(int size, int align, int length, Charset cs) {
super(size, align);
this.length = length;
this.charset = cs;
}
protected String(int size, int align, Offset offset, int length, Charset cs) {
super(size, align, offset);
this.length = length;
this.charset = cs;
}
public final int length() {
return length;
}
protected abstract MemoryIO getStringMemory();
public final java.lang.String get() {
return getStringMemory().getString(0, length, charset);
}
public final void set(java.lang.String value) {
getStringMemory().putString(0, value, length, charset);
}
@Override
public final java.lang.String toString() {
return get();
}
}
public class UTFString extends String {
public UTFString(int length, Charset cs) {
super(length * 8, 8, length, cs); // FIXME: This won't work for non-ASCII
}
protected MemoryIO getStringMemory() {
return getMemoryIO().slice(offset(), length());
}
}
public class UTF8String extends UTFString {
public UTF8String(int size) {
super(size, Charset.forName("UTF-8"));
}
}
public class AsciiString extends UTFString {
public AsciiString(int size) {
super(size, Charset.forName("ASCII"));
}
}
public class UTFStringRef extends String {
public UTFStringRef(int length, Charset cs) {
super(Constants.ADDRESS_SIZE, Constants.ADDRESS_SIZE, length, cs);
}
public UTFStringRef(Charset cs) {
this(Integer.MAX_VALUE, cs);
}
protected MemoryIO getStringMemory() {
return getMemoryIO().getMemoryIO(offset(), length());
}
}
public class UTF8StringRef extends UTFStringRef {
public UTF8StringRef(int size) {
super(size, Charset.forName("UTF-8"));
}
public UTF8StringRef() {
super(Integer.MAX_VALUE, Charset.forName("UTF-8"));
}
}
public class AsciiStringRef extends UTFStringRef {
public AsciiStringRef(int size) {
super(size, Charset.forName("ASCII"));
}
public AsciiStringRef() {
super(Integer.MAX_VALUE, Charset.forName("ASCII"));
}
}
/**
* Specialized padding fields for structs. Use this instead of arrays of other
* members for more efficient struct construction.
*/
public final class Padding extends AbstractMember {
public Padding(Type type, int length) {
super(type.size() * 8 * length, type.alignment() * 8);
}
}
/*
public final Marshaller.Session marshal(Marshaller marshaller, MarshalContext context) {
return __info.marshal(marshaller, context);
}
*/
}
jaffl-0.5.9/src/com/kenai/jaffl/struct/StructUtil.java 0000664 0000000 0000000 00000003615 12017475436 0022654 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.struct;
import com.kenai.jaffl.MemoryIO;
import java.lang.reflect.Array;
/**
*
*/
public final class StructUtil {
private StructUtil() {}
public final static MemoryIO getMemoryIO(Struct struct) {
return struct.__info.getMemoryIO(0);
}
public final static MemoryIO getMemoryIO(Struct struct, int flags) {
return struct.__info.getMemoryIO(flags);
}
public final static int getSize(Struct struct) {
return struct.__info.size();
}
public final static int getMinimumAlignment(Struct struct) {
return struct.__info.getMinimumAlignment();
}
public final static boolean isDirect(Struct struct) {
return struct.__info.isDirect();
}
@SuppressWarnings("unchecked")
public static final T[] newArray(Class type, int length) {
try {
T[] array = (T[]) Array.newInstance(type, length);
for (int i = 0; i < length; ++i) {
array[i] = type.newInstance();
}
if (array.length > 0) {
final int align = getMinimumAlignment(array[0]);
final int mask = align - 1;
int structSize = getSize(array[0]);
if ((structSize & mask) != 0) {
structSize = (structSize & ~mask) + align;
}
MemoryIO memory = MemoryIO.allocateDirect(structSize * length);
for (int i = 0; i < array.length; ++i) {
array[i].useMemory(memory.slice(structSize * i, structSize));
}
}
return array;
} catch (SecurityException ex) {
throw new RuntimeException(ex);
} catch (InstantiationException ex) {
throw new RuntimeException(ex);
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
}
}
}
jaffl-0.5.9/src/com/kenai/jaffl/struct/Union.java 0000664 0000000 0000000 00000001123 12017475436 0021612 0 ustar 00root root 0000000 0000000 /*
* This file is covered by the license described in the LICENSE file in the root of
* the project, however, it incorporates some code from the javolution project,
* and that copyright is reproduced here.
*
* Copyright (C) 2006 - Javolution (http://javolution.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package com.kenai.jaffl.struct;
/**
* Represents a C union
*/
public abstract class Union extends Struct {
protected Union() {
super(true);
}
}
jaffl-0.5.9/src/com/kenai/jaffl/util/ 0000775 0000000 0000000 00000000000 12017475436 0017313 5 ustar 00root root 0000000 0000000 jaffl-0.5.9/src/com/kenai/jaffl/util/BufferPool.java 0000664 0000000 0000000 00000000360 12017475436 0022220 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.util;
import java.nio.ByteBuffer;
import java.util.List;
public interface BufferPool {
public ByteBuffer get(int size);
public void put(ByteBuffer buffer);
public void putAll(List list);
}
jaffl-0.5.9/src/com/kenai/jaffl/util/BufferUtil.java 0000664 0000000 0000000 00000014377 12017475436 0022241 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.util;
import com.kenai.jaffl.Platform;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CodingErrorAction;
/**
*
*/
public final class BufferUtil {
private BufferUtil() {}
public final static void putString(ByteBuffer buf, Charset charset, String value) {
putCharSequence(buf, charset, value);
}
public final static String getString(ByteBuffer buf, Charset charset) {
return getCharSequence(buf, charset).toString();
}
public final static void putCharSequence(ByteBuffer buf, Charset charset, CharSequence value) {
putCharSequence(buf, charset.newEncoder(), value);
}
public final static void putCharSequence(ByteBuffer buf, CharsetEncoder encoder, CharSequence value) {
//
// Convert any CharSequence implementor (String, etc) into a native
// C string.
//
encoder.reset().onMalformedInput(CodingErrorAction.REPLACE)
.onUnmappableCharacter(CodingErrorAction.REPLACE)
.encode(CharBuffer.wrap(value), buf, true);
encoder.flush(buf);
final int nulSize = Math.round(encoder.maxBytesPerChar());
// NUL terminate the string
if (nulSize == 4) {
buf.putInt(0);
} else if (nulSize == 2) {
buf.putShort((short) 0);
} else if (nulSize == 1) {
buf.put((byte) 0);
}
}
public final static CharSequence getCharSequence(ByteBuffer buf, Charset charset) {
return getCharSequence(buf, charset.newDecoder());
}
public final static CharSequence getCharSequence(final ByteBuffer buf, final CharsetDecoder decoder) {
final ByteBuffer buffer = buf.slice();
// Find the NUL terminator and limit to that, so the
// StringBuffer/StringBuilder does not have superfluous NUL chars
int end = indexOf(buffer, (byte) 0);
if (end < 0) {
end = buffer.limit();
}
buffer.position(0).limit(end);
try {
return decoder.reset().onMalformedInput(CodingErrorAction.REPLACE)
.onUnmappableCharacter(CodingErrorAction.REPLACE).decode(buffer);
} catch (CharacterCodingException ex) {
throw new Error("Illegal character data in native string", ex);
}
}
/**
* Finds the position of a byte relative to the start of the buffer.
*
* @param buf The ByteBuffer to find the value in
* @param value The value to locate
* @return The position within the buffer that value is found, or -1 if not
* found.
*/
public final static int positionOf(ByteBuffer buf, byte value) {
if (buf.hasArray()) {
final byte[] array = buf.array();
final int offset = buf.arrayOffset();
final int limit = buf.limit();
for (int pos = buf.position(); pos < limit; ++pos) {
if (array[offset + pos] == value) {
return pos;
}
}
} else {
final int limit = buf.limit();
for (int pos = buf.position(); pos < limit; ++pos) {
if (buf.get(pos) == value) {
return pos;
}
}
}
return -1;
}
public final static int indexOf(ByteBuffer buf, byte value) {
if (buf.hasArray()) {
byte[] array = buf.array();
int begin = buf.arrayOffset() + buf.position();
int end = begin + buf.limit();
for (int offset = 0; offset < end && offset > -1; ++offset) {
if (array[begin + offset] == value) {
return offset;
}
}
} else {
int begin = buf.position();
for (int offset = 0; offset < buf.limit(); ++offset) {
if (buf.get(begin + offset) == value) {
return offset;
}
}
}
return -1;
}
private static interface AddressIO {
public long getAddress(ByteBuffer io, int offset);
public void putAddress(ByteBuffer io, int offset, long address);
public static class AddressIO32 implements AddressIO {
public static final AddressIO IMPL = new AddressIO32();
public long getAddress(ByteBuffer io, int offset) {
return io.getInt(offset);
}
public void putAddress(ByteBuffer io, int offset, long address) {
io.putInt(offset, (int) address);
}
}
public static class AddressIO64 implements AddressIO {
public static final AddressIO IMPL = new AddressIO64();
public long getAddress(ByteBuffer io, int offset) {
return io.getLong(offset);
}
public void putAddress(ByteBuffer io, int offset, long address) {
io.putLong(offset, address);
}
}
public static final AddressIO INSTANCE = Platform.getPlatform().addressSize() == 32
? AddressIO32.IMPL : AddressIO64.IMPL;
}
public final static long getAddress(ByteBuffer buf, int position) {
return AddressIO.INSTANCE.getAddress(buf, position);
}
public final static void putAddress(ByteBuffer buf, int position, long address) {
AddressIO.INSTANCE.putAddress(buf, position, address);
}
/*
public final static Pointer getPointer(ByteBuffer buf, int position) {
return new Pointer(getAddress(buf, position));
}
public final static void putPointer(ByteBuffer buf, int position, Pointer value) {
putAddress(buf, position, value.nativeAddress());
}
*/
public static ByteBuffer slice(final ByteBuffer buffer, final int position) {
final ByteBuffer tmp = buffer.duplicate();
tmp.position(position);
return tmp.slice();
}
public static ByteBuffer slice(final ByteBuffer buffer, final int position, final int size) {
final ByteBuffer tmp = buffer.duplicate();
tmp.position(position).limit(position + size);
return tmp.slice();
}
} jaffl-0.5.9/src/com/kenai/jaffl/util/EnumMapper.java 0000664 0000000 0000000 00000006131 12017475436 0022230 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.util;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Provides mapping from Enum values to native integers and vice-versa
*/
public class EnumMapper {
public static interface IntegerEnum {
public int intValue();
}
private static final class Entry {
Map enumMap = new HashMap();
Map valueMap = new HashMap();
}
private static final class SingletonHolder {
private static final EnumMapper INSTANCE = new EnumMapper();
}
public static EnumMapper getInstance() {
return SingletonHolder.INSTANCE;
}
private static final int getIntegerValue(Enum e) {
if (e instanceof IntegerEnum) {
return ((IntegerEnum) e).intValue();
} else {
return e.ordinal();
}
}
private Entry createEntry(Class extends Enum> enumClass) {
Entry entry = new Entry();
for (Enum e : enumClass.getEnumConstants()) {
int intValue = getIntegerValue(e);
entry.enumMap.put(intValue, e);
entry.valueMap.put(e, intValue);
}
return entry;
}
private Entry getEntry(Class extends Enum> enumClass) {
Entry entry = enums.get(enumClass);
if (entry == null) {
//
// When building the entry, lock on the class so other lookups can proceed
// without waiting for the build.
//
synchronized (enumClass) {
//
// Re-check in case two threads tried at the same time and fell through
// to here.
//
if (!enums.containsKey(enumClass)) {
enums.put(enumClass, entry = createEntry(enumClass));
} else {
entry = enums.get(enumClass);
}
}
}
return entry;
}
public int intValue(Enum value) {
//return getEntry(value.getClass()).valueMap.get(value);
return getIntegerValue(value);
}
public > E valueOf(int value, Class enumClass) {
Enum e = getEntry(enumClass).enumMap.get(value);
if (e == null) {
//
// No value found - try to find the default value for unknown values.
// This is useful for enums that aren't fixed in stone and/or where you
// don't want to throw an Exception for an unknown value.
//
try {
return Enum.valueOf(enumClass, "__UNKNOWN_NATIVE_VALUE");
} catch (IllegalArgumentException ex) {
//
// No default, so just give up and throw an exception
//
throw new IllegalArgumentException("No known Enum mapping for value " + value + " of type " + enumClass.getName());
}
}
return enumClass.cast(e);
}
private final Map, Entry> enums = new ConcurrentHashMap, Entry>();
}
jaffl-0.5.9/src/com/kenai/jaffl/util/MultiBufferPool.java 0000664 0000000 0000000 00000005210 12017475436 0023232 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.util;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.List;
public class MultiBufferPool implements BufferPool {
/**
* Creates a new instance of MultiBufferPool
*/
public MultiBufferPool(int maxBufferSize, int maxItemsPerSize, boolean threadSafe) {
this.maxBufferSize = maxBufferSize;
this.maxItemsPerSize = maxItemsPerSize;
maxPoolIndex = getSizeIndex(maxBufferSize);
pools = new SimpleBufferPool[maxPoolIndex + 1];
// Now create each of the buckets
for (int i = 0; i <= maxPoolIndex; ++i) {
if (threadSafe) {
pools[i] = new SynchronizedPool(1 << i, maxItemsPerSize);
} else {
pools[i] = new SimpleBufferPool(1 << i, maxItemsPerSize);
}
}
}
public MultiBufferPool(int maxBufferSize, int maxItemsPerSize) {
this(maxBufferSize, maxItemsPerSize, false);
}
private final int maxBufferSize, maxItemsPerSize, maxPoolIndex;
private SimpleBufferPool[] pools;
private static final int getSizeIndex(int size) {
int start = 0;
int ssize = size;
//
// Cut down the loop size by dividing up the address space
//
if (ssize > 0xffff) {
start += 16;
ssize >>= 16;
}
if (ssize > 0xff) {
start += 8;
ssize >>= 8;
}
if (ssize > 0xf) {
start += 4;
}
for (int i = start; i < 32; ++i) {
if ((1 << i) >= size) {
//System.out.println("size " + size + " maps to pool index " + i);
return i;
}
}
return 32;
}
public ByteBuffer get(int size) {
int index = getSizeIndex(size);
if (index <= maxPoolIndex) {
return pools[index].get(size);
}
return ByteBuffer.allocateDirect(size).order(ByteOrder.nativeOrder());
}
public void put(ByteBuffer buf) {
int index = getSizeIndex(buf.capacity());
if (index <= maxPoolIndex) {
pools[index].put(buf);
}
}
public void putAll(List list) {
for (ByteBuffer buf : list) {
put(buf);
}
}
static class SynchronizedPool extends SimpleBufferPool {
public SynchronizedPool(int bufferSize, int poolSize) {
super(bufferSize, poolSize);
}
public synchronized ByteBuffer get(int size) {
return super.get(size);
}
public synchronized void put(ByteBuffer buf) {
super.put(buf);
}
}
}
jaffl-0.5.9/src/com/kenai/jaffl/util/SimpleBufferPool.java 0000664 0000000 0000000 00000005527 12017475436 0023404 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.util;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.List;
public class SimpleBufferPool implements BufferPool {
private final int bufferSize, poolSize;
private final BufferPool parent;
private final ArrayList list;
/**
* Creates a new instance of SimpleBufferPool
* @param bufferSize The Size of ByteBuffer this pool should return
* @param poolSize The maximum number of ByteBuffers to cache
*/
public SimpleBufferPool(int bufferSize, int poolSize) {
this(new DefaultPool(), bufferSize, poolSize);
}
/** Creates a new instance of SimpleBufferPool
* @param parent The parent pool from which to to fetch/return extra buffers.
* @param bufferSize The Size of ByteBuffer this pool should return.
* @param poolSize The maximum number of ByteBuffers to cache.
*/
public SimpleBufferPool(BufferPool parent, int bufferSize, int poolSize) {
this.parent = parent;
this.bufferSize = bufferSize;
this.poolSize = poolSize;
this.list = new ArrayList(poolSize);
}
public ByteBuffer get(int size) {
if (size <= bufferSize && !list.isEmpty()) {
//System.out.println("Returning cached buffer for size=" + size);
// Removing from the end of the ArrayList is O(1)
ByteBuffer buf = list.remove(list.size() - 1);
buf.rewind().limit(size);
return buf;
}
// Fetch a new buffer from the parent pool
//System.out.println("Allocating new direct ByteBuffer");
// Default to allocating a new buffer - make it at least bufferSize so it
// can be added back to the pool later
// This also handles buffers that are larger than the pool bufferSize.
// System.out.println("Requested buffer size of " + size + " is larger than " + bufferSize);
ByteBuffer buf = parent.get(Math.max(size, bufferSize));
buf.rewind().limit(size);
return buf;
}
public void put(ByteBuffer buf) {
if (list.size() < poolSize && buf.capacity() == bufferSize) {
//System.out.println("Storing ByteBuffer in pool size=" + bufferSize);
// Adding at the end of the ArrayList is O(1)
list.add(buf);
} else {
parent.put(buf);
}
}
public void putAll(List list) {
for (ByteBuffer buf : list) {
put(buf);
}
}
static class DefaultPool implements BufferPool {
public ByteBuffer get(int size) {
return ByteBuffer.allocateDirect(size).order(ByteOrder.nativeOrder());
}
// Just let the GC collect the buffers
public void put(ByteBuffer buffer) { }
public void putAll(List list) { }
}
}
jaffl-0.5.9/test/ 0000775 0000000 0000000 00000000000 12017475436 0013577 5 ustar 00root root 0000000 0000000 jaffl-0.5.9/test/com/ 0000775 0000000 0000000 00000000000 12017475436 0014355 5 ustar 00root root 0000000 0000000 jaffl-0.5.9/test/com/kenai/ 0000775 0000000 0000000 00000000000 12017475436 0015444 5 ustar 00root root 0000000 0000000 jaffl-0.5.9/test/com/kenai/jaffl/ 0000775 0000000 0000000 00000000000 12017475436 0016526 5 ustar 00root root 0000000 0000000 jaffl-0.5.9/test/com/kenai/jaffl/ArrayTest.java 0000664 0000000 0000000 00000016770 12017475436 0021322 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl;
import com.kenai.jaffl.annotations.In;
import com.kenai.jaffl.annotations.Out;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
public class ArrayTest {
public static interface TestLib {
// Pointer ptr_return_array_element(Pointer[] array, int index);
// void ptr_set_array_element(Pointer[] array, int index, Pointer value);
byte ptr_ret_int8_t(byte[] p, int offset);
short ptr_ret_int16_t(short[] p, int offset);
int ptr_ret_int32_t(int[] p, int offset);
long ptr_ret_int64_t(long[] p, int offset);
float ptr_ret_float(float[] p, int offset);
// Pointer ptr_ret_pointer(Pointer[] p, int offset);
double ptr_ret_double(double[] p, int offset);
void ptr_set_int8_t(byte[] p, int offset, byte value);
void ptr_set_int16_t(short[] p, int offset, short value);
void ptr_set_int32_t(int[] p, int offset, int value);
void ptr_set_int64_t(long[] p, int offset, long value);
void ptr_set_float(float[] p, int offset, float value);
void ptr_set_double(double[] p, int offset, double value);
// void ptr_set_pointer(Pointer[] p, int offset, Pointer value);
Pointer ptr_malloc(int size);
void ptr_free(Pointer ptr);
}
public static interface TestLibInOnly {
byte ptr_ret_int8_t(@In byte[] p, int offset);
short ptr_ret_int16_t(@In short[] p, int offset);
int ptr_ret_int32_t(@In int[] p, int offset);
long ptr_ret_int64_t(@In long[] p, int offset);
float ptr_ret_float(@In float[] p, int offset);
void ptr_set_int8_t(@In byte[] p, int offset, byte value);
void ptr_set_int16_t(@In short[] p, int offset, short value);
void ptr_set_int32_t(@In int[] p, int offset, int value);
void ptr_set_int64_t(@In long[] p, int offset, long value);
void ptr_set_float(@In float[] p, int offset, float value);
void ptr_set_double(@In double[] p, int offset, double value);
// void ptr_set_pointer(@In Pointer[] p, int offset, Pointer value);
}
public static interface TestLibOutOnly {
byte ptr_ret_int8_t(@Out byte[] p, int offset);
short ptr_ret_int16_t(@Out short[] p, int offset);
int ptr_ret_int32_t(@Out int[] p, int offset);
long ptr_ret_int64_t(@Out long[] p, int offset);
float ptr_ret_float(@Out float[] p, int offset);
void ptr_set_int8_t(@Out byte[] p, int offset, byte value);
void ptr_set_int16_t(@Out short[] p, int offset, short value);
void ptr_set_int32_t(@Out int[] p, int offset, int value);
void ptr_set_int64_t(@Out long[] p, int offset, long value);
void ptr_set_float(@Out float[] p, int offset, float value);
void ptr_set_double(@Out double[] p, int offset, double value);
// void ptr_set_pointer(@Out Pointer[] p, int offset, Pointer value);
}
static TestLib testlib;
public ArrayTest() {
}
@BeforeClass
public static void setUpClass() throws Exception {
testlib = TstUtil.loadTestLib(TestLib.class);
}
@AfterClass
public static void tearDownClass() throws Exception {
}
@Before
public void setUp() {
}
@After
public void tearDown() {
}
@Test
public void byteByReference() {
final byte MAGIC = (byte) 0xfe;
byte[] ref = { MAGIC };
assertEquals("byte reference not read correctly", MAGIC, testlib.ptr_ret_int8_t(ref, 0));
final byte MAGIC2 = (byte) 0xca;
testlib.ptr_set_int8_t(ref, 0, MAGIC2);
assertEquals("byte reference not written correctly", MAGIC2, ref[0]);
}
@Test
public void shortByReference() {
final short MAGIC = (short) 0xfee1;
short[] ref = { MAGIC };
assertEquals("short reference not read correctly", MAGIC, testlib.ptr_ret_int16_t(ref, 0));
final short MAGIC2 = (short) 0xcafe;
testlib.ptr_set_int16_t(ref, 0, MAGIC2);
assertEquals("short reference not written correctly", MAGIC2, ref[0]);
}
@Test
public void intByReference() {
final int MAGIC = (int) 0xfee1dead;
int[] ref = { MAGIC };
assertEquals("int reference not read correctly", MAGIC, testlib.ptr_ret_int32_t(ref, 0));
final int MAGIC2 = (int) 0xcafebabe;
testlib.ptr_set_int32_t(ref, 0, MAGIC2);
assertEquals("int reference not written correctly", MAGIC2, ref[0]);
}
@Test
public void longByReference() {
final long MAGIC = 0x1234fee1dead6789L;
long[] ref = { MAGIC };
assertEquals("long reference not read correctly", MAGIC, testlib.ptr_ret_int64_t(ref, 0));
final long MAGIC2 = 0xcafebabe12345678L;
testlib.ptr_set_int64_t(ref, 0, MAGIC2);
assertEquals("long reference not written correctly", MAGIC2, ref[0]);
}
// @Test
// public void pointerByReference() {
// final Pointer MAGIC = new Pointer(0xfee1dead);
// Pointer[] ref = { MAGIC };
// assertEquals("Pointer reference not read correctly", MAGIC, testlib.ptr_ret_pointer(ref, 0));
// final Pointer MAGIC2 = new Pointer(0xcafebabe);
// testlib.ptr_set_pointer(ref, 0, MAGIC2);
// assertEquals("Pointer reference not written correctly", MAGIC2, ref[0]);
// }
@Test
public void floatByReference() {
final float MAGIC = (float) 0xfee1dead;
float[] ref = { MAGIC };
assertEquals("float reference not read correctly", MAGIC, testlib.ptr_ret_float(ref, 0), 0.0f);
final float MAGIC2 = (float) 0xcafebabe;
testlib.ptr_set_float(ref, 0, MAGIC2);
assertEquals("float reference not written correctly", MAGIC2, ref[0], 0f);
}
@Test
public void doubleByReference() {
final double MAGIC = 0x1234fee1dead6789L;
double[] ref = { MAGIC };
assertEquals("double reference not read correctly", MAGIC, testlib.ptr_ret_double(ref, 0), 0d);
final double MAGIC2 = (double) 0xcafebabe12345678L;
testlib.ptr_set_double(ref, 0, MAGIC2);
assertEquals("double reference not written correctly", MAGIC2, ref[0], 0d);
}
//@Test
public void inOnlyByteByReference() {
TestLibInOnly lib = TstUtil.loadTestLib(TestLibInOnly.class);
final byte MAGIC = (byte) 0xfe;
byte[] ref = { MAGIC };
assertEquals("byte reference not read correctly", MAGIC, lib.ptr_ret_int8_t(ref, 0));
final byte MAGIC2 = (byte) 0xca;
lib.ptr_set_int8_t(ref, 0, MAGIC2);
assertEquals("byte array read from native memory when it should not be", MAGIC, ref[0]);
}
//@Test
public void inOnlyByteArray() {
TestLibInOnly lib = TstUtil.loadTestLib(TestLibInOnly.class);
final byte MAGIC = (byte) 0xfe;
byte[] ref = new byte[1024];
ref[0] = MAGIC;
assertEquals("byte array not read correctly", MAGIC, lib.ptr_ret_int8_t(ref, 0));
final byte MAGIC2 = (byte) 0xca;
lib.ptr_set_int8_t(ref, 0, MAGIC2);
assertEquals("byte array read from native memory when it should not be", MAGIC, ref[0]);
}
//@Test
public void outOnlyByteByReference() {
TestLibOutOnly lib = TstUtil.loadTestLib(TestLibOutOnly.class);
final byte MAGIC = (byte) 0xfe;
byte[] ref = { MAGIC };
final byte MAGIC2 = (byte) 0xca;
lib.ptr_set_int8_t(ref, 0, MAGIC2);
assertEquals("byte reference not copied from native memory", MAGIC2, ref[0]);
}
} jaffl-0.5.9/test/com/kenai/jaffl/BufferTest.java 0000664 0000000 0000000 00000033261 12017475436 0021447 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl;
import com.kenai.jaffl.annotations.In;
import com.kenai.jaffl.annotations.Out;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.CharBuffer;
import java.nio.DoubleBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.LongBuffer;
import java.nio.ShortBuffer;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
/**
*
* @author wayne
*/
public class BufferTest {
public BufferTest() {
}
public static interface TestLib {
void fillByteBuffer(@Out ByteBuffer buf, byte value, int size);
// void fillCharBuffer(@Out CharBuffer buf, char value, int size);
void fillShortBuffer(@Out ShortBuffer buf, short value, int size);
void fillIntBuffer(@Out IntBuffer buf, int value, int size);
void fillLongBuffer(@Out LongBuffer buf, long value, int size);
void fillFloatBuffer(@Out FloatBuffer buf, float value, int size);
void fillDoubleBuffer(@Out DoubleBuffer buf, double value, int size);
void fillByteBuffer(@Out byte[] buf, byte value, int size);
// void fillCharBuffer(@Out char[] buf, char value, int size);
void fillShortBuffer(@Out short[] buf, short value, int size);
void fillIntBuffer(@Out int[] buf, int value, int size);
void fillLongBuffer(@Out long[] buf, long value, int size);
void fillFloatBuffer(@Out float[] buf, float value, int size);
void fillDoubleBuffer(@Out double[] buf, double value, int size);
void copyByteBuffer(@Out ByteBuffer dst, @In ByteBuffer src, int size);
void copyByteBuffer(@Out ByteBuffer dst, @In byte[] src, int size);
void copyByteBuffer(@Out byte[] dst, @In ByteBuffer src, int size);
void copyByteBuffer(@Out byte[] dst, @In byte[] src, int size);
void copyShortBuffer(@Out ShortBuffer dst, @In ShortBuffer src, int size);
void copyShortBuffer(@Out ShortBuffer dst, @In short[] src, int size);
void copyShortBuffer(@Out short[] dst, @In ShortBuffer src, int size);
void copyShortBuffer(@Out short[] dst, @In short[] src, int size);
void copyIntBuffer(@Out IntBuffer dst, @In IntBuffer src, int size);
void copyIntBuffer(@Out IntBuffer dst, @In int[] src, int size);
void copyIntBuffer(@Out int[] dst, @In IntBuffer src, int size);
void copyIntBuffer(@Out int[] dst, @In int[] src, int size);
}
static TestLib lib;
@BeforeClass
public static void setUpClass() throws Exception {
lib = TstUtil.loadTestLib(TestLib.class);
}
@AfterClass
public static void tearDownClass() throws Exception {
lib = null;
}
@Before
public void setUp() {
}
@After
public void tearDown() {
}
// SMALL sized heap buffers can be done using direct buffers
private static final int SMALL = 64;
// LARGE sized heap buffers are handled via the native code
private static final int LARGE = 2048;
public void testByteBufferArgument(int size) {
ByteBuffer buf = ByteBuffer.allocate(size).order(ByteOrder.nativeOrder());
final byte MAGIC = (byte)0xED;
lib.fillByteBuffer(buf, MAGIC, buf.remaining());
for (int i=0;i < buf.capacity();i++) {
assertEquals("Bad value at index " + i, MAGIC, buf.get(i));
}
}
@Test
public void fillSmallByteBufferArgument() {
testByteBufferArgument(SMALL);
}
@Test
public void fillLargeByteBufferArgument() {
testByteBufferArgument(LARGE);
}
@Test
public void fillByteBufferWithOffsetArgument() {
ByteBuffer buf = ByteBuffer.allocate(SMALL).order(ByteOrder.nativeOrder());
final byte MAGIC = (byte)0xED;
buf.put((byte)0xDE);
lib.fillByteBuffer(buf.slice(), MAGIC, SMALL - 1);
assertEquals("Value at position 0 overwritten", (byte)0xde, buf.get(0));
for (int i=buf.position();i < buf.capacity();i++) {
assertEquals("Bad value at index " + i, MAGIC, buf.get(i));
}
}
@Test
public void fillByteBufferSlice() {
final int SIZE = SMALL;
ByteBuffer buf = ByteBuffer.allocate(SIZE).order(ByteOrder.nativeOrder());
final byte MAGIC = (byte)0xED;
buf.put(0, (byte)0xDE);
buf.put(buf.limit() - 1, (byte) 0xDE);
ByteBuffer dup = buf.duplicate();
dup.position(1).limit(buf.limit() - 1);
ByteBuffer slice = dup.slice();
lib.fillByteBuffer(slice, MAGIC, slice.capacity());
assertEquals("Value at position 0 overwritten", (byte)0xde, buf.get(0));
assertEquals("Value at position " + (SIZE - 1) + " overwritten",
(byte)0xde, buf.get(SIZE - 1));
for (int i = 1; i < buf.capacity() - 1; i++) {
assertEquals("Bad value at index " + i, MAGIC, buf.get(i));
}
}
public void testShortBufferArgument(int size) {
ShortBuffer buf = ShortBuffer.allocate(size);
final short MAGIC = (short)0xABED;
lib.fillShortBuffer(buf, MAGIC, size);
for (int i=0;i < buf.capacity();i++) {
assertEquals("Bad value at index " + i, MAGIC, buf.get(i));
}
}
@Test
public void fillSmallShortBufferArgument() {
testShortBufferArgument(SMALL);
}
@Test
public void fillLargeShortBufferArgument() {
testShortBufferArgument(LARGE);
}
@Test
public void fillShortBufferWithOffsetArgument() {
ShortBuffer buf = ShortBuffer.allocate(SMALL);
final short MAGIC = (short)0xABED;
buf.put((short)0xDEAD);
lib.fillShortBuffer(buf.slice(), MAGIC, SMALL - 1);
assertEquals("Value at position 0 overwritten", (short)0xdead, buf.get(0));
for (int i=1;i < buf.capacity();i++) {
assertEquals("Bad value at index " + i, MAGIC, buf.get(i));
}
}
@Test
public void fillShortBufferSlice() {
ShortBuffer buf = ShortBuffer.allocate(SMALL);
final short FILL = (short) 0x1234;
final short GUARD = (short) 0xdead;
buf.put(0, GUARD).put(buf.limit() - 1, GUARD);
ShortBuffer dup = buf.duplicate();
dup.position(1).limit(buf.limit() - 1);
ShortBuffer slice = dup.slice();
lib.fillShortBuffer(slice, FILL, slice.capacity());
assertEquals("Value at position 0 overwritten", GUARD, buf.get(0));
assertEquals("Value at position " + (buf.limit() - 1) + " overwritten",
GUARD, buf.get(buf.limit() - 1));
for (int i = 1; i < buf.limit() - 1; i++) {
assertEquals("Bad value at index " + i, FILL, buf.get(i));
}
}
public void testIntBufferArgument(int size) {
IntBuffer buf = IntBuffer.allocate(size);
final int MAGIC = 0xABEDCF23;
lib.fillIntBuffer(buf, MAGIC, size);
for (int i=0;i < buf.capacity();i++) {
assertEquals("Bad value at index " + i, MAGIC, buf.get(i));
}
}
@Test
public void fillSmallIntBufferArgument() {
testIntBufferArgument(SMALL);
}
@Test
public void fillLargeIntBufferArgument() {
testIntBufferArgument(SMALL);
}
@Test
public void fillIntBufferWithOffsetArgument() {
IntBuffer buf = IntBuffer.allocate(SMALL);
final int MAGIC = 0xABEDCF23;
buf.put(0xdeadbeef);
lib.fillIntBuffer(buf.slice(), MAGIC, SMALL - 1);
assertEquals("Value at position 0 overwritten", 0xdeadbeef, buf.get(0));
for (int i=1;i < buf.capacity();i++) {
assertEquals("Bad value at index " + i, MAGIC, buf.get(i));
}
}
@Test
public void fillIntBufferSlice() {
IntBuffer buf = IntBuffer.allocate(SMALL);
final int FILL = 0x12345678;
final int GUARD = 0xdeadbeef;
buf.put(0, GUARD).put(buf.limit() - 1, GUARD);
IntBuffer dup = buf.duplicate();
dup.position(1).limit(buf.limit() - 1);
IntBuffer slice = dup.slice();
lib.fillIntBuffer(slice, FILL, slice.capacity());
assertEquals("Value at position 0 overwritten", GUARD, buf.get(0));
assertEquals("Value at position " + (buf.limit() - 1) + " overwritten",
GUARD, buf.get(buf.limit() - 1));
for (int i = 1; i < buf.limit() - 1; i++) {
assertEquals("Bad value at index " + i, FILL, buf.get(i));
}
}
@Test
public void fillLongBufferArgument() {
LongBuffer buf = LongBuffer.allocate(SMALL);
final long MAGIC = 0x1234567887654321L;
lib.fillLongBuffer(buf, MAGIC, SMALL);
for (int i=0;i < buf.capacity();i++) {
assertEquals("Bad value at index " + i, MAGIC, buf.get(i));
}
}
@Test
public void fillLongBufferWithOffsetArgument() {
LongBuffer buf = LongBuffer.allocate(SMALL);
final long MAGIC = 0x1234567887654321L;
buf.put(0xdeadbeefL);
lib.fillLongBuffer(buf.slice(), MAGIC, SMALL - 1);
assertEquals("Value at position 0 overwritten", 0xdeadbeefL, buf.get(0));
for (int i=1;i < buf.capacity();i++) {
assertEquals("Bad value at index " + i, MAGIC, buf.get(i));
}
}
@Test
public void fillLongBufferSlice() {
LongBuffer buf = LongBuffer.allocate(SMALL);
final long GUARD = 0xdeadbeefL;
final long FILL = 0x1234567887654321L;
buf.put(0, GUARD).put(buf.limit() - 1, GUARD);
LongBuffer dup = buf.duplicate();
dup.position(1).limit(buf.limit() - 1);
LongBuffer slice = dup.slice();
lib.fillLongBuffer(dup.slice(), FILL, slice.capacity());
assertEquals("Value at position 0 overwritten", GUARD, buf.get(0));
assertEquals("Value at position " + (buf.limit() - 1) + " overwritten",
GUARD, buf.get(buf.limit() - 1));
for (int i = 1; i < buf.limit() - 1; i++) {
assertEquals("Bad value at index " + i, FILL, buf.get(i));
}
}
@Test
public void fillDirectByteBufferArgument() {
ByteBuffer buf = ByteBuffer.allocateDirect(SMALL).order(ByteOrder.nativeOrder());
final byte MAGIC = (byte)0xED;
lib.fillByteBuffer(buf, MAGIC, SMALL);
for (int i=0;i < buf.capacity();i++) {
assertEquals("Bad value at index " + i, MAGIC, buf.get(i));
}
}
@Test
public void fillDirectShortBufferArgument() {
ByteBuffer buf = ByteBuffer.allocateDirect(SMALL*2).order(ByteOrder.nativeOrder());
ShortBuffer shortBuf = buf.asShortBuffer();
final short MAGIC = (short)0xABED;
lib.fillShortBuffer(shortBuf, MAGIC, SMALL);
for (int i=0;i < shortBuf.capacity();i++) {
assertEquals("Bad value at index " + i, MAGIC, shortBuf.get(i));
}
}
@Test
public void fillDirectIntBufferArgument() {
ByteBuffer buf = ByteBuffer.allocateDirect(SMALL*4).order(ByteOrder.nativeOrder());
IntBuffer intBuf = buf.asIntBuffer();
final int MAGIC = 0xABEDCF23;
lib.fillIntBuffer(intBuf, MAGIC, SMALL);
for (int i=0;i < intBuf.capacity();i++) {
assertEquals("Bad value at index " + i, MAGIC, intBuf.get(i));
}
}
@Test
public void fillDirectLongBufferArgument() {
ByteBuffer buf = ByteBuffer.allocateDirect(SMALL*8).order(ByteOrder.nativeOrder());
LongBuffer longBuf = buf.asLongBuffer();
final long MAGIC = 0x1234567887654321L;
lib.fillLongBuffer(longBuf, MAGIC, SMALL);
for (int i=0;i < longBuf.capacity();i++) {
assertEquals("Bad value at index " + i, MAGIC, longBuf.get(i));
}
}
@Test
public void copySmallDirectByteBufferToArray() {
testCopyByteBufferToArray(ByteBuffer.allocateDirect(SMALL));
}
@Test
public void copyLargeDirectByteBufferToArray() {
testCopyByteBufferToArray(ByteBuffer.allocateDirect(LARGE));
}
@Test
public void copySmallHeapByteBufferToArray() {
testCopyByteBufferToArray(ByteBuffer.allocate(SMALL));
}
@Test
public void copyLargeHeapByteBufferToArray() {
testCopyByteBufferToArray(ByteBuffer.allocate(LARGE));
}
public void testCopyByteBufferToArray(ByteBuffer src) {
final int size = src.capacity();
for (int i = 0; i < size; ++i) {
src.put(i, (byte) i);
}
byte[] dst = new byte[size];
lib.copyByteBuffer(dst, src, size);
for (int i = 0; i < size; ++i) {
assertEquals("Bad value at index " + i, (byte) i, dst[i]);
}
}
// FIXME: re-enable when read-only buffers are supported
// @Test
public void copyReadOnlyHeapByteBufferToArray() {
final int size = SMALL;
ByteBuffer src = ByteBuffer.allocate(size);
for (int i = 0; i < size; ++i) {
src.put(i, (byte) i);
}
byte[] dst = new byte[size];
lib.copyByteBuffer(dst, src.asReadOnlyBuffer(), size);
for (int i = 0; i < size; ++i) {
assertEquals("Bad value at index " + i, (byte) i, dst[i]);
}
}
// @Test
// public void pinnedByteBuffer() {
// ByteBuffer buf = ByteBuffer.allocate(LARGE);
// Function fillByteBuffer = NativeLibrary.getInstance("jffitest").getFunction("fillByteBuffer");
// NativeInvoker nativeInvoker = FFINativeInvoker.getInvoker(fillByteBuffer, NativeInvoker.VOID);
// CallBuilder cb = CallBuilder.create(nativeInvoker);
// final byte MAGIC = (byte)0xED;
// cb.addPinned(buf).addInt8(MAGIC).addInt32(buf.remaining()).invokeVoid();
// for (int i=0;i < buf.capacity();i++) {
// assertEquals("Bad value at index " + i, MAGIC, buf.get(i));
// }
// }
} jaffl-0.5.9/test/com/kenai/jaffl/ClosureTest.java 0000664 0000000 0000000 00000050616 12017475436 0021655 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
/**
*
* @author wayne
*/
public class ClosureTest {
public ClosureTest() {
}
private static TestLib lib;
@BeforeClass
public static void setUpClass() throws Exception {
lib = TstUtil.loadTestLib(TestLib.class);
}
@AfterClass
public static void tearDownClass() throws Exception {
}
@Before
public void setUp() {
}
@After
public void tearDown() {
}
// FIXME: re-enable when closure/callbacks are working
@Test public void nop() {}
public static interface TestLib {
// public static interface ClosureVrV extends Closure {
// public void invoke();
// }
// void testClosureVrV(Closure closure);
// public static interface ClosureVrB extends Closure {
// public byte invoke();
// }
// byte testClosureVrB(Closure closure);
// public static interface ClosureVrS extends Closure {
// public short invoke();
// }
// short testClosureVrS(Closure closure);
// int testClosureVrI(Closure closure);
// long testClosureVrL(Closure closure);
// float testClosureVrF(Closure closure);
// public interface ClosureVrD extends Closure {
// public double invoke();
// }
// double testClosureVrD(Closure closure);
//
// public interface ClosureIrV extends Closure {
// public void invoke(int a1);
// }
// void testClosureBrV(Closure closure, byte a1);
// void testClosureSrV(Closure closure, short a1);
// void testClosureIrV(Closure closure, int a1);
// void testClosureLrV(Closure closure, long a1);
// void testClosureFrV(Closure closure, float a1);
// void testClosureDrV(Closure closure, double a1);
//
// // closures with small-big-small arguments
// void testClosureBSBrV(Closure closure, byte a1, short a2, byte a3);
// void testClosureBIBrV(Closure closure, byte a1, int a2, byte a3);
// void testClosureBLBrV(Closure closure, byte a1, long a2, byte a3);
// void testClosureBFBrV(Closure closure, byte a1, float a2, byte a3);
// void testClosureBDBrV(Closure closure, byte a1, double a2, byte a3);
//
// void testClosureSBSrV(Closure closure, short a1, byte a2, short a3);
// void testClosureSISrV(Closure closure, short a1, int a2, short a3);
// void testClosureSLSrV(Closure closure, short a1, long a2, short a3);
// void testClosureSFSrV(Closure closure, short a1, float a2, short a3);
// void testClosureSDSrV(Closure closure, short a1, double a2, short a3);
//
// // Now big-smaller-smaller
// void testClosureLSBrV(Closure closure, long a1, short a2, byte a3);
// // big-smaller-small
// void testClosureLBSrV(Closure closure, long a1, byte a2, short a3);
}
// @Test
// public void closureVrV() {
// final boolean[] called = { false };
// final TestLib.ClosureVrV closure = new TestLib.ClosureVrV() {
//
// public void invoke() {
// called[0] = true;
// }
// };
// lib.testClosureVrV(closure);
// assertTrue("Closure not called", called[0]);
// }
// @Test
// public void closureVrB() {
// final boolean[] called = { false };
// final byte MAGIC = (byte) 0xfe;
// TestLib.ClosureVrB closure = new TestLib.ClosureVrB() {
//
// public byte invoke() {
// called[0] = true;
// return MAGIC;
// }
// };
// byte retVal = lib.testClosureVrB(closure);
// assertTrue("Closure not called", called[0]);
// assertEquals("Incorrect return value from closure", MAGIC, retVal);
// }
// @Test
// public void closureVrS() {
// final boolean[] called = { false };
// final short MAGIC = (short) 0xfee1;
// TestLib.ClosureVrS closure = new TestLib.ClosureVrS() {
//
// public short invoke() {
// called[0] = true;
// return MAGIC;
// }
// };
// short retVal = lib.testClosureVrS(closure);
// assertTrue("Closure not called", called[0]);
// assertEquals("Incorrect return value from closure", MAGIC, retVal);
// }
// @Test
// public void closureVrI() {
// final boolean[] called = { false };
// final int MAGIC = (int) 0xfee1dead;
// Closure closure = new Closure() {
//
// public int invoke() {
// called[0] = true;
// return MAGIC;
// }
// };
// int retVal = lib.testClosureVrI(closure);
// assertTrue("Closure not called", called[0]);
// assertEquals("Incorrect return value from closure", MAGIC, retVal);
// }
// @Test
// public void closureVrL() {
// final boolean[] called = { false };
// final long MAGIC = 0xfee1deadcafebabeL;
// Closure closure = new Closure() {
//
// public long invoke() {
// called[0] = true;
// return MAGIC;
// }
// };
// long retVal = lib.testClosureVrL(closure);
// assertTrue("Closure not called", called[0]);
// assertEquals("Incorrect return value from closure", MAGIC, retVal);
// }
// @Test
// public void closureVrF() {
// final boolean[] called = { false };
// final float MAGIC = (float) 0xfee1dead;
// Closure closure = new Closure() {
//
// public float invoke() {
// called[0] = true;
// return MAGIC;
// }
// };
// float retVal = lib.testClosureVrF(closure);
// assertTrue("Closure not called", called[0]);
// assertEquals("Incorrect return value from closure", MAGIC, retVal, 0f);
// }
// @Test
// public void closureVrD() {
// final boolean[] called = { false };
// final double MAGIC = (double) 0xfee1dead;
// TestLib.ClosureVrD closure = new TestLib.ClosureVrD() {
//
// public double invoke() {
// called[0] = true;
// return MAGIC;
// }
// };
// double retVal = lib.testClosureVrD(closure);
// assertTrue("Closure not called", called[0]);
// assertEquals("Incorrect return value from closure", MAGIC, retVal, 0d);
// }
// @Test
// public void closureBrV() {
// final boolean[] called = { false };
// final byte[] val = { 0 };
// final byte MAGIC = (byte) 0xde;
// Closure closure = new Closure() {
//
// public void invoke(byte a1) {
// called[0] = true;
// val[0] = a1;
// }
// };
// lib.testClosureBrV(closure, MAGIC);
// assertTrue("Closure not called", called[0]);
// assertEquals("Wrong value passed to closure", MAGIC, val[0]);
// }
// @Test
// public void closureSrV() {
// final boolean[] called = { false };
// final short[] val = { 0 };
// final short MAGIC = (short) 0xdead;
// Closure closure = new Closure() {
//
// public void invoke(short a1) {
// called[0] = true;
// val[0] = a1;
// }
// };
// lib.testClosureSrV(closure, MAGIC);
// assertTrue("Closure not called", called[0]);
// assertEquals("Wrong value passed to closure", MAGIC, val[0]);
// }
// @Test
// public void closureIrV() {
// final boolean[] called = { false };
// final int[] val = { 0 };
// final int MAGIC = 0xdeadbeef;
// Closure closure = new Closure() {
//
// public void invoke(int a1) {
// called[0] = true;
// val[0] = a1;
// }
// };
// lib.testClosureIrV(closure, MAGIC);
// assertTrue("Closure not called", called[0]);
// assertEquals("Wrong value passed to closure", MAGIC, val[0]);
// }
// @Test
// public void closureLrV() {
// final boolean[] called = { false };
// final long[] val = { 0 };
// final long MAGIC = 0xfee1deadcafebabeL;
// Closure closure = new Closure() {
//
// public void invoke(long a1) {
// called[0] = true;
// val[0] = a1;
// }
// };
// lib.testClosureLrV(closure, MAGIC);
// assertTrue("Closure not called", called[0]);
// assertEquals("Wrong value passed to closure", MAGIC, val[0]);
// }
// @Test
// public void closureFrV() {
// final boolean[] called = { false };
// final float[] val = { 0 };
// final float MAGIC = (float) 0xdeadbeef;
// Closure closure = new Closure() {
//
// public void invoke(float a1) {
// called[0] = true;
// val[0] = a1;
// }
// };
// lib.testClosureFrV(closure, MAGIC);
// assertTrue("Closure not called", called[0]);
// assertEquals("Wrong value passed to closure", MAGIC, val[0], 0f);
// }
// @Test
// public void closureDrV() {
// final boolean[] called = { false };
// final double[] val = { 0 };
// final double MAGIC = (double) 0xfee1deadcafebabeL;
// Closure closure = new Closure() {
//
// public void invoke(double a1) {
// called[0] = true;
// val[0] = a1;
// }
// };
// lib.testClosureDrV(closure, MAGIC);
// assertTrue("Closure not called", called[0]);
// assertEquals("Wrong value passed to closure", MAGIC, val[0], 0d);
// }
// @Test
// public void closureBSBrV() {
// final boolean[] called = { false };
// final byte[] v1 = { 0 };
// final short[] v2 = { 0 };
// final byte[] v3 = { 0 };
// final byte A1 = (byte) 0x11;
// final short A2 = (short) 0xfee1;
// final byte A3 = (byte) 0x22;
// Closure closure = new Closure() {
//
// public void invoke(byte a1, short a2, byte a3) {
// called[0] = true;
// v1[0] = a1;
// v2[0] = a2;
// v3[0] = a3;
// }
// };
// lib.testClosureBSBrV(closure, A1, A2, A3);
// assertTrue("Closure not called", called[0]);
// assertEquals("Wrong value passed to closure", A1, v1[0]);
// assertEquals("Wrong value passed to closure", A2, v2[0]);
// assertEquals("Wrong value passed to closure", A3, v3[0]);
// }
// @Test
// public void closureBIBrV() {
// final boolean[] called = { false };
// final byte[] v1 = { 0 };
// final int[] v2 = { 0 };
// final byte[] v3 = { 0 };
// final byte A1 = (byte) 0x11;
// final int A2 = (int) 0xfee1dead;
// final byte A3 = (byte) 0x22;
// Closure closure = new Closure() {
//
// public void invoke(byte a1, int a2, byte a3) {
// called[0] = true;
// v1[0] = a1;
// v2[0] = a2;
// v3[0] = a3;
// }
// };
// lib.testClosureBIBrV(closure, A1, A2, A3);
// assertTrue("Closure not called", called[0]);
// assertEquals("Wrong value passed to closure", A1, v1[0]);
// assertEquals("Wrong value passed to closure", A2, v2[0]);
// assertEquals("Wrong value passed to closure", A3, v3[0]);
// }
// @Test
// public void closureBLBrV() {
// final boolean[] called = { false };
// final byte[] v1 = { 0 };
// final long[] v2 = { 0 };
// final byte[] v3 = { 0 };
// final byte A1 = (byte) 0x11;
// final long A2 = (long) 0xfee1deadcafebabeL;
// final byte A3 = (byte) 0x22;
// Closure closure = new Closure() {
//
// public void invoke(byte a1, long a2, byte a3) {
// called[0] = true;
// v1[0] = a1;
// v2[0] = a2;
// v3[0] = a3;
// }
// };
// lib.testClosureBLBrV(closure, A1, A2, A3);
// assertTrue("Closure not called", called[0]);
// assertEquals("Wrong value passed to closure", A1, v1[0]);
// assertEquals("Wrong value passed to closure", A2, v2[0]);
// assertEquals("Wrong value passed to closure", A3, v3[0]);
// }
// @Test
// public void closureBFBrV() {
// final boolean[] called = { false };
// final byte[] v1 = { 0 };
// final float[] v2 = { 0 };
// final byte[] v3 = { 0 };
// final byte A1 = (byte) 0x11;
// final float A2 = (float) 0xfee1dead;
// final byte A3 = (byte) 0x22;
// Closure closure = new Closure() {
//
// public void invoke(byte a1, float a2, byte a3) {
// called[0] = true;
// v1[0] = a1;
// v2[0] = a2;
// v3[0] = a3;
// }
// };
// lib.testClosureBFBrV(closure, A1, A2, A3);
// assertTrue("Closure not called", called[0]);
// assertEquals("Wrong value passed to closure", A1, v1[0]);
// assertEquals("Wrong value passed to closure", A2, v2[0], 0f);
// assertEquals("Wrong value passed to closure", A3, v3[0]);
// }
// @Test
// public void closureBDBrV() {
// final boolean[] called = { false };
// final byte[] v1 = { 0 };
// final double[] v2 = { 0 };
// final byte[] v3 = { 0 };
// final byte A1 = (byte) 0x11;
// final double A2 = (double) 0xfee1deadcafebabeL;
// final byte A3 = (byte) 0x22;
// Closure closure = new Closure() {
//
// public void invoke(byte a1, double a2, byte a3) {
// called[0] = true;
// v1[0] = a1;
// v2[0] = a2;
// v3[0] = a3;
// }
// };
// lib.testClosureBDBrV(closure, A1, A2, A3);
// assertTrue("Closure not called", called[0]);
// assertEquals("Wrong value passed to closure", A1, v1[0]);
// assertEquals("Wrong value passed to closure", A2, v2[0], 0d);
// assertEquals("Wrong value passed to closure", A3, v3[0]);
// }
// @Test
// public void closureSBSrV() {
// final boolean[] called = { false };
// final short[] v1 = { 0 };
// final byte[] v2 = { 0 };
// final short[] v3 = { 0 };
// final short A1 = (short) 0x1111;
// final byte A2 = (byte) 0xfe;
// final short A3 = (short) 0x2222;
// Closure closure = new Closure() {
//
// public void invoke(short a1, byte a2, short a3) {
// called[0] = true;
// v1[0] = a1;
// v2[0] = a2;
// v3[0] = a3;
// }
// };
// lib.testClosureSBSrV(closure, A1, A2, A3);
// assertTrue("Closure not called", called[0]);
// assertEquals("Wrong value passed to closure", A1, v1[0]);
// assertEquals("Wrong value passed to closure", A2, v2[0]);
// assertEquals("Wrong value passed to closure", A3, v3[0]);
// }
// @Test
// public void closureSISrV() {
// final boolean[] called = { false };
// final short[] v1 = { 0 };
// final int[] v2 = { 0 };
// final short[] v3 = { 0 };
// final short A1 = (short) 0x1111;
// final int A2 = (int) 0xfee1dead;
// final short A3 = (short) 0x2222;
// Closure closure = new Closure() {
//
// public void invoke(short a1, int a2, short a3) {
// called[0] = true;
// v1[0] = a1;
// v2[0] = a2;
// v3[0] = a3;
// }
// };
// lib.testClosureSISrV(closure, A1, A2, A3);
// assertTrue("Closure not called", called[0]);
// assertEquals("Wrong value passed to closure", A1, v1[0]);
// assertEquals("Wrong value passed to closure", A2, v2[0]);
// assertEquals("Wrong value passed to closure", A3, v3[0]);
// }
//
// @Test
// public void closureSLSrV() {
// final boolean[] called = { false };
// final short[] v1 = { 0 };
// final long[] v2 = { 0 };
// final short[] v3 = { 0 };
// final short A1 = (short) 0x1111;
// final long A2 = (long) 0xfee1deadcafebabeL;
// final short A3 = (short) 0x2222;
// Closure closure = new Closure() {
//
// public void invoke(short a1, long a2, short a3) {
// called[0] = true;
// v1[0] = a1;
// v2[0] = a2;
// v3[0] = a3;
// }
// };
// lib.testClosureSLSrV(closure, A1, A2, A3);
// assertTrue("Closure not called", called[0]);
// assertEquals("Wrong value passed to closure", A1, v1[0]);
// assertEquals("Wrong value passed to closure", A2, v2[0]);
// assertEquals("Wrong value passed to closure", A3, v3[0]);
// }
// @Test
// public void closureSFSrV() {
// final boolean[] called = { false };
// final short[] v1 = { 0 };
// final float[] v2 = { 0 };
// final short[] v3 = { 0 };
// final short A1 = (short) 0x1111;
// final float A2 = (float) 0xfee1dead;
// final short A3 = (short) 0x2222;
// Closure closure = new Closure() {
//
// public void invoke(short a1, float a2, short a3) {
// called[0] = true;
// v1[0] = a1;
// v2[0] = a2;
// v3[0] = a3;
// }
// };
// lib.testClosureSFSrV(closure, A1, A2, A3);
// assertTrue("Closure not called", called[0]);
// assertEquals("Wrong value passed to closure", A1, v1[0]);
// assertEquals("Wrong value passed to closure", A2, v2[0], 0f);
// assertEquals("Wrong value passed to closure", A3, v3[0]);
// }
// @Test
// public void closureSDSrV() {
// final boolean[] called = { false };
// final short[] v1 = { 0 };
// final double[] v2 = { 0 };
// final short[] v3 = { 0 };
// final short A1 = (short) 0x1111;
// final double A2 = (double) 0xfee1deadcafebabeL;
// final short A3 = (short) 0x2222;
// Closure closure = new Closure() {
//
// public void invoke(short a1, double a2, short a3) {
// called[0] = true;
// v1[0] = a1;
// v2[0] = a2;
// v3[0] = a3;
// }
// };
// lib.testClosureSDSrV(closure, A1, A2, A3);
// assertTrue("Closure not called", called[0]);
// assertEquals("Wrong value passed to closure", A1, v1[0]);
// assertEquals("Wrong value passed to closure", A2, v2[0], 0d);
// assertEquals("Wrong value passed to closure", A3, v3[0]);
// }
// @Test
// public void closureLSBrV() {
// final boolean[] called = { false };
// final long[] v1 = { 0 };
// final short[] v2 = { 0 };
// final byte[] v3 = { 0 };
// final long A1 = (long) 0xfee1deadcafebabeL;
// final short A2 = (short) 0x1111;
// final byte A3 = (byte) 0x22;
// Closure closure = new Closure() {
//
// public void invoke(long a1, short a2, byte a3) {
// called[0] = true;
// v1[0] = a1;
// v2[0] = a2;
// v3[0] = a3;
// }
// };
// lib.testClosureLSBrV(closure, A1, A2, A3);
// assertTrue("Closure not called", called[0]);
// assertEquals("Wrong value passed to closure", A1, v1[0]);
// assertEquals("Wrong value passed to closure", A2, v2[0]);
// assertEquals("Wrong value passed to closure", A3, v3[0]);
// }
// @Test
// public void closureLBSrV() {
// final boolean[] called = { false };
// final long[] v1 = { 0 };
// final byte[] v2 = { 0 };
// final short[] v3 = { 0 };
// final long A1 = (long) 0xfee1deadcafebabeL;
// final byte A2 = (byte) 0x11;
// final short A3 = (short) 0x2222;
// Closure closure = new Closure() {
//
// public void invoke(long a1, byte a2, short a3) {
// called[0] = true;
// v1[0] = a1;
// v2[0] = a2;
// v3[0] = a3;
// }
// };
// lib.testClosureLBSrV(closure, A1, A2, A3);
// assertTrue("Closure not called", called[0]);
// assertEquals("Wrong value passed to closure", A1, v1[0]);
// assertEquals("Wrong value passed to closure", A2, v2[0]);
// assertEquals("Wrong value passed to closure", A3, v3[0]);
// }
} jaffl-0.5.9/test/com/kenai/jaffl/EnumTest.java 0000664 0000000 0000000 00000004143 12017475436 0021137 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl;
import com.kenai.jaffl.util.EnumMapper;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
/**
*
*/
public class EnumTest {
public EnumTest() {
}
public static enum TestEnum implements EnumMapper.IntegerEnum {
A(1),
B(2),
C(3),
Z(100);
TestEnum(int value) {
this.value = value;
}
public int intValue() {
return value;
}
private final int value;
}
public static interface TestLib {
public int ret_int32_t(TestEnum e);
public int add_int32_t(TestEnum i1, TestEnum i2);
}
public static interface ReturnEnumLib {
public TestEnum ret_int32_t(int e);
public TestEnum ret_int32_t(TestEnum e);
public TestEnum add_int32_t(int i1, int i2);
public TestEnum add_int32_t(TestEnum i1, TestEnum i2);
}
static TestLib testlib;
static ReturnEnumLib retenum;
@BeforeClass
public static void setUpClass() throws Exception {
testlib = TstUtil.loadTestLib(TestLib.class);
retenum = TstUtil.loadTestLib(ReturnEnumLib.class);
}
@AfterClass
public static void tearDownClass() throws Exception {
}
@Before
public void setUp() {
}
@After
public void tearDown() {
}
// TODO add test methods here.
// The methods must be annotated with annotation @Test. For example:
//
// @Test
// public void hello() {}
@Test
public void enumArgument() {
assertEquals("Wrong value returned for enum", TestEnum.Z.intValue(), testlib.ret_int32_t(TestEnum.Z));
assertEquals("Wrong value returned for enum", TestEnum.C.intValue(), testlib.add_int32_t(TestEnum.A, TestEnum.B));
}
@Test
public void returnEnum() {
assertEquals("Wrong value returned for enum", TestEnum.Z, retenum.ret_int32_t(TestEnum.Z.intValue()));
assertEquals("Wrong value returned for enum", TestEnum.C, retenum.add_int32_t(1, 2));
}
} jaffl-0.5.9/test/com/kenai/jaffl/LastErrorTest.java 0000664 0000000 0000000 00000001640 12017475436 0022147 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl;
import com.kenai.jaffl.annotations.SaveError;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
/**
*
*/
public class LastErrorTest {
public static interface TestLib {
@SaveError
int setLastError(int error);
}
public LastErrorTest() {
}
@BeforeClass
public static void setUpClass() throws Exception {
}
@AfterClass
public static void tearDownClass() throws Exception {
}
@Before
public void setUp() {
}
@After
public void tearDown() {
}
@Test public void testLastError() {
TestLib lib = TstUtil.loadTestLib(TestLib.class);
final int MAGIC = 0xdeadbeef;
lib.setLastError(MAGIC);
assertEquals("Wrong errno value", MAGIC, LastError.getLastError());
}
} jaffl-0.5.9/test/com/kenai/jaffl/LibraryTest.java 0000664 0000000 0000000 00000002030 12017475436 0021630 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Test library locating/loading
*/
public class LibraryTest {
public LibraryTest() {
}
@BeforeClass
public static void setUpClass() throws Exception {
}
@AfterClass
public static void tearDownClass() throws Exception {
}
@Before
public void setUp() {
}
@After
public void tearDown() {
}
// TODO add test methods here.
// The methods must be annotated with annotation @Test. For example:
//
// @Test
// public void hello() {}
public static interface TestLib {
int setLastError(int error);
}
@Test public void loadTestLib() {
TestLib lib = TstUtil.loadTestLib(TestLib.class);
assertNotNull("Could not load libtest", lib);
// This just forces the library to really load and call a function
lib.setLastError(0);
}
} jaffl-0.5.9/test/com/kenai/jaffl/MemoryIOTest.java 0000664 0000000 0000000 00000036065 12017475436 0021743 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
/**
*
* @author wayne
*/
public class MemoryIOTest {
public MemoryIOTest() {
}
@BeforeClass
public static void setUpClass() throws Exception {
}
@AfterClass
public static void tearDownClass() throws Exception {
}
@Before
public void setUp() {
}
@After
public void tearDown() {
}
private static final Pointer getBufferPointer(ByteBuffer buffer) {
return TstUtil.getDirectBufferPointer(buffer);
}
private static final MemoryIO wrapPointer(Pointer ptr, int size) {
return MemoryIO.wrap(ptr, size);
}
private static final MemoryIO wrapPointer(Pointer ptr) {
return MemoryIO.wrap(ptr);
}
private static final MemoryIO wrap(ByteBuffer buffer) {
return MemoryIO.wrap(buffer);
}
private static final MemoryIO allocateDirect(int size) {
return MemoryIO.allocateDirect(size);
}
private final void testPutByte(MemoryIO io, ByteBuffer buffer, int size) {
for (int i = 0; i < size; ++i) {
io.putByte(i, (byte) (i + 5));
assertEquals("Incorrect value at offset " + i, (byte) (i + 5), buffer.get(i));
}
}
private final void testGetByte(MemoryIO io, ByteBuffer buffer, int size) {
for (int i = 0; i < size; ++i) {
buffer.put(i, (byte) (i + 5));
assertEquals("Incorrect value at offset " + i, (byte) (i + 5), io.getByte(i));
}
}
private final void testPutShort(MemoryIO io, ByteBuffer buffer, int size) {
for (int i = 0; i <= size - 2; ++i) {
io.putShort(i, (short) i);
assertEquals("Incorrect value at offset " + i, (short) i, buffer.getShort(i));
}
}
private final void testGetShort(MemoryIO io, ByteBuffer buffer, int size) {
for (int i = 0; i <= size - 2; ++i) {
buffer.putShort(i, (short) i);
assertEquals("Incorrect value at offset " + i, (short) i, io.getShort(i));
}
}
private final void testPutInt(MemoryIO io, ByteBuffer buffer, int size) {
for (int i = 0; i <= size - 4; ++i) {
io.putInt(i, i);
assertEquals("Incorrect value at offset " + i, i, buffer.getInt(i));
}
}
private final void testGetInt(MemoryIO io, ByteBuffer buffer, int size) {
for (int i = 0; i <= size - 4; ++i) {
buffer.putInt(i, i);
assertEquals("Incorrect value at offset " + i, i, io.getInt(i));
}
}
private final void testPutLong(MemoryIO io, ByteBuffer buffer, int size) {
for (int i = 0; i <= size - 8; ++i) {
io.putLong(i, i);
assertEquals("Incorrect value at offset " + i, (long) i, buffer.getLong(i));
}
}
private final void testGetLong(MemoryIO io, ByteBuffer buffer, int size) {
for (int i = 0; i <= size - 8; ++i) {
buffer.putLong(i, i);
assertEquals("Incorrect value at offset " + i, (long) i, io.getLong(i));
}
}
private final void testPutFloat(MemoryIO io, ByteBuffer buffer, int size) {
for (int i = 0; i <= size - (Float.SIZE / 8); ++i) {
io.putFloat(i, i);
assertEquals("Incorrect value at offset " + i, (float) i, buffer.getFloat(i), 0f);
}
}
private final void testGetFloat(MemoryIO io, ByteBuffer buffer, int size) {
for (int i = 0; i <= size - (Float.SIZE / 8); ++i) {
buffer.putFloat(i, i);
assertEquals("Incorrect value at offset " + i, (float) i, io.getFloat(i), 0f);
}
}
private final void testPutDouble(MemoryIO io, ByteBuffer buffer, int size) {
for (int i = 0; i <= size - (Double.SIZE / 8); ++i) {
io.putDouble(i, (double) i);
assertEquals("Incorrect value at offset " + i, (double) i, buffer.getDouble(i), 0d);
}
}
private final void testGetDouble(MemoryIO io, ByteBuffer buffer, int size) {
for (int i = 0; i <= size - (Double.SIZE / 8); ++i) {
buffer.putDouble(i, (double) i);
assertEquals("Incorrect value at offset " + i, (double) i, io.getDouble(i), 0d);
}
}
@Test public void testBoundedIOPutByte() {
final int SIZE = 16;
ByteBuffer buffer = ByteBuffer.allocateDirect(SIZE);
testPutByte(wrapPointer(getBufferPointer(buffer), SIZE), buffer, SIZE);
}
@Test public void testBoundedIOGetByte() {
final int SIZE = 16;
ByteBuffer buffer = ByteBuffer.allocateDirect(SIZE);
testGetByte(wrapPointer(getBufferPointer(buffer), SIZE), buffer, SIZE);
}
@Test public void testBoundedIOPutShort() {
final int SIZE = 16;
ByteBuffer buffer = ByteBuffer.allocateDirect(SIZE).order(ByteOrder.nativeOrder());
testPutShort(wrapPointer(getBufferPointer(buffer), SIZE), buffer, SIZE);
}
@Test public void testBoundedIOGetShort() {
final int SIZE = 16;
ByteBuffer buffer = ByteBuffer.allocateDirect(SIZE).order(ByteOrder.nativeOrder());
testGetShort(wrapPointer(getBufferPointer(buffer), SIZE), buffer, SIZE);
}
@Test public void testBoundedIOPutInt() {
final int SIZE = 16;
ByteBuffer buffer = ByteBuffer.allocateDirect(SIZE).order(ByteOrder.nativeOrder());
testPutInt(wrapPointer(getBufferPointer(buffer), SIZE), buffer, SIZE);
}
@Test public void testBoundedIOGetInt() {
final int SIZE = 16;
ByteBuffer buffer = ByteBuffer.allocateDirect(SIZE).order(ByteOrder.nativeOrder());
testGetInt(wrapPointer(getBufferPointer(buffer), SIZE), buffer, SIZE);
}
@Test public void testBoundedIOPutLong() {
final int SIZE = 16;
ByteBuffer buffer = ByteBuffer.allocateDirect(SIZE).order(ByteOrder.nativeOrder());
testPutLong(wrapPointer(getBufferPointer(buffer), SIZE), buffer, SIZE);
}
@Test public void testBoundedIOGetLong() {
final int SIZE = 16;
ByteBuffer buffer = ByteBuffer.allocateDirect(SIZE).order(ByteOrder.nativeOrder());
testGetLong(wrapPointer(getBufferPointer(buffer), SIZE), buffer, SIZE);
}
@Test public void testBoundedIOPutFloat() {
final int SIZE = 16;
ByteBuffer buffer = ByteBuffer.allocateDirect(SIZE).order(ByteOrder.nativeOrder());
testPutFloat(wrapPointer(getBufferPointer(buffer), SIZE), buffer, SIZE);
}
@Test public void testBoundedIOGetFloat() {
final int SIZE = 16;
ByteBuffer buffer = ByteBuffer.allocateDirect(SIZE).order(ByteOrder.nativeOrder());
testGetFloat(wrapPointer(getBufferPointer(buffer), SIZE), buffer, SIZE);
}
@Test public void testBoundedIOPutDouble() {
final int SIZE = 16;
ByteBuffer buffer = ByteBuffer.allocateDirect(SIZE).order(ByteOrder.nativeOrder());
testPutDouble(wrapPointer(getBufferPointer(buffer), SIZE), buffer, SIZE);
}
@Test public void testBoundedIOGetDouble() {
final int SIZE = 16;
ByteBuffer buffer = ByteBuffer.allocateDirect(SIZE).order(ByteOrder.nativeOrder());
testGetDouble(wrapPointer(getBufferPointer(buffer), SIZE), buffer, SIZE);
}
@Test
public void testNegativeBoundedIO() {
final int SIZE = 16;
MemoryIO memio = allocateDirect(SIZE);
try {
memio.putByte(-1, (byte) 0);
fail("Should have thrown IndexOutOfBoundsException");
} catch (IndexOutOfBoundsException ex) {
}
}
@Test
public void testOverflowBoundedIO() {
final int SIZE = 16;
MemoryIO memio = allocateDirect(SIZE);
try {
memio.putByte(16, (byte) 0);
fail("Should have thrown IndexOutOfBoundsException");
} catch (IndexOutOfBoundsException ex) {
}
}
@Test public void testNativeIOPutByte() {
final int SIZE = 16;
ByteBuffer buffer = ByteBuffer.allocateDirect(SIZE);
testPutByte(wrapPointer(getBufferPointer(buffer)), buffer, SIZE);
}
@Test public void testNativeIOGetByte() {
final int SIZE = 16;
ByteBuffer buffer = ByteBuffer.allocateDirect(SIZE);
testGetByte(wrapPointer(getBufferPointer(buffer)), buffer, SIZE);
}
@Test public void testNativeIOPutShort() {
final int SIZE = 16;
ByteBuffer buffer = ByteBuffer.allocateDirect(SIZE).order(ByteOrder.nativeOrder());
testPutShort(wrapPointer(getBufferPointer(buffer)), buffer, SIZE);
}
@Test public void testNativeIOGetShort() {
final int SIZE = 16;
ByteBuffer buffer = ByteBuffer.allocateDirect(SIZE).order(ByteOrder.nativeOrder());
testGetShort(wrapPointer(getBufferPointer(buffer)), buffer, SIZE);
}
@Test public void testNativeIOPutInt() {
final int SIZE = 16;
ByteBuffer buffer = ByteBuffer.allocateDirect(SIZE).order(ByteOrder.nativeOrder());
testPutInt(wrapPointer(getBufferPointer(buffer)), buffer, SIZE);
}
@Test public void testNativeIOGetInt() {
final int SIZE = 16;
ByteBuffer buffer = ByteBuffer.allocateDirect(SIZE).order(ByteOrder.nativeOrder());
testGetInt(wrapPointer(getBufferPointer(buffer)), buffer, SIZE);
}
@Test public void testNativeIOPutLong() {
final int SIZE = 16;
ByteBuffer buffer = ByteBuffer.allocateDirect(SIZE).order(ByteOrder.nativeOrder());
testPutLong(wrapPointer(getBufferPointer(buffer)), buffer, SIZE);
}
@Test public void testNativeIOGetLong() {
final int SIZE = 16;
ByteBuffer buffer = ByteBuffer.allocateDirect(SIZE).order(ByteOrder.nativeOrder());
testGetLong(wrapPointer(getBufferPointer(buffer)), buffer, SIZE);
}
@Test public void testNativeIOPutFloat() {
final int SIZE = 16;
ByteBuffer buffer = ByteBuffer.allocateDirect(SIZE).order(ByteOrder.nativeOrder());
testPutFloat(wrapPointer(getBufferPointer(buffer)), buffer, SIZE);
}
@Test public void testNativeIOGetFloat() {
final int SIZE = 16;
ByteBuffer buffer = ByteBuffer.allocateDirect(SIZE).order(ByteOrder.nativeOrder());
testGetFloat(wrapPointer(getBufferPointer(buffer)), buffer, SIZE);
}
@Test public void testNativeIOPutDouble() {
final int SIZE = 16;
ByteBuffer buffer = ByteBuffer.allocateDirect(SIZE).order(ByteOrder.nativeOrder());
testPutDouble(wrapPointer(getBufferPointer(buffer)), buffer, SIZE);
}
@Test public void testNativeIOGetDouble() {
final int SIZE = 16;
ByteBuffer buffer = ByteBuffer.allocateDirect(SIZE).order(ByteOrder.nativeOrder());
testGetDouble(wrapPointer(getBufferPointer(buffer)), buffer, SIZE);
}
@Test public void testBufferIOPutByte() {
final int SIZE = 16;
ByteBuffer buffer = ByteBuffer.allocate(SIZE);
testPutByte(wrap(buffer), buffer, SIZE);
}
@Test public void testBufferIOGetByte() {
final int SIZE = 16;
ByteBuffer buffer = ByteBuffer.allocate(SIZE);
testGetByte(wrap(buffer), buffer, SIZE);
}
@Test public void testBufferIOPutShort() {
final int SIZE = 16;
ByteBuffer buffer = ByteBuffer.allocate(SIZE).order(ByteOrder.nativeOrder());
testPutShort(wrap(buffer), buffer, SIZE);
}
@Test public void testBufferIOGetShort() {
final int SIZE = 16;
ByteBuffer buffer = ByteBuffer.allocate(SIZE).order(ByteOrder.nativeOrder());
testGetShort(wrap(buffer), buffer, SIZE);
}
@Test public void testBufferIOPutInt() {
final int SIZE = 16;
ByteBuffer buffer = ByteBuffer.allocate(SIZE).order(ByteOrder.nativeOrder());
testPutInt(wrap(buffer), buffer, SIZE);
}
@Test public void testBufferIOGetInt() {
final int SIZE = 16;
ByteBuffer buffer = ByteBuffer.allocate(SIZE).order(ByteOrder.nativeOrder());
testGetInt(wrap(buffer), buffer, SIZE);
}
@Test public void testBufferIOPutLong() {
final int SIZE = 16;
ByteBuffer buffer = ByteBuffer.allocate(SIZE).order(ByteOrder.nativeOrder());
testPutLong(wrap(buffer), buffer, SIZE);
}
@Test public void testBufferIOGetLong() {
final int SIZE = 16;
ByteBuffer buffer = ByteBuffer.allocate(SIZE).order(ByteOrder.nativeOrder());
testGetLong(wrap(buffer), buffer, SIZE);
}
@Test public void testBufferIOPutFloat() {
final int SIZE = 16;
ByteBuffer buffer = ByteBuffer.allocate(SIZE).order(ByteOrder.nativeOrder());
testPutFloat(wrap(buffer), buffer, SIZE);
}
@Test public void testBufferIOGetFloat() {
final int SIZE = 16;
ByteBuffer buffer = ByteBuffer.allocate(SIZE).order(ByteOrder.nativeOrder());
testGetFloat(wrap(buffer), buffer, SIZE);
}
@Test public void testBufferIOPutDouble() {
final int SIZE = 16;
ByteBuffer buffer = ByteBuffer.allocate(SIZE).order(ByteOrder.nativeOrder());
testPutDouble(wrap(buffer), buffer, SIZE);
}
@Test public void testBufferIOGetDouble() {
final int SIZE = 16;
ByteBuffer buffer = ByteBuffer.allocate(SIZE).order(ByteOrder.nativeOrder());
testGetDouble(wrap(buffer), buffer, SIZE);
}
@Test
public void testNegativeBufferIO() {
final int SIZE = 16;
MemoryIO memio = wrap(ByteBuffer.allocate(SIZE));
try {
memio.putByte(-1, (byte) 0);
fail("Should have thrown IndexOutOfBoundsException");
} catch (IndexOutOfBoundsException ex) {
}
}
@Test
public void testOverflowBufferIO() {
final int SIZE = 16;
MemoryIO memio = wrap(ByteBuffer.allocate(SIZE));
try {
memio.putByte(16, (byte) 0);
fail("Should have thrown IndexOutOfBoundsException");
} catch (IndexOutOfBoundsException ex) {
}
}
@Test public void transferDirectToHeap() throws Exception {
ByteBuffer buf = ByteBuffer.allocate(1024);
MemoryIO dst = MemoryIO.wrap(buf);
MemoryIO src = MemoryIO.allocateDirect(1024);
byte[] MAGIC = "MAGIC".getBytes();
src.put(0, MAGIC, 0, MAGIC.length);
src.transferTo(0, dst, 0, MAGIC.length);
for (int i = 0; i < MAGIC.length; ++i) {
assertEquals("Wrong byte at index " + i, MAGIC[i], dst.getByte(i));
}
for (int i = 0; i < MAGIC.length; ++i) {
assertEquals("Wrong byte at index " + i, MAGIC[i], buf.get(i));
}
}
@Test public void transferDirectToDirect() throws Exception {
MemoryIO dst = MemoryIO.allocateDirect(1024);
MemoryIO src = MemoryIO.allocateDirect(1024);
final byte[] MAGIC = "MAGIC".getBytes();
final int SRCOFF = 100;
final int DSTOFF = 123;
src.put(SRCOFF, MAGIC, 0, MAGIC.length);
src.transferTo(SRCOFF, dst, DSTOFF, MAGIC.length);
for (int i = 0; i < MAGIC.length; ++i) {
assertEquals("Wrong byte at index " + i, MAGIC[i], dst.getByte(DSTOFF + i));
}
}
} jaffl-0.5.9/test/com/kenai/jaffl/NumberTest.java 0000664 0000000 0000000 00000021037 12017475436 0021464 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl;
import java.util.Random;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
/**
*
* @author wayne
*/
public class NumberTest {
public NumberTest() {
}
public static interface TestLib {
public byte add_int8_t(byte i1, byte i2);
public short add_int16_t(short i1, short i2);
public int add_int32_t(int i1, int i2);
public long add_int64_t(long i1, long i2);
public NativeLong add_long(NativeLong i1, NativeLong i2);
public NativeLong sub_long(NativeLong i1, NativeLong i2);
public NativeLong mul_long(NativeLong i1, NativeLong i2);
public NativeLong div_long(NativeLong i1, NativeLong i2);
public float add_float(float f1, float f2);
public float sub_float(float f1, float f2);
public float mul_float(float f1, float f2);
public float div_float(float f1, float f2);
public double add_double(double f1, double f2);
public double sub_double(double f1, double f2);
public double mul_double(double f1, double f2);
public double div_double(double f1, double f2);
}
static TestLib testlib;
@BeforeClass
public static void setUpClass() throws Exception {
testlib = TstUtil.loadTestLib(TestLib.class);
}
@AfterClass
public static void tearDownClass() throws Exception {
}
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
}
@Test
public void testByteAddition() throws Exception {
for (int i = 0; i <= 255; ++i) {
byte i1 = (byte) i;
byte i2 = (byte) 0xde;
assertEquals("byte addition failed", (byte) (i1 + i2), testlib.add_int8_t(i1, i2));
}
}
@Test
public void testShortAddition() throws Exception {
for (int i = 0; i <= 0xffff; ++i) {
short i1 = (short) i;
short i2 = (short) 0xdead;
assertEquals("byte addition failed", (short) (i1 + i2), testlib.add_int16_t(i1, i2));
}
}
static interface FloatOp {
public float j(float f1, float f2);
public float n(float f1, float f2);
}
private void testFloat(FloatOp op) throws Exception {
float f1 = 1.0f;
float f2 = (float) 0xdeadbeef;
assertEquals("float " + op + " failed", op.j(f1, f2), op.n(f1, f2), 0f);
for (int i = 0; i < 0xffff; ++i) {
f1 = (float) i;
assertEquals("float + " + op + " failed", op.j(f1, f2), op.n(f1, f2), 0f);
}
Random random = new Random();
for (int i = 0; i < 0xffff; ++i) {
f1 = random.nextFloat();
f2 = random.nextFloat();
float expected = op.j(f1, f2);
float result = op.n(f1, f2);
if (expected != result) {
fail(String.format("float " + op + "(%f, %f) failed - expected: %f, received: %f",
f1, f2, expected, result));
}
}
}
@Test
public void testFloatAddition() throws Exception {
testFloat(new FloatOp() {
public float j(float f1, float f2) {
return f1 + f2;
}
public float n(float f1, float f2) {
return testlib.add_float(f1, f2);
}
@Override
public String toString() { return "add"; }
});
}
@Test
public void testFloatSubtraction() throws Exception {
testFloat(new FloatOp() {
public float j(float f1, float f2) {
return f1 - f2;
}
public float n(float f1, float f2) {
return testlib.sub_float(f1, f2);
}
@Override
public String toString() { return "subtract"; }
});
}
@Test
public void testFloatMultiplication() throws Exception {
testFloat(new FloatOp() {
public float j(float f1, float f2) {
return f1 * f2;
}
public float n(float f1, float f2) {
return testlib.mul_float(f1, f2);
}
public String toString() { return "multiply"; }
});
}
@Test
public void testFloatDivision() throws Exception {
testFloat(new FloatOp() {
public float j(float f1, float f2) {
return f1 / f2;
}
public float n(float f1, float f2) {
return testlib.div_float(f1, f2);
}
@Override
public String toString() { return "divide"; }
});
}
static interface DoubleOp {
public double j(double f1, double f2);
public double n(double f1, double f2);
}
private void testDouble(DoubleOp op) throws Exception {
double f1 = 1.0f;
double f2 = (double) 0xdeadbeef;
assertEquals("double " + op + " failed", op.j(f1, f2), op.n(f1, f2), 0d);
for (int i = 0; i < 0xffff; ++i) {
f1 = (float) i;
assertEquals("double + " + op + " failed", op.j(f1, f2), op.n(f1, f2), 0d);
}
Random random = new Random();
for (int i = 0; i < 0xffff; ++i) {
f1 = random.nextFloat();
f2 = random.nextFloat();
double expected = op.j(f1, f2);
double result = op.n(f1, f2);
if (expected != result) {
fail(String.format("double " + op + "(%f, %f) failed - expected: %f, received: %f",
f1, f2, expected, result));
}
}
}
@Test
public void testDoubleAddition() throws Exception {
testDouble(new DoubleOp() {
public double j(double f1, double f2) {
return f1 + f2;
}
public double n(double f1, double f2) {
return testlib.add_double(f1, f2);
}
@Override
public String toString() { return "add"; }
});
}
@Test
public void testDoubleSubtraction() throws Exception {
testDouble(new DoubleOp() {
public double j(double f1, double f2) {
return f1 - f2;
}
public double n(double f1, double f2) {
return testlib.sub_double(f1, f2);
}
@Override
public String toString() { return "subtract"; }
});
}
@Test
public void testDoubleMultiplication() throws Exception {
testDouble(new DoubleOp() {
public double j(double f1, double f2) {
return f1 * f2;
}
public double n(double f1, double f2) {
return testlib.mul_double(f1, f2);
}
@Override
public String toString() { return "multiply"; }
});
}
@Test
public void testDoubleDivision() throws Exception {
testDouble(new DoubleOp() {
public double j(double f1, double f2) {
return f1 / f2;
}
public double n(double f1, double f2) {
return testlib.div_double(f1, f2);
}
@Override
public String toString() { return "divide"; }
});
}
static interface NativeLongOp {
public long j(long f1, long f2);
public long n(long f1, long f2);
}
private void testNativeLong(NativeLongOp op) throws Exception {
long i1 = 1;
long i2 = 2;
assertEquals("NativeLong " + op + " failed", op.j(i1, i2), op.n(i1, i2));
for (int i = 0; i < 0xffff; ++i) {
assertEquals("NativeLong + " + op + " failed", op.j(i, i2), op.n(i, i2));
}
}
@Test
public void NativeLong_valueOf() {
for (int i = -1000; i < 1000; ++i) {
assertEquals("Incorrect value from valueOf(" + i+ ")", i, NativeLong.valueOf(i).intValue());
}
for (long i = -1000; i < 1000; ++i) {
assertEquals("Incorrect value from valueOf(" + i+ ")", i, NativeLong.valueOf(i).longValue());
}
}
@Test
public void testNativeLongAddition() throws Exception {
testNativeLong(new NativeLongOp() {
public long j(long i1, long i2) {
return i1 + i2;
}
public long n(long i1, long i2) {
return testlib.add_long(NativeLong.valueOf(i1), NativeLong.valueOf(i2)).longValue();
}
});
}
} jaffl-0.5.9/test/com/kenai/jaffl/PointerTest.java 0000664 0000000 0000000 00000017141 12017475436 0021655 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
/**
*
* @author wayne
*/
public class PointerTest {
public PointerTest() {
}
public static interface TestLib {
Pointer ptr_return_array_element(Pointer[] array, int index);
void ptr_set_array_element(Pointer[] array, int index, Pointer value);
byte ptr_ret_int8_t(Pointer p, int offset);
short ptr_ret_int16_t(Pointer p, int offset);
int ptr_ret_int32_t(Pointer p, int offset);
long ptr_ret_int64_t(Pointer p, int offset);
float ptr_ret_float(Pointer p, int offset);
double ptr_ret_double(Pointer p, int offset);
void ptr_set_int8_t(Pointer p, int offset, byte value);
void ptr_set_int16_t(Pointer p, int offset, short value);
void ptr_set_int32_t(Pointer p, int offset, int value);
void ptr_set_int64_t(Pointer p, int offset, long value);
void ptr_set_float(Pointer p, int offset, float value);
void ptr_set_double(Pointer p, int offset, double value);
Pointer ptr_malloc(int size);
void ptr_free(Pointer ptr);
}
static TestLib testlib;
public static interface Libc {
Pointer calloc(int nmemb, int size);
Pointer malloc(int size);
void free(Pointer ptr);
void cfree(Pointer ptr);
}
static Libc libc;
@BeforeClass
public static void setUpClass() throws Exception {
testlib = TstUtil.loadTestLib(TestLib.class);
libc = Library.loadLibrary("c", Libc.class);
}
@AfterClass
public static void tearDownClass() throws Exception {
}
@Before
public void setUp() {
}
@After
public void tearDown() {
}
// @Test
// public void testGetPointerArrayArgument() throws Exception {
//
// Pointer MAGIC0 = new Pointer(0xdeadbeef);
// Pointer MAGIC1 = new Pointer(0xcafebabe);
// Pointer[] array = { MAGIC0, MAGIC1 };
//
// assertEquals("Incorrect Pointer at index 0", MAGIC0,
// testlib.ptr_return_array_element(array, 0));
// assertEquals("Incorrect Pointer at index 1", MAGIC1,
// testlib.ptr_return_array_element(array, 1));
// }
// @Test
// public void testSetPointerArrayArgument() throws Exception {
//
// Pointer MAGIC0 = new Pointer(0xdeadbeef);
// Pointer MAGIC1 = new Pointer(0xcafebabe);
// Pointer[] array = { MAGIC0, MAGIC1 };
//
// testlib.ptr_set_array_element(array, 0, MAGIC1);
// testlib.ptr_set_array_element(array, 1, MAGIC0);
// assertEquals("Pointer at index 0 not set", MAGIC1, array[0]);
// assertEquals("Pointer at index 1 not set", MAGIC0, array[1]);
// }
//
// @Test
// public void testLongPointerValue() throws Exception {
// long MAGIC0 = 0xdeadbeefL | (Address.SIZE == 64 ? (0xfee1deadL << 32) : 0L);
// assertEquals("Pointer value not equal", MAGIC0, new Pointer(MAGIC0).nativeAddress());
// }
static final int SIZE = 128;
@Test
public void testPointerSetByte() {
Pointer p = testlib.ptr_malloc(SIZE);
byte MAGIC = (byte) 0xFE;
for (int i = 0; i < SIZE; ++i) {
p.putByte(i, MAGIC);
assertEquals("Byte not set at offset " + i, MAGIC, testlib.ptr_ret_int8_t(p, i));
}
}
@Test
public void testPointerSetShort() {
Pointer p = testlib.ptr_malloc(SIZE);
short MAGIC = (short) 0xFEE1;
for (int i = 0; i < (SIZE - 1); ++i) {
p.putShort(i, MAGIC);
assertEquals("Short not set at offset " + i, MAGIC, testlib.ptr_ret_int16_t(p, i));
}
}
@Test
public void testPointerSetInt() {
Pointer p = testlib.ptr_malloc(SIZE);
int MAGIC = (int) 0xFEE1DEAD;
for (int i = 0; i < (SIZE - 3); ++i) {
p.putInt(i, MAGIC);
assertEquals("Integer not set at offset " + i, MAGIC, testlib.ptr_ret_int32_t(p, i));
}
}
@Test
public void testPointerSetLong() {
Pointer p = testlib.ptr_malloc(SIZE);
long MAGIC = 0xFEE1DEADABCDEF12L;
for (int i = 0; i < (SIZE - 7); ++i) {
p.putLong(i, MAGIC);
assertEquals("Long not set at offset " + i, MAGIC, testlib.ptr_ret_int64_t(p, i));
}
}
@Test
public void testPointerSetFloat() {
Pointer p = testlib.ptr_malloc(SIZE);
float MAGIC = (float) 0xFEE1DEADABCDEF12L;
for (int i = 0; i < (SIZE - 7); ++i) {
p.putFloat(i, MAGIC);
assertEquals("Float not set at offset " + i, MAGIC, testlib.ptr_ret_float(p, i), 0f);
}
}
@Test
public void testPointerSetDouble() {
Pointer p = testlib.ptr_malloc(SIZE);
double MAGIC = (double) 0xFEE1DEADABCDEF12L;
for (int i = 0; i < (SIZE - 7); ++i) {
p.putDouble(i, MAGIC);
assertEquals("Double not set at offset " + i, MAGIC, testlib.ptr_ret_double(p, i), 0d);
}
}
@Test
public void testPointerGetByte() {
Pointer p = testlib.ptr_malloc(SIZE);
byte MAGIC = (byte) 0xFE;
for (int i = 0; i < SIZE; ++i) {
testlib.ptr_set_int8_t(p, i, MAGIC);
assertEquals("Byte not set at offset " + i, MAGIC, p.getByte(i));
}
}
@Test
public void testPointerGetShort() {
Pointer p = testlib.ptr_malloc(SIZE);
short MAGIC = (short) 0xFEE1;
for (int i = 0; i < SIZE - 1; ++i) {
testlib.ptr_set_int16_t(p, i, MAGIC);
assertEquals("Short not set at offset " + i, MAGIC, p.getShort(i));
}
}
@Test
public void testPointerGetInt() {
Pointer p = testlib.ptr_malloc(SIZE);
int MAGIC = (int) 0xFEE1DEAD;
for (int i = 0; i < SIZE - 3; ++i) {
testlib.ptr_set_int32_t(p, i, MAGIC);
assertEquals("Integer not set at offset " + i, MAGIC, p.getInt(i));
}
}
@Test
public void testPointerGetLong() {
Pointer p = testlib.ptr_malloc(SIZE);
long MAGIC = 0xFEE1DEADABCDEF12L;
for (int i = 0; i < SIZE - 7; ++i) {
testlib.ptr_set_int64_t(p, i, MAGIC);
assertEquals("Long not set at offset " + i, MAGIC, p.getLong(i));
}
}
@Test
public void testPointerGetFloat() {
Pointer p = testlib.ptr_malloc(SIZE);
float MAGIC = (float) 0xFEE1DEADABCDEF12L;
for (int i = 0; i < (SIZE - 7); ++i) {
testlib.ptr_set_float(p, i, MAGIC);
assertEquals("Float not set at offset " + i, MAGIC, p.getFloat(i), 0f);
}
}
@Test
public void testPointerGetDouble() {
Pointer p = testlib.ptr_malloc(SIZE);
double MAGIC = (double) 0xFEE1DEADABCDEF12L;
for (int i = 0; i < (SIZE - 7); ++i) {
testlib.ptr_set_double(p, i, MAGIC);
assertEquals("Double not set at offset " + i, MAGIC, p.getDouble(i), 0d);
}
}
@Test
public void testMalloc() {
Pointer[] pointers = new Pointer[1024];
for (int i = 0; i < pointers.length; ++i) {
pointers[i] = testlib.ptr_malloc(SIZE);
}
for (int i = 0; i < pointers.length; ++i) {
testlib.ptr_free(pointers[i]);
}
}
@Test
public void testLibcMalloc() {
if (Platform.getPlatform().getOS() != Platform.OS.LINUX) {
Pointer p = libc.malloc(SIZE);
libc.free(p);
}
}
} jaffl-0.5.9/test/com/kenai/jaffl/ResultConverterTest.java 0000664 0000000 0000000 00000005147 12017475436 0023406 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl;
import com.kenai.jaffl.mapper.FromNativeContext;
import com.kenai.jaffl.mapper.FromNativeConverter;
import com.kenai.jaffl.mapper.ToNativeConverter;
import com.kenai.jaffl.mapper.TypeMapper;
import java.util.HashMap;
import java.util.Map;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
/**
*
* @author wayne
*/
public class ResultConverterTest {
public static final class TestType {
public final String str;
public TestType(String str) {
this.str = str;
}
}
public static interface TestLib {
TestType strdup(CharSequence cs);
void cfree(Pointer ptr);
}
public static interface Libc {
Pointer calloc(int nmemb, int size);
Pointer malloc(int size);
void free(Pointer ptr);
void cfree(Pointer ptr);
}
public static final class TestTypeResultConverter implements FromNativeConverter {
public Class nativeType() {
return Pointer.class;
}
public TestType fromNative(Pointer nativeValue, FromNativeContext context) {
return new TestType(nativeValue.getString(0));
}
}
static final TypeMapper mapper = new TypeMapper() {
public FromNativeConverter getFromNativeConverter(Class type) {
if (TestType.class == type) {
return new TestTypeResultConverter();
}
return null;
}
public ToNativeConverter getToNativeConverter(Class type) {
return null;
}
};
static TestLib testlib;
public ResultConverterTest() {
}
@BeforeClass
public static void setUpClass() throws Exception {
Map options = new HashMap();
options.put(LibraryOption.TypeMapper, mapper);
System.setProperty("jaffl.compiler.dump", "true");
testlib = Library.loadLibrary("c", TestLib.class, options);
}
@AfterClass
public static void tearDownClass() throws Exception {
}
@Before
public void setUp() {
}
@After
public void tearDown() {
}
// TODO add test methods here.
// The methods must be annotated with annotation @Test. For example:
//
// @Test
// public void hello() {}
@Test public void testCustomResult() {
final String MAGIC = "test";
TestType t = testlib.strdup(MAGIC);
assertNotNull(t);
assertEquals("contents not set", MAGIC, t.str);
}
}
jaffl-0.5.9/test/com/kenai/jaffl/StringTest.java 0000664 0000000 0000000 00000005211 12017475436 0021476 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
/**
*
* @author wayne
*/
public class StringTest {
public StringTest() {
}
public static interface TestLib {
boolean string_equals(CharSequence s1, byte[] s2);
void string_set(StringBuffer dst, CharSequence src);
void string_set(StringBuilder dst, CharSequence src);
void string_concat(StringBuilder dst, CharSequence src);
void string_concat(StringBuffer dst, CharSequence src);
}
static TestLib testlib;
@BeforeClass
public static void setUpClass() throws Exception {
testlib = TstUtil.loadTestLib(TestLib.class);
}
@AfterClass
public static void tearDownClass() throws Exception {
}
@Before
public void setUp() {
}
@After
public void tearDown() {
}
@Test
public void testReadOnlyString() {
String MAGIC = "deadbeef\u0000";
assertTrue("String did not equal byte array", testlib.string_equals(MAGIC, MAGIC.getBytes()));
assertTrue("StringBuffer did not equal byte array", testlib.string_equals(new StringBuffer(MAGIC), MAGIC.getBytes()));
assertTrue("StringBuilder did not equal byte array", testlib.string_equals(new StringBuilder(MAGIC), MAGIC.getBytes()));
}
@Test
public void testSetStringBuffer() {
String MAGIC = "deadbeef";
StringBuffer buffer = new StringBuffer(1024);
testlib.string_set(buffer, MAGIC);
assertEquals("StringBuffer was not set", MAGIC, buffer.toString());
}
@Test
public void testSetStringBuilder() {
String MAGIC = "deadbeef";
StringBuilder buffer = new StringBuilder(1024);
testlib.string_set(buffer, MAGIC);
assertEquals("StringBuilder was not set", MAGIC, buffer.toString());
}
@Test
public void testStringBufferAppend() {
String ORIG = "test ";
String MAGIC = "deadbeef";
StringBuffer buffer = new StringBuffer(1024);
buffer.append(ORIG);
testlib.string_concat(buffer, MAGIC);
assertEquals("StringBuilder was not set", ORIG + MAGIC, buffer.toString());
}
@Test
public void testStringBuilderAppend() {
String ORIG = "test ";
String MAGIC = "deadbeef";
StringBuilder buffer = new StringBuilder(1024);
buffer.append(ORIG);
testlib.string_concat(buffer, MAGIC);
assertEquals("StringBuilder was not set", ORIG + MAGIC, buffer.toString());
}
} jaffl-0.5.9/test/com/kenai/jaffl/TstUtil.java 0000664 0000000 0000000 00000001541 12017475436 0021002 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl;
import java.nio.ByteBuffer;
import java.util.Collections;
import java.util.Map;
public final class TstUtil {
private TstUtil() {}
public static final String getTestLibraryName() {
return "test";
}
public static interface HelperLib {
Pointer ptr_from_buffer(ByteBuffer buf);
}
public static T loadTestLib(Class interfaceClass) {
final Map options = Collections.emptyMap();
return loadTestLib(interfaceClass, options);
}
public static T loadTestLib(Class interfaceClass, Map options) {
return Library.loadLibrary(getTestLibraryName(), interfaceClass, options);
}
public static Pointer getDirectBufferPointer(ByteBuffer buf) {
return TstUtil.loadTestLib(HelperLib.class).ptr_from_buffer(buf);
}
}
jaffl-0.5.9/test/com/kenai/jaffl/byref/ 0000775 0000000 0000000 00000000000 12017475436 0017635 5 ustar 00root root 0000000 0000000 jaffl-0.5.9/test/com/kenai/jaffl/byref/AddressByReferenceTest.java 0000664 0000000 0000000 00000005663 12017475436 0025051 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.byref;
import com.kenai.jaffl.Address;
import com.kenai.jaffl.TstUtil;
import com.kenai.jaffl.annotations.In;
import com.kenai.jaffl.annotations.Out;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
/**
*
* @author wayne
*/
public class AddressByReferenceTest {
public AddressByReferenceTest() {
}
@BeforeClass
public static void setUpClass() throws Exception {
}
@AfterClass
public static void tearDownClass() throws Exception {
}
@Before
public void setUp() {
}
@After
public void tearDown() {
}
public static interface TestLib {
Address ptr_ret_pointer(AddressByReference p, int offset);
void ptr_set_pointer(AddressByReference p, int offset, Address value);
}
public static interface TestLibInOnly {
Address ptr_ret_pointer(@In AddressByReference p, int offset);
void ptr_set_pointer(@In AddressByReference p, int offset, Address value);
}
public static interface TestLibOutOnly {
Address ptr_ret_pointer(@Out AddressByReference p, int offset);
void ptr_set_pointer(@Out AddressByReference p, int offset, Address value);
}
// TODO add test methods here.
// The methods must be annotated with annotation @Test. For example:
//
// @Test
// public void hello() {}
@Test public void dummy() {}
@Test public void inOnlyReferenceSet() {
TestLibInOnly lib = TstUtil.loadTestLib(TestLibInOnly.class);
final Address MAGIC = new Address(0xdeadbeef);
AddressByReference ref = new AddressByReference(MAGIC);
assertEquals("Wrong value passed", MAGIC, lib.ptr_ret_pointer(ref, 0));
}
// @Test public void inOnlyIntReferenceNotWritten() {
// TestLibInOnly lib = TstUtil.loadTestLib(TestLibInOnly.class);
// final Address MAGIC = new Address(0xdeadbeef);
// AddressByReference ref = new AddressByReference(MAGIC);
// lib.ptr_set_pointer(ref, 0, new Address(0));
// assertEquals("Int reference written when it should not be", MAGIC, ref.getValue());
// }
// @Test public void outOnlyIntReferenceNotRead() {
// TestLibOutOnly lib = TstUtil.loadTestLib(TestLibOutOnly.class);
// final Address MAGIC = new Address(0xdeadbeef);
// AddressByReference ref = new AddressByReference(MAGIC);
// assertTrue("Reference value passed to native code when it should not be", MAGIC != lib.ptr_ret_pointer(ref, 0));
// }
// @Test public void outOnlyIntReferenceGet() {
// TestLibOutOnly lib = TstUtil.loadTestLib(TestLibOutOnly.class);
// final Address MAGIC = new Address(0xdeadbeef);
// AddressByReference ref = new AddressByReference(new Address(0));
// lib.ptr_set_pointer(ref, 0, MAGIC);
// assertEquals("Reference value not set", MAGIC, ref.getValue());
// }
} jaffl-0.5.9/test/com/kenai/jaffl/byref/ByteByReferenceTest.java 0000664 0000000 0000000 00000005064 12017475436 0024362 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.byref;
import com.kenai.jaffl.TstUtil;
import com.kenai.jaffl.annotations.In;
import com.kenai.jaffl.annotations.Out;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
/**
*
*/
public class ByteByReferenceTest {
public ByteByReferenceTest() {
}
@BeforeClass
public static void setUpClass() throws Exception {
}
@AfterClass
public static void tearDownClass() throws Exception {
}
@Before
public void setUp() {
}
@After
public void tearDown() {
}
public static interface TestLib {
byte ptr_ret_int8_t(ByteByReference p, int offset);
void ptr_set_int_t(ByteByReference p, int offset, byte value);
}
public static interface TestLibInOnly {
byte ptr_ret_int8_t(@In ByteByReference p, int offset);
void ptr_set_int8_t(@In ByteByReference p, int offset, byte value);
}
public static interface TestLibOutOnly {
byte ptr_ret_int8_t(@Out ByteByReference p, int offset);
void ptr_set_int8_t(@Out ByteByReference p, int offset, byte value);
}
@Test public void inOnlyReferenceSet() {
TestLibInOnly lib = TstUtil.loadTestLib(TestLibInOnly.class);
final byte MAGIC = (byte) 0xef;
ByteByReference ref = new ByteByReference(MAGIC);
assertEquals("Wrong value passed", MAGIC, lib.ptr_ret_int8_t(ref, 0));
}
@Test public void inOnlyByteReferenceNotWritten() {
TestLibInOnly lib = TstUtil.loadTestLib(TestLibInOnly.class);
final byte MAGIC = (byte) 0xef;
ByteByReference ref = new ByteByReference(MAGIC);
lib.ptr_set_int8_t(ref, 0, (byte) 0);
assertEquals("Int reference written when it should not be", Byte.valueOf(MAGIC), ref.getValue());
}
@Test public void outOnlyByteReferenceNotRead() {
TestLibOutOnly lib = TstUtil.loadTestLib(TestLibOutOnly.class);
final byte MAGIC = (byte) 0xef;
ByteByReference ref = new ByteByReference(MAGIC);
assertTrue("Reference value passed to native code when it should not be", MAGIC != lib.ptr_ret_int8_t(ref, 0));
}
@Test public void outOnlyByteReferenceGet() {
TestLibOutOnly lib = TstUtil.loadTestLib(TestLibOutOnly.class);
final byte MAGIC = (byte) 0xef;
ByteByReference ref = new ByteByReference((byte) 0);
lib.ptr_set_int8_t(ref, 0, MAGIC);
assertEquals("Reference value not set", Byte.valueOf(MAGIC), ref.getValue());
}
} jaffl-0.5.9/test/com/kenai/jaffl/byref/IntByReferenceTest.java 0000664 0000000 0000000 00000005016 12017475436 0024206 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.byref;
import com.kenai.jaffl.TstUtil;
import com.kenai.jaffl.annotations.In;
import com.kenai.jaffl.annotations.Out;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
/**
*
*/
public class IntByReferenceTest {
public IntByReferenceTest() {
}
@BeforeClass
public static void setUpClass() throws Exception {
}
@AfterClass
public static void tearDownClass() throws Exception {
}
@Before
public void setUp() {
}
@After
public void tearDown() {
}
public static interface TestLib {
int ptr_ret_int32_t(IntByReference p, int offset);
void ptr_set_int32_t(IntByReference p, int offset, int value);
}
public static interface TestLibInOnly {
int ptr_ret_int32_t(@In IntByReference p, int offset);
void ptr_set_int32_t(@In IntByReference p, int offset, int value);
}
public static interface TestLibOutOnly {
int ptr_ret_int32_t(@Out IntByReference p, int offset);
void ptr_set_int32_t(@Out IntByReference p, int offset, int value);
}
@Test public void inOnlyIntReferenceSet() {
TestLibInOnly lib = TstUtil.loadTestLib(TestLibInOnly.class);
final int MAGIC = 0xdeadbeef;
IntByReference ref = new IntByReference(MAGIC);
assertEquals("Wrong value passed", MAGIC, lib.ptr_ret_int32_t(ref, 0));
}
@Test public void inOnlyIntReferenceNotWritten() {
TestLibInOnly lib = TstUtil.loadTestLib(TestLibInOnly.class);
final int MAGIC = 0xdeadbeef;
IntByReference ref = new IntByReference(MAGIC);
lib.ptr_set_int32_t(ref, 0, 0);
assertEquals("Int reference written when it should not be", Integer.valueOf(MAGIC), ref.getValue());
}
@Test public void outOnlyIntReferenceNotRead() {
TestLibOutOnly lib = TstUtil.loadTestLib(TestLibOutOnly.class);
final int MAGIC = 0xdeadbeef;
IntByReference ref = new IntByReference(MAGIC);
assertTrue("Reference value passed to native code when it should not be", MAGIC != lib.ptr_ret_int32_t(ref, 0));
}
@Test public void outOnlyIntReferenceGet() {
TestLibOutOnly lib = TstUtil.loadTestLib(TestLibOutOnly.class);
final int MAGIC = 0xdeadbeef;
IntByReference ref = new IntByReference(0);
lib.ptr_set_int32_t(ref, 0, MAGIC);
assertEquals("Reference value not set", Integer.valueOf(MAGIC), ref.getValue());
}
} jaffl-0.5.9/test/com/kenai/jaffl/struct/ 0000775 0000000 0000000 00000000000 12017475436 0020052 5 ustar 00root root 0000000 0000000 jaffl-0.5.9/test/com/kenai/jaffl/struct/AlignmentTest.java 0000664 0000000 0000000 00000002353 12017475436 0023476 0 ustar 00root root 0000000 0000000 /*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.kenai.jaffl.struct;
import com.kenai.jaffl.Platform;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
/**
*
* @author wayne
*/
public class AlignmentTest {
public AlignmentTest() {
}
@BeforeClass
public static void setUpClass() throws Exception {
}
@AfterClass
public static void tearDownClass() throws Exception {
}
@Before
public void setUp() {
}
@After
public void tearDown() {
}
// TODO add test methods here.
// The methods must be annotated with annotation @Test. For example:
//
// @Test
// public void hello() {}
class PointerStruct extends Struct {
public final Signed8 s8 = new Signed8();
public final Pointer p = new Pointer();
}
@Test public void alignPointer() throws Throwable {
PointerStruct s = new PointerStruct();
final int SIZE = Platform.getPlatform().addressSize() == 32 ? 8 : 16;
assertEquals("Incorrect pointer field alignment", SIZE, StructUtil.getSize(s));
}
} jaffl-0.5.9/test/com/kenai/jaffl/struct/ArrayTest.java 0000664 0000000 0000000 00000004360 12017475436 0022636 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.struct;
import com.kenai.jaffl.MemoryIO;
import com.kenai.jaffl.TstUtil;
import com.kenai.jaffl.provider.AbstractArrayMemoryIO;
import com.kenai.jaffl.provider.DelegatingMemoryIO;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
public class ArrayTest {
public ArrayTest() {
}
@BeforeClass
public static void setUpClass() throws Exception {
}
@AfterClass
public static void tearDownClass() throws Exception {
}
@Before
public void setUp() {
}
@After
public void tearDown() {
}
public static final class s8 extends Struct {
public final Signed8 s8 = new Signed8();
}
public static final class s32 extends Struct {
public final Signed8 s8 = new Signed8();
}
public static interface TestLib {
byte ptr_ret_int8_t(s8[] s, int index);
}
// TODO add test methods here.
// The methods must be annotated with annotation @Test. For example:
//
// @Test
// public void hello() {}
@Test public void s8Array() {
TestLib testlib = TstUtil.loadTestLib(TestLib.class);
s8[] array = StructUtil.newArray(s8.class, 10);
assertEquals("Array length incorrect", 10, array.length);
for (int i = 0; i < array.length; ++i) {
assertNotNull("Memory not allocated for array member", StructUtil.getMemoryIO(array[i]));
}
MemoryIO io = ((DelegatingMemoryIO) StructUtil.getMemoryIO(array[0])).getDelegatedMemoryIO();
for (int i = 0; i < array.length; ++i) {
assertSame("Different backing memory", io, ((DelegatingMemoryIO) StructUtil.getMemoryIO(array[i])).getDelegatedMemoryIO());
}
if (io instanceof AbstractArrayMemoryIO) {
assertEquals("Incorrect size", array.length, ((AbstractArrayMemoryIO)io).length());
}
for (int i = 0; i < array.length; ++i) {
array[i].s8.set((byte) i);
}
for (int i = 0; i < array.length; ++i) {
assertEquals("Incorrect value written to native memory at index " + i,
(byte) i, testlib.ptr_ret_int8_t(array, i));
}
}
} jaffl-0.5.9/test/com/kenai/jaffl/struct/AsciiStringFieldTest.java 0000664 0000000 0000000 00000005011 12017475436 0024735 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2008 Wayne Meissner
*
* This file is part of jffi.
*
* This code is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* version 3 for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with this work. If not, see .
*/
package com.kenai.jaffl.struct;
import com.kenai.jaffl.annotations.In;
import com.kenai.jaffl.annotations.Out;
import com.kenai.jaffl.annotations.Pinned;
import com.kenai.jaffl.annotations.Transient;
import com.kenai.jaffl.TstUtil;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
/**
*
* @author wayne
*/
public class AsciiStringFieldTest {
public AsciiStringFieldTest() {
}
public class StringFieldStruct extends Struct {
public final String string = new AsciiString(32);
}
public static interface TestLib {
// This makes use of the string being the first field in the struct
int string_equals(@Pinned @In @Transient StringFieldStruct s1, String s2);
int copyByteBuffer(@Pinned @Out StringFieldStruct dst, @In byte[] src, int len);
int copyByteBuffer(@Pinned @Out byte[] dst, @Pinned @In @Transient StringFieldStruct src, int len);
int copyByteBuffer(@Pinned @Out StringBuilder dst, @Pinned @In @Transient StringFieldStruct src, int len);
}
static TestLib testlib;
@BeforeClass
public static void setUpClass() throws Exception {
testlib = TstUtil.loadTestLib(TestLib.class);
}
@AfterClass
public static void tearDownClass() throws Exception {
}
@Before
public void setUp() {
}
@After
public void tearDown() {
}
@Test
public void stringFieldFirstInStruct() {
StringFieldStruct s = new StringFieldStruct();
final String MAGIC = "test";
s.string.set(MAGIC);
StringBuilder tmp = new StringBuilder(s.string.length());
testlib.copyByteBuffer(tmp, s, s.string.length());
assertEquals("String not put into struct correctly", MAGIC, tmp.toString());
}
} jaffl-0.5.9/test/com/kenai/jaffl/struct/EnumTest.java 0000664 0000000 0000000 00000015433 12017475436 0022467 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2008 Wayne Meissner
*
* This file is part of jffi.
*
* This code is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* version 3 for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with this work. If not, see .
*/
package com.kenai.jaffl.struct;
import com.kenai.jaffl.util.EnumMapper;
import com.kenai.jaffl.TstUtil;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
/**
*
* @author wayne
*/
public class EnumTest {
public EnumTest() {
}
public enum TestEnum {
ZERO,
B,
MAGIC;
}
public class struct1 extends Struct {
public final Enum8 b = new Enum8(TestEnum.class);
public final Enum16 s = new Enum16(TestEnum.class);
public final Enum32 i = new Enum32(TestEnum.class);
public final Enum64 i64 = new Enum64(TestEnum.class);
public final EnumLong l = new EnumLong(TestEnum.class);
}
public static interface TestLib {
byte struct_field_Signed8(struct1 s);
short struct_field_Signed16(struct1 s);
int struct_field_Signed32(struct1 s);
long struct_field_Signed64(struct1 s);
float struct_field_Float32(struct1 s);
double struct_field_Float64(struct1 s);
short struct_align_Signed16(Int16Align s);
int struct_align_Signed32(Int32Align s);
long struct_align_Signed64(Int64Align s);
long struct_align_SignedLong(LongAlign s);
// float struct_align_Float32(Float32Align s);
// double struct_align_Float64(Float64Align s);
// void struct_set_string(struct1 s, String string);
}
static TestLib testlib;
@BeforeClass
public static void setUpClass() throws Exception {
testlib = TstUtil.loadTestLib(TestLib.class);
}
@AfterClass
public static void tearDownClass() throws Exception {
}
@Before
public void setUp() {
}
@After
public void tearDown() {
}
// TODO add test methods here.
// The methods must be annotated with annotation @Test. For example:
//
// @Test
// public void hello() {}
public static class Int16Align extends Struct {
public final Enum8 first = new Enum8(TestEnum.class);
public final Enum16 s = new Enum16(TestEnum.class);
}
public static class Int32Align extends Struct {
public final Enum8 first = new Enum8(TestEnum.class);
public final Enum32 i = new Enum32(TestEnum.class);
}
public static class Int64Align extends Struct {
public final Enum8 first = new Enum8(TestEnum.class);
public final Enum64 l = new Enum64(TestEnum.class);
}
public static class LongAlign extends Struct {
public final Enum8 first = new Enum8(TestEnum.class);
public final EnumLong l = new EnumLong(TestEnum.class);
}
@Test public void testInt8InitialValue() {
struct1 s = new struct1();
assertEquals("default value not zero", TestEnum.ZERO, s.b.get());
}
@Test public void testInt8Set() {
struct1 s = new struct1();
final TestEnum MAGIC = TestEnum.MAGIC;
s.b.set(MAGIC);
assertEquals("Byte value not set correctly", MAGIC, s.b.get());
}
@Test
public void byteField() {
final byte MAGIC = (byte) EnumMapper.getInstance().intValue(TestEnum.MAGIC);
struct1 s = new struct1();
s.b.set(TestEnum.MAGIC);
assertEquals("byte field not set", MAGIC, testlib.struct_field_Signed8(s));
s.b.set(TestEnum.ZERO);
assertEquals("byte field not cleared", (byte) 0, testlib.struct_field_Signed8(s));
}
@Test
public void shortField() {
final short MAGIC = (short) EnumMapper.getInstance().intValue(TestEnum.MAGIC);
struct1 s = new struct1();
s.s.set(TestEnum.MAGIC);
assertEquals("short field not set", MAGIC, testlib.struct_field_Signed16(s));
s.s.set(TestEnum.ZERO);
assertEquals("short field not cleared", (short) 0, testlib.struct_field_Signed16(s));
}
@Test
public void intField() {
final int MAGIC = EnumMapper.getInstance().intValue(TestEnum.MAGIC);
struct1 s = new struct1();
s.i.set(TestEnum.MAGIC);
assertEquals("int field not set", MAGIC, testlib.struct_field_Signed32(s));
s.i.set(TestEnum.ZERO);
assertEquals("int field not cleared", 0, testlib.struct_field_Signed32(s));
}
@Test
public void longField() {
final long MAGIC = EnumMapper.getInstance().intValue(TestEnum.MAGIC);
struct1 s = new struct1();
s.i64.set(TestEnum.MAGIC);
assertEquals("long field not set", MAGIC, testlib.struct_field_Signed64(s));
s.i64.set(TestEnum.ZERO);
assertEquals("long field not cleared", 0L, testlib.struct_field_Signed64(s));
}
@Test
public void alignInt16Field() {
final short MAGIC = (short) EnumMapper.getInstance().intValue(TestEnum.MAGIC);
Int16Align s = new Int16Align();
s.s.set(TestEnum.MAGIC);
assertEquals("short field not aligned", MAGIC, testlib.struct_align_Signed16(s));
}
@Test
public void alignSigned32Field() {
final int MAGIC = (int) EnumMapper.getInstance().intValue(TestEnum.MAGIC);
Int32Align s = new Int32Align();
s.i.set(TestEnum.MAGIC);
assertEquals("int field not aligned", MAGIC, testlib.struct_align_Signed32(s));
}
@Test
public void alignSigned64Field() {
final long MAGIC = EnumMapper.getInstance().intValue(TestEnum.MAGIC);
Int64Align s = new Int64Align();
s.l.set(TestEnum.MAGIC);
assertEquals("long field not aligned", MAGIC, testlib.struct_align_Signed64(s));
}
@Test
public void alignSignedLongField() {
final long MAGIC = EnumMapper.getInstance().intValue(TestEnum.MAGIC);
LongAlign s = new LongAlign();
s.l.set(TestEnum.MAGIC);
assertEquals("native long field not aligned", MAGIC, testlib.struct_align_SignedLong(s));
}
} jaffl-0.5.9/test/com/kenai/jaffl/struct/PaddingTest.java 0000664 0000000 0000000 00000001651 12017475436 0023126 0 ustar 00root root 0000000 0000000
package com.kenai.jaffl.struct;
import com.kenai.jaffl.Type;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
public class PaddingTest {
public PaddingTest() {
}
@BeforeClass
public static void setUpClass() throws Exception {
}
@AfterClass
public static void tearDownClass() throws Exception {
}
@Before
public void setUp() {
}
@After
public void tearDown() {
}
static final class LongPadding extends Struct {
public final Signed8 s8 = new Signed8();
public final Padding pad = new Padding(Type.SLONG, 3);
}
@Test public void longPadding() throws Throwable {
final int SIZE = Type.SLONG.alignment() + (Type.SLONG.size() * 3);
assertEquals("incorrect size", SIZE, StructUtil.getSize(new LongPadding()));
}
} jaffl-0.5.9/test/com/kenai/jaffl/struct/StructureTest.java 0000664 0000000 0000000 00000023527 12017475436 0023566 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2008 Wayne Meissner
*
* This file is part of jffi.
*
* This code is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* version 3 for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with this work. If not, see .
*/
package com.kenai.jaffl.struct;
import com.kenai.jaffl.MemoryIO;
import com.kenai.jaffl.TstUtil;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
/**
*
*/
public class StructureTest {
public StructureTest() {
}
public static interface TestLib {
byte struct_field_Signed8(struct1 s);
short struct_field_Signed16(struct1 s);
int struct_field_Signed32(struct1 s);
long struct_field_Signed64(struct1 s);
float struct_field_Float32(struct1 s);
double struct_field_Float64(struct1 s);
short struct_align_Signed16(Int16Align s);
int struct_align_Signed32(Int32Align s);
long struct_align_Signed64(Int64Align s);
long struct_align_SignedLong(LongAlign s);
struct1 struct_make_struct(byte b, short s, int i, long ll, float f, double d);
// float struct_align_Float32(Float32Align s);
// double struct_align_Float64(Float64Align s);
// void struct_set_string(struct1 s, String string);
}
static TestLib testlib;
@BeforeClass
public static void setUpClass() throws Exception {
testlib = TstUtil.loadTestLib(TestLib.class);
}
@AfterClass
public static void tearDownClass() throws Exception {
}
@Before
public void setUp() {
}
@After
public void tearDown() {
}
public static class struct1 extends Struct {
public final Signed8 b = new Signed8();
public final Signed16 s = new Signed16();
public final Signed32 i = new Signed32();
public final Signed64 i64 = new Signed64();
public final SignedLong l = new SignedLong();
public final Float f = new Float();
public final Double d = new Double();
}
public static class Int16Align extends Struct {
public final Signed8 first = new Signed8();
public final Signed16 s = new Signed16();
}
public static class Int32Align extends Struct {
public final Signed8 first = new Signed8();
public final Signed32 i = new Signed32();
}
public static class Int64Align extends Struct {
public final Signed8 first = new Signed8();
public final Signed64 l = new Signed64();
}
public static class LongAlign extends Struct {
public final Signed8 first = new Signed8();
public final SignedLong l = new SignedLong();
}
@Test public void testInt8InitialValue() {
struct1 s = new struct1();
assertEquals("default value not zero", (byte) 0, s.b.get());
}
@Test public void testInt8Set() {
struct1 s = new struct1();
final byte MAGIC = (byte) 0xfe;
s.b.set(MAGIC);
assertEquals("Byte value not set correctly", MAGIC, s.b.get());
}
@Test
public void byteField() {
final byte MAGIC = (byte) 0xbe;
struct1 s = new struct1();
s.b.set(MAGIC);
assertEquals("byte field not set", MAGIC, testlib.struct_field_Signed8(s));
s.b.set((byte) 0);
assertEquals("byte field not cleared", (byte) 0, testlib.struct_field_Signed8(s));
}
@Test
public void shortField() {
final short MAGIC = (short) 0xbeef;
struct1 s = new struct1();
s.s.set(MAGIC);
assertEquals("short field not set", MAGIC, testlib.struct_field_Signed16(s));
s.s.set((short) 0);
assertEquals("short field not cleared", (short) 0, testlib.struct_field_Signed16(s));
}
@Test
public void intField() {
final int MAGIC = 0xdeadbeef;
struct1 s = new struct1();
s.i.set(MAGIC);
assertEquals("int field not set", MAGIC, testlib.struct_field_Signed32(s));
s.i.set(0);
assertEquals("int field not cleared", 0, testlib.struct_field_Signed32(s));
}
@Test
public void longField() {
final long MAGIC = 0x1234deadbeef5678L;
struct1 s = new struct1();
s.i64.set(MAGIC);
assertEquals("long field not set", MAGIC, testlib.struct_field_Signed64(s));
s.i64.set(0);
assertEquals("long field not cleared", 0L, testlib.struct_field_Signed64(s));
}
@Test
public void alignInt16Field() {
final short MAGIC = (short) 0xbeef;
Int16Align s = new Int16Align();
s.s.set(MAGIC);
assertEquals("short field not aligned", MAGIC, testlib.struct_align_Signed16(s));
}
@Test
public void alignSigned32Field() {
final int MAGIC = (int) 0xdeadbeef;
Int32Align s = new Int32Align();
s.i.set(MAGIC);
assertEquals("int field not aligned", MAGIC, testlib.struct_align_Signed32(s));
}
@Test
public void alignSigned64Field() {
final long MAGIC = 0x1234deadbeef5678L;
Int64Align s = new Int64Align();
s.l.set(MAGIC);
assertEquals("long field not aligned", MAGIC, testlib.struct_align_Signed64(s));
}
@Test
public void alignSignedLongField() {
final long MAGIC = 0xdeadbeef;
LongAlign s = new LongAlign();
s.l.set(MAGIC);
assertEquals("native long field not aligned", MAGIC, testlib.struct_align_SignedLong(s));
}
@Test
public void returnStructAddress() throws Throwable {
final byte B = 0x11;
final short S = 0x2222;
final int I = 0x33333333;
final long L = 0x4444444444444444L;
final float F = (float) 0x55555555;
final double D = (double) 0x6666666666666666L;
struct1 s = testlib.struct_make_struct(B, S, I, L, F, D);
assertEquals("Incorrect byte value in struct", B, s.b.get());
assertEquals("Incorrect short value in struct", S, s.s.get());
assertEquals("Incorrect int value in struct", I, s.i.get());
assertEquals("Incorrect int64 value in struct", L, s.i64.get());
assertEquals("Incorrect float value in struct", F, s.f.get(), 0f);
assertEquals("Incorrect double value in struct", D, s.d.get(), 0d);
}
private static final class ArrayTest extends Struct {
public final Signed8[] byteArray = array(new Signed8[8]);
}
@Test
public void arrayMember() {
ArrayTest s = new ArrayTest();
assertEquals("First element not at correct offset", 0L, s.byteArray[0].offset());
assertEquals("Second element not at correct offset", 1L, s.byteArray[1].offset());
assertEquals("Last element not at correct offset", 7L, s.byteArray[7].offset());
}
private static final class Unsigned8Test extends Struct {
public final Unsigned8 u8 = new Unsigned8();
}
@Test
public void unsigned8() {
Unsigned8Test s = new Unsigned8Test();
final short MAGIC = (short) Byte.MAX_VALUE + 1;
s.u8.set(MAGIC);
assertEquals("Incorrect unsigned byte value", MAGIC, s.u8.shortValue());
}
private static final class Unsigned16Test extends Struct {
public final Unsigned16 u16 = new Unsigned16();
}
@Test
public void unsigned16() {
Unsigned16Test s = new Unsigned16Test();
final int MAGIC = (int) Short.MAX_VALUE + 1;
s.u16.set(MAGIC);
assertEquals("Incorrect unsigned short value", MAGIC, s.u16.intValue());
}
private static final class Unsigned32Test extends Struct {
public final Unsigned32 u32 = new Unsigned32();
}
@Test
public void unsigned32() {
Unsigned32Test s = new Unsigned32Test();
final long MAGIC = (long) Integer.MAX_VALUE + 1;
s.u32.set(MAGIC);
assertEquals("Incorrect unsigned int value", MAGIC, s.u32.longValue());
}
private static final class Unsigned64Test extends Struct {
public final Unsigned64 u64 = new Unsigned64();
}
@Test
public void unsigned64() {
Unsigned64Test s = new Unsigned64Test();
final long MAGIC = Long.MAX_VALUE;
s.u64.set(MAGIC);
assertEquals("Incorrect unsigned long long value", MAGIC, s.u64.longValue());
// Just make sure that an Unsigned64 doesn't do anything weird with negative values
s.u64.set(Long.MIN_VALUE);
assertEquals("Incorrect unsigned long long value", Long.MIN_VALUE, s.u64.longValue());
}
private static final class UnsignedLongTest extends Struct {
public final UnsignedLong ul = new UnsignedLong();
}
@Test
public void unsignedLong() {
UnsignedLongTest s = new UnsignedLongTest();
final long MAGIC = (long) Integer.MAX_VALUE + 1;
s.ul.set(MAGIC);
assertEquals("Incorrect unsigned long value", MAGIC, s.ul.longValue());
}
private class InnerStruct extends Struct {
public final Signed8 s8 = new Signed8();
}
private class InnerTest extends Struct {
public final Signed32 i32 = new Signed32();
public final InnerStruct s = inner(new InnerStruct());
}
@Test public void innerStruct() {
InnerTest t = new InnerTest();
MemoryIO io = StructUtil.getMemoryIO(t);
io.putInt(0, 0xdeadbeef);
io.putByte(4, (byte) 0x12);
assertEquals("incorrect inner struct field value", (byte) 0x12, t.s.s8.get());
}
} jaffl-0.5.9/test/com/kenai/jaffl/struct/UTF8StringFieldTest.java 0000664 0000000 0000000 00000006417 12017475436 0024446 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2008 Wayne Meissner
*
* This file is part of jffi.
*
* This code is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* version 3 for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with this work. If not, see .
*/
package com.kenai.jaffl.struct;
import com.kenai.jaffl.TstUtil;
import com.kenai.jaffl.annotations.In;
import com.kenai.jaffl.annotations.Out;
import com.kenai.jaffl.annotations.Pinned;
import com.kenai.jaffl.annotations.Transient;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
/**
*
* @author wayne
*/
public class UTF8StringFieldTest {
public UTF8StringFieldTest() {
}
public class StringFieldStruct extends Struct {
public final UTF8String string = new UTF8String(32);
}
public static interface TestLib {
// This makes use of the string being the first field in the struct
int string_equals(@Pinned @In @Transient StringFieldStruct s1, String s2);
int copyByteBuffer(@Pinned @Out StringFieldStruct dst, @In byte[] src, int len);
int copyByteBuffer(@Pinned @Out byte[] dst, @Pinned @In @Transient StringFieldStruct src, int len);
int copyByteBuffer(@Pinned @Out StringBuilder dst, @Pinned @In @Transient StringFieldStruct src, int len);
}
static TestLib testlib;
@BeforeClass
public static void setUpClass() throws Exception {
testlib = TstUtil.loadTestLib(TestLib.class);
}
@AfterClass
public static void tearDownClass() throws Exception {
}
@Before
public void setUp() {
}
@After
public void tearDown() {
}
@Test public void stringFieldFirstInStruct() {
StringFieldStruct s = new StringFieldStruct();
final String MAGIC = "test";
s.string.set(MAGIC);
StringBuilder tmp = new StringBuilder(s.string.length());
testlib.copyByteBuffer(tmp, s, s.string.length());
assertEquals("String not put into struct correctly", MAGIC, tmp.toString());
}
private final class SockaddrUnix extends Struct {
private final Signed8 sun_len = new Signed8();
private final Signed8 sun_family = new Signed8();
private final UTF8String sun_path = new UTF8String(100);
}
@Test public void SockaddrUnix() {
final int SUN_LEN = 1;
final int SUN_FAM = 2;
final String SUN_PATH = "test";
SockaddrUnix s = new SockaddrUnix();
s.sun_len.set(SUN_LEN);
s.sun_family.set(SUN_FAM);
s.sun_path.set(SUN_PATH);
assertEquals("Incorrect sun_len value", SUN_LEN, s.sun_len.intValue());
assertEquals("Incorrect sun_fam value", SUN_FAM, s.sun_family.intValue());
assertEquals("Incorrect sun_path value", SUN_PATH, s.sun_path.toString());
}
} jaffl-0.5.9/test/com/kenai/jaffl/struct/UnionTest.java 0000664 0000000 0000000 00000007677 12017475436 0022666 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2008 Wayne Meissner
*
* This file is part of jffi.
*
* This code is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* version 3 for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with this work. If not, see .
*/
package com.kenai.jaffl.struct;
import java.nio.ByteOrder;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
/**
*
*/
public class UnionTest {
public UnionTest() {
}
@BeforeClass
public static void setUpClass() throws Exception {
}
@AfterClass
public static void tearDownClass() throws Exception {
}
@Before
public void setUp() {
}
@After
public void tearDown() {
}
public static final class union extends Union {
public final Signed8 s8 = new Signed8();
public final Unsigned8 u8 = new Unsigned8();
public final Signed16 s16 = new Signed16();
public final Unsigned16 u16 = new Unsigned16();
public final Signed32 s32 = new Signed32();
public final Unsigned32 u32 = new Unsigned32();
public final Signed64 s64 = new Signed64();
public final Unsigned64 u64 = new Unsigned64();
}
@Test public void offsetTest() {
union u = new union();
assertEquals("Not at offset 0", 0L, u.s8.offset());
assertEquals("Not at offset 0", 0L, u.u8.offset());
assertEquals("Not at offset 0", 0L, u.s16.offset());
assertEquals("Not at offset 0", 0L, u.u16.offset());
assertEquals("Not at offset 0", 0L, u.s32.offset());
assertEquals("Not at offset 0", 0L, u.s32.offset());
assertEquals("Not at offset 0", 0L, u.s64.offset());
assertEquals("Not at offset 0", 0L, u.u64.offset());
}
@Test public void s8s16() {
union u = new union();
final int MAGIC = ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN)
? 0xef00 : 0x00ef;
u.s16.set((short) MAGIC);
assertEquals("Wrong value", (byte) 0xef, u.s8.get());
}
@Test public void s8s32() {
union u = new union();
final int MAGIC = ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN)
? 0xef000000 : 0x000000ef;
u.s32.set(MAGIC);
assertEquals("Wrong value", (byte) 0xef, u.s8.get());
}
@Test public void s16s32() {
union u = new union();
final int MAGIC = ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN)
? 0xdead0000 : 0x0000dead;
u.s32.set(MAGIC);
assertEquals("Wrong value", (short) 0xdead, u.s16.get());
}
@Test public void s8s64() {
union u = new union();
final long MAGIC = ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN)
? 0xef00000000000000L : 0xefL;
u.s64.set(MAGIC);
assertEquals("Wrong value", (byte) 0xef, u.s8.get());
}
@Test public void s16s64() {
union u = new union();
final long MAGIC = ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN)
? 0xbeef000000000000L : 0xbeefL;
u.s64.set(MAGIC);
assertEquals("Wrong value", (short) 0xbeef, u.s16.get());
}
@Test public void s32s64() {
union u = new union();
final long MAGIC = ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN)
? 0xdeadbeef00000000L : 0xdeadbeefL;
u.s64.set(MAGIC);
assertEquals("Wrong value", 0xdeadbeef, u.s32.get());
}
}