#ifndef _PY_TRIPLE_OBJ_H #define _PY_TRIPLE_OBJ_H #define PY_SSIZE_T_CLEAN #include #include #include "py_term.h" typedef struct { PyObject_HEAD LSUP_Triple * ob_struct; PyObject *s; PyObject *p; PyObject *o; } TripleObject; static int Triple_init (TripleObject *self, PyObject *args) { PyObject *s = NULL, *p = NULL, *o = NULL, *tmp; if (! PyArg_ParseTuple (args, "OOO", &s, &p, &o)) return -1; // TODO check for null s, p, o tmp = self->s; Py_INCREF(s); self->s = s; Py_XDECREF(tmp); tmp = self->p; Py_INCREF(p); self->p = p; Py_XDECREF(tmp); tmp = self->o; Py_INCREF(o); self->o = o; Py_XDECREF(tmp); self->ob_struct = LSUP_triple_new ( ((TermObject *) self->s)->ob_struct, ((TermObject *) self->p)->ob_struct, ((TermObject *) self->o)->ob_struct); if (!self->ob_struct) { PyErr_SetString (PyExc_ValueError, "Could not create triple."); return -1; } return 0; } static void Triple_dealloc (TripleObject *self) { Py_XDECREF(self->s); Py_XDECREF(self->p); Py_XDECREF(self->o); free (self->ob_struct); // Term pointers were allocated independently. Py_TYPE (self)->tp_free ((PyObject *) self); } static PyMemberDef Triple_members[] = { {"s", T_OBJECT_EX, offsetof(TripleObject, s), 0, "Triple subject."}, {"p", T_OBJECT_EX, offsetof(TripleObject, p), 0, "Triple predicate."}, {"o", T_OBJECT_EX, offsetof(TripleObject, o), 0, "Triple object."}, {NULL} }; static PyObject * Triple_richcmp (PyObject *obj1, PyObject *obj2, int op) { // Only equality and non-equality supported. if (op != Py_EQ && op != Py_NE) Py_RETURN_NOTIMPLEMENTED; LSUP_Triple *t1 = ((TripleObject *) obj1)->ob_struct; LSUP_Triple *t2 = ((TripleObject *) obj2)->ob_struct; if ( ( LSUP_term_equals (t1->s, t2->s) && LSUP_term_equals (t1->p, t2->p) && LSUP_term_equals (t1->o, t2->o) ) ^ (op == Py_NE) ) Py_RETURN_TRUE; Py_RETURN_FALSE; } static Py_hash_t Triple_hash (PyObject *self) { return LSUP_triple_hash (((TripleObject *)self)->ob_struct); } PyTypeObject TripleType = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "triple.Triple", .tp_doc = "RDF triple.", .tp_basicsize = sizeof(TripleObject), .tp_itemsize = 0, .tp_flags = Py_TPFLAGS_DEFAULT, .tp_new = PyType_GenericNew, .tp_init = (initproc) Triple_init, .tp_dealloc = (destructor) Triple_dealloc, .tp_members = Triple_members, .tp_richcompare = Triple_richcmp, .tp_hash = Triple_hash, }; /** @brief Build a triple object from a LSUP_Triple struct. */ PyObject * build_triple (LSUP_Triple *spo) { PyObject *s_obj = build_term (spo->s), *p_obj = build_term (spo->p), *o_obj = build_term (spo->o); log_trace ("Building triple."); PyObject *trp_args = Py_BuildValue ("OOO", s_obj, p_obj, o_obj); if (UNLIKELY (!trp_args)) { PyErr_SetString (PyExc_SystemError, "Error building triple args."); return NULL; } PyObject *spo_obj = PyObject_CallObject ((PyObject *)&TripleType, trp_args); Py_DECREF (trp_args); if (UNLIKELY (!spo_obj)) { PyErr_SetString (PyExc_SystemError, "Error building triple object."); return NULL; } return spo_obj; } #endif