diff options
author | David Robillard <d@drobilla.net> | 2023-09-10 15:06:42 -0400 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2023-12-02 18:49:08 -0500 |
commit | 248a874d7425749d29cf900a1c3783c624ea8d8c (patch) | |
tree | aed59f5a484a815cd254506866e98a947858904d /src/writer.c | |
parent | 0bd10132c6707353dba80bd89cf0102ee7ca4e34 (diff) | |
download | serd-248a874d7425749d29cf900a1c3783c624ea8d8c.tar.gz serd-248a874d7425749d29cf900a1c3783c624ea8d8c.tar.bz2 serd-248a874d7425749d29cf900a1c3783c624ea8d8c.zip |
Add support for custom allocators
This makes it explicit in the API where memory is allocated, and allows the
user to provide a custom allocator to avoid the use of the default system
allocator for whatever reason.
Diffstat (limited to 'src/writer.c')
-rw-r--r-- | src/writer.c | 95 |
1 files changed, 54 insertions, 41 deletions
diff --git a/src/writer.c b/src/writer.c index fa1abd9f..6d52b4e6 100644 --- a/src/writer.c +++ b/src/writer.c @@ -3,6 +3,7 @@ #include "block_dumper.h" #include "env.h" +#include "memory.h" #include "namespaces.h" #include "node.h" #include "sink.h" @@ -34,7 +35,6 @@ #include <stdbool.h> #include <stdint.h> #include <stdio.h> -#include <stdlib.h> #include <string.h> typedef enum { @@ -175,14 +175,11 @@ supports_uriref(const SerdWriter* writer) } static SerdStatus -free_context(WriteContext* const ctx) +free_context(SerdWriter* const writer) { - serd_node_free(ctx->graph); - serd_node_free(ctx->subject); - serd_node_free(ctx->predicate); - ctx->graph = NULL; - ctx->subject = NULL; - ctx->predicate = NULL; + serd_node_free(writer->world->allocator, writer->context.graph); + serd_node_free(writer->world->allocator, writer->context.subject); + serd_node_free(writer->world->allocator, writer->context.predicate); return SERD_SUCCESS; } @@ -234,13 +231,14 @@ push_context(SerdWriter* const writer, // Update the current context - const WriteContext current = {type, - flags, - serd_node_copy(graph), - serd_node_copy(subject), - serd_node_copy(predicate), - 0U, - 0U}; + const WriteContext current = { + type, + flags, + serd_node_copy(writer->world->allocator, graph), + serd_node_copy(writer->world->allocator, subject), + serd_node_copy(writer->world->allocator, predicate), + 0U, + 0U}; writer->context = current; return SERD_SUCCESS; @@ -251,7 +249,7 @@ pop_context(SerdWriter* writer) { assert(writer->anon_stack_size > 0); - free_context(&writer->context); + free_context(writer); writer->context = writer->anon_stack[--writer->anon_stack_size]; } @@ -971,10 +969,10 @@ write_pred(SerdWriter* writer, SerdStatementFlags flags, const SerdNode* pred) TRY(st, write_node(writer, pred, SERD_PREDICATE, flags)); TRY(st, write_sep(writer, flags, SEP_P_O)); - serd_node_set(&writer->context.predicate, pred); writer->context.predicates = true; writer->context.comma_indented = false; - return st; + return serd_node_set( + writer->world->allocator, &writer->context.predicate, pred); } SERD_NODISCARD static SerdStatus @@ -1068,7 +1066,7 @@ update_abbreviation_context(SerdWriter* const writer, { SerdStatus st = SERD_SUCCESS; - // Push context for anonymous or list subject if necessary + // Push context for list or anonymous subject if necessary if (flags & SERD_ANON_S) { st = push_context(writer, CTX_BLANK, flags, graph, subject, predicate); } else if (flags & SERD_LIST_S) { @@ -1175,9 +1173,13 @@ write_turtle_trig_statement(SerdWriter* const writer, TRY(st, write_sep(writer, flags, SEP_ANON_S_P)); } - // Set context to new subject and write predicate + // Set context to new subject reset_context(writer, 0U); - serd_node_set(&writer->context.subject, subject); + TRY(st, + serd_node_set( + writer->world->allocator, &writer->context.subject, subject)); + + // Write predicate if (!(flags & SERD_LIST_S)) { TRY(st, write_pred(writer, flags, predicate)); } @@ -1218,7 +1220,7 @@ write_trig_statement(SerdWriter* const writer, if (graph) { TRY(st, write_node(writer, graph, SERD_GRAPH, flags)); TRY(st, write_sep(writer, flags, SEP_GRAPH_BEGIN)); - serd_node_set(&writer->context.graph, graph); + serd_node_set(writer->world->allocator, &writer->context.graph, graph); } } @@ -1340,14 +1342,18 @@ serd_writer_new(SerdWorld* world, assert(env); assert(output); - SerdBlockDumper dumper = {NULL, NULL, 0U, 0U}; - if (serd_block_dumper_open(&dumper, output, block_size)) { + SerdBlockDumper dumper = {world->allocator, NULL, NULL, 0U, 0U}; + if (serd_block_dumper_open(world, &dumper, output, block_size)) { return NULL; } - const size_t max_depth = world->limits.writer_max_depth; - const WriteContext context = WRITE_CONTEXT_NULL; - SerdWriter* writer = (SerdWriter*)calloc(1, sizeof(SerdWriter)); + const WriteContext context = WRITE_CONTEXT_NULL; + + SerdWriter* writer = (SerdWriter*)serd_wcalloc(world, 1, sizeof(SerdWriter)); + if (!writer) { + serd_block_dumper_close(&dumper); + return NULL; + } writer->world = world; writer->syntax = syntax; @@ -1358,13 +1364,19 @@ serd_writer_new(SerdWorld* world, writer->output = dumper; writer->context = context; - if (max_depth) { - writer->max_depth = max_depth; - writer->anon_stack = (WriteContext*)calloc(max_depth, sizeof(WriteContext)); + if (world->limits.writer_max_depth) { + writer->max_depth = world->limits.writer_max_depth; + writer->anon_stack = (WriteContext*)serd_wcalloc( + world, world->limits.writer_max_depth, sizeof(WriteContext)); + if (!writer->anon_stack) { + serd_wfree(world, writer); + return NULL; + } } - writer->iface.handle = writer; - writer->iface.on_event = (SerdEventFunc)serd_writer_on_event; + writer->iface.allocator = world->allocator; + writer->iface.handle = writer; + writer->iface.on_event = (SerdEventFunc)serd_writer_on_event; return writer; } @@ -1374,14 +1386,15 @@ serd_writer_chop_blank_prefix(SerdWriter* writer, const char* prefix) { assert(writer); - free(writer->bprefix); + serd_wfree(writer->world, writer->bprefix); writer->bprefix_len = 0; writer->bprefix = NULL; const size_t prefix_len = prefix ? strlen(prefix) : 0; if (prefix_len) { writer->bprefix_len = prefix_len; - writer->bprefix = (char*)malloc(writer->bprefix_len + 1); + writer->bprefix = + (char*)serd_wmalloc(writer->world, writer->bprefix_len + 1); memcpy(writer->bprefix, prefix, writer->bprefix_len + 1); } } @@ -1417,12 +1430,12 @@ serd_writer_set_root_uri(SerdWriter* writer, const SerdStringView uri) { assert(writer); - serd_node_free(writer->root_node); + serd_node_free(writer->world->allocator, writer->root_node); writer->root_node = NULL; writer->root_uri = SERD_URI_NULL; if (uri.length) { - writer->root_node = serd_new_uri(uri); + writer->root_node = serd_new_uri(writer->world->allocator, uri); writer->root_uri = serd_node_uri_view(writer->root_node); } @@ -1462,13 +1475,13 @@ serd_writer_free(SerdWriter* writer) } serd_writer_finish(writer); - free_context(&writer->context); + free_context(writer); free_anon_stack(writer); serd_block_dumper_close(&writer->output); - free(writer->anon_stack); - free(writer->bprefix); - serd_node_free(writer->root_node); - free(writer); + serd_wfree(writer->world, writer->anon_stack); + serd_wfree(writer->world, writer->bprefix); + serd_node_free(writer->world->allocator, writer->root_node); + serd_wfree(writer->world, writer); } const SerdSink* |