1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
|
Description: Provide a default implementation of the abstract Structure.getFieldOrder()
method to preserve the compatibility with JNA < 3.5.0. The implementation is derived
from the JNA 3.4.2 code.
Author: Emmanuel Bourg <ebourg@apache.org>
Forwarded: not-needed
--- a/src/com/sun/jna/Structure.java
+++ b/src/com/sun/jna/Structure.java
@@ -116,6 +116,34 @@
*/
public interface ByReference { }
+ private static class MemberOrder {
+ private static final String[] FIELDS = { "first", "second", "middle", "penultimate", "last" };
+ public int first;
+ public int second;
+ public int middle;
+ public int penultimate;
+ public int last;
+ }
+
+ private static final boolean REVERSE_FIELDS;
+ private static final boolean REQUIRES_FIELD_ORDER;
+
+ static {
+ // Check for predictable field order; IBM and JRockit store fields in
+ // reverse order; Excelsior JET requires explicit order
+ Field[] fields = MemberOrder.class.getFields();
+ List names = new ArrayList();
+ for (int i=0; i < fields.length; i++) {
+ names.add(fields[i].getName());
+ }
+ List expected = Arrays.asList(MemberOrder.FIELDS);
+ List reversed = new ArrayList(expected);
+ Collections.reverse(reversed);
+
+ REVERSE_FIELDS = names.equals(reversed);
+ REQUIRES_FIELD_ORDER = !(names.equals(expected) || REVERSE_FIELDS);
+ }
+
/** Use the platform default alignment. */
public static final int ALIGN_DEFAULT = 0;
/** No alignment, place all fields on nearest 1-byte boundary */
@@ -888,7 +916,32 @@
* guaranteed to be predictable.
* @return ordered list of field names
*/
- protected abstract List<String> getFieldOrder();
+ protected List<String> getFieldOrder() {
+ if (REQUIRES_FIELD_ORDER) {
+ throw new Error("This VM does not store fields in a predictable order; you must implement Structure.getFieldOrder on " + getClass() + " to explicitly indicate the field order: " + System.getProperty("java.vendor") + ", " + System.getProperty("java.version"));
+ }
+
+ return getFieldNames();
+ }
+
+ private List<String> getFieldNames() {
+ List<String> names = new ArrayList<String>();
+ for (Class cls = getClass(); !cls.equals(Structure.class); cls = cls.getSuperclass()) {
+ List<String> fields = new ArrayList<String>();
+ for (Field field : cls.getDeclaredFields()) {
+ int modifiers = field.getModifiers();
+ if (Modifier.isStatic(modifiers) || !Modifier.isPublic(modifiers)) {
+ continue;
+ }
+ fields.add(field.getName());
+ }
+ if (REVERSE_FIELDS) {
+ Collections.reverse(fields);
+ }
+ names.addAll(0, fields);
+ }
+ return names;
+ }
/**
* Force a compile-time error on the old method of field definition
|