From d37123707c7cde6368d6d368995628ad4809913c Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 4 Feb 2018 15:33:36 +0100 Subject: Use opaque node API --- src/env.c | 28 ++++++++++++---------- src/n3.c | 28 ++++++++++++---------- src/node.c | 15 ++++++++---- src/serd_internal.h | 2 ++ src/writer.c | 68 ++++++++++++++++++++++++++++++----------------------- 5 files changed, 83 insertions(+), 58 deletions(-) (limited to 'src') diff --git a/src/env.c b/src/env.c index 95e255cb..f1bfd2d7 100644 --- a/src/env.c +++ b/src/env.c @@ -98,7 +98,7 @@ serd_env_find(const SerdEnv* env, for (size_t i = 0; i < env->n_prefixes; ++i) { const SerdNode* const prefix_name = &env->prefixes[i].name; if (prefix_name->n_bytes == name_len) { - if (!memcmp(prefix_name->buf, name, name_len)) { + if (!memcmp(serd_node_get_string(prefix_name), name, name_len)) { return &env->prefixes[i]; } } @@ -111,7 +111,8 @@ serd_env_add(SerdEnv* env, const SerdNode* name, const SerdNode* uri) { - SerdPrefix* const prefix = serd_env_find(env, name->buf, name->n_bytes); + 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; prefix->uri = serd_node_copy(uri); @@ -132,7 +133,7 @@ serd_env_set_prefix(SerdEnv* env, { if (!name->buf || uri->type != SERD_URI) { return SERD_ERR_BAD_ARG; - } else if (serd_uri_string_has_scheme(uri->buf)) { + } else if (serd_uri_string_has_scheme(serd_node_get_string(uri))) { // Set prefix to absolute URI serd_env_add(env, name, uri); } else { @@ -191,11 +192,12 @@ serd_env_qualify(const SerdEnv* env, for (size_t i = 0; i < env->n_prefixes; ++i) { const SerdNode* const prefix_uri = &env->prefixes[i].uri; if (uri->n_bytes >= prefix_uri->n_bytes) { - if (!strncmp((const char*)uri->buf, - (const char*)prefix_uri->buf, - prefix_uri->n_bytes)) { + const char* prefix_str = serd_node_get_string(prefix_uri); + const char* uri_str = serd_node_get_string(uri); + + if (!strncmp(uri_str, prefix_str, prefix_uri->n_bytes)) { *prefix = env->prefixes[i].name; - suffix->buf = uri->buf + prefix_uri->n_bytes; + suffix->buf = uri_str + prefix_uri->n_bytes; suffix->len = uri->n_bytes - prefix_uri->n_bytes; if (is_name(suffix->buf, suffix->len)) { return true; @@ -213,19 +215,19 @@ serd_env_expand(const SerdEnv* env, SerdSlice* uri_prefix, SerdSlice* uri_suffix) { - const char* const colon = (const char*)memchr( - curie->buf, ':', curie->n_bytes + 1); + const char* const str = serd_node_get_string(curie); + const char* const colon = (const char*)memchr(str, ':', curie->n_bytes + 1); if (curie->type != SERD_CURIE || !colon) { return SERD_ERR_BAD_ARG; } - const size_t name_len = colon - curie->buf; - const SerdPrefix* const prefix = serd_env_find(env, curie->buf, name_len); + const size_t name_len = colon - str; + const SerdPrefix* const prefix = serd_env_find(env, str, name_len); if (prefix) { - uri_prefix->buf = prefix->uri.buf; + 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 - curie->buf) - 1; + uri_suffix->len = curie->n_bytes - (colon - str) - 1; return SERD_SUCCESS; } return SERD_ERR_BAD_CURIE; diff --git a/src/n3.c b/src/n3.c index 51b06d91..9c7784e1 100644 --- a/src/n3.c +++ b/src/n3.c @@ -547,7 +547,8 @@ read_PN_PREFIX_tail(SerdReader* reader, Ref dest) } const SerdNode* const n = deref(reader, dest); - if (n->buf[n->n_bytes - 1] == '.' && read_PN_CHARS(reader, dest)) { + if (serd_node_get_string(n)[n->n_bytes - 1] == '.' && + read_PN_CHARS(reader, dest)) { r_err(reader, SERD_ERR_BAD_SYNTAX, "prefix ends with `.'\n"); return SERD_ERR_BAD_SYNTAX; } @@ -827,7 +828,8 @@ read_verb(SerdReader* reader, Ref* dest) const SerdStatus st = read_PN_PREFIX(reader, *dest); bool ate_dot = false; SerdNode* node = deref(reader, *dest); - if (!st && node->n_bytes == 1 && node->buf[0] == 'a' && + if (!st && node->n_bytes == 1 && + serd_node_get_string(node)[0] == 'a' && is_token_end(peek_byte(reader))) { pop_node(reader, *dest); return (*dest = push_node(reader, SERD_URI, NS_RDF "type", 47)); @@ -866,8 +868,9 @@ read_BLANK_NODE_LABEL(SerdReader* reader, bool* ate_dot) } } - SerdNode* n = deref(reader, ref); - if (n->buf[n->n_bytes - 1] == '.' && read_PN_CHARS(reader, ref)) { + SerdNode* n = deref(reader, ref); + char* buf = serd_node_buffer(n); + if (buf[n->n_bytes - 1] == '.' && read_PN_CHARS(reader, ref)) { // Ate trailing dot, pop it from stack/node and inform caller --n->n_bytes; serd_stack_pop(&reader->stack, 1); @@ -875,12 +878,11 @@ read_BLANK_NODE_LABEL(SerdReader* reader, bool* ate_dot) } if (reader->syntax == SERD_TURTLE) { - if (is_digit(n->buf[reader->bprefix_len + 1])) { - if ((n->buf[reader->bprefix_len]) == 'b') { - ((char*)n->buf)[reader->bprefix_len] = 'B'; // Prevent clash + if (is_digit(buf[reader->bprefix_len + 1])) { + if ((buf[reader->bprefix_len]) == 'b') { + buf[reader->bprefix_len] = 'B'; // Prevent clash reader->seen_genid = true; - } else if (reader->seen_genid && - n->buf[reader->bprefix_len] == 'B') { + } else if (reader->seen_genid && buf[reader->bprefix_len] == 'B') { r_err(reader, SERD_ERR_ID_CLASH, "found both `b' and `B' blank IDs, prefix required\n"); return pop_node(reader, ref); @@ -1010,8 +1012,10 @@ read_object(SerdReader* reader, ReadContext* ctx, bool emit, bool* ate_dot) o = push_node(reader, SERD_CURIE, "", 0); while (!read_PN_CHARS_BASE(reader, o)) {} node = deref(reader, o); - if ((node->n_bytes == 4 && !memcmp(node->buf, "true", 4)) || - (node->n_bytes == 5 && !memcmp(node->buf, "false", 5))) { + if ((node->n_bytes == 4 && + !memcmp(serd_node_get_string(node), "true", 4)) || + (node->n_bytes == 5 && + !memcmp(serd_node_get_string(node), "false", 5))) { node->type = SERD_LITERAL; datatype = push_node( reader, SERD_URI, XSD_BOOLEAN, XSD_BOOLEAN_LEN); @@ -1346,7 +1350,7 @@ tokcmp(SerdReader* reader, Ref ref, const char* tok, size_t n) if (!node || node->n_bytes != n) { return -1; } - return serd_strncasecmp((const char*)node->buf, tok, n); + return serd_strncasecmp(serd_node_get_string(node), tok, n); } bool diff --git a/src/node.c b/src/node.c index 3be90856..65a2172b 100644 --- a/src/node.c +++ b/src/node.c @@ -31,6 +31,12 @@ # endif #endif +char* +serd_node_buffer(SerdNode* node) +{ + return (char*)(node + 1); +} + SERD_API SerdNode serd_node_from_string(SerdType type, const char* str) @@ -118,8 +124,9 @@ serd_node_new_uri_from_node(const SerdNode* uri_node, const SerdURI* base, SerdURI* out) { - return (uri_node->type == SERD_URI && uri_node->buf) - ? serd_node_new_uri_from_string(uri_node->buf, base, out) + 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; } @@ -394,14 +401,14 @@ SERD_API const char* serd_node_get_string(const SerdNode* node) { - return node->buf; + return node ? node->buf : NULL; } SERD_API size_t serd_node_get_length(const SerdNode* node) { - return node->n_bytes; + return node ? node->n_bytes : 0; } SERD_API diff --git a/src/serd_internal.h b/src/serd_internal.h index c666dfa6..6c273b6c 100644 --- a/src/serd_internal.h +++ b/src/serd_internal.h @@ -44,6 +44,8 @@ static const uint8_t replacement_char[] = { 0xEF, 0xBF, 0xBD }; +char* serd_node_buffer(SerdNode* node); + /* File and Buffer Utilities */ static inline FILE* diff --git a/src/writer.c b/src/writer.c index dfbfc94a..d40e4024 100644 --- a/src/writer.c +++ b/src/writer.c @@ -236,6 +236,12 @@ write_uri(SerdWriter* writer, const char* utf8, size_t n_bytes) return len; } +static size_t +write_uri_from_node(SerdWriter* writer, const SerdNode* node) +{ + return write_uri(writer, serd_node_get_string(node), node->n_bytes); +} + static bool lname_must_escape(const char c) { @@ -422,22 +428,23 @@ write_literal(SerdWriter* writer, Field field, SerdStatementFlags flags) { - if (supports_abbrev(writer) && datatype && datatype->buf) { - const char* type_uri = (const char*)datatype->buf; + const char* node_str = serd_node_get_string(node); + const char* type_uri = serd_node_get_string(datatype); + if (supports_abbrev(writer) && type_uri) { if (!strncmp(type_uri, NS_XSD, sizeof(NS_XSD) - 1) && ( !strcmp(type_uri + sizeof(NS_XSD) - 1, "boolean") || !strcmp(type_uri + sizeof(NS_XSD) - 1, "integer"))) { - sink(node->buf, node->n_bytes, writer); + sink(node_str, node->n_bytes, writer); return true; } else if (!strncmp(type_uri, NS_XSD, sizeof(NS_XSD) - 1) && !strcmp(type_uri + sizeof(NS_XSD) - 1, "decimal") && - strchr((const char*)node->buf, '.') && - node->buf[node->n_bytes - 1] != '.') { + strchr(node_str, '.') && + node_str[node->n_bytes - 1] != '.') { /* xsd:decimal literals without trailing digits, e.g. "5.", can not be written bare in Turtle. We could add a 0 which is prettier, but changes the text and breaks round tripping. */ - sink(node->buf, node->n_bytes, writer); + sink(node_str, node->n_bytes, writer); return true; } } @@ -445,17 +452,17 @@ write_literal(SerdWriter* writer, if (supports_abbrev(writer) && (node->flags & (SERD_HAS_NEWLINE|SERD_HAS_QUOTE))) { sink("\"\"\"", 3, writer); - write_text(writer, WRITE_LONG_STRING, node->buf, node->n_bytes); + write_text(writer, WRITE_LONG_STRING, node_str, node->n_bytes); sink("\"\"\"", 3, writer); } else { sink("\"", 1, writer); - write_text(writer, WRITE_STRING, node->buf, node->n_bytes); + write_text(writer, WRITE_STRING, node_str, node->n_bytes); sink("\"", 1, writer); } - if (lang && lang->buf) { + if (lang && serd_node_get_string(lang)) { sink("@", 1, writer); - sink(lang->buf, lang->n_bytes, writer); - } else if (datatype && datatype->buf) { + sink(serd_node_get_string(lang), lang->n_bytes, writer); + } else if (type_uri) { sink("^^", 2, writer); return write_node(writer, datatype, NULL, NULL, FIELD_NONE, flags); } @@ -477,16 +484,16 @@ write_uri_node(SerdWriter* const writer, sink("== ", 3, writer); } - const bool has_scheme = serd_uri_string_has_scheme(node->buf); + const char* node_str = serd_node_get_string(node); + const bool has_scheme = serd_uri_string_has_scheme(node_str); if (field == FIELD_PREDICATE && supports_abbrev(writer) - && !strcmp((const char*)node->buf, NS_RDF "type")) { + && !strcmp(node_str, NS_RDF "type")) { return sink("a", 1, writer) == 1; - } else if (supports_abbrev(writer) - && !strcmp((const char*)node->buf, NS_RDF "nil")) { + } else if (supports_abbrev(writer) && !strcmp(node_str, NS_RDF "nil")) { return sink("()", 2, writer) == 2; } else if (has_scheme && (writer->style & SERD_STYLE_CURIED) && serd_env_qualify(writer->env, node, &prefix, &suffix)) { - write_uri(writer, prefix.buf, prefix.n_bytes); + write_uri_from_node(writer, &prefix); sink(":", 1, writer); write_uri(writer, suffix.buf, suffix.len); return true; @@ -496,7 +503,7 @@ write_uri_node(SerdWriter* const writer, if (writer->style & SERD_STYLE_RESOLVED) { SerdURI in_base_uri, uri, abs_uri; serd_env_get_base_uri(writer->env, &in_base_uri); - serd_uri_parse(node->buf, &uri); + serd_uri_parse(node_str, &uri); serd_uri_resolve(&uri, &in_base_uri, &abs_uri); bool rooted = uri_is_under(&writer->base_uri, &writer->root_uri); SerdURI* root = rooted ? &writer->root_uri : & writer->base_uri; @@ -509,7 +516,7 @@ write_uri_node(SerdWriter* const writer, &uri, &writer->base_uri, root, uri_sink, writer); } } else { - write_uri(writer, node->buf, node->n_bytes); + write_uri_from_node(writer, node); } write_sep(writer, SEP_URI_END); if (is_inline_start(writer, field, flags)) { @@ -525,6 +532,8 @@ write_curie(SerdWriter* const writer, const Field field, const SerdStatementFlags flags) { + const char* node_str = serd_node_get_string(node); + SerdSlice prefix; SerdSlice suffix; SerdStatus st; @@ -532,7 +541,7 @@ write_curie(SerdWriter* const writer, case SERD_NTRIPLES: case SERD_NQUADS: if ((st = serd_env_expand(writer->env, node, &prefix, &suffix))) { - w_err(writer, st, "undefined namespace prefix `%s'\n", node->buf); + w_err(writer, st, "undefined namespace prefix `%s'\n", node_str); return false; } write_sep(writer, SEP_URI_BEGIN); @@ -547,7 +556,7 @@ write_curie(SerdWriter* const writer, write_sep(writer, SEP_ANON_BEGIN); sink("== ", 3, writer); } - write_lname(writer, node->buf, node->n_bytes); + write_lname(writer, node_str, node->n_bytes); if (is_inline_start(writer, field, flags)) { sink(" ;", 2, writer); write_newline(writer); @@ -562,6 +571,7 @@ write_blank(SerdWriter* const writer, const Field field, const SerdStatementFlags flags) { + const char* node_str = serd_node_get_string(node); if (supports_abbrev(writer)) { if (is_inline_start(writer, field, flags)) { ++writer->indent; @@ -583,14 +593,14 @@ write_blank(SerdWriter* const writer, } sink("_:", 2, writer); - if (writer->bprefix && !strncmp((const char*)node->buf, + if (writer->bprefix && !strncmp(node_str, (const char*)writer->bprefix, writer->bprefix_len)) { - sink(node->buf + writer->bprefix_len, + sink(node_str + writer->bprefix_len, node->n_bytes - writer->bprefix_len, writer); } else { - sink(node->buf, node->n_bytes, writer); + sink(node_str, node->n_bytes, writer); } return true; @@ -645,11 +655,11 @@ write_list_obj(SerdWriter* writer, const SerdNode* datatype, const SerdNode* lang) { - if (!strcmp((const char*)object->buf, NS_RDF "nil")) { + if (!strcmp(serd_node_get_string(object), NS_RDF "nil")) { --writer->indent; write_sep(writer, SEP_LIST_END); return true; - } else if (!strcmp((const char*)predicate->buf, NS_RDF "first")) { + } else if (!strcmp(serd_node_get_string(predicate), NS_RDF "first")) { write_sep(writer, SEP_LIST_SEP); write_node(writer, object, datatype, lang, FIELD_OBJECT, flags); } @@ -899,7 +909,7 @@ serd_writer_set_base_uri(SerdWriter* writer, reset_context(writer, true); } sink("@base <", 7, writer); - sink(uri->buf, uri->n_bytes, writer); + sink(serd_node_get_string(uri), uri->n_bytes, writer); sink("> .\n", 4, writer); } writer->indent = 0; @@ -916,7 +926,7 @@ serd_writer_set_root_uri(SerdWriter* writer, serd_node_free(&writer->root_node); if (uri && uri->buf) { writer->root_node = serd_node_copy(uri); - serd_uri_parse(uri->buf, &writer->root_uri); + serd_uri_parse(serd_node_get_string(uri), &writer->root_uri); } else { writer->root_node = SERD_NODE_NULL; writer->root_uri = SERD_URI_NULL; @@ -937,9 +947,9 @@ serd_writer_set_prefix(SerdWriter* writer, reset_context(writer, true); } sink("@prefix ", 8, writer); - sink(name->buf, name->n_bytes, writer); + sink(serd_node_get_string(name), name->n_bytes, writer); sink(": <", 3, writer); - write_uri(writer, uri->buf, uri->n_bytes); + write_uri_from_node(writer, uri); sink("> .\n", 4, writer); } writer->indent = 0; -- cgit v1.2.1