src.org.python.modules.jffi.Structure 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 java.util.List;
import org.python.core.Py;
import org.python.core.PyNewWrapper;
import org.python.core.PyObject;
import org.python.core.PyType;
import org.python.core.Traverseproc;
import org.python.core.Visitproc;
import org.python.expose.ExposedClassMethod;
import org.python.expose.ExposedNew;
import org.python.expose.ExposedType;
@ExposedType(name = "jffi.Structure", base = CData.class)
public class Structure extends CData implements Pointer, Traverseproc {
public static final PyType TYPE = PyType.fromClass(Structure.class);
private final StructLayout layout;
private final MemoryOp memoryOp;
Structure(PyType pyType, StructLayout layout) {
this(pyType, layout, AllocatedNativeMemory.allocate(layout.size(), true));
}
Structure(PyType pyType, StructLayout layout, Memory m) {
super(pyType, layout);
this.layout = layout;
this.memoryOp = new MemoryOp.StructOp(pyType, layout);
setReferenceMemory(m);
}
@ExposedNew
public static PyObject Structure_new(PyNewWrapper new_, boolean init, PyType subtype,
PyObject[] args, String[] keywords) {
StructLayout layout = getStructLayout(subtype);
Structure s = new Structure(subtype, layout);
if (args.length > 0) {
int n = args.length - keywords.length;
List fields = layout.getFieldList();
Memory m = s.getMemory();
// First, do non-keyword args in order
for (int i = 0; i < n; ++i) {
StructLayout.Field f = fields.get(i);
f.op.put(m, f.offset, args[i]);
}
// Now handle the keyworded args by looking up the field
for (int i = n; i < args.length; ++i) {
StructLayout.Field f = layout.getField(keywords[i - n]);
f.op.put(m, f.offset, args[i]);
}
}
return s;
}
static final StructLayout getStructLayout(PyType subtype) {
PyObject jffi_type = subtype.__getattr__("_jffi_type");
if (!(jffi_type instanceof StructLayout)) {
throw Py.TypeError("invalid _jffi_type for " + subtype.fastGetName() + "; should be instance of jffi.StructLayout");
}
return (StructLayout) jffi_type;
}
@ExposedClassMethod(names= { "from_address" })
public static final PyObject from_address(PyType subtype, PyObject address) {
return new Structure(subtype, getStructLayout(subtype), Util.getMemoryForAddress(address));
}
protected final void initReferenceMemory(Memory m) {
throw Py.RuntimeError("reference memory already initialized");
}
@Override
MemoryOp getMemoryOp() {
return memoryOp;
}
StructLayout.Field getField(PyObject key) {
StructLayout.Field f = layout.getField(key);
if (f == null) {
throw Py.NameError(String.format("struct %s has no field '%s'", getType().fastGetName(), key.toString()));
}
return f;
}
@Override
public PyObject __getitem__(PyObject key) {
StructLayout.Field f = getField(key);
return f.op.get(getReferenceMemory(), f.offset);
}
@Override
public void __setitem__(PyObject key, PyObject value) {
StructLayout.Field f = getField(key);
f.op.put(getReferenceMemory(), f.offset, value);
}
public DirectMemory getMemory() {
return getReferenceMemory();
}
/* Traverseproc implementation */
@Override
public int traverse(Visitproc visit, Object arg) {
if (layout != null) {
int res = visit.visit(layout, arg);
if (res != 0) {
return res;
}
}
return super.traverse(visit, arg);
}
@Override
public boolean refersDirectlyTo(PyObject ob) {
if (ob != null && layout == ob) {
return true;
}
return super.refersDirectlyTo(ob);
}
}