aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2018-05-11 18:11:44 +0200
committerDavid Robillard <d@drobilla.net>2019-04-13 19:15:32 +0200
commit57bd081bc1a2a926501e7c48f1125565f9fb64f7 (patch)
tree89af53a998d459a169fee264e52137b1d0b16fa9 /src
parent732f2a6cb961949a63b82fb30d9b84e74786a33a (diff)
downloadserd-57bd081bc1a2a926501e7c48f1125565f9fb64f7.tar.gz
serd-57bd081bc1a2a926501e7c48f1125565f9fb64f7.tar.bz2
serd-57bd081bc1a2a926501e7c48f1125565f9fb64f7.zip
Clean up node construction API
Diffstat (limited to 'src')
-rw-r--r--src/env.c42
-rw-r--r--src/env.h24
-rw-r--r--src/node.c146
-rw-r--r--src/node.h1
-rw-r--r--src/serdi.c11
-rw-r--r--src/string_utils.h16
-rw-r--r--src/writer.c19
7 files changed, 140 insertions, 119 deletions
diff --git a/src/env.c b/src/env.c
index 7f737419..045c4eeb 100644
--- a/src/env.c
+++ b/src/env.c
@@ -14,6 +14,8 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include "env.h"
+
#include "node.h"
#include "serd/serd.h"
@@ -57,13 +59,15 @@ serd_env_free(SerdEnv* env)
free(env);
}
+const SerdURI*
+serd_env_get_parsed_base_uri(const SerdEnv* env)
+{
+ return &env->base_uri;
+}
+
const SerdNode*
-serd_env_get_base_uri(const SerdEnv* env,
- SerdURI* out)
+serd_env_get_base_uri(const SerdEnv* env)
{
- if (out) {
- *out = env->base_uri;
- }
return env->base_uri_node;
}
@@ -71,14 +75,16 @@ SerdStatus
serd_env_set_base_uri(SerdEnv* env,
const SerdNode* uri)
{
- if (!env || !uri) {
+ if (!env || !uri || uri->type != SERD_URI) {
return SERD_ERR_BAD_ARG;
}
// Resolve base URI and create a new node and URI for it
+ SerdNode* base_uri_node = serd_node_new_resolved_uri_i(
+ serd_node_get_string(uri), &env->base_uri);
+
SerdURI base_uri;
- SerdNode* base_uri_node = serd_node_new_uri_from_node(
- uri, &env->base_uri, &base_uri);
+ serd_uri_parse(serd_node_get_string(base_uri_node), &base_uri);
if (base_uri_node) {
// Replace the current base URI
@@ -137,13 +143,12 @@ serd_env_set_prefix(SerdEnv* env,
serd_env_add(env, name, uri);
} else {
// Resolve relative URI and create a new node and URI for it
- SerdURI abs_uri;
- SerdNode* abs_uri_node = serd_node_new_uri_from_node(
- uri, &env->base_uri, &abs_uri);
+ SerdNode* abs_uri = serd_node_new_resolved_uri_i(
+ serd_node_get_string(uri), &env->base_uri);
// Set prefix to resolved (absolute) URI
- serd_env_add(env, name, abs_uri_node);
- serd_node_free(abs_uri_node);
+ serd_env_add(env, name, abs_uri);
+ serd_node_free(abs_uri);
}
return SERD_SUCCESS;
}
@@ -153,8 +158,8 @@ serd_env_set_prefix_from_strings(SerdEnv* env,
const char* name,
const char* uri)
{
- SerdNode* name_node = serd_node_new_string(SERD_LITERAL, name);
- SerdNode* uri_node = serd_node_new_string(SERD_URI, uri);
+ SerdNode* name_node = serd_node_new_string(name);
+ SerdNode* uri_node = serd_node_new_uri(uri);
const SerdStatus st = serd_env_set_prefix(env, name_node, uri_node);
@@ -228,10 +233,9 @@ serd_env_expand_node(const SerdEnv* env,
ret->n_bytes = len;
return ret;
}
- case SERD_URI: {
- SerdURI ignored;
- return serd_node_new_uri_from_node(node, &env->base_uri, &ignored);
- }
+ case SERD_URI:
+ return serd_node_new_resolved_uri_i(
+ serd_node_get_string(node), &env->base_uri);
default:
return NULL;
}
diff --git a/src/env.h b/src/env.h
new file mode 100644
index 00000000..ecb6cc15
--- /dev/null
+++ b/src/env.h
@@ -0,0 +1,24 @@
+/*
+ Copyright 2011-2018 David Robillard <http://drobilla.net>
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+#ifndef SERD_ENV_H
+#define SERD_ENV_H
+
+#include "serd/serd.h"
+
+const SerdURI* serd_env_get_parsed_base_uri(const SerdEnv* env);
+
+#endif // SERD_ENV_H
diff --git a/src/node.c b/src/node.c
index cd6aeb72..4cf26aa9 100644
--- a/src/node.c
+++ b/src/node.c
@@ -39,6 +39,9 @@
static const size_t serd_node_align = sizeof(SerdNode);
+static SerdNode*
+serd_node_new_from_uri(const SerdURI* uri, const SerdURI* base);
+
static size_t
serd_node_pad_size(const size_t n_bytes)
{
@@ -85,31 +88,30 @@ serd_node_set(SerdNode** dst, const SerdNode* src)
}
}
-SerdNode*
-serd_node_new_string(SerdType type, const char* str)
+static SerdNode*
+serd_node_new_simple(SerdType type, const char* str)
{
if (!str) {
return NULL;
}
- uint32_t flags = 0;
- const size_t n_bytes = serd_strlen(str, &flags);
- SerdNode* node = serd_node_malloc(n_bytes, flags, type);
+ const size_t n_bytes = strlen(str);
+ SerdNode* node = serd_node_malloc(n_bytes, 0, type);
memcpy(serd_node_buffer(node), str, n_bytes);
node->n_bytes = n_bytes;
return node;
}
SerdNode*
-serd_node_new_substring(SerdType type, const char* str, const size_t len)
+serd_node_new_string(const char* str)
{
if (!str) {
return NULL;
}
uint32_t flags = 0;
- const size_t n_bytes = serd_substrlen(str, len, &flags);
- SerdNode* node = serd_node_malloc(n_bytes, flags, type);
+ const size_t n_bytes = serd_strlen(str, &flags);
+ SerdNode* node = serd_node_malloc(n_bytes, flags, SERD_LITERAL);
memcpy(serd_node_buffer(node), str, n_bytes);
node->n_bytes = n_bytes;
return node;
@@ -165,15 +167,19 @@ serd_node_new_literal(const char* str,
SerdNode*
serd_node_new_blank(const char* str)
{
- if (!str) {
- return NULL;
- }
+ return serd_node_new_simple(SERD_BLANK, str);
+}
- const size_t n_bytes = strlen(str);
- SerdNode* node = serd_node_malloc(n_bytes, 0, SERD_BLANK);
- memcpy(serd_node_buffer(node), str, n_bytes);
- node->n_bytes = n_bytes;
- return node;
+SerdNode*
+serd_node_new_curie(const char* str)
+{
+ return serd_node_new_simple(SERD_CURIE, str);
+}
+
+SerdNode*
+serd_node_new_uri(const char* str)
+{
+ return serd_node_new_simple(SERD_URI, str);
}
SerdNode*
@@ -232,29 +238,43 @@ string_sink(const void* buf, size_t size, size_t nmemb, void* stream)
}
SerdNode*
-serd_node_new_uri_from_node(const SerdNode* uri_node,
- const SerdURI* base,
- SerdURI* out)
+serd_node_new_resolved_uri(const char* str, const SerdNode* base)
{
- const char* uri_str = serd_node_get_string(uri_node);
- return (uri_node->type == SERD_URI && uri_str)
- ? serd_node_new_uri_from_string(uri_str, base, out)
- : NULL;
+ if (!base || base->type != SERD_URI) {
+ return NULL;
+ }
+
+ SerdURI base_uri;
+ serd_uri_parse(serd_node_get_string(base), &base_uri);
+ return serd_node_new_resolved_uri_i(str, &base_uri);
}
SerdNode*
-serd_node_new_uri_from_string(const char* str,
- const SerdURI* base,
- SerdURI* out)
+serd_node_resolve(const SerdNode* node, const SerdNode* base)
+{
+ if (!node || !base || node->type != SERD_URI || base->type != SERD_URI) {
+ return NULL;
+ }
+
+ SerdURI uri;
+ SerdURI base_uri;
+ serd_uri_parse(serd_node_get_string(node), &uri);
+ serd_uri_parse(serd_node_get_string(base), &base_uri);
+
+ return serd_node_new_from_uri(&uri, &base_uri);
+}
+
+SerdNode*
+serd_node_new_resolved_uri_i(const char* str, const SerdURI* base)
{
if (!str || str[0] == '\0') {
// Empty URI => Base URI, or nothing if no base is given
- return base ? serd_node_new_uri(base, NULL, out) : NULL;
+ return base ? serd_node_new_from_uri(base, NULL) : NULL;
}
SerdURI uri;
serd_uri_parse(str, &uri);
- return serd_node_new_uri(&uri, base, out); // Resolve/Serialise
+ return serd_node_new_from_uri(&uri, base);
}
static inline bool
@@ -277,10 +297,7 @@ is_uri_path_char(const char c)
}
SerdNode*
-serd_node_new_file_uri(const char* path,
- const char* hostname,
- SerdURI* out,
- bool escape)
+serd_node_new_file_uri(const char* path, const char* hostname, bool escape)
{
const size_t path_len = strlen(path);
const size_t hostname_len = hostname ? strlen(hostname) : 0;
@@ -311,18 +328,13 @@ serd_node_new_file_uri(const char* path,
}
serd_buffer_sink_finish(&buffer);
- SerdNode* node = serd_node_new_substring(
- SERD_URI, (const char*)buffer.buf, buffer.len);
- if (out) {
- serd_uri_parse(serd_node_buffer(node), out);
- }
-
+ SerdNode* node = serd_node_new_uri((const char*)buffer.buf);
free(buffer.buf);
return node;
}
-SerdNode*
-serd_node_new_uri(const SerdURI* uri, const SerdURI* base, SerdURI* out)
+static SerdNode*
+serd_node_new_from_uri(const SerdURI* uri, const SerdURI* base)
{
SerdURI abs_uri = *uri;
if (base) {
@@ -337,33 +349,36 @@ serd_node_new_uri(const SerdURI* uri, const SerdURI* base, SerdURI* out)
serd_node_buffer(node)[actual_len] = '\0';
node->n_bytes = actual_len;
- if (out) {
- serd_uri_parse(serd_node_buffer(node), out); // TODO: avoid double parse
- }
-
return node;
}
SerdNode*
-serd_node_new_relative_uri(const SerdURI* uri,
- const SerdURI* base,
- const SerdURI* root,
- SerdURI* out)
+serd_node_new_relative_uri(const char* str,
+ const SerdNode* base,
+ const SerdNode* root)
{
- const size_t uri_len = serd_uri_string_length(uri);
- const size_t base_len = serd_uri_string_length(base);
+ SerdURI uri = SERD_URI_NULL;
+ SerdURI base_uri = SERD_URI_NULL;
+ SerdURI root_uri = SERD_URI_NULL;
+
+ serd_uri_parse(str, &uri);
+ if (base) {
+ serd_uri_parse(serd_node_get_string(base), &base_uri);
+ }
+ if (root) {
+ serd_uri_parse(serd_node_get_string(root), &root_uri);
+ }
+
+ const size_t uri_len = serd_uri_string_length(&uri);
+ const size_t base_len = serd_uri_string_length(&base_uri);
SerdNode* node = serd_node_malloc(uri_len + base_len, 0, SERD_URI);
char* ptr = serd_node_buffer(node);
const size_t actual_len = serd_uri_serialise_relative(
- uri, base, root, string_sink, &ptr);
+ &uri, &base_uri, root ? &root_uri : NULL, string_sink, &ptr);
serd_node_buffer(node)[actual_len] = '\0';
node->n_bytes = actual_len;
- if (out) {
- serd_uri_parse(serd_node_buffer(node), out); // TODO: avoid double parse
- }
-
return node;
}
@@ -520,6 +535,15 @@ serd_node_get_length(const SerdNode* node)
return node ? node->n_bytes : 0;
}
+static const SerdNode*
+serd_node_get_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_get_datatype(const SerdNode* node)
{
@@ -527,11 +551,7 @@ serd_node_get_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_get_meta_node(node);
assert(datatype->type == SERD_URI || datatype->type == SERD_CURIE);
return datatype;
}
@@ -543,11 +563,7 @@ serd_node_get_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_get_meta_node(node);
assert(lang->type == SERD_LITERAL);
return lang;
}
diff --git a/src/node.h b/src/node.h
index e39702a5..1dbb10d0 100644
--- a/src/node.h
+++ b/src/node.h
@@ -41,5 +41,6 @@ serd_node_buffer_c(const SerdNode* node)
SerdNode* serd_node_malloc(size_t n_bytes, SerdNodeFlags flags, SerdType type);
void serd_node_set(SerdNode** dst, const SerdNode* src);
+SerdNode* serd_node_new_resolved_uri_i(const char* str, const SerdURI* base);
#endif // SERD_NODE_H
diff --git a/src/serdi.c b/src/serdi.c
index 6a1c6d29..2627f572 100644
--- a/src/serdi.c
+++ b/src/serdi.c
@@ -223,13 +223,11 @@ main(int argc, char** argv)
: SERD_NQUADS);
}
- SerdURI base_uri = SERD_URI_NULL;
- SerdNode* base = NULL;
+ SerdNode* base = NULL;
if (a < argc) { // Base URI given on command line
- base = serd_node_new_uri_from_string(
- (const char*)argv[a], NULL, &base_uri);
+ base = serd_node_new_uri((const char*)argv[a]);
} else if (!from_string && !from_stdin) { // Use input file URI
- base = serd_node_new_file_uri(input, NULL, &base_uri, true);
+ base = serd_node_new_file_uri(input, NULL, true);
}
FILE* out_fd = stdout;
@@ -260,7 +258,6 @@ main(int argc, char** argv)
output_syntax,
(SerdStyle)output_style,
env,
- &base_uri,
(SerdWriteFunc)fwrite,
out_fd);
@@ -272,7 +269,7 @@ main(int argc, char** argv)
serd_world_set_error_sink(world, quiet_error_sink, NULL);
}
- SerdNode* root = serd_node_new_string(SERD_URI, root_uri);
+ SerdNode* root = serd_node_new_uri(root_uri);
serd_writer_set_root_uri(writer, root);
serd_writer_chop_blank_prefix(writer, chop_prefix);
serd_reader_add_blank_prefix(reader, add_prefix);
diff --git a/src/string_utils.h b/src/string_utils.h
index 63dcddbc..717cfda5 100644
--- a/src/string_utils.h
+++ b/src/string_utils.h
@@ -102,22 +102,6 @@ serd_update_flags(const char c, SerdNodeFlags* const flags)
}
}
-static inline size_t
-serd_substrlen(const char* const str,
- const size_t len,
- SerdNodeFlags* const flags)
-{
- if (flags) {
- size_t i = 0;
- *flags = 0;
- for (; i < len && str[i]; ++i) {
- serd_update_flags(str[i], flags);
- }
- return i;
- }
- return strlen(str);
-}
-
static inline int
serd_strncasecmp(const char* s1, const char* s2, size_t n)
{
diff --git a/src/writer.c b/src/writer.c
index b3a61761..e5ee5e58 100644
--- a/src/writer.c
+++ b/src/writer.c
@@ -15,6 +15,7 @@
*/
#include "byte_sink.h"
+#include "env.h"
#include "node.h"
#include "serd_internal.h"
#include "stack.h"
@@ -101,7 +102,6 @@ struct SerdWriterImpl {
SerdEnv* env;
SerdNode* root_node;
SerdURI root_uri;
- SerdURI base_uri;
SerdStack anon_stack;
SerdByteSink byte_sink;
SerdErrorSink error_sink;
@@ -530,19 +530,18 @@ write_uri_node(SerdWriter* const writer,
write_sep(writer, SEP_URI_BEGIN);
if (writer->style & SERD_STYLE_RESOLVED) {
- SerdURI in_base_uri, uri, abs_uri;
- serd_env_get_base_uri(writer->env, &in_base_uri);
+ const SerdURI* base_uri = serd_env_get_parsed_base_uri(writer->env);
+ SerdURI uri, abs_uri;
serd_uri_parse(node_str, &uri);
- serd_uri_resolve(&uri, &in_base_uri, &abs_uri);
- bool rooted = uri_is_under(&writer->base_uri, &writer->root_uri);
- SerdURI* root = rooted ? &writer->root_uri : & writer->base_uri;
+ serd_uri_resolve(&uri, base_uri, &abs_uri);
+ bool rooted = uri_is_under(base_uri, &writer->root_uri);
+ const SerdURI* root = rooted ? &writer->root_uri : base_uri;
if (!uri_is_under(&abs_uri, root) ||
writer->syntax == SERD_NTRIPLES ||
writer->syntax == SERD_NQUADS) {
serd_uri_serialise(&abs_uri, uri_sink, writer);
} else {
- serd_uri_serialise_relative(
- &uri, &writer->base_uri, root, uri_sink, writer);
+ serd_uri_serialise_relative(&uri, base_uri, root, uri_sink, writer);
}
} else {
write_uri_from_node(writer, node);
@@ -869,7 +868,6 @@ serd_writer_new(SerdWorld* world,
SerdSyntax syntax,
SerdStyle style,
SerdEnv* env,
- const SerdURI* base_uri,
SerdWriteFunc ssink,
void* stream)
{
@@ -881,7 +879,6 @@ serd_writer_new(SerdWorld* world,
writer->env = env;
writer->root_node = NULL;
writer->root_uri = SERD_URI_NULL;
- writer->base_uri = base_uri ? *base_uri : SERD_URI_NULL;
writer->anon_stack = serd_stack_new(4 * sizeof(WriteContext));
writer->context = context;
writer->list_subj = NULL;
@@ -917,8 +914,6 @@ serd_writer_set_base_uri(SerdWriter* writer,
const SerdNode* uri)
{
if (!serd_env_set_base_uri(writer->env, uri)) {
- serd_env_get_base_uri(writer->env, &writer->base_uri);
-
if (writer->syntax == SERD_TURTLE || writer->syntax == SERD_TRIG) {
if (ctx(writer, FIELD_GRAPH) || ctx(writer, FIELD_SUBJECT)) {
sink(" .\n\n", 4, writer);