1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package com.ochafik.lang.jnaerator.runtime;
20
21 import com.sun.jna.Memory;
22 import java.lang.ref.WeakReference;
23 import java.lang.reflect.Field;
24 import java.nio.Buffer;
25
26 import com.sun.jna.Native;
27 import com.sun.jna.Pointer;
28 import java.lang.reflect.Array;
29
30 public abstract class Structure<S extends Structure<S, V, R>, V extends S, R extends S>
31 extends com.sun.jna.Structure
32 implements
33 Comparable<Structure<S, V, R>>,
34 StructureType,
35 StructureTypeDependent
36 {
37 public interface ByReference extends com.sun.jna.Structure.ByReference, StructureTypeDependent {}
38 public interface ByValue extends com.sun.jna.Structure.ByValue, StructureTypeDependent {}
39
40 transient WeakReference<StructureType> dependency;
41 @Override
42 public void setDependency(StructureType type) {
43 this.dependency = type == null ? null : new WeakReference<StructureType>(type);
44 }
45 protected void readDependency() {
46 StructureType dep;
47 if (dependency == null || (dep = dependency.get()) == null)
48 return;
49 dep.read();
50 }
51
52 @Override
53 public void read() {
54 super.read();
55 readDependency();
56 }
57 @Override
58 public void write() {
59 super.write();
60 readDependency();
61 }
62
63 protected <T extends Structure<S, V, R>> T setupClone(T clone, StructureType dependency) {
64 write();
65 clone.useMemory(getPointer());
66 clone.setDependency(this);
67 return clone;
68 }
69
70
71
72 protected abstract S newInstance();
73 protected abstract V newByValue();
74 protected abstract R newByReference();
75
76 public R byReference() { return setupClone(newByReference(), this); }
77 public V byValue() { return setupClone(newByValue(), this); }
78 public S clone() { return setupClone(newInstance(), this); }
79
80 public static <S extends Structure>
81 S[] newArray(Class<S> structClass, int arrayLength) {
82 try {
83 S first = structClass.newInstance();
84 int sz = first.size();
85 Memory mem = new Memory(arrayLength * sz);
86 first.use(mem);
87 S[] array = (S[])first.castToArray(arrayLength);
88 for (int i = 1; i < arrayLength; i++) {
89 S s = structClass.newInstance();
90 s.use(mem, i * sz);
91 array[i] = s;
92 }
93 return array;
94 } catch (Exception ex) {
95 throw new RuntimeException(ex);
96 }
97 }
98
99
100
101 @Deprecated
102 @SuppressWarnings("unchecked")
103 @Override
104 public S[] toArray(int size) {
105 return (S[])super.toArray(size);
106 }
107
108
109
110 @Deprecated
111 public S[] toArray() {
112 return toArray(1);
113 }
114
115
116
117 @Deprecated
118 @SuppressWarnings("unchecked")
119 public R[] toReferenceArray(int size) {
120 return (R[])byReference().toArray(size);
121 }
122
123
124
125 @Deprecated
126 @SuppressWarnings("unchecked")
127 public V[] toValueArray(int size) {
128 return (V[])byValue().toArray(size);
129 }
130
131
132
133 @Deprecated
134 public R[] toReferenceArray() {
135 return toReferenceArray(1);
136 }
137
138
139
140 @Deprecated
141 public V[] toValueArray() {
142 return toValueArray(1);
143 }
144
145
146
147
148 @Deprecated
149 @SuppressWarnings("unchecked")
150 @Override
151 public S[] toArray(com.sun.jna.Structure[] array) {
152 return (S[])super.toArray(array);
153 }
154
155 @SuppressWarnings("unchecked")
156 public S[] castToArray(int size) {
157 return (S[])super.toArray(size);
158 }
159 public S[] castToArray() {
160 return castToArray(1);
161 }
162 @SuppressWarnings("unchecked")
163 public R[] castToReferenceArray(int size) {
164 return (R[])byReference().toArray(size);
165 }
166 @SuppressWarnings("unchecked")
167 public V[] castToValueArray(int size) {
168 return (V[])byValue().toArray(size);
169 }
170 public R[] castToReferenceArray() {
171 return castToReferenceArray(1);
172 }
173 public V[] castToValueArray() {
174 return castToValueArray(1);
175 }
176 @SuppressWarnings("unchecked")
177 public S[] castToArray(com.sun.jna.Structure[] array) {
178 return (S[])super.toArray(array);
179 }
180
181
182 @Override
183 protected Integer getBitsAnnotation(Field field) {
184 Bits bits = field.getAnnotation(Bits.class);
185 return bits == null ? null : bits.value();
186 }
187
188
189 @Override
190 public int compareTo(Structure<S, V, R> o) {
191 if (o == this)
192 return 0;
193 if (!(o instanceof Structure<?, ?, ?>))
194 return 1;
195
196 int size = size();
197 int d = size - ((Structure<?, ?, ?>)o).size();
198 if (d != 0)
199 return d;
200
201 Structure<?, ?, ?> s = (Structure<?, ?, ?>)o;
202 if (getPointer().equals(s.getPointer()))
203 return 0;
204
205 write();
206 s.write();
207
208 byte[] bytes1 = getPointer().getByteArray(0, size);
209 byte[] bytes2 = s.getPointer().getByteArray(0, size);
210
211 for (int i = 0; i < size; i++) {
212 byte b1 = bytes1[i], b2 = bytes2[i];
213 if (b1 != b2)
214 return b1 < b2 ? -1 : 1;
215 }
216 return 0;
217 }
218
219 protected <T extends Union<?, ?, ?>> T setupClone(T clone) {
220 write();
221 clone.use(getPointer());
222 return clone;
223 }
224
225 public S use(Pointer m) {
226 return use(m, 0);
227 }
228 public S use(Pointer m, long byteOffset) {
229 useMemory(m, (int)byteOffset);
230 return (S)this;
231 }
232 public S use(Buffer m) {
233 return use(m, 0);
234 }
235 public S use(Buffer b, long byteOffset) {
236 useMemory(Native.getDirectBufferPointer(b), (int)byteOffset);
237 return (S)this;
238 }
239
240 }