term.pyx 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. from rdflib import URIRef, BNode, Literal
  2. #from cpython.mem cimport PyMem_Malloc, PyMem_Free
  3. from libc.stdlib cimport malloc, free
  4. #from libc.string cimport memcpy
  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_PK_FMT_ID = b'S(cs)'
  10. DEF LSUP_PK_FMT_LIT = b'S(csss)'
  11. cdef int serialize(
  12. term, unsigned char **pack_data, size_t *pack_size) except -1:
  13. cdef:
  14. bytes term_data = term.encode()
  15. bytes term_datatype
  16. bytes term_lang
  17. IdentifierTerm id_t
  18. LiteralTerm lit_t
  19. if isinstance(term, Literal):
  20. term_datatype = (getattr(term, 'datatype') or '').encode()
  21. term_lang = (getattr(term, 'language') or '').encode()
  22. lit_t.type = LSUP_TERM_TYPE_LITERAL
  23. lit_t.data = term_data
  24. lit_t.datatype = <unsigned char *>term_datatype
  25. lit_t.lang = <unsigned char *>term_lang
  26. tpl.tpl_jot(tpl.TPL_MEM, pack_data, pack_size, LSUP_PK_FMT_LIT, &lit_t)
  27. else:
  28. if isinstance(term, URIRef):
  29. id_t.type = LSUP_TERM_TYPE_URIREF
  30. elif isinstance(term, BNode):
  31. id_t.type = LSUP_TERM_TYPE_BNODE
  32. else:
  33. raise ValueError(f'Unsupported term type: {type(term)}')
  34. id_t.data = term_data
  35. tpl.tpl_jot(tpl.TPL_MEM, pack_data, pack_size, LSUP_PK_FMT_ID, &id_t)
  36. cdef deserialize(const unsigned char *data, const size_t data_size):
  37. cdef:
  38. char term_type
  39. char *fmt = NULL
  40. char *_pk = NULL
  41. unsigned char *term_data = NULL
  42. unsigned char *term_lang = NULL
  43. unsigned char *term_datatype = NULL
  44. datatype = None
  45. lang = None
  46. fmt = tpl.tpl_peek(tpl.TPL_MEM, data, data_size)
  47. try:
  48. if fmt == LSUP_PK_FMT_LIT:
  49. _pk = tpl.tpl_peek(
  50. tpl.TPL_MEM | tpl.TPL_DATAPEEK, data, data_size, b'csss',
  51. &term_type, &term_data, &term_datatype, &term_lang)
  52. if len(term_datatype) > 0:
  53. datatype = term_datatype.decode()
  54. elif len(term_lang) > 0:
  55. lang = term_lang.decode()
  56. return Literal(term_data.decode(), datatype=datatype, lang=lang)
  57. elif fmt == LSUP_PK_FMT_ID:
  58. _pk = tpl.tpl_peek(
  59. tpl.TPL_MEM | tpl.TPL_DATAPEEK, data, data_size, b'cs',
  60. &term_type, &term_data)
  61. uri = term_data.decode()
  62. if term_type == LSUP_TERM_TYPE_URIREF:
  63. return URIRef(uri)
  64. elif term_type == LSUP_TERM_TYPE_BNODE:
  65. return BNode(uri)
  66. else:
  67. raise IOError(f'Unknown term type code: {term_type}')
  68. else:
  69. msg = f'Unknown structure pack format: {fmt}'
  70. raise IOError(msg)
  71. finally:
  72. free(term_data)
  73. free(term_datatype)
  74. free(term_lang)
  75. free(_pk)
  76. free(fmt)