123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
- #include "tpl.h"
- #include "term.h"
- /*
- * tpl packing format for the term structure.
- */
- #define TERM_PACK_FMT "S(suc)"
- /*
- * Extern variables.
- */
- IDCache *LSUP_id_cache = NULL;
- uint32_t LSUP_default_dtype_key = 0;
- regex_t *LSUP_uri_ptn;
- /*
- * Static variables.
- */
- // Characters not allowed in a URI string.
- static const char *invalid_uri_chars = "<>\" {}|\\^`";
- /*
- * API functions.
- */
- LSUP_Term *
- LSUP_term_new (
- LSUP_TermType type, const char *data, const char *metadata)
- {
- LSUP_Term *term;
- CALLOC_GUARD (term, NULL);
- // If undefined, just set the type.
- if (type == LSUP_TERM_UNDEFINED) term->type = type;
- else if (UNLIKELY (LSUP_term_init (
- term, type, data, metadata) != LSUP_OK)) {
- free (term);
- return NULL;
- }
- return term;
- }
- LSUP_Term *
- LSUP_term_new_from_buffer (const LSUP_Buffer *sterm)
- {
- if (UNLIKELY (!sterm)) return NULL;
- LSUP_Term *term;
- MALLOC_GUARD (term, NULL);
- tpl_node *tn;
- tn = tpl_map (TERM_PACK_FMT, term);
- if (UNLIKELY (!tn)) goto fail;
- if (UNLIKELY (tpl_load (tn, TPL_MEM, sterm->addr, sterm->size) < 0))
- goto fail;
- if (UNLIKELY (tpl_unpack (tn, 0) < 0)) goto fail;
- tpl_free (tn);
- return term;
- fail:
- tpl_free (tn);
- free (term);
- return NULL;
- }
- LSUP_Buffer *
- LSUP_buffer_new_from_term (const LSUP_Term *term)
- {
- if (UNLIKELY (!term)) return NULL;
- LSUP_Buffer *sterm;
- MALLOC_GUARD (sterm, NULL);
- int rc = tpl_jot (
- TPL_MEM, &sterm->addr, &sterm->size, TERM_PACK_FMT, term);
- if (rc != 0) {
- free (sterm);
- return NULL;
- }
- return sterm;
- }
- LSUP_rc
- LSUP_term_init(
- LSUP_Term *term, LSUP_TermType type,
- const char *data, const char *metadata)
- {
- // This can never be LSUP_TERM_UNDEFINED.
- if (!data) return LSUP_VALUE_ERR;
- term->type = type;
- // Validate URI.
- if (term->type == LSUP_TERM_IRIREF) {
- if (strpbrk (data, invalid_uri_chars) != NULL) {
- log_error (
- "Characters %s are not allowed. Got: %s\n",
- invalid_uri_chars, data);
- return LSUP_VALUE_ERR;
- }
- if (regexec (LSUP_uri_ptn, data, 0, NULL, 0) != 0) {
- fprintf (stderr, "Error matching URI pattern.\n");
- return LSUP_VALUE_ERR;
- }
- }
- char *data_tmp = realloc (term->data, strlen (data) + 1);
- if (UNLIKELY (!data_tmp)) return LSUP_MEM_ERR;
- term->data = data_tmp;
- strcpy (term->data, data);
- if (term->type == LSUP_TERM_LT_LITERAL) {
- term->lang = XXH64 (metadata, strlen (metadata) + 1, HASH_SEED);
- LSUP_tcache_add_id (term->lang, metadata);
- } else if (metadata && strcmp (metadata, DEFAULT_DTYPE) != 0) {
- term->datatype = XXH64 (metadata, strlen (metadata) + 1, HASH_SEED);
- LSUP_tcache_add_id (term->datatype, metadata);
- }
- return LSUP_OK;
- }
- LSUP_rc
- LSUP_uri_init (LSUP_Term *term, const char *data)
- {
- if (!data) {
- uuid_t uuid;
- uuid_generate_random (uuid);
- uuid_str_t uuid_str;
- uuid_unparse_lower (uuid, uuid_str);
- char uri[UUIDSTR_SIZE + 10];
- sprintf (uri, "urn:uuid4:%s", uuid_str);
- data = uri;
- }
- return LSUP_term_init (term, LSUP_TERM_IRIREF, data, NULL);
- }
- bool LSUP_term_equals (const LSUP_Term *term1, const LSUP_Term *term2)
- {
- if (term1->type != term2->type)
- return false;
- if (strcmp (term1->data, term2->data) != 0)
- return false;
- if (term1->type == LSUP_TERM_LITERAL)
- return term1->datatype == term2->datatype;
- if (term1->type == LSUP_TERM_LT_LITERAL)
- return term1->lang == term2->lang;
- return true;
- }
- void LSUP_term_done (LSUP_Term *term)
- {
- free (term->data);
- term->data = NULL;
- }
- void LSUP_term_free (LSUP_Term *term)
- {
- if (LIKELY (term != NULL)) {
- free (term->data);
- free (term);
- }
- }
- LSUP_rc
- LSUP_tcache_add_id (const uint32_t key, const char *data)
- {
- struct id_cache_t *entry;
- HASH_FIND_INT (LSUP_id_cache, &key, entry);
- if (entry) return LSUP_NOACTION;
- MALLOC_GUARD (entry, LSUP_MEM_ERR);
- entry->key = key;
- entry->data = strdup (data);
- HASH_ADD_INT (LSUP_id_cache, key, entry);
- return LSUP_OK;
- }
- const char *
- LSUP_tcache_get_id (const uint32_t key)
- {
- struct id_cache_t *entry;
- HASH_FIND_INT (LSUP_id_cache, &key, entry);
- if (entry) log_trace ("Id found for key %d: %s", key, entry->data);
- else log_trace ("No ID found for key %d.", key);
- return (entry) ? entry->data : NULL;
- }
- // Extern inline functions.
- LSUP_Key LSUP_term_hash (const LSUP_Term *term);
- LSUP_Term *LSUP_uri_new (const char *data);
- LSUP_rc LSUP_uri_init (LSUP_Term *term, const char *data);
|