term.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. //#define PY_SSIZE_T_CLEAN
  2. //#include <Python.h>
  3. #include "term.h"
  4. #define CHR sizeof(char)
  5. #define NLEN(str) (str) == NULL ? 0 : strlen((str))
  6. int
  7. LSUP_term_init(
  8. LSUP_Term *term, LSUP_term_type type,
  9. char *data, char *datatype, char *lang) {
  10. term->type = type;
  11. if (data == NULL) return -1;
  12. if (term->type == LSUP_TERM_URI) {
  13. TRACE(STR, "Checking URI term.");
  14. // TODO Move this to a code block that is only executed once.
  15. regex_t ptn;
  16. int status = regcomp(&ptn, URI_REGEX_STR, REG_EXTENDED|REG_NOSUB);
  17. assert(status == 0);
  18. //TRACE(STR, "Regex compiled.");
  19. //TRACE("Checking data: %s", data);
  20. status = regexec(&ptn, data, 0, NULL, 0);
  21. regfree(&ptn);
  22. if (status != 0) {
  23. printf("Error matching URI pattern.\n");
  24. return(-1);
  25. }
  26. TRACE(STR, "URI checked.");
  27. }
  28. term->data = malloc(strlen(data) + 1);
  29. strcpy(term->data, data);
  30. if (datatype != NULL) {
  31. term->datatype = malloc(strlen(datatype) + 1);
  32. strcpy(term->datatype, datatype);
  33. } else {
  34. term->datatype = NULL;
  35. }
  36. if (lang != NULL) {
  37. // TODO validate language and country code
  38. //char lsize = 5 ? lang[2] == "-" : 2;
  39. memcpy(term->lang, lang, LANG_SIZE);
  40. } else {
  41. memset(term->lang, 0, LANG_SIZE);
  42. }
  43. return 0;
  44. }
  45. LSUP_Term
  46. *LSUP_term_new(
  47. LSUP_term_type type, char *data, char *datatype, char *lang) {
  48. LSUP_Term *term;
  49. CRITICAL(term = malloc(sizeof(LSUP_Term)));
  50. LSUP_term_init(term, type, data, datatype, lang);
  51. return term;
  52. }
  53. char *
  54. LSUP_term_gen_random_str()
  55. {
  56. uuid_t uuid;
  57. uuid_generate_random(uuid);
  58. uuid_str_t uuid_str;
  59. uuid_unparse_lower(uuid, uuid_str);
  60. static char uri[UUIDSTR_SIZE + 9];
  61. sprintf(uri, "urn:lsup:%s", uuid_str);
  62. return uri;
  63. }
  64. int
  65. LSUP_term_serialize(const LSUP_Term *term, LSUP_Buffer *sterm)
  66. {
  67. size_t size, data_len, datatype_len,
  68. data_idx, datatype_idx, lang_idx;
  69. data_idx = CHR;
  70. data_len = strlen(term->data) + CHR;
  71. size = data_idx + data_len;
  72. if (term->datatype != NULL) {
  73. datatype_idx = size;
  74. datatype_len = strlen(term->datatype) + CHR;
  75. size += datatype_len;
  76. if (strlen(term->lang) > 0) {
  77. lang_idx = size;
  78. size += LANG_SIZE;
  79. }
  80. }
  81. TRACE("Serialized term size: %lu", size);
  82. LSUP_buffer_init(sterm, size);
  83. // Copy type.
  84. memset(sterm->addr, (unsigned char)term->type, CHR);
  85. // Copy data.
  86. memcpy(sterm->addr + data_idx, term->data, data_len);
  87. if (term->datatype != NULL) {
  88. // Copy data type.
  89. memcpy(sterm->addr + datatype_idx, term->datatype, datatype_len);
  90. if (strlen(term->lang) > 0) {
  91. // Copy lang tag.
  92. memcpy(sterm->addr + lang_idx, term->lang, LANG_SIZE);
  93. }
  94. }
  95. return 0;
  96. }
  97. int
  98. LSUP_term_deserialize(const LSUP_Buffer *sterm, LSUP_Term *term)
  99. {
  100. size_t cur;
  101. char *data, *datatype = NULL;
  102. langtag lang = "\00";
  103. char type = ((char*)(sterm->addr))[0];
  104. cur = CHR;
  105. data = (char*)sterm->addr + cur;
  106. cur += strlen(data) + CHR;
  107. if (type == LSUP_TERM_LITERAL) {
  108. datatype = (char*)sterm->addr + cur;
  109. cur += strlen(datatype) + CHR;
  110. if (strlen(datatype) == 0)
  111. datatype = NULL;
  112. if (cur < sterm->size)
  113. strcpy(lang, sterm->addr + cur);
  114. }
  115. LSUP_term_init(term, type, data, datatype, lang);
  116. return 0;
  117. }
  118. bool LSUP_term_equals(const LSUP_Term *term1, const LSUP_Term *term2)
  119. {
  120. if (term1->type != term2->type)
  121. return false;
  122. if (strcmp(term1->data, term2->data) != 0)
  123. return false;
  124. if (term1->type == LSUP_TERM_LITERAL) {
  125. if ((term1->datatype == NULL) != (term2->datatype == NULL)) // XOR
  126. return false;
  127. if (
  128. term1->datatype != NULL &&
  129. strcmp(term1->datatype, term2->datatype) != 0)
  130. return false;
  131. if ((term1->lang == NULL) != (term2->lang == NULL)) // XOR
  132. return false;
  133. if (
  134. term1->lang != NULL &&
  135. strcmp(term1->lang, term2->lang) != 0)
  136. return false;
  137. }
  138. return true;
  139. }
  140. void LSUP_term_done(LSUP_Term *term)
  141. {
  142. if (LIKELY(term->data != NULL)) {
  143. free(term->data);
  144. term->data = NULL;
  145. }
  146. if (term->datatype != NULL) {
  147. free(term->datatype);
  148. term->datatype = NULL;
  149. }
  150. }
  151. void LSUP_term_free(LSUP_Term *term)
  152. {
  153. if (LIKELY(term != NULL)) {
  154. LSUP_term_done(term);
  155. free(term);
  156. term = NULL;
  157. }
  158. }
  159. // Extern inline functions.
  160. LSUP_Key LSUP_sterm_to_key(const LSUP_SerTerm *sterm);
  161. LSUP_Key LSUP_term_to_key(const LSUP_Term *term);