diff options
-rw-r--r-- | include/serd/env.h | 23 | ||||
-rw-r--r-- | include/serd/node.h | 42 | ||||
-rw-r--r-- | include/serd/writer.h | 11 | ||||
-rw-r--r-- | src/env.c | 97 | ||||
-rw-r--r-- | src/env.h | 14 | ||||
-rw-r--r-- | src/node.c | 151 | ||||
-rw-r--r-- | src/serdi.c | 25 | ||||
-rw-r--r-- | src/writer.c | 42 | ||||
-rw-r--r-- | test/test_env.c | 49 | ||||
-rw-r--r-- | test/test_node.c | 62 | ||||
-rw-r--r-- | test/test_reader_writer.c | 55 | ||||
-rw-r--r-- | test/test_uri.c | 12 | ||||
-rw-r--r-- | test/test_writer.c | 76 |
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 @@ -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 @@ -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(); |