diff options
author | David Robillard <d@drobilla.net> | 2011-12-11 08:26:29 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2011-12-11 08:26:29 +0000 |
commit | 7a650f12ff560dcb3a0cdbbf425992a424b043ce (patch) | |
tree | 38bbcf0e805403b26054ad2a2be8759d3eacebe4 /src | |
parent | b132ab7f84abae6fd337cc32f97df22ad5076ee5 (diff) | |
download | serd-7a650f12ff560dcb3a0cdbbf425992a424b043ce.tar.gz serd-7a650f12ff560dcb3a0cdbbf425992a424b043ce.tar.bz2 serd-7a650f12ff560dcb3a0cdbbf425992a424b043ce.zip |
Simply reader by using a stack of SerdNode rather than weird internal types.
git-svn-id: http://svn.drobilla.net/serd/trunk@237 490d8e77-9747-427b-9fa3-0b8f29cee8a0
Diffstat (limited to 'src')
-rw-r--r-- | src/reader.c | 454 |
1 files changed, 204 insertions, 250 deletions
diff --git a/src/reader.c b/src/reader.c index 4a148b96..e430a206 100644 --- a/src/reader.c +++ b/src/reader.c @@ -42,29 +42,18 @@ typedef struct { typedef uint32_t uchar; +/* Reference to a node in the stack (we can not use pointers since the + stack may be reallocated, invalidating any pointers to elements). +*/ typedef size_t Ref; typedef struct { - SerdType type; - Ref value; -} Node; - -typedef struct { - const Node* graph; - const Node* subject; - const Node* predicate; + Ref graph; + Ref subject; + Ref predicate; SerdStatementFlags* flags; } ReadContext; -/** Measured UTF-8 string. */ -typedef struct { - size_t n_bytes; ///< Size in bytes - size_t n_chars; ///< Length in characters - uint8_t buf[]; ///< Buffer -} SerdString; - -static const Node INTERNAL_NODE_NULL = { 0, 0 }; - struct SerdReaderImpl { void* handle; void (*free_handle)(void* ptr); @@ -72,10 +61,9 @@ struct SerdReaderImpl { SerdPrefixSink prefix_sink; SerdStatementSink statement_sink; SerdEndSink end_sink; - Node rdf_type; - Node rdf_first; - Node rdf_rest; - Node rdf_nil; + Ref rdf_first; + Ref rdf_rest; + Ref rdf_nil; FILE* fd; SerdStack stack; SerdSyntax syntax; @@ -86,8 +74,8 @@ struct SerdReaderImpl { unsigned next_id; int err; uint8_t* read_buf; - int32_t read_head; ///< Offset into read_buf - bool from_file; ///< True iff reading from @ref fd + int32_t read_head; ///< Offset into read_buf + bool from_file; ///< True iff reading from @ref fd bool eof; #ifdef SERD_STACK_CHECK Ref* alloc_stack; ///< Stack of push offsets @@ -124,13 +112,6 @@ warn(SerdReader* reader, const char* fmt, ...) return 0; } -static Node -make_node(SerdType type, Ref value) -{ - const Node ret = { type, value }; - return ret; -} - static inline bool page(SerdReader* reader) { @@ -207,41 +188,41 @@ eat_string(SerdReader* reader, const char* str, unsigned n) #ifdef SERD_STACK_CHECK static inline bool -stack_is_top_string(SerdReader* reader, Ref ref) +stack_is_top_node(SerdReader* reader, Ref ref) { return ref == reader->alloc_stack[reader->n_allocs - 1]; } #endif -// Make a new string from a non-UTF-8 C string (internal use only) static Ref -push_string(SerdReader* reader, const char* c_str, size_t n_bytes) +push_node(SerdReader* reader, SerdType type, const char* c_str, size_t n_bytes) { uint8_t* mem = serd_stack_push(&reader->stack, - sizeof(SerdString) + n_bytes + 1); - SerdString* const str = (SerdString*)mem; - str->n_bytes = n_bytes; - str->n_chars = n_bytes; - memcpy(str->buf, c_str, n_bytes + 1); + sizeof(SerdNode) + n_bytes + 1); + SerdNode* const node = (SerdNode*)mem; + node->n_bytes = n_bytes; + node->n_chars = n_bytes; + node->flags = 0; + node->type = type; + node->buf = NULL; + + uint8_t* buf = mem + sizeof(SerdNode); + memcpy(buf, c_str, n_bytes + 1); #ifdef SERD_STACK_CHECK reader->alloc_stack = realloc( reader->alloc_stack, sizeof(uint8_t*) * (++reader->n_allocs)); reader->alloc_stack[reader->n_allocs - 1] = (mem - reader->stack.buf); #endif - return (uint8_t*)str - reader->stack.buf; + return (uint8_t*)node - reader->stack.buf; } -static Node -push_uri(SerdReader* reader, const char* str, size_t len) -{ - return make_node(SERD_URI, push_string(reader, str, len)); -} - -static inline SerdString* +static inline SerdNode* deref(SerdReader* reader, const Ref ref) { if (ref) { - return (SerdString*)(reader->stack.buf + ref); + SerdNode* node = (SerdNode*)(reader->stack.buf + ref); + node->buf = (uint8_t*)node + sizeof(SerdNode); + return node; } return NULL; } @@ -250,106 +231,77 @@ static inline void push_byte(SerdReader* reader, Ref ref, const uint8_t c) { #ifdef SERD_STACK_CHECK - assert(stack_is_top_string(reader, ref)); + assert(stack_is_top_node(reader, ref)); #endif serd_stack_push(&reader->stack, 1); - SerdString* const str = deref(reader, ref); - ++str->n_bytes; + SerdNode* const node = deref(reader, ref); + ++node->n_bytes; if ((c & 0xC0) != 0x80) { // Does not start with `10', start of a new character - ++str->n_chars; + ++node->n_chars; } - assert(str->n_bytes >= str->n_chars); - str->buf[str->n_bytes - 1] = c; - str->buf[str->n_bytes] = '\0'; + assert(node->n_bytes >= node->n_chars); + uint8_t* const buf = (uint8_t*)node + sizeof(SerdNode); + buf[node->n_bytes - 1] = c; + buf[node->n_bytes] = '\0'; } static inline void append_string(SerdReader* reader, Ref ref, const uint8_t* suffix, size_t len) { #ifdef SERD_STACK_CHECK - assert(stack_is_top_string(reader, ref)); + assert(stack_is_top_node(reader, ref)); #endif serd_stack_push(&reader->stack, len); - SerdString* const str = deref(reader, ref); - assert(str->n_bytes >= str->n_chars); - memcpy(str->buf + str->n_bytes, suffix, len + 1); - str->n_bytes += len; - str->n_chars += len; + SerdNode* const node = deref(reader, ref); + assert(node->n_bytes >= node->n_chars); + uint8_t* const buf = (uint8_t*)node + sizeof(SerdNode); + memcpy(buf + node->n_bytes, suffix, len + 1); + node->n_bytes += len; + node->n_chars += len; } static void -pop_string(SerdReader* reader, Ref ref) +pop_node(SerdReader* reader, Ref ref) { - if (ref) { - if (ref == reader->rdf_nil.value - || ref == reader->rdf_first.value - || ref == reader->rdf_rest.value) { - return; - } - #ifdef SERD_STACK_CHECK - if (!stack_is_top_string(reader, ref)) { - fprintf(stderr, "Attempt to pop non-top string %s\n", + if (ref + && ref != reader->rdf_nil + && ref != reader->rdf_first + && ref != reader->rdf_rest) { +#ifdef SERD_STACK_CHECK + if (!stack_is_top_node(reader, ref)) { + fprintf(stderr, "Attempt to pop non-top node %s\n", deref(reader, ref)->buf); } - assert(stack_is_top_string(reader, ref)); + assert(stack_is_top_node(reader, ref)); --reader->n_allocs; - #endif - SerdString* str = deref(reader, ref); - serd_stack_pop(&reader->stack, sizeof(SerdString) + str->n_bytes + 1); - } -} - -static inline SerdNode -public_node_from_ref(SerdReader* reader, SerdType type, Ref ref) -{ - if (!ref) { - return SERD_NODE_NULL; - } - const SerdString* str = deref(reader, ref); - const SerdNode node = { str->buf, str->n_bytes, str->n_chars, 0, type }; - return node; -} - -static inline SerdNode -public_node(SerdReader* reader, const Node* private) -{ - if (private) { - return public_node_from_ref(reader, private->type, private->value); - } else { - return SERD_NODE_NULL; +#endif + SerdNode* const node = deref(reader, ref); + uint8_t* const top = reader->stack.buf + reader->stack.size; + serd_stack_pop(&reader->stack, top - (uint8_t*)node); } } static inline bool emit_statement(SerdReader* reader, SerdStatementFlags* flags, - const Node* g, const Node* s, const Node* p, const Node* o, - const Node* d, Ref l, uint32_t f) + Ref g, Ref s, Ref p, Ref o, + Ref d, Ref l) { assert(s && p && o); - assert(s->value && p->value && o->value); - const SerdNode graph = public_node(reader, g); - const SerdNode subject = public_node(reader, s); - const SerdNode predicate = public_node(reader, p); - SerdNode object = public_node(reader, o); - const SerdNode datatype = public_node(reader, d); - const SerdNode lang = public_node_from_ref(reader, SERD_LITERAL, l); - object.flags = f; bool ret = !reader->statement_sink - || !reader->statement_sink(reader->handle, - *flags, - &graph, - &subject, - &predicate, - &object, - &datatype, - &lang); + || !reader->statement_sink(reader->handle, *flags, + deref(reader, g), + deref(reader, s), + deref(reader, p), + deref(reader, o), + deref(reader, d), + deref(reader, l)); *flags = (*flags & SERD_ANON_CONT) ? SERD_ANON_CONT : 0; return ret; } static bool -read_collection(SerdReader* reader, ReadContext ctx, Node* dest); +read_collection(SerdReader* reader, ReadContext ctx, Ref* dest); static bool read_predicateObjectList(SerdReader* reader, ReadContext ctx, bool blank); @@ -703,13 +655,14 @@ static Ref read_longString(SerdReader* reader, SerdNodeFlags* flags) { eat_string(reader, "\"\"\"", 3); - Ref str = push_string(reader, "", 0); + Ref ref = push_node(reader, SERD_LITERAL, "", 0); + assert(stack_is_top_node(reader, ref)); SerdStatus st; - while (!(st = read_lcharacter(reader, str, flags))) {} + while (!(st = read_lcharacter(reader, ref, flags))) {} if (st < SERD_ERR_UNKNOWN) { - return str; + return ref; } - pop_string(reader, str); + pop_node(reader, ref); return 0; } @@ -718,14 +671,14 @@ static Ref read_string(SerdReader* reader, SerdNodeFlags* flags) { eat_byte(reader, '\"'); - Ref str = push_string(reader, "", 0); + Ref ref = push_node(reader, SERD_LITERAL, "", 0); SerdStatus st; - while (!(st = read_scharacter(reader, str, flags))) {} + while (!(st = read_scharacter(reader, ref, flags))) {} if (st < SERD_ERR_UNKNOWN) { eat_byte(reader, '\"'); - return str; + return ref; } - pop_string(reader, str); + pop_node(reader, ref); return 0; } @@ -751,13 +704,13 @@ read_quotedString(SerdReader* reader, SerdNodeFlags* flags) static inline Ref read_relativeURI(SerdReader* reader) { - Ref str = push_string(reader, "", 0); + Ref ref = push_node(reader, SERD_URI, "", 0); SerdStatus st; - while (!(st = read_ucharacter(reader, str))) {} + while (!(st = read_ucharacter(reader, ref))) {} if (st < SERD_ERR_UNKNOWN) { - return str; + return ref; } - pop_string(reader, str); + pop_node(reader, ref); return 0; } @@ -808,12 +761,12 @@ read_prefixName(SerdReader* reader) return 0; } TRY_RET(c = read_nameStartChar(reader, false)); - Ref str = push_string(reader, "", 0); - push_byte(reader, str, c); + Ref ref = push_node(reader, SERD_CURIE, "", 0); + push_byte(reader, ref, c); while ((c = read_nameChar(reader)) != 0) { - push_byte(reader, str, c); + push_byte(reader, ref, c); } - return str; + return ref; } // [32] name ::= nameStartChar nameChar* @@ -842,20 +795,20 @@ read_language(SerdReader* reader) error(reader, "unexpected `%c'\n", start); return 0; } - Ref str = push_string(reader, "", 0); - push_byte(reader, str, eat_byte(reader, start)); + Ref ref = push_node(reader, SERD_LITERAL, "", 0); + push_byte(reader, ref, eat_byte(reader, start)); uint8_t c; while ((c = peek_byte(reader)) && in_range(c, 'a', 'z')) { - push_byte(reader, str, eat_byte(reader, c)); + push_byte(reader, ref, eat_byte(reader, c)); } while (peek_byte(reader) == '-') { - push_byte(reader, str, eat_byte(reader, '-')); + push_byte(reader, ref, eat_byte(reader, '-')); while ((c = peek_byte(reader)) && ( in_range(c, 'a', 'z') || in_range(c, '0', '9'))) { - push_byte(reader, str, eat_byte(reader, c)); + push_byte(reader, ref, eat_byte(reader, c)); } } - return str; + return ref; } // [28] uriref ::= '<' relativeURI '>' @@ -867,7 +820,7 @@ read_uriref(SerdReader* reader) if (str && eat_byte(reader, '>')) { return str; } - pop_string(reader, str); + pop_node(reader, str); return 0; } @@ -877,14 +830,14 @@ read_qname(SerdReader* reader) { Ref prefix = read_prefixName(reader); if (!prefix) { - prefix = push_string(reader, "", 0); + prefix = push_node(reader, SERD_CURIE, "", 0); } TRY_THROW(eat_byte(reader, ':')); push_byte(reader, prefix, ':'); Ref str = read_name(reader, prefix, false); return str ? str : prefix; except: - pop_string(reader, prefix); + pop_node(reader, prefix); return 0; } @@ -913,75 +866,77 @@ read_0_9(SerdReader* reader, Ref str, bool at_least_one) // | ([0-9])+ exponent ) // [16] integer ::= ( '-' | '+' ) ? [0-9]+ static bool -read_number(SerdReader* reader, Node* dest, Node* datatype) +read_number(SerdReader* reader, Ref* dest, Ref* datatype) { #define XSD_DECIMAL NS_XSD "decimal" #define XSD_DOUBLE NS_XSD "double" #define XSD_INTEGER NS_XSD "integer" - Ref str = push_string(reader, "", 0); + Ref ref = push_node(reader, SERD_LITERAL, "", 0); uint8_t c = peek_byte(reader); bool has_decimal = false; if (c == '-' || c == '+') { - push_byte(reader, str, eat_byte(reader, c)); + push_byte(reader, ref, eat_byte(reader, c)); } if ((c = peek_byte(reader)) == '.') { has_decimal = true; // decimal case 2 (e.g. '.0' or `-.0' or `+.0') - push_byte(reader, str, eat_byte(reader, c)); - TRY_THROW(read_0_9(reader, str, true)); + push_byte(reader, ref, eat_byte(reader, c)); + TRY_THROW(read_0_9(reader, ref, true)); } else { // all other cases ::= ( '-' | '+' ) [0-9]+ ( . )? ( [0-9]+ )? ... - TRY_THROW(read_0_9(reader, str, true)); + TRY_THROW(read_0_9(reader, ref, true)); if ((c = peek_byte(reader)) == '.') { has_decimal = true; - push_byte(reader, str, eat_byte(reader, c)); - TRY_THROW(read_0_9(reader, str, false)); + push_byte(reader, ref, eat_byte(reader, c)); + TRY_THROW(read_0_9(reader, ref, false)); } } c = peek_byte(reader); if (c == 'e' || c == 'E') { // double - push_byte(reader, str, eat_byte(reader, c)); + push_byte(reader, ref, eat_byte(reader, c)); switch ((c = peek_byte(reader))) { case '+': case '-': - push_byte(reader, str, eat_byte(reader, c)); + push_byte(reader, ref, eat_byte(reader, c)); default: break; } - read_0_9(reader, str, true); - *datatype = push_uri(reader, XSD_DOUBLE, sizeof(XSD_DOUBLE) - 1); + read_0_9(reader, ref, true); + *datatype = push_node(reader, SERD_URI, + XSD_DOUBLE, sizeof(XSD_DOUBLE) - 1); } else if (has_decimal) { - *datatype = push_uri(reader, XSD_DECIMAL, sizeof(XSD_DECIMAL) - 1); + *datatype = push_node(reader, SERD_URI, + XSD_DECIMAL, sizeof(XSD_DECIMAL) - 1); } else { - *datatype = push_uri(reader, XSD_INTEGER, sizeof(XSD_INTEGER) - 1); + *datatype = push_node(reader, SERD_URI, + XSD_INTEGER, sizeof(XSD_INTEGER) - 1); } - *dest = make_node(SERD_LITERAL, str); - assert(dest->value); + *dest = ref; return true; except: - pop_string(reader, datatype->value); - pop_string(reader, str); + pop_node(reader, *datatype); + pop_node(reader, ref); return false; } // [25] resource ::= uriref | qname static bool -read_resource(SerdReader* reader, Node* dest) +read_resource(SerdReader* reader, Ref* dest) { switch (peek_byte(reader)) { case '<': - *dest = make_node(SERD_URI, read_uriref(reader)); + *dest = read_uriref(reader); break; default: - *dest = make_node(SERD_CURIE, read_qname(reader)); + *dest = read_qname(reader); } - return (dest->value != 0); + return *dest != 0; } // [14] literal ::= quotedString ( '@' language )? | datatypeString // | integer | double | decimal | boolean static bool -read_literal(SerdReader* reader, Node* dest, - Node* datatype, Ref* lang, SerdNodeFlags* flags) +read_literal(SerdReader* reader, Ref* dest, + Ref* datatype, Ref* lang, SerdNodeFlags* flags) { Ref str = 0; const uint8_t c = peek_byte(reader); @@ -1003,26 +958,26 @@ read_literal(SerdReader* reader, Node* dest, eat_byte(reader, '@'); TRY_THROW(*lang = read_language(reader)); } - *dest = make_node(SERD_LITERAL, str); + *dest = str; } else { return error(reader, "unknown literal type\n"); } return true; except: - pop_string(reader, str); + pop_node(reader, str); return false; } // [12] predicate ::= resource static bool -read_predicate(SerdReader* reader, Node* dest) +read_predicate(SerdReader* reader, Ref* dest) { return read_resource(reader, dest); } // [9] verb ::= predicate | 'a' static bool -read_verb(SerdReader* reader, Node* dest) +read_verb(SerdReader* reader, Ref* dest) { uint8_t pre[2]; peek_string(reader, pre, 2); @@ -1031,7 +986,7 @@ read_verb(SerdReader* reader, Node* dest) switch (pre[1]) { case 0x9: case 0xA: case 0xD: case 0x20: eat_byte(reader, 'a'); - *dest = push_uri(reader, NS_RDF "type", 47); + *dest = push_node(reader, SERD_URI, NS_RDF "type", 47); return true; default: break; // fall through } @@ -1046,13 +1001,13 @@ read_nodeID(SerdReader* reader) { eat_byte(reader, '_'); eat_byte(reader, ':'); - Ref ref = push_string(reader, "", 0); + Ref ref = push_node(reader, SERD_BLANK, "", 0); read_name(reader, ref, true); - SerdString* const str = deref(reader, ref); + SerdNode* const node = deref(reader, ref); if (reader->syntax == SERD_TURTLE - && !strncmp((const char*)str->buf, "genid", 5)) { + && !strncmp((const char*)node->buf, "genid", 5)) { // Replace "genid" nodes with "docid" to prevent clashing - memcpy(str->buf, "docid", 5); + memcpy((uint8_t*)node + sizeof(SerdNode), "docid", 5); } return ref; } @@ -1060,19 +1015,20 @@ read_nodeID(SerdReader* reader) static Ref blank_id(SerdReader* reader) { - Ref str; + Ref ref; if (reader->bprefix) { - str = push_string(reader, - (const char*)reader->bprefix, - reader->bprefix_len); + ref = push_node(reader, + SERD_BLANK, + (const char*)reader->bprefix, + reader->bprefix_len); } else { - str = push_string(reader, "", 0); + ref = push_node(reader, SERD_BLANK, "", 0); } char num[32]; snprintf(num, sizeof(num), "%u", reader->next_id++); - append_string(reader, str, (const uint8_t*)"genid", 5); - append_string(reader, str, (const uint8_t*)num, strlen(num)); - return str; + append_string(reader, ref, (const uint8_t*)"genid", 5); + append_string(reader, ref, (const uint8_t*)num, strlen(num)); + return ref; } // Spec: [21] blank ::= nodeID | '[]' @@ -1080,24 +1036,24 @@ blank_id(SerdReader* reader) // Impl: [21] blank ::= nodeID | '[ ws* ]' // | '[' ws* predicateObjectList ws* ']' | collection static bool -read_blank(SerdReader* reader, ReadContext ctx, bool subject, Node* dest) +read_blank(SerdReader* reader, ReadContext ctx, bool subject, Ref* dest) { const bool was_anon_subject = subject && (*ctx.flags | SERD_ANON_CONT); switch (peek_byte(reader)) { case '_': - *dest = make_node(SERD_BLANK, read_nodeID(reader)); + *dest = read_nodeID(reader); return true; case '[': eat_byte(reader, '['); read_ws_star(reader); - *dest = make_node(SERD_BLANK, blank_id(reader)); + *dest = blank_id(reader); if (peek_byte(reader) == ']') { eat_byte(reader, ']'); *ctx.flags |= (subject) ? SERD_EMPTY_S : SERD_EMPTY_O; if (ctx.subject) { TRY_RET(emit_statement(reader, ctx.flags, ctx.graph, ctx.subject, ctx.predicate, - dest, NULL, 0, 0)); + *dest, 0, 0)); } return true; } @@ -1106,9 +1062,9 @@ read_blank(SerdReader* reader, ReadContext ctx, bool subject, Node* dest) if (ctx.subject) { TRY_RET(emit_statement(reader, ctx.flags, ctx.graph, ctx.subject, ctx.predicate, - dest, NULL, 0, 0)); + *dest, 0, 0)); } - ctx.subject = dest; + ctx.subject = *dest; if (!subject) { *ctx.flags |= SERD_ANON_CONT; } @@ -1116,8 +1072,7 @@ read_blank(SerdReader* reader, ReadContext ctx, bool subject, Node* dest) read_ws_star(reader); eat_byte(reader, ']'); if (reader->end_sink) { - const SerdNode end = public_node(reader, dest); - reader->end_sink(reader->handle, &end); + reader->end_sink(reader->handle, deref(reader, *dest)); } if (!was_anon_subject) { *ctx.flags &= ~SERD_ANON_CONT; @@ -1128,7 +1083,7 @@ read_blank(SerdReader* reader, ReadContext ctx, bool subject, Node* dest) if (ctx.subject) { TRY_RET(emit_statement(reader, ctx.flags, ctx.graph, ctx.subject, ctx.predicate, - dest, NULL, 0, 0)); + *dest, 0, 0)); } return true; } @@ -1166,8 +1121,8 @@ read_object(SerdReader* reader, ReadContext ctx) uint8_t pre[6]; bool ret = false; bool emit = (ctx.subject != 0); - Node o = INTERNAL_NODE_NULL; - Node datatype = INTERNAL_NODE_NULL; + Ref o = 0; + Ref datatype = 0; Ref lang = 0; uint32_t flags = 0; const uint8_t c = peek_byte(reader); @@ -1197,31 +1152,31 @@ read_object(SerdReader* reader, ReadContext ctx) peek_string(reader, pre, 6); if (!memcmp(pre, "true", 4) && is_object_end(pre[4])) { eat_string(reader, "true", 4); - const Ref value = push_string(reader, "true", 4); - datatype = push_uri(reader, XSD_BOOLEAN, XSD_BOOLEAN_LEN); - o = make_node(SERD_LITERAL, value); + o = push_node(reader, SERD_LITERAL, "true", 4); + datatype = push_node(reader, SERD_URI, + XSD_BOOLEAN, XSD_BOOLEAN_LEN); } else if (!memcmp(pre, "false", 5) && is_object_end(pre[5])) { eat_string(reader, "false", 5); - const Ref value = push_string(reader, "false", 5); - datatype = push_uri(reader, XSD_BOOLEAN, XSD_BOOLEAN_LEN); - o = make_node(SERD_LITERAL, value); + o = push_node(reader, SERD_LITERAL, "false", 5); + datatype = push_node(reader, SERD_URI, + XSD_BOOLEAN, XSD_BOOLEAN_LEN); } else if (!is_object_end(c)) { - o = make_node(SERD_CURIE, read_qname(reader)); + o = read_qname(reader); } - ret = o.value; + ret = o; } if (ret && emit) { - assert(o.value); + deref(reader, o)->flags = flags; ret = emit_statement(reader, ctx.flags, ctx.graph, ctx.subject, ctx.predicate, - &o, &datatype, lang, flags); + o, datatype, lang); } except: - pop_string(reader, lang); - pop_string(reader, datatype.value); - pop_string(reader, o.value); + pop_node(reader, lang); + pop_node(reader, datatype); + pop_node(reader, o); #ifndef NDEBUG assert(reader->stack.size == orig_stack_size); #endif @@ -1254,13 +1209,13 @@ read_predicateObjectList(SerdReader* reader, ReadContext ctx, bool blank) if (reader->eof) { return false; } - Node predicate = INTERNAL_NODE_NULL; + Ref predicate = 0; TRY_RET(read_verb(reader, &predicate)); TRY_THROW(read_ws_plus(reader)); - ctx.predicate = &predicate; + ctx.predicate = predicate; TRY_THROW(read_objectList(reader, ctx, blank)); - pop_string(reader, predicate.value); - predicate.value = 0; + pop_node(reader, predicate); + predicate = 0; read_ws_star(reader); while (peek_byte(reader) == ';') { eat_byte(reader, ';'); @@ -1270,18 +1225,18 @@ read_predicateObjectList(SerdReader* reader, ReadContext ctx, bool blank) return true; default: TRY_THROW(read_verb(reader, &predicate)); - ctx.predicate = &predicate; + ctx.predicate = predicate; TRY_THROW(read_ws_plus(reader)); TRY_THROW(read_objectList(reader, ctx, blank)); - pop_string(reader, predicate.value); - predicate.value = 0; + pop_node(reader, predicate); + predicate = 0; read_ws_star(reader); } } - pop_string(reader, predicate.value); + pop_node(reader, predicate); return true; except: - pop_string(reader, predicate.value); + pop_node(reader, predicate); return false; } @@ -1293,26 +1248,26 @@ read_collection_rec(SerdReader* reader, ReadContext ctx) if (peek_byte(reader) == ')') { eat_byte(reader, ')'); TRY_RET(emit_statement(reader, ctx.flags, - NULL, + 0, ctx.subject, - &reader->rdf_rest, - &reader->rdf_nil, NULL, 0, 0)); + reader->rdf_rest, + reader->rdf_nil, 0, 0)); return false; } else { - const Node rest = make_node(SERD_BLANK, blank_id(reader)); + const Ref rest = blank_id(reader); TRY_RET(emit_statement(reader, ctx.flags, ctx.graph, ctx.subject, - &reader->rdf_rest, - &rest, NULL, 0, 0)); - ctx.subject = &rest; - ctx.predicate = &reader->rdf_first; + reader->rdf_rest, + rest, 0, 0)); + ctx.subject = rest; + ctx.predicate = reader->rdf_first; if (read_object(reader, ctx)) { read_collection_rec(reader, ctx); - pop_string(reader, rest.value); + pop_node(reader, rest); return true; } else { - pop_string(reader, rest.value); + pop_node(reader, rest); return false; } } @@ -1321,7 +1276,7 @@ read_collection_rec(SerdReader* reader, ReadContext ctx) // [22] itemList ::= object+ // [23] collection ::= '(' itemList? ')' static bool -read_collection(SerdReader* reader, ReadContext ctx, Node* dest) +read_collection(SerdReader* reader, ReadContext ctx, Ref* dest) { TRY_RET(eat_byte(reader, '(')); read_ws_star(reader); @@ -1331,22 +1286,22 @@ read_collection(SerdReader* reader, ReadContext ctx, Node* dest) return true; } - *dest = make_node(SERD_BLANK, blank_id(reader)); - ctx.subject = dest; - ctx.predicate = &reader->rdf_first; + *dest = blank_id(reader); + ctx.subject = *dest; + ctx.predicate = reader->rdf_first; if (!read_object(reader, ctx)) { return error(reader, "unexpected end of collection\n"); } - ctx.subject = dest; + ctx.subject = *dest; return read_collection_rec(reader, ctx); } // [11] subject ::= resource | blank -static Node +static Ref read_subject(SerdReader* reader, ReadContext ctx) { - Node subject = INTERNAL_NODE_NULL; + Ref subject = 0; switch (peek_byte(reader)) { case '[': case '(': case '_': read_blank(reader, ctx, true, &subject); @@ -1362,13 +1317,13 @@ read_subject(SerdReader* reader, ReadContext ctx) static bool read_triples(SerdReader* reader, ReadContext ctx) { - const Node subject = read_subject(reader, ctx); - bool ret = false; - if (subject.value != 0) { - ctx.subject = &subject; + const Ref subject = read_subject(reader, ctx); + bool ret = false; + if (subject) { + ctx.subject = subject; TRY_RET(read_ws_plus(reader)); ret = read_predicateObjectList(reader, ctx, false); - pop_string(reader, subject.value); + pop_node(reader, subject); } ctx.subject = ctx.predicate = 0; return ret; @@ -1383,11 +1338,10 @@ read_base(SerdReader* reader) TRY_RET(read_ws_plus(reader)); Ref uri; TRY_RET(uri = read_uriref(reader)); - const SerdNode uri_node = public_node_from_ref(reader, SERD_URI, uri); if (reader->base_sink) { - reader->base_sink(reader->handle, &uri_node); + reader->base_sink(reader->handle, deref(reader, uri)); } - pop_string(reader, uri); + pop_node(reader, uri); return true; } @@ -1402,20 +1356,20 @@ read_prefixID(SerdReader* reader) bool ret = true; Ref name = read_prefixName(reader); if (!name) { - name = push_string(reader, "", 0); + name = push_node(reader, SERD_LITERAL, "", 0); } TRY_THROW(eat_byte(reader, ':') == ':'); read_ws_star(reader); Ref uri = 0; TRY_THROW(uri = read_uriref(reader)); - const SerdNode name_node = public_node_from_ref(reader, SERD_LITERAL, name); - const SerdNode uri_node = public_node_from_ref(reader, SERD_URI, uri); if (reader->prefix_sink) { - ret = !reader->prefix_sink(reader->handle, &name_node, &uri_node); + ret = !reader->prefix_sink(reader->handle, + deref(reader, name), + deref(reader, uri)); } - pop_string(reader, uri); + pop_node(reader, uri); except: - pop_string(reader, name); + pop_node(reader, name); return ret; } @@ -1503,9 +1457,9 @@ serd_reader_new(SerdSyntax syntax, #define RDF_FIRST NS_RDF "first" #define RDF_REST NS_RDF "rest" #define RDF_NIL NS_RDF "nil" - me->rdf_first = make_node(SERD_URI, push_string(me, RDF_FIRST, 48)); - me->rdf_rest = make_node(SERD_URI, push_string(me, RDF_REST, 47)); - me->rdf_nil = make_node(SERD_URI, push_string(me, RDF_NIL, 46)); + me->rdf_first = push_node(me, SERD_URI, RDF_FIRST, 48); + me->rdf_rest = push_node(me, SERD_URI, RDF_REST, 47); + me->rdf_nil = push_node(me, SERD_URI, RDF_NIL, 46); return me; } @@ -1514,9 +1468,9 @@ SERD_API void serd_reader_free(SerdReader* reader) { - pop_string(reader, reader->rdf_nil.value); - pop_string(reader, reader->rdf_rest.value); - pop_string(reader, reader->rdf_first.value); + pop_node(reader, reader->rdf_nil); + pop_node(reader, reader->rdf_rest); + pop_node(reader, reader->rdf_first); #ifdef SERD_STACK_CHECK free(reader->alloc_stack); |