py_term.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  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. if (datatype) {
  23. LSUP_Term *dtype_uri = LSUP_term_new (
  24. LSUP_TERM_IRIREF, datatype, NULL);
  25. self->ob_struct = LSUP_term_new (
  26. (LSUP_TermType) term_type, data, dtype_uri);
  27. } else {
  28. self->ob_struct = LSUP_term_new (
  29. (LSUP_TermType) term_type, data, lang);
  30. }
  31. if (!self->ob_struct) {
  32. PyErr_SetString (PyExc_ValueError, "Could not create term.");
  33. return -1;
  34. }
  35. return 0;
  36. }
  37. static int
  38. Term_iriref_init (TermObject *self, PyObject *args, PyObject *kwargs)
  39. {
  40. char *data = NULL;
  41. NSMapObject *nsm = NULL;
  42. static char *kwlist[] = {"data", "nsm", NULL};
  43. if (!PyArg_ParseTupleAndKeywords (
  44. args, kwargs, "|sO", kwlist, &data, &nsm))
  45. return -1;
  46. if (nsm && !PyObject_TypeCheck (nsm, &NSMapType)) {
  47. PyErr_SetString (PyExc_TypeError, "nsm is not a NSMap type.");
  48. return -1;
  49. }
  50. self->ob_struct = LSUP_iriref_new (
  51. data, (nsm ? nsm->ob_struct : NULL));
  52. if (!self->ob_struct) {
  53. PyErr_SetString (PyExc_ValueError, "Could not create term.");
  54. return -1;
  55. }
  56. return 0;
  57. }
  58. static int
  59. Term_literal_init (TermObject *self, PyObject *args, PyObject *kwargs)
  60. {
  61. char *data = NULL, *datatype = NULL, *lang = NULL;
  62. static char *kwlist[] = {"", "datatype", "lang", NULL};
  63. if (!PyArg_ParseTupleAndKeywords (
  64. args, kwargs, "s|zz", kwlist, &data, &datatype, &lang))
  65. return -1;
  66. if (lang)
  67. self->ob_struct = LSUP_lt_literal_new (data, lang);
  68. else {
  69. LSUP_Term *dtype = (datatype) ? LSUP_iriref_new (datatype, NULL) : NULL;
  70. self->ob_struct = LSUP_literal_new (data, dtype);
  71. }
  72. if (!self->ob_struct) {
  73. PyErr_SetString (PyExc_ValueError, "Could not create term.");
  74. return -1;
  75. }
  76. return 0;
  77. }
  78. static int
  79. Term_bnode_init (TermObject *self, PyObject *args, PyObject *kwargs)
  80. {
  81. char *data;
  82. static char *kwlist[] = {"data", NULL};
  83. if (!PyArg_ParseTupleAndKeywords (args, kwargs, "|s", kwlist, &data))
  84. return -1;
  85. self->ob_struct = LSUP_term_new (LSUP_TERM_BNODE, data, NULL);
  86. if (!self->ob_struct) {
  87. PyErr_SetString (PyExc_ValueError, "Could not create term.");
  88. return -1;
  89. }
  90. return 0;
  91. }
  92. static void
  93. Term_dealloc (TermObject *self)
  94. {
  95. LSUP_term_free (self->ob_struct);
  96. Py_TYPE (self)->tp_free ((PyObject *) self);
  97. }
  98. static PyObject *
  99. Term_get_type (TermObject *self, void *closure)
  100. {
  101. return PyLong_FromLong (self->ob_struct->type);
  102. }
  103. static PyObject *
  104. Term_get_data (TermObject *self, void *closure)
  105. { return PyUnicode_FromString (self->ob_struct->data); }
  106. static PyObject *
  107. Term_iriref_get_nsm (TermObject *self, void *closure)
  108. {
  109. LSUP_Term *term = self->ob_struct;
  110. if (!LSUP_IS_IRI(term))
  111. Py_RETURN_NONE;
  112. LSUP_NSMap *nsm = LSUP_iriref_nsm (term);
  113. if (!nsm) Py_RETURN_NONE;
  114. NSMapObject *nsm_obj = PyObject_New (NSMapObject, &NSMapType);
  115. if (UNLIKELY (!nsm_obj)) return PyErr_NoMemory();
  116. nsm_obj->ob_struct = nsm;
  117. Py_INCREF (nsm_obj);
  118. return (PyObject *) nsm_obj;
  119. }
  120. static PyObject *
  121. Term_iriref_get_prefix (TermObject *self, void *closure)
  122. {
  123. LSUP_Term *term = self->ob_struct;
  124. if (! LSUP_IS_IRI (term))
  125. Py_RETURN_NONE;
  126. return PyUnicode_FromString (LSUP_iriref_prefix (term));
  127. }
  128. static PyObject *
  129. Term_iriref_get_path (TermObject *self, void *closure)
  130. {
  131. LSUP_Term *term = self->ob_struct;
  132. if (! LSUP_IS_IRI (term))
  133. Py_RETURN_NONE;
  134. return PyUnicode_FromString (LSUP_iriref_path (term));
  135. }
  136. static PyObject *
  137. Term_iriref_get_frag (TermObject *self, void *closure)
  138. {
  139. LSUP_Term *term = self->ob_struct;
  140. if (! LSUP_IS_IRI (term))
  141. Py_RETURN_NONE;
  142. return PyUnicode_FromString (LSUP_iriref_frag (term));
  143. }
  144. static PyObject *
  145. Term_lit_get_datatype (TermObject *self, void *closure)
  146. {
  147. if (!self->ob_struct->datatype) Py_RETURN_NONE;
  148. char *dtype_data =
  149. self->ob_struct->type == LSUP_TERM_LT_LITERAL ? DEFAULT_DTYPE :
  150. self->ob_struct->datatype->data;
  151. TermObject *datatype = (TermObject *) Py_TYPE (self)->tp_alloc (
  152. Py_TYPE (self), 0);
  153. if (!datatype) return PyErr_NoMemory();
  154. datatype->ob_struct = LSUP_iriref_new (dtype_data, NULL);
  155. Py_INCREF (datatype);
  156. return (PyObject *) datatype;
  157. }
  158. static PyObject *
  159. Term_lit_get_lang (TermObject *self, void *closure)
  160. {
  161. if (
  162. self->ob_struct->type != LSUP_TERM_LT_LITERAL
  163. || self->ob_struct->lang[0] == '\0')
  164. Py_RETURN_NONE;
  165. return PyUnicode_FromString (self->ob_struct->lang);
  166. }
  167. static PyGetSetDef Term_getsetters[] = {
  168. {"_type", (getter) Term_get_type, NULL, "Term type.", NULL},
  169. {"_data", (getter) Term_get_data, NULL, "Term data.", NULL},
  170. {
  171. "_nsm", (getter) Term_iriref_get_nsm,
  172. NULL, "IRI ref namespace map.", NULL
  173. },
  174. {
  175. "_prefix", (getter) Term_iriref_get_prefix,
  176. NULL, "IRI ref prefix.", NULL
  177. },
  178. {
  179. "_path", (getter) Term_iriref_get_path,
  180. NULL, "IRI ref path after prefix.", NULL
  181. },
  182. {
  183. "_frag", (getter) Term_iriref_get_frag,
  184. NULL, "IRI ref fragment.", NULL
  185. },
  186. {
  187. "_datatype", (getter) Term_lit_get_datatype,
  188. NULL, "Literal term data type.", NULL
  189. },
  190. {
  191. "_lang", (getter) Term_lit_get_lang,
  192. NULL, "Literal term language tag.", NULL
  193. },
  194. {NULL}
  195. };
  196. static PyGetSetDef IRIRef_getsetters[] = {
  197. {"data", (getter) Term_get_data, NULL, "IRI string.", NULL},
  198. {
  199. "nsm", (getter) Term_iriref_get_nsm,
  200. NULL, "Namespace map.", NULL
  201. },
  202. {
  203. "prefix", (getter) Term_iriref_get_prefix,
  204. NULL, "IRI ref prefix.", NULL
  205. },
  206. {
  207. "path", (getter) Term_iriref_get_path,
  208. NULL, "IRI ref path after prefix.", NULL
  209. },
  210. {
  211. "frag", (getter) Term_iriref_get_frag,
  212. NULL, "IRI ref fragment.", NULL
  213. },
  214. {NULL}
  215. };
  216. static PyGetSetDef Literal_getsetters[] = {
  217. {"data", (getter) Term_get_data, NULL, "Literal data.", NULL},
  218. {
  219. "datatype", (getter) Term_lit_get_datatype,
  220. NULL, "Data type.", NULL
  221. },
  222. {
  223. "lang", (getter) Term_lit_get_lang,
  224. NULL, "Language tag.", NULL
  225. },
  226. {NULL}
  227. };
  228. static PyGetSetDef BNode_getsetters[] = {
  229. {"data", (getter) Term_get_data, NULL, "Blank node label.", NULL},
  230. {NULL}
  231. };
  232. static PyObject *
  233. Term_repr (TermObject *term_obj)
  234. {
  235. LSUP_Term *term = term_obj->ob_struct;
  236. char *term_repr_ptn = "<%s @%p> '%s'";
  237. char *term_nt;
  238. if (UNLIKELY (nt_codec.encode_term (term, NULL, &term_nt) != LSUP_OK)) {
  239. PyErr_SetString (PyExc_ValueError, "Error serializing term.");
  240. return NULL;
  241. }
  242. char *term_repr = malloc (
  243. strlen (term_repr_ptn) +
  244. strlen (term_nt) +
  245. strlen (term_obj->tp_name) + 32); // 32 for pointer address + NUL
  246. if (UNLIKELY (!term_repr)) return PyErr_NoMemory;
  247. sprintf (
  248. term_repr, term_repr_ptn,
  249. term_obj->tp_name, term->obj, term_nt);
  250. PyObject *result = PyUnicode_FromString (term_repr);
  251. free (term_repr);
  252. if (UNLIKELY (!result)) return PyErr_NoMemory;
  253. Py_INCREF (result);
  254. return result;
  255. }
  256. static PyObject *
  257. Term_str (PyObject *term_obj)
  258. {
  259. LSUP_Term *term = term_obj->ob_struct;
  260. PyObject *result = PyUnicode_FromString (term->data);
  261. if (UNLIKELY (!result)) return PyErr_NoMemory;
  262. Py_INCREF (result);
  263. return result;
  264. }
  265. static PyObject *
  266. Term_richcmp (PyObject *obj1, PyObject *obj2, int op);
  267. static Py_hash_t
  268. Term_hash (PyObject *self)
  269. { return LSUP_term_hash (((TermObject *)self)->ob_struct); }
  270. PyTypeObject TermType = {
  271. PyVarObject_HEAD_INIT(NULL, 0)
  272. .tp_name = "term.Term",
  273. .tp_doc = "RDF term",
  274. .tp_basicsize = sizeof (TermObject),
  275. .tp_itemsize = 0,
  276. .tp_flags = Py_TPFLAGS_DEFAULT,
  277. .tp_new = PyType_GenericNew,
  278. .tp_init = (initproc) Term_init,
  279. .tp_dealloc = (destructor) Term_dealloc,
  280. .tp_repr = Term_repr,
  281. .tp_str = Term_str,
  282. .tp_getset = Term_getsetters,
  283. .tp_richcompare = Term_richcmp,
  284. .tp_hash = Term_hash,
  285. };
  286. PyTypeObject IRIRefType = {
  287. PyVarObject_HEAD_INIT(NULL, 0)
  288. .tp_name = "term.IRIRef",
  289. .tp_doc = "RDF IRI reference.",
  290. .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
  291. .tp_base = &TermType,
  292. .tp_init = (initproc) Term_iriref_init,
  293. .tp_getset = IRIRef_getsetters,
  294. };
  295. PyTypeObject LiteralType = {
  296. PyVarObject_HEAD_INIT(NULL, 0)
  297. .tp_name = "term.Literal",
  298. .tp_doc = "RDF Literal.",
  299. .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
  300. .tp_base = &TermType,
  301. .tp_init = (initproc) Term_literal_init,
  302. .tp_getset = Literal_getsetters,
  303. };
  304. PyTypeObject BNodeType = {
  305. PyVarObject_HEAD_INIT(NULL, 0)
  306. .tp_name = "term.BNode",
  307. .tp_doc = "RDF Blanbk Node.",
  308. .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
  309. .tp_base = &TermType,
  310. .tp_init = (initproc) Term_bnode_init,
  311. .tp_getset = BNode_getsetters,
  312. };
  313. static PyObject *
  314. Term_richcmp (PyObject *obj1, PyObject *obj2, int op)
  315. {
  316. PyObject *result = NULL;
  317. if (
  318. ! PyObject_TypeCheck (obj1, &TermType) ||
  319. ! PyObject_TypeCheck (obj2, &TermType)
  320. ) return NULL;
  321. int c = 0;
  322. LSUP_Term *t1 = ((TermObject *) obj1)->ob_struct;
  323. LSUP_Term *t2 = ((TermObject *) obj2)->ob_struct;
  324. switch (op) {
  325. case Py_LT: result = Py_NotImplemented; break;
  326. case Py_LE: result = Py_NotImplemented; break;
  327. case Py_EQ: c = LSUP_term_equals (t1, t2); break;
  328. case Py_NE: c = ! LSUP_term_equals (t1, t2); break;
  329. case Py_GT: result = Py_NotImplemented; break;
  330. case Py_GE: result = Py_NotImplemented; break;
  331. }
  332. if (!result) result = c ? Py_True : Py_False;
  333. Py_INCREF(result);
  334. return result;
  335. }
  336. PyObject *
  337. build_term (LSUP_Term *t)
  338. {
  339. log_trace ("Building term: %s", t->data);
  340. PyTypeObject *term_obj_type;
  341. PyObject *term_args;
  342. switch (t->type) {
  343. case LSUP_TERM_IRIREF:
  344. term_obj_type = &IRIRefType;
  345. term_args = Py_BuildValue ("(s)", t->data);
  346. break;
  347. case LSUP_TERM_NS_IRIREF:
  348. term_obj_type = &IRIRefType;
  349. term_args = Py_BuildValue ("sO", t->data, LSUP_iriref_nsm (t));
  350. break;
  351. case LSUP_TERM_BNODE:
  352. term_obj_type = &BNodeType;
  353. term_args = Py_BuildValue ("(s)", t->data);
  354. break;
  355. case LSUP_TERM_LITERAL:
  356. term_obj_type = &LiteralType;
  357. term_args = Py_BuildValue ("sz", t->data, t->datatype->data, NULL);
  358. break;
  359. case LSUP_TERM_LT_LITERAL:
  360. term_obj_type = &LiteralType;
  361. term_args = Py_BuildValue ("sz", t->data, NULL, t->lang);
  362. break;
  363. default:
  364. return NULL;
  365. }
  366. if (UNLIKELY (!term_args)) return NULL;
  367. PyObject *t_obj = PyObject_CallObject (
  368. (PyObject *)term_obj_type, term_args);
  369. Py_DECREF (term_args);
  370. if (UNLIKELY (!t_obj)) return NULL;
  371. return t_obj;
  372. }
  373. // END _PY_TERM_OBJ_H
  374. #endif