os.arch
System property
- @param name from os.name
System property
- */
- public static String getNativeLibraryResourcePrefix(int osType, String arch, String name) {
- return Platform.getNativeLibraryResourcePrefix(osType, arch, name);
- }
-
/**
* Loads the JNA stub library.
* First tries jna.boot.library.path, then the system path, then from the
@@ -641,7 +626,7 @@ private static void loadNativeDispatchLibrary() {
StringTokenizer dirs = new StringTokenizer(bootPath, File.pathSeparator);
while (dirs.hasMoreTokens()) {
String dir = dirs.nextToken();
- File file = new File(new File(dir), System.mapLibraryName(libName));
+ File file = new File(new File(dir), System.mapLibraryName(libName).replace(".dylib", ".jnilib"));
String path = file.getAbsolutePath();
if (file.exists()) {
try {
@@ -699,10 +684,12 @@ private static void loadNativeDispatchLibrary() {
*/
private static void loadNativeDispatchLibraryFromClasspath() {
try {
- String prefix = "/com/sun/jna/" + getNativeLibraryResourcePrefix();
- File lib = extractFromResourcePath("jnidispatch", prefix, Native.class.getClassLoader());
+ String libName = "/com/sun/jna/" + Platform.RESOURCE_PREFIX + "/" + System.mapLibraryName("jnidispatch").replace(".dylib", ".jnilib");
+ File lib = extractFromResourcePath(libName, Native.class.getClassLoader());
if (lib == null) {
- throw new UnsatisfiedLinkError("Could not find JNA native support");
+ if (lib == null) {
+ throw new UnsatisfiedLinkError("Could not find JNA native support");
+ }
}
System.load(lib.getAbsolutePath());
nativeLibraryPath = lib.getAbsolutePath();
@@ -724,50 +711,53 @@ static boolean isUnpacked(File file) {
return file.getName().startsWith(JNA_TMPLIB_PREFIX);
}
- /** Attempt to extract a native library from the current resource path.
- * Expects native libraries to be stored under
- * the path returned by {@link #getNativeLibraryResourcePrefix()},
- * and reachable by the current thread context class loader.
- * @param name Base name of native library to extract
+ /** Attempt to extract a native library from the current resource path,
+ * using the current thread context class loader.
+ * @param name Base name of native library to extract. May also be an
+ * absolute resource path (i.e. starts with "/"), in which case the
+ * no transformations of the library name are performed. If only the base
+ * name is given, the resource path is attempted both with and without
+ * {@link Platform#RESOURCE_PREFIX}, after mapping the library name via
+ * {@link NativeLibrary#mapSharedLibraryName(String)}.
* @return File indicating extracted resource on disk
* @throws IOException if resource not found
*/
- static File extractFromResourcePath(String name) throws IOException {
- return extractFromResourcePath(name, "/" + getNativeLibraryResourcePrefix(), Thread.currentThread().getContextClassLoader());
- }
-
- /** Attempt to extract a native library from the current resource path.
- * Expects native libraries to be stored under
- * the path returned by {@link #getNativeLibraryResourcePrefix(int, String,
- * String)}.
- * @param name Base name of native library to extract
+ public static File extractFromResourcePath(String name) throws IOException {
+ return extractFromResourcePath(name, null);
+ }
+
+ /** Attempt to extract a native library from the resource path using the
+ * given class loader.
+ * @param name Base name of native library to extract. May also be an
+ * absolute resource path (i.e. starts with "/"), in which case the
+ * no transformations of the library name are performed. If only the base
+ * name is given, the resource path is attempted both with and without
+ * {@link Platform#RESOURCE_PREFIX}, after mapping the library name via
+ * {@link NativeLibrary#mapSharedLibraryName(String)}.
* @param loader Class loader to use to load resources
- * @param resourcePrefix prefix to use when looking for the resource
* @return File indicating extracted resource on disk
* @throws IOException if resource not found
*/
- static File extractFromResourcePath(String name, String resourcePrefix, ClassLoader loader) throws IOException {
- String libname = name.startsWith("/") ? name : System.mapLibraryName(name);
- String resourcePath = name.startsWith("/") ? name : resourcePrefix + "/" + libname;
+ public static File extractFromResourcePath(String name, ClassLoader loader) throws IOException {
+ if (loader == null) {
+ loader = Thread.currentThread().getContextClassLoader();
+ }
+ String libname = name.startsWith("/") ? name : NativeLibrary.mapSharedLibraryName(name);
+ String resourcePath = name.startsWith("/") ? name : Platform.RESOURCE_PREFIX + "/" + libname;
if (resourcePath.startsWith("/")) {
resourcePath = resourcePath.substring(1);
}
URL url = loader.getResource(resourcePath);
-
- // User libraries will have '.dylib'
- if (url == null && Platform.isMac()) {
- if (resourcePath.endsWith(".jnilib")) {
- resourcePath = resourcePath.substring(0, resourcePath.lastIndexOf(".jnilib")) + ".dylib";
- }
- // Ugly hack for OpenJDK (soylatte) - JNI libs use the usual
- // .dylib extension
- else if (resourcePath.endsWith(".dylib")) {
- resourcePath = resourcePath.substring(0, resourcePath.lastIndexOf(".dylib")) + ".jnilib";
- }
- url = loader.getResource(resourcePath);
+ if (url == null && resourcePath.startsWith(Platform.RESOURCE_PREFIX)) {
+ // If not found with the standard resource prefix, try without it
+ url = loader.getResource(libname);
}
if (url == null) {
- throw new IOException("Native library (" + resourcePath + ") not found in resource path (" + System.getProperty("java.class.path") + ")");
+ String path = System.getProperty("java.class.path");
+ if (loader instanceof URLClassLoader) {
+ path = Arrays.asList(((URLClassLoader)loader).getURLs()).toString();
+ }
+ throw new IOException("Native library (" + resourcePath + ") not found in resource path (" + path + ")");
}
File lib = null;
@@ -1298,13 +1288,17 @@ private static int getConversion(Class type, TypeMapper mapper) {
/** When called from a class static initializer, maps all native methods
* found within that class to native libraries via the JNA raw calling
- * interface.
+ * interface. Uses the class loader of the given class to search for the
+ * native library in the resource path if it is not found in the system
+ * library load path or jna.library.path
.
* @param cls Class with native methods to register
* @param libName name of or path to native library to which functions
* should be bound
*/
public static void register(Class cls, String libName) {
- register(cls, NativeLibrary.getInstance(libName));
+ Map options = new HashMap();
+ options.put(Library.OPTION_CLASSLOADER, cls.getClassLoader());
+ register(cls, NativeLibrary.getInstance(libName, options));
}
/** When called from a class static initializer, maps all native methods
@@ -1548,7 +1542,7 @@ public static void main(String[] args) {
System.out.println("Version: " + version);
System.out.println(" Native: " + getNativeVersion() + " ("
+ getAPIChecksum() + ")");
- System.out.println(" Prefix: " + getNativeLibraryResourcePrefix());
+ System.out.println(" Prefix: " + Platform.RESOURCE_PREFIX);
}
/** Free the given callback trampoline. */
diff --git a/src/com/sun/jna/NativeLibrary.java b/src/com/sun/jna/NativeLibrary.java
index 2abd0073c3..83003ac004 100644
--- a/src/com/sun/jna/NativeLibrary.java
+++ b/src/com/sun/jna/NativeLibrary.java
@@ -1,5 +1,5 @@
/* Copyright (c) 2007 Wayne Meissner, All Rights Reserved
- * Copyright (c) 2007, 2008, 2009 Timothy Wall, All Rights Reserved
+ * Copyright (c) 2007-20013 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
@@ -54,7 +54,7 @@
* installed on the classpath under
* ${os-prefix}/LIBRARY_FILENAME
, where ${os-prefix}
* is the OS/Arch prefix returned by {@link
- * Native#getNativeLibraryResourcePrefix()}. If bundled in a jar file, the
+ * Platform#getNativeLibraryResourcePrefix()}. If bundled in a jar file, the
* resource will be extracted to jna.tmpdir
for loading, and
* later removed (but only if jna.nounpack
is false or not set).
*
@@ -119,6 +119,7 @@ private static int openFlags(Map options) {
}
private static NativeLibrary loadLibrary(String libraryName, Map options) {
+ boolean isAbsolutePath = new File(libraryName).isAbsolute();
List searchPath = new LinkedList();
int openFlags = openFlags(options);
@@ -187,7 +188,8 @@ else if (Platform.isLinux()) {
}
}
// Search framework libraries on OS X
- else if (Platform.isMac() && !libraryName.endsWith(".dylib")) {
+ else if (Platform.isMac()
+ && !libraryName.endsWith(".dylib")) {
libraryPath = matchFramework(libraryName);
if (libraryPath != null) {
try {
@@ -197,7 +199,7 @@ else if (Platform.isMac() && !libraryName.endsWith(".dylib")) {
}
}
// Try the same library with a "lib" prefix
- else if (Platform.isWindows()) {
+ else if (Platform.isWindows() && !isAbsolutePath) {
libraryPath = findLibraryPath("lib" + libraryName, searchPath);
try { handle = Native.open(libraryPath, openFlags); }
catch(UnsatisfiedLinkError e2) { e = e2; }
@@ -206,7 +208,7 @@ else if (Platform.isWindows()) {
// path, using the current context class loader.
if (handle == 0) {
try {
- File embedded = Native.extractFromResourcePath(libraryName);
+ File embedded = Native.extractFromResourcePath(libraryName, (ClassLoader)options.get(Library.OPTION_CLASSLOADER));
handle = Native.open(embedded.getAbsolutePath());
// Don't leave temporary files around
if (Native.isUnpacked(embedded)) {
@@ -254,7 +256,7 @@ static String matchFramework(String libraryName) {
private String getLibraryName(String libraryName) {
String simplified = libraryName;
final String BASE = "---";
- String template = mapLibraryName(BASE);
+ String template = mapSharedLibraryName(BASE);
int prefixEnd = template.indexOf(BASE);
if (prefixEnd > 0 && simplified.startsWith(template.substring(0, prefixEnd))) {
simplified = simplified.substring(prefixEnd);
@@ -283,6 +285,28 @@ public static final NativeLibrary getInstance(String libraryName) {
return getInstance(libraryName, Collections.EMPTY_MAP);
}
+ /**
+ * Returns an instance of NativeLibrary for the specified name.
+ * The library is loaded if not already loaded. If already loaded, the
+ * existing instance is returned.
+ * More than one name may map to the same NativeLibrary instance; only
+ * a single instance will be provided for any given unique file path.
+ *
+ * @param libraryName The library name to load.
+ * This can be short form (e.g. "c"),
+ * an explicit version (e.g. "libc.so.6"), or
+ * the full path to the library (e.g. "/lib/libc.so.6").
+ * @param classLoader The class loader to use to load the native library.
+ * This only affects library loading when the native library is
+ * included somewhere in the classpath, either bundled in a jar file
+ * 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);
+ }
+
/**
* Returns an instance of NativeLibrary for the specified name.
* The library is loaded if not already loaded. If already loaded, the
@@ -306,7 +330,7 @@ public static final NativeLibrary getInstance(String libraryName, Map options) {
// Use current process to load libraries we know are already
// loaded by the VM to ensure we get the correct version
- if ((Platform.isLinux() || Platform.isAix())
+ if ((Platform.isLinux() || Platform.isAIX())
&& Platform.C_LIBRARY_NAME.equals(libraryName)) {
libraryName = null;
}
@@ -548,7 +572,7 @@ private static String findLibraryPath(String libName, List searchPath) {
//
// Get the system name for the library (e.g. libfoo.so)
//
- String name = mapLibraryName(libName);
+ String name = mapSharedLibraryName(libName);
// Search in the JNA paths for it
for (Iterator it = searchPath.iterator(); it.hasNext(); ) {
@@ -575,8 +599,12 @@ private static String findLibraryPath(String libName, List searchPath) {
//
return name;
}
- private static String mapLibraryName(String libName) {
+ /** Similar to {@link System#mapLibraryName}, except that it maps to
+ standard shared library formats rather than specifically JNI formats.
+ @param libName base (undecorated) name of library
+ */
+ static String mapSharedLibraryName(String libName) {
if (Platform.isMac()) {
if (libName.startsWith("lib")
&& (libName.endsWith(".dylib")
@@ -598,7 +626,7 @@ else if (Platform.isLinux()) {
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;
}
diff --git a/src/com/sun/jna/Platform.java b/src/com/sun/jna/Platform.java
index 878afa7f79..3367dd0729 100644
--- a/src/com/sun/jna/Platform.java
+++ b/src/com/sun/jna/Platform.java
@@ -118,9 +118,13 @@ public static final boolean isAndroid() {
public static final boolean isLinux() {
return osType == LINUX;
}
- public static final boolean isAix() {
+ public static final boolean isAIX() {
return osType == AIX;
}
+ /** @deprecated */
+ public static final boolean isAix() {
+ return isAIX();
+ }
public static final boolean isWindowsCE() {
return osType == WINDOWSCE;
}
diff --git a/src/com/sun/jna/Structure.java b/src/com/sun/jna/Structure.java
index a17efa1c74..8431799c17 100644
--- a/src/com/sun/jna/Structure.java
+++ b/src/com/sun/jna/Structure.java
@@ -114,7 +114,7 @@ public interface ByReference { }
String arch = System.getProperty("os.arch").toLowerCase();
isPPC = "ppc".equals(arch) || "powerpc".equals(arch);
isSPARC = "sparc".equals(arch);
- isARM = arch.startsWith("arm");
+ isARM = arch.startsWith("arm");
}
/** Use the platform default alignment. */
@@ -137,7 +137,7 @@ public interface ByReference { }
isSPARC
|| ((isPPC || isARM)
&& (Platform.isLinux() || Platform.isAndroid()))
- || Platform.isAix()
+ || Platform.isAIX()
? 8 : Native.LONG_SIZE;
protected static final int CALCULATE_SIZE = -1;
static final Map layoutInfo = new WeakHashMap();
@@ -216,7 +216,7 @@ TypeMapper getTypeMapper() {
return typeMapper;
}
- /** Initialize the type mapper for this structure.
+ /** Initialize the type mapper for this structure.
* If null
, the default mapper for the
* defining class will be used.
*/
@@ -871,7 +871,7 @@ private List sort(Collection c) {
return list;
}
- /** Returns all field names (sorted) provided so far by
+ /** Returns all field names (sorted) provided so far by
{@link #getFieldOrder}
@param force set if results are required immediately
@return null if not yet able to provide fields, and force is false.
@@ -899,7 +899,7 @@ protected List getFields(boolean force) {
Set orderedNames = new HashSet(fieldOrder);
if (!orderedNames.equals(names)) {
- throw new Error("Structure.getFieldOrder() on " + getClass()
+ throw new Error("Structure.getFieldOrder() on " + getClass()
+ " returns names ("
+ sort(fieldOrder)
+ ") which do not match declared field names ("
@@ -991,6 +991,8 @@ private static class LayoutInfo {
private int alignType = ALIGN_DEFAULT;
private TypeMapper typeMapper;
private boolean variable;
+ // For unions only, field on which the union FFI type info is based
+ private StructField typeInfoField;
}
private void validateField(String name, Class type) {
@@ -1029,7 +1031,6 @@ private void validateFields() {
members.
*/
private LayoutInfo deriveLayout(boolean force, boolean avoidFFIType) {
-
int calculatedSize = 0;
List fields = getFields(force);
if (fields == null) {
@@ -1139,11 +1140,24 @@ else if (writeConverter != null || readConverter != null) {
if ((calculatedSize % fieldAlignment) != 0) {
calculatedSize += fieldAlignment - (calculatedSize % fieldAlignment);
}
- structField.offset = calculatedSize;
- calculatedSize += structField.size;
+ if (this instanceof Union) {
+ structField.offset = 0;
+ calculatedSize = Math.max(calculatedSize, structField.size);
+ }
+ else {
+ structField.offset = calculatedSize;
+ calculatedSize += structField.size;
+ }
// Save the field in our list
info.fields.put(structField.name, structField);
+
+ if (info.typeInfoField == null
+ || info.typeInfoField.size < structField.size
+ || (info.typeInfoField.size == structField.size
+ && Structure.class.isAssignableFrom(structField.type))) {
+ info.typeInfoField = structField;
+ }
}
if (calculatedSize > 0) {
@@ -1283,9 +1297,9 @@ else if (actualAlignType == ALIGN_GNUC) {
if (!isFirstElement || !(Platform.isMac() && isPPC)) {
alignment = Math.min(MAX_GNUC_ALIGNMENT, alignment);
}
- if (!isFirstElement && Platform.isAix() && (type.getName().equals("double"))) {
+ if (!isFirstElement && Platform.isAIX() && (type.getName().equals("double"))) {
alignment = 4;
- }
+ }
}
return alignment;
}
@@ -1504,7 +1518,7 @@ Pointer getTypeInfo() {
This is typically most effective when a native call populates a large
structure and you only need a few fields out of it. After the native
call you can call {@link #readField(String)} on only the fields of
- interest.
+ interest.
*/
public void setAutoSynch(boolean auto) {
setAutoRead(auto);
@@ -1544,7 +1558,7 @@ static Pointer getTypeInfo(Object obj) {
return FFIType.get(obj);
}
- /** Called from native code only; same as {@link
+ /** Called from native code only; same as {@link
* #newInstance(Class,Pointer)}, except that it additionally performs
* {@link #conditionalAutoRead()}.
*/
@@ -1619,6 +1633,20 @@ public static Structure newInstance(Class type) throws IllegalArgumentException
}
}
+ /** Keep track of the largest aggregate field of the union to use for
+ * FFI type information.
+ */
+ StructField typeInfoField() {
+ LayoutInfo info;
+ synchronized(layoutInfo) {
+ info = (LayoutInfo)layoutInfo.get(getClass());
+ }
+ if (info != null) {
+ return info.typeInfoField;
+ }
+ return null;
+ }
+
static class StructField extends Object {
public String name;
public Class type;
@@ -1704,7 +1732,7 @@ private FFIType(Structure ref) {
ref.ensureAllocated(true);
if (ref instanceof Union) {
- StructField sf = ((Union)ref).biggestField;
+ StructField sf = ((Union)ref).typeInfoField();
els = new Pointer[] {
get(ref.getFieldValue(sf.field), sf.type),
null,
diff --git a/src/com/sun/jna/Union.java b/src/com/sun/jna/Union.java
index d899e81ba2..d08b50d482 100644
--- a/src/com/sun/jna/Union.java
+++ b/src/com/sun/jna/Union.java
@@ -1,14 +1,14 @@
/* Copyright (c) 2007-2012 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;
@@ -20,18 +20,17 @@
/** Represents a native union. When writing to native memory, the field
* corresponding to the type passed to {@link #setType} will be written
* to native memory. Upon reading from native memory, Structure, String,
- * or WString fields will not be initialized unless they are
+ * or WString fields will not be initialized unless they are
* the current field as identified by a call to {@link #setType}. The current
* field is always unset by default to avoid accidentally attempting to read
- * a field that is not valid. In the case of a String, for instance, an
+ * a field that is not valid. In the case of a String, for instance, an
* invalid pointer may result in a memory fault when attempting to initialize
- * the String.
+ * the String.
*/
public abstract class Union extends Structure {
private StructField activeField;
- StructField biggestField;
-
- /** Create a Union whose size and alignment will be calculated
+
+ /** Create a Union whose size and alignment will be calculated
* automatically.
*/
protected Union() { }
@@ -65,10 +64,10 @@ protected List getFieldOrder() {
return list;
}
- /** Indicates by type which field will be used to write to native memory.
+ /** Indicates by type which field will be used to write to native memory.
* If there are multiple fields of the same type, use {@link
* #setType(String)} instead with the field name.
- * @throws IllegalArgumentException if the type does not correspond to
+ * @throws IllegalArgumentException if the type does not correspond to
* any declared union field.
*/
public void setType(Class type) {
@@ -82,7 +81,7 @@ public void setType(Class type) {
}
throw new IllegalArgumentException("No field of type " + type + " in " + this);
}
-
+
/**
* Indicates which field will be used to write to native memory.
* @throws IllegalArgumentException if the name does not correspond to
@@ -199,11 +198,11 @@ void writeField(StructField field) {
}
/** Avoid reading pointer-based fields and structures unless explicitly
- * selected. Structures may contain pointer-based fields which can
+ * selected. Structures may contain pointer-based fields which can
* crash the VM if not properly initialized.
*/
Object readField(StructField field) {
- if (field == activeField
+ if (field == activeField
|| (!Structure.class.isAssignableFrom(field.type)
&& !String.class.isAssignableFrom(field.type)
&& !WString.class.isAssignableFrom(field.type))) {
@@ -211,56 +210,12 @@ Object readField(StructField field) {
}
// Field not accessible
// TODO: read structure, to the extent possible; need a "recursive"
- // flag to "read"
+ // flag to "read" to indicate we want to avoid pointer-based fields
return null;
}
-
- /** Adjust the size to be the size of the largest element, and ensure
- * all fields begin at offset zero.
- */
- int calculateSize(boolean force, boolean avoidFFIType) {
- int size = super.calculateSize(force, avoidFFIType);
- if (size != CALCULATE_SIZE) {
- int fsize = 0;
- for (Iterator i=fields().values().iterator();i.hasNext();) {
- StructField f = (StructField)i.next();
- f.offset = 0;
- if (f.size > fsize
- // Prefer aggregate types to simple types, since they
- // will have more complex packing rules (some platforms
- // have specific methods for packing small structs into
- // registers, which may not match the packing of bytes
- // for a primitive type).
- || (f.size == fsize
- && Structure.class.isAssignableFrom(f.type))) {
- fsize = f.size;
- biggestField = f;
- }
- }
- size = calculateAlignedSize(fsize);
- if (size > 0) {
- // Update native FFI type information, if needed
- if (this instanceof ByValue && !avoidFFIType) {
- getTypeInfo();
- }
- }
- }
- return size;
- }
+
/** All fields are considered the "first" element. */
protected int getNativeAlignment(Class type, Object value, boolean isFirstElement) {
return super.getNativeAlignment(type, value, true);
}
-
- /** Avoid calculating type information until we know our biggest field.
- * Return type information for the largest field to ensure all available
- * bits are used.
- */
- Pointer getTypeInfo() {
- if (biggestField == null) {
- // Not calculated yet
- return null;
- }
- return super.getTypeInfo();
- }
}
diff --git a/src/com/sun/jna/Version.java b/src/com/sun/jna/Version.java
old mode 100755
new mode 100644
diff --git a/src/com/sun/jna/overview.html b/src/com/sun/jna/overview.html
index 40a751b381..e66bd1b14c 100644
--- a/src/com/sun/jna/overview.html
+++ b/src/com/sun/jna/overview.html
@@ -128,8 +128,9 @@
The search path for loaded native libraries may be modified by
-setting jna.library.path
and a few other properties. See {@link
-com.sun.jna.NativeLibrary} for details.
+setting jna.library.path
and a few other properties. You may
+also bundle native libraries in a jar file and have JNA automatically extract
+them for loading. See {@link com.sun.jna.NativeLibrary} for details.
Table of Contents diff --git a/test/com/sun/jna/CallbacksTest.java b/test/com/sun/jna/CallbacksTest.java index 612751b950..306141149e 100644 --- a/test/com/sun/jna/CallbacksTest.java +++ b/test/com/sun/jna/CallbacksTest.java @@ -1088,7 +1088,7 @@ public void callback() { 1, threads.size()); } - // Thread object is never GC'd on linux-amd64 and (sometimes) win32-amd64 + // Thread object is never GC'd on linux-amd64 and darwin-amd64 (w/openjdk7) public void testAttachedThreadCleanupOnExit() throws Exception { final Set threads = new HashSet(); final int[] called = { 0 }; diff --git a/test/com/sun/jna/DirectTest.java b/test/com/sun/jna/DirectTest.java index 2ecbb19548..7fa5a28b01 100644 --- a/test/com/sun/jna/DirectTest.java +++ b/test/com/sun/jna/DirectTest.java @@ -22,20 +22,13 @@ import java.net.URLClassLoader; //@SuppressWarnings("unused") -public class DirectTest extends TestCase { - - private static final String BUILDDIR = - System.getProperty("jna.builddir", - "build" + (Platform.is64Bit() ? "-d64" : "")); +public class DirectTest extends TestCase implements Paths { private static class JNI { static { - String path = BUILDDIR + "/native/" + System.mapLibraryName("testlib");; + String path = TESTPATH + NativeLibrary.mapSharedLibraryName("testlib"); if (!new File(path).isAbsolute()) { - path = System.getProperty("user.dir") + "/" + path; - } - if (path.endsWith(".jnilib")) { - path = path.replace(".jnilib", ".dylib"); + path = new File(path).getAbsolutePath(); } System.load(path); } @@ -117,7 +110,7 @@ public TestLoader() throws MalformedURLException { : new URL[] { new File(BUILDDIR + "/classes").toURI().toURL(), new File(BUILDDIR + "/test-classes").toURI().toURL(), - }, null); + }, new CloverLoader()); } protected Class findClass(String name) throws ClassNotFoundException { String boot = System.getProperty("jna.boot.library.path"); @@ -132,6 +125,7 @@ protected Class findClass(String name) throws ClassNotFoundException { } } + // Fails under clover public void testRegisterMethods() throws Exception { // Use a dedicated class loader to ensure the class can be gc'd String name = "com.sun.jna.DirectTest$MathLibrary"; diff --git a/test/com/sun/jna/JNAUnloadTest.java b/test/com/sun/jna/JNAUnloadTest.java index 1c34258f31..6250cb03f0 100644 --- a/test/com/sun/jna/JNAUnloadTest.java +++ b/test/com/sun/jna/JNAUnloadTest.java @@ -18,25 +18,22 @@ import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; +import java.util.Properties; import junit.framework.TestCase; /** Test loading and unloading native support from various locations. Note * that no JNI classes are directly referenced in these tests. */ -public class JNAUnloadTest extends TestCase { +public class JNAUnloadTest extends TestCase implements Paths { - private static final String BUILDDIR = - System.getProperty("jna.builddir", "build" - + (Platform.is64Bit() ? "-d64" : "")); - private class TestLoader extends URLClassLoader { public TestLoader(boolean fromJar) throws MalformedURLException { super(new URL[] { Platform.isWindowsCE() ? new File("/Storage Card/" + (fromJar ? "jna.jar" : "test.jar")).toURI().toURL() : new File(BUILDDIR + (fromJar ? "/jna.jar" : "/classes")).toURI().toURL(), - }, null); + }, new CloverLoader()); if (fromJar) { assertJarExists(); } @@ -58,7 +55,7 @@ protected Class findClass(String name) throws ClassNotFoundException { } protected void assertJarExists() { - File jar = new File((Platform.isWindowsCE() ? "/Storage Card" : BUILDDIR) + "/jna.jar"); + File jar = new File(JNAJAR); if (!jar.exists()) { throw new Error("Expected JNA jar file at " + jar + " is missing"); } @@ -66,8 +63,8 @@ protected void assertJarExists() { protected void assertLibraryExists() { String osPrefix = Platform.getNativeLibraryResourcePrefix(); - String name = System.mapLibraryName("jnidispatch"); - File lib = new File((Platform.isWindowsCE() ? "/Storage Card" : BUILDDIR + "/classes") + "/com/sun/jna/" + osPrefix + "/" + name); + String name = System.mapLibraryName("jnidispatch").replace(".dylib", ".jnilib"); + File lib = new File(CLASSES + "/com/sun/jna/" + osPrefix + "/" + name); if (!lib.exists()) { throw new Error("Expected JNA library at " + lib + " is missing"); } @@ -103,7 +100,7 @@ public void testAvoidResourcePathLoading() throws Exception { } } - // Fails under clover + // GC Fails under clover public void testLoadAndUnloadFromJar() throws Exception { ClassLoader loader = new TestLoader(true); Class cls = Class.forName("com.sun.jna.Native", true, loader); @@ -157,7 +154,7 @@ public void testLoadAndUnloadFromJar() throws Exception { } } - // Fails under clover and OpenJDK(linux/ppc) + // GC Fails under clover and OpenJDK(linux/ppc) public void testLoadAndUnloadFromResourcePath() throws Exception { ClassLoader loader = new TestLoader(false); Class cls = Class.forName("com.sun.jna.Native", true, loader); @@ -209,6 +206,23 @@ public void testLoadAndUnloadFromResourcePath() throws Exception { } } + public void testLoadFromUnicodePath() throws Exception { + final String UNICODE = getName() + "-\u0444\u043b\u0441\u0432\u0443"; + File tmpdir = Native.getTempDir(); + File unicodeDir = new File(tmpdir, UNICODE); + unicodeDir.mkdirs(); + Properties props = System.getProperties(); + try { + System.setProperty("jna.tmpdir", unicodeDir.getAbsolutePath()); + ClassLoader loader = new TestLoader(true); + Class cls = Class.forName("com.sun.jna.Native", true, loader); + assertEquals("Wrong class loader", loader, cls.getClassLoader()); + } + finally { + System.setProperties(props); + } + } + public static void main(String[] args) { junit.textui.TestRunner.run(JNAUnloadTest.class); } diff --git a/test/com/sun/jna/LastErrorTest.java b/test/com/sun/jna/LastErrorTest.java index c0283fff8e..a900428308 100644 --- a/test/com/sun/jna/LastErrorTest.java +++ b/test/com/sun/jna/LastErrorTest.java @@ -75,10 +75,10 @@ public void testLastErrorPerThreadStorage() throws Exception { } } + private final int ERROR = Platform.isWindows() ? 1 : -1; public void testThrowLastError() { TestLibrary lib = (TestLibrary)Native.loadLibrary("testlib", TestLibrary.class, OPTIONS); - final int ERROR = -1; lib.noThrowLastError(ERROR); assertEquals("Last error not preserved", ERROR, Native.getLastError()); try { @@ -87,14 +87,13 @@ public void testThrowLastError() { } catch(LastErrorException e) { assertEquals("Exception should contain error code", ERROR, e.getErrorCode()); - assertTrue("Exception should include error message: " + e.getMessage(), e.getMessage().length() > 10); + assertTrue("Exception should include error message: '" + e.getMessage() + "'", e.getMessage().length() > 0); } } public void testThrowLastErrorDirect() { TestLibrary lib = new DirectTestLibrary(); - final int ERROR = -1; lib.noThrowLastError(ERROR); assertEquals("Last error not preserved", ERROR, Native.getLastError()); try { @@ -103,7 +102,7 @@ public void testThrowLastErrorDirect() { } catch(LastErrorException e) { assertEquals("Exception should contain error code", ERROR, e.getErrorCode()); - assertTrue("Exception should include error message: " + e.getMessage(), e.getMessage().length() > 10); + assertTrue("Exception should include error message: " + e.getMessage(), e.getMessage().length() > 0); } } diff --git a/test/com/sun/jna/LibraryLoadTest.java b/test/com/sun/jna/LibraryLoadTest.java index 5f4a00a843..9d44a46620 100644 --- a/test/com/sun/jna/LibraryLoadTest.java +++ b/test/com/sun/jna/LibraryLoadTest.java @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2009 Timothy Wall, All Rights Reserved +/* Copyright (c) 2007-20013 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 @@ -19,14 +19,20 @@ import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; import junit.framework.TestCase; -public class LibraryLoadTest extends TestCase { +public class LibraryLoadTest extends TestCase implements Paths { - private static final String BUILDDIR = - System.getProperty("jna.builddir", "build" - + (Platform.is64Bit() ? "-d64" : "")); + private class TestLoader extends URLClassLoader { + public TestLoader(File path) throws MalformedURLException { + super(new URL[] { path.toURI().toURL(), }, + new CloverLoader()); + } + } public void testLoadJNALibrary() { assertTrue("Pointer size should never be zero", Pointer.SIZE > 0); @@ -52,33 +58,33 @@ public void testLoadAWTAfterJNA() { } } - public interface TestLibrary extends Library { - } - public void testLoadFromJNALibraryPath() { + // Tests are already configured to load from this path NativeLibrary.getInstance("testlib"); } - public void testLoadFromClasspath() { - NativeLibrary.getInstance("testlib-path"); + public void testLoadFromClasspath() throws MalformedURLException { + NativeLibrary.getInstance("testlib-path", new TestLoader(new File(TESTPATH))); } - public void testLoadFromClasspathAbsolute() { - String name = System.mapLibraryName("testlib-path").replace(".jnilib", ".dylib"); - NativeLibrary.getInstance("/" + Platform.RESOURCE_PREFIX + "/" + name); + public void testLoadFromClasspathAbsolute() throws MalformedURLException { + String name = NativeLibrary.mapSharedLibraryName("testlib-path"); + NativeLibrary.getInstance("/" + name, new TestLoader(new File(TESTPATH))); } - public void testLoadFromJar() { - NativeLibrary.getInstance("testlib-jar"); + public void testLoadFromJar() throws MalformedURLException { + NativeLibrary.getInstance("testlib-jar", new TestLoader(new File(TESTJAR))); } - public void testLoadFromJarAbsolute() { - String name = System.mapLibraryName("testlib-jar").replace(".jnilib", ".dylib"); - NativeLibrary.getInstance("/" + Platform.RESOURCE_PREFIX + "/" + name); + public void testLoadFromJarAbsolute() throws MalformedURLException { + String name = NativeLibrary.mapSharedLibraryName("testlib-jar"); + NativeLibrary.getInstance("/" + name, new TestLoader(new File(TESTJAR))); } - public void testLoadExplicitAbsolutePath() { - NativeLibrary.getInstance(new File(BUILDDIR + "/native/testlib-truncated").getAbsolutePath()); + public void testLoadExplicitAbsolutePath() throws MalformedURLException { + // windows requires ".dll" suffix + String name = "testlib-truncated" + (Platform.isWindows() ? ".dll" : ""); + NativeLibrary.getInstance(new File(TESTPATH, name).getAbsolutePath()); } public static interface CLibrary extends Library { @@ -98,7 +104,6 @@ public void testLoadCLibrary() { load(); } - private static final String UNICODE = "\u0444\u043b\u0441\u0432\u0443"; private void copy(File src, File dst) throws Exception { FileInputStream is = new FileInputStream(src); FileOutputStream os = new FileOutputStream(dst); @@ -116,34 +121,66 @@ private void copy(File src, File dst) throws Exception { } public void testLoadLibraryWithUnicodeName() throws Exception { - String tmp = System.getProperty("java.io.tmpdir"); - String libName = System.mapLibraryName("jnidispatch"); - File src = new File(BUILDDIR + "/native", libName); + File tmpdir = Native.getTempDir(); + String libName = NativeLibrary.mapSharedLibraryName("testlib"); + File src = new File(TESTPATH, libName); if (Platform.isWindowsCE()) { src = new File("/Storage Card", libName); } assertTrue("Expected JNA native library at " + src + " is missing", src.exists()); - String newLibName = UNICODE; - if (libName.startsWith("lib")) - newLibName = "lib" + newLibName; - int dot = libName.lastIndexOf("."); - if (dot != -1) { - if (Platform.isMac()) { - newLibName += ".dylib"; + final String UNICODE = "\u0444\u043b\u0441\u0432\u0443"; + + String newLibName = libName.replace("testlib", UNICODE); + File dst = new File(tmpdir, newLibName); + dst.deleteOnExit(); + copy(src, dst); + NativeLibrary.getInstance(UNICODE, new TestLoader(tmpdir)); + } + + public void testLoadFrameworkLibrary() { + if (Platform.isMac()) { + final String PATH = "/System/Library/Frameworks/CoreServices.framework"; + assertTrue("CoreServices not present on this setup, expected at " + PATH, new File(PATH).exists()); + try { + NativeLibrary lib = NativeLibrary.getInstance("CoreServices"); + assertNotNull("CoreServices not found", lib); } - else { - newLibName += libName.substring(dot, libName.length()); + catch(UnsatisfiedLinkError e) { + fail("Should search /System/Library/Frameworks"); } } - File dst = new File(tmp, newLibName); - dst.deleteOnExit(); - copy(src, dst); - NativeLibrary.addSearchPath(UNICODE, tmp); - NativeLibrary nl = NativeLibrary.getInstance(UNICODE); - nl.dispose(); } + public void testLoadFrameworkLibraryAbsolute() { + if (Platform.isMac()) { + final String PATH = "/System/Library/Frameworks/CoreServices"; + final String FRAMEWORK = PATH + ".framework"; + assertTrue("CoreServices not present on this setup, expected at " + FRAMEWORK, new File(FRAMEWORK).exists()); + try { + NativeLibrary lib = NativeLibrary.getInstance(PATH); + assertNotNull("CoreServices not found", lib); + } + catch(UnsatisfiedLinkError e) { + fail("Should try FRAMEWORK.framework/FRAMEWORK if the absolute framework (truncated) path given exists: " + e); + } + } + } + + public void testLoadFrameworkLibraryAbsoluteFull() { + if (Platform.isMac()) { + final String PATH = "/System/Library/Frameworks/CoreServices.framework/CoreServices"; + assertTrue("CoreServices not present on this setup, expected at " + PATH, new File(PATH).exists()); + try { + NativeLibrary lib = NativeLibrary.getInstance(PATH); + assertNotNull("CoreServices not found", lib); + } + catch(UnsatisfiedLinkError e) { + fail("Should try FRAMEWORK verbatim if the absolute path given exists: " + e); + } + } + } + public void testHandleObjectMethods() { CLibrary lib = (CLibrary)load(); String method = "toString"; diff --git a/test/com/sun/jna/NativeLibraryTest.java b/test/com/sun/jna/NativeLibraryTest.java index 73690ad51a..72d5d1dff9 100644 --- a/test/com/sun/jna/NativeLibraryTest.java +++ b/test/com/sun/jna/NativeLibraryTest.java @@ -26,6 +26,31 @@ public class NativeLibraryTest extends TestCase { public static interface TestLibrary extends Library { int callCount(); } + + public void testMapSharedLibraryName() { + final Object[][] MAPPINGS = { + { Platform.MAC, "lib", ".dylib" }, + { Platform.LINUX, "lib", ".so" }, + { Platform.WINDOWS, "", ".dll" }, + { Platform.SOLARIS, "lib", ".so" }, + { Platform.FREEBSD, "lib", ".so" }, + { Platform.OPENBSD, "lib", ".so" }, + { Platform.WINDOWSCE, "", ".dll" }, + { Platform.AIX, "lib", ".a" }, + { Platform.ANDROID, "lib", ".so" }, + { Platform.GNU, "lib", ".so" }, + { Platform.KFREEBSD, "lib", ".so" }, + }; + for (int i=0;i < MAPPINGS.length;i++) { + int osType = ((Integer)MAPPINGS[i][0]).intValue(); + if (osType == Platform.getOSType()) { + assertEquals("Wrong shared library name mapping", + MAPPINGS[i][1] + "testlib" + MAPPINGS[i][2], + NativeLibrary.mapSharedLibraryName("testlib")); + } + } + } + public void testGCNativeLibrary() throws Exception { NativeLibrary lib = NativeLibrary.getInstance("testlib"); WeakReference ref = new WeakReference(lib); @@ -116,42 +141,6 @@ public void testFunctionHoldsLibraryReference() throws Exception { assertNull("Library not GC'd", ref.get()); } - public void testLoadFrameworkLibrary() { - if (Platform.isMac()) { - try { - NativeLibrary lib = NativeLibrary.getInstance("CoreServices"); - assertNotNull("CoreServices not found", lib); - } - catch(UnsatisfiedLinkError e) { - fail("Should search /System/Library/Frameworks"); - } - } - } - - public void testLoadFrameworkLibraryAbsolute() { - if (Platform.isMac()) { - try { - NativeLibrary lib = NativeLibrary.getInstance("/System/Library/Frameworks/CoreServices"); - assertNotNull("CoreServices not found", lib); - } - catch(UnsatisfiedLinkError e) { - fail("Should try FRAMEWORK.framework/FRAMEWORK if absolute and exists"); - } - } - } - - public void testLoadFrameworkLibraryAbsoluteFull() { - if (Platform.isMac()) { - try { - NativeLibrary lib = NativeLibrary.getInstance("/System/Library/Frameworks/CoreServices.framework/CoreServices"); - assertNotNull("CoreServices not found", lib); - } - catch(UnsatisfiedLinkError e) { - fail("Should try FRAMEWORK if absolute and exists"); - } - } - } - public void testLookupGlobalVariable() { NativeLibrary lib = NativeLibrary.getInstance("testlib"); Pointer global = lib.getGlobalVariableAddress("test_global"); diff --git a/test/com/sun/jna/NativeTest.java b/test/com/sun/jna/NativeTest.java index 8458cd30f7..20579df245 100644 --- a/test/com/sun/jna/NativeTest.java +++ b/test/com/sun/jna/NativeTest.java @@ -244,62 +244,6 @@ public void testToCharArray() { assertEquals("Wrong char array contents: " + new String(buf), VALUE, new String(buf, 0, buf.length-1)); } - public void testOSPrefix() { - assertEquals("Wrong resource path", "win32-x86", - Native.getNativeLibraryResourcePrefix(Platform.WINDOWS, - "x86", "Windows")); - assertEquals("Wrong resource path Windows/i386", "win32-x86", - Native.getNativeLibraryResourcePrefix(Platform.WINDOWS, - "i386", "Windows")); - assertEquals("Wrong resource path Windows CE/arm", "w32ce-arm", - Native.getNativeLibraryResourcePrefix(Platform.WINDOWSCE, - "arm", "Windows CE")); - assertEquals("Wrong resource path Mac/x86", "darwin", - Native.getNativeLibraryResourcePrefix(Platform.MAC, - "x86", "Darwin")); - assertEquals("Wrong resource path Mac/x86", "darwin", - Native.getNativeLibraryResourcePrefix(Platform.MAC, - "i386", "Darwin")); - assertEquals("Wrong resource path Mac/x86_64", "darwin", - Native.getNativeLibraryResourcePrefix(Platform.MAC, - "x86_64", "Mac")); - assertEquals("Wrong resource path Solaris/sparc", "sunos-sparc", - Native.getNativeLibraryResourcePrefix(Platform.SOLARIS, - "sparc", "Solaris")); - assertEquals("Wrong resource path SunOS/sparcv9", "sunos-sparcv9", - Native.getNativeLibraryResourcePrefix(Platform.SOLARIS, - "sparcv9", "SunOS")); - assertEquals("Wrong resource path Linux/i386", "linux-x86", - Native.getNativeLibraryResourcePrefix(Platform.LINUX, - "i386", "Linux/Gnu")); - assertEquals("Wrong resource path Linux/x86", "linux-x86", - Native.getNativeLibraryResourcePrefix(Platform.LINUX, - "x86", "Linux")); - assertEquals("Wrong resource path Linux/x86", "linux-x86-64", - Native.getNativeLibraryResourcePrefix(Platform.LINUX, - "x86_64", "Linux")); - assertEquals("Wrong resource path Linux/x86", "linux-x86-64", - Native.getNativeLibraryResourcePrefix(Platform.LINUX, - "amd64", "Linux")); - assertEquals("Wrong resource path Linux/ppc", "linux-ppc", - Native.getNativeLibraryResourcePrefix(Platform.LINUX, - "powerpc", "Linux")); - assertEquals("Wrong resource path OpenBSD/x86", "openbsd-x86", - Native.getNativeLibraryResourcePrefix(Platform.OPENBSD, - "x86", "OpenBSD")); - assertEquals("Wrong resource path FreeBSD/x86", "freebsd-x86", - Native.getNativeLibraryResourcePrefix(Platform.FREEBSD, - "x86", "FreeBSD")); - assertEquals("Wrong resource path Linux/armv7l (android)", "android-arm", - Native.getNativeLibraryResourcePrefix(Platform.ANDROID, - "armv7l", "Linux")); - - assertEquals("Wrong resource path other/other", "name-ppc", - Native.getNativeLibraryResourcePrefix(Platform.UNSPECIFIED, - "PowerPC", "Name Of System")); - - } - public static class DirectMapping { public static class DirectStructure extends Structure { public int field; diff --git a/test/com/sun/jna/Paths.java b/test/com/sun/jna/Paths.java new file mode 100644 index 0000000000..c7f8592199 --- /dev/null +++ b/test/com/sun/jna/Paths.java @@ -0,0 +1,41 @@ +/* Copyright (c) 2009 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; + +import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; + +public interface Paths { + boolean USING_CLOVER = System.getProperty("java.class.path").indexOf("clover") != -1; + /** Use this as a parent class loader to ensure clover can be loaded. */ + class CloverLoader extends URLClassLoader { + public CloverLoader() throws MalformedURLException{ + super(new URL[] { + new File(USING_CLOVER ? "lib/clover.jar" : "/dev/null").toURI().toURL() + }, null); + } + } + String BUILDDIR = Platform.isWindowsCE() + ? "/Storage Card" + : System.getProperty("jna.builddir", + USING_CLOVER + ? "build.clover" + : "build" + (Platform.is64Bit() ? "-d64" : "")); + String CLASSES = BUILDDIR + (Platform.isWindowsCE() ? "" : "/classes"); + String JNAJAR = BUILDDIR + "/jna.jar"; + + String TESTPATH = Platform.isWindowsCE() ? "/Storage Card/" : BUILDDIR + "/native/"; + String TESTJAR = BUILDDIR + "/jna-test.jar"; +} diff --git a/test/com/sun/jna/PerformanceTest.java b/test/com/sun/jna/PerformanceTest.java index 61e03071d8..4162b3271f 100644 --- a/test/com/sun/jna/PerformanceTest.java +++ b/test/com/sun/jna/PerformanceTest.java @@ -17,9 +17,6 @@ import com.sun.jna.ptr.PointerByReference; import java.lang.ref.*; import java.io.File; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLClassLoader; import java.nio.Buffer; import java.nio.ByteBuffer; import java.nio.ByteOrder; @@ -28,22 +25,15 @@ import com.sun.jna.DirectTest.TestLibrary; //@SuppressWarnings("unused") -public class PerformanceTest extends TestCase { +public class PerformanceTest extends TestCase implements Paths { public void testEmpty() { } - private static final String BUILDDIR = - System.getProperty("jna.builddir", - "build" + (Platform.is64Bit() ? "-d64" : "")); - private static class JNI { static { - String path = BUILDDIR + "/native/" + System.mapLibraryName("testlib");; + String path = TESTPATH + NativeLibrary.mapSharedLibraryName("testlib");; if (!new File(path).isAbsolute()) { - path = System.getProperty("user.dir") + "/" + path; - } - if (path.endsWith(".jnilib")) { - path = path.replace(".jnilib", ".dylib"); + path = new File(path).getAbsolutePath(); } System.load(path); } diff --git a/test/com/sun/jna/PlatformTest.java b/test/com/sun/jna/PlatformTest.java new file mode 100644 index 0000000000..c4813ded6e --- /dev/null +++ b/test/com/sun/jna/PlatformTest.java @@ -0,0 +1,80 @@ +/* Copyright (c) 2013 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; + +import junit.framework.TestCase; + +//@SuppressWarnings("unused") +public class PlatformTest extends TestCase { + + public void testOSPrefix() { + assertEquals("Wrong resource path", "win32-x86", + Platform.getNativeLibraryResourcePrefix(Platform.WINDOWS, + "x86", "Windows")); + assertEquals("Wrong resource path Windows/i386", "win32-x86", + Platform.getNativeLibraryResourcePrefix(Platform.WINDOWS, + "i386", "Windows")); + assertEquals("Wrong resource path Windows CE/arm", "w32ce-arm", + Platform.getNativeLibraryResourcePrefix(Platform.WINDOWSCE, + "arm", "Windows CE")); + assertEquals("Wrong resource path Mac/x86", "darwin", + Platform.getNativeLibraryResourcePrefix(Platform.MAC, + "x86", "Darwin")); + assertEquals("Wrong resource path Mac/x86", "darwin", + Platform.getNativeLibraryResourcePrefix(Platform.MAC, + "i386", "Darwin")); + assertEquals("Wrong resource path Mac/x86_64", "darwin", + Platform.getNativeLibraryResourcePrefix(Platform.MAC, + "x86_64", "Mac")); + assertEquals("Wrong resource path Solaris/sparc", "sunos-sparc", + Platform.getNativeLibraryResourcePrefix(Platform.SOLARIS, + "sparc", "Solaris")); + assertEquals("Wrong resource path SunOS/sparcv9", "sunos-sparcv9", + Platform.getNativeLibraryResourcePrefix(Platform.SOLARIS, + "sparcv9", "SunOS")); + assertEquals("Wrong resource path Linux/i386", "linux-x86", + Platform.getNativeLibraryResourcePrefix(Platform.LINUX, + "i386", "Linux/Gnu")); + assertEquals("Wrong resource path Linux/x86", "linux-x86", + Platform.getNativeLibraryResourcePrefix(Platform.LINUX, + "x86", "Linux")); + assertEquals("Wrong resource path Linux/x86", "linux-x86-64", + Platform.getNativeLibraryResourcePrefix(Platform.LINUX, + "x86_64", "Linux")); + assertEquals("Wrong resource path Linux/x86", "linux-x86-64", + Platform.getNativeLibraryResourcePrefix(Platform.LINUX, + "amd64", "Linux")); + assertEquals("Wrong resource path Linux/ppc", "linux-ppc", + Platform.getNativeLibraryResourcePrefix(Platform.LINUX, + "powerpc", "Linux")); + assertEquals("Wrong resource path OpenBSD/x86", "openbsd-x86", + Platform.getNativeLibraryResourcePrefix(Platform.OPENBSD, + "x86", "OpenBSD")); + assertEquals("Wrong resource path FreeBSD/x86", "freebsd-x86", + Platform.getNativeLibraryResourcePrefix(Platform.FREEBSD, + "x86", "FreeBSD")); + assertEquals("Wrong resource path Linux/armv7l (android)", "android-arm", + Platform.getNativeLibraryResourcePrefix(Platform.ANDROID, + "armv7l", "Linux")); + + assertEquals("Wrong resource path other/other", "name-ppc", + Platform.getNativeLibraryResourcePrefix(Platform.UNSPECIFIED, + "PowerPC", "Name Of System")); + + } + + + public static void main(String[] args) { + junit.textui.TestRunner.run(PlatformTest.class); + } +} diff --git a/test/com/sun/jna/StructureTest.java b/test/com/sun/jna/StructureTest.java index 2c4f21c1dc..482e06955d 100644 --- a/test/com/sun/jna/StructureTest.java +++ b/test/com/sun/jna/StructureTest.java @@ -88,7 +88,7 @@ public static class TestAllocStructure extends Structure { public int f2; public int f3; protected List getFieldOrder() { - return Arrays.asList(new String[] { "f0", "f1", "f2", "f3" }); + return Arrays.asList(new String[] { "f0", "f1", "f2", "f3" }); } } @@ -151,7 +151,7 @@ class TestStructure extends Structure { public float f; public double d; protected List getFieldOrder() { - return Arrays.asList(new String[] { "b", "s", "i", "l", "f", "d" }); + return Arrays.asList(new String[] { "b", "s", "i", "l", "f", "d" }); } } Structure s = new TestStructure(); @@ -170,7 +170,7 @@ class TestStructure extends Structure { public float f; public double d; protected List getFieldOrder() { - return Arrays.asList(new String[] { "b", "s", "i", "l", "f", "d" }); + return Arrays.asList(new String[] { "b", "s", "i", "l", "f", "d" }); } } Structure s = new TestStructure(); @@ -195,21 +195,21 @@ public static class TestStructure0 extends FilledStructure { public byte field0 = 0x01; public short field1 = 0x0202; protected List getFieldOrder() { - return Arrays.asList(new String[] { "field0", "field1" }); + return Arrays.asList(new String[] { "field0", "field1" }); } } public static class TestStructure1 extends FilledStructure { public byte field0 = 0x01; public int field1 = 0x02020202; protected List getFieldOrder() { - return Arrays.asList(new String[] { "field0", "field1" }); + return Arrays.asList(new String[] { "field0", "field1" }); } } public static class TestStructure2 extends FilledStructure { public short field0 = 0x0101; public int field1 = 0x02020202; protected List getFieldOrder() { - return Arrays.asList(new String[] { "field0", "field1" }); + return Arrays.asList(new String[] { "field0", "field1" }); } } public static class TestStructure3 extends FilledStructure { @@ -217,7 +217,7 @@ public static class TestStructure3 extends FilledStructure { public short field1 = 0x0202; public int field2 = 0x03030303; protected List getFieldOrder() { - return Arrays.asList(new String[] { "field0", "field1", "field2" }); + return Arrays.asList(new String[] { "field0", "field1", "field2" }); } } public static class TestStructure4 extends FilledStructure { @@ -226,14 +226,14 @@ public static class TestStructure4 extends FilledStructure { public int field2 = 0x03030303; public long field3 = 0x0404040404040404L; protected List getFieldOrder() { - return Arrays.asList(new String[] { "field0", "field1", "field2", "field3" }); + return Arrays.asList(new String[] { "field0", "field1", "field2", "field3" }); } } public static class TestStructure5 extends FilledStructure { public long field0 = 0x0101010101010101L; public byte field1 = 0x02; protected List getFieldOrder() { - return Arrays.asList(new String[] { "field0", "field1" }); + return Arrays.asList(new String[] { "field0", "field1" }); } } public interface SizeTest extends Library { @@ -354,7 +354,7 @@ protected void allocateMemory(int size) { ++allocations; } protected List getFieldOrder() { - return Arrays.asList(new String[] { "x", "y" }); + return Arrays.asList(new String[] { "x", "y" }); } } public void testStructureField() { @@ -362,7 +362,7 @@ class TestStructure extends Structure { public PublicTestStructure s1, s2; public int after; protected List getFieldOrder() { - return Arrays.asList(new String[] { "s1", "s2", "after" }); + return Arrays.asList(new String[] { "s1", "s2", "after" }); } } TestStructure s = new TestStructure(); @@ -386,6 +386,25 @@ protected List getFieldOrder() { s.s2.getPointer()); } + static class TestUnion extends Union { + public int u_int; + public float u_float; + public double u_double; + } + public void testUnionField() { + class TestStructure extends Structure { + public long s_long; + public TestUnion s_union; + public int s_int; + protected List getFieldOrder() { + return Arrays.asList(new String[] { "s_long", "s_union", "s_int" }); + } + } + TestStructure s = new TestStructure(); + assertEquals("Wrong structure size", 24, s.size()); + assertEquals("Wrong union size", 8, s.s_union.size()); + } + public static class NonAllocatingTestStructure extends PublicTestStructure { public NonAllocatingTestStructure() { } public NonAllocatingTestStructure(Pointer p) { super(p); read(); } @@ -394,16 +413,16 @@ protected void allocateMemory(int size) { } } - // TODO: add'l newInstance(Pointer) tests: + // TODO: add'l newInstance(Pointer) tests: // NOTE: ensure structure-by-value respected (no more flag on newjavastructure) - // native call (direct mode) + // native call (direct mode) // getNativeAlignment public void testStructureFieldAvoidsSeparateMemoryAllocation() { class TestStructure extends Structure { public NonAllocatingTestStructure s1; public TestStructure() { } protected List getFieldOrder() { - return Arrays.asList(new String[] { "s1" }); + return Arrays.asList(new String[] { "s1" }); } } TestStructure ts = new TestStructure(); @@ -434,8 +453,8 @@ class TestStructure extends Structure { // initialized array elements public PublicTestStructure[] inner2 = (PublicTestStructure[]) new PublicTestStructure().toArray(2); - protected List getFieldOrder() { - return Arrays.asList(new String[] { "inner", "inner2" }); + protected List getFieldOrder() { + return Arrays.asList(new String[] { "inner", "inner2" }); } } TestStructure s = new TestStructure(); @@ -530,7 +549,7 @@ public TestStructure() { public double[] da = new double[3]; public PublicTestStructure nested; protected List getFieldOrder() { - return Arrays.asList(new String[] { "z", "b", "c", "s", "i", "l", "f", "d", "ba", "ca", "sa", "ia", "la", "fa", "da", "nested" }); + return Arrays.asList(new String[] { "z", "b", "c", "s", "i", "l", "f", "d", "ba", "ca", "sa", "ia", "la", "fa", "da", "nested" }); } } TestStructure s = new TestStructure(); @@ -624,8 +643,8 @@ public void testNativeLongWrite() throws Exception { class TestStructure extends Structure { public int i; public NativeLong l; - protected List getFieldOrder() { - return Arrays.asList(new String[] { "i", "l" }); + protected List getFieldOrder() { + return Arrays.asList(new String[] { "i", "l" }); } } TestStructure s = new TestStructure(); @@ -672,14 +691,14 @@ protected List getFieldOrder() { public static class BadFieldStructure extends Structure { public Object badField; - protected List getFieldOrder() { + protected List getFieldOrder() { return Arrays.asList(new String[] { "badField" }); } } public void testUnsupportedField() { class BadNestedStructure extends Structure { public BadFieldStructure badStruct = new BadFieldStructure(); - protected List getFieldOrder() { + protected List getFieldOrder() { return Arrays.asList(new String[] { "badStruct" }); } } @@ -881,7 +900,7 @@ public void testPreserveStructureByReferenceWithUnchangedPointerOnRead() { assertTrue("Read should preserve structure memory", inner.getPointer() instanceof Memory); } - + public static class TestPointer extends PointerType { } public void testPreservePointerFields() { class TestStructure extends Structure { @@ -925,7 +944,7 @@ protected List getFieldOrder() { assertEquals("String field should not be overwritten", m2, s.getPointer().getPointer(Pointer.SIZE)); } - // Ensure string cacheing doesn't interfere with wrapped structure writes. + // Ensure string cacheing doesn't interfere with wrapped structure writes. public static class StructureFromNative extends Structure { public String s; protected List getFieldOrder() { @@ -938,7 +957,7 @@ public StructureFromNative(Pointer p) { public StructureFromNative() { } } - + public void testInitializeStructureFieldWithStrings() { class ContainingStructure extends Structure { public StructureFromNative inner; @@ -1021,7 +1040,7 @@ protected List getFieldOrder() { } TestStructure s = new TestStructure(); s.field = new PublicTestStructure.ByReference(); - PublicTestStructure.ByReference[] array = + PublicTestStructure.ByReference[] array = (PublicTestStructure.ByReference[])s.field.toArray(2); final int VALUE = -1; array[1].x = VALUE; @@ -1066,13 +1085,13 @@ protected List getFieldOrder() { return Arrays.asList(new String[] { "size", "alignment", "type", "elements" }); } public TestFFIType(Pointer p) { - super(p); + super(p); read(); assertTrue("Test FFIType type not initialized: " + this, this.type != 0); // Force libffi to explicitly calculate the size field of // this FFIType object - int size = Native.initialize_ffi_type(p.peer); + int size = Native.initialize_ffi_type(p.peer); read(); assertEquals("Test FFIType size improperly initialized: " + TestFFIType.this, size, TestFFIType.this.size.intValue()); } @@ -1123,7 +1142,7 @@ class TestStructure extends Structure { public int intField; public PublicTestStructure inner; protected List getFieldOrder() { - return Arrays.asList(new String[] { "intField", "inner" }); + return Arrays.asList(new String[] { "intField", "inner" }); } } TestStructure s = new TestStructure(); @@ -1154,7 +1173,7 @@ public void testNativeMappedWrite() { class TestStructure extends Structure { public ByteByReference ref; protected List getFieldOrder() { - return Arrays.asList(new String[] { "ref" }); + return Arrays.asList(new String[] { "ref" }); } } TestStructure s = new TestStructure(); @@ -1171,7 +1190,7 @@ public void testNativeMappedRead() { class TestStructure extends Structure { public ByteByReference ref; protected List getFieldOrder() { - return Arrays.asList(new String[] { "ref" }); + return Arrays.asList(new String[] { "ref" }); } } TestStructure s = new TestStructure(); @@ -1191,7 +1210,7 @@ protected List getFieldOrder() { public static class ROStructure extends Structure { public final int field; protected List getFieldOrder() { - return Arrays.asList(new String[] { "field" }); + return Arrays.asList(new String[] { "field" }); } { // Initialize in ctor to avoid compiler replacing @@ -1241,7 +1260,7 @@ public void testNativeMappedArrayField() { class TestStructure extends Structure { public NativeLong[] longs = new NativeLong[SIZE]; protected List getFieldOrder() { - return Arrays.asList(new String[] { "longs" }); + return Arrays.asList(new String[] { "longs" }); } } TestStructure s = new TestStructure(); @@ -1277,7 +1296,7 @@ class TestStructure extends Structure { public NativeLong nl = INITIAL; public NativeLong uninitialized; protected List getFieldOrder() { - return Arrays.asList(new String[] { "nl", "uninitialized" }); + return Arrays.asList(new String[] { "nl", "uninitialized" }); } } TestStructure ts = new TestStructure(); @@ -1300,7 +1319,7 @@ public void testThrowErrorOnMissingFieldOrderOnDerivedStructure() { class TestStructure extends Structure { public int f1, f2; protected List getFieldOrder() { - return Arrays.asList(new String[] { "f1", "f2" }); + return Arrays.asList(new String[] { "f1", "f2" }); } } class TestStructure2 extends TestStructure { @@ -1333,7 +1352,7 @@ public void testThrowErrorOnIncorrectFieldOrderCount() { class TestStructure extends Structure { public int f1, f2; protected List getFieldOrder() { - return Arrays.asList(new String[] { "f1", "f2", "f3" }); + return Arrays.asList(new String[] { "f1", "f2", "f3" }); } } try { @@ -1387,7 +1406,7 @@ protected List getFieldOrder() { return list; } } - + TestStructure s = new TestStructure(); assertEquals("Wrong field order", Arrays.asList(ORDER), s.getFieldOrder()); @@ -1444,13 +1463,13 @@ protected List getFieldOrder() { Structure s = new TestStructure(); assertEquals("Wrong type mapper: " + s, mapper, s.getTypeMapper()); } - + public void testWriteWithNullBoxedPrimitives() { class TestStructure extends Structure { public Boolean zfield; public Integer field; protected List getFieldOrder() { - return Arrays.asList(new String[] { "zfield", "field" }); + return Arrays.asList(new String[] { "zfield", "field" }); } } TestStructure s = new TestStructure(); @@ -1465,7 +1484,7 @@ class OtherStructure extends Structure { public int[] second = new int[4]; public Pointer[] third = new Pointer[4]; protected List getFieldOrder() { - return Arrays.asList(new String[] { "first", "second", "third" }); + return Arrays.asList(new String[] { "first", "second", "third" }); } } class TestStructure extends Structure { @@ -1492,7 +1511,7 @@ protected List getFieldOrder() { assertTrue("Equals is not symmetric", s2.equals(s1)); assertTrue("Equals is not transitive", s1.equals(s2) && s2.equals(s3) && s1.equals(s3)); - + } public void testStructureEqualsByValueByReference() { @@ -1501,7 +1520,7 @@ class TestStructure extends Structure { public int[] second = new int[4]; public Pointer[] third = new Pointer[4]; protected List getFieldOrder() { - return Arrays.asList(new String[] { "first", "second", "third" }); + return Arrays.asList(new String[] { "first", "second", "third" }); } } class ByReference extends TestStructure implements Structure.ByReference { } @@ -1518,14 +1537,14 @@ class ByValue extends TestStructure implements Structure.ByValue { } assertTrue("Equals is not symmetric (ByValue)", s3.equals(s1)); assertTrue("Equals is not transitive (ByReference/ByValue)", s1.equals(s2) && s2.equals(s3) && s1.equals(s3)); - + } public void testStructureHashCodeMatchesEqualsTrue() { class TestStructure extends Structure { public int first; protected List getFieldOrder() { - return Arrays.asList(new String[] { "first" }); + return Arrays.asList(new String[] { "first" }); } } TestStructure s1 = new TestStructure(); @@ -1540,7 +1559,7 @@ class TestStructure extends Structure { public byte first; public int second; protected List getFieldOrder() { - return Arrays.asList(new String[] { "first", "second" }); + return Arrays.asList(new String[] { "first", "second" }); } } TestStructure s1 = new TestStructure(); @@ -1559,7 +1578,7 @@ public TestStructureByRef() { } public int unique; public TestStructureByRef s; protected List getFieldOrder() { - return Arrays.asList(new String[] { "unique", "s" }); + return Arrays.asList(new String[] { "unique", "s" }); } } TestStructureByRef s = new TestStructureByRef(); @@ -1592,7 +1611,7 @@ public static class ByReference extends CyclicTestStructure implements Structure public CyclicTestStructure() { } public CyclicTestStructure.ByReference next; protected List getFieldOrder() { - return Arrays.asList(new String[] { "next" }); + return Arrays.asList(new String[] { "next" }); } } public void testCyclicRead() { @@ -1618,7 +1637,7 @@ public void testAvoidMemoryAllocationInPointerCTOR() { class TestStructure extends Structure { public int field; protected List getFieldOrder() { - return Arrays.asList(new String[] { "field" }); + return Arrays.asList(new String[] { "field" }); } public TestStructure(Pointer p) { super(p); @@ -1637,7 +1656,7 @@ class TestStructure extends Structure { public int intField; public byte[] arrayField = new byte[256]; protected List getFieldOrder() { - return Arrays.asList(new String[] { "intField", "arrayField" }); + return Arrays.asList(new String[] { "intField", "arrayField" }); } public TestStructure(Pointer p) { super(p); @@ -1676,7 +1695,7 @@ public TestByReferenceArrayField(Pointer m) { public ByReference[] array = new ByReference[13]; public int value2; protected List getFieldOrder() { - return Arrays.asList(new String[] { "value1", "array", "value2" }); + return Arrays.asList(new String[] { "value1", "array", "value2" }); } public static class ByReference extends TestByReferenceArrayField implements Structure.ByReference { } @@ -1703,7 +1722,7 @@ public void testEquals() { class TestStructure extends Structure { public int field; protected List getFieldOrder() { - return Arrays.asList(new String[] { "field" }); + return Arrays.asList(new String[] { "field" }); } public TestStructure() { } public TestStructure(Pointer p) { super(p); read(); } @@ -1720,7 +1739,7 @@ public void testStructureLayoutCacheing() { class TestStructure extends Structure { public int field; protected List getFieldOrder() { - return Arrays.asList(new String[] { "field" }); + return Arrays.asList(new String[] { "field" }); } } Structure ts = new TestStructure(); ts.ensureAllocated(); @@ -1728,12 +1747,12 @@ protected List getFieldOrder() { assertSame("Structure layout not cached", ts.fields(), ts2.fields()); } - + public void testStructureLayoutVariableNoCache() { class TestStructure extends Structure { public byte[] variable; protected List getFieldOrder() { - return Arrays.asList(new String[] { "variable" }); + return Arrays.asList(new String[] { "variable" }); } public TestStructure(int size) { this.variable = new byte[size]; @@ -1767,7 +1786,7 @@ public Object toNative(Object value, ToNativeContext c) { class TestStructure extends Structure { public boolean field; protected List getFieldOrder() { - return Arrays.asList(new String[] { "field" }); + return Arrays.asList(new String[] { "field" }); } public TestStructure() { super(m); @@ -1788,7 +1807,7 @@ class TestStructure extends Structure { public byte first; public int second; protected List getFieldOrder() { - return Arrays.asList(new String[] { "first", "second" }); + return Arrays.asList(new String[] { "first", "second" }); } public TestStructure() { setAlignType(ALIGN_NONE); @@ -1851,7 +1870,7 @@ public TestStructure() { super(mapper); } protected List getFieldOrder() { - return Arrays.asList(new String[] { "b", "s", "p0", "p1", "p2", "p3", "p4", "p5", "p6", "p7" }); + return Arrays.asList(new String[] { "b", "s", "p0", "p1", "p2", "p3", "p4", "p5", "p6", "p7" }); } } Structure s = new TestStructure(); diff --git a/test/com/sun/jna/UnionTest.java b/test/com/sun/jna/UnionTest.java index 579c26c646..6f2d0d0c70 100644 --- a/test/com/sun/jna/UnionTest.java +++ b/test/com/sun/jna/UnionTest.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; @@ -23,22 +23,22 @@ public class UnionTest extends TestCase { public static class TestStructure extends Structure { public String value; protected List getFieldOrder() { - return Arrays.asList(new String[] { "value" }); + return Arrays.asList(new String[] { "value" }); } } - + public static class BigTestStructure extends Structure { public long field1; public long field2; protected List getFieldOrder() { - return Arrays.asList(new String[] { "field1", "field2" }); + return Arrays.asList(new String[] { "field1", "field2" }); } } - + public static class IntStructure extends Structure { public int value; protected List getFieldOrder() { - return Arrays.asList(new String[] { "value" }); + return Arrays.asList(new String[] { "value" }); } } @@ -59,7 +59,7 @@ public static class SizedUnion extends Union { public WString wstring; public Pointer pointer; } - + public static class StructUnion extends Union { public int intField; public TestStructure testStruct; @@ -69,31 +69,33 @@ public static class StructUnion extends Union { public void testCalculateSize() { Union u = new SizedUnion(); + assertEquals("Wrong union size: " + u, 16, u.size()); assertEquals("Union should be size of largest field", new BigTestStructure().size(), u.size()); } public void testFieldOffsets() { StructUnion u = new StructUnion(); + assertEquals("Wrong union size: " + u, Pointer.SIZE, u.size()); u.setType(u.testStruct.getClass()); u.write(); - assertEquals("Wrong struct member base address", + assertEquals("Wrong struct member base address", u.getPointer(), u.testStruct.getPointer()); u.setType(u.intStruct.getClass()); u.write(); - assertEquals("Wrong struct member base address (2)", + assertEquals("Wrong struct member base address (2)", u.getPointer(), u.intStruct.getPointer()); } public void testWriteUnion() { SizedUnion u = new SizedUnion(); - final int VALUE = 0x12345678; + final int VALUE = 0x12345678; u.intField = VALUE; u.setType(int.class); u.write(); assertEquals("Wrong value written", VALUE, u.getPointer().getInt(0)); } - + public void testReadUnion() { SizedUnion u = new SizedUnion(); final int VALUE = 0x12345678; @@ -109,11 +111,12 @@ public void testReadUnion() { assertNull("Unselected String should be null", u.string); assertNull("Unselected WString should be null", u.wstring); } - + public void testWriteTypedUnion() { final int VALUE = 0x12345678; // write an instance of a direct union class to memory StructUnion u = new StructUnion(); + assertEquals("Wrong union size: " + u, Pointer.SIZE, u.size()); IntStructure intStruct = new IntStructure(); intStruct.value = VALUE; u.setTypedValue(intStruct); @@ -138,6 +141,7 @@ public void callback() { public void testReadTypedUnion() { StructUnion u = new StructUnion(); + assertEquals("Wrong union size: " + u, Pointer.SIZE, u.size()); final int VALUE = 0x12345678; u.getPointer().setInt(0, VALUE); assertEquals("int structure not read properly", VALUE, ((IntStructure) u.getTypedValue(IntStructure.class)).value); @@ -145,29 +149,34 @@ public void testReadTypedUnion() { public void testReadTypeInfo() { SizedUnion u = new SizedUnion(); + assertEquals("Wrong union size: " + u, 16, u.size()); + assertNotNull("Type information is missing for union field of type " + BigTestStructure.class, Structure.getTypeInfo(BigTestStructure.class)); + assertNotNull("Type information is missing for union instance", u.getTypeInfo()); if (Native.POINTER_SIZE == 4) { - assertEquals("Type size should be that of longest field if no field active", + assertEquals("Type size should be that of largest field if no field is active", Structure.getTypeInfo(BigTestStructure.class).getInt(0), u.getTypeInfo().getInt(0)); } else { - assertEquals("Type size should be that of longest field if no field active", + assertEquals("Type size should be that of largest field if no field is active", Structure.getTypeInfo(BigTestStructure.class).getLong(0), u.getTypeInfo().getLong(0)); } u.setType(int.class); + assertNotNull("Type information is missing for union field of type " + BigTestStructure.class, Structure.getTypeInfo(BigTestStructure.class)); + assertNotNull("Type information is missing for union instance after type set", u.getTypeInfo()); if (Native.POINTER_SIZE == 4) { - assertEquals("Type size should be that of longest field if field active", + assertEquals("Type size should be that of largest field if any field is active", Structure.getTypeInfo(BigTestStructure.class).getInt(0), u.getTypeInfo().getInt(0)); } else { - assertEquals("Type size should be that of longest field if field active", + assertEquals("Type size should be that of largest field if any field is active", Structure.getTypeInfo(BigTestStructure.class).getLong(0), u.getTypeInfo().getLong(0)); } } - + public void testArraysInUnion() { class TestUnion extends Union { public byte[] bytes = new byte[16]; @@ -175,6 +184,7 @@ class TestUnion extends Union { public int[] ints = new int[4]; } Union u = new TestUnion(); + assertEquals("Wrong union size: " + u, 16, u.size()); u.setType(byte[].class); u.setType(short[].class); u.setType(int[].class); @@ -183,9 +193,10 @@ class TestUnion extends Union { public void testDuplicateFieldTypes() { class TestUnion extends Union { public int field1; - public int field2; + public int field2; } TestUnion u = new TestUnion(); + assertEquals("Wrong union size: " + u, 4, u.size()); u.setType("field1"); u.field1 = 42; u.write(); diff --git a/test/com/sun/jna/WebStartTest.java b/test/com/sun/jna/WebStartTest.java index a5c7f9db1e..899b2cff81 100644 --- a/test/com/sun/jna/WebStartTest.java +++ b/test/com/sun/jna/WebStartTest.java @@ -40,7 +40,7 @@ * Run tests under web start * Works under OSX, windows, and linux. */ -public class WebStartTest extends TestCase { +public class WebStartTest extends TestCase implements Paths { // Provide a policy file for unsigned jars // Unfortunately this does not allow native libraries @@ -79,6 +79,9 @@ public class WebStartTest extends TestCase { + "