term.pyx 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. from rdflib import URIRef, BNode, Literal
  2. #from cpython.mem cimport PyMem_Malloc, PyMem_Free
  3. from libc.stdint cimport uint64_t
  4. from libc.stdlib cimport malloc, free
  5. from lakesuperior.cy_include cimport cytpl as tpl
  6. DEF LSUP_TERM_TYPE_URIREF = 1
  7. DEF LSUP_TERM_TYPE_BNODE = 2
  8. DEF LSUP_TERM_TYPE_LITERAL = 3
  9. DEF LSUP_TERM_PK_FMT = b'csss'
  10. DEF LSUP_TERM_STRUCT_PK_FMT = b'S(' + LSUP_TERM_PK_FMT + b')'
  11. cdef class Term:
  12. """
  13. RDF term: URI reference, blank node or literal.
  14. """
  15. def __cinit__(self, const tpl.tpl_bin *data):
  16. """
  17. Initialize a Term from pack data.
  18. :param tpl.tpl_bin *data: a pointer to a TPL binary buffer packed
  19. according to the term structure format.
  20. """
  21. self._pk = tpl.tpl_peek(
  22. tpl.TPL_MEM | tpl.TPL_DATAPEEK, data[0].addr, data[0].sz,
  23. LSUP_TERM_PK_FMT, &self.term_type, &self.data, &self.datatype,
  24. &self.lang)
  25. def __dealloc__(self):
  26. free(self.data)
  27. free(self.datatype)
  28. free(self.lang)
  29. free(self._pk)
  30. free(self._fmt)
  31. def to_py_term(self):
  32. """
  33. Return an RDFLib term.
  34. """
  35. data = (<bytes>self.data).decode()
  36. if self.term_type == LSUP_TERM_TYPE_LITERAL:
  37. return Literal(
  38. data, datatype=datatype, lang=lang)
  39. else:
  40. uri = term_data.decode()
  41. if self.term_type == LSUP_TERM_TYPE_URIREF:
  42. return URIRef(uri)
  43. elif self.term_type == LSUP_TERM_TYPE_BNODE:
  44. return BNode(uri)
  45. else:
  46. raise IOError(f'Unknown term type code: {self.term_type}')
  47. def to_bytes(self):
  48. """
  49. Return a Python bytes object of the serialized term.
  50. """
  51. ser_data = self.serialize()
  52. return <bytes>ser_data.data[:ser_data.sz]
  53. cdef tpl.tpl_bin serialize(self):
  54. #term_obj, unsigned char **pack_data, size_t *pack_size) except -1:
  55. cdef:
  56. bytes term_data = term_obj.encode()
  57. bytes term_datatype
  58. bytes term_lang
  59. term_obj term
  60. if isinstance(term_obj, Literal):
  61. term_datatype = (getattr(term_obj, 'datatype') or '').encode()
  62. term_lang = (getattr(term_obj, 'language') or '').encode()
  63. term.type = LSUP_TERM_TYPE_LITERAL
  64. term.data = term_data
  65. term.datatype = <unsigned char *>term_datatype
  66. term.lang = <unsigned char *>term_lang
  67. else:
  68. if isinstance(term_obj, URIRef):
  69. term.type = LSUP_TERM_TYPE_URIREF
  70. elif isinstance(term_obj, BNode):
  71. term.type = LSUP_TERM_TYPE_BNODE
  72. else:
  73. raise ValueError(f'Unsupported term type: {type(term_obj)}')
  74. term.data = term_data
  75. tpl.tpl_jot(
  76. tpl.TPL_MEM, pack_data, pack_size, LSUP_TERM_STRUCT_PK_FMT, &term)