File: 12-structure-backward-compatibility.patch

package info (click to toggle)
libjna-java 4.5.2-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 9,844 kB
  • sloc: java: 75,159; ansic: 4,781; xml: 4,585; makefile: 434; sh: 235
file content (76 lines) | stat: -rw-r--r-- 3,028 bytes parent folder | download
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