All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.python.modules.jffi.Structure Maven / Gradle / Ivy

Go to download

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.

There is a newer version: 2.7.4
Show newest version
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);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy