Comparar commits

..

16 Commits

Autor SHA1 Mensagem Data
Timothy Wall 38ac62cedd build 3.2.2
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@981 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2009-08-05 17:14:24 +00:00
Timothy Wall ce280731af only set javawebstart.version if not already set
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@980 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2009-08-05 14:17:37 +00:00
Timothy Wall 751fb57f71 fix web start test under NetX
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@979 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2009-08-05 14:07:41 +00:00
Timothy Wall be7d90abbf add length-specified Pointer.getStringArray()
update sunos-amd64.jar native
remove debug output

git-svn-id: https://svn.java.net/svn/jna~svn/trunk@978 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2009-08-05 12:15:01 +00:00
Timothy Wall d59585dd4f update natives to 3.2.1
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@977 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2009-08-04 15:49:17 +00:00
Timothy Wall 7a695707a2 avoid potential error if dispatch fails due to bad arguments
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@976 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2009-08-04 14:01:06 +00:00
Timothy Wall 4e590c9450 fix issue 125
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@975 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2009-08-04 13:55:59 +00:00
Timothy Wall b069d1c9e9 add direct version of struct by value tests
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@974 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2009-08-04 13:22:44 +00:00
Timothy Wall 9fa1f7b981 fix bug writing null-valued ByReference structure fields
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@973 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2009-07-31 20:57:57 +00:00
Timothy Wall 4a68e4cd9d canonicalize auto-sync of structure arrays
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@972 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2009-07-31 16:58:15 +00:00
Timothy Wall 8320b6fd7c add missing direct mappings for new tests
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@971 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2009-07-31 16:44:29 +00:00
Timothy Wall e40cf0a1c4 synch callback structure args on callback return
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@970 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2009-07-28 20:00:13 +00:00
Timothy Wall 19106985d7 remove debug output
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@969 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2009-07-27 22:40:33 +00:00
Timothy Wall 3d817c54da add array wrapping tests
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@968 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2009-07-27 22:38:35 +00:00
Timothy Wall ca31877107 find proper c library automatically, avoids ubuntu crash
git-svn-id: https://svn.java.net/svn/jna~svn/trunk@967 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2009-07-27 13:41:16 +00:00
Timothy Wall f5f9afefb0 avoid Structure.equals in read/write
reduce overhead of Structure.toString when struct contents aren't actually used

