py_term.h 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. #ifndef _PY_TERM_OBJ_H
  2. #define _PY_TERM_OBJ_H
  3. #define PY_SSIZE_T_CLEAN
  4. #include <Python.h>
  5. #include <structmember.h>
  6. #include "term.h"
  7. #include "py_namespace.h"
  8. typedef struct {
  9. PyObject_HEAD
  10. LSUP_Term * ob_struct;
  11. } TermObject;
  12. static int
  13. Term_init (TermObject *self, PyObject *args, PyObject *kwargs)
  14. {
  15. unsigned char term_type;
  16. char *data = NULL, *datatype = NULL, *lang = NULL;
  17. static char *kwlist[] = {"", "", "datatype", "lang", NULL};
  18. if (!PyArg_ParseTupleAndKeywords (
  19. args, kwargs, "bs|zz", kwlist,
  20. &term_type, &data, &datatype, &lang))
  21. return -1;
  22. char *metadata = datatype ? datatype : lang;
  23. self->ob_struct = LSUP_term_new (
  24. (LSUP_TermType) term_type, data, metadata);
  25. if (!self->ob_struct) {
  26. PyErr_SetString (PyExc_ValueError, "Could not create term.");
  27. return -1;
  28. }
  29. return 0;
  30. }
  31. static int
  32. Term_iriref_init (TermObject *self, PyObject *args, PyObject *kwargs)
  33. {
  34. char *data = NULL;
  35. LSUP_NSMap *nsm = NULL;
  36. static char *kwlist[] = {"data", "nsm", NULL};
  37. if (!PyArg_ParseTupleAndKeywords (
  38. args, kwargs, "|sO", kwlist, &data, &nsm))
  39. return -1;
  40. if (nsm && !PyObject_TypeCheck (nsm, &NSMapType)) {
  41. PyErr_SetString (PyExc_TypeError, "nsm is not a NSMap type.");
  42. return -1;
  43. }
  44. // TODO Add nsm parameter.
  45. self->ob_struct = LSUP_uri_new (data);
  46. if (!self->ob_struct) {
  47. PyErr_SetString (PyExc_ValueError, "Could not create term.");
  48. return -1;
  49. }
  50. return 0;
  51. }
  52. static int
  53. Term_literal_init (TermObject *self, PyObject *args, PyObject *kwargs)
  54. {
  55. char *data = NULL, *datatype = NULL;
  56. static char *kwlist[] = {"", "datatype", NULL};
  57. if (!PyArg_ParseTupleAndKeywords (
  58. args, kwargs, "s|z", kwlist, &data, &datatype))
  59. return -1;
  60. self->ob_struct = LSUP_term_new (LSUP_TERM_LITERAL, data, datatype);
  61. if (!self->ob_struct) {
  62. PyErr_SetString (PyExc_ValueError, "Could not create term.");
  63. return -1;
  64. }
  65. return 0;
  66. }
  67. static int
  68. Term_lt_literal_init (TermObject *self, PyObject *args, PyObject *kwargs)
  69. {
  70. char *data = NULL, *lang = NULL;
  71. if (!PyArg_ParseTuple (args, "sz", &data, &lang))
  72. return -1;
  73. self->ob_struct = LSUP_term_new (LSUP_TERM_LT_LITERAL, data, lang);
  74. if (!self->ob_struct) {
  75. PyErr_SetString (PyExc_ValueError, "Could not create term.");
  76. return -1;
  77. }
  78. return 0;
  79. }
  80. static int
  81. Term_bnode_init (TermObject *self, PyObject *args, PyObject *kwargs)
  82. {
  83. char *data;
  84. static char *kwlist[] = {"data", NULL};
  85. if (!PyArg_ParseTupleAndKeywords (args, kwargs, "|s", kwlist, &data))
  86. return -1;
  87. self->ob_struct = LSUP_term_new (LSUP_TERM_BNODE, data, NULL);
  88. if (!self->ob_struct) {
  89. PyErr_SetString (PyExc_ValueError, "Could not create term.");
  90. return -1;
  91. }
  92. return 0;
  93. }
  94. static void
  95. Term_dealloc (TermObject *self)
  96. {
  97. LSUP_term_free (self->ob_struct);
  98. Py_TYPE (self)->tp_free ((PyObject *) self);
  99. }
  100. static PyObject *
  101. Term_get_type (TermObject *self, void *closure)
  102. {
  103. PyObject *type = PyLong_FromLong (self->ob_struct->type);
  104. Py_INCREF (type);
  105. return type;
  106. }
  107. static PyObject *
  108. Term_get_data (TermObject *self, void *closure)
  109. {
  110. PyObject *data = PyUnicode_FromString (self->ob_struct->data);
  111. Py_INCREF (data);
  112. return data;
  113. }
  114. static PyObject *
  115. Term_get_datatype (TermObject *self, void *closure)
  116. {
  117. if (!self->ob_struct->datatype) Py_RETURN_NONE;
  118. const LSUP_Term *dtype = LSUP_tcache_get (self->ob_struct->datatype);
  119. if (!dtype) Py_RETURN_NONE;
  120. PyObject *datatype = PyUnicode_FromString (dtype->data);
  121. Py_INCREF (datatype);
  122. return datatype;
  123. }
  124. /*
  125. * This is the same value for all language-tagged literals.
  126. */
  127. static PyObject *
  128. LTLiteral_get_datatype (TermObject *self, void *closure)
  129. {
  130. const LSUP_Term *dtype = LSUP_default_datatype;
  131. PyObject *datatype = PyUnicode_FromString (dtype->data);
  132. Py_INCREF (datatype);
  133. return datatype;
  134. }
  135. static PyObject *
  136. Term_get_lang (TermObject *self, void *closure)
  137. {
  138. if (
  139. !self->ob_struct->datatype || !self->ob_struct->lang ||
  140. strlen (self->ob_struct->lang) == 0)
  141. Py_RETURN_NONE;
  142. PyObject *lang = PyUnicode_FromString (self->ob_struct->lang);
  143. Py_INCREF (lang);
  144. return lang;
  145. }
  146. static PyGetSetDef Term_getsetters[] = {
  147. {"_type", (getter) Term_get_type, NULL, "Term type.", NULL},
  148. {"_data", (getter) Term_get_data, NULL, "Term data.", NULL},
  149. {
  150. "_datatype", (getter) Term_get_datatype,
  151. NULL, "Literal term data type.", NULL
  152. },
  153. {
  154. "_lang", (getter) Term_get_lang,
  155. NULL, "Literal term language tag.", NULL
  156. },
  157. {NULL}
  158. };
  159. static PyGetSetDef IRIRef_getsetters[] = {
  160. {"data", (getter) Term_get_data, NULL, "IRI string.", NULL},
  161. {NULL}
  162. };
  163. static PyGetSetDef Literal_getsetters[] = {
  164. {"data", (getter) Term_get_data, NULL, "Literal data.", NULL},
  165. {
  166. "datatype", (getter) Term_get_datatype,
  167. NULL, "Data type.", NULL
  168. },
  169. {NULL}
  170. };
  171. static PyGetSetDef LTLiteral_getsetters[] = {
  172. {"data", (getter) Term_get_data, NULL, "Literal data.", NULL},
  173. {
  174. "datatype", (getter) LTLiteral_get_datatype,
  175. NULL, "Data type.", NULL
  176. },
  177. {
  178. "lang", (getter) Term_get_lang,
  179. NULL, "Language tag.", NULL
  180. },
  181. {NULL}
  182. };
  183. static PyGetSetDef BNode_getsetters[] = {
  184. {"data", (getter) Term_get_data, NULL, "Blank node label.", NULL},
  185. {NULL}
  186. };
  187. static PyObject *
  188. Term_richcmp (PyObject *obj1, PyObject *obj2, int op);
  189. static Py_hash_t
  190. Term_hash (PyObject *self)
  191. { return LSUP_term_hash (((TermObject *)self)->ob_struct); }
  192. PyTypeObject TermType = {
  193. PyVarObject_HEAD_INIT(NULL, 0)
  194. .tp_name = "term.Term",
  195. .tp_doc = "RDF term",
  196. .tp_basicsize = sizeof (TermObject),
  197. .tp_itemsize = 0,
  198. .tp_flags = Py_TPFLAGS_DEFAULT,
  199. .tp_new = PyType_GenericNew,
  200. .tp_init = (initproc) Term_init,
  201. .tp_dealloc = (destructor) Term_dealloc,
  202. .tp_getset = Term_getsetters,
  203. .tp_richcompare = Term_richcmp,
  204. .tp_hash = Term_hash,
  205. };
  206. PyTypeObject IRIRefType = {
  207. PyVarObject_HEAD_INIT(NULL, 0)
  208. .tp_name = "term.IRIRef",
  209. .tp_doc = "RDF IRI reference.",
  210. .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
  211. .tp_base = &TermType,
  212. .tp_init = (initproc) Term_iriref_init,
  213. .tp_getset = IRIRef_getsetters,
  214. };
  215. PyTypeObject LiteralType = {
  216. PyVarObject_HEAD_INIT(NULL, 0)
  217. .tp_name = "term.Literal",
  218. .tp_doc = "RDF Literal.",
  219. .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
  220. .tp_base = &TermType,
  221. .tp_init = (initproc) Term_literal_init,
  222. .tp_getset = Literal_getsetters,
  223. };
  224. PyTypeObject LTLiteralType = {
  225. PyVarObject_HEAD_INIT(NULL, 0)
  226. .tp_name = "term.LTLiteral",
  227. .tp_doc = "RDF language-tagged Literal.",
  228. .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
  229. .tp_base = &LiteralType,
  230. .tp_init = (initproc) Term_lt_literal_init,
  231. .tp_getset = LTLiteral_getsetters,
  232. };
  233. PyTypeObject BNodeType = {
  234. PyVarObject_HEAD_INIT(NULL, 0)
  235. .tp_name = "term.BNode",
  236. .tp_doc = "RDF Blanbk Node.",
  237. .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
  238. .tp_base = &TermType,
  239. .tp_init = (initproc) Term_bnode_init,
  240. .tp_getset = BNode_getsetters,
  241. };
  242. static PyObject *
  243. Term_richcmp (PyObject *obj1, PyObject *obj2, int op)
  244. {
  245. PyObject *result = NULL;
  246. if (
  247. ! PyObject_TypeCheck (obj1, &TermType) ||
  248. ! PyObject_TypeCheck (obj2, &TermType)
  249. ) return NULL;
  250. int c = 0;
  251. LSUP_Term *t1 = ((TermObject *) obj1)->ob_struct;
  252. LSUP_Term *t2 = ((TermObject *) obj2)->ob_struct;
  253. switch (op) {
  254. case Py_LT: result = Py_NotImplemented; break;
  255. case Py_LE: result = Py_NotImplemented; break;
  256. case Py_EQ: c = LSUP_term_equals (t1, t2); break;
  257. case Py_NE: c = ! LSUP_term_equals (t1, t2); break;
  258. case Py_GT: result = Py_NotImplemented; break;
  259. case Py_GE: result = Py_NotImplemented; break;
  260. }
  261. if (!result) result = c ? Py_True : Py_False;
  262. Py_INCREF(result);
  263. return result;
  264. }
  265. // END _PY_TERM_OBJ_H
  266. #endif