aboutsummaryrefslogtreecommitdiffstats
path: root/src/canon.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/canon.c')
-rw-r--r--src/canon.c51
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;
}