src.org.python.modules.jffi.ArrayCData Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jython Show documentation
Show all versions of jython Show documentation
Jython is an implementation of the high-level, dynamic, object-oriented
language Python written in 100% Pure Java, and seamlessly integrated with
the Java platform. It thus allows you to run Python on any Java platform.
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));
}
}