aboutsummaryrefslogtreecommitdiffstats
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
parent672e90382da08efa8f593fdc9081e31d0e548fa0 (diff)
downloadserd-5c02da92038072f28408854e862fc2d4edf765d4.tar.gz
serd-5c02da92038072f28408854e862fc2d4edf765d4.tar.bz2
serd-5c02da92038072f28408854e862fc2d4edf765d4.zip
Simplify node construction API
-rw-r--r--include/serd/env.h23
-rw-r--r--include/serd/node.h42
-rw-r--r--include/serd/writer.h11
-rw-r--r--src/env.c97
-rw-r--r--src/env.h14
-rw-r--r--src/node.c151
-rw-r--r--src/serdi.c25
-rw-r--r--src/writer.c42
-rw-r--r--test/test_env.c49
-rw-r--r--test/test_node.c62
-rw-r--r--test/test_reader_writer.c55
-rw-r--r--test/test_uri.c12
-rw-r--r--test/test_writer.c76
13 files changed, 365 insertions, 294 deletions
diff --git a/include/serd/env.h b/include/serd/env.h
index 7a03e80d..db2c1150 100644
--- a/include/serd/env.h
+++ b/include/serd/env.h
@@ -9,7 +9,6 @@
#include "serd/sink.h"
#include "serd/status.h"
#include "serd/string_view.h"
-#include "serd/uri.h"
#include <stdbool.h>
@@ -26,21 +25,19 @@ typedef struct SerdEnvImpl SerdEnv;
/// Create a new environment
SERD_API SerdEnv* SERD_ALLOCATED
-serd_env_new(const SerdNode* SERD_NULLABLE base_uri);
+serd_env_new(SerdStringView base_uri);
/// Free `env`
SERD_API void
serd_env_free(SerdEnv* SERD_NULLABLE env);
/// Get the current base URI
-SERD_API const SerdNode* SERD_NULLABLE
-serd_env_base_uri(const SerdEnv* SERD_NONNULL env,
- SerdURIView* SERD_NULLABLE out);
+SERD_PURE_API const SerdNode* SERD_NULLABLE
+serd_env_base_uri(const SerdEnv* SERD_NULLABLE env);
/// Set the current base URI
SERD_API SerdStatus
-serd_env_set_base_uri(SerdEnv* SERD_NONNULL env,
- const SerdNode* SERD_NULLABLE uri);
+serd_env_set_base_uri(SerdEnv* SERD_NONNULL env, SerdStringView uri);
/**
Set a namespace prefix.
@@ -50,15 +47,9 @@ serd_env_set_base_uri(SerdEnv* SERD_NONNULL env,
expand to "http://www.w3.org/2001/XMLSchema#decimal".
*/
SERD_API SerdStatus
-serd_env_set_prefix(SerdEnv* SERD_NONNULL env,
- const SerdNode* SERD_NONNULL name,
- const SerdNode* SERD_NONNULL uri);
-
-/// Set a namespace prefix
-SERD_API SerdStatus
-serd_env_set_prefix_from_strings(SerdEnv* SERD_NONNULL env,
- const char* SERD_NONNULL name,
- const char* SERD_NONNULL uri);
+serd_env_set_prefix(SerdEnv* SERD_NONNULL env,
+ SerdStringView name,
+ SerdStringView uri);
/// Qualify `uri` into a CURIE if possible
SERD_API bool
diff --git a/include/serd/node.h b/include/serd/node.h
index 4aa4ec0a..cbf5efcc 100644
--- a/include/serd/node.h
+++ b/include/serd/node.h
@@ -100,29 +100,40 @@ typedef uint32_t SerdNodeFlags;
*/
/**
- Create a new node from `str`.
+ Create a new simple "token" node.
+
+ A "token" is a node that isn't a typed or tagged literal. This can be used
+ to create URIs, blank nodes, CURIEs, and simple string literals.
*/
SERD_API SerdNode* SERD_ALLOCATED
-serd_new_string(SerdNodeType type, const char* SERD_NULLABLE str);
+serd_new_token(SerdNodeType type, SerdStringView string);
/**
- Create a new node from a prefix of `str`.
+ Create a new string literal node.
*/
SERD_API SerdNode* SERD_ALLOCATED
-serd_new_substring(SerdNodeType type,
- const char* SERD_NULLABLE str,
- size_t len);
+serd_new_string(SerdStringView string);
/**
Create a new literal node from `str`.
- Either `datatype` or `lang` can be given, but not both, unless `datatype` is
- rdf:langString in which case it is ignored.
+ Either `datatype_uri` or `lang` can be given, but not both, unless
+ `datatype_uri` is rdf:langString in which case it is ignored.
*/
SERD_API SerdNode* SERD_ALLOCATED
-serd_new_literal(const char* SERD_NONNULL str,
- const char* SERD_NULLABLE datatype,
- const char* SERD_NULLABLE lang);
+serd_new_literal(SerdStringView string,
+ SerdStringView datatype_uri,
+ SerdStringView lang);
+
+/**
+ Create a new node from a blank node label.
+*/
+SERD_API SerdNode* SERD_ALLOCATED
+serd_new_blank(SerdStringView string);
+
+/// Create a new CURIE node
+SERD_API SerdNode* SERD_ALLOCATED
+serd_new_curie(SerdStringView string);
/**
Create a new URI node from a parsed URI.
@@ -134,7 +145,7 @@ serd_new_parsed_uri(SerdURIView uri);
Create a new URI node from a string.
*/
SERD_API SerdNode* SERD_ALLOCATED
-serd_new_uri(const char* SERD_NONNULL str);
+serd_new_uri(SerdStringView string);
/**
Create a new file URI node from a file system path and optional hostname.
@@ -143,12 +154,9 @@ serd_new_uri(const char* SERD_NONNULL str);
percent encoded as necessary.
If `path` is relative, `hostname` is ignored.
- If `out` is not NULL, it will be set to the parsed URI.
*/
SERD_API SerdNode* SERD_ALLOCATED
-serd_new_file_uri(const char* SERD_NONNULL path,
- const char* SERD_NULLABLE hostname,
- SerdURIView* SERD_NULLABLE out);
+serd_new_file_uri(SerdStringView path, SerdStringView hostname);
/**
Create a new node by serialising `d` into an xsd:decimal string.
@@ -237,7 +245,7 @@ serd_node_string_view(const SerdNode* SERD_NONNULL node);
idea to keep the value if you will be using it several times in the same
scope.
*/
-SERD_API SerdURIView
+SERD_PURE_API SerdURIView
serd_node_uri_view(const SerdNode* SERD_NONNULL node);
/**
diff --git a/include/serd/writer.h b/include/serd/writer.h
index 3327c1b9..976ed5b7 100644
--- a/include/serd/writer.h
+++ b/include/serd/writer.h
@@ -48,12 +48,11 @@ typedef uint32_t SerdWriterFlags;
/// Create a new RDF writer
SERD_API SerdWriter* SERD_ALLOCATED
-serd_writer_new(SerdSyntax syntax,
- SerdWriterFlags flags,
- SerdEnv* SERD_NONNULL env,
- const SerdNode* SERD_NULLABLE base_uri,
- SerdSink SERD_NONNULL ssink,
- void* SERD_NULLABLE stream);
+serd_writer_new(SerdSyntax syntax,
+ SerdWriterFlags flags,
+ SerdEnv* SERD_NONNULL env,
+ SerdSink SERD_NONNULL ssink,
+ void* SERD_NULLABLE stream);
/// Free `writer`
SERD_API void
diff --git a/src/env.c b/src/env.c
index 78680a0f..8b3970b3 100644
--- a/src/env.c
+++ b/src/env.c
@@ -3,10 +3,10 @@
#include "serd/env.h"
+#include "env.h"
#include "node.h"
#include "serd/node.h"
-#include "serd/uri.h"
#include <stdbool.h>
#include <stdio.h>
@@ -26,14 +26,11 @@ struct SerdEnvImpl {
};
SerdEnv*
-serd_env_new(const SerdNode* const base_uri)
+serd_env_new(const SerdStringView base_uri)
{
SerdEnv* env = (SerdEnv*)calloc(1, sizeof(struct SerdEnvImpl));
- if (env && base_uri) {
- if (serd_env_set_base_uri(env, base_uri)) {
- free(env);
- return NULL;
- }
+ if (env && base_uri.length) {
+ serd_env_set_base_uri(env, base_uri);
}
return env;
@@ -55,41 +52,39 @@ serd_env_free(SerdEnv* const env)
free(env);
}
-const SerdNode*
-serd_env_base_uri(const SerdEnv* const env, SerdURIView* const out)
+SerdURIView
+serd_env_base_uri_view(const SerdEnv* const env)
{
- if (out) {
- *out = env->base_uri;
- }
+ return env->base_uri;
+}
- return env->base_uri_node;
+const SerdNode*
+serd_env_base_uri(const SerdEnv* const env)
+{
+ return env ? env->base_uri_node : NULL;
}
SerdStatus
-serd_env_set_base_uri(SerdEnv* const env, const SerdNode* const uri)
+serd_env_set_base_uri(SerdEnv* const env, const SerdStringView uri)
{
- if (uri && uri->type != SERD_URI) {
- return SERD_BAD_ARG;
- }
-
- if (!uri) {
+ if (!uri.length) {
serd_node_free(env->base_uri_node);
env->base_uri_node = NULL;
env->base_uri = SERD_URI_NULL;
return SERD_SUCCESS;
}
+ SerdNode* const old_base_uri = env->base_uri_node;
+
// Resolve the new base against the current base in case it is relative
const SerdURIView new_base_uri =
- serd_resolve_uri(serd_parse_uri(serd_node_string(uri)), env->base_uri);
-
- SerdNode* const new_base_node = serd_new_parsed_uri(new_base_uri);
+ serd_resolve_uri(serd_parse_uri(uri.data), env->base_uri);
// Replace the current base URI
- serd_node_free(env->base_uri_node);
- env->base_uri_node = new_base_node;
+ env->base_uri_node = serd_new_parsed_uri(new_base_uri);
env->base_uri = serd_node_uri_view(env->base_uri_node);
+ serd_node_free(old_base_uri);
return SERD_SUCCESS;
}
@@ -110,39 +105,33 @@ serd_env_find(const SerdEnv* const env,
}
static void
-serd_env_add(SerdEnv* const env,
- const SerdNode* const name,
- const SerdNode* const uri)
+serd_env_add(SerdEnv* const env,
+ const SerdStringView name,
+ const SerdStringView uri)
{
- const char* name_str = serd_node_string(name);
- SerdPrefix* const prefix = serd_env_find(env, name_str, name->length);
+ SerdPrefix* const prefix = serd_env_find(env, name.data, name.length);
if (prefix) {
- if (!serd_node_equals(prefix->uri, uri)) {
- SerdNode* old_prefix_uri = prefix->uri;
- prefix->uri = serd_node_copy(uri);
- serd_node_free(old_prefix_uri);
+ if (!!strcmp(serd_node_string(prefix->uri), uri.data)) {
+ serd_node_free(prefix->uri);
+ prefix->uri = serd_new_uri(uri);
}
} else {
SerdPrefix* const new_prefixes = (SerdPrefix*)realloc(
env->prefixes, (++env->n_prefixes) * sizeof(SerdPrefix));
if (new_prefixes) {
env->prefixes = new_prefixes;
- env->prefixes[env->n_prefixes - 1].name = serd_node_copy(name);
- env->prefixes[env->n_prefixes - 1].uri = serd_node_copy(uri);
+ env->prefixes[env->n_prefixes - 1].name = serd_new_string(name);
+ env->prefixes[env->n_prefixes - 1].uri = serd_new_uri(uri);
}
}
}
SerdStatus
-serd_env_set_prefix(SerdEnv* const env,
- const SerdNode* const name,
- const SerdNode* const uri)
+serd_env_set_prefix(SerdEnv* const env,
+ const SerdStringView name,
+ const SerdStringView uri)
{
- if (!name || uri->type != SERD_URI) {
- return SERD_BAD_ARG;
- }
-
- if (serd_uri_string_has_scheme(serd_node_string(uri))) {
+ if (serd_uri_string_has_scheme(uri.data)) {
// Set prefix to absolute URI
serd_env_add(env, name, uri);
return SERD_SUCCESS;
@@ -153,32 +142,14 @@ serd_env_set_prefix(SerdEnv* const env,
}
// Resolve relative URI and create a new node and URI for it
- SerdNode* const abs_uri =
- serd_new_resolved_uri(serd_node_string_view(uri), env->base_uri);
+ SerdNode* const abs_uri = serd_new_resolved_uri(uri, env->base_uri);
// Set prefix to resolved (absolute) URI
- serd_env_add(env, name, abs_uri);
-
+ serd_env_add(env, name, serd_node_string_view(abs_uri));
serd_node_free(abs_uri);
-
return SERD_SUCCESS;
}
-SerdStatus
-serd_env_set_prefix_from_strings(SerdEnv* const env,
- const char* const name,
- const char* const uri)
-{
- SerdNode* name_node = serd_new_string(SERD_LITERAL, name);
- SerdNode* uri_node = serd_new_string(SERD_URI, uri);
-
- const SerdStatus st = serd_env_set_prefix(env, name_node, uri_node);
-
- serd_node_free(name_node);
- serd_node_free(uri_node);
- return st;
-}
-
bool
serd_env_qualify(const SerdEnv* const env,
const SerdNode* const uri,
diff --git a/src/env.h b/src/env.h
new file mode 100644
index 00000000..ed3fbfd9
--- /dev/null
+++ b/src/env.h
@@ -0,0 +1,14 @@
+// Copyright 2011-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
+
+#ifndef SERD_SRC_ENV_H
+#define SERD_SRC_ENV_H
+
+#include "serd/attributes.h"
+#include "serd/env.h"
+#include "serd/uri.h"
+
+SERD_PURE_FUNC SerdURIView
+serd_env_base_uri_view(const SerdEnv* env);
+
+#endif // SERD_SRC_ENV_H
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;
}
diff --git a/src/serdi.c b/src/serdi.c
index 85462532..cdd3a7b1 100644
--- a/src/serdi.c
+++ b/src/serdi.c
@@ -11,6 +11,7 @@
#include "serd/reader.h"
#include "serd/sink.h"
#include "serd/status.h"
+#include "serd/string_view.h"
#include "serd/syntax.h"
#include "serd/uri.h"
#include "serd/version.h"
@@ -331,20 +332,19 @@ main(int argc, char** argv)
const SerdWriterFlags writer_flags = choose_style(
input_syntax, output_syntax, ascii, bulk_write, full_uris, lax);
- SerdURIView base_uri = SERD_URI_NULL;
- SerdNode* base = NULL;
+ SerdNode* base = NULL;
if (a < argc) { // Base URI given on command line
- base_uri = serd_parse_uri(argv[a]);
- base = serd_new_parsed_uri(base_uri);
+ base = serd_new_uri(serd_string((const char*)argv[a]));
} else if (from_file && in_fd != stdin) { // Use input file URI
- base = serd_new_file_uri(input, NULL, &base_uri);
+ base = serd_new_file_uri(serd_string(input), serd_empty_string());
}
FILE* const out_fd = stdout;
- SerdEnv* const env = serd_env_new(base);
+ SerdEnv* const env =
+ serd_env_new(base ? serd_node_string_view(base) : serd_empty_string());
- SerdWriter* const writer = serd_writer_new(
- output_syntax, writer_flags, env, base, serd_file_sink, out_fd);
+ SerdWriter* const writer =
+ serd_writer_new(output_syntax, writer_flags, env, serd_file_sink, out_fd);
SerdReader* const reader =
serd_reader_new(input_syntax,
@@ -361,11 +361,14 @@ main(int argc, char** argv)
serd_writer_set_error_sink(writer, quiet_error_sink, NULL);
}
- SerdNode* root = root_uri ? serd_new_string(SERD_URI, root_uri) : NULL;
- serd_writer_set_root_uri(writer, root);
+ if (root_uri) {
+ SerdNode* const root = serd_new_uri(serd_string(root_uri));
+ serd_writer_set_root_uri(writer, root);
+ serd_node_free(root);
+ }
+
serd_writer_chop_blank_prefix(writer, chop_prefix);
serd_reader_add_blank_prefix(reader, add_prefix);
- serd_node_free(root);
SerdStatus st = SERD_SUCCESS;
if (!from_file) {
diff --git a/src/writer.c b/src/writer.c
index 5aad6d29..cea75aec 100644
--- a/src/writer.c
+++ b/src/writer.c
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: ISC
#include "byte_sink.h"
+#include "env.h"
#include "node.h"
#include "serd_internal.h"
#include "stack.h"
@@ -759,7 +760,7 @@ write_uri_node(SerdWriter* const writer,
}
if (!has_scheme && !supports_uriref(writer) &&
- !serd_env_base_uri(writer->env, NULL)) {
+ !serd_env_base_uri(writer->env)) {
return w_err(writer,
SERD_BAD_ARG,
"syntax does not support URI reference <%s>\n",
@@ -768,14 +769,13 @@ write_uri_node(SerdWriter* const writer,
TRY(st, esink("<", 1, writer));
- SerdURIView base_uri = SERD_URI_NULL;
- if ((writer->flags & SERD_WRITE_RESOLVED) &&
- serd_env_base_uri(writer->env, &base_uri)) {
- SerdURIView uri = serd_parse_uri(node_str);
- SerdURIView abs_uri = serd_resolve_uri(uri, base_uri);
- bool rooted = uri_is_under(&base_uri, &writer->root_uri);
- const SerdURIView* root = rooted ? &writer->root_uri : &base_uri;
- UriSinkContext ctx = {writer, SERD_SUCCESS};
+ if ((writer->flags & SERD_WRITE_RESOLVED) && serd_env_base_uri(writer->env)) {
+ const SerdURIView base_uri = serd_env_base_uri_view(writer->env);
+ SerdURIView uri = serd_parse_uri(node_str);
+ SerdURIView abs_uri = serd_resolve_uri(uri, base_uri);
+ bool rooted = uri_is_under(&base_uri, &writer->root_uri);
+ const SerdURIView* root = rooted ? &writer->root_uri : &base_uri;
+ UriSinkContext ctx = {writer, SERD_SUCCESS};
if (!supports_abbrev(writer) || !uri_is_under(&abs_uri, root)) {
serd_write_uri(abs_uri, uri_sink, &ctx);
@@ -1126,7 +1126,6 @@ SerdWriter*
serd_writer_new(SerdSyntax syntax,
SerdWriterFlags flags,
SerdEnv* env,
- const SerdNode* base_uri,
SerdSink ssink,
void* stream)
{
@@ -1143,7 +1142,6 @@ serd_writer_new(SerdSyntax syntax,
writer->byte_sink = serd_byte_sink_new(
ssink, stream, (flags & SERD_WRITE_BULK) ? SERD_PAGE_SIZE : 1);
- serd_env_set_base_uri(writer->env, base_uri);
return writer;
}
@@ -1174,14 +1172,24 @@ serd_writer_chop_blank_prefix(SerdWriter* writer, const char* prefix)
SerdStatus
serd_writer_set_base_uri(SerdWriter* writer, const SerdNode* uri)
{
- SerdStatus st = SERD_SUCCESS;
+ if (uri && serd_node_type(uri) != SERD_URI) {
+ return SERD_BAD_ARG;
+ }
+
+ if (serd_node_equals(serd_env_base_uri(writer->env), uri)) {
+ return SERD_SUCCESS;
+ }
- TRY(st, serd_env_set_base_uri(writer->env, uri));
+ const SerdStringView uri_string =
+ uri ? serd_node_string_view(uri) : serd_empty_string();
+
+ SerdStatus st = SERD_SUCCESS;
+ TRY(st, serd_env_set_base_uri(writer->env, uri_string));
if (uri && (writer->syntax == SERD_TURTLE || writer->syntax == SERD_TRIG)) {
TRY(st, terminate_context(writer));
TRY(st, esink("@base <", 7, writer));
- TRY(st, esink(serd_node_string(uri), serd_node_length(uri), writer));
+ TRY(st, esink(uri_string.data, uri_string.length, writer));
TRY(st, esink(">", 1, writer));
writer->last_sep = SEP_NODE;
TRY(st, write_sep(writer, SEP_END_DIRECT));
@@ -1199,7 +1207,7 @@ serd_writer_set_root_uri(SerdWriter* writer, const SerdNode* uri)
if (uri) {
writer->root_node = serd_node_copy(uri);
- writer->root_uri = serd_parse_uri(serd_node_string(writer->root_node));
+ writer->root_uri = serd_node_uri_view(writer->root_node);
}
return SERD_SUCCESS;
@@ -1212,7 +1220,9 @@ serd_writer_set_prefix(SerdWriter* writer,
{
SerdStatus st = SERD_SUCCESS;
- TRY(st, serd_env_set_prefix(writer->env, name, uri));
+ TRY(st,
+ serd_env_set_prefix(
+ writer->env, serd_node_string_view(name), serd_node_string_view(uri)));
if (writer->syntax == SERD_TURTLE || writer->syntax == SERD_TRIG) {
TRY(st, terminate_context(writer));
diff --git a/test/test_env.c b/test/test_env.c
index b1371d16..8dbc24a1 100644
--- a/test/test_env.c
+++ b/test/test_env.c
@@ -24,15 +24,12 @@ count_prefixes(void* handle, const SerdNode* name, const SerdNode* uri)
static void
test_env(void)
{
- SerdNode* u = serd_new_string(SERD_URI, "http://example.org/foo");
- SerdNode* b = serd_new_string(SERD_CURIE, "invalid");
- SerdNode* e = serd_new_string(SERD_URI, "");
- SerdNode* c = serd_new_string(SERD_CURIE, "eg.2:b");
- SerdNode* s = serd_new_string(SERD_LITERAL, "hello");
- SerdEnv* env = serd_env_new(NULL);
- serd_env_set_prefix_from_strings(env, "eg.2", "http://example.org/");
-
- assert(!serd_env_new(s));
+ SerdNode* u = serd_new_uri(serd_string("http://example.org/foo"));
+ SerdNode* b = serd_new_curie(serd_string("invalid"));
+ SerdNode* e = serd_new_uri(serd_empty_string());
+ SerdNode* c = serd_new_curie(serd_string("eg.2:b"));
+ SerdNode* s = serd_new_string(serd_string("hello"));
+ SerdEnv* env = serd_env_new(serd_empty_string());
const SerdNode* prefix_node = NULL;
SerdStringView prefix = serd_empty_string();
@@ -42,20 +39,29 @@ test_env(void)
assert(serd_env_expand(env, NULL, &prefix, &suffix) == SERD_BAD_CURIE);
- assert(serd_env_set_prefix_from_strings(env, "eg.3", "rel") == SERD_BAD_ARG);
+ assert(!serd_env_base_uri(env));
+ assert(!serd_env_set_base_uri(env, serd_empty_string()));
+ assert(!serd_env_base_uri(env));
+ assert(!serd_env_base_uri(env));
+
+ serd_env_set_prefix(
+ env, serd_string("eg.2"), serd_string("http://example.org/"));
+
+ assert(serd_env_set_prefix(env, serd_string("eg.3"), serd_string("rel")) ==
+ SERD_BAD_ARG);
assert(!serd_env_expand_node(NULL, u));
assert(!serd_env_expand_node(env, b));
assert(!serd_env_expand_node(env, s));
assert(!serd_env_expand_node(env, e));
- assert(!serd_env_set_base_uri(env, NULL));
+ assert(!serd_env_set_base_uri(env, serd_empty_string()));
SerdNode* xu = serd_env_expand_node(env, u);
assert(!strcmp(serd_node_string(xu), "http://example.org/foo"));
serd_node_free(xu);
- SerdNode* badpre = serd_new_string(SERD_CURIE, "hm:what");
+ SerdNode* badpre = serd_new_curie(serd_string("hm:what"));
SerdNode* xbadpre = serd_env_expand_node(env, badpre);
assert(!xbadpre);
@@ -63,34 +69,31 @@ test_env(void)
assert(!strcmp(serd_node_string(xc), "http://example.org/b"));
serd_node_free(xc);
- SerdNode* lit = serd_new_string(SERD_LITERAL, "hello");
- assert(serd_env_set_prefix(env, b, lit));
-
- SerdNode* blank = serd_new_string(SERD_BLANK, "b1");
+ SerdNode* blank = serd_new_blank(serd_string("b1"));
assert(!serd_env_expand_node(env, blank));
serd_node_free(blank);
int n_prefixes = 0;
- serd_env_set_prefix_from_strings(env, "eg.2", "http://example.org/");
+ serd_env_set_prefix(
+ env, serd_string("eg.2"), serd_string("http://example.org/"));
serd_env_foreach(env, count_prefixes, &n_prefixes);
assert(n_prefixes == 1);
- SerdNode* shorter_uri = serd_new_string(SERD_URI, "urn:foo");
+ SerdNode* shorter_uri = serd_new_uri(serd_string("urn:foo"));
assert(!serd_env_qualify(env, shorter_uri, &prefix_node, &suffix));
- assert(!serd_env_set_base_uri(env, u));
- assert(serd_node_equals(serd_env_base_uri(env, NULL), u));
+ assert(!serd_env_set_base_uri(env, serd_node_string_view(u)));
+ assert(serd_node_equals(serd_env_base_uri(env), u));
SerdNode* xe = serd_env_expand_node(env, e);
assert(xe);
assert(!strcmp(serd_node_string(xe), "http://example.org/foo"));
serd_node_free(xe);
- assert(!serd_env_set_base_uri(env, NULL));
- assert(!serd_env_base_uri(env, NULL));
+ assert(!serd_env_set_base_uri(env, serd_empty_string()));
+ assert(!serd_env_base_uri(env));
serd_node_free(shorter_uri);
- serd_node_free(lit);
serd_node_free(badpre);
serd_node_free(s);
serd_node_free(c);
diff --git a/test/test_node.c b/test/test_node.c
index 1d4d1107..68bdf784 100644
--- a/test/test_node.c
+++ b/test/test_node.c
@@ -6,6 +6,7 @@
#include "serd/memory.h"
#include "serd/node.h"
#include "serd/string.h"
+#include "serd/string_view.h"
#include "serd/uri.h"
#include <assert.h>
@@ -146,19 +147,22 @@ test_blob_to_node(void)
static void
test_node_equals(void)
{
- const uint8_t replacement_char_str[] = {0xEF, 0xBF, 0xBD, 0};
- SerdNode* lhs =
- serd_new_string(SERD_LITERAL, (const char*)replacement_char_str);
- SerdNode* rhs = serd_new_string(SERD_LITERAL, "123");
+ static const uint8_t replacement_char_str[] = {0xEF, 0xBF, 0xBD, 0};
+
+ SerdNode* const lhs =
+ serd_new_string(serd_substring((const char*)replacement_char_str, 3));
+
+ assert(serd_node_equals(lhs, lhs));
+
+ SerdNode* const rhs = serd_new_string(serd_string("123"));
assert(!serd_node_equals(lhs, rhs));
- SerdNode* qnode = serd_new_string(SERD_CURIE, "foo:bar");
+ SerdNode* const qnode = serd_new_curie(serd_string("foo:bar"));
assert(!serd_node_equals(lhs, qnode));
- assert(serd_node_equals(lhs, lhs));
+ serd_node_free(qnode);
assert(!serd_node_copy(NULL));
- serd_node_free(qnode);
serd_node_free(lhs);
serd_node_free(rhs);
}
@@ -166,15 +170,15 @@ test_node_equals(void)
static void
test_node_from_string(void)
{
- SerdNode* const hello = serd_new_string(SERD_LITERAL, "hello\"");
+ SerdNode* const hello = serd_new_string(serd_string("hello\""));
assert(serd_node_length(hello) == 6);
assert(serd_node_flags(hello) == SERD_HAS_QUOTE);
- assert(!strcmp(serd_node_string(hello), "hello\""));
+ assert(!strncmp(serd_node_string(hello), "hello\"", 6));
assert(!strcmp(serd_node_string_view(hello).data, "hello\""));
assert(serd_node_string_view(hello).length == 6);
serd_node_free(hello);
- SerdNode* const uri = serd_new_string(SERD_URI, "http://example.org/");
+ SerdNode* const uri = serd_new_uri(serd_string("http://example.org/"));
assert(serd_node_length(uri) == 19);
assert(!strcmp(serd_node_string(uri), "http://example.org/"));
assert(serd_node_uri_view(uri).authority.length == 11);
@@ -185,14 +189,11 @@ test_node_from_string(void)
static void
test_node_from_substring(void)
{
- SerdNode* a_b = serd_new_substring(SERD_LITERAL, "a\"bc", 3);
- assert(serd_node_length(a_b) == 3 && serd_node_flags(a_b) == SERD_HAS_QUOTE &&
- !strncmp(serd_node_string(a_b), "a\"b", 3));
-
- serd_node_free(a_b);
- a_b = serd_new_substring(SERD_LITERAL, "a\"bc", 10);
- assert(serd_node_length(a_b) == 4 && serd_node_flags(a_b) == SERD_HAS_QUOTE &&
- !strncmp(serd_node_string(a_b), "a\"bc", 4));
+ SerdNode* const a_b = serd_new_string(serd_substring("a\"bc", 3));
+ assert(serd_node_length(a_b) == 3);
+ assert(serd_node_flags(a_b) == SERD_HAS_QUOTE);
+ assert(strlen(serd_node_string(a_b)) == 3);
+ assert(!strncmp(serd_node_string(a_b), "a\"b", 3));
serd_node_free(a_b);
}
@@ -209,14 +210,18 @@ check_copy_equals(const SerdNode* const node)
static void
test_literal(void)
{
- SerdNode* hello2 = serd_new_literal("hello\"", NULL, NULL);
+ SerdNode* hello2 = serd_new_literal(
+ serd_string("hello\""), serd_empty_string(), serd_empty_string());
+
assert(serd_node_length(hello2) == 6 &&
serd_node_flags(hello2) == SERD_HAS_QUOTE &&
!strcmp(serd_node_string(hello2), "hello\""));
check_copy_equals(hello2);
serd_node_free(hello2);
- SerdNode* hello_l = serd_new_literal("hello_l\"", NULL, "en");
+ SerdNode* hello_l = serd_new_literal(
+ serd_string("hello_l\""), serd_empty_string(), serd_string("en"));
+
assert(serd_node_length(hello_l) == 8);
assert(!strcmp(serd_node_string(hello_l), "hello_l\""));
assert(serd_node_flags(hello_l) == (SERD_HAS_QUOTE | SERD_HAS_LANGUAGE));
@@ -227,8 +232,10 @@ test_literal(void)
check_copy_equals(hello_l);
serd_node_free(hello_l);
- SerdNode* hello_dt =
- serd_new_literal("hello_dt\"", "http://example.org/Thing", NULL);
+ SerdNode* hello_dt = serd_new_literal(serd_string("hello_dt\""),
+ serd_string("http://example.org/Thing"),
+ serd_empty_string());
+
assert(serd_node_length(hello_dt) == 9);
assert(!strcmp(serd_node_string(hello_dt), "hello_dt\""));
assert(serd_node_flags(hello_dt) == (SERD_HAS_QUOTE | SERD_HAS_DATATYPE));
@@ -241,6 +248,16 @@ test_literal(void)
serd_node_free(hello_dt);
}
+static void
+test_blank(void)
+{
+ SerdNode* blank = serd_new_blank(serd_string("b0"));
+ assert(serd_node_length(blank) == 2);
+ assert(serd_node_flags(blank) == 0);
+ assert(!strcmp(serd_node_string(blank), "b0"));
+ serd_node_free(blank);
+}
+
int
main(void)
{
@@ -252,6 +269,7 @@ main(void)
test_node_from_string();
test_node_from_substring();
test_literal();
+ test_blank();
printf("Success\n");
return 0;
diff --git a/test/test_reader_writer.c b/test/test_reader_writer.c
index 245f5328..b1121cbc 100644
--- a/test/test_reader_writer.c
+++ b/test/test_reader_writer.c
@@ -13,6 +13,7 @@
#include "serd/statement.h"
#include "serd/status.h"
#include "serd/stream.h"
+#include "serd/string_view.h"
#include "serd/syntax.h"
#include "serd/writer.h"
@@ -414,9 +415,9 @@ test_write_errors(void)
ctx.n_written = 0;
ctx.error_offset = o;
- SerdEnv* const env = serd_env_new(NULL);
+ SerdEnv* const env = serd_env_new(serd_empty_string());
SerdWriter* const writer =
- serd_writer_new(syntax, style, env, NULL, faulty_sink, &ctx);
+ serd_writer_new(syntax, style, env, faulty_sink, &ctx);
SerdReader* const reader =
serd_reader_new(SERD_TRIG,
@@ -444,27 +445,28 @@ static void
test_writer(const char* const path)
{
FILE* fd = fopen(path, "wb");
- SerdEnv* env = serd_env_new(NULL);
+ SerdEnv* env = serd_env_new(serd_empty_string());
assert(fd);
- SerdWriter* writer =
- serd_writer_new(SERD_TURTLE, 0, env, NULL, serd_file_sink, fd);
+ SerdWriter* writer = serd_writer_new(SERD_TURTLE, 0, env, serd_file_sink, fd);
assert(writer);
serd_writer_chop_blank_prefix(writer, "tmp");
serd_writer_chop_blank_prefix(writer, NULL);
- SerdNode* lit = serd_new_string(SERD_LITERAL, "hello");
+ SerdNode* lit = serd_new_string(serd_string("hello"));
assert(serd_writer_set_base_uri(writer, lit));
assert(serd_writer_set_prefix(writer, lit, lit));
assert(serd_writer_end_anon(writer, NULL));
assert(serd_writer_env(writer) == env);
- uint8_t buf[] = {0xEF, 0xBF, 0xBD, 0};
- SerdNode* s = serd_new_string(SERD_URI, "");
- SerdNode* p = serd_new_string(SERD_URI, "http://example.org/pred");
- SerdNode* o = serd_new_string(SERD_LITERAL, (char*)buf);
+ static const uint8_t buf[] = {0xEF, 0xBF, 0xBD, 0};
+ const SerdStringView buf_view = {(const char*)buf, 3};
+
+ SerdNode* s = serd_new_uri(serd_empty_string());
+ SerdNode* p = serd_new_uri(serd_string("http://example.org/pred"));
+ SerdNode* o = serd_new_string(buf_view);
// Write 3 invalid statements (should write nothing)
const SerdNode* junk[][3] = {{s, o, o}, {o, p, o}, {s, o, p}};
@@ -473,26 +475,33 @@ test_writer(const char* const path)
writer, 0, NULL, junk[i][0], junk[i][1], junk[i][2]));
}
- SerdNode* t = serd_new_literal((char*)buf, "urn:Type", NULL);
- SerdNode* l = serd_new_literal((char*)buf, NULL, "en");
+ const SerdStringView empty = serd_empty_string();
+ const SerdStringView urn_Type = serd_string("urn:Type");
+ const SerdStringView en = serd_string("en");
+
+ SerdNode* const t = serd_new_literal(buf_view, urn_Type, empty);
+ SerdNode* const l = serd_new_literal(buf_view, empty, en);
const SerdNode* good[][3] = {{s, p, o}, {s, p, t}, {s, p, l}};
+
for (size_t i = 0; i < sizeof(good) / (sizeof(SerdNode*) * 3); ++i) {
assert(!serd_writer_write_statement(
writer, 0, NULL, good[i][0], good[i][1], good[i][2]));
}
// Write statements with bad UTF-8 (should be replaced)
- const char bad_str[] = {(char)0xFF, (char)0x90, 'h', 'i', 0};
- SerdNode* bad_lit = serd_new_string(SERD_LITERAL, bad_str);
- SerdNode* bad_uri = serd_new_string(SERD_URI, bad_str);
+ const char bad_str[] = {(char)0xFF, (char)0x90, 'h', 'i', 0};
+ const SerdStringView bad_view = {(const char*)bad_str, 4};
+ SerdNode* bad_lit = serd_new_string(bad_view);
+ SerdNode* bad_uri = serd_new_uri(bad_view);
assert(!serd_writer_write_statement(writer, 0, NULL, s, p, bad_lit));
assert(!serd_writer_write_statement(writer, 0, NULL, s, p, bad_uri));
- serd_node_free(bad_lit);
+
serd_node_free(bad_uri);
+ serd_node_free(bad_lit);
// Write 1 valid statement
serd_node_free(o);
- o = serd_new_string(SERD_LITERAL, "hello");
+ o = serd_new_string(serd_string("hello"));
assert(!serd_writer_write_statement(writer, 0, NULL, s, p, o));
serd_writer_free(writer);
@@ -503,13 +512,13 @@ test_writer(const char* const path)
// Test buffer sink
SerdBuffer buffer = {NULL, 0};
- writer =
- serd_writer_new(SERD_TURTLE, 0, env, NULL, serd_buffer_sink, &buffer);
+ writer = serd_writer_new(SERD_TURTLE, 0, env, serd_buffer_sink, &buffer);
- o = serd_new_string(SERD_URI, "http://example.org/base");
- assert(!serd_writer_set_base_uri(writer, o));
+ SerdNode* const base = serd_new_uri(serd_string("http://example.org/base"));
- serd_node_free(o);
+ serd_writer_set_base_uri(writer, base);
+
+ serd_node_free(base);
serd_writer_free(writer);
char* out = serd_buffer_sink_finish(&buffer);
@@ -540,7 +549,7 @@ test_reader(const char* path)
assert(serd_reader_read_chunk(reader) == SERD_FAILURE);
- SerdNode* g = serd_new_string(SERD_URI, "http://example.org/");
+ SerdNode* g = serd_new_uri(serd_string("http://example.org/"));
serd_reader_set_default_graph(reader, g);
serd_reader_add_blank_prefix(reader, "tmp");
diff --git a/test/test_uri.c b/test/test_uri.c
index 3fe0ebd5..74b732fd 100644
--- a/test/test_uri.c
+++ b/test/test_uri.c
@@ -44,7 +44,8 @@ test_file_uri(const char* const hostname,
expected_path = path;
}
- SerdNode* node = serd_new_file_uri(path, hostname, 0);
+ SerdNode* node = serd_new_file_uri(serd_string(path), serd_string(hostname));
+
const char* node_str = serd_node_string(node);
char* out_hostname = NULL;
char* out_path = serd_parse_file_uri(node_str, &out_hostname);
@@ -193,22 +194,21 @@ check_relative_uri(const char* const uri_string,
assert(base_string);
assert(expected_string);
- SerdNode* const uri_node = serd_new_uri(uri_string);
+ SerdNode* const uri_node = serd_new_uri(serd_string(uri_string));
const SerdURIView uri = serd_node_uri_view(uri_node);
- SerdNode* const base_node = serd_new_uri(base_string);
+ SerdNode* const base_node = serd_new_uri(serd_string(base_string));
const SerdURIView base = serd_node_uri_view(base_node);
SerdNode* result_node = NULL;
if (!root_string) {
result_node = serd_new_parsed_uri(serd_relative_uri(uri, base));
} else {
- SerdNode* const root_node = serd_new_uri(root_string);
+ SerdNode* const root_node = serd_new_uri(serd_string(root_string));
const SerdURIView root = serd_node_uri_view(root_node);
result_node = serd_uri_is_within(uri, root)
? serd_new_parsed_uri(serd_relative_uri(uri, base))
- : serd_new_uri(uri_string);
-
+ : serd_new_uri(serd_string(uri_string));
serd_node_free(root_node);
}
diff --git a/test/test_writer.c b/test/test_writer.c
index 68d9e14e..b15f7fdc 100644
--- a/test/test_writer.c
+++ b/test/test_writer.c
@@ -9,6 +9,7 @@
#include "serd/node.h"
#include "serd/statement.h"
#include "serd/status.h"
+#include "serd/string_view.h"
#include "serd/syntax.h"
#include "serd/writer.h"
@@ -18,18 +19,46 @@
#include <string.h>
static void
+test_write_bad_prefix(void)
+{
+ SerdEnv* env = serd_env_new(serd_empty_string());
+ SerdBuffer buffer = {NULL, 0};
+ SerdWriter* writer =
+ serd_writer_new(SERD_TURTLE, 0U, env, serd_buffer_sink, &buffer);
+
+ assert(writer);
+
+ SerdNode* name = serd_new_string(serd_string("eg"));
+ SerdNode* uri = serd_new_uri(serd_string("rel"));
+
+ assert(serd_writer_set_prefix(writer, name, uri) == SERD_BAD_ARG);
+
+ char* const out = serd_buffer_sink_finish(&buffer);
+
+ assert(!strcmp(out, ""));
+ serd_free(out);
+
+ serd_node_free(uri);
+ serd_node_free(name);
+ serd_writer_free(writer);
+ serd_env_free(env);
+}
+
+static void
test_write_long_literal(void)
{
- SerdEnv* env = serd_env_new(NULL);
+ SerdEnv* env = serd_env_new(serd_empty_string());
SerdBuffer buffer = {NULL, 0};
SerdWriter* writer =
- serd_writer_new(SERD_TURTLE, 0U, env, NULL, serd_buffer_sink, &buffer);
+ serd_writer_new(SERD_TURTLE, 0U, env, serd_buffer_sink, &buffer);
assert(writer);
- SerdNode* s = serd_new_string(SERD_URI, "http://example.org/s");
- SerdNode* p = serd_new_string(SERD_URI, "http://example.org/p");
- SerdNode* o = serd_new_string(SERD_LITERAL, "hello \"\"\"world\"\"\"!");
+ SerdNode* s = serd_new_uri(serd_string("http://example.org/s"));
+ SerdNode* p = serd_new_uri(serd_string("http://example.org/p"));
+ SerdNode* o = serd_new_literal(serd_string("hello \"\"\"world\"\"\"!"),
+ serd_empty_string(),
+ serd_empty_string());
assert(!serd_writer_write_statement(writer, 0, NULL, s, p, o));
@@ -61,14 +90,13 @@ null_sink(const void* const buf, const size_t len, void* const stream)
static void
test_writer_cleanup(void)
{
- SerdStatus st = SERD_SUCCESS;
- SerdEnv* env = serd_env_new(NULL);
- SerdWriter* writer =
- serd_writer_new(SERD_TURTLE, 0U, env, NULL, null_sink, NULL);
+ SerdStatus st = SERD_SUCCESS;
+ SerdEnv* env = serd_env_new(serd_empty_string());
+ SerdWriter* writer = serd_writer_new(SERD_TURTLE, 0U, env, null_sink, NULL);
- SerdNode* s = serd_new_string(SERD_URI, "http://example.org/s");
- SerdNode* p = serd_new_string(SERD_URI, "http://example.org/p");
- SerdNode* o = serd_new_string(SERD_BLANK, "http://example.org/o");
+ SerdNode* s = serd_new_uri(serd_string("http://example.org/s"));
+ SerdNode* p = serd_new_uri(serd_string("http://example.org/p"));
+ SerdNode* o = serd_new_blank(serd_string("start"));
st = serd_writer_write_statement(writer, SERD_ANON_O_BEGIN, NULL, s, p, o);
assert(!st);
@@ -78,7 +106,7 @@ test_writer_cleanup(void)
char buf[12] = {0};
snprintf(buf, sizeof(buf), "b%u", i);
- SerdNode* next_o = serd_new_string(SERD_BLANK, buf);
+ SerdNode* next_o = serd_new_blank(serd_string(buf));
st = serd_writer_write_statement(
writer, SERD_ANON_O_BEGIN, NULL, o, p, next_o);
@@ -89,6 +117,7 @@ test_writer_cleanup(void)
// Finish writing without terminating nodes
assert(!(st = serd_writer_finish(writer)));
+ assert(!(st = serd_writer_set_base_uri(writer, NULL)));
// Set the base to an empty URI
assert(!(st = serd_writer_set_base_uri(writer, NULL)));
@@ -108,19 +137,19 @@ test_strict_write(void)
FILE* const fd = fopen(path, "wb");
assert(fd);
- SerdEnv* const env = serd_env_new(NULL);
+ SerdEnv* const env = serd_env_new(serd_empty_string());
SerdWriter* const writer = serd_writer_new(
- SERD_TURTLE, (SerdWriterFlags)SERD_WRITE_STRICT, env, NULL, null_sink, fd);
+ SERD_TURTLE, (SerdWriterFlags)SERD_WRITE_STRICT, env, null_sink, fd);
assert(writer);
const uint8_t bad_str[] = {0xFF, 0x90, 'h', 'i', 0};
- SerdNode* s = serd_new_string(SERD_URI, "http://example.org/s");
- SerdNode* p = serd_new_string(SERD_URI, "http://example.org/p");
+ SerdNode* s = serd_new_uri(serd_string("http://example.org/s"));
+ SerdNode* p = serd_new_uri(serd_string("http://example.org/p"));
- SerdNode* bad_lit = serd_new_string(SERD_LITERAL, (const char*)bad_str);
- SerdNode* bad_uri = serd_new_string(SERD_URI, (const char*)bad_str);
+ SerdNode* bad_lit = serd_new_string(serd_string((const char*)bad_str));
+ SerdNode* bad_uri = serd_new_uri(serd_string((const char*)bad_str));
assert(serd_writer_write_statement(writer, 0, NULL, s, p, bad_lit) ==
SERD_BAD_TEXT);
@@ -151,14 +180,14 @@ error_sink(const void* const buf, const size_t len, void* const stream)
static void
test_write_error(void)
{
- SerdEnv* const env = serd_env_new(NULL);
+ SerdEnv* const env = serd_env_new(serd_empty_string());
SerdWriter* writer = NULL;
SerdStatus st = SERD_SUCCESS;
- SerdNode* u = serd_new_string(SERD_URI, "http://example.com/u");
+ SerdNode* u = serd_new_uri(serd_string("http://example.com/u"));
- writer = serd_writer_new(
- SERD_TURTLE, (SerdWriterFlags)0, env, NULL, error_sink, NULL);
+ writer =
+ serd_writer_new(SERD_TURTLE, (SerdWriterFlags)0, env, error_sink, NULL);
assert(writer);
st = serd_writer_write_statement(writer, 0U, NULL, u, u, u);
assert(st == SERD_BAD_WRITE);
@@ -171,6 +200,7 @@ test_write_error(void)
int
main(void)
{
+ test_write_bad_prefix();
test_write_long_literal();
test_writer_cleanup();
test_strict_write();