From 91945867cfee9e92df50149311d98eda41b16a60 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Tue, 23 Mar 2021 12:42:43 -0400 Subject: WIP --- src/dumper.c | 200 ++++++++++++++++--------------- src/loader.c | 384 ++++++++++++++++++++++++++++++++++------------------------- 2 files changed, 327 insertions(+), 257 deletions(-) (limited to 'src') diff --git a/src/dumper.c b/src/dumper.c index b2bb852..b6cd08e 100644 --- a/src/dumper.c +++ b/src/dumper.c @@ -33,12 +33,12 @@ #define NS_RDF "http://www.w3.org/1999/02/22-rdf-syntax-ns#" #define NS_XSD "http://www.w3.org/2001/XMLSchema#" -#define STREAM_WARN(msg) \ - serd_world_logf( \ +#define DUMP_WARN(msg) \ + serd_world_logf( \ writer->world, "sratom", SERD_LOG_LEVEL_WARNING, 0, NULL, msg); -#define STREAM_ERRORF(msg, ...) \ - serd_world_logf( \ +#define DUMP_ERRORF(msg, ...) \ + serd_world_logf( \ writer->world, "sratom", SERD_LOG_LEVEL_ERROR, 0, NULL, msg, __VA_ARGS__); struct SratomDumperImpl { @@ -92,53 +92,53 @@ sratom_dumper_new(SerdWorld* const world, LV2_URID_Map* const map, LV2_URID_Unmap* const unmap) { - SratomDumper* writer = (SratomDumper*)calloc(1, sizeof(SratomDumper)); - if (!writer) { + SratomDumper* const dumper = (SratomDumper*)calloc(1, sizeof(SratomDumper)); + if (!dumper) { return NULL; } - writer->world = world; - writer->unmap = unmap; - writer->atom_Event = map->map(map->handle, LV2_ATOM__Event); - writer->atom_beatTime = map->map(map->handle, LV2_ATOM__beatTime); - writer->midi_MidiEvent = map->map(map->handle, LV2_MIDI__MidiEvent); - lv2_atom_forge_init(&writer->forge, map); + dumper->world = world; + dumper->unmap = unmap; + dumper->atom_Event = map->map(map->handle, LV2_ATOM__Event); + dumper->atom_beatTime = map->map(map->handle, LV2_ATOM__beatTime); + dumper->midi_MidiEvent = map->map(map->handle, LV2_MIDI__MidiEvent); + lv2_atom_forge_init(&dumper->forge, map); #define MANAGE_URI(uri) \ serd_nodes_manage(serd_world_nodes(world), \ serd_new_uri(SERD_STATIC_STRING(uri))) - writer->nodes.atom_Path = MANAGE_URI(LV2_ATOM__Path); - writer->nodes.atom_beatTime = MANAGE_URI(LV2_ATOM__beatTime); - writer->nodes.atom_childType = MANAGE_URI(LV2_ATOM__childType); - writer->nodes.atom_frameTime = MANAGE_URI(LV2_ATOM__frameTime); - writer->nodes.midi_MidiEvent = MANAGE_URI(LV2_MIDI__MidiEvent); - writer->nodes.rdf_first = MANAGE_URI(NS_RDF "first"); - writer->nodes.rdf_nil = MANAGE_URI(NS_RDF "nil"); - writer->nodes.rdf_rest = MANAGE_URI(NS_RDF "rest"); - writer->nodes.rdf_type = MANAGE_URI(NS_RDF "type"); - writer->nodes.rdf_value = MANAGE_URI(NS_RDF "value"); - writer->nodes.xsd_base64Binary = MANAGE_URI(NS_XSD "base64Binary"); - writer->nodes.xsd_boolean = MANAGE_URI(NS_XSD "boolean"); - writer->nodes.xsd_decimal = MANAGE_URI(NS_XSD "decimal"); - writer->nodes.xsd_double = MANAGE_URI(NS_XSD "double"); - writer->nodes.xsd_float = MANAGE_URI(NS_XSD "float"); - writer->nodes.xsd_int = MANAGE_URI(NS_XSD "int"); - writer->nodes.xsd_integer = MANAGE_URI(NS_XSD "integer"); - writer->nodes.xsd_long = MANAGE_URI(NS_XSD "long"); + dumper->nodes.atom_Path = MANAGE_URI(LV2_ATOM__Path); + dumper->nodes.atom_beatTime = MANAGE_URI(LV2_ATOM__beatTime); + dumper->nodes.atom_childType = MANAGE_URI(LV2_ATOM__childType); + dumper->nodes.atom_frameTime = MANAGE_URI(LV2_ATOM__frameTime); + dumper->nodes.midi_MidiEvent = MANAGE_URI(LV2_MIDI__MidiEvent); + dumper->nodes.rdf_first = MANAGE_URI(NS_RDF "first"); + dumper->nodes.rdf_nil = MANAGE_URI(NS_RDF "nil"); + dumper->nodes.rdf_rest = MANAGE_URI(NS_RDF "rest"); + dumper->nodes.rdf_type = MANAGE_URI(NS_RDF "type"); + dumper->nodes.rdf_value = MANAGE_URI(NS_RDF "value"); + dumper->nodes.xsd_base64Binary = MANAGE_URI(NS_XSD "base64Binary"); + dumper->nodes.xsd_boolean = MANAGE_URI(NS_XSD "boolean"); + dumper->nodes.xsd_decimal = MANAGE_URI(NS_XSD "decimal"); + dumper->nodes.xsd_double = MANAGE_URI(NS_XSD "double"); + dumper->nodes.xsd_float = MANAGE_URI(NS_XSD "float"); + dumper->nodes.xsd_int = MANAGE_URI(NS_XSD "int"); + dumper->nodes.xsd_integer = MANAGE_URI(NS_XSD "integer"); + dumper->nodes.xsd_long = MANAGE_URI(NS_XSD "long"); #undef MANAGE_URI - return writer; + return dumper; } void -sratom_dumper_free(SratomDumper* writer) +sratom_dumper_free(SratomDumper* const writer) { free(writer); } -static int +static SratomStatus write_atom(StreamContext* ctx, const SerdNode* subject, const SerdNode* predicate, @@ -147,15 +147,16 @@ write_atom(StreamContext* ctx, const void* body); static void -list_append(StreamContext* ctx, - SerdNode** s, - const SerdNode** p, - uint32_t size, - uint32_t type, - const void* body) +list_append(StreamContext* const ctx, + SerdNode** const s, + const SerdNode** const p, + const uint32_t size, + const uint32_t type, + const void* const body) { // Generate a list node - SerdNode* node = serd_node_copy(serd_world_get_blank(ctx->writer->world)); + SerdNode* const node = + serd_node_copy(serd_world_get_blank(ctx->writer->world)); serd_sink_write(ctx->sink, ctx->sflags, *s, *p, node, NULL); // _:node rdf:first value @@ -170,19 +171,20 @@ list_append(StreamContext* ctx, } static void -list_end(StreamContext* ctx, const SerdNode* s, const SerdNode* p) +list_end(const StreamContext* const ctx, + const SerdNode* const s, + const SerdNode* const p) { // _:node rdf:rest rdf:nil - serd_sink_write( - ctx->sink, ctx->sflags, s, p, ctx->writer->nodes.rdf_nil, NULL); + serd_sink_write(ctx->sink, 0, s, p, ctx->writer->nodes.rdf_nil, NULL); } static void -start_object(StreamContext* ctx, - const SerdNode* subject, - const SerdNode* predicate, - const SerdNode* node, - const char* type) +start_object(StreamContext* const ctx, + const SerdNode* const subject, + const SerdNode* const predicate, + const SerdNode* const node, + const char* const type) { if (subject && predicate) { serd_sink_write( @@ -192,7 +194,7 @@ start_object(StreamContext* ctx, } if (type) { - SerdNode* o = serd_new_uri(SERD_MEASURE_STRING(type)); + SerdNode* const o = serd_new_uri(SERD_MEASURE_STRING(type)); serd_sink_write( ctx->sink, ctx->sflags, node, ctx->writer->nodes.rdf_type, o, NULL); @@ -202,10 +204,10 @@ start_object(StreamContext* ctx, } static void -end_object(StreamContext* ctx, - const SerdNode* subject, - const SerdNode* predicate, - const SerdNode* node) +end_object(const StreamContext* const ctx, + const SerdNode* const subject, + const SerdNode* const predicate, + const SerdNode* const node) { if (subject && predicate) { serd_sink_write_end(ctx->sink, node); @@ -213,30 +215,33 @@ end_object(StreamContext* ctx, } static bool -path_is_absolute(const char* path) +path_is_absolute(const char* const path) { return (path[0] == '/' || (isalpha(path[0]) && path[1] == ':' && (path[2] == '/' || path[2] == '\\'))); } static const SerdNode* -number_type(StreamContext* ctx, const SerdNode* type) +number_type(const StreamContext* const ctx, const SerdNode* const type) { SratomDumper* const writer = ctx->writer; const bool pretty = (ctx->flags & SRATOM_PRETTY_NUMBERS); + if (pretty) { if (type == writer->nodes.xsd_int || type == writer->nodes.xsd_long) { return writer->nodes.xsd_integer; - } else if (type == writer->nodes.xsd_float || - type == writer->nodes.xsd_double) { + } + + if (type == writer->nodes.xsd_float || type == writer->nodes.xsd_double) { return writer->nodes.xsd_decimal; } } + return type; } static bool -is_primitive_type(StreamContext* ctx, const LV2_URID type) +is_primitive_type(const StreamContext* const ctx, const LV2_URID type) { SratomDumper* const writer = ctx->writer; return (!type || type == writer->forge.Bool || type == writer->forge.Double || @@ -246,20 +251,22 @@ is_primitive_type(StreamContext* ctx, const LV2_URID type) type == writer->forge.URI || type == writer->forge.URID); } -static int -write_atom(StreamContext* const ctx, - const SerdNode* subject, - const SerdNode* predicate, - const LV2_URID type, - const uint32_t size, - const void* const body) +static SratomStatus +write_atom(StreamContext* const ctx, + const SerdNode* const subject, + const SerdNode* const predicate, + const LV2_URID type, + const uint32_t size, + const void* const body) { - SratomDumper* writer = ctx->writer; - LV2_URID_Unmap* unmap = writer->unmap; - const SerdSink* sink = ctx->sink; - const SerdEnv* env = ctx->env; - const char* const type_uri = unmap->unmap(unmap->handle, type); - SerdNode* object = NULL; + SratomDumper* const writer = ctx->writer; + LV2_URID_Unmap* const unmap = writer->unmap; + const SerdSink* const sink = ctx->sink; + const SerdEnv* const env = ctx->env; + const char* const type_uri = unmap->unmap(unmap->handle, type); + SerdNode* object = NULL; + SratomStatus st = SRATOM_SUCCESS; + if (type == 0 && size == 0) { object = serd_node_copy(writer->nodes.rdf_nil); } else if (type == writer->forge.String) { @@ -281,7 +288,7 @@ write_atom(StreamContext* const ctx, object = serd_new_plain_literal(SERD_MEASURE_STRING(str), SERD_MEASURE_STRING(lang + prefix_len)); } else { - STREAM_ERRORF("Unknown language URID %u\n", lit->lang); + DUMP_ERRORF("Unknown language URID %u\n", lit->lang); } } } else if (type == writer->forge.URID) { @@ -296,8 +303,8 @@ write_atom(StreamContext* const ctx, } else { const SerdNode* base_uri = serd_env_base_uri(env); if (!base_uri || strncmp(serd_node_string(base_uri), "file://", 7)) { - STREAM_WARN("Relative path but base is not a file URI.\n"); - STREAM_WARN("Writing ambiguous atom:Path literal.\n"); + DUMP_WARN("Relative path but base is not a file URI.\n"); + DUMP_WARN("Writing ambiguous atom:Path literal.\n"); object = serd_new_typed_literal( str, serd_node_string_view(writer->nodes.atom_Path)); } else { @@ -341,8 +348,8 @@ write_atom(StreamContext* const ctx, free(str); } else if (type == writer->atom_Event) { - const LV2_Atom_Event* ev = (const LV2_Atom_Event*)body; - const SerdNode* id = serd_world_get_blank(writer->world); + const LV2_Atom_Event* const ev = (const LV2_Atom_Event*)body; + const SerdNode* const id = serd_world_get_blank(writer->world); start_object(ctx, subject, predicate, id, NULL); SerdNode* time = NULL; const SerdNode* p = NULL; @@ -362,28 +369,34 @@ write_atom(StreamContext* const ctx, ctx, id, p, ev->body.type, ev->body.size, LV2_ATOM_BODY_CONST(&ev->body)); end_object(ctx, subject, predicate, id); } else if (type == writer->forge.Tuple) { - SerdNode* id = serd_node_copy(serd_world_get_blank(writer->world)); + SerdNode* id = serd_node_copy(serd_world_get_blank(writer->world)); + const SerdNode* p = writer->nodes.rdf_value; start_object(ctx, subject, predicate, id, type_uri); - const SerdNode* p = writer->nodes.rdf_value; + ctx->sflags |= SERD_LIST_O | SERD_TERSE_O; LV2_ATOM_TUPLE_BODY_FOREACH (body, size, i) { if (!is_primitive_type(ctx, i->type)) { ctx->sflags &= ~SERD_TERSE_O; } } + LV2_ATOM_TUPLE_BODY_FOREACH (body, size, i) { list_append(ctx, &id, &p, i->size, i->type, LV2_ATOM_BODY(i)); } - list_end(ctx, id, p); + + serd_sink_write(ctx->sink, 0, id, p, ctx->writer->nodes.rdf_nil, NULL); end_object(ctx, subject, predicate, id); serd_node_free(id); } else if (type == writer->forge.Vector) { - const LV2_Atom_Vector_Body* vec = (const LV2_Atom_Vector_Body*)body; + const LV2_Atom_Vector_Body* const vec = (const LV2_Atom_Vector_Body*)body; + SerdNode* id = serd_node_copy(serd_world_get_blank(writer->world)); start_object(ctx, subject, predicate, id, type_uri); + const SerdNode* p = writer->nodes.atom_childType; - SerdNode* child_type = serd_new_uri( + SerdNode* const child_type = serd_new_uri( SERD_MEASURE_STRING(unmap->unmap(unmap->handle, vec->child_type))); + serd_sink_write(sink, ctx->sflags, id, p, child_type, NULL); p = writer->nodes.rdf_value; serd_node_free(child_type); @@ -391,16 +404,18 @@ write_atom(StreamContext* const ctx, if (is_primitive_type(ctx, vec->child_type)) { ctx->sflags |= SERD_TERSE_O; } + for (const char* i = (const char*)(vec + 1); i < (const char*)vec + size; i += vec->child_size) { list_append(ctx, &id, &p, vec->child_size, vec->child_type, i); } - list_end(ctx, id, p); + + serd_sink_write(ctx->sink, 0, id, p, ctx->writer->nodes.rdf_nil, NULL); end_object(ctx, subject, predicate, id); serd_node_free(id); } else if (lv2_atom_forge_is_object_type(&writer->forge, type)) { const LV2_Atom_Object_Body* obj = (const LV2_Atom_Object_Body*)body; - const char* otype = unmap->unmap(unmap->handle, obj->otype); + const char* const otype = unmap->unmap(unmap->handle, obj->otype); SerdNode* id = NULL; if (lv2_atom_forge_is_blank(&writer->forge, type, obj)) { @@ -414,7 +429,7 @@ write_atom(StreamContext* const ctx, } LV2_ATOM_OBJECT_BODY_FOREACH (obj, size, prop) { const char* const key = unmap->unmap(unmap->handle, prop->key); - SerdNode* pred = serd_new_uri(SERD_MEASURE_STRING(key)); + SerdNode* const pred = serd_new_uri(SERD_MEASURE_STRING(key)); write_atom(ctx, id, pred, @@ -454,18 +469,17 @@ write_atom(StreamContext* const ctx, } if (object) { - if (!subject && !predicate) { - subject = serd_world_get_blank(writer->world); - predicate = writer->nodes.rdf_first; + if (!subject || !predicate) { + const SerdNode* const blank = serd_world_get_blank(writer->world); serd_sink_write(sink, ctx->sflags | SERD_LIST_S | SERD_TERSE_S, - subject, - predicate, + blank, + writer->nodes.rdf_first, object, NULL); serd_sink_write(sink, SERD_TERSE_S, - subject, + blank, writer->nodes.rdf_rest, writer->nodes.rdf_nil, NULL); @@ -476,10 +490,10 @@ write_atom(StreamContext* const ctx, serd_node_free(object); - return 0; + return st; } -int +SratomStatus sratom_dump(SratomDumper* const writer, const SerdEnv* const env, const SerdSink* const sink, @@ -500,7 +514,7 @@ sratom_dump(SratomDumper* const writer, return write_atom(&ctx, subject, predicate, type, size, body); } -int +SratomStatus sratom_dump_atom(SratomDumper* const writer, const SerdEnv* const env, const SerdSink* const sink, diff --git a/src/loader.c b/src/loader.c index 46e7c51..46a23f3 100644 --- a/src/loader.c +++ b/src/loader.c @@ -23,7 +23,6 @@ #include "serd/serd.h" #include -#include #include #include #include @@ -37,6 +36,17 @@ typedef enum { MODE_SUBJECT, MODE_BODY, MODE_SEQUENCE } ReadMode; +typedef struct { + const SerdNode* atom_beatTime; + const SerdNode* atom_childType; + const SerdNode* atom_frameTime; + const SerdNode* rdf_first; + const SerdNode* rdf_rest; + const SerdNode* rdf_type; + const SerdNode* rdf_value; + const SerdNode* xsd_base64Binary; +} LoaderNodes; + struct SratomLoaderImpl { LV2_URID_Map* map; LV2_Atom_Forge forge; @@ -44,25 +54,16 @@ struct SratomLoaderImpl { LV2_URID atom_frameTime; LV2_URID atom_beatTime; LV2_URID midi_MidiEvent; - struct { - const SerdNode* atom_beatTime; - const SerdNode* atom_childType; - const SerdNode* atom_frameTime; - const SerdNode* rdf_first; - const SerdNode* rdf_rest; - const SerdNode* rdf_type; - const SerdNode* rdf_value; - const SerdNode* xsd_base64Binary; - } nodes; + LoaderNodes nodes; }; typedef struct { - SratomLoader* loader; - const SerdNode* base_uri; - LV2_URID seq_unit; + SratomLoader* SERD_NONNULL loader; + const SerdNode* SERD_NONNULL base_uri; + LV2_URID seq_unit; } LoadContext; -static void +static SratomStatus read_node(LoadContext* ctx, LV2_Atom_Forge* forge, const SerdModel* model, @@ -70,55 +71,58 @@ read_node(LoadContext* ctx, ReadMode mode); SratomLoader* -sratom_loader_new(SerdWorld* world, LV2_URID_Map* map) +sratom_loader_new(SerdWorld* const world, LV2_URID_Map* const map) { - SratomLoader* sratom = (SratomLoader*)calloc(1, sizeof(SratomLoader)); - if (!sratom) { + SratomLoader* const loader = (SratomLoader*)calloc(1, sizeof(SratomLoader)); + if (!loader) { return NULL; } - sratom->world = world; - sratom->map = map; - sratom->atom_frameTime = map->map(map->handle, LV2_ATOM__frameTime); - sratom->atom_beatTime = map->map(map->handle, LV2_ATOM__beatTime); - sratom->midi_MidiEvent = map->map(map->handle, LV2_MIDI__MidiEvent); - lv2_atom_forge_init(&sratom->forge, map); + loader->world = world; + loader->map = map; + loader->atom_frameTime = map->map(map->handle, LV2_ATOM__frameTime); + loader->atom_beatTime = map->map(map->handle, LV2_ATOM__beatTime); + loader->midi_MidiEvent = map->map(map->handle, LV2_MIDI__MidiEvent); + + lv2_atom_forge_init(&loader->forge, map); #define MANAGE_URI(uri) \ serd_nodes_manage(serd_world_nodes(world), \ serd_new_uri(SERD_STATIC_STRING(uri))) - sratom->nodes.atom_beatTime = MANAGE_URI(LV2_ATOM__beatTime); - sratom->nodes.atom_childType = MANAGE_URI(LV2_ATOM__childType); - sratom->nodes.atom_frameTime = MANAGE_URI(LV2_ATOM__frameTime); - sratom->nodes.rdf_first = MANAGE_URI(NS_RDF "first"); - sratom->nodes.rdf_rest = MANAGE_URI(NS_RDF "rest"); - sratom->nodes.rdf_type = MANAGE_URI(NS_RDF "type"); - sratom->nodes.rdf_value = MANAGE_URI(NS_RDF "value"); - sratom->nodes.xsd_base64Binary = MANAGE_URI(NS_XSD "base64Binary"); + loader->nodes.atom_beatTime = MANAGE_URI(LV2_ATOM__beatTime); + loader->nodes.atom_childType = MANAGE_URI(LV2_ATOM__childType); + loader->nodes.atom_frameTime = MANAGE_URI(LV2_ATOM__frameTime); + loader->nodes.rdf_first = MANAGE_URI(NS_RDF "first"); + loader->nodes.rdf_rest = MANAGE_URI(NS_RDF "rest"); + loader->nodes.rdf_type = MANAGE_URI(NS_RDF "type"); + loader->nodes.rdf_value = MANAGE_URI(NS_RDF "value"); + loader->nodes.xsd_base64Binary = MANAGE_URI(NS_XSD "base64Binary"); -#undef INTERN_URI +#undef MANAGE_URI - return sratom; + return loader; } void -sratom_loader_free(SratomLoader* loader) +sratom_loader_free(SratomLoader* const loader) { free(loader); } static void -read_list_value(LoadContext* ctx, - LV2_Atom_Forge* forge, - const SerdModel* model, - const SerdNode* node, - ReadMode mode) +read_list_value(LoadContext* const ctx, + LV2_Atom_Forge* const forge, + const SerdModel* const model, + const SerdNode* const node, + const ReadMode mode) { - const SerdNode* fst = + const SerdNode* const fst = serd_model_get(model, node, ctx->loader->nodes.rdf_first, NULL, NULL); - const SerdNode* rst = + + const SerdNode* const rst = serd_model_get(model, node, ctx->loader->nodes.rdf_rest, NULL, NULL); + if (fst && rst) { read_node(ctx, forge, model, fst, mode); read_list_value(ctx, forge, model, rst, mode); @@ -126,21 +130,21 @@ read_list_value(LoadContext* ctx, } static void -read_resource(LoadContext* ctx, - LV2_Atom_Forge* forge, - const SerdModel* model, - const SerdNode* node, - LV2_URID otype) +read_resource(LoadContext* const ctx, + LV2_Atom_Forge* const forge, + const SerdModel* const model, + const SerdNode* const node, + const LV2_URID otype) { - LV2_URID_Map* map = ctx->loader->map; - SerdRange* r = serd_model_range(model, node, NULL, NULL, NULL); + LV2_URID_Map* const map = ctx->loader->map; + SerdRange* const r = serd_model_range(model, node, NULL, NULL, NULL); for (; !serd_range_empty(r); serd_range_next(r)) { const SerdStatement* match = serd_range_front(r); - const SerdNode* p = serd_statement_predicate(match); - const SerdNode* o = serd_statement_object(match); - if (p) { - const char* p_uri = serd_node_string(p); - uint32_t p_urid = map->map(map->handle, p_uri); + if (match) { + const SerdNode* const p = serd_statement_predicate(match); + const SerdNode* const o = serd_statement_object(match); + const char* const p_uri = serd_node_string(p); + const uint32_t p_urid = map->map(map->handle, p_uri); if (!(serd_node_equals(p, ctx->loader->nodes.rdf_type) && serd_node_type(o) == SERD_URI && map->map(map->handle, serd_node_string(o)) == otype)) { @@ -153,146 +157,184 @@ read_resource(LoadContext* ctx, } static uint32_t -atom_size(SratomLoader* loader, uint32_t type_urid) +atom_size(SratomLoader* const loader, const uint32_t type_urid) { - if (type_urid == loader->forge.Int) { + if (type_urid == loader->forge.Int || type_urid == loader->forge.Bool) { return sizeof(int32_t); - } else if (type_urid == loader->forge.Long) { + } + + if (type_urid == loader->forge.URID) { + return sizeof(uint32_t); + } + + if (type_urid == loader->forge.Long) { return sizeof(int64_t); - } else if (type_urid == loader->forge.Float) { + } + + if (type_urid == loader->forge.Float) { return sizeof(float); - } else if (type_urid == loader->forge.Double) { + } + + if (type_urid == loader->forge.Double) { return sizeof(double); - } else if (type_urid == loader->forge.Bool) { - return sizeof(int32_t); - } else if (type_urid == loader->forge.URID) { - return sizeof(uint32_t); } + return 0; } -static void -read_uri(LoadContext* ctx, LV2_Atom_Forge* forge, const SerdNode* node) +static SratomStatus +read_uri(LoadContext* const ctx, + LV2_Atom_Forge* const forge, + const SerdNode* const node) { SratomLoader* const loader = ctx->loader; LV2_URID_Map* const map = loader->map; const char* const str = serd_node_string(node); + LV2_Atom_Forge_Ref ref = 0; if (!strcmp(str, NS_RDF "nil")) { - lv2_atom_forge_atom(forge, 0, 0); + ref = lv2_atom_forge_atom(forge, 0, 0); } else if (!strncmp(str, "file://", 7)) { - const SerdURIView base_uri = serd_node_uri_view(ctx->base_uri); - const SerdURIView uri = serd_parse_uri(str); - if (serd_uri_is_within(uri, base_uri)) { + const SerdURIView uri = serd_parse_uri(str); + if (ctx->base_uri && + serd_uri_is_within(uri, serd_node_uri_view(ctx->base_uri))) { SerdNode* const rel = serd_new_parsed_uri(serd_relative_uri( serd_parse_uri(str), serd_node_uri_view(ctx->base_uri))); - char* path = serd_parse_file_uri(serd_node_string(rel), NULL); - lv2_atom_forge_path(forge, path, strlen(path)); + char* const path = serd_parse_file_uri(serd_node_string(rel), NULL); + if (!path) { + return SRATOM_BAD_FILE_URI; + } + + ref = lv2_atom_forge_path(forge, path, strlen(path)); serd_free(path); serd_node_free(rel); } else { char* const path = serd_parse_file_uri(str, NULL); - lv2_atom_forge_path(forge, path, strlen(path)); + if (!path) { + return SRATOM_BAD_FILE_URI; + } + + ref = lv2_atom_forge_path(forge, path, strlen(path)); serd_free(path); } } else { - lv2_atom_forge_urid(forge, map->map(map->handle, str)); + ref = lv2_atom_forge_urid(forge, map->map(map->handle, str)); } + + return ref ? SRATOM_SUCCESS : SRATOM_BAD_FORGE; } -static void +static SratomStatus read_typed_literal(SratomLoader* const loader, LV2_Atom_Forge* const forge, const SerdNode* const node, const SerdNode* const datatype) { - const char* const str = serd_node_string(node); - const size_t len = serd_node_length(node); - const char* const type_uri = serd_node_string(datatype); + const char* const str = serd_node_string(node); + const size_t len = serd_node_length(node); + const char* const type_uri = serd_node_string(datatype); + LV2_Atom_Forge_Ref ref = 0; if (!strcmp(type_uri, NS_XSD "int") || !strcmp(type_uri, NS_XSD "integer")) { - lv2_atom_forge_int(forge, strtol(str, NULL, 10)); + ref = lv2_atom_forge_int(forge, strtol(str, NULL, 10)); } else if (!strcmp(type_uri, NS_XSD "long")) { - lv2_atom_forge_long(forge, strtol(str, NULL, 10)); - } else if (!strcmp(type_uri, NS_XSD "float") || - !strcmp(type_uri, NS_XSD "decimal")) { - lv2_atom_forge_float(forge, serd_get_float(node)); - } else if (!strcmp(type_uri, NS_XSD "double")) { - lv2_atom_forge_double(forge, serd_get_double(node)); + ref = lv2_atom_forge_long(forge, strtol(str, NULL, 10)); + } else if (!strcmp(type_uri, NS_XSD "decimal") || + !strcmp(type_uri, NS_XSD "double")) { + ref = lv2_atom_forge_double(forge, serd_get_double(node)); + } else if (!strcmp(type_uri, NS_XSD "float")) { + ref = lv2_atom_forge_float(forge, serd_get_float(node)); } else if (!strcmp(type_uri, NS_XSD "boolean")) { - lv2_atom_forge_bool(forge, serd_get_boolean(node)); + ref = lv2_atom_forge_bool(forge, serd_get_boolean(node)); } else if (!strcmp(type_uri, NS_XSD "base64Binary")) { - size_t size = 0; - void* body = serd_base64_decode(str, len, &size); - lv2_atom_forge_atom(forge, size, forge->Chunk); - lv2_atom_forge_write(forge, body, size); + size_t size = 0; + void* const body = serd_base64_decode(str, len, &size); + if ((ref = lv2_atom_forge_atom(forge, size, forge->Chunk))) { + ref = lv2_atom_forge_write(forge, body, size); + } free(body); } else if (!strcmp(type_uri, LV2_ATOM__Path)) { - lv2_atom_forge_path(forge, str, len); + ref = lv2_atom_forge_path(forge, str, len); } else if (!strcmp(type_uri, LV2_MIDI__MidiEvent)) { - lv2_atom_forge_atom(forge, len / 2, loader->midi_MidiEvent); - for (const char* s = str; s < str + len; s += 2) { - unsigned num; - sscanf(s, "%2X", &num); - const uint8_t c = num; - lv2_atom_forge_raw(forge, &c, 1); + if ((ref = lv2_atom_forge_atom(forge, len / 2, loader->midi_MidiEvent))) { + for (const char* s = str; s < str + len; s += 2) { + unsigned num = 0u; + sscanf(s, "%2X", &num); + const uint8_t c = num; + if (!(ref = lv2_atom_forge_raw(forge, &c, 1))) { + return SRATOM_BAD_FORGE; + } + } + lv2_atom_forge_pad(forge, len / 2); } - lv2_atom_forge_pad(forge, len / 2); } else { - lv2_atom_forge_literal( + ref = lv2_atom_forge_literal( forge, str, len, loader->map->map(loader->map->handle, type_uri), 0); } + + return ref ? SRATOM_SUCCESS : SRATOM_BAD_FORGE; } -static void +static SratomStatus read_plain_literal(SratomLoader* const loader, LV2_Atom_Forge* const forge, const SerdNode* const node, const SerdNode* const language) { - const char* const str = serd_node_string(node); - const size_t len = serd_node_length(node); - const char* lang_str = serd_node_string(language); - const char* prefix = "http://lexvo.org/id/iso639-3/"; - const size_t lang_len = strlen(prefix) + strlen(lang_str); - char* const lang_uri = (char*)calloc(lang_len + 1, 1); + static const char* const prefix = "http://lexvo.org/id/iso639-3/"; + + const char* const str = serd_node_string(node); + const size_t len = serd_node_length(node); + const char* lang_str = serd_node_string(language); + const size_t prefix_len = strlen(prefix); + const size_t lang_len = prefix_len + strlen(lang_str); + char* const lang_uri = (char*)calloc(lang_len + 1, 1); snprintf(lang_uri, lang_len + 1, "%s%s", prefix, lang_str); - lv2_atom_forge_literal( + const LV2_Atom_Forge_Ref ref = lv2_atom_forge_literal( forge, str, len, 0, loader->map->map(loader->map->handle, lang_uri)); free(lang_uri); + + return ref ? SRATOM_SUCCESS : SRATOM_BAD_FORGE; } -static void -read_literal(SratomLoader* loader, LV2_Atom_Forge* forge, const SerdNode* node) +static SratomStatus +read_literal(SratomLoader* const loader, + LV2_Atom_Forge* const forge, + const SerdNode* const node) { assert(serd_node_type(node) == SERD_LITERAL); const SerdNode* const datatype = serd_node_datatype(node); - const SerdNode* const language = serd_node_language(node); if (datatype) { - read_typed_literal(loader, forge, node, datatype); - } else if (language) { - read_plain_literal(loader, forge, node, language); - } else { - lv2_atom_forge_string( - forge, serd_node_string(node), serd_node_length(node)); + return read_typed_literal(loader, forge, node, datatype); + } + + const SerdNode* const language = serd_node_language(node); + if (language) { + return read_plain_literal(loader, forge, node, language); } + + const LV2_Atom_Forge_Ref ref = lv2_atom_forge_string( + forge, serd_node_string(node), serd_node_length(node)); + + return ref ? SRATOM_SUCCESS : SRATOM_BAD_FORGE; } -static void -read_object(LoadContext* ctx, - LV2_Atom_Forge* forge, - const SerdModel* model, - const SerdNode* node, - ReadMode mode) +static SratomStatus +read_object(LoadContext* const ctx, + LV2_Atom_Forge* const forge, + const SerdModel* const model, + const SerdNode* const node, + const ReadMode mode) { SratomLoader* const loader = ctx->loader; LV2_URID_Map* const map = loader->map; const char* const str = serd_node_string(node); + SratomStatus st = SRATOM_SUCCESS; const SerdNode* const type = serd_model_get(model, node, loader->nodes.rdf_type, NULL, NULL); @@ -336,7 +378,7 @@ read_object(LoadContext* ctx, ctx->seq_unit = 0; read_list_value(ctx, forge, model, value, MODE_SEQUENCE); - LV2_Atom_Sequence* seq = + LV2_Atom_Sequence* const seq = (LV2_Atom_Sequence*)lv2_atom_forge_deref(forge, ref); seq->body.unit = ((ctx->seq_unit == loader->atom_frameTime) ? 0 : ctx->seq_unit); @@ -344,9 +386,13 @@ read_object(LoadContext* ctx, } else if (type_urid == loader->forge.Vector) { const SerdNode* child_type_node = serd_model_get(model, node, loader->nodes.atom_childType, NULL, NULL); - uint32_t child_type = + if (!child_type_node) { + return SRATOM_BAD_VECTOR; + } + + const uint32_t child_type = map->map(map->handle, serd_node_string(child_type_node)); - uint32_t child_size = atom_size(loader, child_type); + const uint32_t child_size = atom_size(loader, child_type); if (child_size > 0) { LV2_Atom_Forge_Ref ref = lv2_atom_forge_vector_head(forge, &frame, child_size, child_type); @@ -358,10 +404,10 @@ read_object(LoadContext* ctx, } else if (value && serd_node_equals(serd_node_datatype(value), loader->nodes.xsd_base64Binary)) { - const char* vstr = serd_node_string(value); - const size_t vlen = serd_node_length(value); - size_t size = 0; - void* body = serd_base64_decode(vstr, vlen, &size); + const char* const vstr = serd_node_string(value); + const size_t vlen = serd_node_length(value); + size_t size = 0; + void* body = serd_base64_decode(vstr, vlen, &size); lv2_atom_forge_atom(forge, size, type_urid); lv2_atom_forge_write(forge, body, size); free(body); @@ -372,7 +418,7 @@ read_object(LoadContext* ctx, lv2_atom_forge_object(forge, &frame, urid, type_urid); read_resource(ctx, forge, model, node, type_urid); } else { - read_uri(ctx, forge, node); + st = read_uri(ctx, forge, node); } } else { @@ -383,41 +429,46 @@ read_object(LoadContext* ctx, if (frame.ref) { lv2_atom_forge_pop(forge, &frame); } + + return st; } -static void -read_node(LoadContext* ctx, - LV2_Atom_Forge* forge, - const SerdModel* model, - const SerdNode* node, - ReadMode mode) +static SratomStatus +read_node(LoadContext* const ctx, + LV2_Atom_Forge* const forge, + const SerdModel* const model, + const SerdNode* const node, + const ReadMode mode) { if (serd_node_type(node) == SERD_LITERAL) { - read_literal(ctx->loader, forge, node); - } else if (serd_node_type(node) == SERD_URI && mode != MODE_SUBJECT) { - read_uri(ctx, forge, node); - } else { - read_object(ctx, forge, model, node, mode); + return read_literal(ctx->loader, forge, node); } + + if (serd_node_type(node) == SERD_URI && mode != MODE_SUBJECT) { + return read_uri(ctx, forge, node); + } + + return read_object(ctx, forge, model, node, mode); } -int -sratom_load(SratomLoader* loader, - const SerdNode* base_uri, - LV2_Atom_Forge* forge, - const SerdModel* model, - const SerdNode* node) +SratomStatus +sratom_load(SratomLoader* const loader, + const SerdNode* const base_uri, + LV2_Atom_Forge* const forge, + const SerdModel* const model, + const SerdNode* const node) { LoadContext ctx = {loader, base_uri, 0}; - read_node(&ctx, forge, model, node, MODE_SUBJECT); - return 0; + return read_node(&ctx, forge, model, node, MODE_SUBJECT); } static SerdModel* -model_from_string(SratomLoader* loader, SerdEnv* env, const char* str) +model_from_string(SratomLoader* const loader, + SerdEnv* const env, + const char* const str) { SerdModel* const model = serd_model_new(loader->world, SERD_INDEX_SPO); - SerdSink* const inserter = serd_inserter_new(model, env, NULL); + SerdSink* const inserter = serd_inserter_new(model, NULL); SerdNode* const name = serd_new_string(SERD_STATIC_STRING("string")); SerdByteSource* const source = serd_byte_source_new_string(str, name); @@ -446,15 +497,17 @@ sratom_from_string(SratomLoader* const loader, SerdEnv* const env, const char* const str) { - SerdModel* model = model_from_string(loader, env, str); + SerdModel* const model = model_from_string(loader, env, str); if (!model || serd_model_empty(model)) { LOAD_ERROR("Failed to read string into model"); return NULL; } - const SerdNode* node = NULL; - SerdIter* begin = serd_model_begin(model); - const SerdStatement* s = serd_iter_get(begin); + const SerdNode* node = NULL; + SerdIter* const begin = serd_model_begin(model); + const SerdStatement* const s = serd_iter_get(begin); + + assert(s); if (serd_model_size(model) == 2 && serd_node_type(serd_statement_subject(s)) == SERD_BLANK && serd_node_equals(serd_statement_predicate(s), loader->nodes.rdf_first)) { @@ -478,28 +531,31 @@ sratom_from_string(SratomLoader* const loader, } static LV2_Atom_Forge_Ref -sratom_forge_sink(LV2_Atom_Forge_Sink_Handle handle, - const void* buf, - uint32_t size) +sratom_forge_sink(const LV2_Atom_Forge_Sink_Handle handle, + const void* const buf, + const uint32_t size) { - SerdBuffer* chunk = (SerdBuffer*)handle; + SerdBuffer* const chunk = (SerdBuffer*)handle; const LV2_Atom_Forge_Ref ref = chunk->len + 1; + serd_buffer_sink(buf, 1, size, chunk); return ref; } static LV2_Atom* -sratom_forge_deref(LV2_Atom_Forge_Sink_Handle handle, LV2_Atom_Forge_Ref ref) +sratom_forge_deref(const LV2_Atom_Forge_Sink_Handle handle, + const LV2_Atom_Forge_Ref ref) { - SerdBuffer* chunk = (SerdBuffer*)handle; + SerdBuffer* const chunk = (SerdBuffer*)handle; + return (LV2_Atom*)((char*)chunk->buf + ref - 1); } LV2_Atom* -sratom_from_model(SratomLoader* loader, - const SerdNode* base_uri, - const SerdModel* model, - const SerdNode* subject) +sratom_from_model(SratomLoader* const loader, + const SerdNode* const base_uri, + const SerdModel* const model, + const SerdNode* const subject) { if (!subject) { return NULL; -- cgit v1.2.1