aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--serd/serd.h58
-rw-r--r--src/env.c77
-rw-r--r--src/node.c168
-rw-r--r--src/reader.c22
-rw-r--r--src/serd_internal.h12
-rw-r--r--src/serdi.c13
-rw-r--r--src/writer.c149
-rw-r--r--tests/serd_test.c351
8 files changed, 457 insertions, 393 deletions
diff --git a/serd/serd.h b/serd/serd.h
index 1d217a3c..63a17be9 100644
--- a/serd/serd.h
+++ b/serd/serd.h
@@ -214,12 +214,7 @@ typedef uint32_t SerdNodeFlags;
/**
A syntactic RDF node.
*/
-typedef struct {
- const char* buf; /**< Value string */
- size_t n_bytes; /**< Size in bytes (not including null) */
- SerdNodeFlags flags; /**< Node flags (e.g. string properties) */
- SerdType type; /**< Node type */
-} SerdNode;
+typedef struct SerdNodeImpl SerdNode;
/**
An unterminated immutable slice of a string.
@@ -445,34 +440,25 @@ serd_uri_serialise_relative(const SerdURI* uri,
@{
*/
-static const SerdNode SERD_NODE_NULL = { NULL, 0, 0, SERD_NOTHING };
-
/**
- Make a (shallow) node from `str`.
-
- This measures, but does not copy, `str`. No memory is allocated.
+ Create a new node from `str`.
*/
SERD_API
-SerdNode
-serd_node_from_string(SerdType type, const char* str);
+SerdNode*
+serd_node_new_string(SerdType type, const char* str);
/**
- Make a (shallow) node from a prefix of `str`.
-
- This measures, but does not copy, `str`. No memory is allocated.
- Note that the returned node may not be null terminated.
+ Create a new node from a prefix of `str`.
*/
SERD_API
-SerdNode
-serd_node_from_substring(SerdType type, const char* str, size_t len);
+SerdNode*
+serd_node_new_substring(SerdType type, const char* str, size_t len);
/**
- Make a deep copy of `node`.
-
- @return a node that the caller must free with serd_node_free().
+ Return a deep copy of `node`.
*/
SERD_API
-SerdNode
+SerdNode*
serd_node_copy(const SerdNode* node);
/**
@@ -486,7 +472,7 @@ serd_node_equals(const SerdNode* a, const SerdNode* b);
Simple wrapper for serd_node_new_uri() to resolve a URI node.
*/
SERD_API
-SerdNode
+SerdNode*
serd_node_new_uri_from_node(const SerdNode* uri_node,
const SerdURI* base,
SerdURI* out);
@@ -495,7 +481,7 @@ serd_node_new_uri_from_node(const SerdNode* uri_node,
Simple wrapper for serd_node_new_uri() to resolve a URI string.
*/
SERD_API
-SerdNode
+SerdNode*
serd_node_new_uri_from_string(const char* str,
const SerdURI* base,
SerdURI* out);
@@ -511,7 +497,7 @@ serd_node_new_uri_from_string(const char* str,
If `out` is not NULL, it will be set to the parsed URI.
*/
SERD_API
-SerdNode
+SerdNode*
serd_node_new_file_uri(const char* path,
const char* hostname,
SerdURI* out,
@@ -528,7 +514,7 @@ serd_node_new_file_uri(const char* path,
memory owned by the new returned node).
*/
SERD_API
-SerdNode
+SerdNode*
serd_node_new_uri(const SerdURI* uri, const SerdURI* base, SerdURI* out);
/**
@@ -544,7 +530,7 @@ serd_node_new_uri(const SerdURI* uri, const SerdURI* base, SerdURI* out);
memory owned by the new returned node).
*/
SERD_API
-SerdNode
+SerdNode*
serd_node_new_relative_uri(const SerdURI* uri,
const SerdURI* base,
const SerdURI* root,
@@ -566,14 +552,14 @@ serd_node_new_relative_uri(const SerdURI* uri,
@param frac_digits The maximum number of digits after the decimal place.
*/
SERD_API
-SerdNode
+SerdNode*
serd_node_new_decimal(double d, unsigned frac_digits);
/**
Create a new node by serialising `i` into an xsd:integer string.
*/
SERD_API
-SerdNode
+SerdNode*
serd_node_new_integer(int64_t i);
/**
@@ -586,7 +572,7 @@ serd_node_new_integer(int64_t i);
@param wrap_lines Wrap lines at 76 characters to conform to RFC 2045.
*/
SERD_API
-SerdNode
+SerdNode*
serd_node_new_blob(const void* buf, size_t size, bool wrap_lines);
/**
@@ -742,10 +728,10 @@ serd_env_set_prefix_from_strings(SerdEnv* env,
*/
SERD_API
bool
-serd_env_qualify(const SerdEnv* env,
- const SerdNode* uri,
- SerdNode* prefix,
- SerdSlice* suffix);
+serd_env_qualify(const SerdEnv* env,
+ const SerdNode* uri,
+ const SerdNode** prefix,
+ SerdSlice* suffix);
/**
Expand `curie`.
@@ -766,7 +752,7 @@ serd_env_expand(const SerdEnv* env,
Returns null if `node` can not be expanded.
*/
SERD_API
-SerdNode
+SerdNode*
serd_env_expand_node(const SerdEnv* env,
const SerdNode* node);
diff --git a/src/env.c b/src/env.c
index f1bfd2d7..6abcef72 100644
--- a/src/env.c
+++ b/src/env.c
@@ -20,14 +20,14 @@
#include <string.h>
typedef struct {
- SerdNode name;
- SerdNode uri;
+ SerdNode* name;
+ SerdNode* uri;
} SerdPrefix;
struct SerdEnvImpl {
SerdPrefix* prefixes;
size_t n_prefixes;
- SerdNode base_uri_node;
+ SerdNode* base_uri_node;
SerdURI base_uri;
};
@@ -47,11 +47,11 @@ void
serd_env_free(SerdEnv* env)
{
for (size_t i = 0; i < env->n_prefixes; ++i) {
- serd_node_free(&env->prefixes[i].name);
- serd_node_free(&env->prefixes[i].uri);
+ serd_node_free(env->prefixes[i].name);
+ serd_node_free(env->prefixes[i].uri);
}
free(env->prefixes);
- serd_node_free(&env->base_uri_node);
+ serd_node_free(env->base_uri_node);
free(env);
}
@@ -63,7 +63,7 @@ serd_env_get_base_uri(const SerdEnv* env,
if (out) {
*out = env->base_uri;
}
- return &env->base_uri_node;
+ return env->base_uri_node;
}
SERD_API
@@ -76,13 +76,13 @@ serd_env_set_base_uri(SerdEnv* env,
}
// Resolve base URI and create a new node and URI for it
- SerdURI base_uri;
- SerdNode base_uri_node = serd_node_new_uri_from_node(
+ SerdURI base_uri;
+ SerdNode* base_uri_node = serd_node_new_uri_from_node(
uri, &env->base_uri, &base_uri);
- if (base_uri_node.buf) {
+ if (base_uri_node) {
// Replace the current base URI
- serd_node_free(&env->base_uri_node);
+ serd_node_free(env->base_uri_node);
env->base_uri_node = base_uri_node;
env->base_uri = base_uri;
return SERD_SUCCESS;
@@ -96,7 +96,7 @@ serd_env_find(const SerdEnv* env,
size_t name_len)
{
for (size_t i = 0; i < env->n_prefixes; ++i) {
- const SerdNode* const prefix_name = &env->prefixes[i].name;
+ const SerdNode* const prefix_name = env->prefixes[i].name;
if (prefix_name->n_bytes == name_len) {
if (!memcmp(serd_node_get_string(prefix_name), name, name_len)) {
return &env->prefixes[i];
@@ -114,9 +114,9 @@ serd_env_add(SerdEnv* env,
const char* name_str = serd_node_get_string(name);
SerdPrefix* const prefix = serd_env_find(env, name_str, name->n_bytes);
if (prefix) {
- SerdNode old_prefix_uri = prefix->uri;
+ SerdNode* old_prefix_uri = prefix->uri;
prefix->uri = serd_node_copy(uri);
- serd_node_free(&old_prefix_uri);
+ serd_node_free(old_prefix_uri);
} else {
env->prefixes = (SerdPrefix*)realloc(
env->prefixes, (++env->n_prefixes) * sizeof(SerdPrefix));
@@ -131,20 +131,20 @@ serd_env_set_prefix(SerdEnv* env,
const SerdNode* name,
const SerdNode* uri)
{
- if (!name->buf || uri->type != SERD_URI) {
+ if (!name || uri->type != SERD_URI) {
return SERD_ERR_BAD_ARG;
} else if (serd_uri_string_has_scheme(serd_node_get_string(uri))) {
// Set prefix to absolute URI
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(
+ SerdURI abs_uri;
+ SerdNode* abs_uri_node = serd_node_new_uri_from_node(
uri, &env->base_uri, &abs_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_node);
+ serd_node_free(abs_uri_node);
}
return SERD_SUCCESS;
}
@@ -155,10 +155,14 @@ serd_env_set_prefix_from_strings(SerdEnv* env,
const char* name,
const char* uri)
{
- const SerdNode name_node = serd_node_from_string(SERD_LITERAL, name);
- const SerdNode uri_node = serd_node_from_string(SERD_URI, uri);
+ SerdNode* name_node = serd_node_new_string(SERD_LITERAL, name);
+ SerdNode* uri_node = serd_node_new_string(SERD_URI, uri);
- return serd_env_set_prefix(env, &name_node, &uri_node);
+ const SerdStatus st = serd_env_set_prefix(env, name_node, uri_node);
+
+ serd_node_free(name_node);
+ serd_node_free(uri_node);
+ return st;
}
static inline bool
@@ -184,13 +188,13 @@ is_name(const char* buf, size_t len)
SERD_API
bool
-serd_env_qualify(const SerdEnv* env,
- const SerdNode* uri,
- SerdNode* prefix,
- SerdSlice* suffix)
+serd_env_qualify(const SerdEnv* env,
+ const SerdNode* uri,
+ const SerdNode** prefix,
+ SerdSlice* suffix)
{
for (size_t i = 0; i < env->n_prefixes; ++i) {
- const SerdNode* const prefix_uri = &env->prefixes[i].uri;
+ const SerdNode* const prefix_uri = env->prefixes[i].uri;
if (uri->n_bytes >= prefix_uri->n_bytes) {
const char* prefix_str = serd_node_get_string(prefix_uri);
const char* uri_str = serd_node_get_string(uri);
@@ -224,8 +228,8 @@ serd_env_expand(const SerdEnv* env,
const size_t name_len = colon - str;
const SerdPrefix* const prefix = serd_env_find(env, str, name_len);
if (prefix) {
- uri_prefix->buf = serd_node_get_string(&prefix->uri);
- uri_prefix->len = prefix->uri.n_bytes;
+ uri_prefix->buf = serd_node_get_string(prefix->uri);
+ uri_prefix->len = prefix->uri->n_bytes;
uri_suffix->buf = colon + 1;
uri_suffix->len = curie->n_bytes - (colon - str) - 1;
return SERD_SUCCESS;
@@ -234,7 +238,7 @@ serd_env_expand(const SerdEnv* env,
}
SERD_API
-SerdNode
+SerdNode*
serd_env_expand_node(const SerdEnv* env,
const SerdNode* node)
{
@@ -243,12 +247,13 @@ serd_env_expand_node(const SerdEnv* env,
SerdSlice prefix;
SerdSlice suffix;
if (serd_env_expand(env, node, &prefix, &suffix)) {
- return SERD_NODE_NULL;
+ return NULL;
}
const size_t len = prefix.len + suffix.len;
- char* buf = (char*)malloc(len + 1);
- SerdNode ret = { buf, len, 0, SERD_URI };
- snprintf((char*)buf, ret.n_bytes + 1, "%s%s", prefix.buf, suffix.buf);
+ SerdNode* ret = serd_node_malloc(len, 0, SERD_URI);
+ char* buf = serd_node_buffer(ret);
+ snprintf(buf, len + 1, "%s%s", prefix.buf, suffix.buf);
+ ret->n_bytes = len;
return ret;
}
case SERD_URI: {
@@ -256,7 +261,7 @@ serd_env_expand_node(const SerdEnv* env,
return serd_node_new_uri_from_node(node, &env->base_uri, &ignored);
}
default:
- return SERD_NODE_NULL;
+ return NULL;
}
}
@@ -267,6 +272,6 @@ serd_env_foreach(const SerdEnv* env,
void* handle)
{
for (size_t i = 0; i < env->n_prefixes; ++i) {
- func(handle, &env->prefixes[i].name, &env->prefixes[i].uri);
+ func(handle, env->prefixes[i].name, env->prefixes[i].uri);
}
}
diff --git a/src/node.c b/src/node.c
index 65a2172b..e7e18533 100644
--- a/src/node.c
+++ b/src/node.c
@@ -31,52 +31,79 @@
# endif
#endif
+SerdNode*
+serd_node_malloc(size_t n_bytes, SerdNodeFlags flags, SerdType type)
+{
+ SerdNode* node = (SerdNode*)calloc(1, sizeof(SerdNode) + n_bytes + 1);
+ node->n_bytes = 0;
+ node->flags = flags;
+ node->type = type;
+ return node;
+}
+
char*
serd_node_buffer(SerdNode* node)
{
return (char*)(node + 1);
}
+void
+serd_node_set(SerdNode** dst, const SerdNode* src)
+{
+ if (src) {
+ if (!(*dst) || (*dst)->n_bytes < src->n_bytes) {
+ (*dst) = (SerdNode*)realloc(*dst, sizeof(SerdNode) + src->n_bytes + 1);
+ }
+
+ memcpy(*dst, src, sizeof(SerdNode) + src->n_bytes + 1);
+ } else if (*dst) {
+ (*dst)->type = SERD_NOTHING;
+ }
+}
+
SERD_API
-SerdNode
-serd_node_from_string(SerdType type, const char* str)
+SerdNode*
+serd_node_new_string(SerdType type, const char* str)
{
if (!str) {
- return SERD_NODE_NULL;
+ return NULL;
}
- uint32_t flags = 0;
- const size_t n_bytes = serd_strlen(str, &flags);
- const SerdNode ret = { str, n_bytes, flags, type };
- return ret;
+ uint32_t flags = 0;
+ const size_t n_bytes = serd_strlen(str, &flags);
+ SerdNode* node = serd_node_malloc(n_bytes, flags, type);
+ memcpy(serd_node_buffer(node), str, n_bytes);
+ node->n_bytes = n_bytes;
+ return node;
}
SERD_API
-SerdNode
-serd_node_from_substring(SerdType type, const char* str, const size_t len)
+SerdNode*
+serd_node_new_substring(SerdType type, const char* str, const size_t len)
{
if (!str) {
- return SERD_NODE_NULL;
+ return NULL;
}
- uint32_t flags = 0;
- const size_t n_bytes = serd_substrlen(str, len, &flags);
- const SerdNode ret = { str, n_bytes, flags, type };
- return ret;
+ uint32_t flags = 0;
+ const size_t n_bytes = serd_substrlen(str, len, &flags);
+ SerdNode* node = serd_node_malloc(n_bytes, flags, type);
+ memcpy(serd_node_buffer(node), str, n_bytes);
+ node->n_bytes = n_bytes;
+ return node;
}
SERD_API
-SerdNode
+SerdNode*
serd_node_copy(const SerdNode* node)
{
- if (!node || !node->buf) {
- return SERD_NODE_NULL;
+ if (!node) {
+ return NULL;
}
- SerdNode copy = *node;
- char* buf = (char*)malloc(copy.n_bytes + 1);
- memcpy(buf, node->buf, copy.n_bytes + 1);
- copy.buf = buf;
+ const size_t size = sizeof(SerdNode) + node->n_bytes + 1;
+ SerdNode* copy = (SerdNode*)malloc(size);
+ memcpy(copy, node, size);
return copy;
}
@@ -84,12 +111,11 @@ SERD_API
bool
serd_node_equals(const SerdNode* a, const SerdNode* b)
{
- return (a == b)
- || (a->type == b->type
- && a->n_bytes == b->n_bytes
- && ((a->buf == b->buf) || !memcmp((const char*)a->buf,
- (const char*)b->buf,
- a->n_bytes + 1)));
+ return (a == b) ||
+ (a && b && a->type == b->type && a->n_bytes == b->n_bytes &&
+ !memcmp(serd_node_get_string(a),
+ serd_node_get_string(b),
+ a->n_bytes));
}
static size_t
@@ -119,7 +145,7 @@ string_sink(const void* buf, size_t len, void* stream)
}
SERD_API
-SerdNode
+SerdNode*
serd_node_new_uri_from_node(const SerdNode* uri_node,
const SerdURI* base,
SerdURI* out)
@@ -127,18 +153,18 @@ serd_node_new_uri_from_node(const SerdNode* uri_node,
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)
- : SERD_NODE_NULL;
+ : NULL;
}
SERD_API
-SerdNode
+SerdNode*
serd_node_new_uri_from_string(const char* str,
const SerdURI* base,
SerdURI* out)
{
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) : SERD_NODE_NULL;
+ return base ? serd_node_new_uri(base, NULL, out) : NULL;
}
SerdURI uri;
@@ -166,7 +192,7 @@ is_uri_path_char(const char c)
}
SERD_API
-SerdNode
+SerdNode*
serd_node_new_file_uri(const char* path,
const char* hostname,
SerdURI* out,
@@ -201,16 +227,18 @@ 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((const char*)buffer.buf, out);
+ serd_uri_parse(serd_node_buffer(node), out);
}
- return serd_node_from_substring(
- SERD_URI, (const char*)buffer.buf, buffer.len);
+ free(buffer.buf);
+ return node;
}
SERD_API
-SerdNode
+SerdNode*
serd_node_new_uri(const SerdURI* uri, const SerdURI* base, SerdURI* out)
{
SerdURI abs_uri = *uri;
@@ -219,23 +247,22 @@ serd_node_new_uri(const SerdURI* uri, const SerdURI* base, SerdURI* out)
}
const size_t len = serd_uri_string_length(&abs_uri);
- char* buf = (char*)malloc(len + 1);
- SerdNode node = { buf, len, 0, SERD_URI };
- char* ptr = buf;
+ SerdNode* node = serd_node_malloc(len, 0, SERD_URI);
+ char* ptr = serd_node_buffer(node);
const size_t actual_len = serd_uri_serialise(&abs_uri, string_sink, &ptr);
- buf[actual_len] = '\0';
- node.n_bytes = actual_len;
+ serd_node_buffer(node)[actual_len] = '\0';
+ node->n_bytes = actual_len;
if (out) {
- serd_uri_parse(buf, out); // TODO: cleverly avoid double parse
+ serd_uri_parse(serd_node_buffer(node), out); // TODO: avoid double parse
}
return node;
}
SERD_API
-SerdNode
+SerdNode*
serd_node_new_relative_uri(const SerdURI* uri,
const SerdURI* base,
const SerdURI* root,
@@ -243,17 +270,16 @@ serd_node_new_relative_uri(const SerdURI* uri,
{
const size_t uri_len = serd_uri_string_length(uri);
const size_t base_len = serd_uri_string_length(base);
- char* buf = (char*)malloc(uri_len + base_len + 1);
- SerdNode node = { buf, 0, 0, SERD_URI };
- char* ptr = buf;
+ 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);
- buf[actual_len] = '\0';
- node.n_bytes = actual_len;
+ serd_node_buffer(node)[actual_len] = '\0';
+ node->n_bytes = actual_len;
if (out) {
- serd_uri_parse(buf, out); // TODO: cleverly avoid double parse
+ serd_uri_parse(serd_node_buffer(node), out); // TODO: avoid double parse
}
return node;
@@ -267,18 +293,19 @@ serd_digits(double abs)
}
SERD_API
-SerdNode
+SerdNode*
serd_node_new_decimal(double d, unsigned frac_digits)
{
if (isnan(d) || isinf(d)) {
- return SERD_NODE_NULL;
+ return NULL;
}
- const double abs_d = fabs(d);
- const unsigned int_digits = serd_digits(abs_d);
- char* buf = (char*)calloc(int_digits + frac_digits + 3, 1);
- SerdNode node = { buf, 0, 0, SERD_LITERAL };
- const double int_part = floor(abs_d);
+ const double abs_d = fabs(d);
+ const unsigned int_digits = serd_digits(abs_d);
+ const size_t len = int_digits + frac_digits + 3;
+ SerdNode* const node = serd_node_malloc(len, 0, SERD_LITERAL);
+ char* const buf = serd_node_buffer(node);
+ const double int_part = floor(abs_d);
// Point s to decimal point location
char* s = buf + int_digits;
@@ -294,13 +321,14 @@ serd_node_new_decimal(double d, unsigned frac_digits)
*t-- = '0' + (dec % 10);
} while ((dec /= 10) > 0);
+
*s++ = '.';
// Write fractional part (right to left)
double frac_part = fabs(d - int_part);
if (frac_part < DBL_EPSILON) {
*s++ = '0';
- node.n_bytes = (s - buf);
+ node->n_bytes = (s - buf);
} else {
uint64_t frac = frac_part * pow(10.0, (int)frac_digits) + 0.5;
s += frac_digits - 1;
@@ -309,7 +337,7 @@ serd_node_new_decimal(double d, unsigned frac_digits)
// Skip trailing zeros
for (; i < frac_digits - 1 && !(frac % 10); ++i, --s, frac /= 10) {}
- node.n_bytes = (s - buf) + 1;
+ node->n_bytes = (s - buf) + 1;
// Write digits from last trailing zero to decimal point
for (; i < frac_digits; ++i) {
@@ -322,13 +350,13 @@ serd_node_new_decimal(double d, unsigned frac_digits)
}
SERD_API
-SerdNode
+SerdNode*
serd_node_new_integer(int64_t i)
{
int64_t abs_i = (i < 0) ? -i : i;
const unsigned digits = serd_digits(abs_i);
- char* buf = (char*)calloc(digits + 2, 1);
- SerdNode node = { (const char*)buf, 0, 0, SERD_LITERAL };
+ SerdNode* node = serd_node_malloc(digits + 2, 0, SERD_LITERAL);
+ char* buf = serd_node_buffer(node);
// Point s to the end
char* s = buf + digits - 1;
@@ -337,7 +365,7 @@ serd_node_new_integer(int64_t i)
++s;
}
- node.n_bytes = (s - buf) + 1;
+ node->n_bytes = (s - buf) + 1;
// Write integer part (right to left)
do {
@@ -369,12 +397,12 @@ encode_chunk(uint8_t out[4], const uint8_t in[3], size_t n_in)
}
SERD_API
-SerdNode
+SerdNode*
serd_node_new_blob(const void* buf, size_t size, bool wrap_lines)
{
const size_t len = ((size + 2) / 3) * 4 + (wrap_lines ? (size / 57) : 0);
- uint8_t* str = (uint8_t*)calloc(1, len + 2);
- SerdNode node = { (const char*)str, len, 0, SERD_LITERAL };
+ SerdNode* node = serd_node_malloc(len + 1, 0, SERD_LITERAL);
+ uint8_t* str = (uint8_t*)serd_node_buffer(node);
for (size_t i = 0, j = 0; i < size; i += 3, j += 4) {
uint8_t in[4] = { 0, 0, 0, 0 };
size_t n_in = MIN(3, size - i);
@@ -382,11 +410,12 @@ serd_node_new_blob(const void* buf, size_t size, bool wrap_lines)
if (wrap_lines && i > 0 && (i % 57) == 0) {
str[j++] = '\n';
- node.flags |= SERD_HAS_NEWLINE;
+ node->flags |= SERD_HAS_NEWLINE;
}
encode_chunk(str + j, in, n_in);
}
+ node->n_bytes = len + 1;
return node;
}
@@ -401,7 +430,7 @@ SERD_API
const char*
serd_node_get_string(const SerdNode* node)
{
- return node ? node->buf : NULL;
+ return node ? (const char*)(node + 1) : NULL;
}
SERD_API
@@ -422,8 +451,5 @@ SERD_API
void
serd_node_free(SerdNode* node)
{
- if (node && node->buf) {
- free((char*)node->buf);
- node->buf = NULL;
- }
+ free(node);
}
diff --git a/src/reader.c b/src/reader.c
index 7e2fa4ec..cedf84cf 100644
--- a/src/reader.c
+++ b/src/reader.c
@@ -40,9 +40,9 @@ void
set_blank_id(SerdReader* reader, Ref ref, size_t buf_size)
{
SerdNode* node = deref(reader, ref);
+ char* buf = (char*)(node + 1);
const char* prefix = reader->bprefix ? (const char*)reader->bprefix : "";
- node->n_bytes = snprintf(
- (char*)node->buf, buf_size, "%sb%u", prefix, reader->next_id++);
+ node->n_bytes = snprintf(buf, buf_size, "%sb%u", prefix, reader->next_id++);
}
size_t
@@ -83,7 +83,6 @@ push_node_padded(SerdReader* reader, size_t maxlen,
node->n_bytes = n_bytes;
node->flags = 0;
node->type = type;
- node->buf = NULL;
char* buf = (char*)(node + 1);
memcpy(buf, str, n_bytes + 1);
@@ -105,12 +104,7 @@ push_node(SerdReader* reader, SerdType type, const char* str, size_t n_bytes)
SerdNode*
deref(SerdReader* reader, const Ref ref)
{
- if (ref) {
- SerdNode* node = (SerdNode*)(reader->stack.buf + ref);
- node->buf = (char*)node + sizeof(SerdNode);
- return node;
- }
- return NULL;
+ return ref ? (SerdNode*)(reader->stack.buf + ref) : NULL;
}
Ref
@@ -133,8 +127,8 @@ bool
emit_statement(SerdReader* reader, ReadContext ctx, Ref o, Ref d, Ref l)
{
SerdNode* graph = deref(reader, ctx.graph);
- if (!graph && reader->default_graph.buf) {
- graph = &reader->default_graph;
+ if (!graph && reader->default_graph) {
+ graph = reader->default_graph;
}
bool ret = !reader->statement_sink ||
!reader->statement_sink(
@@ -179,7 +173,7 @@ serd_reader_new(SerdSyntax syntax,
me->prefix_sink = prefix_sink;
me->statement_sink = statement_sink;
me->end_sink = end_sink;
- me->default_graph = SERD_NODE_NULL;
+ me->default_graph = NULL;
me->stack = serd_stack_new(SERD_PAGE_SIZE);
me->syntax = syntax;
me->next_id = 1;
@@ -216,7 +210,7 @@ serd_reader_free(SerdReader* reader)
pop_node(reader, reader->rdf_nil);
pop_node(reader, reader->rdf_rest);
pop_node(reader, reader->rdf_first);
- serd_node_free(&reader->default_graph);
+ serd_node_free(reader->default_graph);
#ifdef SERD_STACK_CHECK
free(reader->allocs);
@@ -256,7 +250,7 @@ void
serd_reader_set_default_graph(SerdReader* reader,
const SerdNode* graph)
{
- serd_node_free(&reader->default_graph);
+ serd_node_free(reader->default_graph);
reader->default_graph = serd_node_copy(graph);
}
diff --git a/src/serd_internal.h b/src/serd_internal.h
index 6c273b6c..5be89a12 100644
--- a/src/serd_internal.h
+++ b/src/serd_internal.h
@@ -44,6 +44,16 @@
static const uint8_t replacement_char[] = { 0xEF, 0xBF, 0xBD };
+struct SerdNodeImpl {
+ size_t n_bytes; /**< Size in bytes (not including null) */
+ SerdNodeFlags flags; /**< Node flags (e.g. string properties) */
+ SerdType type; /**< Node type */
+};
+
+static const SerdNode SERD_NODE_NULL = { 0, 0, SERD_NOTHING };
+
+SerdNode* serd_node_malloc(size_t n_bytes, SerdNodeFlags flags, SerdType type);
+void serd_node_set(SerdNode** dst, const SerdNode* src);
char* serd_node_buffer(SerdNode* node);
/* File and Buffer Utilities */
@@ -520,7 +530,7 @@ struct SerdReaderImpl {
Ref rdf_first;
Ref rdf_rest;
Ref rdf_nil;
- SerdNode default_graph;
+ SerdNode* default_graph;
SerdByteSource source;
SerdStack stack;
SerdSyntax syntax;
diff --git a/src/serdi.c b/src/serdi.c
index 419d3d06..571e2208 100644
--- a/src/serdi.c
+++ b/src/serdi.c
@@ -221,8 +221,8 @@ main(int argc, char** argv)
: SERD_NQUADS);
}
- SerdURI base_uri = SERD_URI_NULL;
- SerdNode base = SERD_NODE_NULL;
+ SerdURI base_uri = SERD_URI_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);
@@ -231,7 +231,7 @@ main(int argc, char** argv)
}
FILE* out_fd = stdout;
- SerdEnv* env = serd_env_new(&base);
+ SerdEnv* env = serd_env_new(base);
int output_style = 0;
if (output_syntax == SERD_NTRIPLES || ascii) {
@@ -270,10 +270,11 @@ main(int argc, char** argv)
serd_writer_set_error_sink(writer, quiet_error_sink, NULL);
}
- SerdNode root = serd_node_from_string(SERD_URI, root_uri);
- serd_writer_set_root_uri(writer, &root);
+ SerdNode* root = serd_node_new_string(SERD_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);
+ serd_node_free(root);
SerdStatus status = SERD_SUCCESS;
if (!from_file) {
@@ -292,7 +293,7 @@ main(int argc, char** argv)
serd_writer_finish(writer);
serd_writer_free(writer);
serd_env_free(env);
- serd_node_free(&base);
+ serd_node_free(base);
if (from_file) {
fclose(in_fd);
diff --git a/src/writer.c b/src/writer.c
index d40e4024..2190d51f 100644
--- a/src/writer.c
+++ b/src/writer.c
@@ -22,16 +22,12 @@
#include <string.h>
typedef struct {
- SerdNode graph;
- SerdNode subject;
- SerdNode predicate;
+ SerdNode* graph;
+ SerdNode* subject;
+ SerdNode* predicate;
} WriteContext;
-static const WriteContext WRITE_CONTEXT_NULL = {
- { 0, 0, 0, SERD_NOTHING },
- { 0, 0, 0, SERD_NOTHING },
- { 0, 0, 0, SERD_NOTHING }
-};
+static const WriteContext WRITE_CONTEXT_NULL = { NULL, NULL, NULL };
typedef enum {
SEP_NONE,
@@ -82,7 +78,7 @@ struct SerdWriterImpl {
SerdSyntax syntax;
SerdStyle style;
SerdEnv* env;
- SerdNode root_node;
+ SerdNode* root_node;
SerdURI root_uri;
SerdURI base_uri;
SerdStack anon_stack;
@@ -90,7 +86,7 @@ struct SerdWriterImpl {
SerdErrorSink error_sink;
void* error_handle;
WriteContext context;
- SerdNode list_subj;
+ SerdNode* list_subj;
unsigned list_depth;
unsigned indent;
uint8_t* bprefix;
@@ -142,18 +138,23 @@ anon_stack_top(SerdWriter* writer)
+ writer->anon_stack.size - sizeof(WriteContext));
}
-static void
-copy_node(SerdNode* dst, const SerdNode* src)
-{
- if (src) {
- dst->buf = (char*)realloc((char*)dst->buf, src->n_bytes + 1);
- dst->n_bytes = src->n_bytes;
- dst->flags = src->flags;
- dst->type = src->type;
- memcpy((char*)dst->buf, src->buf, src->n_bytes + 1);
- } else {
- dst->type = SERD_NOTHING;
+static inline SerdNode*
+ctx(SerdWriter* writer, const Field field)
+{
+ SerdNode* node = NULL;
+ switch (field) {
+ case FIELD_SUBJECT:
+ node = writer->context.subject;
+ break;
+ case FIELD_PREDICATE:
+ node = writer->context.predicate;
+ break;
+ case FIELD_GRAPH:
+ node = writer->context.graph;
+ default: break;
}
+
+ return node && node->type ? node : NULL;
}
static inline size_t
@@ -394,22 +395,26 @@ write_sep(SerdWriter* writer, const Sep sep)
static SerdStatus
reset_context(SerdWriter* writer, bool graph)
{
- if (graph) {
- writer->context.graph.type = SERD_NOTHING;
+ if (graph && writer->context.graph) {
+ writer->context.graph->type = SERD_NOTHING;
+ }
+ if (writer->context.subject) {
+ writer->context.subject->type = SERD_NOTHING;
+ }
+ if (writer->context.predicate) {
+ writer->context.predicate->type = SERD_NOTHING;
}
- writer->context.subject.type = SERD_NOTHING;
- writer->context.predicate.type = SERD_NOTHING;
- writer->empty = false;
+ writer->empty = false;
return SERD_SUCCESS;
}
static SerdStatus
free_context(SerdWriter* writer)
{
- serd_node_free(&writer->context.graph);
- serd_node_free(&writer->context.subject);
- serd_node_free(&writer->context.predicate);
- return reset_context(writer, true);
+ serd_node_free(writer->context.graph);
+ serd_node_free(writer->context.subject);
+ serd_node_free(writer->context.predicate);
+ return SERD_SUCCESS;
}
static bool
@@ -475,8 +480,8 @@ write_uri_node(SerdWriter* const writer,
const Field field,
const SerdStatementFlags flags)
{
- SerdNode prefix;
- SerdSlice suffix;
+ const SerdNode* prefix;
+ SerdSlice suffix;
if (is_inline_start(writer, field, flags)) {
++writer->indent;
@@ -493,7 +498,7 @@ write_uri_node(SerdWriter* const writer,
return sink("()", 2, writer) == 2;
} else if (has_scheme && (writer->style & SERD_STYLE_CURIED) &&
serd_env_qualify(writer->env, node, &prefix, &suffix)) {
- write_uri_from_node(writer, &prefix);
+ write_uri_from_node(writer, prefix);
sink(":", 1, writer);
write_uri(writer, suffix.buf, suffix.len);
return true;
@@ -578,7 +583,7 @@ write_blank(SerdWriter* const writer,
return write_sep(writer, SEP_ANON_BEGIN);
} else if (field == FIELD_SUBJECT && (flags & SERD_LIST_S_BEGIN)) {
assert(writer->list_depth == 0);
- copy_node(&writer->list_subj, node);
+ serd_node_set(&writer->list_subj, node);
++writer->list_depth;
++writer->indent;
return write_sep(writer, SEP_LIST_BEGIN);
@@ -644,7 +649,7 @@ write_pred(SerdWriter* writer, SerdStatementFlags flags, const SerdNode* pred)
{
write_node(writer, pred, NULL, NULL, FIELD_PREDICATE, flags);
write_sep(writer, SEP_P_O);
- copy_node(&writer->context.predicate, pred);
+ serd_node_set(&writer->context.predicate, pred);
}
static bool
@@ -677,9 +682,8 @@ serd_writer_write_statement(SerdWriter* writer,
const SerdNode* datatype,
const SerdNode* lang)
{
- if (!subject || !predicate || !object
- || !subject->buf || !predicate->buf || !object->buf
- || !is_resource(subject) || !is_resource(predicate)) {
+ if (!subject || !predicate || !object ||
+ !is_resource(subject) || !is_resource(predicate)) {
return SERD_ERR_BAD_ARG;
}
@@ -706,13 +710,13 @@ serd_writer_write_statement(SerdWriter* writer,
break;
}
- if ((graph && !serd_node_equals(graph, &writer->context.graph)) ||
- (!graph && writer->context.graph.type)) {
+ if ((graph && !serd_node_equals(graph, writer->context.graph)) ||
+ (!graph && ctx(writer, FIELD_GRAPH))) {
writer->indent = 0;
- if (writer->context.subject.type) {
+ if (ctx(writer, FIELD_SUBJECT)) {
write_sep(writer, SEP_END_S);
}
- if (writer->context.graph.type) {
+ if (ctx(writer, FIELD_GRAPH)) {
write_sep(writer, SEP_GRAPH_END);
}
@@ -721,23 +725,23 @@ serd_writer_write_statement(SerdWriter* writer,
TRY(write_node(writer, graph, datatype, lang, FIELD_GRAPH, flags));
++writer->indent;
write_sep(writer, SEP_GRAPH_BEGIN);
- copy_node(&writer->context.graph, graph);
+ serd_node_set(&writer->context.graph, graph);
}
}
if ((flags & SERD_LIST_CONT)) {
if (write_list_obj(writer, flags, predicate, object, datatype, lang)) {
// Reached end of list
- if (--writer->list_depth == 0 && writer->list_subj.type) {
+ if (--writer->list_depth == 0 && writer->list_subj) {
reset_context(writer, false);
- serd_node_free(&writer->context.subject);
+ serd_node_free(writer->context.subject);
writer->context.subject = writer->list_subj;
- writer->list_subj = SERD_NODE_NULL;
+ writer->list_subj = NULL;
}
return SERD_SUCCESS;
}
- } else if (serd_node_equals(subject, &writer->context.subject)) {
- if (serd_node_equals(predicate, &writer->context.predicate)) {
+ } else if (serd_node_equals(subject, writer->context.subject)) {
+ if (serd_node_equals(predicate, writer->context.predicate)) {
// Abbreviate S P
if (!(flags & SERD_ANON_O_BEGIN)) {
++writer->indent;
@@ -749,14 +753,14 @@ serd_writer_write_statement(SerdWriter* writer,
}
} else {
// Abbreviate S
- Sep sep = writer->context.predicate.type ? SEP_END_P : SEP_S_P;
+ Sep sep = ctx(writer, FIELD_PREDICATE) ? SEP_END_P : SEP_S_P;
write_sep(writer, sep);
write_pred(writer, flags, predicate);
write_node(writer, object, datatype, lang, FIELD_OBJECT, flags);
}
} else {
// No abbreviation
- if (writer->context.subject.type) {
+ if (ctx(writer, FIELD_SUBJECT)) {
assert(writer->indent > 0);
--writer->indent;
if (serd_stack_is_empty(&writer->anon_stack)) {
@@ -775,7 +779,7 @@ serd_writer_write_statement(SerdWriter* writer,
}
reset_context(writer, false);
- copy_node(&writer->context.subject, subject);
+ serd_node_set(&writer->context.subject, subject);
if (!(flags & SERD_LIST_S_BEGIN)) {
write_pred(writer, flags, predicate);
@@ -789,15 +793,15 @@ serd_writer_write_statement(SerdWriter* writer,
&writer->anon_stack, sizeof(WriteContext));
*ctx = writer->context;
WriteContext new_context = {
- serd_node_copy(graph), serd_node_copy(subject), SERD_NODE_NULL };
+ serd_node_copy(graph), serd_node_copy(subject), NULL };
if ((flags & SERD_ANON_S_BEGIN)) {
new_context.predicate = serd_node_copy(predicate);
}
writer->context = new_context;
} else {
- copy_node(&writer->context.graph, graph);
- copy_node(&writer->context.subject, subject);
- copy_node(&writer->context.predicate, predicate);
+ serd_node_set(&writer->context.graph, graph);
+ serd_node_set(&writer->context.subject, subject);
+ serd_node_set(&writer->context.predicate, predicate);
}
return SERD_SUCCESS;
@@ -821,10 +825,10 @@ serd_writer_end_anon(SerdWriter* writer,
free_context(writer);
writer->context = *anon_stack_top(writer);
serd_stack_pop(&writer->anon_stack, sizeof(WriteContext));
- const bool is_subject = serd_node_equals(node, &writer->context.subject);
+ const bool is_subject = serd_node_equals(node, writer->context.subject);
if (is_subject) {
- copy_node(&writer->context.subject, node);
- writer->context.predicate.type = SERD_NOTHING;
+ serd_node_set(&writer->context.subject, node);
+ writer->context.predicate->type = SERD_NOTHING;
}
return SERD_SUCCESS;
}
@@ -833,15 +837,17 @@ SERD_API
SerdStatus
serd_writer_finish(SerdWriter* writer)
{
- if (writer->context.subject.type) {
+ if (ctx(writer, FIELD_SUBJECT)) {
write_sep(writer, SEP_END_S);
}
- if (writer->context.graph.type) {
+ if (ctx(writer, FIELD_GRAPH)) {
write_sep(writer, SEP_GRAPH_END);
}
serd_byte_sink_flush(&writer->byte_sink);
- writer->indent = 0;
- return free_context(writer);
+ free_context(writer);
+ writer->indent = 0;
+ writer->context = WRITE_CONTEXT_NULL;
+ return SERD_SUCCESS;
}
SERD_API
@@ -858,12 +864,12 @@ serd_writer_new(SerdSyntax syntax,
writer->syntax = syntax;
writer->style = style;
writer->env = env;
- writer->root_node = SERD_NODE_NULL;
+ 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 = SERD_NODE_NULL;
+ writer->list_subj = NULL;
writer->empty = true;
writer->byte_sink = serd_byte_sink_new(
ssink, stream, (style & SERD_STYLE_BULK) ? SERD_PAGE_SIZE : 1);
@@ -904,7 +910,7 @@ serd_writer_set_base_uri(SerdWriter* writer,
serd_env_get_base_uri(writer->env, &writer->base_uri);
if (writer->syntax == SERD_TURTLE || writer->syntax == SERD_TRIG) {
- if (writer->context.graph.type || writer->context.subject.type) {
+ if (ctx(writer, FIELD_GRAPH) || ctx(writer, FIELD_SUBJECT)) {
sink(" .\n\n", 4, writer);
reset_context(writer, true);
}
@@ -923,12 +929,13 @@ SerdStatus
serd_writer_set_root_uri(SerdWriter* writer,
const SerdNode* uri)
{
- serd_node_free(&writer->root_node);
- if (uri && uri->buf) {
+ serd_node_free(writer->root_node);
+ if (uri) {
writer->root_node = serd_node_copy(uri);
- serd_uri_parse(serd_node_get_string(uri), &writer->root_uri);
+ serd_uri_parse(serd_node_get_string(writer->root_node),
+ &writer->root_uri);
} else {
- writer->root_node = SERD_NODE_NULL;
+ writer->root_node = NULL;
writer->root_uri = SERD_URI_NULL;
}
return SERD_SUCCESS;
@@ -942,7 +949,7 @@ serd_writer_set_prefix(SerdWriter* writer,
{
if (!serd_env_set_prefix(writer->env, name, uri)) {
if (writer->syntax == SERD_TURTLE || writer->syntax == SERD_TRIG) {
- if (writer->context.graph.type || writer->context.subject.type) {
+ if (ctx(writer, FIELD_GRAPH) || ctx(writer, FIELD_SUBJECT)) {
sink(" .\n\n", 4, writer);
reset_context(writer, true);
}
@@ -966,7 +973,7 @@ serd_writer_free(SerdWriter* writer)
serd_stack_free(&writer->anon_stack);
free(writer->bprefix);
serd_byte_sink_free(&writer->byte_sink);
- serd_node_free(&writer->root_node);
+ serd_node_free(writer->root_node);
free(writer);
}
diff --git a/tests/serd_test.c b/tests/serd_test.c
index dfa3d397..cf039e1c 100644
--- a/tests/serd_test.c
+++ b/tests/serd_test.c
@@ -92,24 +92,25 @@ check_file_uri(const char* hostname,
expected_path = path;
}
- SerdNode node = serd_node_new_file_uri(path, hostname, 0, escape);
- char* out_hostname = NULL;
- char* out_path = serd_file_uri_parse(node.buf, &out_hostname);
- int ret = 0;
- if (strcmp((const char*)node.buf, expected_uri)) {
- ret = FAILF("Bad URI %s != %s\n", node.buf, expected_uri);
+ SerdNode* node = serd_node_new_file_uri(path, hostname, 0, escape);
+ const char* node_str = serd_node_get_string(node);
+ char* out_hostname = NULL;
+ char* out_path = serd_file_uri_parse(node_str, &out_hostname);
+ int ret = 0;
+ if (strcmp(node_str, expected_uri)) {
+ ret = FAILF("Bad URI %s != %s\n", node_str, expected_uri);
} else if (!hostname && out_hostname) {
ret = FAILF("hostname `%s' shouldn't exist\n", out_hostname);
} else if (hostname && !out_hostname) {
ret = FAILF("expected hostname `%s'\n", hostname);
} else if (strcmp((const char*)out_path, (const char*)expected_path)) {
ret = FAILF("path=>URI=>path failure %s => %s => %s\n",
- path, node.buf, out_path);
+ path, node_str, out_path);
}
free(out_path);
free(out_hostname);
- serd_node_free(&node);
+ serd_node_free(node);
return ret;
}
@@ -155,20 +156,19 @@ main(void)
};
for (unsigned i = 0; i < sizeof(dbl_test_nums) / sizeof(double); ++i) {
- SerdNode node = serd_node_new_decimal(dbl_test_nums[i], 8);
- const bool pass = (node.buf && dbl_test_strs[i])
- ? !strcmp(node.buf, dbl_test_strs[i])
- : (node.buf == dbl_test_strs[i]);
+ SerdNode* node = serd_node_new_decimal(dbl_test_nums[i], 8);
+ const char* node_str = serd_node_get_string(node);
+ const bool pass = (node_str && dbl_test_strs[i])
+ ? !strcmp(node_str, dbl_test_strs[i])
+ : (node_str == dbl_test_strs[i]);
if (!pass) {
- FAILF("Serialised `%s' != %s\n",
- node.buf, dbl_test_strs[i]);
+ FAILF("Serialised `%s' != %s\n", node_str, dbl_test_strs[i]);
}
- const size_t len = node.buf ? strlen(node.buf) : 0;
- if (node.n_bytes != len) {
- FAILF("Length %zu != %zu\n",
- node.n_bytes, len);
+ const size_t len = node_str ? strlen(node_str) : 0;
+ if (serd_node_get_length(node) != len) {
+ FAILF("Length %zu != %zu\n", serd_node_get_length(node), len);
}
- serd_node_free(&node);
+ serd_node_free(node);
}
// Test serd_node_new_integer
@@ -182,17 +182,16 @@ main(void)
};
for (unsigned i = 0; i < sizeof(int_test_nums) / sizeof(double); ++i) {
- SerdNode node = serd_node_new_integer(int_test_nums[i]);
- if (strcmp((const char*)node.buf, (const char*)int_test_strs[i])) {
- FAILF("Serialised `%s' != %s\n",
- node.buf, int_test_strs[i]);
+ SerdNode* node = serd_node_new_integer(int_test_nums[i]);
+ const char* node_str = serd_node_get_string(node);
+ if (strcmp(node_str, (const char*)int_test_strs[i])) {
+ FAILF("Serialised `%s' != %s\n", node_str, int_test_strs[i]);
}
- const size_t len = strlen(node.buf);
- if (node.n_bytes != len) {
- FAILF("Length %zu,%zu != %zu\n",
- node.n_bytes, len);
+ const size_t len = strlen(node_str);
+ if (serd_node_get_length(node) != len) {
+ FAILF("Length %zu,%zu != %zu\n", serd_node_get_length(node), len);
}
- serd_node_free(&node);
+ serd_node_free(node);
}
// Test serd_node_new_blob
@@ -202,10 +201,11 @@ main(void)
data[i] = (uint8_t)(rand() % 256);
}
- SerdNode blob = serd_node_new_blob(data, size, size % 5);
- size_t out_size;
- uint8_t* out = (uint8_t*)serd_base64_decode(
- blob.buf, blob.n_bytes, &out_size);
+ size_t out_size;
+ SerdNode* blob = serd_node_new_blob(data, size, size % 5);
+ const char* blob_str = serd_node_get_string(blob);
+ uint8_t* out = (uint8_t*)serd_base64_decode(
+ blob_str, serd_node_get_length(blob), &out_size);
if (out_size != size) {
FAILF("Blob size %zu != %zu\n", out_size, size);
}
@@ -216,7 +216,7 @@ main(void)
}
}
- serd_node_free(&blob);
+ serd_node_free(blob);
free(out);
free(data);
}
@@ -310,148 +310,167 @@ main(void)
// Test serd_node_equals
const uint8_t replacement_char_str[] = { 0xEF, 0xBF, 0xBD, 0 };
- SerdNode lhs = serd_node_from_string(SERD_LITERAL, (const char*)replacement_char_str);
- SerdNode rhs = serd_node_from_string(SERD_LITERAL, "123");
- if (serd_node_equals(&lhs, &rhs)) {
- FAILF("%s == %s\n", lhs.buf, rhs.buf);
+ SerdNode* lhs = serd_node_new_string(SERD_LITERAL, (const char*)replacement_char_str);
+ SerdNode* rhs = serd_node_new_string(SERD_LITERAL, "123");
+ if (serd_node_equals(lhs, rhs)) {
+ FAILF("%s == %s\n",
+ serd_node_get_string(lhs), serd_node_get_string(rhs));
}
- SerdNode qnode = serd_node_from_string(SERD_CURIE, "foo:bar");
- if (serd_node_equals(&lhs, &qnode)) {
- FAILF("%s == %s\n", lhs.buf, qnode.buf);
+ SerdNode* qnode = serd_node_new_string(SERD_CURIE, "foo:bar");
+ if (serd_node_equals(lhs, qnode)) {
+ FAILF("%s == %s\n",
+ serd_node_get_string(lhs), serd_node_get_string(qnode));
}
+ serd_node_free(qnode);
- if (!serd_node_equals(&lhs, &lhs)) {
- FAILF("%s != %s\n", lhs.buf, lhs.buf);
+ if (!serd_node_equals(lhs, lhs)) {
+ FAILF("%s != %s\n",
+ serd_node_get_string(lhs), serd_node_get_string(lhs));
}
- SerdNode null_copy = serd_node_copy(&SERD_NODE_NULL);
- if (!serd_node_equals(&SERD_NODE_NULL, &null_copy)) {
- FAIL("copy of null node != null node\n");
+ if (serd_node_copy(NULL)) {
+ FAIL("made non-null copy of null node\n");
}
- // Test serd_node_from_string
+ serd_node_free(lhs);
+ serd_node_free(rhs);
- SerdNode node = serd_node_from_string(SERD_LITERAL, "hello\"");
- if (node.n_bytes != 6 || node.flags != SERD_HAS_QUOTE
- || strcmp((const char*)node.buf, "hello\"")) {
- FAILF("Bad node %s %zu %d %d\n",
- node.buf, node.n_bytes, node.flags, node.type);
+ // Test serd_node_new_string
+
+ SerdNode* hello = serd_node_new_string(SERD_LITERAL, "hello\"");
+ if (serd_node_get_length(hello) != 6 ||
+ serd_node_get_flags(hello) != SERD_HAS_QUOTE ||
+ strcmp(serd_node_get_string(hello), "hello\"")) {
+ FAILF("Bad node %s\n", serd_node_get_string(hello));
}
- node = serd_node_from_string(SERD_URI, NULL);
- if (!serd_node_equals(&node, &SERD_NODE_NULL)) {
- FAIL("Creating node from NULL string failed\n");
+ if (serd_node_new_string(SERD_URI, NULL)) {
+ FAIL("Successfully created node from NULL string\n");
}
- // Test serd_node_from_substring
+ // Test serd_node_new_substring
- SerdNode empty = serd_node_from_substring(SERD_LITERAL, NULL, 32);
- if (empty.buf || empty.n_bytes || empty.flags || empty.type) {
+ if (serd_node_new_substring(SERD_LITERAL, NULL, 32)) {
FAIL("Successfully created node from NULL substring\n");
}
- SerdNode a_b = serd_node_from_substring(SERD_LITERAL, "a\"bc", 3);
- if (a_b.n_bytes != 3 || a_b.flags != SERD_HAS_QUOTE
- || strncmp((const char*)a_b.buf, "a\"b", 3)) {
- FAILF("Bad node %s %zu %d %d\n",
- a_b.buf, a_b.n_bytes, a_b.flags, a_b.type);
+ SerdNode* a_b = serd_node_new_substring(SERD_LITERAL, "a\"bc", 3);
+ if (serd_node_get_length(a_b) != 3 ||
+ serd_node_get_flags(a_b) != SERD_HAS_QUOTE ||
+ strncmp(serd_node_get_string(a_b), "a\"b", 3)) {
+ FAILF("Bad node %s\n", serd_node_get_string(a_b));
}
- a_b = serd_node_from_substring(SERD_LITERAL, "a\"bc", 10);
- if (a_b.n_bytes != 4 || a_b.flags != SERD_HAS_QUOTE
- || strncmp((const char*)a_b.buf, "a\"bc", 4)) {
- FAILF("Bad node %s %zu %zu %d %d\n",
- a_b.buf, a_b.n_bytes, a_b.flags, a_b.type);
+ serd_node_free(a_b);
+ a_b = serd_node_new_substring(SERD_LITERAL, "a\"bc", 10);
+ if (serd_node_get_length(a_b) != 4 ||
+ serd_node_get_flags(a_b) != SERD_HAS_QUOTE ||
+ strncmp(serd_node_get_string(a_b), "a\"bc", 4)) {
+ FAILF("Bad node %s\n", serd_node_get_string(a_b));
}
+ serd_node_free(a_b);
// Test serd_node_new_uri_from_string
- SerdNode nonsense = serd_node_new_uri_from_string(NULL, NULL, NULL);
- if (nonsense.type != SERD_NOTHING) {
+ if (serd_node_new_uri_from_string(NULL, NULL, NULL)) {
FAIL("Successfully created NULL URI\n");
}
SerdURI base_uri;
- SerdNode base = serd_node_new_uri_from_string("http://example.org/",
+ SerdNode* base = serd_node_new_uri_from_string("http://example.org/",
NULL, &base_uri);
- SerdNode nil = serd_node_new_uri_from_string(NULL, &base_uri, NULL);
- SerdNode nil2 = serd_node_new_uri_from_string("", &base_uri, NULL);
- if (nil.type != SERD_URI || strcmp((const char*)nil.buf, (const char*)base.buf) ||
- nil2.type != SERD_URI || strcmp((const char*)nil2.buf, (const char*)base.buf)) {
- FAILF("URI %s != base %s\n", nil.buf, base.buf);
+ SerdNode* nil = serd_node_new_uri_from_string(NULL, &base_uri, NULL);
+ SerdNode* nil2 = serd_node_new_uri_from_string("", &base_uri, NULL);
+ if (serd_node_get_type(nil) != SERD_URI ||
+ strcmp(serd_node_get_string(nil), serd_node_get_string(base)) ||
+ serd_node_get_type(nil2) != SERD_URI ||
+ strcmp(serd_node_get_string(nil2), serd_node_get_string(base))) {
+ FAILF("URI %s != base %s\n",
+ serd_node_get_string(nil),
+ serd_node_get_string(base));
}
- serd_node_free(&nil);
- serd_node_free(&nil2);
// Test serd_node_new_relative_uri
- SerdNode abs = serd_node_from_string(SERD_URI, "http://example.org/foo/bar");
- SerdURI abs_uri;
- serd_uri_parse(abs.buf, &abs_uri);
+ SerdNode* abs = serd_node_new_string(SERD_URI, "http://example.org/foo/bar");
+ SerdURI abs_uri;
+ serd_uri_parse(serd_node_get_string(abs), &abs_uri);
- SerdURI rel_uri;
- SerdNode rel = serd_node_new_relative_uri(&abs_uri, &base_uri, NULL, &rel_uri);
- if (strcmp((const char*)rel.buf, "/foo/bar")) {
- FAILF("Bad relative URI %s (expected '/foo/bar')\n", rel.buf);
+ SerdURI rel_uri;
+ SerdNode* rel = serd_node_new_relative_uri(&abs_uri, &base_uri, NULL, &rel_uri);
+ if (strcmp(serd_node_get_string(rel), "/foo/bar")) {
+ FAILF("Bad relative URI %s (expected '/foo/bar')\n",
+ serd_node_get_string(rel));
}
- serd_node_free(&rel);
- serd_node_free(&base);
+ serd_node_free(abs);
+ serd_node_free(nil);
+ serd_node_free(nil2);
+ serd_node_free(rel);
+ serd_node_free(base);
// Test SerdEnv
- SerdNode u = serd_node_from_string(SERD_URI, "http://example.org/foo");
- SerdNode b = serd_node_from_string(SERD_CURIE, "invalid");
- SerdNode c = serd_node_from_string(SERD_CURIE, "eg.2:b");
- SerdEnv* env = serd_env_new(NULL);
+ SerdNode* u = serd_node_new_string(SERD_URI, "http://example.org/foo");
+ SerdNode* b = serd_node_new_string(SERD_CURIE, "invalid");
+ SerdNode* c = serd_node_new_string(SERD_CURIE, "eg.2:b");
+ SerdEnv* env = serd_env_new(NULL);
serd_env_set_prefix_from_strings(env, "eg.2", "http://example.org/");
+ if (serd_env_get_base_uri(env, NULL)) {
+ FAIL("Unexpected initial base URI\n");
+ }
+
if (!serd_env_set_base_uri(env, NULL)) {
FAIL("Successfully set NULL base URI\n");
}
- if (!serd_env_set_base_uri(env, &node)) {
- FAILF("Set base URI to %s\n", node.buf);
+ if (!serd_env_set_base_uri(env, hello)) {
+ FAILF("Set base URI to %s\n", serd_node_get_string(hello));
}
- if (!serd_node_equals(serd_env_get_base_uri(env, NULL), &node)) {
- FAIL("Base URI mismatch\n");
+ if (serd_env_get_base_uri(env, NULL)) {
+ FAIL("Unexpected base URI\n");
}
SerdSlice prefix, suffix;
- if (!serd_env_expand(env, &b, &prefix, &suffix)) {
- FAILF("Expanded invalid curie %s\n", b.buf);
+ if (!serd_env_expand(env, b, &prefix, &suffix)) {
+ FAILF("Expanded invalid curie %s\n", serd_node_get_string(b));
}
- SerdNode xnode = serd_env_expand_node(env, &node);
- if (!serd_node_equals(&xnode, &SERD_NODE_NULL)) {
- FAILF("Expanded %s to %s\n", c.buf, xnode.buf);
+ SerdNode* xnode = serd_env_expand_node(env, hello);
+ if (xnode) {
+ FAILF("Expanded %s\n", serd_node_get_string(c));
}
+ serd_node_free(hello);
- SerdNode xu = serd_env_expand_node(env, &u);
- if (strcmp((const char*)xu.buf, "http://example.org/foo")) {
- FAILF("Expanded %s to %s\n", c.buf, xu.buf);
+ SerdNode* xu = serd_env_expand_node(env, u);
+ if (strcmp(serd_node_get_string(xu), "http://example.org/foo")) {
+ FAILF("Expanded %s to %s\n",
+ serd_node_get_string(c), serd_node_get_string(xu));
}
- serd_node_free(&xu);
+ serd_node_free(xu);
- SerdNode badpre = serd_node_from_string(SERD_CURIE, "hm:what");
- SerdNode xbadpre = serd_env_expand_node(env, &badpre);
- if (!serd_node_equals(&xbadpre, &SERD_NODE_NULL)) {
- FAILF("Expanded invalid curie %s\n", badpre.buf);
+ SerdNode* badpre = serd_node_new_string(SERD_CURIE, "hm:what");
+ SerdNode* xbadpre = serd_env_expand_node(env, badpre);
+ if (xbadpre) {
+ FAILF("Expanded invalid curie %s\n", serd_node_get_string(badpre));
}
+ serd_node_free(badpre);
- SerdNode xc = serd_env_expand_node(env, &c);
- if (strcmp((const char*)xc.buf, "http://example.org/b")) {
- FAILF("Expanded %s to %s\n", c.buf, xc.buf);
+ SerdNode* xc = serd_env_expand_node(env, c);
+ if (strcmp(serd_node_get_string(xc), "http://example.org/b")) {
+ FAILF("Expanded %s to %s\n",
+ serd_node_get_string(c), serd_node_get_string(xc));
}
- serd_node_free(&xc);
+ serd_node_free(xc);
- if (!serd_env_set_prefix(env, &SERD_NODE_NULL, &SERD_NODE_NULL)) {
+ if (!serd_env_set_prefix(env, NULL, NULL)) {
FAIL("Set NULL prefix\n");
}
- const SerdNode lit = serd_node_from_string(SERD_LITERAL, "hello");
- if (!serd_env_set_prefix(env, &b, &lit)) {
+ SerdNode* lit = serd_node_new_string(SERD_LITERAL, "hello");
+ if (!serd_env_set_prefix(env, b, lit)) {
FAIL("Set prefix to literal\n");
}
@@ -462,11 +481,15 @@ main(void)
FAILF("Bad prefix count %d\n", n_prefixes);
}
- SerdNode shorter_uri = serd_node_from_string(SERD_URI, "urn:foo");
- SerdNode prefix_name;
- if (serd_env_qualify(env, &shorter_uri, &prefix_name, &suffix)) {
- FAILF("Qualified %s\n", shorter_uri.buf);
+ SerdNode* shorter_uri = serd_node_new_string(SERD_URI, "urn:foo");
+ const SerdNode* prefix_name;
+ if (serd_env_qualify(env, shorter_uri, &prefix_name, &suffix)) {
+ FAILF("Qualified %s\n", serd_node_get_string(shorter_uri));
}
+ serd_node_free(shorter_uri);
+ serd_node_free(u);
+ serd_node_free(b);
+ serd_node_free(c);
// Test SerdReader and SerdWriter
@@ -485,10 +508,11 @@ main(void)
serd_writer_chop_blank_prefix(writer, "tmp");
serd_writer_chop_blank_prefix(writer, NULL);
- if (!serd_writer_set_base_uri(writer, &lit)) {
- FAILF("Set base URI to %s\n", lit.buf);
- } else if (!serd_writer_set_prefix(writer, &lit, &lit)) {
- FAILF("Set prefix %s to %s\n", lit.buf, lit.buf);
+ if (!serd_writer_set_base_uri(writer, lit)) {
+ FAILF("Set base URI to %s\n", serd_node_get_string(lit));
+ } else if (!serd_writer_set_prefix(writer, lit, lit)) {
+ FAILF("Set prefix %s to %s\n",
+ serd_node_get_string(lit), serd_node_get_string(lit));
} else if (!serd_writer_end_anon(writer, NULL)) {
FAIL("Ended non-existent anonymous node\n");
} else if (serd_writer_get_env(writer) != env) {
@@ -496,20 +520,20 @@ main(void)
}
uint8_t buf[] = { 0xEF, 0xBF, 0xBD, 0 };
- SerdNode s = serd_node_from_string(SERD_URI, "");
- SerdNode p = serd_node_from_string(SERD_URI, "http://example.org/pred");
- SerdNode o = serd_node_from_string(SERD_LITERAL, (char*)buf);
+ SerdNode* s = serd_node_new_string(SERD_URI, "");
+ SerdNode* p = serd_node_new_string(SERD_URI, "http://example.org/pred");
+ SerdNode* o = serd_node_new_string(SERD_LITERAL, (char*)buf);
// Write 3 invalid statements (should write nothing)
- const SerdNode* junk[][5] = { { &s, &p, NULL, NULL, NULL },
- { &s, NULL, &o, NULL, NULL },
- { NULL, &p, &o, NULL, NULL },
- { &s, &p, &SERD_NODE_NULL, NULL, NULL },
- { &s, &SERD_NODE_NULL, &o, NULL, NULL },
- { &SERD_NODE_NULL, &p, &o, NULL, NULL },
- { &s, &o, &o, NULL, NULL },
- { &o, &p, &o, NULL, NULL },
- { &s, &p, &SERD_NODE_NULL, NULL, NULL },
+ const SerdNode* junk[][5] = { { s, p, NULL, NULL, NULL },
+ { s, NULL, o, NULL, NULL },
+ { NULL, p, o, NULL, NULL },
+ { s, p, NULL, NULL, NULL },
+ { s, NULL, o, NULL, NULL },
+ { NULL, p, o, NULL, NULL },
+ { s, o, o, NULL, NULL },
+ { o, p, o, NULL, NULL },
+ { s, p, NULL, NULL, NULL },
{ NULL, NULL, NULL, NULL, NULL } };
for (unsigned i = 0; i < sizeof(junk) / (sizeof(SerdNode*) * 5); ++i) {
if (!serd_writer_write_statement(
@@ -519,18 +543,18 @@ main(void)
}
}
- const SerdNode t = serd_node_from_string(SERD_URI, "urn:Type");
- const SerdNode l = serd_node_from_string(SERD_LITERAL, "en");
- const SerdNode* good[][5] = { { &s, &p, &o, NULL, NULL },
- { &s, &p, &o, &SERD_NODE_NULL, &SERD_NODE_NULL },
- { &s, &p, &o, &t, NULL },
- { &s, &p, &o, NULL, &l },
- { &s, &p, &o, &t, &l },
- { &s, &p, &o, &t, &SERD_NODE_NULL },
- { &s, &p, &o, &SERD_NODE_NULL, &l },
- { &s, &p, &o, NULL, &SERD_NODE_NULL },
- { &s, &p, &o, &SERD_NODE_NULL, NULL },
- { &s, &p, &o, &SERD_NODE_NULL, NULL } };
+ SerdNode* t = serd_node_new_string(SERD_URI, "urn:Type");
+ SerdNode* l = serd_node_new_string(SERD_LITERAL, "en");
+ const SerdNode* good[][5] = { { s, p, o, NULL, NULL },
+ { s, p, o, NULL, NULL },
+ { s, p, o, t, NULL },
+ { s, p, o, NULL, l },
+ { s, p, o, t, l },
+ { s, p, o, t, NULL },
+ { s, p, o, NULL, l },
+ { s, p, o, NULL, NULL },
+ { s, p, o, NULL, NULL },
+ { s, p, o, NULL, NULL } };
for (unsigned i = 0; i < sizeof(good) / (sizeof(SerdNode*) * 5); ++i) {
if (serd_writer_write_statement(
writer, 0, NULL,
@@ -541,35 +565,45 @@ main(void)
// Write statements with bad UTF-8 (should be replaced)
const char bad_str[] = { (char)0xFF, (char)0x90, 'h', 'i', 0 };
- SerdNode bad_lit = serd_node_from_string(SERD_LITERAL, bad_str);
- SerdNode bad_uri = serd_node_from_string(SERD_URI, bad_str);
+ SerdNode* bad_lit = serd_node_new_string(SERD_LITERAL, bad_str);
+ SerdNode* bad_uri = serd_node_new_string(SERD_URI, bad_str);
if (serd_writer_write_statement(writer, 0, NULL,
- &s, &p, &bad_lit, NULL, NULL)) {
+ s, p, bad_lit, NULL, NULL)) {
FAIL("Failed to write junk UTF-8 literal\n");
} else if (serd_writer_write_statement(writer, 0, NULL,
- &s, &p, &bad_uri, NULL, NULL)) {
+ s, p, bad_uri, NULL, NULL)) {
FAIL("Failed to write junk UTF-8 URI\n");
}
+ serd_node_free(bad_uri);
+ serd_node_free(bad_lit);
// Write 1 valid statement
- o = serd_node_from_string(SERD_LITERAL, "hello");
+ serd_node_free(o);
+ o = serd_node_new_string(SERD_LITERAL, "hello");
if (serd_writer_write_statement(writer, 0, NULL,
- &s, &p, &o, NULL, NULL)) {
+ s, p, o, NULL, NULL)) {
FAIL("Failed to write valid statement\n");
}
serd_writer_free(writer);
+ serd_node_free(lit);
+ serd_node_free(s);
+ serd_node_free(p);
+ serd_node_free(o);
+ serd_node_free(t);
+ serd_node_free(l);
// Test buffer sink
SerdBuffer buffer = { NULL, 0 };
writer = serd_writer_new(
SERD_TURTLE, (SerdStyle)0, env, NULL, serd_buffer_sink, &buffer);
- o = serd_node_from_string(SERD_URI, "http://example.org/base");
- if (serd_writer_set_base_uri(writer, &o)) {
+ o = serd_node_new_string(SERD_URI, "http://example.org/base");
+ if (serd_writer_set_base_uri(writer, o)) {
FAIL("Failed to write to chunk sink\n");
}
+ serd_node_free(o);
serd_writer_free(writer);
char* out = serd_buffer_sink_finish(&buffer);
@@ -593,10 +627,11 @@ main(void)
FAIL("Corrupt reader handle\n");
}
- SerdNode g = serd_node_from_string(SERD_URI, "http://example.org/");
- serd_reader_set_default_graph(reader, &g);
+ SerdNode* g = serd_node_new_string(SERD_URI, "http://example.org/");
+ serd_reader_set_default_graph(reader, g);
serd_reader_add_blank_prefix(reader, "tmp");
serd_reader_add_blank_prefix(reader, NULL);
+ serd_node_free(g);
if (!serd_reader_read_file(reader, "http://notafile")) {
FAIL("Apparently read an http URI\n");
@@ -611,8 +646,8 @@ main(void)
FAILF("Error reading file (%s)\n", serd_strerror(st));
} else if (rt->n_statements != 13) {
FAILF("Bad statement count %d\n", rt->n_statements);
- } else if (!rt->graph || !rt->graph->buf ||
- strcmp((const char*)rt->graph->buf, "http://example.org/")) {
+ } else if (!rt->graph || !serd_node_get_string(rt->graph) ||
+ strcmp(serd_node_get_string(rt->graph), "http://example.org/")) {
FAILF("Bad graph %p\n", rt->graph);
}