-
Notifications
You must be signed in to change notification settings - Fork 227
Expand file tree
/
Copy pathArrayCData.java
More file actions
191 lines (152 loc) · 5.88 KB
/
ArrayCData.java
File metadata and controls
191 lines (152 loc) · 5.88 KB
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
package org.python.modules.jffi;
import org.python.core.Py;
import org.python.core.PyIterator;
import org.python.core.PyList;
import org.python.core.PyNewWrapper;
import org.python.core.PyObject;
import org.python.core.PySequenceList;
import org.python.core.PyType;
import org.python.core.SequenceIndexDelegate;
import org.python.core.Visitproc;
import org.python.expose.ExposedClassMethod;
import org.python.expose.ExposedNew;
import org.python.expose.ExposedType;
@ExposedType(name = "jffi.ArrayCData", base = CData.class)
public class ArrayCData extends CData implements Pointer {
public static final PyType TYPE = PyType.fromClass(ArrayCData.class);
final CType.Array arrayType;
final CType componentType;
final MemoryOp componentMemoryOp;
ArrayCData(PyType subtype, CType.Array arrayType, DirectMemory memory, MemoryOp componentMemoryOp) {
super(subtype, arrayType, memory);
this.arrayType = arrayType;
this.componentType = arrayType.componentType;
this.componentMemoryOp = componentMemoryOp;
}
@ExposedNew
public static PyObject ArrayCData_new(PyNewWrapper new_, boolean init, PyType subtype,
PyObject[] args, String[] keywords) {
CType.Array arrayType = getArrayType(subtype);
// Only clear the array if it is not going to be completely filled
boolean clear = args.length < arrayType.length;
DirectMemory memory = AllocatedNativeMemory.allocateAligned(arrayType.componentType.size() * arrayType.length,
arrayType.componentType.alignment(), clear);
int offset = 0;
for (PyObject value : args) {
arrayType.componentMemoryOp.put(memory, offset, value);
offset += arrayType.componentType.size();
}
return new ArrayCData(subtype, arrayType, memory, arrayType.componentMemoryOp);
}
static final CType.Array getArrayType(PyType subtype) {
PyObject jffi_type = subtype.__getattr__("_jffi_type");
if (!(jffi_type instanceof CType.Array)) {
throw Py.TypeError("invalid _jffi_type for " + subtype.getName());
}
return (CType.Array) jffi_type;
}
@ExposedClassMethod(names= { "from_address" })
public static final PyObject from_address(PyType subtype, PyObject address) {
CType.Array arrayType = getArrayType(subtype);
DirectMemory m = Util.getMemoryForAddress(address);
PointerCData cdata = new PointerCData(subtype, arrayType, m.getMemory(0), arrayType.componentMemoryOp);
cdata.setReferenceMemory(m);
return cdata;
}
public final DirectMemory getMemory() {
return getReferenceMemory();
}
protected final void initReferenceMemory(Memory m) {
// Nothing to do, since the reference memory was initialized during construction
}
@Override
public PyObject __finditem__(int index) {
return delegator.checkIdxAndFindItem(index);
}
@Override
public PyObject __getitem__(PyObject index) {
return delegator.checkIdxAndGetItem(index);
}
@Override
public void __setitem__(int index, PyObject value) {
delegator.checkIdxAndSetItem(index, value);
}
@Override
public void __setitem__(PyObject index, PyObject value) {
delegator.checkIdxAndSetItem(index, value);
}
@Override
public void __delitem__(PyObject key) {
throw Py.TypeError("Array does not support item deletion");
}
@Override
public PyObject __iter__() {
return new ArrayIter();
}
protected final SequenceIndexDelegate delegator = new SequenceIndexDelegate() {
@Override
public String getTypeName() {
return getType().fastGetName();
}
@Override
public void setItem(int idx, PyObject value) {
componentMemoryOp.put(getReferenceMemory(), idx * componentType.size(), value);
}
@Override
public void setSlice(int start, int stop, int step, PyObject value) {
if (!(value instanceof PySequenceList)) {
throw Py.TypeError("expected list or tuple");
}
PySequenceList list = (PySequenceList) value;
for (int i = 0; i < stop - start; ++i) {
setItem(start + i, list.pyget(i));
}
}
@Override
public int len() {
return arrayType.length;
}
@Override
public void delItem(int idx) {
throw Py.TypeError("Array does not support item deletion");
}
@Override
public void delItems(int start, int stop) {
throw Py.TypeError("Array does not support item deletion");
}
@Override
public PyObject getItem(int idx) {
return componentMemoryOp.get(getReferenceMemory(), idx * componentType.size());
}
@Override
public PyObject getSlice(int start, int stop, int step) {
PyObject[] result = new PyObject[stop - start];
for (int i = 0; i < result.length; ++i) {
result[i] = getItem(start + i);
}
return new PyList(result);
}
};
public class ArrayIter extends PyIterator {
private int index = 0;
public PyObject __iternext__() {
if (index >= arrayType.length) {
return null;
}
return componentMemoryOp.get(getReferenceMemory(), index++ * componentType.size());
}
}
/* Traverseproc implementation */
@Override
public int traverse(Visitproc visit, Object arg) {
int retVal = super.traverse(visit, arg);
if (retVal != 0) {
return retVal;
}
return componentType != null ? visit.visit(componentType, arg) : 0;
}
@Override
public boolean refersDirectlyTo(PyObject ob) {
return ob != null && (componentType == ob || super.refersDirectlyTo(ob));
}
}