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>2023-12-02 16:27:02 -0500
commit5c02da92038072f28408854e862fc2d4edf765d4 (patch)
tree34577415801279981b626b18c1dc69dc79afea7f /src/node.c
parent672e90382da08efa8f593fdc9081e31d0e548fa0 (diff)
downloadserd-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.c151
1 files changed, 83 insertions, 68 deletions
diff --git a/src/node.c b/src/node.c
index 8edf7fc1..43a4b502 100644
--- a/src/node.c
+++ b/src/node.c
@@ -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;
}