aboutsummaryrefslogtreecommitdiffstats
path: root/src/reader.h
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2018-05-12 20:39:23 +0200
committerDavid Robillard <d@drobilla.net>2019-04-13 19:15:32 +0200
commitfea20a9af56d5b7640ced14cde92fe6746291502 (patch)
tree848c9e3a4e3e33d0b65ef39142d0ff8507af3391 /src/reader.h
parent29cfc326f8f64d8327597f2218f0caefeed4560f (diff)
downloadserd-fea20a9af56d5b7640ced14cde92fe6746291502.tar.gz
serd-fea20a9af56d5b7640ced14cde92fe6746291502.tar.bz2
serd-fea20a9af56d5b7640ced14cde92fe6746291502.zip
Use a fixed-size reader stack
This improves performance, and makes the reader more suitable for embedded or network-facing applications, at the cost of requiring the user to specify a maximum stack size.
Diffstat (limited to 'src/reader.h')
-rw-r--r--src/reader.h73
1 files changed, 37 insertions, 36 deletions
diff --git a/src/reader.h b/src/reader.h
index c3ea2e77..36d6da03 100644
--- a/src/reader.h
+++ b/src/reader.h
@@ -35,18 +35,13 @@
# define SERD_STACK_ASSERT_TOP(reader, ref)
#endif
-/* 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 {
- Ref graph;
- Ref subject;
- Ref predicate;
- Ref object;
- Ref datatype;
- Ref lang;
+ SerdNode* graph;
+ SerdNode* subject;
+ SerdNode* predicate;
+ SerdNode* object;
+ SerdNode* datatype;
+ SerdNode* lang;
SerdStatementFlags* flags;
} ReadContext;
@@ -55,9 +50,9 @@ struct SerdReaderImpl {
const SerdSink* sink;
SerdErrorSink error_sink;
void* error_handle;
- Ref rdf_first;
- Ref rdf_rest;
- Ref rdf_nil;
+ SerdNode* rdf_first;
+ SerdNode* rdf_rest;
+ SerdNode* rdf_nil;
SerdNode* default_graph;
SerdByteSource source;
SerdStack stack;
@@ -70,33 +65,31 @@ struct SerdReaderImpl {
bool strict; ///< True iff strict parsing
bool seen_genid;
#ifdef SERD_STACK_CHECK
- Ref* allocs; ///< Stack of push offsets
+ SerdNode** allocs; ///< Stack of push offsets
size_t n_allocs; ///< Number of stack pushes
#endif
};
int r_err(SerdReader* reader, SerdStatus st, const char* fmt, ...);
-Ref push_node_padded(SerdReader* reader,
- size_t maxlen,
- SerdType type,
- const char* str,
- size_t n_bytes);
-
-Ref push_node(SerdReader* reader,
- SerdType type,
- const char* str,
- size_t n_bytes);
+SerdNode* push_node_padded(SerdReader* reader,
+ size_t maxlen,
+ SerdType type,
+ const char* str,
+ size_t n_bytes);
-size_t genid_size(SerdReader* reader);
-Ref blank_id(SerdReader* reader);
-void set_blank_id(SerdReader* reader, Ref ref, size_t buf_size);
+SerdNode* push_node(SerdReader* reader,
+ SerdType type,
+ const char* str,
+ size_t n_bytes);
-SerdNode* deref(SerdReader* reader, Ref ref);
+size_t genid_size(SerdReader* reader);
+SerdNode* blank_id(SerdReader* reader);
+void set_blank_id(SerdReader* reader, SerdNode* node, size_t buf_size);
-Ref pop_node(SerdReader* reader, Ref ref);
+SerdNode* pop_node(SerdReader* reader, const SerdNode* node);
-bool emit_statement(SerdReader* reader, ReadContext ctx, Ref o);
+bool emit_statement(SerdReader* reader, ReadContext ctx, SerdNode* o);
bool read_n3_statement(SerdReader* reader);
SerdStatus read_nquadsDoc(SerdReader* reader);
@@ -151,23 +144,31 @@ eat_string(SerdReader* reader, const char* str, unsigned n)
}
static inline SerdStatus
-push_byte(SerdReader* reader, Ref ref, const uint8_t c)
+push_byte(SerdReader* reader, SerdNode* node, const uint8_t c)
{
SERD_STACK_ASSERT_TOP(reader, ref);
- char* const s = (char*)serd_stack_push(&reader->stack, 1);
- SerdNode* const node = (SerdNode*)(reader->stack.buf + ref);
+ char* const s = (char*)serd_stack_push(&reader->stack, 1);
+ if (!s) {
+ return SERD_ERR_OVERFLOW;
+ }
+
++node->n_bytes;
*(s - 1) = c;
*s = '\0';
return SERD_SUCCESS;
}
-static inline void
-push_bytes(SerdReader* reader, Ref ref, const uint8_t* bytes, unsigned len)
+static inline SerdStatus
+push_bytes(SerdReader* reader, SerdNode* ref, const uint8_t* bytes, unsigned len)
{
+ if (reader->stack.buf_size < reader->stack.size + len) {
+ return SERD_ERR_OVERFLOW;
+ }
+
for (unsigned i = 0; i < len; ++i) {
push_byte(reader, ref, bytes[i]);
}
+ return SERD_SUCCESS;
}
#endif // SERD_READER_H