static bool read_statement(SerdReader* reader) { SerdStatementFlags flags = 0; ReadContext ctx = { 0, 0, 0, &flags }; read_ws_star(reader); bool ate_dot = false; switch (peek_byte(reader)) { case '\0': reader->eof = true; return true; case '@': TRY_RET(read_directive(reader)); read_ws_star(reader); return (eat_byte_check(reader, '.') == '.'); default: if (!read_triples(reader, ctx, &ate_dot)) { return false; } else if (ate_dot) { return true; } else { read_ws_star(reader); return (eat_byte_check(reader, '.') == '.'); } break; } read_ws_star(reader); // remove? return true; }
static bool read_predicateObjectList(SerdReader* reader, ReadContext ctx, bool* ate_dot) { uint8_t c; while (true) { TRY_THROW(read_verb(reader, &ctx.predicate)); read_ws_star(reader); TRY_THROW(read_objectList(reader, ctx, ate_dot)); ctx.predicate = pop_node(reader, ctx.predicate); if (*ate_dot) { return true; } do { read_ws_star(reader); switch (c = peek_byte(reader)) { case 0: return false; case '.': case ']': return true; case ';': eat_byte_safe(reader, c); } } while (c == ';'); } pop_node(reader, ctx.predicate); return true; except: pop_node(reader, ctx.predicate); return false; }
static bool read_prefixID(SerdReader* reader) { bool ret = true; // `@' is already eaten in read_directive eat_string(reader, "prefix", 6); TRY_RET(read_ws_plus(reader)); Ref name = push_node(reader, SERD_LITERAL, "", 0); if (read_PN_PREFIX(reader, name) > SERD_FAILURE) { return pop_node(reader, name); } if (eat_byte_check(reader, ':') != ':') { return pop_node(reader, name); } read_ws_star(reader); const Ref uri = read_IRIREF(reader); if (!uri) { pop_node(reader, name); return false; } if (reader->prefix_sink) { ret = !reader->prefix_sink(reader->handle, deref(reader, name), deref(reader, uri)); } pop_node(reader, uri); pop_node(reader, name); return ret; }
static bool read_triples(SerdReader* reader, ReadContext ctx, bool* ate_dot) { bool nested = false; const Ref subject = read_subject(reader, ctx, &nested); bool ret = false; if (subject) { ctx.subject = subject; if (nested) { read_ws_star(reader); ret = true; if (peek_byte(reader) != '.') { ret = read_predicateObjectList(reader, ctx, ate_dot); } } else { TRY_RET(read_ws_plus(reader)); ret = read_predicateObjectList(reader, ctx, ate_dot); } pop_node(reader, subject); } else { ret = false; } ctx.subject = ctx.predicate = 0; return ret; }
static inline bool eat_delim(SerdReader* reader, const char delim) { if (peek_delim(reader, delim)) { eat_byte_safe(reader, delim); return read_ws_star(reader); } return false; }
static bool read_blank(SerdReader* reader, ReadContext ctx, bool subject, Ref* dest, bool* ate_dot) { const SerdStatementFlags old_flags = *ctx.flags; bool empty; switch (peek_byte(reader)) { case '_': return (*dest = read_BLANK_NODE_LABEL(reader, ate_dot)); case '[': eat_byte_safe(reader, '['); if ((empty = peek_delim(reader, ']'))) { *ctx.flags |= (subject) ? SERD_EMPTY_S : SERD_EMPTY_O; } else { *ctx.flags |= (subject) ? SERD_ANON_S_BEGIN : SERD_ANON_O_BEGIN; if (peek_delim(reader, '=')) { if (!(*dest = read_blankName(reader)) || !eat_delim(reader, ';')) { return false; } } } if (!*dest) { *dest = blank_id(reader); } if (ctx.subject) { TRY_RET(emit_statement(reader, ctx, *dest, 0, 0)); } ctx.subject = *dest; if (!empty) { *ctx.flags &= ~(SERD_LIST_CONT); if (!subject) { *ctx.flags |= SERD_ANON_CONT; } bool ate_dot_in_list = false; read_predicateObjectList(reader, ctx, &ate_dot_in_list); if (ate_dot_in_list) { return r_err(reader, SERD_ERR_BAD_SYNTAX, "`.' inside blank\n"); } read_ws_star(reader); if (reader->end_sink) { reader->end_sink(reader->handle, deref(reader, *dest)); } *ctx.flags = old_flags; } return (eat_byte_check(reader, ']') == ']'); case '(': return read_collection(reader, ctx, dest); default: return false; // never reached } }
static Ref read_blankName(SerdReader* reader) { eat_byte_safe(reader, '='); if (eat_byte_check(reader, '=') != '=') { return r_err(reader, SERD_ERR_BAD_SYNTAX, "expected `='\n"); } Ref subject = 0; bool ate_dot = false; read_ws_star(reader); read_iri(reader, &subject, &ate_dot); return subject; }
static inline bool peek_delim(SerdReader* reader, const char delim) { read_ws_star(reader); return peek_byte(reader) == delim; }
static inline bool read_ws_plus(SerdReader* reader) { TRY_RET(read_ws(reader)); return read_ws_star(reader); }