options) {
this.options = options;
+ this.function = new Function(address, callingConvention, (String) options.get(Library.OPTION_STRING_ENCODING));
}
/** Chain invocation to the native function. */
@@ -642,15 +649,13 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl
if (Library.Handler.OBJECT_TOSTRING.equals(method)) {
String str = "Proxy interface to " + function;
Method m = (Method)options.get(Function.OPTION_INVOKING_METHOD);
- Class cls = findCallbackClass(m.getDeclaringClass());
+ Class> cls = findCallbackClass(m.getDeclaringClass());
str += " (" + cls.getName() + ")";
return str;
- }
- else if (Library.Handler.OBJECT_HASHCODE.equals(method)) {
- return new Integer(hashCode());
- }
- else if (Library.Handler.OBJECT_EQUALS.equals(method)) {
+ } else if (Library.Handler.OBJECT_HASHCODE.equals(method)) {
+ return Integer.valueOf(hashCode());
+ } else if (Library.Handler.OBJECT_EQUALS.equals(method)) {
Object o = args[0];
if (o != null && Proxy.isProxyClass(o.getClass())) {
return Function.valueOf(Proxy.getInvocationHandler(o) == this);
@@ -671,7 +676,7 @@ public Pointer getPointer() {
* Other types (String, WString, Structure, arrays, NativeMapped,
* etc) are supported in the Java library.
*/
- private static boolean isAllowableNativeType(Class cls) {
+ private static boolean isAllowableNativeType(Class> cls) {
return cls == void.class || cls == Void.class
|| cls == boolean.class || cls == Boolean.class
|| cls == byte.class || cls == Byte.class
diff --git a/src/com/sun/jna/DefaultTypeMapper.java b/src/com/sun/jna/DefaultTypeMapper.java
index af288a5801..7df92177fc 100644
--- a/src/com/sun/jna/DefaultTypeMapper.java
+++ b/src/com/sun/jna/DefaultTypeMapper.java
@@ -8,87 +8,74 @@
* This library 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 for more details.
+ * Lesser General Public License for more details.
*/
package com.sun.jna;
import java.util.ArrayList;
-import java.util.Iterator;
+import java.util.Collection;
import java.util.List;
/** Provide custom mappings to and from native types. The default lookup
* checks classes corresponding to converters in the order added; if the
* class to be converted is an instance of the converter's registered class,
- * the converter will be used.
- * Derived classes should install additional converters using
+ * the converter will be used.
+ * Derived classes should install additional converters using
* {@link #addToNativeConverter}
* and/or {@link #addFromNativeConverter} in the default constructor. Classes
* for primitive types will automatically register for the corresponding
- * Object type and vice versa (i.e. you don't have to register both
+ * Object type and vice versa (i.e. you don't have to register both
* int.class
and Integer.class
).
* If you want different mapping behavior than the default, simply override
* {@link #getToNativeConverter} and {@link #getFromNativeConverter}.
- * @see Library#OPTION_TYPE_MAPPER
+ * @see Library#OPTION_TYPE_MAPPER
*/
public class DefaultTypeMapper implements TypeMapper {
private static class Entry {
- public Class type;
+ public Class> type;
public Object converter;
- public Entry(Class type, Object converter) {
+ public Entry(Class> type, Object converter) {
this.type = type;
this.converter = converter;
}
}
- private List toNativeConverters = new ArrayList();
- private List fromNativeConverters = new ArrayList();
- private Class getAltClass(Class cls) {
+
+ private List toNativeConverters = new ArrayList();
+ private List fromNativeConverters = new ArrayList();
+
+ private Class> getAltClass(Class> cls) {
if (cls == Boolean.class) {
return boolean.class;
- }
- else if (cls == boolean.class) {
+ } else if (cls == boolean.class) {
return Boolean.class;
- }
- else if (cls == Byte.class) {
+ } else if (cls == Byte.class) {
return byte.class;
- }
- else if (cls == byte.class) {
+ } else if (cls == byte.class) {
return Byte.class;
- }
- else if (cls == Character.class) {
+ } else if (cls == Character.class) {
return char.class;
- }
- else if (cls == char.class) {
+ } else if (cls == char.class) {
return Character.class;
- }
- else if (cls == Short.class) {
+ } else if (cls == Short.class) {
return short.class;
- }
- else if (cls == short.class) {
+ } else if (cls == short.class) {
return Short.class;
- }
- else if (cls == Integer.class) {
+ } else if (cls == Integer.class) {
return int.class;
- }
- else if (cls == int.class) {
+ } else if (cls == int.class) {
return Integer.class;
- }
- else if (cls == Long.class) {
+ } else if (cls == Long.class) {
return long.class;
- }
- else if (cls == long.class) {
+ } else if (cls == long.class) {
return Long.class;
- }
- else if (cls == Float.class) {
+ } else if (cls == Float.class) {
return float.class;
- }
- else if (cls == float.class) {
+ } else if (cls == float.class) {
return Float.class;
- }
- else if (cls == Double.class) {
+ } else if (cls == Double.class) {
return double.class;
- }
- else if (cls == double.class) {
+ } else if (cls == double.class) {
return Double.class;
}
return null;
@@ -100,56 +87,58 @@ else if (cls == double.class) {
* @param converter {@link ToNativeConverter} to transform an object of
* the given Java class into its native-compatible form.
*/
- public void addToNativeConverter(Class cls, ToNativeConverter converter) {
+ public void addToNativeConverter(Class> cls, ToNativeConverter converter) {
toNativeConverters.add(new Entry(cls, converter));
- Class alt = getAltClass(cls);
+ Class> alt = getAltClass(cls);
if (alt != null) {
toNativeConverters.add(new Entry(alt, converter));
}
}
- /** Add a {@link FromNativeConverter} to convert a native result type into the
+ /**
+ * Add a {@link FromNativeConverter} to convert a native result type into the
* given Java type. Converters are checked for in the order added.
+ *
* @param cls Java class for the Java representation of a native type.
* @param converter {@link FromNativeConverter} to transform a
* native-compatible type into its Java equivalent.
*/
- public void addFromNativeConverter(Class cls, FromNativeConverter converter) {
+ public void addFromNativeConverter(Class> cls, FromNativeConverter converter) {
fromNativeConverters.add(new Entry(cls, converter));
- Class alt = getAltClass(cls);
+ Class> alt = getAltClass(cls);
if (alt != null) {
fromNativeConverters.add(new Entry(alt, converter));
}
}
- /** Add a {@link TypeConverter} to provide bidirectional mapping between
- * a native and Java type.
+
+ /**
+ * Add a {@link TypeConverter} to provide bidirectional mapping between
+ * a native and Java type.
+ *
* @param cls Java class representation for a native type
* @param converter {@link TypeConverter} to translate between native and
* Java types.
*/
- public void addTypeConverter(Class cls, TypeConverter converter) {
+ public void addTypeConverter(Class> cls, TypeConverter converter) {
addFromNativeConverter(cls, converter);
addToNativeConverter(cls, converter);
}
-
- private Object lookupConverter(Class javaClass, List converters) {
- for (Iterator i=converters.iterator();i.hasNext();) {
- Entry entry = (Entry)i.next();
+
+ private Object lookupConverter(Class> javaClass, Collection extends Entry> converters) {
+ for (Entry entry : converters) {
if (entry.type.isAssignableFrom(javaClass)) {
return entry.converter;
}
}
return null;
}
- /* (non-Javadoc)
- * @see com.sun.jna.TypeMapper#getFromNativeConverter(java.lang.Class)
- */
- public FromNativeConverter getFromNativeConverter(Class javaType) {
+
+ @Override
+ public FromNativeConverter getFromNativeConverter(Class> javaType) {
return (FromNativeConverter)lookupConverter(javaType, fromNativeConverters);
}
- /* (non-Javadoc)
- * @see com.sun.jna.TypeMapper#getToNativeConverter(java.lang.Class)
- */
- public ToNativeConverter getToNativeConverter(Class javaType) {
+
+ @Override
+ public ToNativeConverter getToNativeConverter(Class> javaType) {
return (ToNativeConverter)lookupConverter(javaType, toNativeConverters);
}
}
diff --git a/src/com/sun/jna/FromNativeContext.java b/src/com/sun/jna/FromNativeContext.java
index 70b905afd5..12d1727fb7 100644
--- a/src/com/sun/jna/FromNativeContext.java
+++ b/src/com/sun/jna/FromNativeContext.java
@@ -1,25 +1,25 @@
/* Copyright (c) 2007 Timothy Wall, All Rights Reserved
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
- *
+ *
* This library 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 for more details.
+ * Lesser General Public License for more details.
*/
package com.sun.jna;
/** Provides context for converting a native value into a Java type. */
public class FromNativeContext {
- private Class type;
- FromNativeContext(Class javaType) {
+ private Class> type;
+ FromNativeContext(Class> javaType) {
this.type = javaType;
}
/** The desired Java type of the result. */
- public Class getTargetType() {
+ public Class> getTargetType() {
return type;
}
}
diff --git a/src/com/sun/jna/FromNativeConverter.java b/src/com/sun/jna/FromNativeConverter.java
index 2ee1485920..c73c7d7819 100644
--- a/src/com/sun/jna/FromNativeConverter.java
+++ b/src/com/sun/jna/FromNativeConverter.java
@@ -8,7 +8,7 @@
* This library 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 for more details.
+ * Lesser General Public License for more details.
*/
package com.sun.jna;
@@ -16,9 +16,9 @@
/** Define conversion from a native type to the appropriate Java type. */
public interface FromNativeConverter {
/** Convert the given native object into its Java representation using
- * the given context.
+ * the given context.
*/
Object fromNative(Object nativeValue, FromNativeContext context);
/** Indicate the native type used by this converter. */
- Class nativeType();
+ Class> nativeType();
}
diff --git a/src/com/sun/jna/Function.java b/src/com/sun/jna/Function.java
index c47d9db685..de4e9baab8 100644
--- a/src/com/sun/jna/Function.java
+++ b/src/com/sun/jna/Function.java
@@ -6,7 +6,7 @@
* This library 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 for more details.
+ * Lesser General Public License for more details.
*/
package com.sun.jna;
@@ -15,13 +15,13 @@
import java.util.Map;
/**
- * An abstraction for a native function pointer. An instance of
- * Function
represents a pointer to some native function.
+ *
An abstraction for a native function pointer. An instance of
+ * Function
represents a pointer to some native function.
* {@link #invoke(Class,Object[],Map)} is the primary means to call
* the function.
*
* Function call behavior may be modified by passing one of the following call
- * flags:
+ * flags:
*
* {@link Function#C_CONVENTION} Use C calling convention (default)
* {@link Function#ALT_CONVENTION} Use alternate calling convention (e.g. stdcall)
@@ -47,7 +47,7 @@ public interface PostCallRead {
*/
void read();
}
-
+
/** Maximum number of arguments supported by a JNA function call. */
public static final int MAX_NARGS = 256;
@@ -60,14 +60,14 @@ public interface PostCallRead {
/** Whether to throw an exception if last error is non-zero after call. */
public static final int THROW_LAST_ERROR = 0x40;
- static final Integer INTEGER_TRUE = new Integer(-1);
- static final Integer INTEGER_FALSE = new Integer(0);
+ static final Integer INTEGER_TRUE = Integer.valueOf(-1);
+ static final Integer INTEGER_FALSE = Integer.valueOf(0);
- /**
- * Obtain a Function
representing a native
+ /**
+ * Obtain a Function
representing a native
* function that follows the standard "C" calling convention.
- *
- * The allocated instance represents a pointer to the named native
+ *
+ *
The allocated instance represents a pointer to the named native
* function from the named library, called with the standard "C" calling
* convention.
*
@@ -81,12 +81,12 @@ public interface PostCallRead {
public static Function getFunction(String libraryName, String functionName) {
return NativeLibrary.getInstance(libraryName).getFunction(functionName);
}
-
+
/**
- * Obtain a Function
representing a native
+ * Obtain a Function
representing a native
* function.
- *
- *
The allocated instance represents a pointer to the named native
+ *
+ *
The allocated instance represents a pointer to the named native
* function from the named library.
*
* @param libraryName
@@ -95,19 +95,19 @@ public static Function getFunction(String libraryName, String functionName) {
* Name of the native function to be linked with
* @param callFlags
* Function call flags
- *
+ *
* @throws UnsatisfiedLinkError if the library is not found or
* the given function name is not found within the library.
*/
public static Function getFunction(String libraryName, String functionName, int callFlags) {
return NativeLibrary.getInstance(libraryName).getFunction(functionName, callFlags, null);
}
-
+
/**
- * Obtain a Function
representing a native
+ * Obtain a Function
representing a native
* function.
- *
- *
The allocated instance represents a pointer to the named native
+ *
+ *
The allocated instance represents a pointer to the named native
* function from the named library.
*
* @param libraryName
@@ -119,21 +119,21 @@ public static Function getFunction(String libraryName, String functionName, int
* @param encoding
* Encoding to use for conversion between Java and native
* strings.
- *
+ *
* @throws UnsatisfiedLinkError if the library is not found or
* the given function name is not found within the library.
*/
public static Function getFunction(String libraryName, String functionName, int callFlags, String encoding) {
return NativeLibrary.getInstance(libraryName).getFunction(functionName, callFlags, encoding);
}
-
+
/**
- * Obtain a Function
representing a native
+ * Obtain a Function
representing a native
* function pointer. In general, this function should be used by dynamic
* languages; Java code should allow JNA to bind to a specific Callback
* interface instead by defining a return type or Structure field type.
- *
- *
The allocated instance represents a pointer to the native
+ *
+ *
The allocated instance represents a pointer to the native
* function pointer.
*
* @param p Native function pointer
@@ -143,12 +143,12 @@ public static Function getFunction(Pointer p) {
}
/**
- * Obtain a Function
representing a native
+ * Obtain a Function
representing a native
* function pointer. In general, this function should be used by dynamic
* languages; Java code should allow JNA to bind to a specific Callback
- * interface instead by defining a return type or Structure field type.
- *
- *
The allocated instance represents a pointer to the native
+ * interface instead by defining a return type or Structure field type.
+ *
+ *
The allocated instance represents a pointer to the native
* function pointer.
*
* @param p
@@ -166,7 +166,7 @@ public static Function getFunction(Pointer p, int callFlags) {
private final String functionName;
final String encoding;
final int callFlags;
- final Map options;
+ final Map options;
/** For internal JNA use. */
static final String OPTION_INVOKING_METHOD = "invoking-method";
@@ -175,11 +175,11 @@ public static Function getFunction(Pointer p, int callFlags) {
private static final VarArgsChecker IS_VARARGS = VarArgsChecker.create();
/**
- * Create a new Function
that is linked with a native
+ * Create a new Function
that is linked with a native
* function that follows the given calling convention.
- *
- * The allocated instance represents a pointer to the named native
- * function from the supplied library, called with the given calling
+ *
+ *
The allocated instance represents a pointer to the named native
+ * function from the supplied library, called with the given calling
* convention.
*
* @param library
@@ -195,34 +195,33 @@ public static Function getFunction(Pointer p, int callFlags) {
*/
Function(NativeLibrary library, String functionName, int callFlags, String encoding) {
checkCallingConvention(callFlags & MASK_CC);
- if (functionName == null)
+ if (functionName == null) {
throw new NullPointerException("Function name must not be null");
+ }
this.library = library;
this.functionName = functionName;
this.callFlags = callFlags;
this.options = library.options;
- this.encoding = encoding != null
- ? encoding : Native.getDefaultStringEncoding();
+ this.encoding = encoding != null ? encoding : Native.getDefaultStringEncoding();
try {
this.peer = library.getSymbolAddress(functionName);
- }
- catch(UnsatisfiedLinkError e) {
- throw new UnsatisfiedLinkError("Error looking up function '"
- + functionName + "': "
+ } catch(UnsatisfiedLinkError e) {
+ throw new UnsatisfiedLinkError("Error looking up function '"
+ + functionName + "': "
+ e.getMessage());
}
}
-
+
/**
- * Create a new Function
that is linked with a native
+ * Create a new Function
that is linked with a native
* function that follows the given calling convention.
- *
- *
The allocated instance represents a pointer to the given
- * function address, called with the given calling
+ *
+ *
The allocated instance represents a pointer to the given
+ * function address, called with the given calling
* convention.
*
* @param functionAddress
- * Address of the native function
+ * Address of the native function
* @param callFlags
* Function call flags
* @param encoding
@@ -241,12 +240,12 @@ public static Function getFunction(Pointer p, int callFlags) {
this.encoding = encoding != null
? encoding : Native.getDefaultStringEncoding();
}
-
+
private void checkCallingConvention(int convention)
throws IllegalArgumentException {
// TODO: perform per-platform calling convention checks
if ((convention & MASK_CC) != convention) {
- throw new IllegalArgumentException("Unrecognized calling convention: "
+ throw new IllegalArgumentException("Unrecognized calling convention: "
+ convention);
}
}
@@ -262,16 +261,16 @@ public int getCallingConvention() {
/** Invoke the native function with the given arguments, returning the
* native result as an Object.
*/
- public Object invoke(Class returnType, Object[] inArgs) {
+ public Object invoke(Class> returnType, Object[] inArgs) {
return invoke(returnType, inArgs, this.options);
- }
-
+ }
+
/** Invoke the native function with the given arguments, returning the
* native result as an Object.
*/
- public Object invoke(Class returnType, Object[] inArgs, Map options) {
+ public Object invoke(Class> returnType, Object[] inArgs, Map options) {
Method invokingMethod = (Method)options.get(OPTION_INVOKING_METHOD);
- Class[] paramTypes = invokingMethod != null ? invokingMethod.getParameterTypes() : null;
+ Class>[] paramTypes = invokingMethod != null ? invokingMethod.getParameterTypes() : null;
return invoke(invokingMethod, paramTypes, returnType, inArgs, options);
}
@@ -280,7 +279,7 @@ public Object invoke(Class returnType, Object[] inArgs, Map options) {
* types are already at hand. When calling {@link Function#invoke(Class, Object[], Map)},
* the method has to be in the options under key {@link Function#OPTION_INVOKING_METHOD}.
*/
- Object invoke(Method invokingMethod, Class[] paramTypes, Class returnType, Object[] inArgs, Map options) {
+ Object invoke(Method invokingMethod, Class>[] paramTypes, Class> returnType, Object[] inArgs, Map options) {
// Clone the argument array to obtain a scratch space for modified
// types/values
Object[] args = { };
@@ -292,28 +291,25 @@ Object invoke(Method invokingMethod, Class[] paramTypes, Class returnType, Objec
System.arraycopy(inArgs, 0, args, 0, args.length);
}
- TypeMapper mapper =
- (TypeMapper)options.get(Library.OPTION_TYPE_MAPPER);
+ TypeMapper mapper = (TypeMapper)options.get(Library.OPTION_TYPE_MAPPER);
boolean allowObjects = Boolean.TRUE.equals(options.get(Library.OPTION_ALLOW_OBJECTS));
boolean isVarArgs = args.length > 0 && invokingMethod != null ? isVarArgs(invokingMethod) : false;
for (int i=0; i < args.length; i++) {
- Class paramType = invokingMethod != null
+ Class> paramType = invokingMethod != null
? (isVarArgs && i >= paramTypes.length-1
? paramTypes[paramTypes.length-1].getComponentType()
: paramTypes[i])
: null;
- args[i] = convertArgument(args, i, invokingMethod,
- mapper, allowObjects, paramType);
+ args[i] = convertArgument(args, i, invokingMethod, mapper, allowObjects, paramType);
}
-
- Class nativeReturnType = returnType;
+
+ Class> nativeReturnType = returnType;
FromNativeConverter resultConverter = null;
if (NativeMapped.class.isAssignableFrom(returnType)) {
NativeMappedConverter tc = NativeMappedConverter.getInstance(returnType);
resultConverter = tc;
nativeReturnType = tc.nativeType();
- }
- else if (mapper != null) {
+ } else if (mapper != null) {
resultConverter = mapper.getFromNativeConverter(returnType);
if (resultConverter != null) {
nativeReturnType = resultConverter.nativeType();
@@ -321,7 +317,6 @@ else if (mapper != null) {
}
Object result = invoke(args, nativeReturnType, allowObjects);
-
// Convert the result to a custom value/type if appropriate
if (resultConverter != null) {
FromNativeContext context;
@@ -343,13 +338,12 @@ else if (mapper != null) {
if (!(inArg instanceof Structure.ByValue)) {
((Structure)inArg).autoRead();
}
- }
- else if (args[i] instanceof PostCallRead) {
+ } else if (args[i] instanceof PostCallRead) {
((PostCallRead)args[i]).read();
if (args[i] instanceof PointerArray) {
PointerArray array = (PointerArray)args[i];
if (Structure.ByReference[].class.isAssignableFrom(inArg.getClass())) {
- Class type = inArg.getClass().getComponentType();
+ Class> type = inArg.getClass().getComponentType();
Structure[] ss = (Structure[])inArg;
for (int si=0;si < ss.length;si++) {
Pointer p = array.getPointer(Pointer.SIZE * si);
@@ -357,68 +351,54 @@ else if (args[i] instanceof PostCallRead) {
}
}
}
- }
- else if (Structure[].class.isAssignableFrom(inArg.getClass())) {
+ } else if (Structure[].class.isAssignableFrom(inArg.getClass())) {
Structure.autoRead((Structure[])inArg);
}
}
}
-
+
return result;
}
- /** @see NativeLibrary#NativeLibrary(String,String,long,Map) implementation */
- Object invoke(Object[] args, Class returnType, boolean allowObjects) {
+ /* @see NativeLibrary#NativeLibrary(String,String,long,Map) implementation */
+ Object invoke(Object[] args, Class> returnType, boolean allowObjects) {
Object result = null;
if (returnType == null || returnType==void.class || returnType==Void.class) {
Native.invokeVoid(peer, callFlags, args);
result = null;
- }
- else if (returnType==boolean.class || returnType==Boolean.class) {
+ } else if (returnType==boolean.class || returnType==Boolean.class) {
result = valueOf(Native.invokeInt(peer, callFlags, args) != 0);
- }
- else if (returnType==byte.class || returnType==Byte.class) {
- result = new Byte((byte)Native.invokeInt(peer, callFlags, args));
- }
- else if (returnType==short.class || returnType==Short.class) {
- result = new Short((short)Native.invokeInt(peer, callFlags, args));
- }
- else if (returnType==char.class || returnType==Character.class) {
- result = new Character((char)Native.invokeInt(peer, callFlags, args));
- }
- else if (returnType==int.class || returnType==Integer.class) {
- result = new Integer(Native.invokeInt(peer, callFlags, args));
- }
- else if (returnType==long.class || returnType==Long.class) {
- result = new Long(Native.invokeLong(peer, callFlags, args));
- }
- else if (returnType==float.class || returnType==Float.class) {
- result = new Float(Native.invokeFloat(peer, callFlags, args));
- }
- else if (returnType==double.class || returnType==Double.class) {
- result = new Double(Native.invokeDouble(peer, callFlags, args));
- }
- else if (returnType==String.class) {
+ } else if (returnType==byte.class || returnType==Byte.class) {
+ result = Byte.valueOf((byte)Native.invokeInt(peer, callFlags, args));
+ } else if (returnType==short.class || returnType==Short.class) {
+ result = Short.valueOf((short)Native.invokeInt(peer, callFlags, args));
+ } else if (returnType==char.class || returnType==Character.class) {
+ result = Character.valueOf((char)Native.invokeInt(peer, callFlags, args));
+ } else if (returnType==int.class || returnType==Integer.class) {
+ result = Integer.valueOf(Native.invokeInt(peer, callFlags, args));
+ } else if (returnType==long.class || returnType==Long.class) {
+ result = Long.valueOf(Native.invokeLong(peer, callFlags, args));
+ } else if (returnType==float.class || returnType==Float.class) {
+ result = Float.valueOf(Native.invokeFloat(peer, callFlags, args));
+ } else if (returnType==double.class || returnType==Double.class) {
+ result = Double.valueOf(Native.invokeDouble(peer, callFlags, args));
+ } else if (returnType==String.class) {
result = invokeString(callFlags, args, false);
- }
- else if (returnType==WString.class) {
+ } else if (returnType==WString.class) {
String s = invokeString(callFlags, args, true);
if (s != null) {
result = new WString(s);
}
- }
- else if (Pointer.class.isAssignableFrom(returnType)) {
+ } else if (Pointer.class.isAssignableFrom(returnType)) {
return invokePointer(callFlags, args);
- }
- else if (Structure.class.isAssignableFrom(returnType)) {
+ } else if (Structure.class.isAssignableFrom(returnType)) {
if (Structure.ByValue.class.isAssignableFrom(returnType)) {
- Structure s =
+ Structure s =
Native.invokeStructure(peer, callFlags, args,
Structure.newInstance(returnType));
s.autoRead();
result = s;
- }
- else {
+ } else {
result = invokePointer(callFlags, args);
if (result != null) {
Structure s = Structure.newInstance(returnType, (Pointer)result);
@@ -426,20 +406,17 @@ else if (Structure.class.isAssignableFrom(returnType)) {
result = s;
}
}
- }
- else if (Callback.class.isAssignableFrom(returnType)) {
+ } else if (Callback.class.isAssignableFrom(returnType)) {
result = invokePointer(callFlags, args);
if (result != null) {
result = CallbackReference.getCallback(returnType, (Pointer)result);
}
- }
- else if (returnType==String[].class) {
+ } else if (returnType==String[].class) {
Pointer p = invokePointer(callFlags, args);
if (p != null) {
result = p.getStringArray(0, encoding);
}
- }
- else if (returnType==WString[].class) {
+ } else if (returnType==WString[].class) {
Pointer p = invokePointer(callFlags, args);
if (p != null) {
String[] arr = p.getWideStringArray(0);
@@ -449,14 +426,12 @@ else if (returnType==WString[].class) {
}
result = warr;
}
- }
- else if (returnType==Pointer[].class) {
+ } else if (returnType==Pointer[].class) {
Pointer p = invokePointer(callFlags, args);
if (p != null) {
result = p.getPointerArray(0);
}
- }
- else if (allowObjects) {
+ } else if (allowObjects) {
result = Native.invokeObject(peer, callFlags, args);
if (result != null
&& !returnType.isAssignableFrom(result.getClass())) {
@@ -464,15 +439,12 @@ else if (allowObjects) {
+ " does not match result "
+ result.getClass());
}
- }
- else {
- throw new IllegalArgumentException("Unsupported return type "
- + returnType
- + " in function " + getName());
+ } else {
+ throw new IllegalArgumentException("Unsupported return type " + returnType + " in function " + getName());
}
return result;
}
-
+
private Pointer invokePointer(int callFlags, Object[] args) {
long ptr = Native.invokePointer(peer, callFlags, args);
return ptr == 0 ? null : new Pointer(ptr);
@@ -480,15 +452,14 @@ private Pointer invokePointer(int callFlags, Object[] args) {
private Object convertArgument(Object[] args, int index,
Method invokingMethod, TypeMapper mapper,
- boolean allowObjects, Class expectedType) {
+ boolean allowObjects, Class> expectedType) {
Object arg = args[index];
if (arg != null) {
- Class type = arg.getClass();
+ Class> type = arg.getClass();
ToNativeConverter converter = null;
if (NativeMapped.class.isAssignableFrom(type)) {
converter = NativeMappedConverter.getInstance(type);
- }
- else if (mapper != null) {
+ } else if (mapper != null) {
converter = mapper.getToNativeConverter(type);
}
if (converter != null) {
@@ -502,31 +473,30 @@ else if (mapper != null) {
arg = converter.toNative(arg, context);
}
}
- if (arg == null || isPrimitiveArray(arg.getClass())) {
+ if (arg == null || isPrimitiveArray(arg.getClass())) {
return arg;
}
- Class argClass = arg.getClass();
- // Convert Structures to native pointers
+
+ Class> argClass = arg.getClass();
+ // Convert Structures to native pointers
if (arg instanceof Structure) {
Structure struct = (Structure)arg;
struct.autoWrite();
if (struct instanceof Structure.ByValue) {
// Double-check against the method signature, if available
- Class ptype = struct.getClass();
+ Class> ptype = struct.getClass();
if (invokingMethod != null) {
- Class[] ptypes = invokingMethod.getParameterTypes();
+ Class>[] ptypes = invokingMethod.getParameterTypes();
if (IS_VARARGS.isVarArgs(invokingMethod)) {
if (index < ptypes.length-1) {
ptype = ptypes[index];
- }
- else {
- Class etype = ptypes[ptypes.length-1].getComponentType();
+ } else {
+ Class> etype = ptypes[ptypes.length-1].getComponentType();
if (etype != Object.class) {
ptype = etype;
}
}
- }
- else {
+ } else {
ptype = ptypes[index];
}
}
@@ -535,44 +505,35 @@ else if (mapper != null) {
}
}
return struct.getPointer();
- }
- // Convert Callback to Pointer
- else if (arg instanceof Callback) {
+ } else if (arg instanceof Callback) {
+ // Convert Callback to Pointer
return CallbackReference.getFunctionPointer((Callback)arg);
- }
- // String arguments are converted to native pointers here rather
- // than in native code so that the values will be valid until
- // this method returns.
- // Convert String to native pointer (const)
- else if (arg instanceof String) {
+ } else if (arg instanceof String) {
+ // String arguments are converted to native pointers here rather
+ // than in native code so that the values will be valid until
+ // this method returns.
+ // Convert String to native pointer (const)
return new NativeString((String)arg, false).getPointer();
- }
- // Convert WString to native pointer (const)
- else if (arg instanceof WString) {
+ } else if (arg instanceof WString) {
+ // Convert WString to native pointer (const)
return new NativeString(arg.toString(), true).getPointer();
- }
- // Default conversion of boolean to int; if you want something
- // different, use a ToNativeConverter
- else if (arg instanceof Boolean) {
+ } else if (arg instanceof Boolean) {
+ // Default conversion of boolean to int; if you want something
+ // different, use a ToNativeConverter
return Boolean.TRUE.equals(arg) ? INTEGER_TRUE : INTEGER_FALSE;
- }
- else if (String[].class == argClass) {
+ } else if (String[].class == argClass) {
return new StringArray((String[])arg, encoding);
- }
- else if (WString[].class == argClass) {
+ } else if (WString[].class == argClass) {
return new StringArray((WString[])arg);
- }
- else if (Pointer[].class == argClass) {
+ } else if (Pointer[].class == argClass) {
return new PointerArray((Pointer[])arg);
- }
- else if (NativeMapped[].class.isAssignableFrom(argClass)) {
+ } else if (NativeMapped[].class.isAssignableFrom(argClass)) {
return new NativeMappedArray((NativeMapped[])arg);
- }
- else if (Structure[].class.isAssignableFrom(argClass)) {
+ } else if (Structure[].class.isAssignableFrom(argClass)) {
// If the signature is Structure[], disallow
// Structure.ByReference[] and Structure.ByReference elements
Structure[] ss = (Structure[])arg;
- Class type = argClass.getComponentType();
+ Class> type = argClass.getComponentType();
boolean byRef = Structure.ByReference.class.isAssignableFrom(type);
if (expectedType != null) {
if (!Structure.ByReference[].class.isAssignableFrom(expectedType)) {
@@ -599,27 +560,21 @@ else if (Structure[].class.isAssignableFrom(argClass)) {
pointers[i] = ss[i] != null ? ss[i].getPointer() : null;
}
return new PointerArray(pointers);
- }
- else if (ss.length == 0) {
+ } else if (ss.length == 0) {
throw new IllegalArgumentException("Structure array must have non-zero length");
- }
- else if (ss[0] == null) {
+ } else if (ss[0] == null) {
Structure.newInstance(type).toArray(ss);
return ss[0].getPointer();
- }
- else {
+ } else {
Structure.autoWrite(ss);
return ss[0].getPointer();
}
- }
- else if (argClass.isArray()){
- throw new IllegalArgumentException("Unsupported array argument type: "
+ } else if (argClass.isArray()){
+ throw new IllegalArgumentException("Unsupported array argument type: "
+ argClass.getComponentType());
- }
- else if (allowObjects) {
+ } else if (allowObjects) {
return arg;
- }
- else if (!Native.isSupportedNativeType(arg.getClass())) {
+ } else if (!Native.isSupportedNativeType(arg.getClass())) {
throw new IllegalArgumentException("Unsupported argument type "
+ arg.getClass().getName()
+ " at parameter " + index
@@ -628,11 +583,11 @@ else if (!Native.isSupportedNativeType(arg.getClass())) {
return arg;
}
- private boolean isPrimitiveArray(Class argClass) {
- return argClass.isArray()
+ private boolean isPrimitiveArray(Class> argClass) {
+ return argClass.isArray()
&& argClass.getComponentType().isPrimitive();
}
-
+
/**
* Call the native function being represented by this object
*
@@ -669,6 +624,7 @@ private String invokeString(int callFlags, Object[] args, boolean wide) {
}
/** Provide a human-readable representation of this object. */
+ @Override
public String toString() {
if (library != null) {
return "native function " + functionName + "(" + library.getName()
@@ -684,13 +640,13 @@ public Object invokeObject(Object[] args) {
return invoke(Object.class, args);
}
- /** Convenience method for
+ /** Convenience method for
* {@link #invoke(Class,Object[]) invoke(Pointer.class, args)}.
*/
public Pointer invokePointer(Object[] args) {
return (Pointer)invoke(Pointer.class, args);
}
-
+
/** Convenience method for
* {@link #invoke(Class,Object[]) invoke(String.class, args)}
* or {@link #invoke(Class,Object[]) invoke(WString.class, args)}
@@ -703,40 +659,41 @@ public String invokeString(Object[] args, boolean wide) {
return o != null ? o.toString() : null;
}
- /** Convenience method for
+ /** Convenience method for
* {@link #invoke(Class,Object[]) invoke(Integer.class, args)}.
*/
public int invokeInt(Object[] args) {
return ((Integer)invoke(Integer.class, args)).intValue();
}
- /** Convenience method for
+ /** Convenience method for
* {@link #invoke(Class,Object[]) invoke(Long.class, args)}.
*/
public long invokeLong(Object[] args) {
return ((Long)invoke(Long.class, args)).longValue();
}
- /** Convenience method for
+ /** Convenience method for
* {@link #invoke(Class,Object[]) invoke(Float.class, args)}.
*/
public float invokeFloat(Object[] args) {
return ((Float)invoke(Float.class, args)).floatValue();
}
- /** Convenience method for
+ /** Convenience method for
* {@link #invoke(Class,Object[]) invoke(Double.class, args)}.
*/
public double invokeDouble(Object[] args) {
return ((Double)invoke(Double.class, args)).doubleValue();
}
- /** Convenience method for
+ /** Convenience method for
* {@link #invoke(Class,Object[]) invoke(Void.class, args)}.
*/
public void invokeVoid(Object[] args) {
invoke(Void.class, args);
}
-
+
/** Two function pointers are equal if they share the same peer address
* and calling convention.
*/
+ @Override
public boolean equals(Object o) {
if (o == this) return true;
if (o == null) return false;
@@ -752,20 +709,21 @@ public boolean equals(Object o) {
/** Provide a unique hash code for {@link Function}s which are
equivalent.
*/
+ @Override
public int hashCode() {
return callFlags + options.hashCode() + super.hashCode();
}
- /** Concatenate varargs with normal args to obtain a simple argument
- * array.
+ /** Concatenate varargs with normal args to obtain a simple argument
+ * array.
*/
static Object[] concatenateVarArgs(Object[] inArgs) {
// If the final argument is an array of something other than
- // primitives, Structure, or String, treat it as varargs and
+ // primitives, Structure, or String, treat it as varargs and
// concatenate the previous arguments with the varargs elements.
if (inArgs != null && inArgs.length > 0) {
Object lastArg = inArgs[inArgs.length-1];
- Class argType = lastArg != null ? lastArg.getClass() : null;
+ Class> argType = lastArg != null ? lastArg.getClass() : null;
if (argType != null && argType.isArray()) {
Object[] varArgs = (Object[])lastArg;
Object[] fullArgs = new Object[inArgs.length+varArgs.length];
@@ -773,7 +731,7 @@ static Object[] concatenateVarArgs(Object[] inArgs) {
System.arraycopy(varArgs, 0, fullArgs, inArgs.length-1, varArgs.length);
// For convenience, always append a NULL argument to the end
// of varargs, whether the called API requires it or not. If
- // it is not needed, it will be ignored, but if it *is*
+ // it is not needed, it will be ignored, but if it *is*
// required, it avoids forcing the Java client to always
// explicitly add it.
fullArgs[fullArgs.length-1] = null;
@@ -782,12 +740,12 @@ static Object[] concatenateVarArgs(Object[] inArgs) {
}
return inArgs;
}
-
+
/** Varargs are only supported on 1.5+. */
static boolean isVarArgs(Method m) {
return IS_VARARGS.isVarArgs(m);
}
-
+
private static class NativeMappedArray extends Memory implements PostCallRead {
private final NativeMapped[] original;
public NativeMappedArray(NativeMapped[] arg) {
@@ -795,6 +753,7 @@ public NativeMappedArray(NativeMapped[] arg) {
this.original = arg;
setValue(0, original, original.getClass());
}
+ @Override
public void read() {
getValue(0, original.getClass(), original);
}
@@ -810,11 +769,12 @@ public PointerArray(Pointer[] arg) {
}
setPointer(Pointer.SIZE*arg.length, null);
}
+ @Override
public void read() {
read(0, original, 0, original.length);
}
}
-
+
/** Implementation of Boolean.valueOf for older VMs. */
static Boolean valueOf(boolean b) {
return b ? Boolean.TRUE : Boolean.FALSE;
diff --git a/src/com/sun/jna/FunctionResultContext.java b/src/com/sun/jna/FunctionResultContext.java
index 0e5da7dfcc..d294c82575 100644
--- a/src/com/sun/jna/FunctionResultContext.java
+++ b/src/com/sun/jna/FunctionResultContext.java
@@ -1,29 +1,35 @@
/* Copyright (c) 2007 Timothy Wall, All Rights Reserved
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
- *
+ *
* This library 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 for more details.
+ * Lesser General Public License for more details.
*/
package com.sun.jna;
/** Provide result conversion context for a function call. */
public class FunctionResultContext extends FromNativeContext {
-
private Function function;
private Object[] args;
- FunctionResultContext(Class resultClass, Function function, Object[] args) {
+
+ FunctionResultContext(Class> resultClass, Function function, Object[] args) {
super(resultClass);
this.function = function;
this.args = args;
}
- /** Get the function that was invoked. */
- public Function getFunction() { return function; }
- /** Get the arguments used in this function call. */
- public Object[] getArguments() { return args; }
+
+ /** @return The {@link Function} that was invoked. */
+ public Function getFunction() {
+ return function;
+ }
+
+ /** @return The arguments used in this function call. */
+ public Object[] getArguments() {
+ return args;
+ }
}
diff --git a/src/com/sun/jna/IntegerType.java b/src/com/sun/jna/IntegerType.java
index 4c999ea433..aad2e7d28a 100644
--- a/src/com/sun/jna/IntegerType.java
+++ b/src/com/sun/jna/IntegerType.java
@@ -26,6 +26,7 @@
* @author twalljava@java.net
*/
public abstract class IntegerType extends Number implements NativeMapped {
+ private static final long serialVersionUID = 1L;
private int size;
private Number number;
@@ -65,20 +66,20 @@ public void setValue(long value) {
case 1:
if (unsigned) this.value = value & 0xFFL;
truncated = (byte) value;
- this.number = new Byte((byte) value);
+ this.number = Byte.valueOf((byte) value);
break;
case 2:
if (unsigned) this.value = value & 0xFFFFL;
truncated = (short) value;
- this.number = new Short((short) value);
+ this.number = Short.valueOf((short) value);
break;
case 4:
if (unsigned) this.value = value & 0xFFFFFFFFL;
truncated = (int) value;
- this.number = new Integer((int) value);
+ this.number = Integer.valueOf((int) value);
break;
case 8:
- this.number = new Long(value);
+ this.number = Long.valueOf(value);
break;
default:
throw new IllegalArgumentException("Unsupported size: " + size);
@@ -120,7 +121,7 @@ public Object fromNative(Object nativeValue, FromNativeContext context) {
}
@Override
- public Class nativeType() {
+ public Class> nativeType() {
return number.getClass();
}
diff --git a/src/com/sun/jna/InvocationMapper.java b/src/com/sun/jna/InvocationMapper.java
index de66ee4e2c..b6b3aa912c 100644
--- a/src/com/sun/jna/InvocationMapper.java
+++ b/src/com/sun/jna/InvocationMapper.java
@@ -26,7 +26,7 @@
* public Object invoke(Object proxy, Method method, Object[] args) {
* Object[] newArgs = new Object[args.length+1];
* System.arraycopy(args, 0, newArgs, 1, args.length);
- * newArgs[0] = new Integer(3); // _xstat version
+ * newArgs[0] = Integer.valueOf(3); // _xstat version
* return f.invoke(newArgs);
* }
* };
diff --git a/src/com/sun/jna/LastErrorException.java b/src/com/sun/jna/LastErrorException.java
index 83dc24cfe6..cb9bd64e85 100644
--- a/src/com/sun/jna/LastErrorException.java
+++ b/src/com/sun/jna/LastErrorException.java
@@ -8,19 +8,20 @@
* This library 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 for more details.
+ * Lesser General Public License for more details.
*/
package com.sun.jna;
-/**
+/**
* Exception representing a non-zero error code returned in either
- * errno
+ * errno
* or GetLastError()
.
*/
public class LastErrorException extends RuntimeException {
-
+ private static final long serialVersionUID = 1L;
+
private int errorCode;
-
+
private static String formatMessage(int code) {
return Platform.isWindows()
? "GetLastError() returned " + code
@@ -35,7 +36,7 @@ private static String parseMessage(String m) {
return m;
}
}
-
+
public LastErrorException(String msg) {
super(parseMessage(msg.trim()));
try {
@@ -48,7 +49,7 @@ public LastErrorException(String msg) {
this.errorCode = -1;
}
}
-
+
/**
* Returns the error code of the error.
* @return
@@ -57,7 +58,7 @@ public LastErrorException(String msg) {
public int getErrorCode() {
return errorCode;
}
-
+
public LastErrorException(int code) {
super(formatMessage(code));
this.errorCode = code;
diff --git a/src/com/sun/jna/Library.java b/src/com/sun/jna/Library.java
index 54088abc28..967629f9cf 100644
--- a/src/com/sun/jna/Library.java
+++ b/src/com/sun/jna/Library.java
@@ -6,7 +6,7 @@
* This library 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 for more details.
+ * Lesser General Public License for more details.
*/
package com.sun.jna;
@@ -26,39 +26,39 @@
*
*
* By convention, method names are identical to the native names, although you
- * can map java names to different native names by providing a
+ * can map java names to different native names by providing a
* {@link FunctionMapper} as a value for key {@link #OPTION_FUNCTION_MAPPER}
* in the options map passed to the
* {@link Native#loadLibrary(String, Class, Map)} call.
*
- * Although the names for structures and structure fields may be chosen
- * arbitrarily, they should correspond as closely as possible to the native
+ * Although the names for structures and structure fields may be chosen
+ * arbitrarily, they should correspond as closely as possible to the native
* definitions. The same is true for parameter names.
*
* This interface supports multiple, concurrent invocations of any library
* methods on the Java side. Check your library documentation for its
* multi-threading requirements on the native side. If a library is not safe
- * for simultaneous multi-threaded access, consider using
- * {@link Native#synchronizedLibrary} to prevent simultaneous multi-threaded
- * access to the native code.
+ * for simultaneous multi-threaded access, consider using
+ * {@link Native#synchronizedLibrary} to prevent simultaneous multi-threaded
+ * access to the native code.
*
* Optional fields
* Interface options will be automatically propagated to structures defined
- * within the library provided a call to
+ * within the library provided a call to
* {@link Native#loadLibrary(String,Class,Map)} is made prior to instantiating
* any of those structures. One common way of ensuring this is to declare
- * an INSTANCE field in the interface which holds the
+ * an INSTANCE field in the interface which holds the
* loadLibrary
result.
*
* OPTIONS (an instance of {@link Map}),
* TYPE_MAPPER (an instance of {@link TypeMapper}),
- * STRUCTURE_ALIGNMENT (one of the alignment types defined in
+ * STRUCTURE_ALIGNMENT (one of the alignment types defined in
* {@link Structure}), and STRING_ENCODING (a {@link String}) may also
* be defined. If no instance of the interface has been instantiated, these
* fields will be used to determine customization settings for structures and
- * methods defined within the interface.
+ * methods defined within the interface.
*
- *
+ *
* @author Todd Fast, todd.fast@sun.com
* @author Timothy Wall, twalljava@dev.java.net
*/
@@ -70,7 +70,7 @@ public interface Library {
/** Option key for an {@link InvocationMapper} for the library. */
String OPTION_INVOCATION_MAPPER = "invocation-mapper";
/** Option key for structure alignment type ({@link Integer}), which should
- * be one of the predefined alignment types in {@link Structure}.
+ * be one of the predefined alignment types in {@link Structure}.
*/
String OPTION_STRUCTURE_ALIGNMENT = "structure-alignment";
/**
Option key for per-library String encoding. This affects conversions
@@ -102,110 +102,107 @@ public interface Library {
String OPTION_CLASSLOADER = "classloader";
static class Handler implements InvocationHandler {
-
+
static final Method OBJECT_TOSTRING;
static final Method OBJECT_HASHCODE;
static final Method OBJECT_EQUALS;
-
+
static {
try {
- OBJECT_TOSTRING = Object.class.getMethod("toString", new Class[0]);
- OBJECT_HASHCODE= Object.class.getMethod("hashCode", new Class[0]);
- OBJECT_EQUALS = Object.class.getMethod("equals", new Class[] { Object.class });
- }
- catch (Exception e) {
+ OBJECT_TOSTRING = Object.class.getMethod("toString");
+ OBJECT_HASHCODE= Object.class.getMethod("hashCode");
+ OBJECT_EQUALS = Object.class.getMethod("equals", Object.class);
+ } catch (Exception e) {
throw new Error("Error retrieving Object.toString() method");
}
}
+ /**
+ * FunctionInfo has to be immutable to to make the object visible
+ * to other threads fully initialized. This is a prerequisite for
+ * using the class in the double checked locking scenario of {@link Handler#invoke(Object, Method, Object[])}
+ */
+ private static final class FunctionInfo {
+ final InvocationHandler handler;
+ final Function function;
+ final boolean isVarArgs;
+ final Map options;
+ final Class>[] parameterTypes;
+
+ FunctionInfo(InvocationHandler handler, Function function, Class>[] parameterTypes, boolean isVarArgs, Map options) {
+ this.handler = handler;
+ this.function = function;
+ this.isVarArgs = isVarArgs;
+ this.options = options;
+ this.parameterTypes = parameterTypes;
+ }
+ }
+
private final NativeLibrary nativeLibrary;
- private final Class interfaceClass;
+ private final Class> interfaceClass;
// Library invocation options
- private final Map options;
+ private final Map options;
private final InvocationMapper invocationMapper;
- private final Map functions = new WeakHashMap();
- public Handler(String libname, Class interfaceClass, Map options) {
+ private final Map functions = new WeakHashMap();
+ public Handler(String libname, Class> interfaceClass, Map options) {
if (libname != null && "".equals(libname.trim())) {
- throw new IllegalArgumentException("Invalid library name \""
- + libname + "\"");
+ throw new IllegalArgumentException("Invalid library name \"" + libname + "\"");
+ }
+
+ if (!interfaceClass.isInterface()) {
+ throw new IllegalArgumentException(libname + " does not implement an interface: " + interfaceClass.getName());
}
this.interfaceClass = interfaceClass;
- options = new HashMap(options);
- int callingConvention =
- AltCallingConvention.class.isAssignableFrom(interfaceClass)
- ? Function.ALT_CONVENTION : Function.C_CONVENTION;
- if (options.get(OPTION_CALLING_CONVENTION) == null) {
- options.put(OPTION_CALLING_CONVENTION,
- new Integer(callingConvention));
+ this.options = new HashMap(options);
+ int callingConvention = AltCallingConvention.class.isAssignableFrom(interfaceClass)
+ ? Function.ALT_CONVENTION
+ : Function.C_CONVENTION;
+ if (this.options.get(OPTION_CALLING_CONVENTION) == null) {
+ this.options.put(OPTION_CALLING_CONVENTION, Integer.valueOf(callingConvention));
}
- if (options.get(OPTION_CLASSLOADER) == null) {
- options.put(OPTION_CLASSLOADER, interfaceClass.getClassLoader());
+ if (this.options.get(OPTION_CLASSLOADER) == null) {
+ this.options.put(OPTION_CLASSLOADER, interfaceClass.getClassLoader());
}
- this.options = options;
- this.nativeLibrary = NativeLibrary.getInstance(libname, options);
- invocationMapper = (InvocationMapper)options.get(OPTION_INVOCATION_MAPPER);
+ this.nativeLibrary = NativeLibrary.getInstance(libname, this.options);
+ invocationMapper = (InvocationMapper)this.options.get(OPTION_INVOCATION_MAPPER);
}
public NativeLibrary getNativeLibrary() {
return nativeLibrary;
}
-
+
public String getLibraryName() {
return nativeLibrary.getName();
}
- public Class getInterfaceClass() {
+ public Class> getInterfaceClass() {
return interfaceClass;
}
-
- /**
- * FunctionInfo has to be immutable to to make the object visible
- * to other threads fully initialized. This is a prerequisite for
- * using the class in the double checked locking scenario of {@link Handler#invoke(Object, Method, Object[])}
- */
- private static final class FunctionInfo {
-
- FunctionInfo(InvocationHandler handler, Function function, Class[] parameterTypes, boolean isVarArgs, Map options) {
- super();
- this.handler = handler;
- this.function = function;
- this.isVarArgs = isVarArgs;
- this.options = options;
- this.parameterTypes = parameterTypes;
- }
-
- final InvocationHandler handler;
- final Function function;
- final boolean isVarArgs;
- final Map options;
- final Class[] parameterTypes;
- }
+ @Override
public Object invoke(Object proxy, Method method, Object[] inArgs)
throws Throwable {
// Intercept Object methods
if (OBJECT_TOSTRING.equals(method)) {
return "Proxy interface to " + nativeLibrary;
- }
- else if (OBJECT_HASHCODE.equals(method)) {
- return new Integer(hashCode());
- }
- else if (OBJECT_EQUALS.equals(method)) {
+ } else if (OBJECT_HASHCODE.equals(method)) {
+ return Integer.valueOf(hashCode());
+ } else if (OBJECT_EQUALS.equals(method)) {
Object o = inArgs[0];
if (o != null && Proxy.isProxyClass(o.getClass())) {
return Function.valueOf(Proxy.getInvocationHandler(o) == this);
}
return Boolean.FALSE;
}
-
+
// Using the double-checked locking pattern to speed up function calls
- FunctionInfo f = (FunctionInfo)functions.get(method);
+ FunctionInfo f = functions.get(method);
if(f == null) {
synchronized(functions) {
- f = (FunctionInfo)functions.get(method);
+ f = functions.get(method);
if (f == null) {
boolean isVarArgs = Function.isVarArgs(method);
InvocationHandler handler = null;
@@ -213,13 +210,13 @@ else if (OBJECT_EQUALS.equals(method)) {
handler = invocationMapper.getInvocationHandler(nativeLibrary, method);
}
Function function = null;
- Class[] parameterTypes = null;
- Map options = null;
+ Class>[] parameterTypes = null;
+ Map options = null;
if (handler == null) {
// Find the function to invoke
function = nativeLibrary.getFunction(method.getName(), method);
parameterTypes = method.getParameterTypes();
- options = new HashMap(this.options);
+ options = new HashMap(this.options);
options.put(Function.OPTION_INVOKING_METHOD, method);
}
f = new FunctionInfo(handler, function, parameterTypes, isVarArgs, options);
diff --git a/src/com/sun/jna/Memory.java b/src/com/sun/jna/Memory.java
index d0f68dbb26..f255d9d092 100644
--- a/src/com/sun/jna/Memory.java
+++ b/src/com/sun/jna/Memory.java
@@ -6,26 +6,27 @@
* This library 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 for more details.
+ * Lesser General Public License for more details.
*/
package com.sun.jna;
+import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
+import java.nio.Buffer;
import java.nio.ByteBuffer;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
+import java.util.LinkedList;
import java.util.Map;
-import java.util.Set;
import java.util.WeakHashMap;
/**
- * A Pointer
to memory obtained from the native heap via a
+ * A Pointer
to memory obtained from the native heap via a
* call to malloc
.
*
* In some cases it might be necessary to use memory obtained from
- * malloc
. For example, Memory
helps
+ * malloc
. For example, Memory
helps
* accomplish the following idiom:
*
* void *buf = malloc(BUF_LEN * sizeof(char));
@@ -42,17 +43,14 @@
* @see Pointer
*/
public class Memory extends Pointer {
-
- private static final Map buffers;
/** Keep track of all allocated memory so we can dispose of it before unloading. */
- private static final Map allocatedMemory;
+ private static final Map> allocatedMemory =
+ Collections.synchronizedMap(new WeakHashMap>());
- static {
- buffers = Collections.synchronizedMap(Platform.HAS_BUFFERS
- ? (Map)new WeakIdentityHashMap()
- : (Map)new HashMap());
- allocatedMemory = Collections.synchronizedMap(new WeakHashMap());
- }
+ private static final Map buffers =
+ Collections.synchronizedMap(Platform.HAS_BUFFERS
+ ? new WeakIdentityHashMap()
+ : new HashMap());
/** Force cleanup of memory that has associated NIO Buffers which have
been GC'd.
@@ -63,8 +61,10 @@ public static void purge() {
/** Dispose of all allocated memory. */
public static void disposeAll() {
- for (Iterator i=allocatedMemory.keySet().iterator();i.hasNext();) {
- ((Memory)i.next()).dispose();
+ // use a copy since dispose() modifies the map
+ Collection refs = new LinkedList(allocatedMemory.keySet());
+ for (Memory r : refs) {
+ r.dispose();
}
}
@@ -79,18 +79,21 @@ public SharedMemory(long offset, long size) {
this.peer = Memory.this.peer + offset;
}
/** No need to free memory. */
+ @Override
protected void dispose() {
this.peer = 0;
- }
+ }
/** Pass bounds check to parent. */
+ @Override
protected void boundsCheck(long off, long sz) {
Memory.this.boundsCheck(this.peer - Memory.this.peer + off, sz);
}
+ @Override
public String toString() {
return super.toString() + " (shared from " + Memory.this.toString() + ")";
}
}
-
+
/**
* Allocate space in the native heap via a call to C's malloc
.
*
@@ -100,39 +103,43 @@ public Memory(long size) {
this.size = size;
if (size <= 0) {
throw new IllegalArgumentException("Allocation size must be greater than zero");
- }
+ }
peer = malloc(size);
- if (peer == 0)
+ if (peer == 0)
throw new OutOfMemoryError("Cannot allocate " + size + " bytes");
- allocatedMemory.put(this, new WeakReference(this));
+ allocatedMemory.put(this, new WeakReference(this));
}
- protected Memory() { }
+ protected Memory() {
+ super();
+ }
/** Provide a view of this memory using the given offset as the base address. The
* returned {@link Pointer} will have a size equal to that of the original
* minus the offset.
* @throws IndexOutOfBoundsException if the requested memory is outside
- * the allocated bounds.
+ * the allocated bounds.
*/
+ @Override
public Pointer share(long offset) {
return share(offset, size() - offset);
}
-
+
/** Provide a view of this memory using the given offset as the base
- * address, bounds-limited with the given size. Maintains a reference to
+ * address, bounds-limited with the given size. Maintains a reference to
* the original {@link Memory} object to avoid GC as long as the shared
* memory is referenced.
* @throws IndexOutOfBoundsException if the requested memory is outside
- * the allocated bounds.
+ * the allocated bounds.
*/
+ @Override
public Pointer share(long offset, long sz) {
boundsCheck(offset, sz);
return new SharedMemory(offset, sz);
}
-
- /** Provide a view onto this structure with the given alignment.
+
+ /** Provide a view onto this structure with the given alignment.
* @param byteBoundary Align memory to this number of bytes; should be a
* power of two.
* @throws IndexOutOfBoundsException if the requested alignment can
@@ -147,7 +154,7 @@ public Memory align(int byteBoundary) {
for (int i=0;i < 32;i++) {
if (byteBoundary == (1<malloc space, a la
- * Pointer.read
. But this method performs a bounds
+ * Pointer.read
. But this method performs a bounds
* checks to ensure that the indirection does not cause memory outside the
* malloc
ed space to be accessed.
*
- * @see Pointer#read(long,byte[],int,int)
+ * @see Pointer#read(long,byte[],int,int)
*/
+ @Override
public void read(long bOff, byte[] buf, int index, int length) {
boundsCheck(bOff, length * 1L);
super.read(bOff, buf, index, length);
}
-
/**
* Indirect the native pointer to malloc
space, a la
- * Pointer.read
. But this method performs a bounds
+ * Pointer.read
. But this method performs a bounds
* checks to ensure that the indirection does not cause memory outside the
* malloc
ed space to be accessed.
*
* @see Pointer#read(long,short[],int,int)
*/
+ @Override
public void read(long bOff, short[] buf, int index, int length) {
boundsCheck(bOff, length * 2L);
super.read(bOff, buf, index, length);
}
-
/**
* Indirect the native pointer to malloc
space, a la
- * Pointer.read
. But this method performs a bounds
+ * Pointer.read
. But this method performs a bounds
* checks to ensure that the indirection does not cause memory outside the
* malloc
ed space to be accessed.
*
- * @see Pointer#read(long,char[],int,int)
+ * @see Pointer#read(long,char[],int,int)
*/
+ @Override
public void read(long bOff, char[] buf, int index, int length) {
boundsCheck(bOff, length * 2L);
super.read(bOff, buf, index, length);
}
-
/**
* Indirect the native pointer to malloc
space, a la
- * Pointer.read
. But this method performs a bounds
+ * Pointer.read
. But this method performs a bounds
* checks to ensure that the indirection does not cause memory outside the
* malloc
ed space to be accessed.
*
* @see Pointer#read(long,int[],int,int)
*/
+ @Override
public void read(long bOff, int[] buf, int index, int length) {
boundsCheck(bOff, length * 4L);
super.read(bOff, buf, index, length);
}
-
/**
* Indirect the native pointer to malloc
space, a la
- * Pointer.read
. But this method performs a bounds
+ * Pointer.read
. But this method performs a bounds
* checks to ensure that the indirection does not cause memory outside the
* malloc
ed space to be accessed.
*
- * @see Pointer#read(long,long[],int,int)
+ * @see Pointer#read(long,long[],int,int)
*/
+ @Override
public void read(long bOff, long[] buf, int index, int length) {
boundsCheck(bOff, length * 8L);
super.read(bOff, buf, index, length);
}
-
/**
* Indirect the native pointer to malloc
space, a la
- * Pointer.read
. But this method performs a bounds
+ * Pointer.read
. But this method performs a bounds
* checks to ensure that the indirection does not cause memory outside the
* malloc
ed space to be accessed.
*
- * @see Pointer#read(long,float[],int,int)
+ * @see Pointer#read(long,float[],int,int)
*/
+ @Override
public void read(long bOff, float[] buf, int index, int length) {
boundsCheck(bOff, length * 4L);
super.read(bOff, buf, index, length);
}
-
/**
* Indirect the native pointer to malloc
space, a la
* Pointer.read
. But this method performs a bounds checks to
* ensure that the indirection does not cause memory outside the
* malloc
ed space to be accessed.
*
- * @see Pointer#read(long,double[],int,int)
+ * @see Pointer#read(long,double[],int,int)
*/
- public void read(long bOff, double[] buf, int index, int length)
- {
+ @Override
+ public void read(long bOff, double[] buf, int index, int length) {
boundsCheck(bOff, length * 8L);
super.read(bOff, buf, index, length);
}
-
-
-
//////////////////////////////////////////////////////////////////////////
// Raw write methods
//////////////////////////////////////////////////////////////////////////
/**
* Indirect the native pointer to malloc
space, a la
- * Pointer.write
. But this method performs a bounds
+ * Pointer.write
. But this method performs a bounds
* checks to ensure that the indirection does not cause memory outside the
* malloc
ed space to be accessed.
*
- * @see Pointer#write(long,byte[],int,int)
+ * @see Pointer#write(long,byte[],int,int)
*/
+ @Override
public void write(long bOff, byte[] buf, int index, int length) {
boundsCheck(bOff, length * 1L);
super.write(bOff, buf, index, length);
}
-
/**
* Indirect the native pointer to malloc
space, a la
- * Pointer.write
. But this method performs a bounds
+ * Pointer.write
. But this method performs a bounds
* checks to ensure that the indirection does not cause memory outside the
* malloc
ed space to be accessed.
*
* @see Pointer#write(long,short[],int,int)
*/
+ @Override
public void write(long bOff, short[] buf, int index, int length) {
boundsCheck(bOff, length * 2L);
super.write(bOff, buf, index, length);
}
-
/**
* Indirect the native pointer to malloc
space, a la
- * Pointer.write
. But this method performs a bounds
+ * Pointer.write
. But this method performs a bounds
* checks to ensure that the indirection does not cause memory outside the
* malloc
ed space to be accessed.
*
* @see Pointer#write(long,char[],int,int)
*/
+ @Override
public void write(long bOff, char[] buf, int index, int length) {
boundsCheck(bOff, length * 2L);
super.write(bOff, buf, index, length);
}
-
/**
* Indirect the native pointer to malloc
space, a la
- * Pointer.write
. But this method performs a bounds
+ * Pointer.write
. But this method performs a bounds
* checks to ensure that the indirection does not cause memory outside the
* malloc
ed space to be accessed.
*
- * @see Pointer#write(long,int[],int,int)
+ * @see Pointer#write(long,int[],int,int)
*/
+ @Override
public void write(long bOff, int[] buf, int index, int length) {
boundsCheck(bOff, length * 4L);
super.write(bOff, buf, index, length);
}
-
/**
* Indirect the native pointer to malloc
space, a la
- * Pointer.write
. But this method performs a bounds
+ * Pointer.write
. But this method performs a bounds
* checks to ensure that the indirection does not cause memory outside the
* malloc
ed space to be accessed.
*
- * @see Pointer#write(long,long[],int,int)
+ * @see Pointer#write(long,long[],int,int)
*/
+ @Override
public void write(long bOff, long[] buf, int index, int length) {
boundsCheck(bOff, length * 8L);
super.write(bOff, buf, index, length);
}
-
/**
* Indirect the native pointer to malloc
space, a la
- * Pointer.write
. But this method performs a bounds
+ * Pointer.write
. But this method performs a bounds
* checks to ensure that the indirection does not cause memory outside the
* malloc
ed space to be accessed.
*
* @see Pointer#write(long,float[],int,int)
*/
+ @Override
public void write(long bOff, float[] buf, int index, int length) {
boundsCheck(bOff, length * 4L);
super.write(bOff, buf, index, length);
}
-
/**
* Indirect the native pointer to malloc
space, a la
- * Pointer.write
. But this method performs a bounds
+ * Pointer.write
. But this method performs a bounds
* checks to ensure that the indirection does not cause memory outside the
* malloc
ed space to be accessed.
*
- * @see Pointer#write(long,double[],int,int)
+ * @see Pointer#write(long,double[],int,int)
*/
+ @Override
public void write(long bOff, double[] buf, int index, int length) {
boundsCheck(bOff, length * 8L);
super.write(bOff, buf, index, length);
}
-
-
-
//////////////////////////////////////////////////////////////////////////
// Java type read methods
//////////////////////////////////////////////////////////////////////////
/**
* Indirect the native pointer to malloc
space, a la
- * Pointer.getByte
. But this method performs a bounds
+ * Pointer.getByte
. But this method performs a bounds
* checks to ensure that the indirection does not cause memory outside the
* malloc
ed space to be accessed.
*
* @see Pointer#getByte(long)
*/
+ @Override
public byte getByte(long offset) {
boundsCheck(offset, 1);
return super.getByte(offset);
}
-
/**
* Indirect the native pointer to malloc
space, a la
- * Pointer.getByte
. But this method performs a bounds
+ * Pointer.getByte
. But this method performs a bounds
* checks to ensure that the indirection does not cause memory outside the
* malloc
ed space to be accessed.
*
* @see Pointer#getByte(long)
*/
+ @Override
public char getChar(long offset) {
boundsCheck(offset, 1);
return super.getChar(offset);
}
-
/**
* Indirect the native pointer to malloc
space, a la
* Pointer.getShort
. But this method performs a bounds
@@ -453,83 +459,84 @@ public char getChar(long offset) {
*
* @see Pointer#getShort(long)
*/
+ @Override
public short getShort(long offset) {
boundsCheck(offset, 2);
return super.getShort(offset);
}
-
/**
* Indirect the native pointer to malloc
space, a la
- * Pointer.getInt
. But this method performs a bounds
+ * Pointer.getInt
. But this method performs a bounds
* checks to ensure that the indirection does not cause memory outside the
* malloc
ed space to be accessed.
*
* @see Pointer#getInt(long)
*/
+ @Override
public int getInt(long offset) {
boundsCheck(offset, 4);
return super.getInt(offset);
}
-
/**
* Indirect the native pointer to malloc
space, a la
- * Pointer.getLong
. But this method performs a bounds
+ * Pointer.getLong
. But this method performs a bounds
* checks to ensure that the indirection does not cause memory outside the
* malloc
ed space to be accessed.
*
* @see Pointer#getLong(long)
*/
+ @Override
public long getLong(long offset) {
boundsCheck(offset, 8);
return super.getLong(offset);
}
-
/**
* Indirect the native pointer to malloc
space, a la
- * Pointer.getFloat
. But this method performs a bounds
+ * Pointer.getFloat
. But this method performs a bounds
* checks to ensure that the indirection does not cause memory outside the
* malloc
ed space to be accessed.
*
* @see Pointer#getFloat(long)
*/
+ @Override
public float getFloat(long offset) {
boundsCheck(offset, 4);
return super.getFloat(offset);
}
-
/**
* Indirect the native pointer to malloc
space, a la
- * Pointer.getDouble
. But this method performs a
- * bounds check to ensure that the indirection does not cause memory
+ * Pointer.getDouble
. But this method performs a
+ * bounds check to ensure that the indirection does not cause memory
* outside the malloc
ed space to be accessed.
*
* @see Pointer#getDouble(long)
*/
+ @Override
public double getDouble(long offset) {
boundsCheck(offset, 8);
return super.getDouble(offset);
}
-
/**
* Indirect the native pointer to malloc
space, a la
- * Pointer.getPointer
. But this method performs
- * a bounds checks to ensure that the indirection does not cause memory
+ * Pointer.getPointer
. But this method performs
+ * a bounds checks to ensure that the indirection does not cause memory
* outside the malloc
ed space to be accessed.
*
* @see Pointer#getPointer(long)
*/
+ @Override
public Pointer getPointer(long offset) {
boundsCheck(offset, Pointer.SIZE);
return super.getPointer(offset);
}
/**
- * Get a ByteBuffer mapped to a portion of this memory.
+ * Get a ByteBuffer mapped to a portion of this memory.
* We keep a weak reference to all ByteBuffers provided so that this
* memory object is not GC'd while there are still implicit outstanding
* references to it (it'd be nice if we could attach our own reference to
@@ -538,8 +545,9 @@ public Pointer getPointer(long offset) {
*
* @param offset byte offset from pointer to start the buffer
* @param length Length of ByteBuffer
- * @return a direct ByteBuffer that accesses the memory being pointed to,
+ * @return a direct ByteBuffer that accesses the memory being pointed to,
*/
+ @Override
public ByteBuffer getByteBuffer(long offset, long length) {
boundsCheck(offset, length);
ByteBuffer b = super.getByteBuffer(offset, length);
@@ -549,12 +557,14 @@ public ByteBuffer getByteBuffer(long offset, long length) {
return b;
}
+ @Override
public String getString(long offset, String encoding) {
// NOTE: we only make sure the start of the string is within bounds
boundsCheck(offset, 0);
return super.getString(offset, encoding);
}
+ @Override
public String getWideString(long offset) {
// NOTE: we only make sure the start of the string is within bounds
boundsCheck(offset, 0);
@@ -567,132 +577,135 @@ public String getWideString(long offset) {
/**
* Indirect the native pointer to malloc
space, a la
- * Pointer.setByte
. But this method performs a bounds
+ * Pointer.setByte
. But this method performs a bounds
* checks to ensure that the indirection does not cause memory outside the
* malloc
ed space to be accessed.
*
* @see Pointer#setByte
*/
+ @Override
public void setByte(long offset, byte value) {
boundsCheck(offset, 1);
super.setByte(offset, value);
}
-
/**
* Indirect the native pointer to malloc
space, a la
- * Pointer.setChar
. But this method performs a bounds
+ * Pointer.setChar
. But this method performs a bounds
* checks to ensure that the indirection does not cause memory outside the
* malloc
ed space to be accessed.
*
* @see Pointer#setChar
*/
+ @Override
public void setChar(long offset, char value) {
boundsCheck(offset, Native.WCHAR_SIZE);
super.setChar(offset, value);
}
-
/**
* Indirect the native pointer to malloc
space, a la
- * Pointer.setShort
. But this method performs a bounds
+ * Pointer.setShort
. But this method performs a bounds
* checks to ensure that the indirection does not cause memory outside the
* malloc
ed space to be accessed.
*
* @see Pointer#setShort
*/
+ @Override
public void setShort(long offset, short value) {
boundsCheck(offset, 2);
super.setShort(offset, value);
}
-
/**
* Indirect the native pointer to malloc
space, a la
- * Pointer.setInt
. But this method performs a bounds
+ * Pointer.setInt
. But this method performs a bounds
* checks to ensure that the indirection does not cause memory outside the
* malloc
ed space to be accessed.
*
* @see Pointer#setInt
*/
+ @Override
public void setInt(long offset, int value) {
boundsCheck(offset, 4);
super.setInt(offset, value);
}
-
/**
* Indirect the native pointer to malloc
space, a la
- * Pointer.setLong
. But this method performs a bounds
+ * Pointer.setLong
. But this method performs a bounds
* checks to ensure that the indirection does not cause memory outside the
* malloc
ed space to be accessed.
*
* @see Pointer#setLong
*/
+ @Override
public void setLong(long offset, long value) {
boundsCheck(offset, 8);
super.setLong(offset, value);
}
-
/**
* Indirect the native pointer to malloc
space, a la
- * Pointer.setFloat
. But this method performs a bounds
+ * Pointer.setFloat
. But this method performs a bounds
* checks to ensure that the indirection does not cause memory outside the
* malloc
ed space to be accessed.
*
* @see Pointer#setFloat
*/
+ @Override
public void setFloat(long offset, float value) {
boundsCheck(offset, 4);
super.setFloat(offset, value);
}
-
/**
* Indirect the native pointer to malloc
space, a la
- * Pointer.setDouble
. But this method performs a
- * bounds checks to ensure that the indirection does not cause memory
+ * Pointer.setDouble
. But this method performs a
+ * bounds checks to ensure that the indirection does not cause memory
* outside the malloc
ed space to be accessed.
*
* @see Pointer#setDouble
*/
+ @Override
public void setDouble(long offset, double value) {
boundsCheck(offset, 8);
super.setDouble(offset, value);
}
-
/**
* Indirect the native pointer to malloc
space, a la
- * Pointer.setPointer
. But this method performs
- * a bounds checks to ensure that the indirection does not cause memory
+ * Pointer.setPointer
. But this method performs
+ * a bounds checks to ensure that the indirection does not cause memory
* outside the malloc
ed space to be accessed.
*
* @see Pointer#setPointer
*/
+ @Override
public void setPointer(long offset, Pointer value) {
boundsCheck(offset, Pointer.SIZE);
super.setPointer(offset, value);
}
+ @Override
public void setString(long offset, String value, String encoding) {
boundsCheck(offset, Native.getBytes(value, encoding).length + 1L);
super.setString(offset, value, encoding);
}
+ @Override
public void setWideString(long offset, String value) {
boundsCheck(offset, (value.length() + 1L) * Native.WCHAR_SIZE);
super.setWideString(offset, value);
}
+ @Override
public String toString() {
- return "allocated@0x" + Long.toHexString(peer) + " ("
- + size + " bytes)";
+ return "allocated@0x" + Long.toHexString(peer) + " (" + size + " bytes)";
}
protected static void free(long p) {
- // free(0) is a no-op, so avoid the overhead of the call
+ // free(0) is a no-op, so avoid the overhead of the call
if (p != 0) {
Native.free(p);
}
diff --git a/src/com/sun/jna/MethodResultContext.java b/src/com/sun/jna/MethodResultContext.java
index 1078bbe4d8..63e413fbc6 100644
--- a/src/com/sun/jna/MethodResultContext.java
+++ b/src/com/sun/jna/MethodResultContext.java
@@ -1,14 +1,14 @@
/* Copyright (c) 2007 Wayne Meissner, All Rights Reserved
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
- *
+ *
* This library 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 for more details.
+ * Lesser General Public License for more details.
*/
package com.sun.jna;
@@ -20,11 +20,13 @@
*/
public class MethodResultContext extends FunctionResultContext {
private final Method method;
- MethodResultContext(Class resultClass, Function function, Object[] args,
- Method method) {
+ MethodResultContext(Class> resultClass, Function function, Object[] args, Method method) {
super(resultClass, function, args);
- this.method = method;
+ this.method = method;
+ }
+
+ /** @return The {@link Method} used to invoke this function call. */
+ public Method getMethod() {
+ return method;
}
- /** Get the Method used to invoke this function call. */
- public Method getMethod() { return method; }
}
diff --git a/src/com/sun/jna/Native.java b/src/com/sun/jna/Native.java
index d960223941..91c1394673 100644
--- a/src/com/sun/jna/Native.java
+++ b/src/com/sun/jna/Native.java
@@ -22,6 +22,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
+import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
@@ -41,7 +42,6 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
@@ -101,8 +101,8 @@ public final class Native implements Version {
// Used by tests, do not remove
static String jnidispatchPath = null;
- private static final Map options = new WeakHashMap();
- private static final Map libraries = new WeakHashMap();
+ private static final Map, Map> typeOptions = new WeakHashMap, Map>();
+ private static final Map, Reference>> libraries = new WeakHashMap, Reference>>();
private static final String _OPTION_ENCLOSING_LIBRARY = "enclosing-library";
private static final UncaughtExceptionHandler DEFAULT_HANDLER =
new UncaughtExceptionHandler() {
@@ -465,7 +465,7 @@ public static T loadLibrary(Class interfaceClass) {
* dependent libraries are missing.
* @see #loadLibrary(String, Class, Map)
*/
- public static T loadLibrary(Class interfaceClass, Map options) {
+ public static T loadLibrary(Class interfaceClass, Map options) {
return loadLibrary(null, interfaceClass, options);
}
@@ -484,7 +484,7 @@ public static T loadLibrary(Class interfaceClass, Map options) {
* @see #loadLibrary(String, Class, Map)
*/
public static T loadLibrary(String name, Class interfaceClass) {
- return loadLibrary(name, interfaceClass, Collections.emptyMap());
+ return loadLibrary(name, interfaceClass, Collections.emptyMap());
}
/** Load a library interface from the given shared library, providing
@@ -503,7 +503,7 @@ public static T loadLibrary(String name, Class interfaceClass) {
* @throws UnsatisfiedLinkError if the library cannot be found or
* dependent libraries are missing.
*/
- public static T loadLibrary(String name, Class interfaceClass, Map options) {
+ public static T loadLibrary(String name, Class interfaceClass, Map options) {
if (!Library.class.isAssignableFrom(interfaceClass)) {
throw new IllegalArgumentException("Interface (" + interfaceClass.getSimpleName() + ")"
+ " of library=" + name + " does not extend " + Library.class.getSimpleName());
@@ -531,7 +531,7 @@ private static void loadLibraryInstance(Class> cls) {
if (field.getType() == cls
&& Modifier.isStatic(field.getModifiers())) {
// Ensure the field gets initialized by reading it
- libraries.put(cls, new WeakReference(field.get(null)));
+ libraries.put(cls, new WeakReference(field.get(null)));
break;
}
}
@@ -558,8 +558,8 @@ static Class> findEnclosingLibraryClass(Class> cls) {
// Check for direct-mapped libraries, which won't necessarily
// implement com.sun.jna.Library.
synchronized(libraries) {
- if (options.containsKey(cls)) {
- Map libOptions = (Map)options.get(cls);
+ if (typeOptions.containsKey(cls)) {
+ Map libOptions = typeOptions.get(cls);
Class> enclosingClass = (Class>)libOptions.get(_OPTION_ENCLOSING_LIBRARY);
if (enclosingClass != null) {
return enclosingClass;
@@ -594,40 +594,44 @@ static Class> findEnclosingLibraryClass(Class> cls) {
* @param type The type class
* @return The options map
*/
- public static Map getLibraryOptions(Class> type) {
+ public static Map getLibraryOptions(Class> type) {
+ Map libraryOptions;
+ // cached already ?
synchronized(libraries) {
- if (options.containsKey(type)) {
- return (Map)options.get(type);
+ libraryOptions = typeOptions.get(type);
+ if (libraryOptions != null) {
+ return libraryOptions;
}
}
+
Class> mappingClass = findEnclosingLibraryClass(type);
if (mappingClass != null) {
loadLibraryInstance(mappingClass);
- }
- else {
+ } else {
mappingClass = type;
}
+
synchronized(libraries) {
- if (options.containsKey(mappingClass)) {
- Map libraryOptions = (Map)options.get(mappingClass);
- options.put(type, libraryOptions);
+ libraryOptions = typeOptions.get(mappingClass);
+ if (libraryOptions != null) {
+ typeOptions.put(type, libraryOptions); // cache for next time
return libraryOptions;
}
- Map libraryOptions = null;
+
try {
Field field = mappingClass.getField("OPTIONS");
field.setAccessible(true);
- libraryOptions = (Map)field.get(null);
- }
- catch (NoSuchFieldException e) {
- libraryOptions = Collections.EMPTY_MAP;
- }
- catch (Exception e) {
- throw new IllegalArgumentException("OPTIONS must be a public field of type java.util.Map ("
- + e + "): " + mappingClass);
+ libraryOptions = (Map) field.get(null);
+ if (libraryOptions == null) {
+ throw new IllegalStateException("Null options field");
+ }
+ } catch (NoSuchFieldException e) {
+ libraryOptions = Collections.emptyMap();
+ } catch (Exception e) {
+ throw new IllegalArgumentException("OPTIONS must be a public field of type java.util.Map (" + e + "): " + mappingClass);
}
// Make a clone of the original options
- libraryOptions = new HashMap(libraryOptions);
+ libraryOptions = new HashMap(libraryOptions);
if (!libraryOptions.containsKey(Library.OPTION_TYPE_MAPPER)) {
libraryOptions.put(Library.OPTION_TYPE_MAPPER, lookupField(mappingClass, "TYPE_MAPPER", TypeMapper.class));
}
@@ -640,7 +644,7 @@ public static Map getLibraryOptions(Class> type) {
libraryOptions = cacheOptions(mappingClass, libraryOptions, null);
// Store the original lookup class, if different from the mapping class
if (type != mappingClass) {
- options.put(type, libraryOptions);
+ typeOptions.put(type, libraryOptions);
}
return libraryOptions;
}
@@ -666,7 +670,8 @@ private static Object lookupField(Class> mappingClass, String fieldName, Class
* See {@link com.sun.jna.Library#OPTION_TYPE_MAPPER}.
*/
public static TypeMapper getTypeMapper(Class> cls) {
- return (TypeMapper)getLibraryOptions(cls).get(Library.OPTION_TYPE_MAPPER);
+ Map options = getLibraryOptions(cls);
+ return (TypeMapper) options.get(Library.OPTION_TYPE_MAPPER);
}
/**
@@ -676,7 +681,8 @@ public static TypeMapper getTypeMapper(Class> cls) {
* @see com.sun.jna.Library#OPTION_STRING_ENCODING
*/
public static String getStringEncoding(Class> cls) {
- String encoding = (String)getLibraryOptions(cls).get(Library.OPTION_STRING_ENCODING);
+ Map options = getLibraryOptions(cls);
+ String encoding = (String) options.get(Library.OPTION_STRING_ENCODING);
return encoding != null ? encoding : getDefaultStringEncoding();
}
@@ -1331,9 +1337,9 @@ static Class> findDirectMappedClass(Class> cls) {
was made.
*/
static Class> getCallingClass() {
- Class[] context = new SecurityManager() {
+ Class>[] context = new SecurityManager() {
@Override
- public Class[] getClassContext() {
+ public Class>[] getClassContext() {
return super.getClassContext();
}
}.getClassContext();
@@ -1356,16 +1362,16 @@ public static void setCallbackThreadInitializer(Callback cb, CallbackThreadIniti
CallbackReference.setCallbackThreadInitializer(cb, initializer);
}
- private static Map registeredClasses = new WeakHashMap();
- private static Map registeredLibraries = new WeakHashMap();
+ private static Map, long[]> registeredClasses = new WeakHashMap, long[]>();
+ private static Map, NativeLibrary> registeredLibraries = new WeakHashMap, NativeLibrary>();
private static void unregisterAll() {
synchronized(registeredClasses) {
- for (Iterator i=registeredClasses.entrySet().iterator();i.hasNext();) {
- Map.Entry e = (Map.Entry)i.next();
- unregister((Class>)e.getKey(), (long[])e.getValue());
- i.remove();
+ for (Map.Entry, long[]> e : registeredClasses.entrySet()) {
+ unregister(e.getKey(), e.getValue());
}
+
+ registeredClasses.clear();
}
}
@@ -1383,22 +1389,26 @@ public static void unregister() {
*/
public static void unregister(Class> cls) {
synchronized(registeredClasses) {
- if (registeredClasses.containsKey(cls)) {
- unregister(cls, (long[])registeredClasses.get(cls));
+ long[] handles = registeredClasses.get(cls);
+ if (handles != null) {
+ unregister(cls, handles);
registeredClasses.remove(cls);
registeredLibraries.remove(cls);
}
}
}
- /** @return whether the given class's native components are registered. */
+ /**
+ * @param cls The type {@link Class}
+ * @return whether the given class's native components are registered.
+ */
public static boolean registered(Class> cls) {
synchronized(registeredClasses) {
return registeredClasses.containsKey(cls);
}
}
- /** Unregister the native methods for the given class. */
+ /* Unregister the native methods for the given class. */
private static native void unregister(Class> cls, long[] handles);
static String getSignature(Class> cls) {
@@ -1571,9 +1581,9 @@ private static int getConversion(Class> type, TypeMapper mapper) {
* should be bound
*/
public static void register(Class> cls, String libName) {
- Map options = new HashMap();
- options.put(Library.OPTION_CLASSLOADER, cls.getClassLoader());
- register(cls, NativeLibrary.getInstance(libName, options));
+ NativeLibrary library =
+ NativeLibrary.getInstance(libName, Collections.singletonMap(Library.OPTION_CLASSLOADER, cls.getClassLoader()));
+ register(cls, library);
}
/** When called from a class static initializer, maps all native methods
@@ -1588,15 +1598,16 @@ public static void register(Class> cls, String libName) {
public static void register(Class> cls, NativeLibrary lib) {
Method[] methods = cls.getDeclaredMethods();
List mlist = new ArrayList();
- TypeMapper mapper = (TypeMapper)
- lib.getOptions().get(Library.OPTION_TYPE_MAPPER);
- cacheOptions(cls, lib.getOptions(), null);
+ Map options = lib.getOptions();
+ TypeMapper mapper = (TypeMapper) options.get(Library.OPTION_TYPE_MAPPER);
+ options = cacheOptions(cls, options, null);
for (Method m : methods) {
if ((m.getModifiers() & Modifier.NATIVE) != 0) {
mlist.add(m);
}
}
+
long[] handles = new long[mlist.size()];
for (int i=0;i < handles.length;i++) {
Method method = mlist.get(i);
@@ -1612,80 +1623,80 @@ public static void register(Class> cls, NativeLibrary lib) {
int rcvt = getConversion(rclass, mapper);
boolean throwLastError = false;
switch (rcvt) {
- case CVT_UNSUPPORTED:
- throw new IllegalArgumentException(rclass + " is not a supported return type (in method " + method.getName() + " in " + cls + ")");
- case CVT_TYPE_MAPPER:
- case CVT_TYPE_MAPPER_STRING:
- case CVT_TYPE_MAPPER_WSTRING:
- fromNative = mapper.getFromNativeConverter(rclass);
- // FFIType.get() always looks up the native type for any given
- // class, so if we actually have conversion into a Java
- // object, make sure we use the proper type information
- closure_rtype = FFIType.get(rclass.isPrimitive() ? rclass : Pointer.class).peer;
- rtype = FFIType.get(fromNative.nativeType()).peer;
- break;
- case CVT_NATIVE_MAPPED:
- case CVT_NATIVE_MAPPED_STRING:
- case CVT_NATIVE_MAPPED_WSTRING:
- case CVT_INTEGER_TYPE:
- case CVT_POINTER_TYPE:
- closure_rtype = FFIType.get(Pointer.class).peer;
- rtype = FFIType.get(NativeMappedConverter.getInstance(rclass).nativeType()).peer;
- break;
- case CVT_STRUCTURE:
- closure_rtype = rtype = FFIType.get(Pointer.class).peer;
- break;
- case CVT_STRUCTURE_BYVAL:
- closure_rtype = FFIType.get(Pointer.class).peer;
- rtype = FFIType.get(rclass).peer;
- break;
- default:
- closure_rtype = rtype = FFIType.get(rclass).peer;
- break;
+ case CVT_UNSUPPORTED:
+ throw new IllegalArgumentException(rclass + " is not a supported return type (in method " + method.getName() + " in " + cls + ")");
+ case CVT_TYPE_MAPPER:
+ case CVT_TYPE_MAPPER_STRING:
+ case CVT_TYPE_MAPPER_WSTRING:
+ fromNative = mapper.getFromNativeConverter(rclass);
+ // FFIType.get() always looks up the native type for any given
+ // class, so if we actually have conversion into a Java
+ // object, make sure we use the proper type information
+ closure_rtype = FFIType.get(rclass.isPrimitive() ? rclass : Pointer.class).peer;
+ rtype = FFIType.get(fromNative.nativeType()).peer;
+ break;
+ case CVT_NATIVE_MAPPED:
+ case CVT_NATIVE_MAPPED_STRING:
+ case CVT_NATIVE_MAPPED_WSTRING:
+ case CVT_INTEGER_TYPE:
+ case CVT_POINTER_TYPE:
+ closure_rtype = FFIType.get(Pointer.class).peer;
+ rtype = FFIType.get(NativeMappedConverter.getInstance(rclass).nativeType()).peer;
+ break;
+ case CVT_STRUCTURE:
+ closure_rtype = rtype = FFIType.get(Pointer.class).peer;
+ break;
+ case CVT_STRUCTURE_BYVAL:
+ closure_rtype = FFIType.get(Pointer.class).peer;
+ rtype = FFIType.get(rclass).peer;
+ break;
+ default:
+ closure_rtype = rtype = FFIType.get(rclass).peer;
}
+
for (int t=0;t < ptypes.length;t++) {
Class> type = ptypes[t];
sig += getSignature(type);
- cvt[t] = getConversion(type, mapper);
- if (cvt[t] == CVT_UNSUPPORTED) {
+ int conversionType = getConversion(type, mapper);
+ cvt[t] = conversionType;
+ if (conversionType == CVT_UNSUPPORTED) {
throw new IllegalArgumentException(type + " is not a supported argument type (in method " + method.getName() + " in " + cls + ")");
}
- if (cvt[t] == CVT_NATIVE_MAPPED
- || cvt[t] == CVT_NATIVE_MAPPED_STRING
- || cvt[t] == CVT_NATIVE_MAPPED_WSTRING
- || cvt[t] == CVT_INTEGER_TYPE) {
+ if ((conversionType == CVT_NATIVE_MAPPED)
+ || (conversionType == CVT_NATIVE_MAPPED_STRING)
+ || (conversionType == CVT_NATIVE_MAPPED_WSTRING)
+ || (conversionType == CVT_INTEGER_TYPE)) {
type = NativeMappedConverter.getInstance(type).nativeType();
- }
- else if (cvt[t] == CVT_TYPE_MAPPER
- || cvt[t] == CVT_TYPE_MAPPER_STRING
- || cvt[t] == CVT_TYPE_MAPPER_WSTRING) {
+ } else if ((conversionType == CVT_TYPE_MAPPER)
+ || (conversionType == CVT_TYPE_MAPPER_STRING)
+ || (conversionType == CVT_TYPE_MAPPER_WSTRING)) {
toNative[t] = mapper.getToNativeConverter(type);
}
+
// Determine the type that will be passed to the native
// function, as well as the type to be passed
// from Java initially
- switch(cvt[t]) {
- case CVT_STRUCTURE_BYVAL:
- case CVT_INTEGER_TYPE:
- case CVT_POINTER_TYPE:
- case CVT_NATIVE_MAPPED:
- case CVT_NATIVE_MAPPED_STRING:
- case CVT_NATIVE_MAPPED_WSTRING:
- atypes[t] = FFIType.get(type).peer;
- closure_atypes[t] = FFIType.get(Pointer.class).peer;
- break;
- case CVT_TYPE_MAPPER:
- case CVT_TYPE_MAPPER_STRING:
- case CVT_TYPE_MAPPER_WSTRING:
- closure_atypes[t] = FFIType.get(type.isPrimitive() ? type : Pointer.class).peer;
- atypes[t] = FFIType.get(toNative[t].nativeType()).peer;
- break;
- case CVT_DEFAULT:
- closure_atypes[t] = atypes[t] = FFIType.get(type).peer;
- break;
- default:
- closure_atypes[t] = atypes[t] = FFIType.get(Pointer.class).peer;
- break;
+ switch(conversionType) {
+ case CVT_STRUCTURE_BYVAL:
+ case CVT_INTEGER_TYPE:
+ case CVT_POINTER_TYPE:
+ case CVT_NATIVE_MAPPED:
+ case CVT_NATIVE_MAPPED_STRING:
+ case CVT_NATIVE_MAPPED_WSTRING:
+ atypes[t] = FFIType.get(type).peer;
+ closure_atypes[t] = FFIType.get(Pointer.class).peer;
+ break;
+ case CVT_TYPE_MAPPER:
+ case CVT_TYPE_MAPPER_STRING:
+ case CVT_TYPE_MAPPER_WSTRING:
+ closure_atypes[t] = FFIType.get(type.isPrimitive() ? type : Pointer.class).peer;
+ atypes[t] = FFIType.get(toNative[t].nativeType()).peer;
+ break;
+ case CVT_DEFAULT:
+ closure_atypes[t] = atypes[t] = FFIType.get(type).peer;
+ break;
+ default:
+ closure_atypes[t] = atypes[t] = FFIType.get(Pointer.class).peer;
}
}
sig += ")";
@@ -1710,8 +1721,7 @@ else if (cvt[t] == CVT_TYPE_MAPPER
throwLastError,
toNative, fromNative,
f.encoding);
- }
- catch(NoSuchMethodError e) {
+ } catch(NoSuchMethodError e) {
throw new UnsatisfiedLinkError("No method " + method.getName() + " with signature " + sig + " in " + cls);
}
}
@@ -1721,16 +1731,16 @@ else if (cvt[t] == CVT_TYPE_MAPPER
}
}
- /** Take note of options used for a given library mapping, to facilitate
- looking them up later.
- */
- private static Map cacheOptions(Class> cls, Map libOptions, Object proxy) {
- libOptions = new HashMap(libOptions);
+ /* Take note of options used for a given library mapping, to facilitate
+ * looking them up later.
+ */
+ private static Map cacheOptions(Class> cls, Map options, Object proxy) {
+ Map libOptions = new HashMap(options);
libOptions.put(_OPTION_ENCLOSING_LIBRARY, cls);
synchronized(libraries) {
- options.put(cls, libOptions);
+ typeOptions.put(cls, libOptions);
if (proxy != null) {
- libraries.put(cls, new WeakReference(proxy));
+ libraries.put(cls, new WeakReference(proxy));
}
// If it's a direct mapping, AND implements a Library interface,
@@ -1739,9 +1749,9 @@ private static Map cacheOptions(Class> cls, Map libOptions, Object proxy) {
if (!cls.isInterface()
&& Library.class.isAssignableFrom(cls)) {
Class> ifaces[] = cls.getInterfaces();
- for (int i=0;i < ifaces.length;i++) {
- if (Library.class.isAssignableFrom(ifaces[i])) {
- cacheOptions(ifaces[i], libOptions, proxy);
+ for (Class> ifc : ifaces) {
+ if (Library.class.isAssignableFrom(ifc)) {
+ cacheOptions(ifc, libOptions, proxy);
break;
}
}
@@ -1839,7 +1849,7 @@ public static void main(String[] args) {
*/
static synchronized native long createNativeCallback(Callback callback,
Method method,
- Class[] parameterTypes,
+ Class>[] parameterTypes,
Class> returnType,
int callingConvention,
int flags,
diff --git a/src/com/sun/jna/NativeLibrary.java b/src/com/sun/jna/NativeLibrary.java
index d60fce9362..ea753cb222 100644
--- a/src/com/sun/jna/NativeLibrary.java
+++ b/src/com/sun/jna/NativeLibrary.java
@@ -17,17 +17,18 @@
import java.io.BufferedReader;
import java.io.File;
import java.io.FilenameFilter;
-import java.io.InputStreamReader;
import java.io.IOException;
-import java.lang.ref.WeakReference;
+import java.io.InputStreamReader;
import java.lang.ref.Reference;
+import java.lang.ref.WeakReference;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.Iterator;
+import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -51,7 +52,7 @@
* with a name corresponding to that requested. Absolute paths to frameworks
* are also accepted, either ending at the framework name (sans ".framework")
* or the full path to the framework shared library
- * (e.g. CoreServices.framework/CoreServices).
+ * (e.g. CoreServices.framework/CoreServices).
* Context class loader classpath. Deployed native libraries may be
* installed on the classpath under
* ${os-prefix}/LIBRARY_FILENAME
, where ${os-prefix}
@@ -70,14 +71,14 @@ public class NativeLibrary {
private long handle;
private final String libraryName;
private final String libraryPath;
- private final Map functions = new HashMap();
+ private final Map functions = new HashMap();
final int callFlags;
private String encoding;
- final Map options;
+ final Map options;
- private static final Map libraries = new HashMap();
- private static final Map searchPaths = Collections.synchronizedMap(new HashMap());
- private static final List librarySearchPath = new LinkedList();
+ private static final Map> libraries = new HashMap>();
+ private static final Map> searchPaths = Collections.synchronizedMap(new HashMap>());
+ private static final List librarySearchPath = new ArrayList();
static {
// Force initialization of native library
@@ -89,13 +90,12 @@ private static String functionKey(String name, int flags, String encoding) {
return name + "|" + flags + "|" + encoding;
}
- private NativeLibrary(String libraryName, String libraryPath, long handle, Map options) {
+ private NativeLibrary(String libraryName, String libraryPath, long handle, Map options) {
this.libraryName = getLibraryName(libraryName);
this.libraryPath = libraryPath;
this.handle = handle;
Object option = options.get(Library.OPTION_CALLING_CONVENTION);
- int callingConvention = option instanceof Number
- ? ((Number)option).intValue() : Function.C_CONVENTION;
+ int callingConvention = option instanceof Number ? ((Number)option).intValue() : Function.C_CONVENTION;
this.callFlags = callingConvention;
this.options = options;
this.encoding = (String)options.get(Library.OPTION_STRING_ENCODING);
@@ -108,8 +108,9 @@ private NativeLibrary(String libraryName, String libraryPath, long handle, Map o
if (Platform.isWindows() && "kernel32".equals(this.libraryName.toLowerCase())) {
synchronized(functions) {
Function f = new Function(this, "GetLastError", Function.ALT_CONVENTION, encoding) {
- Object invoke(Object[] args, Class returnType, boolean b) {
- return new Integer(Native.getLastError());
+ @Override
+ Object invoke(Object[] args, Class> returnType, boolean b) {
+ return Integer.valueOf(Native.getLastError());
}
};
functions.put(functionKey("GetLastError", callFlags, encoding), f);
@@ -118,7 +119,7 @@ Object invoke(Object[] args, Class returnType, boolean b) {
}
private static final int DEFAULT_OPEN_OPTIONS = -1;
- private static int openFlags(Map options) {
+ private static int openFlags(Map options) {
Object opt = options.get(Library.OPTION_OPEN_FLAGS);
if (opt instanceof Number) {
return ((Number)opt).intValue();
@@ -126,38 +127,39 @@ private static int openFlags(Map options) {
return DEFAULT_OPEN_OPTIONS;
}
- private static NativeLibrary loadLibrary(String libraryName, Map options) {
- if (Native.DEBUG_LOAD) {
- System.out.println("Looking for library '" + libraryName + "'");
- }
+ private static NativeLibrary loadLibrary(String libraryName, Map options) {
+ if (Native.DEBUG_LOAD) {
+ System.out.println("Looking for library '" + libraryName + "'");
+ }
boolean isAbsolutePath = new File(libraryName).isAbsolute();
- List searchPath = new LinkedList();
+ List searchPath = new ArrayList();
int openFlags = openFlags(options);
// Append web start path, if available. Note that this does not
// attempt any library name variations
String webstartPath = Native.getWebStartLibraryPath(libraryName);
if (webstartPath != null) {
- if (Native.DEBUG_LOAD) {
- System.out.println("Adding web start path " + webstartPath);
- }
+ if (Native.DEBUG_LOAD) {
+ System.out.println("Adding web start path " + webstartPath);
+ }
searchPath.add(webstartPath);
}
//
// Prepend any custom search paths specifically for this library
//
- List customPaths = (List) searchPaths.get(libraryName);
+ List customPaths = searchPaths.get(libraryName);
if (customPaths != null) {
synchronized (customPaths) {
searchPath.addAll(0, customPaths);
}
}
- if (Native.DEBUG_LOAD) {
- System.out.println("Adding paths from jna.library.path: " + System.getProperty("jna.library.path"));
- }
+ if (Native.DEBUG_LOAD) {
+ System.out.println("Adding paths from jna.library.path: " + System.getProperty("jna.library.path"));
+ }
+
searchPath.addAll(initPaths("jna.library.path"));
String libraryPath = findLibraryPath(libraryName, searchPath);
long handle = 0;
@@ -167,92 +169,99 @@ private static NativeLibrary loadLibrary(String libraryName, Map options) {
// name if it cannot find the library.
//
try {
- if (Native.DEBUG_LOAD) {
- System.out.println("Trying " + libraryPath);
- }
+ if (Native.DEBUG_LOAD) {
+ System.out.println("Trying " + libraryPath);
+ }
handle = Native.open(libraryPath, openFlags);
- }
- catch(UnsatisfiedLinkError e) {
+ } catch(UnsatisfiedLinkError e) {
// Add the system paths back for all fallback searching
- if (Native.DEBUG_LOAD) {
- System.out.println("Adding system paths: " + librarySearchPath);
- }
+ if (Native.DEBUG_LOAD) {
+ System.out.println("Adding system paths: " + librarySearchPath);
+ }
searchPath.addAll(librarySearchPath);
}
+
try {
if (handle == 0) {
libraryPath = findLibraryPath(libraryName, searchPath);
- if (Native.DEBUG_LOAD) {
- System.out.println("Trying " + libraryPath);
- }
+ if (Native.DEBUG_LOAD) {
+ System.out.println("Trying " + libraryPath);
+ }
handle = Native.open(libraryPath, openFlags);
if (handle == 0) {
throw new UnsatisfiedLinkError("Failed to load library '" + libraryName + "'");
}
}
- }
- catch(UnsatisfiedLinkError e) {
- // For android, try to "preload" the library using
+ } catch(UnsatisfiedLinkError e) {
+ // For android, try to "preload" the library using
// System.loadLibrary(), which looks into the private /data/data
// path, not found in any properties
if (Platform.isAndroid()) {
try {
- if (Native.DEBUG_LOAD) {
- System.out.println("Preload (via System.loadLibrary) " + libraryName);
- }
+ if (Native.DEBUG_LOAD) {
+ System.out.println("Preload (via System.loadLibrary) " + libraryName);
+ }
System.loadLibrary(libraryName);
handle = Native.open(libraryPath, openFlags);
}
- catch(UnsatisfiedLinkError e2) { e = e2; }
+ catch(UnsatisfiedLinkError e2) {
+ e = e2;
+ }
}
else if (Platform.isLinux() || Platform.isFreeBSD()) {
//
// Failed to load the library normally - try to match libfoo.so.*
//
- if (Native.DEBUG_LOAD) {
- System.out.println("Looking for version variants");
- }
+ if (Native.DEBUG_LOAD) {
+ System.out.println("Looking for version variants");
+ }
libraryPath = matchLibrary(libraryName, searchPath);
if (libraryPath != null) {
- if (Native.DEBUG_LOAD) {
- System.out.println("Trying " + libraryPath);
- }
- try {
+ if (Native.DEBUG_LOAD) {
+ System.out.println("Trying " + libraryPath);
+ }
+ try {
handle = Native.open(libraryPath, openFlags);
}
- catch(UnsatisfiedLinkError e2) { e = e2; }
+ catch(UnsatisfiedLinkError e2) {
+ e = e2;
+ }
}
}
// Search framework libraries on OS X
- else if (Platform.isMac()
- && !libraryName.endsWith(".dylib")) {
- if (Native.DEBUG_LOAD) {
- System.out.println("Looking for matching frameworks");
- }
+ else if (Platform.isMac() && !libraryName.endsWith(".dylib")) {
+ if (Native.DEBUG_LOAD) {
+ System.out.println("Looking for matching frameworks");
+ }
libraryPath = matchFramework(libraryName);
if (libraryPath != null) {
try {
- if (Native.DEBUG_LOAD) {
- System.out.println("Trying " + libraryPath);
- }
+ if (Native.DEBUG_LOAD) {
+ System.out.println("Trying " + libraryPath);
+ }
handle = Native.open(libraryPath, openFlags);
}
- catch(UnsatisfiedLinkError e2) { e = e2; }
+ catch(UnsatisfiedLinkError e2) {
+ e = e2;
+ }
}
}
// Try the same library with a "lib" prefix
else if (Platform.isWindows() && !isAbsolutePath) {
- if (Native.DEBUG_LOAD) {
- System.out.println("Looking for lib- prefix");
- }
+ if (Native.DEBUG_LOAD) {
+ System.out.println("Looking for lib- prefix");
+ }
libraryPath = findLibraryPath("lib" + libraryName, searchPath);
- if (libraryPath != null) {
- if (Native.DEBUG_LOAD) {
- System.out.println("Trying " + libraryPath);
- }
- try { handle = Native.open(libraryPath, openFlags); }
- catch(UnsatisfiedLinkError e2) { e = e2; }
- }
+ if (libraryPath != null) {
+ if (Native.DEBUG_LOAD) {
+ System.out.println("Trying " + libraryPath);
+ }
+ try {
+ handle = Native.open(libraryPath, openFlags);
+ } catch(UnsatisfiedLinkError e2) {
+ e = e2;
+ }
+ }
}
// As a last resort, try to extract the library from the class
// path, using the current context class loader.
@@ -269,17 +278,19 @@ else if (Platform.isWindows() && !isAbsolutePath) {
}
}
}
- catch(IOException e2) { e = new UnsatisfiedLinkError(e2.getMessage()); }
+ catch(IOException e2) {
+ e = new UnsatisfiedLinkError(e2.getMessage());
+ }
}
if (handle == 0) {
- throw new UnsatisfiedLinkError("Unable to load library '" + libraryName + "': "
- + e.getMessage());
+ throw new UnsatisfiedLinkError("Unable to load library '" + libraryName + "': " + e.getMessage());
}
}
- if (Native.DEBUG_LOAD) {
- System.out.println("Found library '" + libraryName + "' at " + libraryPath);
- }
+
+ if (Native.DEBUG_LOAD) {
+ System.out.println("Found library '" + libraryName + "' at " + libraryPath);
+ }
return new NativeLibrary(libraryName, libraryPath, handle, options);
}
@@ -339,7 +350,7 @@ private String getLibraryName(String libraryName) {
* the full path to the library (e.g. "/lib/libc.so.6").
*/
public static final NativeLibrary getInstance(String libraryName) {
- return getInstance(libraryName, Collections.EMPTY_MAP);
+ return getInstance(libraryName, Collections.emptyMap());
}
/**
@@ -359,9 +370,7 @@ public static final NativeLibrary getInstance(String libraryName) {
* or as a plain file within the classpath.
*/
public static final NativeLibrary getInstance(String libraryName, ClassLoader classLoader) {
- Map map = new HashMap();
- map.put(Library.OPTION_CLASSLOADER, classLoader);
- return getInstance(libraryName, map);
+ return getInstance(libraryName, Collections.singletonMap(Library.OPTION_CLASSLOADER, classLoader));
}
/**
@@ -374,15 +383,14 @@ public static final NativeLibrary getInstance(String libraryName, ClassLoader cl
* @param libraryName The library name to load.
* This can be short form (e.g. "c"),
* an explicit version (e.g. "libc.so.6" or
- * "QuickTime.framework/Versions/Current/QuickTime"), or
- * the full (absolute) path to the library (e.g. "/lib/libc.so.6").
- * @param options native library options for the given library (see {@link
- * Library}).
+ * "QuickTime.framework/Versions/Current/QuickTime"), or
+ * the full (absolute) path to the library (e.g. "/lib/libc.so.6").
+ * @param libraryOptions Native library options for the given library (see {@link Library}).
*/
- public static final NativeLibrary getInstance(String libraryName, Map options) {
- options = new HashMap(options);
+ public static final NativeLibrary getInstance(String libraryName, Map libraryOptions) {
+ Map options = new HashMap(libraryOptions);
if (options.get(Library.OPTION_CALLING_CONVENTION) == null) {
- options.put(Library.OPTION_CALLING_CONVENTION, new Integer(Function.C_CONVENTION));
+ options.put(Library.OPTION_CALLING_CONVENTION, Integer.valueOf(Function.C_CONVENTION));
}
// Use current process to load libraries we know are already
@@ -392,8 +400,8 @@ public static final NativeLibrary getInstance(String libraryName, Map options) {
libraryName = null;
}
synchronized (libraries) {
- WeakReference ref = (WeakReference)libraries.get(libraryName + options);
- NativeLibrary library = ref != null ? (NativeLibrary)ref.get() : null;
+ Reference ref = libraries.get(libraryName + options);
+ NativeLibrary library = (ref != null) ? ref.get() : null;
if (library == null) {
if (libraryName == null) {
@@ -402,7 +410,7 @@ public static final NativeLibrary getInstance(String libraryName, Map options) {
else {
library = loadLibrary(libraryName, options);
}
- ref = new WeakReference(library);
+ ref = new WeakReference(library);
libraries.put(library.getName() + options, ref);
File file = library.getFile();
if (file != null) {
@@ -430,7 +438,7 @@ public static synchronized final NativeLibrary getProcess() {
* mapped by some other mechanism, without having to reference or even
* know the exact name of the native library.
*/
- public static synchronized final NativeLibrary getProcess(Map options) {
+ public static synchronized final NativeLibrary getProcess(Map options) {
return getInstance(null, options);
}
@@ -444,15 +452,16 @@ public static synchronized final NativeLibrary getProcess(Map options) {
*/
public static final void addSearchPath(String libraryName, String path) {
synchronized (searchPaths) {
- List customPaths = (List) searchPaths.get(libraryName);
+ List customPaths = searchPaths.get(libraryName);
if (customPaths == null) {
- customPaths = Collections.synchronizedList(new LinkedList());
+ customPaths = Collections.synchronizedList(new ArrayList());
searchPaths.put(libraryName, customPaths);
}
customPaths.add(path);
}
}
+
/**
* Create a new {@link Function} that is linked with a native
* function that follows the NativeLibrary's calling convention.
@@ -460,8 +469,8 @@ public static final void addSearchPath(String libraryName, String path) {
* The allocated instance represents a pointer to the named native
* function from the library.
*
- * @param functionName
- * Name of the native function to be linked with
+ * @param functionName
+ * Name of the native function to be linked with
* @throws UnsatisfiedLinkError if the function is not found
*/
public Function getFunction(String functionName) {
@@ -475,17 +484,16 @@ public Function getFunction(String functionName) {
*
The allocated instance represents a pointer to the named native
* function from the library.
*
- * @param name
- * Name of the native function to be linked with. Uses a
- * function mapper option if one was provided to
- * transform the name.
- * @param method
- * Method to which the native function is to be mapped
+ * @param name
+ * Name of the native function to be linked with. Uses a
+ * function mapper option if one was provided to
+ * transform the name.
+ * @param method
+ * Method to which the native function is to be mapped
* @throws UnsatisfiedLinkError if the function is not found
*/
Function getFunction(String name, Method method) {
- FunctionMapper mapper = (FunctionMapper)
- options.get(Library.OPTION_FUNCTION_MAPPER);
+ FunctionMapper mapper = (FunctionMapper) options.get(Library.OPTION_FUNCTION_MAPPER);
if (mapper != null) {
name = mapper.getFunctionName(this, method);
}
@@ -495,7 +503,7 @@ Function getFunction(String name, Method method) {
name = name.substring(prefix.length());
}
int flags = this.callFlags;
- Class[] etypes = method.getExceptionTypes();
+ Class>[] etypes = method.getExceptionTypes();
for (int i=0;i < etypes.length;i++) {
if (LastErrorException.class.isAssignableFrom(etypes[i])) {
flags |= Function.THROW_LAST_ERROR;
@@ -508,10 +516,10 @@ Function getFunction(String name, Method method) {
* Create a new {@link Function} that is linked with a native
* function that follows a given calling flags.
*
- * @param functionName
- * Name of the native function to be linked with
- * @param callFlags
- * Flags affecting the function invocation
+ * @param functionName
+ * Name of the native function to be linked with
+ * @param callFlags
+ * Flags affecting the function invocation
* @throws UnsatisfiedLinkError if the function is not found
*/
public Function getFunction(String functionName, int callFlags) {
@@ -522,21 +530,22 @@ public Function getFunction(String functionName, int callFlags) {
* Create a new {@link Function} that is linked with a native
* function that follows a given calling flags.
*
- * @param functionName
- * Name of the native function to be linked with
- * @param callFlags
- * Flags affecting the function invocation
+ * @param functionName
+ * Name of the native function to be linked with
+ * @param callFlags
+ * Flags affecting the function invocation
* @param encoding
* Encoding to use to convert between Java and native
- * strings.
+ * strings.
* @throws UnsatisfiedLinkError if the function is not found
*/
public Function getFunction(String functionName, int callFlags, String encoding) {
- if (functionName == null)
+ if (functionName == null) {
throw new NullPointerException("Function name may not be null");
+ }
synchronized (functions) {
String key = functionKey(functionName, callFlags, encoding);
- Function function = (Function) functions.get(key);
+ Function function = functions.get(key);
if (function == null) {
function = new Function(this, functionName, callFlags, encoding);
functions.put(key, function);
@@ -545,8 +554,8 @@ public Function getFunction(String functionName, int callFlags, String encoding)
}
}
- /** Returns this native library instance's options. */
- public Map getOptions() {
+ /** @return this native library instance's options. */
+ public Map getOptions() {
return options;
}
@@ -558,11 +567,8 @@ public Map getOptions() {
public Pointer getGlobalVariableAddress(String symbolName) {
try {
return new Pointer(getSymbolAddress(symbolName));
- }
- catch(UnsatisfiedLinkError e) {
- throw new UnsatisfiedLinkError("Error looking up '"
- + symbolName + "': "
- + e.getMessage());
+ } catch(UnsatisfiedLinkError e) {
+ throw new UnsatisfiedLinkError("Error looking up '" + symbolName + "': " + e.getMessage());
}
}
@@ -576,6 +582,8 @@ long getSymbolAddress(String name) {
}
return Native.findSymbol(handle, name);
}
+
+ @Override
public String toString() {
return "Native Library <" + libraryPath + "@" + handle + ">";
}
@@ -593,19 +601,19 @@ public File getFile() {
return new File(libraryPath);
}
/** Close the library when it is no longer referenced. */
+ @Override
protected void finalize() {
dispose();
}
/** Close all open native libraries. */
static void disposeAll() {
- Set values;
+ Set> values;
synchronized(libraries) {
- values = new HashSet(libraries.values());
+ values = new LinkedHashSet>(libraries.values());
}
- for (Iterator i=values.iterator();i.hasNext();) {
- Reference ref = (WeakReference)i.next();
- NativeLibrary lib = (NativeLibrary)ref.get();
+ for (Reference ref : values) {
+ NativeLibrary lib = ref.get();
if (lib != null) {
lib.dispose();
}
@@ -614,14 +622,20 @@ static void disposeAll() {
/** Close the native library we're mapped to. */
public void dispose() {
+ Set keys = new HashSet();
synchronized(libraries) {
- for (Iterator i=libraries.values().iterator();i.hasNext();) {
- Reference ref = (WeakReference)i.next();
+ for (Map.Entry> e : libraries.entrySet()) {
+ Reference ref = e.getValue();
if (ref.get() == this) {
- i.remove();
+ keys.add(e.getKey());
}
}
+
+ for (String k : keys) {
+ libraries.remove(k);
+ }
}
+
synchronized(this) {
if (handle != 0) {
Native.close(handle);
@@ -630,13 +644,13 @@ public void dispose() {
}
}
- private static List initPaths(String key) {
+ private static List initPaths(String key) {
String value = System.getProperty(key, "");
if ("".equals(value)) {
- return Collections.EMPTY_LIST;
+ return Collections.emptyList();
}
StringTokenizer st = new StringTokenizer(value, File.pathSeparator);
- List list = new ArrayList();
+ List list = new ArrayList();
while (st.hasMoreTokens()) {
String path = st.nextToken();
if (!"".equals(path)) {
@@ -647,7 +661,7 @@ private static List initPaths(String key) {
}
/** Use standard library search paths to find the library. */
- private static String findLibraryPath(String libName, List searchPath) {
+ private static String findLibraryPath(String libName, List searchPath) {
//
// If a full path to the library was specified, don't search for it
@@ -662,8 +676,7 @@ private static String findLibraryPath(String libName, List searchPath) {
String name = mapSharedLibraryName(libName);
// Search in the JNA paths for it
- for (Iterator it = searchPath.iterator(); it.hasNext(); ) {
- String path = (String)it.next();
+ for (String path : searchPath) {
File file = new File(path, name);
if (file.exists()) {
return file.getAbsolutePath();
@@ -713,7 +726,7 @@ else if (Platform.isLinux() || Platform.isFreeBSD()) {
return libName;
}
}
- else if (Platform.isAIX()) { // can be libx.a, libx.a(shr.o), libx.so
+ else if (Platform.isAIX()) { // can be libx.a, libx.a(shr.o), libx.so
if (libName.startsWith("lib")) {
return libName;
}
@@ -748,12 +761,13 @@ private static boolean isVersionedName(String name) {
* where /usr/lib/libc.so does not exist, or it is not a valid symlink to
* a versioned file (e.g. /lib/libc.so.6).
*/
- static String matchLibrary(final String libName, List searchPath) {
- File lib = new File(libName);
+ static String matchLibrary(final String libName, List searchPath) {
+ File lib = new File(libName);
if (lib.isAbsolute()) {
- searchPath = Arrays.asList(new String[] { lib.getParent() });
+ searchPath = Arrays.asList(lib.getParent());
}
FilenameFilter filter = new FilenameFilter() {
+ @Override
public boolean accept(File dir, String filename) {
return (filename.startsWith("lib" + libName + ".so")
|| (filename.startsWith(libName + ".so")
@@ -762,9 +776,9 @@ public boolean accept(File dir, String filename) {
}
};
- List matches = new LinkedList();
- for (Iterator it = searchPath.iterator(); it.hasNext(); ) {
- File[] files = new File((String) it.next()).listFiles(filter);
+ Collection matches = new LinkedList();
+ for (String path : searchPath) {
+ File[] files = new File(path).listFiles(filter);
if (files != null && files.length > 0) {
matches.addAll(Arrays.asList(files));
}
@@ -775,8 +789,8 @@ public boolean accept(File dir, String filename) {
// i.e. libc.so.6 is preferred over libc.so.5
double bestVersion = -1;
String bestMatch = null;
- for (Iterator it = matches.iterator(); it.hasNext(); ) {
- String path = ((File) it.next()).getAbsolutePath();
+ for (File f : matches) {
+ String path = f.getAbsolutePath();
String ver = path.substring(path.lastIndexOf(".so.") + 4);
double version = parseVersion(ver);
if (version > bestVersion) {
@@ -788,10 +802,10 @@ public boolean accept(File dir, String filename) {
}
static double parseVersion(String ver) {
- double v = 0;
- double divisor = 1;
- int dot = ver.indexOf(".");
- while (ver != null) {
+ double v = 0;
+ double divisor = 1;
+ int dot = ver.indexOf(".");
+ while (ver != null) {
String num;
if (dot != -1) {
num = ver.substring(0, dot);
@@ -809,9 +823,9 @@ static double parseVersion(String ver) {
return 0;
}
divisor *= 100;
- }
+ }
- return v;
+ return v;
}
static {
@@ -906,7 +920,7 @@ private static String getMultiArchPath() {
? "-kfreebsd"
: (Platform.isGNU() ? "" : "-linux");
String libc = "-gnu";
-
+
if (Platform.isIntel()) {
cpu = (Platform.is64Bit() ? "x86_64" : "i386");
}
@@ -917,7 +931,7 @@ else if (Platform.isARM()) {
cpu = "arm";
libc = "-gnueabi";
}
-
+
return cpu + kernel + libc;
}
diff --git a/src/com/sun/jna/NativeLong.java b/src/com/sun/jna/NativeLong.java
index 2d9dd17b8e..a760bf2a05 100644
--- a/src/com/sun/jna/NativeLong.java
+++ b/src/com/sun/jna/NativeLong.java
@@ -8,7 +8,7 @@
* This library 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 for more details.
+ * Lesser General Public License for more details.
*/
package com.sun.jna;
@@ -19,6 +19,7 @@
* @author wmeissner@gmail.com
*/
public class NativeLong extends IntegerType {
+ private static final long serialVersionUID = 1L;
/** Size of a native long, in bytes. */
public static final int SIZE = Native.LONG_SIZE;
@@ -26,7 +27,7 @@ public class NativeLong extends IntegerType {
public NativeLong() {
this(0);
}
-
+
/** Create a NativeLong with the given value. */
public NativeLong(long value) {
this(value, false);
diff --git a/src/com/sun/jna/NativeMapped.java b/src/com/sun/jna/NativeMapped.java
index a8a347e8d2..92065dd903 100644
--- a/src/com/sun/jna/NativeMapped.java
+++ b/src/com/sun/jna/NativeMapped.java
@@ -1,27 +1,27 @@
/* Copyright (c) 2007 Wayne Meissner, All Rights Reserved
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
- *
+ *
* This library 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 for more details.
+ * Lesser General Public License for more details.
*/
package com.sun.jna;
-/** Provide conversion for a Java type to and from a native type.
+/** Provide conversion for a Java type to and from a native type.
* {@link Function} and {@link Structure} will use this interface to determine
* how to map a given Java object into a native type.
* Implementations of this interface must provide a no-args constructor.
* See {@link ToNativeConverter} for a list of allowable native types.
- * @author wmeissner
+ * @author wmeissner
*/
public interface NativeMapped {
/** Convert the given native object into its Java representation using
- * the given context.
+ * the given context.
* @param nativeValue Java representation of the native type to be converted.
* @param context Context in which the conversion is taking place.
* @return Converted object.
@@ -34,5 +34,5 @@ public interface NativeMapped {
/** Indicate the native type used by this converter.
* @return Java class representation of the native type.
*/
- Class nativeType();
+ Class> nativeType();
}
diff --git a/src/com/sun/jna/NativeMappedConverter.java b/src/com/sun/jna/NativeMappedConverter.java
index 421dd8ff8c..963af3b3bb 100644
--- a/src/com/sun/jna/NativeMappedConverter.java
+++ b/src/com/sun/jna/NativeMappedConverter.java
@@ -19,27 +19,27 @@
/** Provides type conversion for instances of {@link NativeMapped}. */
public class NativeMappedConverter implements TypeConverter {
- private static final Map/*>*/ converters = new WeakHashMap();
- private final Class type;
- private final Class nativeType;
+ private static final Map, Reference> converters =
+ new WeakHashMap, Reference>();
+ private final Class> type;
+ private final Class> nativeType;
private final NativeMapped instance;
- public static NativeMappedConverter getInstance(Class cls) {
+ public static NativeMappedConverter getInstance(Class> cls) {
synchronized(converters) {
- Reference r = (Reference)converters.get(cls);
- NativeMappedConverter nmc = r != null ? (NativeMappedConverter)r.get() : null;
+ Reference r = converters.get(cls);
+ NativeMappedConverter nmc = r != null ? r.get() : null;
if (nmc == null) {
nmc = new NativeMappedConverter(cls);
- converters.put(cls, new SoftReference(nmc));
+ converters.put(cls, new SoftReference(nmc));
}
return nmc;
}
}
- public NativeMappedConverter(Class type) {
+ public NativeMappedConverter(Class> type) {
if (!NativeMapped.class.isAssignableFrom(type))
- throw new IllegalArgumentException("Type must derive from "
- + NativeMapped.class);
+ throw new IllegalArgumentException("Type must derive from " + NativeMapped.class);
this.type = type;
this.instance = defaultValue();
this.nativeType = instance.nativeType();
@@ -48,26 +48,27 @@ public NativeMappedConverter(Class type) {
public NativeMapped defaultValue() {
try {
return (NativeMapped)type.newInstance();
- }
- catch (InstantiationException e) {
+ } catch (InstantiationException e) {
String msg = "Can't create an instance of " + type
+ ", requires a no-arg constructor: " + e;
throw new IllegalArgumentException(msg);
- }
- catch (IllegalAccessException e) {
+ } catch (IllegalAccessException e) {
String msg = "Not allowed to create an instance of " + type
+ ", requires a public, no-arg constructor: " + e;
throw new IllegalArgumentException(msg);
}
}
+ @Override
public Object fromNative(Object nativeValue, FromNativeContext context) {
return instance.fromNative(nativeValue, context);
}
- public Class nativeType() {
+ @Override
+ public Class> nativeType() {
return nativeType;
}
+ @Override
public Object toNative(Object value, ToNativeContext context) {
if (value == null) {
if (Pointer.class.isAssignableFrom(nativeType)) {
diff --git a/src/com/sun/jna/NativeString.java b/src/com/sun/jna/NativeString.java
index 81f1b726fa..4250c68f98 100644
--- a/src/com/sun/jna/NativeString.java
+++ b/src/com/sun/jna/NativeString.java
@@ -6,16 +6,16 @@
* This library 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 for more details.
+ * Lesser General Public License for more details.
*/
package com.sun.jna;
import java.nio.CharBuffer;
-/** Provides a temporary allocation of an immutable C string
- * (const char*
or const wchar_t*
) for use when
- * converting a Java String into a native memory function argument.
+/** Provides a temporary allocation of an immutable C string
+ * (const char*
or const wchar_t*
) for use when
+ * converting a Java String into a native memory function argument.
*
* @author Todd Fast, todd.fast@sun.com
* @author twall@users.sf.net
@@ -29,6 +29,7 @@ class NativeString implements CharSequence, Comparable {
private class StringMemory extends Memory {
public StringMemory(long size) { super(size); }
+ @Override
public String toString() {
return NativeString.this.toString();
}
@@ -44,8 +45,8 @@ public NativeString(String string) {
/** Create a native string as a NUL-terminated array of wchar_t
* (if wide
is true) or char
.
* If not wide
, the encoding is obtained from {@link
- * Native#getDefaultStringEncoding()}.
- *
+ * Native#getDefaultStringEncoding()}.
+ *
* @param string value to write to native memory
* @param wide whether to store the String as wchar_t
*/
@@ -54,7 +55,7 @@ public NativeString(String string, boolean wide) {
}
/** Create a native string as a NUL-terminated array of
- * wchar_t
.
+ * wchar_t
.
*/
public NativeString(WString string) {
this(string.toString(), WIDE_STRING);
@@ -68,15 +69,14 @@ public NativeString(String string, String encoding) {
throw new NullPointerException("String must not be null");
}
// Allocate the memory to hold the string. Note, we have to
- // make this 1 element longer in order to accommodate the terminating
+ // make this 1 element longer in order to accommodate the terminating
// NUL (which is generated in Pointer.setString()).
this.encoding = encoding;
- if (this.encoding == WIDE_STRING) {
+ if (WIDE_STRING.equals(this.encoding)) {
int len = (string.length() + 1 ) * Native.WCHAR_SIZE;
pointer = new StringMemory(len);
pointer.setWideString(0, string);
- }
- else {
+ } else {
byte[] data = Native.getBytes(string, encoding);
pointer = new StringMemory(data.length + 1);
pointer.write(0, data, 0, data.length);
@@ -84,20 +84,22 @@ public NativeString(String string, String encoding) {
}
}
+ @Override
public int hashCode() {
return toString().hashCode();
}
+ @Override
public boolean equals(Object other) {
-
if (other instanceof CharSequence) {
return compareTo(other) == 0;
}
return false;
}
+ @Override
public String toString() {
- boolean wide = encoding == WIDE_STRING;
+ boolean wide = WIDE_STRING.equals(encoding);
String s = wide ? "const wchar_t*" : "const char*";
s += "(" + (wide ? pointer.getWideString(0) : pointer.getString(0, encoding)) + ")";
return s;
@@ -107,20 +109,23 @@ public Pointer getPointer() {
return pointer;
}
+ @Override
public char charAt(int index) {
return toString().charAt(index);
}
+ @Override
public int length() {
return toString().length();
}
+ @Override
public CharSequence subSequence(int start, int end) {
return CharBuffer.wrap(toString()).subSequence(start, end);
}
+ @Override
public int compareTo(Object other) {
-
if (other == null)
return 1;
diff --git a/src/com/sun/jna/Pointer.java b/src/com/sun/jna/Pointer.java
index 111a683644..264d54f19f 100644
--- a/src/com/sun/jna/Pointer.java
+++ b/src/com/sun/jna/Pointer.java
@@ -6,7 +6,7 @@
* This library 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 for more details.
+ * Lesser General Public License for more details.
*/
package com.sun.jna;
@@ -18,13 +18,13 @@
import java.util.List;
/**
- * An abstraction for a native pointer data type. A Pointer instance
- * represents, on the Java side, a native pointer. The native pointer could
- * be any type of native pointer. Methods such as write
,
- * read
, getXXX
, and setXXX
, provide
+ * An abstraction for a native pointer data type. A Pointer instance
+ * represents, on the Java side, a native pointer. The native pointer could
+ * be any type of native pointer. Methods such as write
,
+ * read
, getXXX
, and setXXX
, provide
* means to access memory underlying the native pointer.
* While a constructor exists to create a Pointer from an integer value, it's
- * not generally a good idea to be creating pointers that way.
+ * not generally a good idea to be creating pointers that way.
*
* @author Sheng Liang, originator
* @author Todd Fast, suitability modifications
@@ -35,22 +35,22 @@ public class Pointer {
/** Size of a native pointer, in bytes. */
public static final int SIZE;
-
+
static {
// Force load of native library
if ((SIZE = Native.POINTER_SIZE) == 0) {
throw new Error("Native library not initialized");
}
}
-
+
/** Convenience constant, same as null
. */
public static final Pointer NULL = null;
-
+
/** Convenience constant, equivalent to (void*)CONSTANT
. */
public static final Pointer createConstant(long peer) {
return new Opaque(peer);
}
-
+
/** Convenience constant, equivalent to (void*)CONSTANT
.
This version will avoid setting any of the high bits on 64-bit
systems.
@@ -58,14 +58,16 @@ public static final Pointer createConstant(long peer) {
public static final Pointer createConstant(int peer) {
return new Opaque((long)peer & 0xFFFFFFFF);
}
-
- /** Pointer value of the real native pointer. Use long to be 64-bit safe.
+
+ /** Pointer value of the real native pointer. Use long to be 64-bit safe.
*/
protected long peer;
/** Derived class must assign peer pointer value. */
- Pointer() { }
-
+ Pointer() {
+ super();
+ }
+
/** Create from native pointer. Don't use this unless you know what
* you're doing.
*/
@@ -77,12 +79,14 @@ public Pointer(long peer) {
public Pointer share(long offset) {
return share(offset, 0);
}
-
+
/** Provide a view of this memory using the given offset to calculate a
* new base address, bounds-limiting the memory with the given size.
*/
public Pointer share(long offset, long sz) {
- if (offset == 0) return this;
+ if (offset == 0L) {
+ return this;
+ }
return new Pointer(peer + offset);
}
@@ -91,27 +95,18 @@ public void clear(long size) {
setMemory(0, size, (byte)0);
}
- /**
- * Compares this Pointer
to the specified object.
- *
- * @param o
- * A Pointer
instance
- * @return True if the other object is a Pointer
,
- * and the C pointers being pointed to by these objects are also
- * equal. Returns false otherwise.
- */
+ @Override
public boolean equals(Object o) {
- if (o == this) return true;
- if (o == null) return false;
- return o instanceof Pointer && ((Pointer)o).peer == peer;
+ if (o == this) {
+ return true;
+ }
+ if (o == null) {
+ return false;
+ }
+ return (o instanceof Pointer) && (((Pointer)o).peer == peer);
}
- /**
- * Returns a hashcode for the native pointer represented by this
- * Pointer
object
- *
- * @return A hash code value for the represented native pointer
- */
+ @Override
public int hashCode() {
return (int)((peer >>> 32) + (peer & 0xFFFFFFFF));
}
@@ -127,7 +122,7 @@ public int hashCode() {
public long indexOf(long offset, byte value) {
return Native.indexOf(peer + offset, value);
}
-
+
/**
* Indirect the native pointer, copying from memory pointed to by
* native pointer, into the specified array.
@@ -166,7 +161,7 @@ public void read(long offset, short[] buf, int index, int length) {
public void read(long offset, char[] buf, int index, int length) {
Native.read(peer + offset, buf, index, length);
}
-
+
/**
* Indirect the native pointer, copying from memory pointed to by
* native pointer, into the specified array.
@@ -301,7 +296,7 @@ public void write(long offset, int[] buf, int index, int length) {
}
/**
- * Indirect the native pointer, copying into memory pointed to by
+ * Indirect the native pointer, copying into memory pointed to by
* native pointer, from the specified array.
*
* @param offset byte offset from pointer into which data is copied
@@ -359,71 +354,58 @@ public void write(long bOff, Pointer[] buf, int index, int length) {
// Java type read methods
//////////////////////////////////////////////////////////////////////////
- Object getValue(long offset, Class type, Object currentValue) {
+ Object getValue(long offset, Class> type, Object currentValue) {
Object result = null;
if (Structure.class.isAssignableFrom(type)) {
Structure s = (Structure)currentValue;
if (Structure.ByReference.class.isAssignableFrom(type)) {
s = Structure.updateStructureByReference(type, s, getPointer(offset));
- }
- else {
+ } else {
s.useMemory(this, (int)offset, true);
s.read();
}
result = s;
- }
- else if (type == boolean.class || type == Boolean.class) {
+ } else if (type == boolean.class || type == Boolean.class) {
result = Function.valueOf(getInt(offset) != 0);
- }
- else if (type == byte.class || type == Byte.class) {
- result = new Byte(getByte(offset));
- }
- else if (type == short.class || type == Short.class) {
- result = new Short(getShort(offset));
- }
- else if (type == char.class || type == Character.class) {
- result = new Character(getChar(offset));
- }
- else if (type == int.class || type == Integer.class) {
- result = new Integer(getInt(offset));
- }
- else if (type == long.class || type == Long.class) {
- result = new Long(getLong(offset));
- }
- else if (type == float.class || type == Float.class) {
- result=new Float(getFloat(offset));
- }
- else if (type == double.class || type == Double.class) {
- result = new Double(getDouble(offset));
- }
- else if (Pointer.class.isAssignableFrom(type)) {
+ } else if (type == byte.class || type == Byte.class) {
+ result = Byte.valueOf(getByte(offset));
+ } else if (type == short.class || type == Short.class) {
+ result = Short.valueOf(getShort(offset));
+ } else if (type == char.class || type == Character.class) {
+ result = Character.valueOf(getChar(offset));
+ } else if (type == int.class || type == Integer.class) {
+ result = Integer.valueOf(getInt(offset));
+ } else if (type == long.class || type == Long.class) {
+ result = Long.valueOf(getLong(offset));
+ } else if (type == float.class || type == Float.class) {
+ result = Float.valueOf(getFloat(offset));
+ } else if (type == double.class || type == Double.class) {
+ result = Double.valueOf(getDouble(offset));
+ } else if (Pointer.class.isAssignableFrom(type)) {
Pointer p = getPointer(offset);
if (p != null) {
Pointer oldp = currentValue instanceof Pointer
? (Pointer)currentValue : null;
- if (oldp == null || p.peer != oldp.peer)
+ if (oldp == null || p.peer != oldp.peer) {
result = p;
- else
+ } else {
result = oldp;
+ }
}
- }
- else if (type == String.class) {
+ } else if (type == String.class) {
Pointer p = getPointer(offset);
result = p != null ? p.getString(0) : null;
- }
- else if (type == WString.class) {
+ } else if (type == WString.class) {
Pointer p = getPointer(offset);
result = p != null ? new WString(p.getWideString(0)) : null;
- }
- else if (Callback.class.isAssignableFrom(type)) {
+ } else if (Callback.class.isAssignableFrom(type)) {
// Overwrite the Java memory if the native pointer is a different
// function pointer.
Pointer fp = getPointer(offset);
if (fp == null) {
result = null;
- }
- else {
+ } else {
Callback cb = (Callback)currentValue;
Pointer oldfp = CallbackReference.getFunctionPointer(cb);
if (!fp.equals(oldfp)) {
@@ -431,13 +413,11 @@ else if (Callback.class.isAssignableFrom(type)) {
}
result = cb;
}
- }
- else if (Platform.HAS_BUFFERS && Buffer.class.isAssignableFrom(type)) {
+ } else if (Platform.HAS_BUFFERS && Buffer.class.isAssignableFrom(type)) {
Pointer bp = getPointer(offset);
if (bp == null) {
result = null;
- }
- else {
+ } else {
Pointer oldbp = currentValue == null ? null
: Native.getDirectBufferPointer((Buffer)currentValue);
if (oldbp == null || !oldbp.equals(bp)) {
@@ -445,8 +425,7 @@ else if (Platform.HAS_BUFFERS && Buffer.class.isAssignableFrom(type)) {
}
result = currentValue;
}
- }
- else if (NativeMapped.class.isAssignableFrom(type)) {
+ } else if (NativeMapped.class.isAssignableFrom(type)) {
NativeMapped nm = (NativeMapped)currentValue;
if (nm != null) {
Object value = getValue(offset, nm.nativeType(), null);
@@ -454,33 +433,29 @@ else if (NativeMapped.class.isAssignableFrom(type)) {
if (nm.equals(result)) {
result = nm;
}
- }
- else {
+ } else {
NativeMappedConverter tc = NativeMappedConverter.getInstance(type);
Object value = getValue(offset, tc.nativeType(), null);
result = tc.fromNative(value, new FromNativeContext(type));
}
- }
- else if (type.isArray()) {
+ } else if (type.isArray()) {
result = currentValue;
if (result == null) {
throw new IllegalStateException("Need an initialized array");
}
readArray(offset, result, type.getComponentType());
- }
- else {
- throw new IllegalArgumentException("Reading \""
- + type + "\" from memory is not supported");
+ } else {
+ throw new IllegalArgumentException("Reading \"" + type + "\" from memory is not supported");
}
return result;
}
/** Read memory starting at offset into the array with element type cls. */
- private void readArray(long offset, Object o, Class cls) {
+ private void readArray(long offset, Object o, Class> cls) {
int length = 0;
length = Array.getLength(o);
Object result = o;
-
+
if (cls == byte.class) {
read(offset, (byte[])result, 0, length);
}
@@ -677,20 +652,21 @@ public ByteBuffer getByteBuffer(long offset, long length) {
/**
* Copy native memory to a Java String. If wide
is true,
- * access the memory as an array of wchar_t
, otherwise
+ * access the memory as an array of wchar_t
, otherwise
* as an array of char
, using the default platform encoding.
*
* @param offset byte offset from pointer to obtain the native string
v * @param wide whether to convert from a wide or standard C string
- * @return the String
value being pointed to
- *
+ * @return the String
value being pointed to
+ *
* @deprecated use {@link #getString(long,String)} or {@link
- * #getWideString(long)} instead.
+ * #getWideString(long)} instead.
*/
+ @Deprecated
public String getString(long offset, boolean wide) {
return wide ? getWideString(offset) : getString(offset);
}
-
+
/** Read a wide (const wchar_t *
) string from memory. */
public String getWideString(long offset) {
return Native.getWideString(peer + offset);
@@ -701,7 +677,7 @@ public String getWideString(long offset) {
* form {@link Native#getDefaultStringEncoding()}.
*
* @param offset byte offset from pointer to start reading bytes
- * @return the String
value being pointed to
+ * @return the String
value being pointed to
*/
public String getString(long offset) {
return getString(offset, Native.getDefaultStringEncoding());
@@ -712,7 +688,7 @@ public String getString(long offset) {
*
* @param offset byte offset from pointer to obtain the native string
* @param encoding the desired encoding
- * @return the String
value being pointed to
+ * @return the String
value being pointed to
*/
public String getString(long offset, String encoding) {
return Native.getString(peer + offset, encoding);
@@ -726,7 +702,7 @@ public byte[] getByteArray(long offset, int arraySize) {
read(offset, buf, 0, arraySize);
return buf;
}
-
+
/** Read a native array of wchar_t of size arraySize
from the
given offset
from this {@link Pointer}.
*/
@@ -785,7 +761,7 @@ public double[] getDoubleArray(long offset, int arraySize) {
* determined by a NULL-valued terminating element.
*/
public Pointer[] getPointerArray(long offset) {
- List array = new ArrayList();
+ List array = new ArrayList();
int addOffset = 0;
Pointer p = getPointer(offset);
while (p != null) {
@@ -793,7 +769,7 @@ public Pointer[] getPointerArray(long offset) {
addOffset += Pointer.SIZE;
p = getPointer(offset + addOffset);
}
- return (Pointer[])array.toArray(new Pointer[array.size()]);
+ return array.toArray(new Pointer[array.size()]);
}
/** Returns an array of {@link Pointer} of the requested size. */
@@ -805,7 +781,7 @@ public Pointer[] getPointerArray(long offset, int arraySize) {
/** Returns an array of String
based on a native array
* of char *
. The array length is determined by a
- * NULL-valued terminating element.
+ * NULL-valued terminating element.
*
* The strings are decoded using the encoding returned by {@link
* Native#getDefaultStringEncoding()}.
@@ -816,14 +792,14 @@ public String[] getStringArray(long offset) {
/** Returns an array of String
based on a native array
* of char *
, using the requested encoding. The array length
- * is determined by a NULL-valued terminating element.
+ * is determined by a NULL-valued terminating element.
*/
public String[] getStringArray(long offset, String encoding) {
return getStringArray(offset, -1, encoding);
}
/** Returns an array of String
based on a native array
- * of char *
, using the given array length.
+ * of char *
, using the given array length.
*
* The strings are decoded using the encoding returned by {@link
* Native#getDefaultStringEncoding()}.
@@ -835,11 +811,12 @@ public String[] getStringArray(long offset, int length) {
/** Returns an array of String
based on a native array
* of char*
or wchar_t*
based on the
* wide
parameter. The array length is determined by a
- * NULL-valued terminating element.
- *
+ * NULL-valued terminating element.
+ *
* @deprecated use {@link #getStringArray(long,String)} or {@link
* #getWideStringArray(long)} instead.
*/
+ @Deprecated
public String[] getStringArray(long offset, boolean wide) {
return getStringArray(offset, -1, wide);
}
@@ -855,10 +832,11 @@ public String[] getWideStringArray(long offset, int length) {
/** Returns an array of String
based on a native array
* of char*
or wchar_t*
based on the
* wide
parameter, using the given array length.
- *
+ *
* @deprecated use {@link #getStringArray(long,int,String)} or {@link
* #getWideStringArray(long,int)} instead.
*/
+ @Deprecated
public String[] getStringArray(long offset, int length, boolean wide) {
return getStringArray(offset, length, wide ? NativeString.WIDE_STRING : Native.getDefaultStringEncoding());
}
@@ -871,7 +849,7 @@ public String[] getStringArray(long offset, int length, boolean wide) {
* @param encoding
*/
public String[] getStringArray(long offset, int length, String encoding) {
- List strings = new ArrayList();
+ List strings = new ArrayList();
Pointer p;
int addOffset = 0;
if (length != -1) {
@@ -880,7 +858,7 @@ public String[] getStringArray(long offset, int length, String encoding) {
while (count++ < length) {
String s = p == null
? null
- : (encoding == NativeString.WIDE_STRING
+ : (NativeString.WIDE_STRING.equals(encoding)
? p.getWideString(0) : p.getString(0, encoding));
strings.add(s);
if (count < length) {
@@ -888,61 +866,49 @@ public String[] getStringArray(long offset, int length, String encoding) {
p = getPointer(offset + addOffset);
}
}
- }
- else {
+ } else {
while ((p = getPointer(offset + addOffset)) != null) {
String s = p == null
? null
- : (encoding == NativeString.WIDE_STRING
+ : (NativeString.WIDE_STRING.equals(encoding)
? p.getWideString(0) : p.getString(0, encoding));
strings.add(s);
addOffset += SIZE;
}
}
- return (String[])strings.toArray(new String[strings.size()]);
+ return strings.toArray(new String[strings.size()]);
}
//////////////////////////////////////////////////////////////////////////
// Java type write methods
//////////////////////////////////////////////////////////////////////////
- void setValue(long offset, Object value, Class type) {
+ void setValue(long offset, Object value, Class> type) {
// Set the value at the offset according to its type
if (type == boolean.class || type == Boolean.class) {
setInt(offset, Boolean.TRUE.equals(value) ? -1 : 0);
- }
- else if (type == byte.class || type == Byte.class) {
+ } else if (type == byte.class || type == Byte.class) {
setByte(offset, value == null ? 0 : ((Byte)value).byteValue());
- }
- else if (type == short.class || type == Short.class) {
+ } else if (type == short.class || type == Short.class) {
setShort(offset, value == null ? 0 : ((Short)value).shortValue());
- }
- else if (type == char.class || type == Character.class) {
+ } else if (type == char.class || type == Character.class) {
setChar(offset, value == null ? 0 : ((Character)value).charValue());
- }
- else if (type == int.class || type == Integer.class) {
+ } else if (type == int.class || type == Integer.class) {
setInt(offset, value == null ? 0 : ((Integer)value).intValue());
- }
- else if (type == long.class || type == Long.class) {
+ } else if (type == long.class || type == Long.class) {
setLong(offset, value == null ? 0 : ((Long)value).longValue());
- }
- else if (type == float.class || type == Float.class) {
+ } else if (type == float.class || type == Float.class) {
setFloat(offset, value == null ? 0f : ((Float)value).floatValue());
- }
- else if (type == double.class || type == Double.class) {
+ } else if (type == double.class || type == Double.class) {
setDouble(offset, value == null ? 0.0 : ((Double)value).doubleValue());
- }
- else if (type == Pointer.class) {
+ } else if (type == Pointer.class) {
setPointer(offset, (Pointer)value);
- }
- else if (type == String.class) {
+ } else if (type == String.class) {
setPointer(offset, (Pointer)value);
- }
- else if (type == WString.class) {
+ } else if (type == WString.class) {
setPointer(offset, (Pointer)value);
- }
- else if (Structure.class.isAssignableFrom(type)) {
+ } else if (Structure.class.isAssignableFrom(type)) {
Structure s = (Structure)value;
if (Structure.ByReference.class.isAssignableFrom(type)) {
setPointer(offset, s == null ? null : s.getPointer());
@@ -954,84 +920,68 @@ else if (Structure.class.isAssignableFrom(type)) {
s.useMemory(this, (int)offset, true);
s.write();
}
- }
- else if (Callback.class.isAssignableFrom(type)) {
+ } else if (Callback.class.isAssignableFrom(type)) {
setPointer(offset, CallbackReference.getFunctionPointer((Callback)value));
- }
- else if (Platform.HAS_BUFFERS && Buffer.class.isAssignableFrom(type)) {
+ } else if (Platform.HAS_BUFFERS && Buffer.class.isAssignableFrom(type)) {
Pointer p = value == null ? null
: Native.getDirectBufferPointer((Buffer)value);
setPointer(offset, p);
- }
- else if (NativeMapped.class.isAssignableFrom(type)) {
+ } else if (NativeMapped.class.isAssignableFrom(type)) {
NativeMappedConverter tc = NativeMappedConverter.getInstance(type);
- Class nativeType = tc.nativeType();
+ Class> nativeType = tc.nativeType();
setValue(offset, tc.toNative(value, new ToNativeContext()), nativeType);
- }
- else if (type.isArray()) {
+ } else if (type.isArray()) {
writeArray(offset, value, type.getComponentType());
- }
- else {
+ } else {
throw new IllegalArgumentException("Writing " + type + " to memory is not supported");
}
}
/** Write memory starting at offset from the array with element type cls. */
- private void writeArray(long offset, Object value, Class cls) {
+ private void writeArray(long offset, Object value, Class> cls) {
if (cls == byte.class) {
byte[] buf = (byte[])value;
write(offset, buf, 0, buf.length);
- }
- else if (cls == short.class) {
+ } else if (cls == short.class) {
short[] buf = (short[])value;
write(offset, buf, 0, buf.length);
- }
- else if (cls == char.class) {
+ } else if (cls == char.class) {
char[] buf = (char[])value;
write(offset, buf, 0, buf.length);
- }
- else if (cls == int.class) {
+ } else if (cls == int.class) {
int[] buf = (int[])value;
write(offset, buf, 0, buf.length);
- }
- else if (cls == long.class) {
+ } else if (cls == long.class) {
long[] buf = (long[])value;
write(offset, buf, 0, buf.length);
- }
- else if (cls == float.class) {
+ } else if (cls == float.class) {
float[] buf = (float[])value;
write(offset, buf, 0, buf.length);
- }
- else if (cls == double.class) {
+ } else if (cls == double.class) {
double[] buf = (double[])value;
write(offset, buf, 0, buf.length);
- }
- else if (Pointer.class.isAssignableFrom(cls)) {
+ } else if (Pointer.class.isAssignableFrom(cls)) {
Pointer[] buf = (Pointer[])value;
write(offset, buf, 0, buf.length);
- }
- else if (Structure.class.isAssignableFrom(cls)) {
+ } else if (Structure.class.isAssignableFrom(cls)) {
Structure[] sbuf = (Structure[])value;
if (Structure.ByReference.class.isAssignableFrom(cls)) {
Pointer[] buf = new Pointer[sbuf.length];
for (int i=0;i < sbuf.length;i++) {
if (sbuf[i] == null) {
buf[i] = null;
- }
- else {
+ } else {
buf[i] = sbuf[i].getPointer();
sbuf[i].write();
}
}
write(offset, buf, 0, buf.length);
- }
- else {
+ } else {
Structure first = sbuf[0];
if (first == null) {
first = Structure.newInstance(cls, share(offset));
sbuf[0] = first;
- }
- else {
+ } else {
first.useMemory(this, (int)offset, true);
}
first.write();
@@ -1039,31 +989,28 @@ else if (Structure.class.isAssignableFrom(cls)) {
for (int i=1;i < sbuf.length;i++) {
if (sbuf[i] == null) {
sbuf[i] = tmp[i];
- }
- else {
+ } else {
sbuf[i].useMemory(this, (int)(offset + i * sbuf[i].size()), true);
}
sbuf[i].write();
}
}
- }
- else if (NativeMapped.class.isAssignableFrom(cls)) {
+ } else if (NativeMapped.class.isAssignableFrom(cls)) {
NativeMapped[] buf = (NativeMapped[])value;
NativeMappedConverter tc = NativeMappedConverter.getInstance(cls);
- Class nativeType = tc.nativeType();
+ Class> nativeType = tc.nativeType();
int size = Native.getNativeSize(value.getClass(), value) / buf.length;
for (int i=0;i < buf.length;i++) {
Object element = tc.toNative(buf[i], new ToNativeContext());
setValue(offset + i*size, element, nativeType);
}
- }
- else {
+ } else {
throw new IllegalArgumentException("Writing array of "
+ cls + " to memory not supported");
}
}
- /** Write value
to the requested bank of memory.
+ /** Write value
to the requested bank of memory.
* @param offset byte offset from pointer to start
* @param length number of bytes to write
* @param value value to be written
@@ -1071,7 +1018,7 @@ else if (NativeMapped.class.isAssignableFrom(cls)) {
public void setMemory(long offset, long length, byte value) {
Native.setMemory(peer + offset, length, value);
}
-
+
/**
* Set value
at location being pointed to. This is equivalent
* to the expression
@@ -1097,7 +1044,7 @@ public void setByte(long offset, byte value) {
public void setShort(long offset, short value) {
Native.setShort(peer + offset, value);
}
-
+
/**
* Set value
at location being pointed to. This is equivalent
* to the expression
@@ -1110,7 +1057,7 @@ public void setShort(long offset, short value) {
public void setChar(long offset, char value) {
Native.setChar(peer + offset, value);
}
-
+
/**
* Set value
at location being pointed to. This is equivalent
* to the expression
@@ -1136,7 +1083,7 @@ public void setInt(long offset, int value) {
public void setLong(long offset, long value) {
Native.setLong(peer + offset, value);
}
-
+
/**
* Set value
at location being pointed to. This is equivalent
* to the expression
@@ -1166,7 +1113,7 @@ public void setNativeLong(long offset, NativeLong value) {
public void setFloat(long offset, float value) {
Native.setFloat(peer + offset, value);
}
-
+
/**
* Set value
at location being pointed to. This is equivalent
* to the expression
@@ -1182,12 +1129,12 @@ public void setDouble(long offset, double value) {
/**
* Set value
at location being pointed to. This is equivalent
- * to the expression
+ * to the expression
* *((void **)((char *)Pointer + offset)) = value
.
*
- * @param offset byte offset from pointer at which value
+ * @param offset byte offset from pointer at which value
* must be set
- * @param value Pointer
holding the actual pointer value to
+ * @param value Pointer
holding the actual pointer value to
* set, which may be null
to indicate a NULL
* pointer.
*/
@@ -1196,18 +1143,19 @@ public void setPointer(long offset, Pointer value) {
}
/**
- * Copy string value
to the location being pointed to.
+ * Copy string value
to the location being pointed to.
*
* @param offset byte offset from pointer at which characters in
* value
must be set
* @param value java.lang.String
value to set
- * @param wide whether to write the native string as an array of
- * wchar_t
. If false, writes as a NUL-terminated array of
+ * @param wide whether to write the native string as an array of
+ * wchar_t
. If false, writes as a NUL-terminated array of
* char
using the encoding indicated by {@link
- * Native#getDefaultStringEncoding()}.
- *
+ * Native#getDefaultStringEncoding()}.
+ *
* @deprecated use {@link #setWideString(long,String)} instead.
*/
+ @Deprecated
public void setString(long offset, String value, boolean wide) {
if (wide) {
setWideString(offset, value);
@@ -1216,10 +1164,10 @@ public void setString(long offset, String value, boolean wide) {
setString(offset, value);
}
}
-
+
/**
* Copy string value
to the location being pointed to as a
- * wide string (wchar_t*
).
+ * wide string (wchar_t*
).
*
* @param offset byte offset from pointer at which characters in
* value
must be set
@@ -1231,7 +1179,7 @@ public void setWideString(long offset, String value) {
/**
* Copy string value
to the location being pointed to as a
- * wide string (wchar_t*
).
+ * wide string (wchar_t*
).
*
* @param offset byte offset from pointer at which characters in
* value
must be set
@@ -1244,7 +1192,7 @@ public void setString(long offset, WString value) {
/**
* Copy bytes out of string value
to the location being
* pointed to, using the encoding indicated by {@link
- * Native#getDefaultStringEncoding()}.
+ * Native#getDefaultStringEncoding()}.
*
* @param offset byte offset from pointer at which characters in
* value
must be set
@@ -1256,7 +1204,7 @@ public void setString(long offset, String value) {
/**
* Copy string value
to the location being pointed to, using
- * the requested encoding.
+ * the requested encoding.
*
* @param offset byte offset from pointer at which characters in
* value
must be set
@@ -1268,7 +1216,7 @@ public void setString(long offset, String value, String encoding) {
write(offset, data, 0, data.length);
setByte(offset + data.length, (byte)0);
}
-
+
/** Dump memory for debugging purposes. */
public String dump(long offset, int size) {
String LS = System.getProperty("line.separator");
@@ -1289,10 +1237,11 @@ public String dump(long offset, int size) {
return contents;
}
+ @Override
public String toString() {
return "native@0x" + Long.toHexString(peer);
}
-
+
/** Read the native peer value. Use with caution. */
public static long nativeValue(Pointer p) {
return p == null ? 0 : p.peer;
@@ -1307,129 +1256,171 @@ public static void nativeValue(Pointer p, long value) {
private static class Opaque extends Pointer {
private Opaque(long peer) { super(peer); }
private final String MSG = "This pointer is opaque: " + this;
+ @Override
public Pointer share(long offset, long size) {
throw new UnsupportedOperationException(MSG);
}
+ @Override
public void clear(long size) {
throw new UnsupportedOperationException(MSG);
}
+ @Override
public long indexOf(long offset, byte value) {
throw new UnsupportedOperationException(MSG);
}
- public void read(long bOff, byte[] buf, int index, int length) {
- throw new UnsupportedOperationException(MSG);
+ @Override
+ public void read(long bOff, byte[] buf, int index, int length) {
+ throw new UnsupportedOperationException(MSG);
}
- public void read(long bOff, char[] buf, int index, int length) {
- throw new UnsupportedOperationException(MSG);
+ @Override
+ public void read(long bOff, char[] buf, int index, int length) {
+ throw new UnsupportedOperationException(MSG);
}
- public void read(long bOff, short[] buf, int index, int length) {
- throw new UnsupportedOperationException(MSG);
+ @Override
+ public void read(long bOff, short[] buf, int index, int length) {
+ throw new UnsupportedOperationException(MSG);
}
- public void read(long bOff, int[] buf, int index, int length) {
- throw new UnsupportedOperationException(MSG);
+ @Override
+ public void read(long bOff, int[] buf, int index, int length) {
+ throw new UnsupportedOperationException(MSG);
}
- public void read(long bOff, long[] buf, int index, int length) {
- throw new UnsupportedOperationException(MSG);
+ @Override
+ public void read(long bOff, long[] buf, int index, int length) {
+ throw new UnsupportedOperationException(MSG);
}
- public void read(long bOff, float[] buf, int index, int length) {
- throw new UnsupportedOperationException(MSG);
+ @Override
+ public void read(long bOff, float[] buf, int index, int length) {
+ throw new UnsupportedOperationException(MSG);
}
- public void read(long bOff, double[] buf, int index, int length) {
- throw new UnsupportedOperationException(MSG);
+ @Override
+ public void read(long bOff, double[] buf, int index, int length) {
+ throw new UnsupportedOperationException(MSG);
}
- public void read(long bOff, Pointer[] buf, int index, int length) {
- throw new UnsupportedOperationException(MSG);
+ @Override
+ public void read(long bOff, Pointer[] buf, int index, int length) {
+ throw new UnsupportedOperationException(MSG);
}
- public void write(long bOff, byte[] buf, int index, int length) {
- throw new UnsupportedOperationException(MSG);
+ @Override
+ public void write(long bOff, byte[] buf, int index, int length) {
+ throw new UnsupportedOperationException(MSG);
}
- public void write(long bOff, char[] buf, int index, int length) {
- throw new UnsupportedOperationException(MSG);
+ @Override
+ public void write(long bOff, char[] buf, int index, int length) {
+ throw new UnsupportedOperationException(MSG);
}
- public void write(long bOff, short[] buf, int index, int length) {
- throw new UnsupportedOperationException(MSG);
+ @Override
+ public void write(long bOff, short[] buf, int index, int length) {
+ throw new UnsupportedOperationException(MSG);
}
- public void write(long bOff, int[] buf, int index, int length) {
- throw new UnsupportedOperationException(MSG);
+ @Override
+ public void write(long bOff, int[] buf, int index, int length) {
+ throw new UnsupportedOperationException(MSG);
}
- public void write(long bOff, long[] buf, int index, int length) {
- throw new UnsupportedOperationException(MSG);
+ @Override
+ public void write(long bOff, long[] buf, int index, int length) {
+ throw new UnsupportedOperationException(MSG);
}
- public void write(long bOff, float[] buf, int index, int length) {
- throw new UnsupportedOperationException(MSG);
+ @Override
+ public void write(long bOff, float[] buf, int index, int length) {
+ throw new UnsupportedOperationException(MSG);
}
- public void write(long bOff, double[] buf, int index, int length) {
- throw new UnsupportedOperationException(MSG);
+ @Override
+ public void write(long bOff, double[] buf, int index, int length) {
+ throw new UnsupportedOperationException(MSG);
}
- public void write(long bOff, Pointer[] buf, int index, int length) {
- throw new UnsupportedOperationException(MSG);
+ @Override
+ public void write(long bOff, Pointer[] buf, int index, int length) {
+ throw new UnsupportedOperationException(MSG);
}
+ @Override
public ByteBuffer getByteBuffer(long offset, long length) {
- throw new UnsupportedOperationException(MSG);
+ throw new UnsupportedOperationException(MSG);
}
+ @Override
public byte getByte(long bOff) {
- throw new UnsupportedOperationException(MSG);
+ throw new UnsupportedOperationException(MSG);
}
+ @Override
public char getChar(long bOff) {
- throw new UnsupportedOperationException(MSG);
+ throw new UnsupportedOperationException(MSG);
}
+ @Override
public short getShort(long bOff) {
- throw new UnsupportedOperationException(MSG);
+ throw new UnsupportedOperationException(MSG);
}
+ @Override
public int getInt(long bOff) {
- throw new UnsupportedOperationException(MSG);
+ throw new UnsupportedOperationException(MSG);
}
+ @Override
public long getLong(long bOff) {
- throw new UnsupportedOperationException(MSG);
+ throw new UnsupportedOperationException(MSG);
}
+ @Override
public float getFloat(long bOff) {
- throw new UnsupportedOperationException(MSG);
+ throw new UnsupportedOperationException(MSG);
}
+ @Override
public double getDouble(long bOff) {
- throw new UnsupportedOperationException(MSG);
+ throw new UnsupportedOperationException(MSG);
}
+ @Override
public Pointer getPointer(long bOff) {
- throw new UnsupportedOperationException(MSG);
+ throw new UnsupportedOperationException(MSG);
}
+ @Override
public String getString(long bOff, String encoding) {
- throw new UnsupportedOperationException(MSG);
+ throw new UnsupportedOperationException(MSG);
}
+ @Override
public String getWideString(long bOff) {
- throw new UnsupportedOperationException(MSG);
+ throw new UnsupportedOperationException(MSG);
}
+ @Override
public void setByte(long bOff, byte value) {
- throw new UnsupportedOperationException(MSG);
+ throw new UnsupportedOperationException(MSG);
}
+ @Override
public void setChar(long bOff, char value) {
- throw new UnsupportedOperationException(MSG);
+ throw new UnsupportedOperationException(MSG);
}
+ @Override
public void setShort(long bOff, short value) {
- throw new UnsupportedOperationException(MSG);
+ throw new UnsupportedOperationException(MSG);
}
+ @Override
public void setInt(long bOff, int value) {
- throw new UnsupportedOperationException(MSG);
+ throw new UnsupportedOperationException(MSG);
}
+ @Override
public void setLong(long bOff, long value) {
- throw new UnsupportedOperationException(MSG);
+ throw new UnsupportedOperationException(MSG);
}
+ @Override
public void setFloat(long bOff, float value) {
- throw new UnsupportedOperationException(MSG);
+ throw new UnsupportedOperationException(MSG);
}
+ @Override
public void setDouble(long bOff, double value) {
- throw new UnsupportedOperationException(MSG);
+ throw new UnsupportedOperationException(MSG);
}
+ @Override
public void setPointer(long offset, Pointer value) {
- throw new UnsupportedOperationException(MSG);
+ throw new UnsupportedOperationException(MSG);
}
+ @Override
public void setString(long offset, String value, String encoding) {
- throw new UnsupportedOperationException(MSG);
+ throw new UnsupportedOperationException(MSG);
}
+ @Override
public void setWideString(long offset, String value) {
- throw new UnsupportedOperationException(MSG);
+ throw new UnsupportedOperationException(MSG);
}
+ @Override
public void setMemory(long offset, long size, byte value) {
- throw new UnsupportedOperationException(MSG);
+ throw new UnsupportedOperationException(MSG);
}
+ @Override
public String toString() {
return "const@0x" + Long.toHexString(peer);
}
diff --git a/src/com/sun/jna/PointerType.java b/src/com/sun/jna/PointerType.java
index 0448be7417..7fc56b433e 100644
--- a/src/com/sun/jna/PointerType.java
+++ b/src/com/sun/jna/PointerType.java
@@ -1,44 +1,45 @@
/* Copyright (c) 2007 Timothy Wall, All Rights Reserved
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
- *
+ *
* This library 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 for more details.
+ * Lesser General Public License for more details.
*/
package com.sun.jna;
/** Type representing a type-safe native pointer.
* Derived classes may override the {@link NativeMapped#fromNative} method,
* which should instantiate a new object (or look up an existing one)
- * of the appropriate type.
+ * of the appropriate type.
*/
public abstract class PointerType implements NativeMapped {
private Pointer pointer;
-
+
/** The default constructor wraps a NULL pointer. */
protected PointerType() {
this.pointer = Pointer.NULL;
}
-
+
/** This constructor is typically used by {@link #fromNative} if generating
- * a new object instance.
+ * a new object instance.
*/
protected PointerType(Pointer p) {
this.pointer = p;
}
- /** All PointerType
classes represent a native {@link Pointer}.
- */
- public Class nativeType() {
+ /* All PointerType
classes represent a native {@link Pointer}. */
+ @Override
+ public Class> nativeType() {
return Pointer.class;
}
/** Convert this object to its native type (a {@link Pointer}). */
+ @Override
public Object toNative() {
return getPointer();
}
@@ -49,24 +50,25 @@ public Object toNative() {
public Pointer getPointer() {
return pointer;
}
-
+
public void setPointer(Pointer p) {
this.pointer = p;
}
-
+
/** The default implementation simply creates a new instance of the class
* and assigns its pointer field. Override if you need different behavior,
* such as ensuring a single {@link PointerType} instance for each unique
* {@link Pointer} value, or instantiating a different {@link PointerType}
* subclass.
*/
+ @Override
public Object fromNative(Object nativeValue, FromNativeContext context) {
// Always pass along null pointer values
if (nativeValue == null) {
return null;
}
try {
- PointerType pt = (PointerType)getClass().newInstance();
+ PointerType pt = getClass().newInstance();
pt.pointer = (Pointer)nativeValue;
return pt;
}
@@ -81,24 +83,30 @@ public Object fromNative(Object nativeValue, FromNativeContext context) {
/** The hash code for a PointerType
is the same as that for
* its pointer.
*/
+ @Override
public int hashCode() {
return pointer != null ? pointer.hashCode() : 0;
}
-
+
/** Instances of PointerType
with identical pointers compare
* equal by default.
*/
+ @Override
public boolean equals(Object o) {
- if (o == this) return true;
+ if (o == this) {
+ return true;
+ }
if (o instanceof PointerType) {
Pointer p = ((PointerType)o).getPointer();
- if (pointer == null)
+ if (pointer == null) {
return p == null;
+ }
return pointer.equals(p);
}
return false;
}
+ @Override
public String toString() {
return pointer == null ? "NULL" : pointer.toString() + " (" + super.toString() + ")";
}
diff --git a/src/com/sun/jna/StringArray.java b/src/com/sun/jna/StringArray.java
index f51a327506..d66773dac4 100644
--- a/src/com/sun/jna/StringArray.java
+++ b/src/com/sun/jna/StringArray.java
@@ -1,5 +1,5 @@
/* Copyright (c) 2007-2008 Timothy Wall, All Rights Reserved
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
@@ -8,7 +8,7 @@
* This library 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 for more details.
+ * Lesser General Public License for more details.
*/
package com.sun.jna;
@@ -16,14 +16,14 @@
import java.util.Arrays;
import java.util.List;
-/** Handle native array of char*
or wchar_t*
type
- * by managing allocation/disposal of native strings within an array of
+/** Handle native array of char*
or wchar_t*
type
+ * by managing allocation/disposal of native strings within an array of
* pointers. An extra NULL pointer is always added to the end of the native
- * pointer array for convenience.
+ * pointer array for convenience.
*/
public class StringArray extends Memory implements Function.PostCallRead {
private String encoding;
- private List natives = new ArrayList();
+ private List natives = new ArrayList();
private Object[] original;
/** Create a native array of strings. */
public StringArray(String[] strings) {
@@ -41,7 +41,7 @@ public StringArray(String[] strings, String encoding) {
public StringArray(WString[] strings) {
this(strings, NativeString.WIDE_STRING);
}
- private StringArray(Object[] strings, String encoding) {
+ private StringArray(Object[] strings, String encoding) {
super((strings.length + 1) * Pointer.SIZE);
this.original = strings;
this.encoding = encoding;
@@ -57,9 +57,10 @@ private StringArray(Object[] strings, String encoding) {
setPointer(Pointer.SIZE * strings.length, null);
}
/** Read back from native memory. */
+ @Override
public void read() {
boolean returnWide = original instanceof WString[];
- boolean wide = encoding == NativeString.WIDE_STRING;
+ boolean wide = NativeString.WIDE_STRING.equals(encoding);
for (int si=0;si < original.length;si++) {
Pointer p = getPointer(si * Pointer.SIZE);
Object s = null;
@@ -71,8 +72,9 @@ public void read() {
}
}
+ @Override
public String toString() {
- boolean wide = encoding == NativeString.WIDE_STRING;
+ boolean wide = NativeString.WIDE_STRING.equals(encoding);
String s = wide ? "const wchar_t*[]" : "const char*[]";
s += Arrays.asList(original);
return s;
diff --git a/src/com/sun/jna/ToNativeConverter.java b/src/com/sun/jna/ToNativeConverter.java
index 473883bb91..1aec645fa8 100644
--- a/src/com/sun/jna/ToNativeConverter.java
+++ b/src/com/sun/jna/ToNativeConverter.java
@@ -38,5 +38,5 @@ public interface ToNativeConverter {
*/
Object toNative(Object value, ToNativeContext context);
/** Indicate the type expected from {@link #toNative}. */
- Class nativeType();
+ Class> nativeType();
}
diff --git a/src/com/sun/jna/TypeMapper.java b/src/com/sun/jna/TypeMapper.java
index b370a66e5a..0674c7f08b 100644
--- a/src/com/sun/jna/TypeMapper.java
+++ b/src/com/sun/jna/TypeMapper.java
@@ -1,28 +1,28 @@
/* Copyright (c) 2007 Timothy Wall, All Rights Reserved
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
- *
+ *
* This library 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 for more details.
+ * Lesser General Public License for more details.
*/
package com.sun.jna;
/** Provides converters for conversion to and from native types. */
public interface TypeMapper {
- /** Return the {@link FromNativeConverter} appropriate for the given Java class.
+ /** Return the {@link FromNativeConverter} appropriate for the given Java class.
* @param javaType Java class representation of the native type.
* @return Converter from the native-compatible type.
*/
- FromNativeConverter getFromNativeConverter(Class javaType);
+ FromNativeConverter getFromNativeConverter(Class> javaType);
- /** Return the {@link ToNativeConverter} appropriate for the given Java class.
+ /** Return the {@link ToNativeConverter} appropriate for the given Java class.
* @param javaType Java class representation of the native type.
* @return Converter to the native-compatible type.
*/
- ToNativeConverter getToNativeConverter(Class javaType);
+ ToNativeConverter getToNativeConverter(Class> javaType);
}
diff --git a/src/com/sun/jna/WString.java b/src/com/sun/jna/WString.java
index 829bf15846..5bacb828e8 100644
--- a/src/com/sun/jna/WString.java
+++ b/src/com/sun/jna/WString.java
@@ -8,40 +8,47 @@
* This library 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 for more details.
+ * Lesser General Public License for more details.
*/
package com.sun.jna;
-import java.nio.CharBuffer;
-
/** Simple wrapper class to identify a wide string argument or return type.
- * @author twall@users.sf.net
+ * @author twall@users.sf.net
*/
public final class WString implements CharSequence, Comparable {
private String string;
public WString(String s){
- if (s == null) throw new NullPointerException("String initializer must be non-null");
+ if (s == null) {
+ throw new NullPointerException("String initializer must be non-null");
+ }
this.string = s;
}
+ @Override
public String toString() {
return string;
}
+ @Override
public boolean equals(Object o) {
- return o instanceof WString && toString().equals(o.toString());
+ return (o instanceof WString) && toString().equals(o.toString());
}
+ @Override
public int hashCode() {
return toString().hashCode();
}
+ @Override
public int compareTo(Object o) {
return toString().compareTo(o.toString());
}
+ @Override
public int length() {
return toString().length();
}
+ @Override
public char charAt(int index) {
return toString().charAt(index);
}
+ @Override
public CharSequence subSequence(int start, int end) {
- return CharBuffer.wrap(toString()).subSequence(start, end);
+ return toString().subSequence(start, end);
}
}
diff --git a/src/com/sun/jna/WeakIdentityHashMap.java b/src/com/sun/jna/WeakIdentityHashMap.java
index d4f5905e46..c4d6533b1d 100644
--- a/src/com/sun/jna/WeakIdentityHashMap.java
+++ b/src/com/sun/jna/WeakIdentityHashMap.java
@@ -20,13 +20,13 @@
* Modified to remove Genercs for JNA.
*/
+import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
+import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
@@ -35,56 +35,63 @@
* Implements a combination of WeakHashMap and IdentityHashMap.
* Useful for caches that need to key off of a == comparison
* instead of a .equals.
- *
+ *
*
* This class is not a general-purpose Map implementation! While
* this class implements the Map interface, it intentionally violates
* Map's general contract, which mandates the use of the equals method
* when comparing objects. This class is designed for use only in the
* rare cases wherein reference-equality semantics are required.
- *
+ *
* Note that this implementation is not synchronized.
*
*/
-public class WeakIdentityHashMap implements Map {
- private final ReferenceQueue queue = new ReferenceQueue();
- private Map backingStore = new HashMap();
-
+public class WeakIdentityHashMap implements Map {
+ private final ReferenceQueue queue = new ReferenceQueue();
+ private Map, V> backingStore = new HashMap, V>();
public WeakIdentityHashMap() {
+ super();
}
+ @Override
public void clear() {
backingStore.clear();
reap();
}
+ @Override
public boolean containsKey(Object key) {
reap();
- return backingStore.containsKey(new IdentityWeakReference(key));
+ return backingStore.containsKey(new IdentityWeakReference(key, queue));
}
+ @Override
public boolean containsValue(Object value) {
reap();
return backingStore.containsValue(value);
}
- public Set entrySet() {
+ @Override
+ public Set> entrySet() {
reap();
- Set ret = new HashSet();
- for (Iterator i=backingStore.entrySet().iterator();i.hasNext();) {
- Map.Entry ref = (Map.Entry)i.next();
- final Object key = ((IdentityWeakReference)ref.getKey()).get();
- final Object value = ref.getValue();
- Map.Entry entry = new Map.Entry() {
- public Object getKey() {
+
+ Set> ret = new LinkedHashSet>();
+ for (Map.Entry extends Reference, ? extends V> ref : backingStore.entrySet()) {
+ final K key = ref.getKey().get();
+ final V value = ref.getValue();
+ Map.Entry entry = new Map.Entry() {
+ @Override
+ public K getKey() {
return key;
}
- public Object getValue() {
+ @Override
+ public V getValue() {
return value;
}
- public Object setValue(Object value) {
+ @Override
+ public V setValue(V value) {
throw new UnsupportedOperationException();
}
};
@@ -92,81 +99,103 @@ public Object setValue(Object value) {
}
return Collections.unmodifiableSet(ret);
}
- public Set keySet() {
+
+ @Override
+ public Set keySet() {
reap();
- Set ret = new HashSet();
- for (Iterator i=backingStore.keySet().iterator();i.hasNext();) {
- IdentityWeakReference ref = (IdentityWeakReference)i.next();
+
+ Set ret = new LinkedHashSet();
+ for (Reference extends K> ref : backingStore.keySet()) {
ret.add(ref.get());
}
return Collections.unmodifiableSet(ret);
}
+ @Override
public boolean equals(Object o) {
+ if (o == null) {
+ return false;
+ }
+ if (o == this) {
+ return true;
+ }
+
+ if (!(o instanceof WeakIdentityHashMap)) {
+ return false;
+ }
+
return backingStore.equals(((WeakIdentityHashMap)o).backingStore);
}
- public Object get(Object key) {
+ @Override
+ public V get(Object key) {
reap();
- return backingStore.get(new IdentityWeakReference(key));
+ return backingStore.get(new IdentityWeakReference(key, queue));
}
- public Object put(Object key, Object value) {
+
+ @Override
+ public V put(K key, V value) {
reap();
- return backingStore.put(new IdentityWeakReference(key), value);
+ return backingStore.put(new IdentityWeakReference(key, queue), value);
}
+ @Override
public int hashCode() {
reap();
return backingStore.hashCode();
}
+ @Override
public boolean isEmpty() {
reap();
return backingStore.isEmpty();
}
- public void putAll(Map t) {
+ @Override
+ public void putAll(Map extends K, ? extends V> m) {
throw new UnsupportedOperationException();
}
- public Object remove(Object key) {
+ @Override
+ public V remove(Object key) {
reap();
- return backingStore.remove(new IdentityWeakReference(key));
+ return backingStore.remove(new IdentityWeakReference(key, queue));
}
+ @Override
public int size() {
reap();
return backingStore.size();
}
- public Collection values() {
+ @Override
+ public Collection values() {
reap();
return backingStore.values();
}
private synchronized void reap() {
- Object zombie = queue.poll();
-
- while (zombie != null) {
- IdentityWeakReference victim = (IdentityWeakReference)zombie;
- backingStore.remove(victim);
- zombie = queue.poll();
+ for (Reference extends K> zombie = queue.poll(); zombie != null; zombie = queue.poll()) {
+ backingStore.remove(zombie);
}
}
- class IdentityWeakReference extends WeakReference {
- int hash;
-
+ static class IdentityWeakReference extends WeakReference {
+ private final int hash;
+
//@SuppressWarnings("unchecked")
- IdentityWeakReference(Object obj) {
- super(obj, queue);
+ IdentityWeakReference(T obj, ReferenceQueue super T> q) {
+ super(obj, q);
hash = System.identityHashCode(obj);
}
+ @Override
public int hashCode() {
return hash;
}
+ @Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
- IdentityWeakReference ref = (IdentityWeakReference)o;
+
+ IdentityWeakReference> ref = (IdentityWeakReference>)o;
if (this.get() == ref.get()) {
return true;
}
@@ -175,7 +204,6 @@ public boolean equals(Object o) {
}
}
-
-
-
-
\ No newline at end of file
+
+
+
diff --git a/src/com/sun/jna/win32/StdCallFunctionMapper.java b/src/com/sun/jna/win32/StdCallFunctionMapper.java
index 1a78c578fd..33badb55ab 100644
--- a/src/com/sun/jna/win32/StdCallFunctionMapper.java
+++ b/src/com/sun/jna/win32/StdCallFunctionMapper.java
@@ -1,19 +1,20 @@
/* Copyright (c) 2007 Timothy Wall, All Rights Reserved
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
- *
+ *
* This library 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 for more details.
+ * Lesser General Public License for more details.
*/
package com.sun.jna.win32;
import java.lang.reflect.Method;
+import com.sun.jna.Function;
import com.sun.jna.FunctionMapper;
import com.sun.jna.Native;
import com.sun.jna.NativeLibrary;
@@ -24,7 +25,7 @@
/** Provides mapping from simple method names to w32 stdcall-decorated names
* where the name suffix is "@" followed by the number of bytes popped by
* the called function.
- * NOTE: if you use custom type mapping for primitive types, you may need to
+ * NOTE: if you use custom type mapping for primitive types, you may need to
* override {@link #getArgumentNativeStackSize(Class)}.
*/
public class StdCallFunctionMapper implements FunctionMapper {
@@ -32,7 +33,7 @@ public class StdCallFunctionMapper implements FunctionMapper {
* @param cls Java class of a parameter
* @return number of native bytes used for this class on the stack
*/
- protected int getArgumentNativeStackSize(Class cls) {
+ protected int getArgumentNativeStackSize(Class> cls) {
if (NativeMapped.class.isAssignableFrom(cls)) {
cls = NativeMappedConverter.getInstance(cls).nativeType();
}
@@ -41,36 +42,42 @@ protected int getArgumentNativeStackSize(Class cls) {
}
try {
return Native.getNativeSize(cls);
- }
- catch(IllegalArgumentException e) {
+ } catch(IllegalArgumentException e) {
throw new IllegalArgumentException("Unknown native stack allocation size for " + cls);
}
}
- /** Convert the given Java method into a decorated stdcall name,
- * if possible.
+
+ /**
+ * Convert the given Java method into a decorated {@code stdcall} name, if possible.
+ *
+ * @param library The {@link NativeLibrary} instance
+ * @param method The invoked {@link Method}
+ * @return The decorated name
*/
+ @Override
public String getFunctionName(NativeLibrary library, Method method) {
String name = method.getName();
int pop = 0;
- Class[] argTypes = method.getParameterTypes();
- for (int i=0;i < argTypes.length;i++) {
- pop += getArgumentNativeStackSize(argTypes[i]);
+ Class>[] argTypes = method.getParameterTypes();
+ for (Class> cls : argTypes) {
+ pop += getArgumentNativeStackSize(cls);
}
+
String decorated = name + "@" + pop;
int conv = StdCallLibrary.STDCALL_CONVENTION;
try {
- name = library.getFunction(decorated, conv).getName();
-
- }
- catch(UnsatisfiedLinkError e) {
+ Function func = library.getFunction(decorated, conv);
+ name = func.getName();
+ } catch(UnsatisfiedLinkError e) {
// try with an explicit underscore
try {
- name = library.getFunction("_" + decorated, conv).getName();
- }
- catch(UnsatisfiedLinkError e2) {
+ Function func = library.getFunction("_" + decorated, conv);
+ name = func.getName();
+ } catch(UnsatisfiedLinkError e2) {
// not found; let caller try undecorated version
}
}
+
return name;
}
}
\ No newline at end of file
diff --git a/src/com/sun/jna/win32/W32APIOptions.java b/src/com/sun/jna/win32/W32APIOptions.java
index ac1ffbbf3f..ead6471b15 100644
--- a/src/com/sun/jna/win32/W32APIOptions.java
+++ b/src/com/sun/jna/win32/W32APIOptions.java
@@ -6,18 +6,24 @@
public interface W32APIOptions extends StdCallLibrary {
/** Standard options to use the unicode version of a w32 API. */
- Map UNICODE_OPTIONS = Collections.unmodifiableMap(new HashMap() {
+ Map UNICODE_OPTIONS = Collections.unmodifiableMap(new HashMap() {
+ private static final long serialVersionUID = 1L; // we're not serializing it
+
{
put(OPTION_TYPE_MAPPER, W32APITypeMapper.UNICODE);
put(OPTION_FUNCTION_MAPPER, W32APIFunctionMapper.UNICODE);
}
});
+
/** Standard options to use the ASCII/MBCS version of a w32 API. */
- Map ASCII_OPTIONS = Collections.unmodifiableMap(new HashMap() {
+ Map ASCII_OPTIONS = Collections.unmodifiableMap(new HashMap() {
+ private static final long serialVersionUID = 1L; // we're not serializing it
{
put(OPTION_TYPE_MAPPER, W32APITypeMapper.ASCII);
put(OPTION_FUNCTION_MAPPER, W32APIFunctionMapper.ASCII);
}
});
- Map DEFAULT_OPTIONS = Boolean.getBoolean("w32.ascii") ? ASCII_OPTIONS : UNICODE_OPTIONS;
+
+ /** Default options to use - depends on the value of {@code w32.ascii} system property */
+ Map DEFAULT_OPTIONS = Boolean.getBoolean("w32.ascii") ? ASCII_OPTIONS : UNICODE_OPTIONS;
}
diff --git a/src/com/sun/jna/win32/W32APITypeMapper.java b/src/com/sun/jna/win32/W32APITypeMapper.java
index 65bf9c944c..98d193c18a 100644
--- a/src/com/sun/jna/win32/W32APITypeMapper.java
+++ b/src/com/sun/jna/win32/W32APITypeMapper.java
@@ -1,14 +1,14 @@
/* Copyright (c) 2007 Timothy Wall, All Rights Reserved
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
- *
+ *
* This library 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 for more details.
+ * Lesser General Public License for more details.
*/
package com.sun.jna.win32;
@@ -20,7 +20,7 @@
import com.sun.jna.TypeMapper;
import com.sun.jna.WString;
-/** Provide standard conversion for W32 API types. This comprises the
+/** Provide standard conversion for W32 API types. This comprises the
* following native types:
*
* Unicode or ASCII/MBCS strings and arrays of string, as appropriate
@@ -29,13 +29,14 @@
* @author twall
*/
public class W32APITypeMapper extends DefaultTypeMapper {
-
+
public static final TypeMapper UNICODE = new W32APITypeMapper(true);
public static final TypeMapper ASCII = new W32APITypeMapper(false);
-
+
protected W32APITypeMapper(boolean unicode) {
if (unicode) {
TypeConverter stringConverter = new TypeConverter() {
+ @Override
public Object toNative(Object value, ToNativeContext context) {
if (value == null)
return null;
@@ -44,12 +45,14 @@ public Object toNative(Object value, ToNativeContext context) {
}
return new WString(value.toString());
}
+ @Override
public Object fromNative(Object value, FromNativeContext context) {
if (value == null)
return null;
return value.toString();
}
- public Class nativeType() {
+ @Override
+ public Class> nativeType() {
return WString.class;
}
};
@@ -57,13 +60,16 @@ public Class nativeType() {
addToNativeConverter(String[].class, stringConverter);
}
TypeConverter booleanConverter = new TypeConverter() {
+ @Override
public Object toNative(Object value, ToNativeContext context) {
- return new Integer(Boolean.TRUE.equals(value) ? 1 : 0);
+ return Integer.valueOf(Boolean.TRUE.equals(value) ? 1 : 0);
}
+ @Override
public Object fromNative(Object value, FromNativeContext context) {
return ((Integer)value).intValue() != 0 ? Boolean.TRUE : Boolean.FALSE;
}
- public Class nativeType() {
+ @Override
+ public Class> nativeType() {
// BOOL is 32-bit int
return Integer.class;
}
diff --git a/test/com/sun/jna/AnnotatedLibraryTest.java b/test/com/sun/jna/AnnotatedLibraryTest.java
index f3f0ff3615..4ada0abbe6 100644
--- a/test/com/sun/jna/AnnotatedLibraryTest.java
+++ b/test/com/sun/jna/AnnotatedLibraryTest.java
@@ -1,6 +1,5 @@
package com.sun.jna;
-import java.lang.annotation.Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -8,9 +7,7 @@
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
-import java.util.HashMap;
-import java.util.Map;
-
+import java.util.Collections;
import junit.framework.TestCase;
public class AnnotatedLibraryTest extends TestCase {
@@ -22,8 +19,9 @@ public class AnnotatedLibraryTest extends TestCase {
public interface AnnotatedLibrary extends Library {
@TestAnnotation boolean isAnnotated();
}
-
+
public class TestInvocationHandler implements InvocationHandler {
+ @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return Boolean.valueOf(method.getAnnotations().length == 1);
}
@@ -38,7 +36,7 @@ public void testProxyMethodHasAnnotations() throws Exception {
new TestInvocationHandler());
assertTrue("Proxy method not annotated", a.isAnnotated());
}
-
+
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public static @interface FooBoolean {}
@@ -48,31 +46,33 @@ public static interface AnnotationTestLibrary extends Library {
}
public void testAnnotationsOnMethods() throws Exception {
final int MAGIC = 0xABEDCF23;
- Map options = new HashMap();
final boolean[] hasAnnotation = {false, false};
- DefaultTypeMapper mapper = new DefaultTypeMapper();
+ DefaultTypeMapper mapper = new DefaultTypeMapper();
mapper.addTypeConverter(Boolean.class, new TypeConverter() {
+ @Override
public Object toNative(Object value, ToNativeContext ctx) {
MethodParameterContext mcontext = (MethodParameterContext)ctx;
hasAnnotation[0] = mcontext.getMethod().getAnnotation(FooBoolean.class) != null;
- return new Integer(Boolean.TRUE.equals(value) ? MAGIC : 0);
+ return Integer.valueOf(Boolean.TRUE.equals(value) ? MAGIC : 0);
}
+ @Override
public Object fromNative(Object value, FromNativeContext context) {
- MethodResultContext mcontext = (MethodResultContext)context;
+ MethodResultContext mcontext = (MethodResultContext)context;
hasAnnotation[1] = mcontext.getMethod().getAnnotation(FooBoolean.class) != null;
return Boolean.valueOf(((Integer) value).intValue() == MAGIC);
}
- public Class nativeType() {
+ @Override
+ public Class> nativeType() {
return Integer.class;
}
});
-
- options.put(Library.OPTION_TYPE_MAPPER, mapper);
- AnnotationTestLibrary lib = Native.loadLibrary("testlib", AnnotationTestLibrary.class, options);
+
+ AnnotationTestLibrary lib =
+ Native.loadLibrary("testlib", AnnotationTestLibrary.class, Collections.singletonMap(Library.OPTION_TYPE_MAPPER, mapper));
assertEquals("Failed to convert integer return to boolean TRUE", true,
lib.returnInt32Argument(true));
- assertTrue("Failed to get annotation from ParameterContext", hasAnnotation[0]);
- assertTrue("Failed to get annotation from ResultContext", hasAnnotation[1]);
+ assertTrue("Failed to get annotation from ParameterContext", hasAnnotation[0]);
+ assertTrue("Failed to get annotation from ResultContext", hasAnnotation[1]);
}
public static void main(String[] args) {
diff --git a/test/com/sun/jna/ArgumentsMarshalTest.java b/test/com/sun/jna/ArgumentsMarshalTest.java
index 1bbb76a9a9..4ab8c3d354 100644
--- a/test/com/sun/jna/ArgumentsMarshalTest.java
+++ b/test/com/sun/jna/ArgumentsMarshalTest.java
@@ -289,7 +289,7 @@ public Class> nativeType() {
}
@Override
public Object toNative() {
- return new Integer(value);
+ return Integer.valueOf(value);
}
}
protected NativeMappedLibrary loadNativeMappedLibrary() {
diff --git a/test/com/sun/jna/CallbacksTest.java b/test/com/sun/jna/CallbacksTest.java
index b511e50f99..4bcc7737c3 100644
--- a/test/com/sun/jna/CallbacksTest.java
+++ b/test/com/sun/jna/CallbacksTest.java
@@ -14,23 +14,24 @@
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
+import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.util.Arrays;
-import java.util.HashMap;
+import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
-import junit.framework.TestCase;
-
import com.sun.jna.Callback.UncaughtExceptionHandler;
import com.sun.jna.CallbacksTest.TestLibrary.CbCallback;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.PointerByReference;
import com.sun.jna.win32.W32APIOptions;
+import junit.framework.TestCase;
+
/** Exercise callback-related functionality.
*
* @author twall@users.sf.net
@@ -64,6 +65,7 @@ protected void waitFor(Thread thread) {
}
public static class SmallTestStructure extends Structure {
+ public static final List FIELDS = createFieldsOrder("value");
public double value;
public static int allocations = 0;
@Override
@@ -74,8 +76,8 @@ protected void allocateMemory(int size) {
public SmallTestStructure() { }
public SmallTestStructure(Pointer p) { super(p); read(); }
@Override
- protected List getFieldOrder() {
- return Arrays.asList(new String[] { "value" });
+ protected List getFieldOrder() {
+ return FIELDS;
}
}
public static class TestStructure extends Structure {
@@ -83,14 +85,16 @@ public static class ByValue extends TestStructure implements Structure.ByValue {
public static interface TestCallback extends Callback {
TestStructure.ByValue callback(TestStructure.ByValue s);
}
+
+ public static final List FIELDS = createFieldsOrder("c", "s", "i", "j", "inner");
public byte c;
public short s;
public int i;
public long j;
public SmallTestStructure inner;
@Override
- protected List getFieldOrder() {
- return Arrays.asList(new String[] { "c", "s", "i", "j", "inner" });
+ protected List getFieldOrder() {
+ return FIELDS;
}
}
public static interface TestLibrary extends Library {
@@ -233,12 +237,12 @@ public Object fromNative(Object nativeValue, FromNativeContext context) {
return new Custom(((Integer)nativeValue).intValue());
}
@Override
- public Class nativeType() {
+ public Class> nativeType() {
return Integer.class;
}
@Override
public Object toNative() {
- return new Integer(value);
+ return Integer.valueOf(value);
}
@Override
public boolean equals(Object o) {
@@ -252,8 +256,8 @@ public void testLookupNullCallback() {
try {
CallbackReference.getCallback(TestLibrary.VoidCallback.class, new Pointer(0));
fail("Null pointer lookup should fail");
- }
- catch(NullPointerException e) {
+ } catch(NullPointerException e) {
+ // expected
}
}
@@ -305,7 +309,7 @@ public void testMultipleMethodsCallback() {
public void testNativeFunctionPointerStringValue() {
Callback cb = CallbackReference.getCallback(TestLibrary.VoidCallback.class, new Pointer(getName().hashCode()));
- Class cls = CallbackReference.findCallbackClass(cb.getClass());
+ Class> cls = CallbackReference.findCallbackClass(cb.getClass());
assertTrue("toString should include Java Callback type: " + cb + " ("
+ cls + ")", cb.toString().indexOf(cls.getName()) != -1);
}
@@ -318,7 +322,7 @@ public void testLookupSameCallback() {
}
// Allow direct tests to override
- protected Map callbackCache() {
+ protected Map callbackCache() {
return CallbackReference.callbackMap;
}
@@ -334,19 +338,17 @@ public void callback() {
lib.callVoidCallback(cb);
assertTrue("Callback not called", called[0]);
- Map refs = new WeakHashMap(callbackCache());
+ Map refs = new WeakHashMap(callbackCache());
assertTrue("Callback not cached", refs.containsKey(cb));
- CallbackReference ref = (CallbackReference)refs.get(cb);
+ CallbackReference ref = refs.get(cb);
refs = callbackCache();
Pointer cbstruct = ref.cbstruct;
cb = null;
System.gc();
for (int i = 0; i < 100 && (ref.get() != null || refs.containsValue(ref)); ++i) {
- try {
- Thread.sleep(10); // Give the GC a chance to run
- System.gc();
- } finally {}
+ Thread.sleep(10); // Give the GC a chance to run
+ System.gc();
}
assertNull("Callback not GC'd", ref.get());
assertFalse("Callback still in map", refs.containsValue(ref));
@@ -668,13 +670,13 @@ public String callback(String arg, String arg2) {
};
// A little internal groping
- Map m = CallbackReference.allocations;
+ Map, ?> m = CallbackReference.allocations;
m.clear();
String arg = getName() + "1" + UNICODE;
String arg2 = getName() + "2" + UNICODE;
String value = lib.callStringCallback(cb, arg, arg2);
- WeakReference ref = new WeakReference(value);
+ WeakReference ref = new WeakReference(value);
arg = null;
value = null;
@@ -905,11 +907,11 @@ public Object callback(Object[] args) {
throw ERROR;
}
@Override
- public Class[] getParameterTypes() {
+ public Class>[] getParameterTypes() {
return new Class[] { CbCallback.class };
}
@Override
- public Class getReturnType() {
+ public Class> getReturnType() {
return CbCallback.class;
}
};
@@ -1015,16 +1017,16 @@ public void clear() {
@Override
public Object fromNative(Object value, FromNativeContext context) {
++fromNativeConversions;
- return new Double(((Integer)value).intValue());
+ return Double.valueOf(((Integer)value).intValue());
}
@Override
- public Class nativeType() {
+ public Class> nativeType() {
return Integer.class;
}
@Override
public Object toNative(Object value, ToNativeContext ctx) {
++toNativeConversions;
- return new Integer(((Double)value).intValue());
+ return Integer.valueOf(((Double)value).intValue());
}
};
addTypeConverter(double.class, converter);
@@ -1032,16 +1034,16 @@ public Object toNative(Object value, ToNativeContext ctx) {
@Override
public Object fromNative(Object value, FromNativeContext context) {
++fromNativeConversions;
- return new Float(((Long)value).intValue());
+ return Float.valueOf(((Long)value).intValue());
}
@Override
- public Class nativeType() {
+ public Class> nativeType() {
return Long.class;
}
@Override
public Object toNative(Object value, ToNativeContext ctx) {
++toNativeConversions;
- return new Long(((Float)value).longValue());
+ return Long.valueOf(((Float)value).longValue());
}
};
addTypeConverter(float.class, converter);
@@ -1058,7 +1060,7 @@ public Object fromNative(Object value, FromNativeContext context) {
return value.toString();
}
@Override
- public Class nativeType() {
+ public Class> nativeType() {
return WString.class;
}
@Override
@@ -1073,11 +1075,8 @@ public Object toNative(Object value, ToNativeContext ctx) {
public static interface CallbackTestLibrary extends Library {
final CallbackTypeMapper _MAPPER = new CallbackTypeMapper();
- final Map _OPTIONS = new HashMap() {
- {
- put(Library.OPTION_TYPE_MAPPER, _MAPPER);
- }
- };
+ final Map _OPTIONS = Collections.singletonMap(Library.OPTION_TYPE_MAPPER, _MAPPER);
+
interface DoubleCallback extends Callback {
double callback(double arg, double arg2);
}
@@ -1103,7 +1102,7 @@ protected CallbackTestLibrary loadCallbackTestLibrary() {
*/
public void testCallbackUsesTypeMapper() throws Exception {
CallbackTestLibrary lib = loadCallbackTestLibrary();
- lib._MAPPER.clear();
+ CallbackTestLibrary._MAPPER.clear();
final double[] ARGS = new double[2];
@@ -1115,9 +1114,9 @@ public double callback(double arg, double arg2) {
return arg + arg2;
}
};
- assertEquals("Wrong type mapper for callback class", lib._MAPPER,
+ assertEquals("Wrong type mapper for callback class", CallbackTestLibrary._MAPPER,
Native.getTypeMapper(CallbackTestLibrary.DoubleCallback.class));
- assertEquals("Wrong type mapper for callback object", lib._MAPPER,
+ assertEquals("Wrong type mapper for callback object", CallbackTestLibrary._MAPPER,
Native.getTypeMapper(cb.getClass()));
double result = lib.callInt32Callback(cb, -1, -2);
@@ -1126,14 +1125,14 @@ public double callback(double arg, double arg2) {
assertEquals("Incorrect result of callback invocation", -3, result, 0);
// Once per argument, then again for return value (convert native int->Java double)
- assertEquals("Type mapper not called for arguments", 3, lib._MAPPER.fromNativeConversions);
+ assertEquals("Type mapper not called for arguments", 3, CallbackTestLibrary._MAPPER.fromNativeConversions);
// Once per argument, then again for return value (convert Java double->native int)
- assertEquals("Type mapper not called for result", 3, lib._MAPPER.toNativeConversions);
+ assertEquals("Type mapper not called for result", 3, CallbackTestLibrary._MAPPER.toNativeConversions);
}
public void testTypeMapperWithWideStrings() throws Exception {
CallbackTestLibrary lib = loadCallbackTestLibrary();
- lib._MAPPER.clear();
+ CallbackTestLibrary._MAPPER.clear();
final String[] ARGS = new String[2];
@@ -1145,9 +1144,9 @@ public String callback(String arg, String arg2) {
return arg + arg2;
}
};
- assertEquals("Wrong type mapper for callback class", lib._MAPPER,
+ assertEquals("Wrong type mapper for callback class", CallbackTestLibrary._MAPPER,
Native.getTypeMapper(CallbackTestLibrary.WStringCallback.class));
- assertEquals("Wrong type mapper for callback object", lib._MAPPER,
+ assertEquals("Wrong type mapper for callback object", CallbackTestLibrary._MAPPER,
Native.getTypeMapper(cb.getClass()));
final String[] EXPECTED = { "magic" + UNICODE, getName() + UNICODE };
@@ -1157,9 +1156,9 @@ public String callback(String arg, String arg2) {
assertEquals("Incorrect result of callback invocation", EXPECTED[0] + EXPECTED[1], result);
// Once per argument, then again for return value (convert const wchar_t*->Java String)
- assertEquals("Type mapper not called for arguments", 3, lib._MAPPER.fromNativeConversions);
+ assertEquals("Type mapper not called for arguments", 3, CallbackTestLibrary._MAPPER.fromNativeConversions);
// Once per argument, then again for return value (convert Java String->const wchar_t*)
- assertEquals("Type mapper not called for result", 3, lib._MAPPER.toNativeConversions);
+ assertEquals("Type mapper not called for result", 3, CallbackTestLibrary._MAPPER.toNativeConversions);
}
public void testCallbackUsesTypeMapperWithDifferentReturnTypeSize() throws Exception {
@@ -1175,9 +1174,9 @@ public float callback(float arg, float arg2) {
return arg + arg2;
}
};
- assertEquals("Wrong type mapper for callback class", lib._MAPPER,
+ assertEquals("Wrong type mapper for callback class", CallbackTestLibrary._MAPPER,
Native.getTypeMapper(CallbackTestLibrary.FloatCallback.class));
- assertEquals("Wrong type mapper for callback object", lib._MAPPER,
+ assertEquals("Wrong type mapper for callback object", CallbackTestLibrary._MAPPER,
Native.getTypeMapper(cb.getClass()));
float result = lib.callInt64Callback(cb, -1, -2);
@@ -1293,7 +1292,7 @@ public void callback() {
// as daemon to avoid VM having to wait for it.
public void testCallbackThreadPersistence() throws Exception {
final int[] called = {0};
- final Set threads = new HashSet();
+ final Set threads = new HashSet();
final int COUNT = 5;
CallbackThreadInitializer init = new CallbackThreadInitializer(true, false) {
@@ -1317,49 +1316,48 @@ public void callback() {
assertEquals("Multiple callbacks on a given native thread should use the same Thread mapping: " + threads,
1, threads.size());
- waitFor((Thread)threads.iterator().next());
+ waitFor(threads.iterator().next());
}
// Thread object is never GC'd on linux-amd64 and darwin-amd64 (w/openjdk7)
public void testCleanupUndetachedThreadOnThreadExit() throws Exception {
- final Set threads = new HashSet();
+ final Set> threads = new HashSet>();
final int[] called = { 0 };
TestLibrary.VoidCallback cb = new TestLibrary.VoidCallback() {
@Override
public void callback() {
- threads.add(new WeakReference(Thread.currentThread()));
+ threads.add(new WeakReference(Thread.currentThread()));
if (++called[0] == 1) {
Thread.currentThread().setName(getName() + " (Thread to be cleaned up)");
}
- Native.detach(false);
+ Native.detach(false);
}
};
- // Always attach as daemon to ensure tests will exit
+ // Always attach as daemon to ensure tests will exit
CallbackThreadInitializer asDaemon = new CallbackThreadInitializer(true) {
- @Override
- public String getName(Callback cb) {
- return "Test thread (native) for " + CallbacksTest.this.getName();
- }
- };
+ @Override
+ public String getName(Callback cb) {
+ return "Test thread (native) for " + CallbacksTest.this.getName();
+ }
+ };
callThreadedCallback(cb, asDaemon, 2, 100, called);
- // Wait for it to start up
+ // Wait for it to start up
long start = System.currentTimeMillis();
while (threads.size() == 0 && called[0] == 0) {
- Thread.sleep(10);
- if (System.currentTimeMillis() - start > THREAD_TIMEOUT) {
- fail("Timed out waiting for thread to detach and terminate");
- }
+ Thread.sleep(10L);
+ if (System.currentTimeMillis() - start > THREAD_TIMEOUT) {
+ fail("Timed out waiting for thread to detach and terminate");
+ }
}
start = System.currentTimeMillis();
- WeakReference ref = (WeakReference)threads.iterator().next();
-
+ Reference ref = threads.iterator().next();
while (ref.get() != null) {
System.gc();
Thread.sleep(100);
- Thread[] remaining = new Thread[Thread.activeCount()];
- Thread.enumerate(remaining);
+ Thread[] remaining = new Thread[Thread.activeCount()];
+ Thread.enumerate(remaining);
if (System.currentTimeMillis() - start > THREAD_TIMEOUT) {
- Thread t = (Thread)ref.get();
+ Thread t = ref.get();
Pointer terminationFlag = Native.getTerminationFlag(t);
assertNotNull("Native thread termination flag is missing", terminationFlag);
if (terminationFlag.getInt(0) == 0) {
@@ -1377,7 +1375,7 @@ public String getName(Callback cb) {
// but callback explicitly detaches it on final invocation.
public void testCallbackIndicatedThreadDetach() throws Exception {
final int[] called = {0};
- final Set threads = new HashSet();
+ final Set threads = new HashSet();
final int COUNT = 5;
TestLibrary.VoidCallback cb = new TestLibrary.VoidCallback() {
@Override
@@ -1400,7 +1398,7 @@ else if (count == COUNT) {
assertEquals("Multiple callbacks in the same native thread should use the same Thread mapping: "
+ threads, 1, threads.size());
- waitFor((Thread)threads.iterator().next());
+ waitFor(threads.iterator().next());
}
public void testDLLCallback() throws Exception {
@@ -1426,7 +1424,7 @@ public void callback() {
Function f = kernel32.getFunction("GetModuleHandleExW");
final int GET_MODULE_HANDLE_FROM_ADDRESS = 0x4;
PointerByReference pref = new PointerByReference();
- int result = f.invokeInt(new Object[] { new Integer(GET_MODULE_HANDLE_FROM_ADDRESS), fp, pref });
+ int result = f.invokeInt(new Object[] { Integer.valueOf(GET_MODULE_HANDLE_FROM_ADDRESS), fp, pref });
assertTrue("GetModuleHandleEx(fptr) failed: " + Native.getLastError(), result != 0);
f = kernel32.getFunction("GetModuleFileNameW");
@@ -1440,9 +1438,9 @@ public void callback() {
assertEquals("Wrong module HANDLE for DLL function pointer", handle, pref.getValue());
// Check slot re-use
- Map refs = new WeakHashMap(callbackCache());
+ Map refs = new WeakHashMap(callbackCache());
assertTrue("Callback not cached", refs.containsKey(cb));
- CallbackReference ref = (CallbackReference)refs.get(cb);
+ CallbackReference ref = refs.get(cb);
refs = callbackCache();
Pointer cbstruct = ref.cbstruct;
Pointer first_fptr = cbstruct.getPointer(0);
@@ -1471,7 +1469,7 @@ public void callback() {
cb = new TestCallback();
lib.callVoidCallback(cb);
- ref = (CallbackReference)refs.get(cb);
+ ref = refs.get(cb);
cbstruct = ref.cbstruct;
assertTrue("Callback not called", called[0]);
@@ -1517,7 +1515,7 @@ public void invoke() { }
};
try {
Pointer p = CallbackReference.getFunctionPointer(cb);
- CallbackReference ref = (CallbackReference)CallbackReference.callbackMap.get(cb);
+ CallbackReference ref = CallbackReference.callbackMap.get(cb);
assertNotNull("CallbackReference not found", ref);
assertEquals("Tag-based calling convention not applied", Function.ALT_CONVENTION, ref.callingConvention);
}
@@ -1533,20 +1531,20 @@ interface TestCallback extends Callback {
}
public void testCallingConventionFromOptions() {
- Map options = new HashMap();
- options.put(Library.OPTION_CALLING_CONVENTION, Function.ALT_CONVENTION);
- OptionCallingConventionTestLibrary lib = Native.loadLibrary("testlib", OptionCallingConventionTestLibrary.class, options);
+ OptionCallingConventionTestLibrary lib =
+ Native.loadLibrary("testlib", OptionCallingConventionTestLibrary.class, Collections.singletonMap(Library.OPTION_CALLING_CONVENTION, Function.ALT_CONVENTION));
+ assertNotNull("Library not loaded", lib);
OptionCallingConventionTestLibrary.TestCallback cb = new OptionCallingConventionTestLibrary.TestCallback() {
@Override
public void invoke() { }
};
try {
Pointer p = CallbackReference.getFunctionPointer(cb);
- CallbackReference ref = (CallbackReference)CallbackReference.callbackMap.get(cb);
+ assertNotNull("No function pointer", p);
+ CallbackReference ref = CallbackReference.callbackMap.get(cb);
assertNotNull("CallbackReference not found", ref);
assertEquals("Option-based calling convention not applied", Function.ALT_CONVENTION, ref.callingConvention);
- }
- catch(IllegalArgumentException e) {
+ } catch(IllegalArgumentException e) {
// Alt convention not supported
}
}
diff --git a/test/com/sun/jna/DirectBufferArgumentsMarshalTest.java b/test/com/sun/jna/DirectBufferArgumentsMarshalTest.java
index a335c7806f..29b5009106 100644
--- a/test/com/sun/jna/DirectBufferArgumentsMarshalTest.java
+++ b/test/com/sun/jna/DirectBufferArgumentsMarshalTest.java
@@ -8,19 +8,17 @@
* This library 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 for more details.
+ * Lesser General Public License for more details.
*/
package com.sun.jna;
import java.nio.ByteBuffer;
-import java.nio.FloatBuffer;
import java.nio.DoubleBuffer;
+import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.LongBuffer;
import java.nio.ShortBuffer;
-import com.sun.jna.ArgumentsMarshalTest.TestLibrary.CheckFieldAlignment.ByReference;
-
/** Exercise a range of native methods.
*
* @author twall@users.sf.net
@@ -30,18 +28,29 @@ public class DirectBufferArgumentsMarshalTest extends BufferArgumentsMarshalTest
public static class DirectTestLibrary implements TestLibrary {
// ByteBuffer alternative definitions
+ @Override
public native int fillInt8Buffer(ByteBuffer buf, int len, byte value);
+ @Override
public native int fillInt16Buffer(ByteBuffer buf, int len, short value);
+ @Override
public native int fillInt32Buffer(ByteBuffer buf, int len, int value);
+ @Override
public native int fillInt64Buffer(ByteBuffer buf, int len, long value);
+ @Override
public native int fillFloatBuffer(ByteBuffer buf, int len, float value);
+ @Override
public native int fillDoubleBuffer(ByteBuffer buf, int len, double value);
-
- // {Short|Int|Long|Float|Double}Buffer alternative definitions
+
+ // {Short|Int|Long|Float|Double}Buffer alternative definitions
+ @Override
public native int fillInt16Buffer(ShortBuffer buf, int len, short value);
+ @Override
public native int fillInt32Buffer(IntBuffer buf, int len, int value);
+ @Override
public native int fillInt64Buffer(LongBuffer buf, int len, long value);
+ @Override
public native int fillFloatBuffer(FloatBuffer buf, int len, float value);
+ @Override
public native int fillDoubleBuffer(DoubleBuffer buf, int len, double value);
static {
@@ -50,12 +59,13 @@ public static class DirectTestLibrary implements TestLibrary {
}
/* Override original. */
+ @Override
protected void setUp() {
lib = new DirectTestLibrary();
}
-
+
public static void main(java.lang.String[] argList) {
junit.textui.TestRunner.run(DirectBufferArgumentsMarshalTest.class);
}
-
+
}
diff --git a/test/com/sun/jna/DirectCallbacksTest.java b/test/com/sun/jna/DirectCallbacksTest.java
index 4be9d4b5b7..22aaa07455 100644
--- a/test/com/sun/jna/DirectCallbacksTest.java
+++ b/test/com/sun/jna/DirectCallbacksTest.java
@@ -8,7 +8,7 @@
* This library 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 for more details.
+ * Lesser General Public License for more details.
*/
package com.sun.jna;
@@ -23,29 +23,52 @@
public class DirectCallbacksTest extends CallbacksTest {
public static class DirectTestLibrary implements TestLibrary {
+ @Override
public native void callVoidCallback(VoidCallbackCustom c);
+ @Override
public native boolean callBooleanCallback(BooleanCallback c, boolean arg, boolean arg2);
+ @Override
public native byte callInt8Callback(ByteCallback c, byte arg, byte arg2);
+ @Override
public native short callInt16Callback(ShortCallback c, short arg, short arg2);
+ @Override
public native int callInt32Callback(Int32Callback c, int arg, int arg2);
+ @Override
public native NativeLong callNativeLongCallback(NativeLongCallback c, NativeLong arg, NativeLong arg2);
+ @Override
public native long callInt64Callback(Int64Callback c, long arg, long arg2);
+ @Override
public native float callFloatCallback(FloatCallback c, float arg, float arg2);
+ @Override
public native double callDoubleCallback(DoubleCallback c, double arg, double arg2);
+ @Override
public native SmallTestStructure callStructureCallback(StructureCallback c, SmallTestStructure arg);
+ @Override
public native String callStringCallback(StringCallback c, String arg, String arg2);
+ @Override
public native WString callWideStringCallback(WideStringCallback c, WString arg, WString arg2);
+ @Override
public Pointer callStringArrayCallback(StringArrayCallback c, String[] arg) { throw new UnsupportedOperationException(); }
+ @Override
public native int callCallbackWithByReferenceArgument(CopyArgToByReference cb, int arg, IntByReference result);
+ @Override
public native TestStructure.ByValue callCallbackWithStructByValue(TestStructure.TestCallback callback, TestStructure.ByValue cbstruct);
+ @Override
public native CbCallback callCallbackWithCallback(CbCallback cb);
+ @Override
public native Int32CallbackX returnCallback();
+ @Override
public native Int32CallbackX returnCallbackArgument(Int32CallbackX cb);
+ @Override
public native void callVoidCallback(VoidCallback c);
+ @Override
public native void callVoidCallbackThreaded(VoidCallback c, int count, int ms, String name);
+ @Override
public native int callInt32Callback(CustomCallback cb, int arg1, int arg2);
+ @Override
public native void callCallbackInStruct(CbStruct s);
+ @Override
public native TestUnion testUnionByValueCallbackArgument(UnionCallback cb, TestUnion arg);
static {
@@ -53,29 +76,37 @@ public static class DirectTestLibrary implements TestLibrary {
}
}
+ @Override
protected void setUp() {
lib = new DirectTestLibrary();
}
-
- protected Map callbackCache() {
+
+ @Override
+ protected Map callbackCache() {
return CallbackReference.directCallbackMap;
}
public static class DirectCallbackTestLibrary implements CallbackTestLibrary {
+ @Override
public native double callInt32Callback(DoubleCallback c, double arg, double arg2);
+ @Override
public native float callInt64Callback(FloatCallback c, float arg, float arg2);
+ @Override
public native String callWideStringCallback(WStringCallback c, String arg, String arg2);
static {
Native.register(NativeLibrary.getInstance("testlib", _OPTIONS));
}
}
+ @Override
protected CallbackTestLibrary loadCallbackTestLibrary() {
return new DirectCallbackTestLibrary();
}
// Currently unsupported tests
+ @Override
public void testCallStringArrayCallback() { }
+ @Override
public void testCallbackExceptionHandlerWithCallbackProxy() { }
public static void main(java.lang.String[] argList) {
diff --git a/test/com/sun/jna/DirectReturnTypesTest.java b/test/com/sun/jna/DirectReturnTypesTest.java
index 525a67be21..d8e139d997 100644
--- a/test/com/sun/jna/DirectReturnTypesTest.java
+++ b/test/com/sun/jna/DirectReturnTypesTest.java
@@ -8,19 +8,12 @@
* This library 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 for more details.
+ * Lesser General Public License for more details.
*/
package com.sun.jna;
-import java.util.HashMap;
import java.util.Map;
-import junit.framework.TestCase;
-
-import com.sun.jna.ReturnTypesTest.TestLibrary.SimpleStructure;
-import com.sun.jna.ReturnTypesTest.TestLibrary.TestStructure;
-import com.sun.jna.ReturnTypesTest.TestLibrary.TestSmallStructure;
-
/** Exercise a range of native methods.
*
* @author twall@users.sf.net
@@ -28,34 +21,57 @@
public class DirectReturnTypesTest extends ReturnTypesTest {
public static class DirectTestLibrary implements TestLibrary {
-
+
+ @Override
public Object returnObjectArgument(Object s) {
throw new IllegalArgumentException(s.getClass().getName());
}
+ @Override
public TestObject returnObjectArgument(TestObject s) {
throw new IllegalArgumentException(s.getClass().getName());
}
+ @Override
public native boolean returnFalse();
+ @Override
public native boolean returnTrue();
+ @Override
public native int returnInt32Zero();
+ @Override
public native int returnInt32Magic();
+ @Override
public native long returnInt64Zero();
+ @Override
public native long returnInt64Magic();
+ @Override
public native NativeLong returnLongZero();
+ @Override
public native NativeLong returnLongMagic();
+ @Override
public native float returnFloatZero();
+ @Override
public native float returnFloatMagic();
+ @Override
public native double returnDoubleZero();
+ @Override
public native double returnDoubleMagic();
+ @Override
public native String returnStringMagic();
+ @Override
public native WString returnWStringMagic();
+ @Override
public native SimpleStructure returnStaticTestStructure();
+ @Override
public native SimpleStructure returnNullTestStructure();
+ @Override
public native TestSmallStructure.ByValue returnSmallStructureByValue();
+ @Override
public native TestStructure.ByValue returnStructureByValue();
+ @Override
public Pointer[] returnPointerArgument(Pointer[] arg) {throw new UnsupportedOperationException();}
+ @Override
public String[] returnPointerArgument(String[] arg) {throw new UnsupportedOperationException();}
+ @Override
public WString[] returnPointerArgument(WString[] arg) {throw new UnsupportedOperationException();}
static {
@@ -63,32 +79,41 @@ public TestObject returnObjectArgument(TestObject s) {
}
}
+ @Override
protected void setUp() {
lib = new DirectTestLibrary();
}
-
+
public static class DirectObjectTestLibrary extends DirectTestLibrary {
- public DirectObjectTestLibrary(Map options) {
+ public DirectObjectTestLibrary(Map options) {
Native.register(getClass(), NativeLibrary.getInstance("testlib", options));
}
}
public static class DirectNativeMappedLibrary implements NativeMappedLibrary {
+ @Override
public native Custom returnInt32Argument(int arg);
+ @Override
public native size_t returnInt32Magic();
+ @Override
public native size_t returnInt64Magic();
static {
Native.register("testlib");
}
}
+ @Override
protected NativeMappedLibrary loadNativeMappedLibrary() {
return new DirectNativeMappedLibrary();
}
// Override not-yet-supported tests
+ @Override
public void testReturnObject() { }
+ @Override
public void testReturnPointerArray() { }
+ @Override
public void testReturnStringArray() { }
+ @Override
public void testReturnWStringArray() { }
public static void main(java.lang.String[] argList) {
diff --git a/test/com/sun/jna/DirectStructureByValueTest.java b/test/com/sun/jna/DirectStructureByValueTest.java
index e0ae4f3189..c484c6bd71 100644
--- a/test/com/sun/jna/DirectStructureByValueTest.java
+++ b/test/com/sun/jna/DirectStructureByValueTest.java
@@ -12,12 +12,6 @@
*/
package com.sun.jna;
-import java.nio.Buffer;
-import java.nio.ByteBuffer;
-import java.util.Map;
-
-import junit.framework.TestCase;
-
/** General structure by value functionality tests. */
public class DirectStructureByValueTest extends StructureByValueTest {
diff --git a/test/com/sun/jna/DirectTest.java b/test/com/sun/jna/DirectTest.java
index 769b5aec79..e7ee2015b5 100644
--- a/test/com/sun/jna/DirectTest.java
+++ b/test/com/sun/jna/DirectTest.java
@@ -19,6 +19,7 @@
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -99,6 +100,7 @@ private static class TestLoader extends URLClassLoader {
public TestLoader() throws MalformedURLException {
this(null);
}
+
public TestLoader(ClassLoader parent) throws MalformedURLException {
super(Platform.isWindowsCE()
? new URL[] {
@@ -171,13 +173,13 @@ protected List getFieldOrder() {
public static interface DirectCallback extends Callback {
void invoke();
}
- public DirectMapping(Map options) {
+ public DirectMapping(Map options) {
Native.register(getClass(), NativeLibrary.getInstance("testlib", options));
}
}
public void testGetOptionsForDirectMappingWithMemberInitializer() {
- Class[] classes = {
+ Class>[] classes = {
DirectMapping.class,
DirectMapping.DirectStructure.class,
DirectMapping.DirectCallback.class,
@@ -185,20 +187,20 @@ public void testGetOptionsForDirectMappingWithMemberInitializer() {
final TypeMapper mapper = new DefaultTypeMapper();
final int alignment = Structure.ALIGN_NONE;
final String encoding = System.getProperty("file.encoding");
- Map options = new HashMap();
+ Map options = new HashMap();
options.put(Library.OPTION_TYPE_MAPPER, mapper);
options.put(Library.OPTION_STRUCTURE_ALIGNMENT, alignment);
options.put(Library.OPTION_STRING_ENCODING, encoding);
DirectMapping lib = new DirectMapping(options);
- for (int i=0;i < classes.length;i++) {
- assertEquals("Wrong type mapper for direct mapping " + classes[i],
- mapper, Native.getTypeMapper(classes[i]));
- assertEquals("Wrong alignment for direct mapping " + classes[i],
- alignment, Native.getStructureAlignment(classes[i]));
- assertEquals("Wrong encoding for direct mapping " + classes[i],
- encoding, Native.getStringEncoding(classes[i]));
- Object last = Native.getLibraryOptions(classes[i]);;
- assertSame("Options not cached", last, Native.getLibraryOptions(classes[i]));
+ for (Class> cls : classes) {
+ assertEquals("Wrong type mapper for direct mapping " + cls,
+ mapper, Native.getTypeMapper(cls));
+ assertEquals("Wrong alignment for direct mapping " + cls,
+ alignment, Native.getStructureAlignment(cls));
+ assertEquals("Wrong encoding for direct mapping " + cls,
+ encoding, Native.getStringEncoding(cls));
+ Object last = Native.getLibraryOptions(cls);
+ assertSame("Options not cached", last, Native.getLibraryOptions(cls));
}
}
@@ -206,7 +208,9 @@ public static class DirectMappingStatic {
final static TypeMapper TEST_MAPPER = new DefaultTypeMapper();
final static int TEST_ALIGNMENT = Structure.ALIGN_DEFAULT;
final static String TEST_ENCODING = System.getProperty("file.encoding");
- final static Map TEST_OPTIONS = new HashMap() {
+ final static Map TEST_OPTIONS = new HashMap() {
+ private static final long serialVersionUID = 1L; // we're not serializing it
+
{
put(Library.OPTION_TYPE_MAPPER, TEST_MAPPER);
put(Library.OPTION_STRUCTURE_ALIGNMENT, TEST_ALIGNMENT);
@@ -229,20 +233,20 @@ public static interface DirectCallback extends Callback {
}
public void testGetOptionsForDirectMappingWithStaticInitializer() {
- Class[] classes = {
+ Class>[] classes = {
DirectMappingStatic.class,
DirectMappingStatic.DirectStructure.class,
DirectMappingStatic.DirectCallback.class,
};
- for (int i=0;i < classes.length;i++) {
- assertEquals("Wrong type mapper for direct mapping " + classes[i],
- DirectMappingStatic.TEST_MAPPER, Native.getTypeMapper(classes[i]));
- assertEquals("Wrong alignment for direct mapping " + classes[i],
- DirectMappingStatic.TEST_ALIGNMENT, Native.getStructureAlignment(classes[i]));
- assertEquals("Wrong encoding for direct mapping " + classes[i],
- DirectMappingStatic.TEST_ENCODING, Native.getStringEncoding(classes[i]));
- Object last = Native.getLibraryOptions(classes[i]);;
- assertSame("Options not cached", last, Native.getLibraryOptions(classes[i]));
+ for (Class> cls : classes) {
+ assertEquals("Wrong type mapper for direct mapping " + cls,
+ DirectMappingStatic.TEST_MAPPER, Native.getTypeMapper(cls));
+ assertEquals("Wrong alignment for direct mapping " + cls,
+ DirectMappingStatic.TEST_ALIGNMENT, Native.getStructureAlignment(cls));
+ assertEquals("Wrong encoding for direct mapping " + cls,
+ DirectMappingStatic.TEST_ENCODING, Native.getStringEncoding(cls));
+ Object last = Native.getLibraryOptions(cls);
+ assertSame("Options not cached", last, Native.getLibraryOptions(cls));
}
}
@@ -262,21 +266,19 @@ public String getFunctionName(NativeLibrary lib, Method method) {
return name;
}
};
- Map options = new HashMap();
- options.put(Library.OPTION_FUNCTION_MAPPER, MAPPER);
+
try {
Native.register(RemappedCLibrary.class,
- NativeLibrary.getInstance(Platform.C_LIBRARY_NAME, options));
+ NativeLibrary.getInstance(Platform.C_LIBRARY_NAME, Collections.singletonMap(Library.OPTION_FUNCTION_MAPPER, MAPPER)));
final String VALUE = getName();
int len;
len = RemappedCLibrary.$$YJP$$strlen(VALUE);
- assertEquals(VALUE.length(), len);
+ assertEquals("Mismatched YJP strlen value", VALUE.length(), len);
len = RemappedCLibrary._prefixed_strlen(VALUE);
- assertEquals(VALUE.length(), len);
- }
- catch(Exception e) {
+ assertEquals("Mismatched prefixed strlen value", VALUE.length(), len);
+ } catch(Exception e) {
fail("Native method was not properly mapped: " + e);
}
}
diff --git a/test/com/sun/jna/DirectTypeMapperTest.java b/test/com/sun/jna/DirectTypeMapperTest.java
index a03f481646..0a961d5bb6 100644
--- a/test/com/sun/jna/DirectTypeMapperTest.java
+++ b/test/com/sun/jna/DirectTypeMapperTest.java
@@ -8,13 +8,12 @@
* This library 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 for more details.
+ * Lesser General Public License for more details.
*/
package com.sun.jna;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.Collections;
import junit.framework.TestCase;
public class DirectTypeMapperTest extends TestCase {
@@ -26,18 +25,19 @@ public static class DirectTestLibraryBoolean {
final static int MAGIC = 0xABEDCF23;
public native int returnInt32Argument(boolean b);
static {
- Map options = new HashMap();
DefaultTypeMapper mapper = new DefaultTypeMapper();
mapper.addToNativeConverter(Boolean.class, new ToNativeConverter() {
+ @Override
public Object toNative(Object arg, ToNativeContext ctx) {
- return new Integer(Boolean.TRUE.equals(arg) ? MAGIC : 0);
+ return Integer.valueOf(Boolean.TRUE.equals(arg) ? MAGIC : 0);
}
- public Class nativeType() {
+ @Override
+ public Class> nativeType() {
return Integer.class;
}
});
- options.put(Library.OPTION_TYPE_MAPPER, mapper);
- Native.register(NativeLibrary.getInstance("testlib", options));
+
+ Native.register(NativeLibrary.getInstance("testlib", Collections.singletonMap(Library.OPTION_TYPE_MAPPER, mapper)));
}
}
/** Converts String to int when going to native. */
@@ -46,16 +46,16 @@ public static class DirectTestLibraryString {
static {
DefaultTypeMapper mapper = new DefaultTypeMapper();
mapper.addToNativeConverter(String.class, new ToNativeConverter() {
+ @Override
public Object toNative(Object arg, ToNativeContext ctx) {
return Integer.valueOf((String) arg, 16);
}
- public Class nativeType() {
+ @Override
+ public Class> nativeType() {
return Integer.class;
}
});
- Map options = new HashMap();
- options.put(Library.OPTION_TYPE_MAPPER, mapper);
- Native.register(NativeLibrary.getInstance("testlib", options));
+ Native.register(NativeLibrary.getInstance("testlib", Collections.singletonMap(Library.OPTION_TYPE_MAPPER, mapper)));
}
}
/** Converts CharSequence to int when going to native. */
@@ -64,17 +64,16 @@ public static class DirectTestLibraryCharSequence {
static {
DefaultTypeMapper mapper = new DefaultTypeMapper();
mapper.addToNativeConverter(CharSequence.class, new ToNativeConverter() {
+ @Override
public Object toNative(Object arg, ToNativeContext ctx) {
return Integer.valueOf(((CharSequence)arg).toString(), 16);
}
- public Class nativeType() {
+ @Override
+ public Class> nativeType() {
return Integer.class;
}
});
- Map options = new HashMap();
- options.put(Library.OPTION_TYPE_MAPPER, mapper);
-
- Native.register(NativeLibrary.getInstance("testlib", options));
+ Native.register(NativeLibrary.getInstance("testlib", Collections.singletonMap(Library.OPTION_TYPE_MAPPER, mapper)));
}
}
/** Converts Number to int when going to native. */
@@ -83,17 +82,16 @@ public static class DirectTestLibraryNumber {
static {
DefaultTypeMapper mapper = new DefaultTypeMapper();
mapper.addToNativeConverter(Number.class, new ToNativeConverter() {
+ @Override
public Object toNative(Object arg, ToNativeContext ctx) {
- return new Integer(((Number)arg).intValue());
+ return Integer.valueOf(((Number)arg).intValue());
}
- public Class nativeType() {
+ @Override
+ public Class> nativeType() {
return Integer.class;
}
});
- Map options = new HashMap();
- options.put(Library.OPTION_TYPE_MAPPER, mapper);
-
- Native.register(NativeLibrary.getInstance("testlib", options));
+ Native.register(NativeLibrary.getInstance("testlib", Collections.singletonMap(Library.OPTION_TYPE_MAPPER, mapper)));
}
}
/** Converts String to WString and back. */
@@ -102,32 +100,32 @@ public static class DirectTestLibraryWString {
static {
DefaultTypeMapper mapper = new DefaultTypeMapper();
mapper.addTypeConverter(String.class, new TypeConverter() {
+ @Override
public Object toNative(Object value, ToNativeContext ctx) {
if (value == null) {
return null;
}
return new WString(value.toString());
}
+ @Override
public Object fromNative(Object value, FromNativeContext context) {
if (value == null) {
return null;
}
return value.toString();
}
- public Class nativeType() {
+ @Override
+ public Class> nativeType() {
return WString.class;
}
});
- Map options = new HashMap();
- options.put(Library.OPTION_TYPE_MAPPER, mapper);
-
- Native.register(NativeLibrary.getInstance("testlib", options));
+ Native.register(NativeLibrary.getInstance("testlib", Collections.singletonMap(Library.OPTION_TYPE_MAPPER, mapper)));
}
}
public void testBooleanToIntArgumentConversion() {
DirectTestLibraryBoolean lib = new DirectTestLibraryBoolean();
assertEquals("Failed to convert Boolean argument to Int",
- lib.MAGIC,
+ DirectTestLibraryBoolean.MAGIC,
lib.returnInt32Argument(true));
}
public void testStringToIntArgumentConversion() {
@@ -143,11 +141,11 @@ public void testCharSequenceToIntArgumentConversion() {
lib.returnInt32Argument(Integer.toHexString(MAGIC)));
}
public void testNumberToIntArgumentConversion() {
-
+
final int MAGIC = 0x7BEDCF23;
DirectTestLibraryNumber lib = new DirectTestLibraryNumber();
assertEquals("Failed to convert Double argument to Int", MAGIC,
- lib.returnInt32Argument(new Double(MAGIC)));
+ lib.returnInt32Argument(Double.valueOf(MAGIC)));
}
public void testStringToWStringArgumentConversion() {
final String MAGIC = "magic" + UNICODE;
@@ -161,36 +159,38 @@ public static class DirectTestLibraryBidirectionalBoolean {
public native boolean returnInt32Argument(boolean b);
static {
final int MAGIC = 0xABEDCF23;
- Map options = new HashMap();
DefaultTypeMapper mapper = new DefaultTypeMapper();
// Use opposite sense of default int<-->boolean conversions
mapper.addToNativeConverter(Boolean.class, new ToNativeConverter() {
+ @Override
public Object toNative(Object value, ToNativeContext ctx) {
- return new Integer(Boolean.TRUE.equals(value) ? 0 : MAGIC);
+ return Integer.valueOf(Boolean.TRUE.equals(value) ? 0 : MAGIC);
}
- public Class nativeType() {
+ @Override
+ public Class> nativeType() {
return Integer.class;
}
});
mapper.addFromNativeConverter(Boolean.class, new FromNativeConverter() {
+ @Override
public Object fromNative(Object value, FromNativeContext context) {
return Boolean.valueOf(((Integer) value).intValue() != MAGIC);
}
- public Class nativeType() {
+ @Override
+ public Class> nativeType() {
return Integer.class;
}
});
- options.put(Library.OPTION_TYPE_MAPPER, mapper);
- Native.register(NativeLibrary.getInstance("testlib", options));
+ Native.register(NativeLibrary.getInstance("testlib", Collections.singletonMap(Library.OPTION_TYPE_MAPPER, mapper)));
}
}
public void testIntegerToBooleanResultConversion() throws Exception {
DirectTestLibraryBidirectionalBoolean lib = new DirectTestLibraryBidirectionalBoolean();
// argument "true" converts to zero; result zero converts to "true"
- assertTrue("Failed to convert integer return to boolean TRUE",
+ assertTrue("Failed to convert integer return to boolean TRUE",
lib.returnInt32Argument(true));
// argument "true" converts to MAGIC; result MAGIC converts to "false"
- assertFalse("Failed to convert integer return to boolean FALSE",
+ assertFalse("Failed to convert integer return to boolean FALSE",
lib.returnInt32Argument(false));
}
public static class PointTestClass {
@@ -200,9 +200,9 @@ public static class PointTestClass {
public static class DirectTypeMappedResultTypeTestLibrary {
public native PointTestClass returnPoint(int x, int y);
static {
- Map options = new HashMap();
DefaultTypeMapper mapper = new DefaultTypeMapper();
mapper.addTypeConverter(PointTestClass.class, new TypeConverter() {
+ @Override
public Object fromNative(Object value, FromNativeContext context) {
Pointer p = (Pointer) value;
PointTestClass pc = new PointTestClass();
@@ -211,16 +211,18 @@ public Object fromNative(Object value, FromNativeContext context) {
Native.free(Pointer.nativeValue(p));
return pc;
}
+ @Override
public Object toNative(Object value, ToNativeContext context) {
return Pointer.NULL; // dummy implementation (not called)
}
- public Class nativeType() {
+ @Override
+ public Class> nativeType() {
return Pointer.class;
}
});
- options.put(Library.OPTION_TYPE_MAPPER, mapper);
+
PointTestClass.TYPE_MAPPER = mapper;
- Native.register(NativeLibrary.getInstance("testlib", options));
+ Native.register(NativeLibrary.getInstance("testlib", Collections.singletonMap(Library.OPTION_TYPE_MAPPER, mapper)));
}
}
public void testTypeMapperResultTypeConversion() throws Exception {
@@ -247,20 +249,20 @@ public static Enumeration fromCode(int code) {
static {
DefaultTypeMapper mapper = new DefaultTypeMapper();
mapper.addTypeConverter(Enumeration.class, new TypeConverter() {
+ @Override
public Object toNative(Object arg, ToNativeContext ctx) {
- return new Integer(((Enumeration)arg).getCode());
+ return Integer.valueOf(((Enumeration)arg).getCode());
}
+ @Override
public Object fromNative(Object value, FromNativeContext context) {
return Enumeration.fromCode(((Integer)value).intValue());
}
- public Class nativeType() {
+ @Override
+ public Class> nativeType() {
return Integer.class;
}
});
- Map options = new HashMap();
- options.put(Library.OPTION_TYPE_MAPPER, mapper);
-
- Native.register(NativeLibrary.getInstance("testlib", options));
+ Native.register(NativeLibrary.getInstance("testlib", Collections.singletonMap(Library.OPTION_TYPE_MAPPER, mapper)));
}
}
public void testEnumerationConversion() {
diff --git a/test/com/sun/jna/FunctionTest.java b/test/com/sun/jna/FunctionTest.java
index 867660e45a..05ceaf975f 100644
--- a/test/com/sun/jna/FunctionTest.java
+++ b/test/com/sun/jna/FunctionTest.java
@@ -8,13 +8,10 @@
* This library 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 for more details.
+ * Lesser General Public License for more details.
*/
package com.sun.jna;
-import java.util.Arrays;
-import java.util.List;
-
import junit.framework.TestCase;
/** Exercise the {@link Function} class.
@@ -30,11 +27,11 @@ public void testTooManyArgs() {
Object[] args = new Object[Function.MAX_NARGS+1];
// Make sure we don't break 'printf'
args[0] = getName();
- try {
+ try {
f.invokeInt(args);
fail("Arguments should be limited to " + Function.MAX_NARGS);
- }
- catch(UnsupportedOperationException e) {
+ } catch(UnsupportedOperationException e) {
+ // expected
}
assertEquals("Wrong result from 'printf'", getName().length(), f.invokeInt(new Object[] { getName() }));
}
@@ -45,13 +42,13 @@ public void testUnsupportedReturnType() {
try {
f.invoke(getClass(), new Object[] { getName() });
fail("Invalid return types should throw an exception");
- }
- catch(IllegalArgumentException e) {
+ } catch(IllegalArgumentException e) {
+ // expected
}
}
public static void main(java.lang.String[] argList) {
junit.textui.TestRunner.run(FunctionTest.class);
}
-
+
}
diff --git a/test/com/sun/jna/GCWaits.java b/test/com/sun/jna/GCWaits.java
index d98043a810..be73d27dc0 100644
--- a/test/com/sun/jna/GCWaits.java
+++ b/test/com/sun/jna/GCWaits.java
@@ -1,3 +1,16 @@
+/* Copyright (c) 2007 Timothy Wall, All Rights Reserved
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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 for more details.
+ */
+
package com.sun.jna;
public interface GCWaits {
diff --git a/test/com/sun/jna/IntegerTypeTest.java b/test/com/sun/jna/IntegerTypeTest.java
index b0660c8926..e38381f30b 100644
--- a/test/com/sun/jna/IntegerTypeTest.java
+++ b/test/com/sun/jna/IntegerTypeTest.java
@@ -8,6 +8,7 @@
public class IntegerTypeTest extends TestCase {
public static class Sized extends IntegerType {
+ private static final long serialVersionUID = 1L;
public Sized() { this(4, 0); }
public Sized(int size, long value) { super(size, value); }
}
@@ -16,8 +17,8 @@ public void testWriteNull() {
class NTStruct extends Structure {
public Sized field;
@Override
- protected List getFieldOrder() {
- return Arrays.asList(new String[] { "field" });
+ protected List getFieldOrder() {
+ return Arrays.asList("field");
}
}
NTStruct s = new NTStruct();
@@ -27,8 +28,8 @@ public void testReadNull() {
class NTStruct extends Structure {
public Sized field;
@Override
- protected List getFieldOrder() {
- return Arrays.asList(new String[] { "field" });
+ protected List getFieldOrder() {
+ return Arrays.asList("field");
}
}
NTStruct s = new NTStruct();
@@ -78,6 +79,8 @@ public void testInitialValue() {
public void testValueBoundaries() {
class TestType extends IntegerType {
+ private static final long serialVersionUID = 1L;
+
public TestType(int size, long value) {
super(size, value);
}
@@ -104,6 +107,8 @@ public TestType(int size, long value) {
public void testUnsignedValues() {
class TestType extends IntegerType {
+ private static final long serialVersionUID = 1L;
+
public TestType(int size, long value) {
super(size, value);
}
@@ -116,6 +121,8 @@ public TestType(int size, long value) {
assertEquals("Wrong unsigned int value", VALUE, new TestType(4, VALUE).longValue());
class UnsignedTestType extends IntegerType {
+ private static final long serialVersionUID = 1L;
+
public UnsignedTestType(int size, long value) {
super(size, value, true);
}
diff --git a/test/com/sun/jna/JNALoadTest.java b/test/com/sun/jna/JNALoadTest.java
index 42ffc2122c..a9b09c788b 100644
--- a/test/com/sun/jna/JNALoadTest.java
+++ b/test/com/sun/jna/JNALoadTest.java
@@ -13,6 +13,7 @@
package com.sun.jna;
import java.io.File;
+import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.net.MalformedURLException;
@@ -115,8 +116,8 @@ public void testLoadAndUnloadFromJar() throws Exception {
assertTrue("Native library not unpacked from jar: " + path,
path.startsWith(System.getProperty("java.io.tmpdir")));
- WeakReference ref = new WeakReference(cls);
- WeakReference clref = new WeakReference(loader);
+ Reference> ref = new WeakReference>(cls);
+ Reference clref = new WeakReference(loader);
loader = null;
cls = null;
field = null;
@@ -136,8 +137,8 @@ public void testLoadAndUnloadFromJar() throws Exception {
}
if (f.exists()) {
- assertTrue("Temporary jnidispatch not marked for later deletion: "
- + f, new File(f.getAbsolutePath()+".x").exists());
+ assertTrue("Temporary jnidispatch not marked for later deletion: " + f,
+ new File(f.getAbsolutePath()+".x").exists());
}
assertFalse("System property jna.loaded not cleared", Boolean.getBoolean("jna.loaded"));
@@ -146,11 +147,9 @@ public void testLoadAndUnloadFromJar() throws Exception {
try {
loader = new TestLoader(true);
cls = Class.forName("com.sun.jna.Native", true, loader);
- }
- catch(Throwable t) {
+ } catch(Throwable t) {
fail("Couldn't load class again after discarding first load: " + t.getMessage());
- }
- finally {
+ } finally {
loader = null;
cls = null;
System.gc();
@@ -169,8 +168,8 @@ public void testLoadAndUnloadFromResourcePath() throws Exception {
String path = (String)field.get(null);
assertNotNull("Native library not found", path);
- WeakReference ref = new WeakReference(cls);
- WeakReference clref = new WeakReference(loader);
+ Reference> ref = new WeakReference>(cls);
+ Reference clref = new WeakReference(loader);
loader = null;
cls = null;
field = null;
diff --git a/test/com/sun/jna/LastErrorTest.java b/test/com/sun/jna/LastErrorTest.java
index d8ccde6a96..6ad3bccb01 100644
--- a/test/com/sun/jna/LastErrorTest.java
+++ b/test/com/sun/jna/LastErrorTest.java
@@ -12,29 +12,29 @@
*/
package com.sun.jna;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.Set;
-import java.util.HashSet;
import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
import junit.framework.TestCase;
//@SuppressWarnings("unused")
public class LastErrorTest extends TestCase {
- private static final Map OPTIONS = new HashMap() {{
- put(Library.OPTION_FUNCTION_MAPPER, new FunctionMapper() {
- @Override
- public String getFunctionName(NativeLibrary library, Method m) {
- if (m.getName().equals("noThrowLastError")
- || m.getName().equals("throwLastError")) {
- return "setLastError";
+ private static final Map OPTIONS =
+ Collections.singletonMap(Library.OPTION_FUNCTION_MAPPER, new FunctionMapper() {
+ @Override
+ public String getFunctionName(NativeLibrary library, Method m) {
+ if (m.getName().equals("noThrowLastError")
+ || m.getName().equals("throwLastError")) {
+ return "setLastError";
+ }
+ return m.getName();
}
- return m.getName();
- }
- });
- }};
+ });
public interface TestLibrary extends Library {
void setLastError(int code);
@@ -58,14 +58,17 @@ public void testLastErrorPerThreadStorage() throws Exception {
final TestLibrary lib = Native.loadLibrary("testlib", TestLibrary.class);
final int NTHREADS = 100;
final int[] errors = new int[NTHREADS];
- Set threads = new HashSet();
+ List threads = new ArrayList(NTHREADS);
for (int i=0;i < NTHREADS;i++) {
final int idx = i;
- Thread t = new Thread() { @Override
- public void run() {
- lib.setLastError(-idx-1);
- errors[idx] = Native.getLastError();
- }};
+ Thread t = new Thread("tLastErrorSetter-" + i) {
+ @Override
+ public void run() {
+ lib.setLastError(-idx-1);
+ errors[idx] = Native.getLastError();
+ }
+ };
+ t.setDaemon(true); // so we can stop the main thread if necessary
threads.add(t);
}
int EXPECTED = 42;
@@ -75,8 +78,10 @@ public void run() {
t.start();
}
for (Thread t : threads) {
- t.join();
+ t.join(TimeUnit.SECONDS.toMillis(7L));
+ assertFalse("Thread " + t.getName() + " still alive", t.isAlive());
}
+
assertEquals("Wrong error on main thread", EXPECTED, Native.getLastError());
for (int i=0;i < threads.size();i++) {
assertEquals("Wrong error on thread " + i, -i-1, errors[i]);
@@ -92,8 +97,7 @@ public void testThrowLastError() {
try {
lib.throwLastError(ERROR);
fail("Method should throw LastErrorException");
- }
- catch(LastErrorException e) {
+ } catch(LastErrorException e) {
assertEquals("Exception should contain error code", ERROR, e.getErrorCode());
assertTrue("Exception should include error message: '" + e.getMessage() + "'", e.getMessage().length() > 0);
}
@@ -107,8 +111,7 @@ public void testThrowLastErrorDirect() {
try {
lib.throwLastError(ERROR);
fail("Method should throw LastErrorException");
- }
- catch(LastErrorException e) {
+ } catch(LastErrorException e) {
assertEquals("Exception should contain error code", ERROR, e.getErrorCode());
assertTrue("Exception should include error message: " + e.getMessage(), e.getMessage().length() > 0);
}
diff --git a/test/com/sun/jna/MemoryTest.java b/test/com/sun/jna/MemoryTest.java
index 59614e5fd9..c292711793 100644
--- a/test/com/sun/jna/MemoryTest.java
+++ b/test/com/sun/jna/MemoryTest.java
@@ -1,19 +1,19 @@
/* Copyright (c) 2007 Timothy Wall, All Rights Reserved
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
- *
+ *
* This library 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 for more details.
+ * Lesser General Public License for more details.
*/
package com.sun.jna;
+import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
-import java.nio.Buffer;
import java.nio.ByteBuffer;
import junit.framework.TestCase;
@@ -23,23 +23,24 @@ public class MemoryTest extends TestCase implements GCWaits {
public void testAutoFreeMemory() throws Exception {
final boolean[] flag = { false };
Memory core = new Memory(10) {
+ @Override
protected void finalize() {
super.finalize();
flag[0] = true;
}
};
Pointer shared = core.share(0, 5);
- WeakReference ref = new WeakReference(core);
-
+ Reference ref = new WeakReference(core);
+
core = null;
System.gc();
- long start = System.currentTimeMillis();
assertFalse("Memory prematurely GC'd", flag[0]);
assertNotNull("Base memory GC'd while shared memory extant", ref.get());
// Avoid having IBM J9 prematurely nullify "shared"
shared.setInt(0, 0);
shared = null;
+ long start = System.currentTimeMillis();
System.gc();
Memory.purge();
for (int i=0;i < GC_WAITS && ref.get() != null;i++) {
@@ -47,7 +48,8 @@ protected void finalize() {
System.gc();
Memory.purge();
}
- assertNull("Memory not GC'd", ref.get());
+ long end = System.currentTimeMillis();
+ assertNull("Memory not GC'd after " + (end - start) + " millis", ref.get());
}
public void testShareMemory() {
@@ -122,8 +124,8 @@ public void testAvoidGCWithExtantBuffer() throws Exception {
m.clear();
ByteBuffer b = m.getByteBuffer(0, m.size());
- WeakReference ref = new WeakReference(m);
- WeakReference bref = new WeakReference(b);
+ Reference ref = new WeakReference(m);
+ Reference