aboutsummaryrefslogtreecommitdiffstats
path: root/src/node.c
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2018-04-29 18:29:03 +0200
committerDavid Robillard <d@drobilla.net>2021-03-07 15:32:24 -0500
commit471ef4960aba6b5e1c9445229cddc0b3eb9ca148 (patch)
treeae6ff30025ec510624c50aa6364a9171aca879bc /src/node.c
parent941b14a0ab8f7c80f94e04762e65a48f9ed02f6e (diff)
downloadserd-471ef4960aba6b5e1c9445229cddc0b3eb9ca148.tar.gz
serd-471ef4960aba6b5e1c9445229cddc0b3eb9ca148.tar.bz2
serd-471ef4960aba6b5e1c9445229cddc0b3eb9ca148.zip
Simplify node construction API
Diffstat (limited to 'src/node.c')
-rw-r--r--src/node.c152
1 files changed, 87 insertions, 65 deletions
diff --git a/src/node.c b/src/node.c
index 34ab3bc0..09ff2b95 100644
--- a/src/node.c
+++ b/src/node.c
@@ -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;
}