diff options
author | David Robillard <d@drobilla.net> | 2018-04-29 18:29:03 +0200 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2023-12-02 16:27:02 -0500 |
commit | 5c02da92038072f28408854e862fc2d4edf765d4 (patch) | |
tree | 34577415801279981b626b18c1dc69dc79afea7f /src/node.c | |
parent | 672e90382da08efa8f593fdc9081e31d0e548fa0 (diff) | |
download | serd-5c02da92038072f28408854e862fc2d4edf765d4.tar.gz serd-5c02da92038072f28408854e862fc2d4edf765d4.tar.bz2 serd-5c02da92038072f28408854e862fc2d4edf765d4.zip |
Simplify node construction API
Diffstat (limited to 'src/node.c')
-rw-r--r-- | src/node.c | 151 |
1 files changed, 83 insertions, 68 deletions
@@ -10,7 +10,6 @@ #include "serd/attributes.h" #include "serd/buffer.h" #include "serd/node.h" -#include "serd/string.h" #include "serd/string_view.h" #include "serd/uri.h" @@ -36,6 +35,9 @@ static const size_t serd_node_align = 2 * sizeof(uint64_t); static const SerdNodeFlags meta_mask = (SERD_HAS_DATATYPE | SERD_HAS_LANGUAGE); +static SerdNode* +serd_new_from_uri(SerdURIView uri, SerdURIView base); + static size_t serd_uri_string_length(const SerdURIView* const uri) { @@ -124,68 +126,74 @@ serd_node_set(SerdNode** const dst, const SerdNode* const src) } SerdNode* -serd_new_string(SerdNodeType type, const char* str) +serd_new_token(const SerdNodeType type, const SerdStringView str) { - SerdNodeFlags flags = 0; - const size_t length = serd_strlen(str, &flags); + SerdNodeFlags flags = 0U; + const size_t length = str.data ? str.length : 0U; SerdNode* node = serd_node_malloc(length, flags, type); - memcpy(serd_node_buffer(node), str, length); - node->length = length; + if (node) { + if (str.data) { + memcpy(serd_node_buffer(node), str.data, length); + } + + node->length = length; + } return node; } SerdNode* -serd_new_substring(const SerdNodeType type, - const char* const str, - const size_t len) +serd_new_string(const SerdStringView str) { SerdNodeFlags flags = 0; - const size_t length = serd_substrlen(str, len, &flags); - SerdNode* node = serd_node_malloc(length, flags, type); - memcpy(serd_node_buffer(node), str, length); + const size_t length = serd_substrlen(str.data, str.length, &flags); + SerdNode* node = serd_node_malloc(length, flags, SERD_LITERAL); + + memcpy(serd_node_buffer(node), str.data, str.length); node->length = length; + return node; } SerdNode* -serd_new_literal(const char* const str, - const char* const datatype, - const char* const lang) +serd_new_literal(const SerdStringView str, + const SerdStringView datatype_uri, + const SerdStringView lang) { SerdNodeFlags flags = 0; - const size_t length = serd_strlen(str, &flags); + const size_t length = serd_substrlen(str.data, str.length, &flags); const size_t len = serd_node_pad_size(length); 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, length); + if (lang.length) { + const size_t total_len = len + sizeof(SerdNode) + lang.length; + + node = serd_node_malloc(total_len, flags | SERD_HAS_LANGUAGE, SERD_LITERAL); node->length = length; + memcpy(serd_node_buffer(node), str.data, length); SerdNode* lang_node = node + 1 + (len / sizeof(SerdNode)); lang_node->type = SERD_LITERAL; - lang_node->length = 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, length); + lang_node->length = lang.length; + memcpy(serd_node_buffer(lang_node), lang.data, lang.length); + + } else if (datatype_uri.length) { + const size_t total_len = len + sizeof(SerdNode) + datatype_uri.length; + + node = serd_node_malloc(total_len, flags | SERD_HAS_DATATYPE, SERD_LITERAL); node->length = length; + memcpy(serd_node_buffer(node), str.data, length); SerdNode* datatype_node = node + 1 + (len / sizeof(SerdNode)); datatype_node->type = SERD_URI; - datatype_node->length = datatype_len; - memcpy(serd_node_buffer(datatype_node), datatype, datatype_len); + datatype_node->length = datatype_uri.length; + memcpy( + serd_node_buffer(datatype_node), datatype_uri.data, datatype_uri.length); + } else { node = serd_node_malloc(length, flags, SERD_LITERAL); - memcpy(serd_node_buffer(node), str, length); + memcpy(serd_node_buffer(node), str.data, length); node->length = length; } @@ -193,6 +201,18 @@ serd_new_literal(const char* const str, } SerdNode* +serd_new_blank(const SerdStringView str) +{ + return serd_new_token(SERD_BLANK, str); +} + +SerdNode* +serd_new_curie(const SerdStringView str) +{ + return serd_new_token(SERD_CURIE, str); +} + +SerdNode* serd_node_copy(const SerdNode* node) { if (!node) { @@ -235,13 +255,9 @@ serd_node_equals(const SerdNode* const a, const SerdNode* const b) } SerdNode* -serd_new_uri(const char* const str) +serd_new_uri(const SerdStringView string) { - const size_t length = strlen(str); - SerdNode* node = serd_node_malloc(length, 0, SERD_URI); - memcpy(serd_node_buffer(node), str, length); - node->length = length; - return node; + return serd_new_token(SERD_URI, string); } SerdNode* @@ -334,54 +350,48 @@ is_dir_sep(const char c) } SerdNode* -serd_new_file_uri(const char* const path, - const char* const hostname, - SerdURIView* const out) -{ - 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; - - if (is_dir_sep(path[0]) || is_windows) { - uri_len = strlen("file://") + hostname_len + is_windows; +serd_new_file_uri(const SerdStringView path, const SerdStringView hostname) +{ + const bool is_windows = is_windows_path(path.data); + size_t uri_len = 0; + char* uri = NULL; + + if (is_dir_sep(path.data[0]) || is_windows) { + uri_len = strlen("file://") + hostname.length + is_windows; uri = (char*)calloc(uri_len + 1, 1); memcpy(uri, "file://", 7); - if (hostname) { - memcpy(uri + 7, hostname, hostname_len + 1); + if (hostname.length) { + memcpy(uri + 7, hostname.data, hostname.length + 1); } if (is_windows) { - uri[7 + hostname_len] = '/'; + uri[7 + hostname.length] = '/'; } } SerdBuffer buffer = {uri, uri_len}; - for (size_t i = 0; i < path_len; ++i) { - if (path[i] == '%') { + for (size_t i = 0; i < path.length; ++i) { + if (path.data[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.data[i])) { + serd_buffer_sink(path.data + i, 1, &buffer); #ifdef _WIN32 - } else if (path[i] == '\\') { + } else if (path.data[i] == '\\') { serd_buffer_sink("/", 1, &buffer); #endif } 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.data[i]); serd_buffer_sink(escape_str, 3, &buffer); } } const size_t length = buffer.len; const char* const string = serd_buffer_sink_finish(&buffer); - SerdNode* const node = serd_new_substring(SERD_URI, string, length); - if (out) { - *out = serd_parse_uri(serd_node_buffer(node)); - } + SerdNode* const node = serd_new_string(serd_substring(string, length)); free(buffer.buf); return node; @@ -527,6 +537,13 @@ serd_node_uri_view(const SerdNode* const node) : SERD_URI_NULL; } +SERD_PURE_FUNC static const SerdNode* +serd_node_meta_node(const SerdNode* node) +{ + const size_t len = serd_node_pad_size(node->length); + return node + 1 + (len / sizeof(SerdNode)); +} + const SerdNode* serd_node_datatype(const SerdNode* const node) { @@ -534,8 +551,7 @@ serd_node_datatype(const SerdNode* const node) return NULL; } - const size_t len = serd_node_pad_size(node->length); - const SerdNode* const datatype = node + 1 + (len / sizeof(SerdNode)); + const SerdNode* const datatype = serd_node_meta_node(node); assert(datatype->type == SERD_URI || datatype->type == SERD_CURIE); return datatype; } @@ -547,8 +563,7 @@ serd_node_language(const SerdNode* const node) return NULL; } - const size_t len = serd_node_pad_size(node->length); - const SerdNode* const lang = node + 1 + (len / sizeof(SerdNode)); + const SerdNode* const lang = serd_node_meta_node(node); assert(lang->type == SERD_LITERAL); return lang; } |