git-svn-id: https://svn.java.net/svn/jna~svn/trunk@966 2f8a963e-d2e4-e7d0-97bf-ccb7fcea9d80
2009-07-27 01:33:15 +00:00
37 arquivos alterados com 596 adições e 216 exclusões
+2 -2
Ver Arquivo
@@ -34,13 +34,13 @@
<!-- JNA library release version -->
<property name="jna.major" value="3"/>
<property name="jna.minor" value="2"/>
<property name="jna.revision" value="1"/>
<property name="jna.revision" value="2"/>
<property name="jna.build" value="${build.number}"/>
<property name="jna.version" value="${jna.major}.${jna.minor}.${jna.revision}"/>
<!-- jnidispatch library release version -->
<property name="jni.major" value="3"/>
<property name="jni.minor" value="2"/>
<property name="jni.revision" value="0"/>
<property name="jni.revision" value="1"/>
<property name="jni.build" value="${build.number}"/>
<property name="jni.version" value="${jni.major}.${jni.minor}.${jni.revision}"/>
<property name="jni.md5" value="c870290c36c8d3fdf85db7c782febc3f"/>
BIN
Ver Arquivo
Arquivo binário não exibido.
BIN
Ver Arquivo
Arquivo binário não exibido.
BIN
Ver Arquivo
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
BIN
Ver Arquivo
Arquivo binário não exibido.
BIN
Ver Arquivo
Arquivo binário não exibido.
BIN
Ver Arquivo
Arquivo binário não exibido.
BIN
Ver Arquivo
Arquivo binário não exibido.
BIN
Ver Arquivo
Arquivo binário não exibido.
BIN
Ver Arquivo
Arquivo binário não exibido.
BIN
Ver Arquivo
Arquivo binário não exibido.
Arquivo binário não exibido.
BIN
Ver Arquivo
Arquivo binário não exibido.
BIN
Ver Arquivo
Arquivo binário não exibido.
BIN
Ver Arquivo
Arquivo binário não exibido.
+1 -1
Ver Arquivo
@@ -27,7 +27,7 @@ OS=$(shell uname | sed -e 's/\(CYGWIN\|MINGW32\).*/win32/g' \
-e 's/Darwin.*/darwin/g' \
-e 's/Linux.*/linux/g')
VERSION=3.2.0 # auto-generated by ant
VERSION=3.2.1 # auto-generated by ant
CHECKSUM=c870290c36c8d3fdf85db7c782febc3f # auto-generated by ant
JAVA_INCLUDES=-I"$(JAVA_HOME)/include" \
+98 -93
Ver Arquivo
@@ -1805,7 +1805,7 @@ getArrayComponentType(JNIEnv *env, jobject obj) {
static void*
getBufferArray(JNIEnv* env, jobject buf,
jobject* arrayp, void **elemp,
jobject* arrayp, void **basep,
void **releasep) {
void *ptr = NULL;
int offset = 0;
@@ -1846,7 +1846,7 @@ do { \
GET_ARRAY(Double, 8);
}
if (ptr != NULL) {
if (elemp) *elemp = ptr;
if (basep) *basep = ptr;
if (arrayp) *arrayp = array;
ptr = (char *)ptr + offset;
}
@@ -2581,106 +2581,111 @@ method_handler(ffi_cif* cif, void* volatile resp, void** argp, void *cdata) {
if (data->flags) {
objects = alloca(data->cif.nargs * sizeof(void*));
memset(objects, 0, data->cif.nargs * sizeof(void*));
release = alloca(data->cif.nargs * sizeof(release_t));
memset(release, 0, data->cif.nargs * sizeof(release_t));
elems = alloca(data->cif.nargs * sizeof(void*));
for (i=0;i < data->cif.nargs;i++) {
if (data->flags[i] != CVT_DEFAULT) {
if (data->arg_types[i]->type == FFI_TYPE_POINTER
&& *(void **)args[i] == NULL) continue;
switch(data->flags[i]) {
case CVT_INTEGER_TYPE:
{
jlong value = getIntegerTypeValue(env, *(void **)args[i]);
if (cif->arg_types[i+2]->size < data->cif.arg_types[i]->size) {
args[i] = alloca(data->cif.arg_types[i]->size);
}
if (data->cif.arg_types[i]->size > sizeof(ffi_arg)) {
*(jlong *)args[i] = value;
}
else {
*(ffi_arg *)args[i] = (ffi_arg)value;
if (data->flags[i] == CVT_DEFAULT) {
continue;
}
if (data->arg_types[i]->type == FFI_TYPE_POINTER
&& *(void **)args[i] == NULL) {
continue;
}
switch(data->flags[i]) {
case CVT_INTEGER_TYPE:
{
jlong value = getIntegerTypeValue(env, *(void **)args[i]);
if (cif->arg_types[i+2]->size < data->cif.arg_types[i]->size) {
args[i] = alloca(data->cif.arg_types[i]->size);
}
if (data->cif.arg_types[i]->size > sizeof(ffi_arg)) {
*(jlong *)args[i] = value;
}
else {
*(ffi_arg *)args[i] = (ffi_arg)value;
}
}
break;
case CVT_POINTER_TYPE:
*(void **)args[i] = getPointerTypeAddress(env, *(void **)args[i]);
break;
case CVT_TYPE_MAPPER:
{
void* valuep = args[i];
int jtype = get_jtype_from_ffi_type(data->closure_cif.arg_types[i+2]);
jobject obj = jtype == '*'
? *(void **)valuep
: new_object(env, (char)jtype, valuep, JNI_FALSE);
if (cif->arg_types[i+2]->size < data->cif.arg_types[i]->size) {
args[i] = alloca(data->cif.arg_types[i]->size);
}
toNativeTypeMapped(env, obj, args[i],
data->cif.arg_types[i]->size,
data->to_native[i]);
}
break;
case CVT_NATIVE_MAPPED:
toNative(env, *(void **)args[i], args[i], data->cif.arg_types[i]->size, JNI_FALSE);
break;
case CVT_POINTER:
*(void **)args[i] = getNativeAddress(env, *(void **)args[i]);
break;
case CVT_STRUCTURE:
objects[i] = *(void **)args[i];
writeStructure(env, *(void **)args[i]);
*(void **)args[i] = getStructureAddress(env, *(void **)args[i]);
break;
case CVT_STRUCTURE_BYVAL:
objects[i] = *(void **)args[i];
writeStructure(env, objects[i]);
args[i] = getStructureAddress(env, objects[i]);
break;
case CVT_STRING:
*(void **)args[i] = newCStringEncoding(env, (jstring)*(void **)args[i], jna_encoding);
break;
case CVT_WSTRING:
{
jstring s = (*env)->CallObjectMethod(env, *(void **)args[i], MID_Object_toString);
*(void **)args[i] = newWideCString(env, s);
}
break;
case CVT_CALLBACK:
*(void **)args[i] = getCallbackAddress(env, *(void **)args[i]);
break;
case CVT_BUFFER:
{
void *ptr = (*env)->GetDirectBufferAddress(env, *(void **)args[i]);
if (ptr != NULL) {
objects[i] = NULL;
release[i] = NULL;
}
else {
ptr = getBufferArray(env, *(jobject *)args[i], (jobject *)&objects[i], &elems[i], (void**)&release[i]);
if (ptr == NULL) {
throw_type = EIllegalArgument;
throw_msg = "Buffer arguments must be direct or have a primitive backing array";
goto cleanup;
}
}
break;
case CVT_POINTER_TYPE:
*(void **)args[i] = getPointerTypeAddress(env, *(void **)args[i]);
break;
case CVT_TYPE_MAPPER:
{
void* valuep = args[i];
int jtype = get_jtype_from_ffi_type(data->closure_cif.arg_types[i+2]);
jobject obj = jtype == '*'
? *(void **)valuep
: new_object(env, (char)jtype, valuep, JNI_FALSE);
if (cif->arg_types[i+2]->size < data->cif.arg_types[i]->size) {
args[i] = alloca(data->cif.arg_types[i]->size);
}
toNativeTypeMapped(env, obj, args[i],
data->cif.arg_types[i]->size,
data->to_native[i]);
}
break;
case CVT_NATIVE_MAPPED:
toNative(env, *(void **)args[i], args[i], data->cif.arg_types[i]->size, JNI_FALSE);
break;
case CVT_POINTER:
*(void **)args[i] = getNativeAddress(env, *(void **)args[i]);
break;
case CVT_STRUCTURE:
objects[i] = *(void **)args[i];
writeStructure(env, *(void **)args[i]);
*(void **)args[i] = getStructureAddress(env, *(void **)args[i]);
break;
case CVT_STRUCTURE_BYVAL:
objects[i] = *(void **)args[i];
writeStructure(env, objects[i]);
args[i] = getStructureAddress(env, objects[i]);
break;
case CVT_STRING:
*(void **)args[i] = newCStringEncoding(env, (jstring)*(void **)args[i], jna_encoding);
break;
case CVT_WSTRING:
{
jstring s = (*env)->CallObjectMethod(env, *(void **)args[i], MID_Object_toString);
*(void **)args[i] = newWideCString(env, s);
}
break;
case CVT_CALLBACK:
*(void **)args[i] = getCallbackAddress(env, *(void **)args[i]);
break;
case CVT_BUFFER:
{
void *ptr = (*env)->GetDirectBufferAddress(env, *(void **)args[i]);
if (ptr != NULL) {
objects[i] = NULL;
release[i] = NULL;
}
else {
ptr = getBufferArray(env, *(jobject *)args[i], (jobject *)&objects[i], &elems[i], (void**)&release[i]);
if (ptr == NULL) {
throw_type = EIllegalArgument;
throw_msg = "Buffer arguments must be direct or have a primitive backing array";
goto cleanup;
}
}
*(void **)args[i] = ptr;
}
break;
#define ARRAY(Type) \
*(void **)args[i] = ptr;
}
break;
#define ARRAY(Type) \
do { \
objects[i] = *(void **)args[i]; \
release[i] = (void *)(*env)->Release##Type##ArrayElements; \
elems[i] = *(void **)args[i] = (*env)->Get##Type##ArrayElements(env, objects[i], NULL); } while(0)
case CVT_ARRAY_BYTE: ARRAY(Byte); break;
case CVT_ARRAY_SHORT: ARRAY(Short); break;
case CVT_ARRAY_CHAR: ARRAY(Char); break;
case CVT_ARRAY_INT: ARRAY(Int); break;
case CVT_ARRAY_LONG: ARRAY(Long); break;
case CVT_ARRAY_FLOAT: ARRAY(Float); break;
case CVT_ARRAY_DOUBLE: ARRAY(Double); break;
default:
break;
}
case CVT_ARRAY_BYTE: ARRAY(Byte); break;
case CVT_ARRAY_SHORT: ARRAY(Short); break;
case CVT_ARRAY_CHAR: ARRAY(Char); break;
case CVT_ARRAY_INT: ARRAY(Int); break;
case CVT_ARRAY_LONG: ARRAY(Long); break;
case CVT_ARRAY_FLOAT: ARRAY(Float); break;
case CVT_ARRAY_DOUBLE: ARRAY(Double); break;
default:
break;
}
}
}
+18
Ver Arquivo
@@ -712,6 +712,24 @@ fillInt64Buffer(int64_t *buf, int len, int64_t value) {
return len;
}
EXPORT int32_t
fillFloatBuffer(float *buf, int len, float value) {
int i;
for (i=0;i < len;i++) {
buf[i] = value;
}
return len;
}
EXPORT int32_t
fillDoubleBuffer(double *buf, int len, double value) {
int i;
for (i=0;i < len;i++) {
buf[i] = value;
}
return len;
}
EXPORT int32_t
addInt32VarArgs(const char *fmt, ...) {
va_list ap;
+1 -2
Ver Arquivo
@@ -6,7 +6,7 @@
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<packaging>jar</packaging>
<version>3.2.1</version>
<version>3.2.2</version>
<name>Java Native Access</name>
<distributionManagement>
@@ -33,7 +33,6 @@
<tasks>
<!--<ant dir="." target="dist" />-->
<attachArtifact file="dist/jna.jar" />
<attachArtifact file="dist/examples.jar" />
<attachArtifact file="dist/src-mvn.zip" classifier="sources" type="jar"/>
</tasks>
</configuration>
+17
Ver Arquivo
@@ -1,4 +1,21 @@
<a name="top"></a>
<h2>Release 3.2.2</h2>
<b>Features</b><br>
<ul>
<li>Provide length-specified Pointer.getStringArray()
</ul>
<b>Bug Fixes</b><br>
<ul>
<li>Fix crash with direct mapping if NULL struct* used (<a href="https://jna.dev.java.net/issues/show_bug.cgi?id=125">Issue 125</a>).
<li>Fix case where null-valued Structure fields would get non-null values on
write.
<li>Synch callback Structure/Structure[] arguments on callback return.
<li>Fix NPE when mapping an interface to the current process.
<li>Automatically load proper C library version from current process on Linux
(avoids crashing bug on Ubuntu with libc-i686 packages active).
<li>Avoid scanning structure contents in Structure.toString if contents aren't
actually used.
</ul>
<h2>Release 3.2.1</h2>
<b>Features</b><br>
<ul>
@@ -393,6 +393,14 @@ class CallbackReference extends WeakReference {
Native.getCallbackExceptionHandler().uncaughtException(cb, e.getTargetException());
}
}
// Synch any structure arguments back to native memory
for (int i=0;i < callbackArgs.length;i++) {
if (callbackArgs[i] instanceof Structure
&& !(callbackArgs[i] instanceof Structure.ByValue)) {
((Structure)callbackArgs[i]).autoWrite();
}
}
return result;
}
/** Called from native code. All arguments are in an array of
+3 -16
Ver Arquivo
@@ -268,10 +268,7 @@ public class Function extends Pointer {
}
}
else if (Structure[].class.isAssignableFrom(inArg.getClass())) {
Structure[] ss = (Structure[])inArg;
for (int si=0;si < ss.length;si++) {
ss[si].autoRead();
}
Structure.autoRead((Structure[])inArg);
}
}
}
@@ -495,18 +492,8 @@ public class Function extends Pointer {
return ss[0].getPointer();
}
else {
Pointer base = ss[0].getPointer();
int size = ss[0].size();
ss[0].autoWrite();
for (int si=1;si < ss.length;si++) {
if (ss[si].getPointer().peer != base.peer + size*si) {
String msg = "Structure array elements must use"
+ " contiguous memory (at element index " + si + ")";
throw new IllegalArgumentException(msg);
}
ss[si].autoWrite();
}
return base;
Structure.autoWrite(ss);
return ss[0].getPointer();
}
}
else if (argClass.isArray()){
+1 -1
Ver Arquivo
@@ -122,7 +122,7 @@ public interface Library {
private final Map functions = new WeakHashMap();
public Handler(String libname, Class interfaceClass, Map options) {
if ("".equals(libname.trim())) {
if (libname != null && "".equals(libname.trim())) {
throw new IllegalArgumentException("Invalid library name \""
+ libname + "\"");
}
+11 -2
Ver Arquivo
@@ -137,7 +137,9 @@ public class NativeLibrary {
//
libraryPath = matchLibrary(libraryName, searchPath);
if (libraryPath != null) {
try { handle = open(libraryPath); }
try {
handle = open(libraryPath);
}
catch(UnsatisfiedLinkError e2) { e = e2; }
}
}
@@ -146,7 +148,9 @@ public class NativeLibrary {
libraryPath = "/System/Library/Frameworks/" + libraryName
+ ".framework/" + libraryName;
if (new File(libraryPath).exists()) {
try { handle = open(libraryPath); }
try {
handle = open(libraryPath);
}
catch(UnsatisfiedLinkError e2) { e = e2; }
}
}
@@ -216,6 +220,11 @@ public class NativeLibrary {
options.put(Library.OPTION_CALLING_CONVENTION, new Integer(Function.C_CONVENTION));
}
// Use current process to load libraries we know are already
// loaded by the VM to ensure we get the correct version
if (Platform.isLinux() && "c".equals(libraryName)) {
libraryName = null;
}
synchronized (libraries) {
WeakReference ref = (WeakReference)libraries.get(libraryName + options);
NativeLibrary library = ref != null ? (NativeLibrary)ref.get() : null;
@@ -66,6 +66,12 @@ public class NativeMappedConverter implements TypeConverter {
}
public Object toNative(Object value, ToNativeContext context) {
return value == null ? defaultValue().toNative() : ((NativeMapped)value).toNative();
if (value == null) {
if (Pointer.class.isAssignableFrom(nativeType)) {
return null;
}
value = defaultValue();
}
return ((NativeMapped)value).toNative();
}
}
+35 -7
Ver Arquivo
@@ -377,6 +377,7 @@ public class Pointer {
//////////////////////////////////////////////////////////////////////////
Object getValue(long offset, Class type, Object currentValue) {
Object result = null;
if (Structure.class.isAssignableFrom(type)) {
Structure s = (Structure)currentValue;
@@ -457,7 +458,7 @@ public class Pointer {
Pointer oldbp = currentValue == null ? null
: Native.getDirectBufferPointer((Buffer)currentValue);
if (oldbp == null || !oldbp.equals(bp)) {
throw new IllegalStateException("Can't autogenerate a direct buffers on memory read");
throw new IllegalStateException("Can't autogenerate a direct buffer on memory read");
}
}
}
@@ -465,7 +466,7 @@ public class Pointer {
NativeMapped nm = (NativeMapped)currentValue;
if (nm != null) {
Object value = getValue(offset, nm.nativeType(), null);
nm.fromNative(value, new FromNativeContext(type));
result = nm.fromNative(value, new FromNativeContext(type));
}
else {
NativeMappedConverter tc = NativeMappedConverter.getInstance(type);
@@ -809,7 +810,14 @@ v * @param wide whether to convert from a wide or standard C string
* NULL-valued terminating element.
*/
public String[] getStringArray(long base) {
return getStringArray(base, false);
return getStringArray(base, -1, false);
}
/** Returns an array of <code>String</code> based on a native array
* of <code>char *</code>, using the given array length.
*/
public String[] getStringArray(long base, int length) {
return getStringArray(base, length, false);
}
/** Returns an array of <code>String</code> based on a native array
@@ -818,13 +826,32 @@ v * @param wide whether to convert from a wide or standard C string
* NULL-valued terminating element.
*/
public String[] getStringArray(long base, boolean wide) {
return getStringArray(base, -1, wide);
}
/** Returns an array of <code>String</code> based on a native array
* of <code>char*</code> or <code>wchar_t*</code> based on the
* <code>wide</code> parameter, using the given array length.
*/
public String[] getStringArray(long base, int length, boolean wide) {
List strings = new ArrayList();
int offset = 0;
Pointer p = getPointer(base);
while (p != null) {
strings.add(p.getString(0, wide));
offset += SIZE;
p = getPointer(base + offset);
if (length != -1) {
int count = 0;
while (count++ < length) {
strings.add(p.getString(0, wide));
offset += SIZE;
p = getPointer(base + offset);
}
}
else {
while (p != null) {
strings.add(p.getString(0, wide));
offset += SIZE;
p = getPointer(base + offset);
}
}
return (String[])strings.toArray(new String[strings.size()]);
}
@@ -834,6 +861,7 @@ v * @param wide whether to convert from a wide or standard C string
//////////////////////////////////////////////////////////////////////////
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);
+106 -45
Ver Arquivo
@@ -220,6 +220,7 @@ public abstract class Structure {
// from the ctor, to ensure fields are properly scanned and allocated
try {
this.memory = m.share(offset, size());
this.array = null;
}
catch(IndexOutOfBoundsException e) {
throw new IllegalArgumentException("Structure exceeds provided memory bounds");
@@ -297,21 +298,57 @@ public abstract class Structure {
will change if structure field values change.
*/
class StructureSet extends AbstractCollection implements Set {
private Collection list = new ArrayList();
public int size() { return list.size(); }
private Structure[] elements;
private int count;
private void ensureCapacity(int size) {
if (elements == null) {
elements = new Structure[size*3/2];
}
else if (elements.length < size) {
Structure[] e = new Structure[size*3/2];
System.arraycopy(elements, 0, e, 0, elements.length);
elements = e;
}
}
public int size() { return count; }
public boolean contains(Object o) {
for (Iterator i=iterator();i.hasNext();) {
if (o == i.next())
return true;
return indexOf(o) != -1;
}
public boolean add(Object o) {
if (!contains(o)) {
ensureCapacity(count+1);
elements[count++] = (Structure)o;
}
return true;
}
private int indexOf(Object o) {
Structure s1 = (Structure)o;
for (int i=0;i < count;i++) {
Structure s2 = (Structure)elements[i];
if (s1 == s2
|| (s1.baseClass() == s2.baseClass()
&& s1.size() == s2.size()
&& s1.getPointer().equals(s2.getPointer()))) {
return i;
}
}
return -1;
}
public boolean remove(Object o) {
int idx = indexOf(o);
if (idx != -1) {
if (--count > 0) {
elements[idx] = elements[count];
elements[count] = null;
}
return true;
}
return false;
}
public boolean add(Object o) {
if (!contains(o))
return list.add(o);
return true;
public Iterator iterator() {
// never actually used
return null;
}
public Iterator iterator() { return list.iterator(); }
}
protected synchronized Object initialValue() {
return new StructureSet();
@@ -820,7 +857,7 @@ public abstract class Structure {
}
public String toString() {
return toString(0);
return toString(0, true);
}
private String format(Class type) {
@@ -829,7 +866,7 @@ public abstract class Structure {
return s.substring(dot + 1);
}
private String toString(int indent) {
private String toString(int indent, boolean showContents) {
String LS = System.getProperty("line.separator");
String name = format(getClass()) + "(" + getPointer() + ")";
if (!(getPointer() instanceof Memory)) {
@@ -839,9 +876,11 @@ public abstract class Structure {
for (int idx=0;idx < indent;idx++) {
prefix += " ";
}
String contents = "";
// Write all fields
for (Iterator i=structFields.values().iterator();i.hasNext();) {
String contents = LS;
if (!showContents) {
contents = "...}";
}
else for (Iterator i=structFields.values().iterator();i.hasNext();) {
StructField sf = (StructField)i.next();
Object value = getField(sf);
String type = format(sf.type);
@@ -854,16 +893,7 @@ public abstract class Structure {
contents += " " + type + " "
+ sf.name + index + "@" + Integer.toHexString(sf.offset);
if (value instanceof Structure) {
if (value instanceof Structure.ByReference) {
String v = value.toString();
if (v.indexOf(LS) != -1) {
v = v.substring(0, v.indexOf(LS));
}
value = v + "...}";
}
else {
value = ((Structure)value).toString(indent + 1);
}
value = ((Structure)value).toString(indent + 1, !(value instanceof Structure.ByReference));
}
contents += "=";
if (value instanceof Long) {
@@ -899,7 +929,7 @@ public abstract class Structure {
}
contents += "]";
}
return name + " {" + LS + contents;
return name + " {" + contents;
}
/** Returns a view of this structure's memory as an array of structures.
@@ -927,7 +957,8 @@ public abstract class Structure {
array[i].read();
}
if (this instanceof ByReference) {
if (!(this instanceof ByValue)) {
// keep track for later auto-read/writes
this.array = array;
}
@@ -943,6 +974,15 @@ public abstract class Structure {
return toArray((Structure[])Array.newInstance(getClass(), size));
}
private Class baseClass() {
if ((this instanceof Structure.ByReference
|| this instanceof Structure.ByValue)
&& Structure.class.isAssignableFrom(getClass().getSuperclass())) {
return getClass().getSuperclass();
}
return getClass();
}
/** This structure is only equal to another based on the same native
* memory address and data type.
*/
@@ -951,24 +991,9 @@ public abstract class Structure {
return true;
if (o == null)
return false;
if (o.getClass() != getClass()) {
// Only allow one class derived from the other and implementing
// ByReference or ByValue, or both implementing
// ByReference/ByValue on the same base class
if (!((o.getClass().isAssignableFrom(getClass())
&& (ByReference.class.isAssignableFrom(getClass())
|| ByValue.class.isAssignableFrom(getClass())))
|| (getClass().isAssignableFrom(o.getClass())
&& (ByReference.class.isAssignableFrom(o.getClass())
|| ByValue.class.isAssignableFrom(o.getClass())))
|| ((ByReference.class.isAssignableFrom(o.getClass())
|| ByValue.class.isAssignableFrom(o.getClass()))
&& (ByReference.class.isAssignableFrom(getClass())
|| ByValue.class.isAssignableFrom(getClass()))
&& (o.getClass().getSuperclass()
== getClass().getSuperclass())))) {
return false;
}
if (o.getClass() != getClass()
&& ((Structure)o).baseClass() != baseClass()) {
return false;
}
Structure s = (Structure)o;
if (s.size() == size()) {
@@ -1233,6 +1258,30 @@ public abstract class Structure {
}
}
private static void structureArrayCheck(Structure[] ss) {
Pointer base = ss[0].getPointer();
int size = ss[0].size();
for (int si=1;si < ss.length;si++) {
if (ss[si].getPointer().peer != base.peer + size*si) {
String msg = "Structure array elements must use"
+ " contiguous memory (bad backing address at Structure array index " + si + ")";
throw new IllegalArgumentException(msg);
}
}
}
public static void autoRead(Structure[] ss) {
structureArrayCheck(ss);
if (ss[0].array == ss) {
ss[0].autoRead();
}
else {
for (int si=0;si < ss.length;si++) {
ss[si].autoRead();
}
}
}
public void autoRead() {
if (getAutoRead()) {
read();
@@ -1244,6 +1293,18 @@ public abstract class Structure {
}
}
public static void autoWrite(Structure[] ss) {
structureArrayCheck(ss);
if (ss[0].array == ss) {
ss[0].autoWrite();
}
else {
for (int si=0;si < ss.length;si++) {
ss[si].autoWrite();
}
}
}
public void autoWrite() {
if (getAutoWrite()) {
write();
@@ -14,6 +14,8 @@ package com.sun.jna;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.DoubleBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.LongBuffer;
import java.nio.ShortBuffer;
@@ -81,17 +83,23 @@ public class ArgumentsMarshalTest extends TestCase {
int fillInt16Buffer(short[] buf, int len, short value);
int fillInt32Buffer(int[] buf, int len, int value);
int fillInt64Buffer(long[] buf, int len, long value);
int fillFloatBuffer(float[] buf, int len, float value);
int fillDoubleBuffer(double[] buf, int len, double value);
// ByteBuffer alternative definitions
int fillInt8Buffer(ByteBuffer buf, int len, byte value);
int fillInt16Buffer(ByteBuffer buf, int len, short value);
int fillInt32Buffer(ByteBuffer buf, int len, int value);
int fillInt64Buffer(ByteBuffer buf, int len, long value);
int fillFloatBuffer(ByteBuffer buf, int len, float value);
int fillDoubleBuffer(ByteBuffer buf, int len, double value);
// {Short,Int,Long}Buffer alternative definitions
// {Short|Int|Long|,Float|Double}Buffer alternative definitions
int fillInt16Buffer(ShortBuffer buf, int len, short value);
int fillInt32Buffer(IntBuffer buf, int len, int value);
int fillInt64Buffer(LongBuffer buf, int len, long value);
int fillFloatBuffer(FloatBuffer buf, int len, float value);
int fillDoubleBuffer(DoubleBuffer buf, int len, double value);
// Nonexistent functions
boolean returnBooleanArgument(Object arg);
@@ -323,6 +331,10 @@ public class ArgumentsMarshalTest extends TestCase {
+ "parameter type, not argument type",
struct.getPointer(),
lib.testStructurePointerArgument(struct));
struct = null;
assertNull("Null argument should be returned",
lib.testStructurePointerArgument(struct));
}
public void testStructureByValueArgument() {
@@ -353,7 +365,6 @@ public class ArgumentsMarshalTest extends TestCase {
public void testWriteStructureArrayArgumentMemory() {
final int LENGTH = 10;
TestLibrary.CheckFieldAlignment block = new TestLibrary.CheckFieldAlignment();
block.useMemory(new Memory(block.size() * LENGTH));
TestLibrary.CheckFieldAlignment[] array =
(TestLibrary.CheckFieldAlignment[])block.toArray(LENGTH);
for (int i=0;i < array.length;i++) {
@@ -508,6 +519,67 @@ public class ArgumentsMarshalTest extends TestCase {
}
}
public void testWrappedByteArrayArgument() {
byte[] array = new byte[1024];
ByteBuffer buf = ByteBuffer.wrap(array, 512, 512).slice();
final byte MAGIC = (byte)0xAB;
lib.fillInt8Buffer(buf, 512, MAGIC);
for (int i=0;i < array.length;i++) {
assertEquals("Bad value at index " + i,
i < 512 ? 0 : MAGIC, array[i]);
}
}
public void testWrappedShortArrayArgument() {
short[] array = new short[1024];
ShortBuffer buf = ShortBuffer.wrap(array, 512, 512).slice();
final short MAGIC = (short)0xABED;
lib.fillInt16Buffer(buf, 512, MAGIC);
for (int i=0;i < array.length;i++) {
assertEquals("Bad value at index " + i,
i < 512 ? 0 : MAGIC, array[i]);
}
}
public void testWrappedIntArrayArgument() {
int[] array = new int[1024];
IntBuffer buf = IntBuffer.wrap(array, 512, 512).slice();
final int MAGIC = 0xABEDCF23;
lib.fillInt32Buffer(buf, 512, MAGIC);
for (int i=0;i < array.length;i++) {
assertEquals("Bad value at index " + i,
i < 512 ? 0 : MAGIC, array[i]);
}
}
public void testWrappedLongArrayArguent() {
long[] array = new long[1024];
LongBuffer buf = LongBuffer.wrap(array, 512, 512).slice();
final long MAGIC = 0x1234567887654321L;
lib.fillInt64Buffer(buf, 512, MAGIC);
for (int i=0;i < array.length;i++) {
assertEquals("Bad value at index " + i,
i < 512 ? 0 : MAGIC, array[i]);
}
}
public void testWrappedFloatArrayArguent() {
float[] array = new float[1024];
FloatBuffer buf = FloatBuffer.wrap(array, 512, 512).slice();
final float MAGIC = -118.625f;
lib.fillFloatBuffer(buf, 512, MAGIC);
for (int i=0;i < array.length;i++) {
assertEquals("Bad value at index " + i,
i < 512 ? 0 : MAGIC, array[i]);
}
}
public void testWrappedDoubleArrayArguent() {
double[] array = new double[1024];
DoubleBuffer buf = DoubleBuffer.wrap(array, 512, 512).slice();
final double MAGIC = -118.625;
lib.fillDoubleBuffer(buf, 512, MAGIC);
for (int i=0;i < array.length;i++) {
assertEquals("Bad value at index " + i,
i < 512 ? 0 : MAGIC, array[i]);
}
}
public void testInvalidArgument() {
try {
lib.returnBooleanArgument(this);
+30 -4
Ver Arquivo
@@ -354,19 +354,45 @@ public class CallbacksTest extends TestCase {
public void testCallStructureCallback() {
final boolean[] called = {false};
final Structure[] cbarg = { null };
final Pointer[] cbarg = { null };
final SmallTestStructure s = new SmallTestStructure();
final double MAGIC = 118.625;
TestLibrary.StructureCallback cb = new TestLibrary.StructureCallback() {
public SmallTestStructure callback(SmallTestStructure arg) {
called[0] = true;
cbarg[0] = arg;
cbarg[0] = arg.getPointer();
arg.value = MAGIC;
return arg;
}
};
SmallTestStructure value = lib.callStructureCallback(cb, s);
assertTrue("Callback not called", called[0]);
assertEquals("Wrong argument passed to callback", s, cbarg[0]);
assertEquals("Wrong structure return", s, value);
assertEquals("Wrong argument passed to callback", s.getPointer(), cbarg[0]);
assertEquals("Structure argument not synched on callback return",
MAGIC, s.value);
assertEquals("Wrong structure return", s.getPointer(), value.getPointer());
assertEquals("Structure return not synched",
MAGIC, value.value);
}
public void testCallStructureArrayCallback() {
final SmallTestStructure s = new SmallTestStructure();
final SmallTestStructure[] array = (SmallTestStructure[])s.toArray(2);
final double MAGIC = 118.625;
TestLibrary.StructureCallback cb = new TestLibrary.StructureCallback() {
public SmallTestStructure callback(SmallTestStructure arg) {
SmallTestStructure[] array =
(SmallTestStructure[])arg.toArray(2);
array[0].value = MAGIC;
array[1].value = MAGIC*2;
return arg;
}
};
SmallTestStructure value = lib.callStructureCallback(cb, s);
assertEquals("Structure array element 0 not synched on callback return",
MAGIC, array[0].value);
assertEquals("Structure array element 1 not synched on callback return",
MAGIC*2, array[1].value);
}
public void testCallBooleanCallback() {
@@ -13,6 +13,8 @@
package com.sun.jna;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.DoubleBuffer;
import java.nio.IntBuffer;
import java.nio.LongBuffer;
import java.nio.ShortBuffer;
@@ -60,17 +62,23 @@ public class DirectArgumentsMarshalTest extends ArgumentsMarshalTest {
public native int fillInt16Buffer(short[] buf, int len, short value);
public native int fillInt32Buffer(int[] buf, int len, int value);
public native int fillInt64Buffer(long[] buf, int len, long value);
public native int fillFloatBuffer(float[] buf, int len, float value);
public native int fillDoubleBuffer(double[] buf, int len, double value);
// ByteBuffer alternative definitions
public native int fillInt8Buffer(ByteBuffer buf, int len, byte value);
public native int fillInt16Buffer(ByteBuffer buf, int len, short value);
public native int fillInt32Buffer(ByteBuffer buf, int len, int value);
public native int fillInt64Buffer(ByteBuffer buf, int len, long value);
public native int fillFloatBuffer(ByteBuffer buf, int len, float value);
public native int fillDoubleBuffer(ByteBuffer buf, int len, double value);
// {Short,Int,Long}Buffer alternative definitions
// {Short|Int|Long|Float|Double}Buffer alternative definitions
public native int fillInt16Buffer(ShortBuffer buf, int len, short value);
public native int fillInt32Buffer(IntBuffer buf, int len, int value);
public native int fillInt64Buffer(LongBuffer buf, int len, long value);
public native int fillFloatBuffer(FloatBuffer buf, int len, float value);
public native int fillDoubleBuffer(DoubleBuffer buf, int len, double value);
// dummy to avoid causing Native.register to fail
public boolean returnBooleanArgument(Object arg) {throw new IllegalArgumentException();}
@@ -0,0 +1,42 @@
/* 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.
* <p/>
* 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.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 {
public static void main(java.lang.String[] argList) {
junit.textui.TestRunner.run(DirectStructureByValueTest.class);
}
public static class DirectTestLibrary implements TestLibrary {
public native byte testStructureByValueArgument8(ByValue8 arg);
public native short testStructureByValueArgument16(ByValue16 arg);
public native int testStructureByValueArgument32(ByValue32 arg);
public native long testStructureByValueArgument64(ByValue64 arg);
public native long testStructureByValueArgument128(ByValue128 arg);
static {
Native.register("testlib");
}
}
protected void setUp() {
lib = new DirectTestLibrary();
}
}
+13
Ver Arquivo
@@ -51,6 +51,9 @@ public class LibraryLoadTest extends TestCase {
int wcslen(WString wstr);
int strlen(String str);
int atol(String str);
Pointer getpwuid(int uid);
int geteuid();
}
public void testLoadAWTAfterJNA() {
@@ -144,6 +147,16 @@ public class LibraryLoadTest extends TestCase {
}
}
// Ubuntu bug when arch-specific libc is active
// Only fails on *some* functions
public void testLoadProperCLibraryVersion() {
if (Platform.isWindows()) return;
CLibrary lib = (CLibrary)Native.loadLibrary("c", CLibrary.class);
assertNotNull("Couldn't get current user",
lib.getpwuid(lib.geteuid()));
}
public static void main(String[] args) {
junit.textui.TestRunner.run(LibraryLoadTest.class);
}
+22
Ver Arquivo
@@ -19,6 +19,7 @@ import java.nio.DoubleBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.LongBuffer;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
@@ -256,6 +257,27 @@ public class PointerTest extends TestCase {
assertEquals("Wrong value", tp, p.getValue(0, TestPointerType.class, null));
}
public void testGetStringArray() {
Pointer p = new Memory(Pointer.SIZE*3);
String VALUE1 = getName();
String VALUE2 = getName() + "2";
p.setPointer(0, new NativeString(VALUE1).getPointer());
p.setPointer(Pointer.SIZE, new NativeString(VALUE2).getPointer());
p.setPointer(Pointer.SIZE*2, null);
assertEquals("Wrong null-terminated String array",
Arrays.asList(new String[] { VALUE1, VALUE2 }),
Arrays.asList(p.getStringArray(0)));
assertEquals("Wrong length-specified String array (1)",
Arrays.asList(new String[] { VALUE1 }),
Arrays.asList(p.getStringArray(0, 1)));
assertEquals("Wrong length-specified String array (2)",
Arrays.asList(new String[] { VALUE1, VALUE2 }),
Arrays.asList(p.getStringArray(0, 2)));
}
public static void main(String[] args) {
junit.textui.TestRunner.run(PointerTest.class);
}
+46 -8
Ver Arquivo
@@ -730,7 +730,7 @@ public class StructureTest extends TestCase {
s.s1 = new StructureTest.PublicTestStructure.ByReference();
s.s1.x = -1;
s.write();
assertEquals("Structure.ByReference not written automatically",
assertEquals("Structure.ByReference field not written automatically",
-1, s.s1.getPointer().getInt(0));
}
@@ -860,11 +860,34 @@ public class StructureTest extends TestCase {
public void testNativeMappedWrite() {
class TestStructure extends Structure {
public ByteByReference ref;
public ByteByReference ref;
}
TestStructure s = new TestStructure();
ByteByReference ref = s.ref = new ByteByReference();
s.write();
assertEquals("Value not properly written", ref.getPointer(), s.getPointer().getPointer(0));
s.ref = null;
s.write();
assertNull("Non-null value was written: " + s.getPointer().getPointer(0), s.getPointer().getPointer(0));
}
public void testNativeMappedRead() {
class TestStructure extends Structure {
public ByteByReference ref;
}
TestStructure s = new TestStructure();
s.read();
assertNull("Should read null for initial field value", s.ref);
ByteByReference ref = new ByteByReference();
s.getPointer().setPointer(0, ref.getPointer());
s.read();
assertEquals("Field incorrectly read", ref, s.ref);
s.getPointer().setPointer(0, null);
s.read();
assertNull("Null field incorrectly read", s.ref);
}
public static class ROStructure extends Structure {
@@ -1075,16 +1098,31 @@ public class StructureTest extends TestCase {
assertTrue("Structure equals should ignore padding", s1.equals(s2));
}
public void testRecursiveReadWrite() {
public void testRecursiveReadWriteDetection() {
class TestStructureByRef extends Structure implements Structure.ByReference{
public TestStructureByRef(Pointer p) { super(p); }
public TestStructureByRef() { }
public int unique;
public TestStructureByRef s;
}
TestStructureByRef s = new TestStructureByRef();
s.s = s;
s.write();
s.read();
s.s = new TestStructureByRef();
s.unique = 1;
s.s.s = s;
s.s.unique = 2;
assertEquals("Temporary storage should be cleared",
0, s.busy().size());
s.write();
assertEquals("Structure field contents not written",
1, s.getPointer().getInt(0));
assertEquals("ByReference structure field contents not written",
2, s.s.getPointer().getInt(0));
s.s.unique = 0;
s.read();
assertEquals("ByReference structure field contents not read",
2, s.s.unique);
assertTrue("Temporary storage should be cleared",
s.busy().isEmpty());
}
}
+52 -31
Ver Arquivo
@@ -14,6 +14,7 @@ package com.sun.jna;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import java.awt.GraphicsEnvironment;
import java.io.File;
@@ -31,7 +32,9 @@ import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Enumeration;
import java.util.Map;
import java.util.Properties;
import java.util.Iterator;
import junit.framework.AssertionFailedError;
import junit.framework.Test;
@@ -66,7 +69,10 @@ public class WebStartTest extends TestCase {
// but will cause unsigned jars to fail (irrespective of policy)
+ " <security><all-permissions/></security>\n"
+ " <resources>\n"
+ " <j2se version='1.4+'/>\n"
// Explicitly supply javawebstart.version, which is missing in NetX
// Boo, java-vm-args doesn't work in NetX
// and neither does javaws -J<arg>
+ " <j2se version='1.4+' java-vm-args='-Djavawebstart.version=0.0'/>\n"
+ " <jar href='jna-test.jar'/>\n"
+ " <jar href='jna.jar'/>\n"
+ " <jar href='junit.jar'/>{CLOVER}\n"
@@ -77,6 +83,8 @@ public class WebStartTest extends TestCase {
+ " <argument>{CLASS}</argument>\n"
+ " <argument>{METHOD}</argument>\n"
+ " <argument>{PORT}</argument>\n"
// NetX doesn't set javawebstart.version, so explicitly flag it
+ " <argument>javawebstart</argument>\n"
+ " </application-desc>\n"
+ "</jnlp>";
@@ -139,7 +147,7 @@ public class WebStartTest extends TestCase {
String path = findJWS();
String[] cmd = {
path,
"-Xnosplash",
"-Xnosplash",
"-wait",
jnlp.toURI().toURL().toString(),
};
@@ -258,42 +266,38 @@ public class WebStartTest extends TestCase {
private String findJWS() throws IOException {
String JAVA_HOME = System.getProperty("java.home");
String BIN = new File(JAVA_HOME, "/bin").getAbsolutePath();
String LIB = new File(JAVA_HOME, "/lib").getAbsolutePath();
if (!new File(LIB, "javaws.jar").exists()) {
LIB = new File("/System/Library/Frameworks/JavaVM.framework/Resources/Deploy.bundle/Contents/Home/lib").getAbsolutePath();
if (!new File(LIB, "javaws.jar").exists()) {
if (!Platform.isWindows())
throw new IOException("javaws.jar not found");
}
}
String PS = System.getProperty("path.separator");
String path = System.getProperty("java.home") + "/bin/javaws";
File javaws = new File(path);
// NOTE: OSX puts javaws somewhere else entirely
// NOTE: win64 only includes javaws in the system path
File javaws = new File(BIN, "javaws" + (Platform.isWindows()?".exe":""));
if (!javaws.exists()) {
// NOTE: OSX puts javaws somewhere else entirely
if (Platform.isMac()) {
javaws = new File(JAVA_HOME, "../Commands/javaws");
}
// NOTE: win64 only includes javaws in the system path
if (Platform.isWindows()) {
FolderInfo info = (FolderInfo)
Native.loadLibrary("shell32", FolderInfo.class);
char[] buf = new char[FolderInfo.MAX_PATH];
int flags = 0;
int result = info.SHGetFolderPathW(null, FolderInfo.CSIDL_WINDOWS, null, 0, buf);
path = Native.toString(buf);
String path = Native.toString(buf);
if (Platform.is64Bit()) {
javaws = new File(path, "SysWOW64/javaws.exe");
}
else {
javaws = new File(path, "system32/javaws.exe");
}
path = javaws.getAbsolutePath();
}
else {
path = javaws.getName();
if (!javaws.exists()) {
throw new IOException("javaws executable not found");
}
}
return path;
return javaws.getAbsolutePath();
}
// TODO: find some way of querying the current VM for the deployment
// properties path
private File findDeploymentProperties() {
String path = System.getProperty("user.home");
File deployment;
@@ -402,27 +406,44 @@ public class WebStartTest extends TestCase {
}
private static void showMessage(String msg) {
showMessage(msg, 60000);
}
private static void showMessage(String msg, int timeout) {
JFrame f = new JFrame("Web Start Test Failure");
f.getContentPane().add(new JLabel(msg));
f.getContentPane().add(new JScrollPane(new JLabel(msg)));
f.pack();
f.setLocation(100, 100);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
try { Thread.sleep(60000); } catch(Exception e) { }
if (timeout != 0) {
try { Thread.sleep(timeout); } catch(Exception e) { }
}
}
public static void main(String[] args) {
if (runningWebStart()) {
String testClass = args.length > 0
? args[0] : WebStartTest.class.getName();
String testMethod = args.length > 1
? args[1] : "testLaunchedUnderWebStart";
int port = args.length > 2
? Integer.parseInt(args[2]) : 8080;
runTestCaseTest(testClass, testMethod, port);
try {
if (args.length == 4
&& "javawebstart".equals(args[3])
&& !runningWebStart()) {
System.setProperty("javawebstart.version", "fake");
}
if (runningWebStart()) {
String testClass = args.length > 0
? args[0] : WebStartTest.class.getName();
String testMethod = args.length > 1
? args[1] : "testLaunchedUnderWebStart";
int port = args.length > 2
? Integer.parseInt(args[2]) : 8080;
runTestCaseTest(testClass, testMethod, port);
}
else {
junit.textui.TestRunner.run(WebStartTest.class);
}
}
else {
junit.textui.TestRunner.run(WebStartTest.class);
catch(Throwable t) {
showMessage("ERROR: " + t.getMessage());
}
}
}