aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/reader.c134
1 files changed, 76 insertions, 58 deletions
diff --git a/src/reader.c b/src/reader.c
index 739112ce..9bfbbe7c 100644
--- a/src/reader.c
+++ b/src/reader.c
@@ -46,8 +46,6 @@ typedef size_t Ref;
typedef struct {
SerdType type;
Ref value;
- Ref datatype;
- Ref lang;
} Node;
typedef struct {
@@ -63,7 +61,7 @@ typedef struct {
uint8_t buf[]; ///< Buffer
} SerdString;
-static const Node INTERNAL_NODE_NULL = { 0, 0, 0, 0 };
+static const Node INTERNAL_NODE_NULL = { 0, 0 };
struct SerdReaderImpl {
void* handle;
@@ -110,9 +108,9 @@ error(SerdReader* reader, const char* fmt, ...)
}
static Node
-make_node(SerdType type, Ref value, Ref datatype, Ref lang)
+make_node(SerdType type, Ref value)
{
- const Node ret = { type, value, datatype, lang };
+ const Node ret = { type, value };
return ret;
}
@@ -281,20 +279,26 @@ public_node_from_ref(SerdReader* reader, SerdType type, Ref ref)
static inline SerdNode
public_node(SerdReader* reader, const Node* private)
{
- return public_node_from_ref(reader, private->type, private->value);
+ if (private) {
+ return public_node_from_ref(reader, private->type, private->value);
+ } else {
+ return SERD_NODE_NULL;
+ }
+
}
static inline bool
emit_statement(SerdReader* reader,
- const Node* g, const Node* s, const Node* p, const Node* o)
+ const Node* g, const Node* s, const Node* p, const Node* o,
+ const Node* datatype, Ref lang)
{
assert(s->value && p->value && o->value);
const SerdNode graph = g ? public_node(reader, g) : SERD_NODE_NULL;
const SerdNode subject = public_node(reader, s);
const SerdNode predicate = public_node(reader, p);
const SerdNode object = public_node(reader, o);
- const SerdNode object_datatype = public_node_from_ref(reader, SERD_URI, o->datatype);
- const SerdNode object_lang = public_node_from_ref(reader, SERD_LITERAL, o->lang);
+ const SerdNode object_datatype = public_node(reader, datatype);
+ const SerdNode object_lang = public_node_from_ref(reader, SERD_LITERAL, lang);
return !reader->statement_sink(reader->handle,
&graph,
&subject,
@@ -824,7 +828,7 @@ 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)
+read_number(SerdReader* reader, Node* dest, Node* datatype)
{
#define XSD_DECIMAL NS_XSD "decimal"
#define XSD_DOUBLE NS_XSD "double"
@@ -832,7 +836,6 @@ read_number(SerdReader* reader, Node* dest)
Ref str = push_string(reader, "", 1);
uint8_t c = peek_byte(reader);
bool has_decimal = false;
- Ref datatype = 0;
if (c == '-' || c == '+') {
push_byte(reader, str, eat_byte(reader, c));
}
@@ -860,17 +863,17 @@ read_number(SerdReader* reader, Node* dest)
default: break;
}
read_0_9(reader, str, true);
- datatype = push_string(reader, XSD_DOUBLE, sizeof(XSD_DOUBLE));
+ *datatype = make_node(SERD_URI, push_string(reader, XSD_DOUBLE, sizeof(XSD_DOUBLE)));
} else if (has_decimal) {
- datatype = push_string(reader, XSD_DECIMAL, sizeof(XSD_DECIMAL));
+ *datatype = make_node(SERD_URI, push_string(reader, XSD_DECIMAL, sizeof(XSD_DECIMAL)));
} else {
- datatype = push_string(reader, XSD_INTEGER, sizeof(XSD_INTEGER));
+ *datatype = make_node(SERD_URI, push_string(reader, XSD_INTEGER, sizeof(XSD_INTEGER)));
}
- *dest = make_node(SERD_LITERAL, str, datatype, 0);
+ *dest = make_node(SERD_LITERAL, str);
assert(dest->value);
return true;
except:
- pop_string(reader, datatype);
+ pop_string(reader, datatype->value);
pop_string(reader, str);
return false;
}
@@ -881,10 +884,10 @@ read_resource(SerdReader* reader, Node* dest)
{
switch (peek_byte(reader)) {
case '<':
- *dest = make_node(SERD_URI, read_uriref(reader), 0, 0);
+ *dest = make_node(SERD_URI, read_uriref(reader));
break;
default:
- *dest = make_node(SERD_CURIE, read_qname(reader), 0, 0);
+ *dest = make_node(SERD_CURIE, read_qname(reader));
}
return (dest->value != 0);
}
@@ -892,31 +895,29 @@ read_resource(SerdReader* reader, Node* dest)
// [14] literal ::= quotedString ( '@' language )? | datatypeString
// | integer | double | decimal | boolean
static bool
-read_literal(SerdReader* reader, Node* dest)
+read_literal(SerdReader* reader, Node* dest, Node* datatype, Ref* lang)
{
- Ref str = 0;
- Node datatype = INTERNAL_NODE_NULL;
- const uint8_t c = peek_byte(reader);
+ Ref str = 0;
+ const uint8_t c = peek_byte(reader);
if (c == '-' || c == '+' || c == '.' || is_digit(c)) {
- return read_number(reader, dest);
+ return read_number(reader, dest, datatype);
} else if (c == '\"') {
str = read_quotedString(reader);
if (!str) {
return false;
}
- Ref lang = 0;
switch (peek_byte(reader)) {
case '^':
eat_byte(reader, '^');
eat_byte(reader, '^');
- TRY_THROW(read_resource(reader, &datatype));
+ TRY_THROW(read_resource(reader, datatype));
break;
case '@':
eat_byte(reader, '@');
- TRY_THROW(lang = read_language(reader));
+ TRY_THROW(*lang = read_language(reader));
}
- *dest = make_node(SERD_LITERAL, str, datatype.value, lang);
+ *dest = make_node(SERD_LITERAL, str);
} else {
return error(reader, "unknown literal type\n");
}
@@ -945,7 +946,7 @@ read_verb(SerdReader* reader, Node* dest)
case 0x9: case 0xA: case 0xD: case 0x20:
eat_byte(reader, 'a');
*dest = make_node(SERD_URI,
- push_string(reader, NS_RDF "type", 48), 0, 0);
+ push_string(reader, NS_RDF "type", 48));
return true;
default: break; // fall through
}
@@ -985,22 +986,26 @@ read_blank(SerdReader* reader, ReadContext ctx, Node* dest)
{
switch (peek_byte(reader)) {
case '_':
- *dest = make_node(SERD_BLANK_ID, read_nodeID(reader), 0, 0);
+ *dest = make_node(SERD_BLANK_ID, read_nodeID(reader));
return true;
case '[':
eat_byte(reader, '[');
read_ws_star(reader);
if (peek_byte(reader) == ']') {
eat_byte(reader, ']');
- *dest = make_node(SERD_BLANK_ID, blank_id(reader), 0, 0);
+ *dest = make_node(SERD_BLANK_ID, blank_id(reader));
if (ctx.subject) {
- TRY_RET(emit_statement(reader, ctx.graph, ctx.subject, ctx.predicate, dest));
+ TRY_RET(emit_statement(reader,
+ ctx.graph, ctx.subject, ctx.predicate,
+ dest, NULL, 0));
}
return true;
}
- *dest = make_node(SERD_ANON_BEGIN, blank_id(reader), 0, 0);
+ *dest = make_node(SERD_ANON_BEGIN, blank_id(reader));
if (ctx.subject) {
- TRY_RET(emit_statement(reader, ctx.graph, ctx.subject, ctx.predicate, dest));
+ TRY_RET(emit_statement(reader,
+ ctx.graph, ctx.subject, ctx.predicate,
+ dest, NULL, 0));
dest->type = SERD_ANON;
}
ctx.subject = dest;
@@ -1015,7 +1020,9 @@ read_blank(SerdReader* reader, ReadContext ctx, Node* dest)
case '(':
if (read_collection(reader, ctx, dest)) {
if (ctx.subject) {
- TRY_RET(emit_statement(reader, ctx.graph, ctx.subject, ctx.predicate, dest));
+ TRY_RET(emit_statement(reader,
+ ctx.graph, ctx.subject, ctx.predicate,
+ dest, NULL, 0));
}
return true;
}
@@ -1051,10 +1058,12 @@ read_object(SerdReader* reader, ReadContext ctx)
#endif
uint8_t pre[6];
- bool ret = false;
- bool emit = (ctx.subject != 0);
- Node o = INTERNAL_NODE_NULL;
- const uint8_t c = peek_byte(reader);
+ bool ret = false;
+ bool emit = (ctx.subject != 0);
+ Node o = INTERNAL_NODE_NULL;
+ Node datatype = INTERNAL_NODE_NULL;
+ Ref lang = 0;
+ const uint8_t c = peek_byte(reader);
switch (c) {
case '\0':
case ')':
@@ -1071,10 +1080,10 @@ read_object(SerdReader* reader, ReadContext ctx)
case '\"': case '+': case '-':
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
- TRY_THROW(ret = read_literal(reader, &o));
+ TRY_THROW(ret = read_literal(reader, &o, &datatype, &lang));
break;
case '.':
- TRY_THROW(ret = read_literal(reader, &o));
+ TRY_THROW(ret = read_literal(reader, &o, &datatype, &lang));
break;
default:
/* Either a boolean literal, or a qname.
@@ -1084,28 +1093,32 @@ 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", 5);
- const Ref datatype = push_string(reader, XSD_BOOLEAN, XSD_BOOLEAN_LEN + 1);
- o = make_node(SERD_LITERAL, value, datatype, 0);
+ const Ref value = push_string(reader, "true", 5);
+ datatype = make_node(SERD_URI, push_string(
+ reader, XSD_BOOLEAN, XSD_BOOLEAN_LEN + 1));
+ o = make_node(SERD_LITERAL, value);
} else if (!memcmp(pre, "false", 5) && is_object_end(pre[5])) {
eat_string(reader, "false", 5);
- const Ref value = push_string(reader, "false", 6);
- const Ref datatype = push_string(reader, XSD_BOOLEAN, XSD_BOOLEAN_LEN + 1);
- o = make_node(SERD_LITERAL, value, datatype, 0);
+ const Ref value = push_string(reader, "false", 6);
+ datatype = make_node(SERD_URI, push_string(
+ reader, XSD_BOOLEAN, XSD_BOOLEAN_LEN + 1));
+ o = make_node(SERD_LITERAL, value);
} else if (!is_object_end(c)) {
- o = make_node(SERD_CURIE, read_qname(reader), 0, 0);
+ o = make_node(SERD_CURIE, read_qname(reader));
}
ret = o.value;
}
if (ret && emit) {
assert(o.value);
- ret = emit_statement(reader, ctx.graph, ctx.subject, ctx.predicate, &o);
+ ret = emit_statement(reader,
+ ctx.graph, ctx.subject, ctx.predicate,
+ &o, &datatype, lang);
}
except:
- pop_string(reader, o.lang);
- pop_string(reader, o.datatype);
+ pop_string(reader, lang);
+ pop_string(reader, datatype.value);
pop_string(reader, o.value);
#ifndef NDEBUG
assert(reader->stack.size == orig_stack_size);
@@ -1177,12 +1190,17 @@ read_collection_rec(SerdReader* reader, ReadContext ctx)
read_ws_star(reader);
if (peek_byte(reader) == ')') {
eat_byte(reader, ')');
- TRY_RET(emit_statement(reader, NULL, ctx.subject,
- &reader->rdf_rest, &reader->rdf_nil));
+ TRY_RET(emit_statement(reader, NULL,
+ ctx.subject,
+ &reader->rdf_rest,
+ &reader->rdf_nil, NULL, 0));
return false;
} else {
- const Node rest = make_node(SERD_BLANK_ID, blank_id(reader), 0, 0);
- TRY_RET(emit_statement(reader, ctx.graph, ctx.subject, &reader->rdf_rest, &rest));
+ const Node rest = make_node(SERD_BLANK_ID, blank_id(reader));
+ TRY_RET(emit_statement(reader, ctx.graph,
+ ctx.subject,
+ &reader->rdf_rest,
+ &rest, NULL, 0));
ctx.subject = &rest;
ctx.predicate = &reader->rdf_first;
if (read_object(reader, ctx)) {
@@ -1209,7 +1227,7 @@ read_collection(SerdReader* reader, ReadContext ctx, Node* dest)
return true;
}
- *dest = make_node(SERD_BLANK_ID, blank_id(reader), 0, 0);
+ *dest = make_node(SERD_BLANK_ID, blank_id(reader));
ctx.subject = dest;
ctx.predicate = &reader->rdf_first;
if (!read_object(reader, ctx)) {
@@ -1372,9 +1390,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, 49), 0, 0);
- me->rdf_rest = make_node(SERD_URI, push_string(me, RDF_REST, 48), 0, 0);
- me->rdf_nil = make_node(SERD_URI, push_string(me, RDF_NIL, 47), 0, 0);
+ me->rdf_first = make_node(SERD_URI, push_string(me, RDF_FIRST, 49));
+ me->rdf_rest = make_node(SERD_URI, push_string(me, RDF_REST, 48));
+ me->rdf_nil = make_node(SERD_URI, push_string(me, RDF_NIL, 47));
return me;
}