diff options
-rw-r--r-- | sratom/sratom.h | 35 | ||||
-rw-r--r-- | src/sratom.c | 32 | ||||
-rw-r--r-- | tests/sratom_test.c | 3 |
3 files changed, 59 insertions, 11 deletions
diff --git a/sratom/sratom.h b/sratom/sratom.h index 046210a..8183be0 100644 --- a/sratom/sratom.h +++ b/sratom/sratom.h @@ -62,6 +62,31 @@ extern "C" { typedef struct SratomImpl Sratom; /** + Mode for reading resources to LV2 Objects. + + This affects how resources (which are either blank nodes or have URIs) are + read by sratom_read(), since they may be read as simple references (a URI or + blank node ID) or a complete description (an atom "Object"). + + Currently, blank nodes are always read as Objects, but support for reading + blank node IDs may be added in the future. +*/ +typedef enum { + /** + Read blank nodes as Objects, and named resources as URIs. + */ + SRATOM_OBJECT_MODE_BLANK, + + /** + Read blank nodes and the main subject as Objects, and any other named + resources as URIs. The "main subject" is the subject parameter passed + to sratom_read(); if this is a resource it will be read as an Object, + but all other named resources encountered will be read as URIs. + */ + SRATOM_OBJECT_MODE_BLANK_SUBJECT, +} SratomObjectMode; + +/** Create a new Atom serialiser. */ SRATOM_API @@ -101,6 +126,14 @@ sratom_set_pretty_numbers(Sratom* sratom, bool pretty_numbers); /** + Configure how resources will be read to form LV2 Objects. +*/ +SRATOM_API +void +sratom_set_object_mode(Sratom* sratom, + SratomObjectMode object_mode); + +/** Write an Atom to RDF. The serialised atom is written to the sink set by sratom_set_sink(). @return 0 on success, or a non-zero error code otherwise. @@ -126,7 +159,7 @@ sratom_read(Sratom* sratom, LV2_Atom_Forge* forge, SordWorld* world, SordModel* model, - const SordNode* node); + const SordNode* subject); /** Serialise an Atom to a Turtle string. diff --git a/src/sratom.c b/src/sratom.c index 8c17de9..93b962e 100644 --- a/src/sratom.c +++ b/src/sratom.c @@ -47,6 +47,7 @@ struct SratomImpl { SerdStatementSink write_statement; SerdEndSink end_anon; void* handle; + SratomObjectMode object_mode; bool pretty_numbers; struct { SordNode* atom_childType; @@ -77,6 +78,7 @@ sratom_new(LV2_URID_Map* map) sratom->midi_MidiEvent = map->map(map->handle, LV2_MIDI__MidiEvent); sratom->next_id = 0; sratom->base_uri = SERD_NODE_NULL; + sratom->object_mode = SRATOM_OBJECT_MODE_BLANK; sratom->pretty_numbers = false; memset(&sratom->nodes, 0, sizeof(sratom->nodes)); lv2_atom_forge_init(&sratom->forge, map); @@ -116,6 +118,14 @@ sratom_set_pretty_numbers(Sratom* sratom, sratom->pretty_numbers = pretty_numbers; } +SRATOM_API +void +sratom_set_object_mode(Sratom* sratom, + SratomObjectMode object_mode) +{ + sratom->object_mode = object_mode; +} + static void gensym(SerdNode* out, char c, unsigned num) { @@ -310,7 +320,7 @@ sratom_write(Sratom* sratom, USTR(LV2_ATOM__frameTime)); datatype = serd_node_from_string(SERD_URI, NS_XSD "decimal"); sratom->write_statement(sratom->handle, SERD_ANON_CONT, NULL, - &id, &p, &time, &datatype, &language); + &id, &p, &time, &datatype, &language); serd_node_free(&time); p = serd_node_from_string(SERD_URI, NS_RDF "value"); @@ -407,7 +417,7 @@ sratom_write(Sratom* sratom, if (object.buf) { sratom->write_statement(sratom->handle, flags, NULL, - subject, predicate, &object, &datatype, &language); + subject, predicate, &object, &datatype, &language); } if (new_node) { @@ -507,12 +517,12 @@ read_resource(Sratom* sratom, SordModel* model, const SordNode* node, LV2_URID otype) -{ +{ LV2_URID_Map* map = sratom->map; SordQuad q = { node, NULL, NULL, NULL }; SordIter* i = sord_find(model, q); SordQuad match; - for (;!sord_iter_end(i); sord_iter_next(i)) { + for (; !sord_iter_end(i); sord_iter_next(i)) { sord_iter_get(i, match); const SordNode* p = match[SORD_PREDICATE]; const SordNode* o = match[SORD_OBJECT]; @@ -613,7 +623,9 @@ read_node(Sratom* sratom, } else { lv2_atom_forge_string(forge, str, len); } - } else if (sord_node_get_type(node) == SORD_URI && mode == MODE_BODY) { + } else if (sord_node_get_type(node) == SORD_URI && + !(sratom->object_mode == SRATOM_OBJECT_MODE_BLANK_SUBJECT + && mode == MODE_SUBJECT)) { if (!strcmp(str, (const char*)NS_RDF "nil")) { lv2_atom_forge_atom(forge, 0, 0); } else if (!strncmp(str, "file://", 7)) { @@ -635,11 +647,7 @@ read_node(Sratom* sratom, } LV2_Atom_Forge_Frame frame = { 0, 0 }; - if (mode == MODE_SUBJECT && sord_node_get_type(node) == SORD_URI) { - lv2_atom_forge_resource( - forge, &frame, map->map(map->handle, str), type_urid); - read_resource(sratom, forge, world, model, node, type_urid); - } else if (mode == MODE_SEQUENCE) { + if (mode == MODE_SEQUENCE) { const SordNode* frame_time = get_object( model, node, sratom->nodes.atom_frameTime); const char* frame_time_str = frame_time @@ -672,6 +680,10 @@ read_node(Sratom* sratom, lv2_atom_forge_atom(forge, size, type_urid); lv2_atom_forge_write(forge, body, size); free(body); + } else if (sord_node_get_type(node) == SORD_URI) { + lv2_atom_forge_resource( + forge, &frame, map->map(map->handle, str), type_urid); + read_resource(sratom, forge, world, model, node, type_urid); } else { lv2_atom_forge_blank(forge, &frame, sratom->next_id++, type_urid); read_resource(sratom, forge, world, model, node, type_urid); diff --git a/tests/sratom_test.c b/tests/sratom_test.c index f9235bc..42020b8 100644 --- a/tests/sratom_test.c +++ b/tests/sratom_test.c @@ -84,6 +84,9 @@ test(bool top_level) lv2_atom_forge_init(&forge, &map); Sratom* sratom = sratom_new(&map); + sratom_set_object_mode( + sratom, + top_level ? SRATOM_OBJECT_MODE_BLANK_SUBJECT : SRATOM_OBJECT_MODE_BLANK); LV2_URID eg_Object = urid_map(NULL, "http://example.org/Object"); LV2_URID eg_one = urid_map(NULL, "http://example.org/a-one"); |