diff options
Diffstat (limited to 'src/node.c')
-rw-r--r-- | src/node.c | 152 |
1 files changed, 87 insertions, 65 deletions
@@ -42,6 +42,9 @@ static const size_t serd_node_align = sizeof(SerdNode); +static SerdNode* +serd_new_from_uri(const SerdURIView uri, const SerdURIView base); + static size_t serd_node_pad_size(const size_t n_bytes) { @@ -92,68 +95,76 @@ serd_node_set(SerdNode** dst, const SerdNode* src) } SerdNode* -serd_new_string(SerdNodeType type, const char* str) +serd_new_simple_node(SerdNodeType type, const SerdStringView str) { + if (type != SERD_BLANK && type != SERD_CURIE && type != SERD_URI) { + return NULL; + } + SerdNodeFlags flags = 0; - const size_t n_bytes = serd_strlen(str, &flags); + const size_t n_bytes = str.buf ? serd_strlen(str.buf, &flags) : 0; SerdNode* node = serd_node_malloc(n_bytes, flags, type); - memcpy(serd_node_buffer(node), str, n_bytes); + memcpy(serd_node_buffer(node), str.buf, n_bytes); node->n_bytes = n_bytes; - return node; } SerdNode* -serd_new_substring(SerdNodeType type, const char* str, const size_t len) +serd_new_string(const SerdStringView str) { SerdNodeFlags flags = 0; - const size_t n_bytes = serd_substrlen(str, len, &flags); - SerdNode* node = serd_node_malloc(n_bytes, flags, type); - memcpy(serd_node_buffer(node), str, n_bytes); + const size_t n_bytes = serd_substrlen(str.buf, str.len, &flags); + SerdNode* node = serd_node_malloc(n_bytes, flags, SERD_LITERAL); + + memcpy(serd_node_buffer(node), str.buf, str.len); node->n_bytes = n_bytes; + return node; } SerdNode* -serd_new_literal(const char* str, const char* datatype, const char* lang) +serd_new_literal(const SerdStringView str, + const SerdStringView datatype_uri, + const SerdStringView lang) { - if (!str || (lang && datatype && strcmp(datatype, NS_RDF "#langString"))) { + if (!str.len || (lang.len && datatype_uri.len && + strcmp(datatype_uri.buf, NS_RDF "langString"))) { return NULL; } SerdNodeFlags flags = 0; - const size_t n_bytes = serd_strlen(str, &flags); + const size_t n_bytes = serd_substrlen(str.buf, str.len, &flags); const size_t len = serd_node_pad_size(n_bytes); SerdNode* node = NULL; - if (lang) { - flags |= SERD_HAS_LANGUAGE; - const size_t lang_len = strlen(lang); - const size_t total_len = len + sizeof(SerdNode) + lang_len; - node = serd_node_malloc(total_len, flags, SERD_LITERAL); - memcpy(serd_node_buffer(node), str, n_bytes); + if (lang.len) { + const size_t total_len = len + sizeof(SerdNode) + lang.len; + + node = serd_node_malloc(total_len, flags | SERD_HAS_LANGUAGE, SERD_LITERAL); node->n_bytes = n_bytes; + memcpy(serd_node_buffer(node), str.buf, n_bytes); SerdNode* lang_node = node + 1 + (len / serd_node_align); lang_node->type = SERD_LITERAL; - lang_node->n_bytes = lang_len; - memcpy(serd_node_buffer(lang_node), lang, lang_len); - } else if (datatype) { - flags |= SERD_HAS_DATATYPE; - const size_t datatype_len = strlen(datatype); - const size_t total_len = len + sizeof(SerdNode) + datatype_len; - node = serd_node_malloc(total_len, flags, SERD_LITERAL); - memcpy(serd_node_buffer(node), str, n_bytes); + lang_node->n_bytes = lang.len; + memcpy(serd_node_buffer(lang_node), lang.buf, lang.len); + + } else if (datatype_uri.len) { + const size_t total_len = len + sizeof(SerdNode) + datatype_uri.len; + + node = serd_node_malloc(total_len, flags | SERD_HAS_DATATYPE, SERD_LITERAL); node->n_bytes = n_bytes; + memcpy(serd_node_buffer(node), str.buf, n_bytes); SerdNode* datatype_node = node + 1 + (len / serd_node_align); datatype_node->type = SERD_URI; - datatype_node->n_bytes = datatype_len; - memcpy(serd_node_buffer(datatype_node), datatype, datatype_len); + datatype_node->n_bytes = datatype_uri.len; + memcpy(serd_node_buffer(datatype_node), datatype_uri.buf, datatype_uri.len); + } else { node = serd_node_malloc(n_bytes, flags, SERD_LITERAL); - memcpy(serd_node_buffer(node), str, n_bytes); + memcpy(serd_node_buffer(node), str.buf, n_bytes); node->n_bytes = n_bytes; } @@ -161,6 +172,18 @@ serd_new_literal(const char* str, const char* datatype, const char* lang) } SerdNode* +serd_new_blank(const SerdStringView str) +{ + return serd_new_simple_node(SERD_BLANK, str); +} + +SerdNode* +serd_new_curie(const SerdStringView str) +{ + return serd_new_simple_node(SERD_CURIE, str); +} + +SerdNode* serd_node_copy(const SerdNode* node) { if (!node) { @@ -217,13 +240,9 @@ string_sink(const void* buf, size_t len, void* stream) } SerdNode* -serd_new_uri(const char* str) +serd_new_uri(const SerdStringView str) { - const size_t n_bytes = strlen(str); - SerdNode* node = serd_node_malloc(n_bytes, 0, SERD_URI); - memcpy(serd_node_buffer(node), str, n_bytes); - node->n_bytes = n_bytes; - return node; + return serd_new_simple_node(SERD_URI, str); } SerdNode* @@ -311,50 +330,46 @@ is_uri_path_char(const char c) } SerdNode* -serd_new_file_uri(const char* path, const char* hostname, SerdURIView* out) +serd_new_file_uri(const SerdStringView path, const SerdStringView hostname) { - const size_t path_len = strlen(path); - const size_t hostname_len = hostname ? strlen(hostname) : 0; - const bool is_windows = is_windows_path(path); - size_t uri_len = 0; - char* uri = NULL; + const bool is_windows = is_windows_path(path.buf); + size_t uri_len = 0; + char* uri = NULL; - if (path[0] == '/' || is_windows) { - uri_len = strlen("file://") + hostname_len + is_windows; + if (path.buf[0] == '/' || is_windows) { + uri_len = strlen("file://") + hostname.len + is_windows; uri = (char*)calloc(uri_len + 1, 1); memcpy(uri, "file://", 7); - if (hostname) { - memcpy(uri + 7, hostname, hostname_len + 1); + if (hostname.len) { + memcpy(uri + 7, hostname.buf, hostname.len + 1); } if (is_windows) { - uri[7 + hostname_len] = '/'; + uri[7 + hostname.len] = '/'; } } SerdBuffer buffer = {uri, uri_len}; - for (size_t i = 0; i < path_len; ++i) { - if (is_windows && path[i] == '\\') { + for (size_t i = 0; i < path.len; ++i) { + if (is_windows && path.buf[i] == '\\') { serd_buffer_sink("/", 1, &buffer); - } else if (path[i] == '%') { + } else if (path.buf[i] == '%') { serd_buffer_sink("%%", 2, &buffer); - } else if (is_uri_path_char(path[i])) { - serd_buffer_sink(path + i, 1, &buffer); + } else if (is_uri_path_char(path.buf[i])) { + serd_buffer_sink(path.buf + i, 1, &buffer); } else { char escape_str[10] = {'%', 0, 0, 0, 0, 0, 0, 0, 0, 0}; - snprintf(escape_str + 1, sizeof(escape_str) - 1, "%X", (unsigned)path[i]); + snprintf( + escape_str + 1, sizeof(escape_str) - 1, "%X", (unsigned)path.buf[i]); serd_buffer_sink(escape_str, 3, &buffer); } } serd_buffer_sink_finish(&buffer); SerdNode* node = - serd_new_substring(SERD_URI, (const char*)buffer.buf, buffer.len); - if (out) { - *out = serd_parse_uri(serd_node_buffer(node)); - } + serd_new_uri(SERD_STRING_VIEW((const char*)buffer.buf, buffer.len - 1)); free(buffer.buf); return node; @@ -488,6 +503,12 @@ serd_node_length(const SerdNode* node) SerdStringView serd_node_string_view(const SerdNode* SERD_NONNULL node) { + static const SerdStringView empty_string_view = {"", 0}; + + if (!node) { + return empty_string_view; + } + const SerdStringView result = {(const char*)(node + 1), node->n_bytes}; return result; @@ -500,6 +521,15 @@ serd_node_uri_view(const SerdNode* SERD_NONNULL node) : SERD_URI_NULL; } +static const SerdNode* +serd_node_meta_node(const SerdNode* node) +{ + const size_t len = serd_node_pad_size(node->n_bytes); + assert((intptr_t)node % serd_node_align == 0); + assert(len % serd_node_align == 0); + return node + 1 + (len / serd_node_align); +} + const SerdNode* serd_node_datatype(const SerdNode* node) { @@ -507,11 +537,7 @@ serd_node_datatype(const SerdNode* node) return NULL; } - const size_t len = serd_node_pad_size(node->n_bytes); - assert((intptr_t)node % serd_node_align == 0); - assert(len % serd_node_align == 0); - - const SerdNode* const datatype = node + 1 + (len / serd_node_align); + const SerdNode* const datatype = serd_node_meta_node(node); assert(datatype->type == SERD_URI || datatype->type == SERD_CURIE); return datatype; } @@ -523,11 +549,7 @@ serd_node_language(const SerdNode* node) return NULL; } - const size_t len = serd_node_pad_size(node->n_bytes); - assert((intptr_t)node % serd_node_align == 0); - assert(len % serd_node_align == 0); - - const SerdNode* const lang = node + 1 + (len / serd_node_align); + const SerdNode* const lang = serd_node_meta_node(node); assert(lang->type == SERD_LITERAL); return lang; } |