diff options
Diffstat (limited to 'src/canon.c')
-rw-r--r-- | src/canon.c | 51 |
1 files changed, 37 insertions, 14 deletions
diff --git a/src/canon.c b/src/canon.c index f8f1d8f0..a02d9a29 100644 --- a/src/canon.c +++ b/src/canon.c @@ -15,6 +15,7 @@ */ #include "caret.h" +#include "memory.h" #include "namespaces.h" #include "node.h" #include "statement.h" @@ -35,7 +36,8 @@ typedef struct { } SerdCanonData; static ExessResult -build_typed(SerdNode** const out, +build_typed(SerdAllocator* const SERD_NONNULL allocator, + SerdNode** const out, const SerdNode* const SERD_NONNULL node, const SerdNode* const SERD_NONNULL datatype) { @@ -46,7 +48,7 @@ build_typed(SerdNode** const out, ExessResult r = {EXESS_SUCCESS, 0}; if (!strcmp(datatype_uri, NS_RDF "langString")) { - *out = serd_new_string(serd_node_string_view(node)); + *out = serd_new_string(allocator, serd_node_string_view(node)); return r; } @@ -65,7 +67,11 @@ build_typed(SerdNode** const out, const size_t datatype_size = serd_node_total_size(datatype); const size_t len = serd_node_pad_length(r.count); const size_t total_len = sizeof(SerdNode) + len + datatype_size; - SerdNode* const result = serd_node_malloc(total_len); + SerdNode* const result = serd_node_malloc(allocator, total_len); + if (!result) { + r.status = EXESS_NO_SPACE; + return r; + } result->length = r.count; result->flags = SERD_HAS_DATATYPE; @@ -86,7 +92,8 @@ build_typed(SerdNode** const out, } static ExessResult -build_tagged(SerdNode** const out, +build_tagged(SerdAllocator* const SERD_NONNULL allocator, + SerdNode** const out, const SerdNode* const SERD_NONNULL node, const SerdNode* const SERD_NONNULL language) { @@ -107,7 +114,8 @@ build_tagged(SerdNode** const out, } // Make a new literal that is otherwise identical - *out = serd_new_literal(serd_node_string_view(node), + *out = serd_new_literal(allocator, + serd_node_string_view(node), serd_node_flags(node), SERD_SUBSTRING(canonical_lang, lang_len)); @@ -122,16 +130,18 @@ serd_canon_on_statement(SerdCanonData* const data, const SerdStatementFlags flags, const SerdStatement* const statement) { - const SerdNode* const object = serd_statement_object(statement); - const SerdNode* const datatype = serd_node_datatype(object); - const SerdNode* const language = serd_node_language(object); + SerdAllocator* const allocator = serd_world_allocator(data->world); + const SerdNode* const object = serd_statement_object(statement); + const SerdNode* const datatype = serd_node_datatype(object); + const SerdNode* const language = serd_node_language(object); if (!datatype && !language) { return serd_sink_write_statement(data->target, flags, statement); } SerdNode* normo = NULL; - const ExessResult r = datatype ? build_typed(&normo, object, datatype) - : build_tagged(&normo, object, language); + const ExessResult r = datatype + ? build_typed(allocator, &normo, object, datatype) + : build_tagged(allocator, &normo, object, language); if (r.status) { SerdCaret caret = {NULL, 0u, 0u}; @@ -151,7 +161,7 @@ serd_canon_on_statement(SerdCanonData* const data, exess_strerror(r.status)); if (!lax) { - return SERD_BAD_LITERAL; + return r.status == EXESS_NO_SPACE ? SERD_BAD_ALLOC : SERD_BAD_LITERAL; } } @@ -165,7 +175,7 @@ serd_canon_on_statement(SerdCanonData* const data, statement->nodes[1], normo, statement->nodes[3]); - serd_node_free(normo); + serd_node_free(allocator, normo); return st; } @@ -183,13 +193,26 @@ serd_canon_new(const SerdWorld* const world, const SerdSink* const target, const SerdCanonFlags flags) { + assert(world); assert(target); - SerdCanonData* const data = (SerdCanonData*)calloc(1, sizeof(SerdCanonData)); + SerdCanonData* const data = + (SerdCanonData*)serd_wcalloc(world, 1, sizeof(SerdCanonData)); + + if (!data) { + return NULL; + } data->world = world; data->target = target; data->flags = flags; - return serd_sink_new(world, data, (SerdEventFunc)serd_canon_on_event, free); + SerdSink* const sink = + serd_sink_new(world, data, (SerdEventFunc)serd_canon_on_event, free); + + if (!sink) { + serd_wfree(world, data); + } + + return sink; } |