From 6e4c4ee8a1fccebedf48b750151a258a559fc50b Mon Sep 17 00:00:00 2001 From: David Robillard Date: Thu, 23 Feb 2012 04:21:30 +0000 Subject: atom_to_rdf.c => sratom.c git-svn-id: http://svn.drobilla.net/lad/trunk/sratom@3999 a436a847-0d15-0410-975c-d299462d15a1 --- src/atom_to_rdf.c | 348 ------------------------------------------------------ src/sratom.c | 348 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 348 insertions(+), 348 deletions(-) delete mode 100644 src/atom_to_rdf.c create mode 100644 src/sratom.c (limited to 'src') diff --git a/src/atom_to_rdf.c b/src/atom_to_rdf.c deleted file mode 100644 index f919f89..0000000 --- a/src/atom_to_rdf.c +++ /dev/null @@ -1,348 +0,0 @@ -/* - Copyright 2012 David Robillard - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ - -#include -#include -#include - -#include "lv2/lv2plug.in/ns/ext/atom/forge.h" -#include "lv2/lv2plug.in/ns/ext/atom/util.h" - -#include "sratom/sratom.h" - -#define NS_RDF (const uint8_t*)"http://www.w3.org/1999/02/22-rdf-syntax-ns#" -#define NS_XSD (const uint8_t*)"http://www.w3.org/2001/XMLSchema#" -#define NS_MIDI (const uint8_t*)"http://lv2plug.in/ns/ext/midi#" - -#define USTR(str) ((const uint8_t*)(str)) - -struct SratomImpl { - SerdWriter* writer; - LV2_URID_Map* map; - LV2_URID_Unmap* unmap; - LV2_Atom_Forge forge; - LV2_URID atom_Event; - LV2_URID midi_MidiEvent; - unsigned next_id; -}; - -SRATOM_API -Sratom* -sratom_new(LV2_URID_Map* map, - LV2_URID_Unmap* unmap) -{ - Sratom* sratom = (Sratom*)malloc(sizeof(Sratom)); - sratom->writer = NULL; - sratom->map = map; - sratom->unmap = unmap; - sratom->atom_Event = map->map(map->handle, LV2_ATOM_URI "#Event"); - sratom->midi_MidiEvent = map->map(map->handle, (const char*)NS_MIDI "MidiEvent"); - sratom->next_id = 0; - lv2_atom_forge_init(&sratom->forge, map); - return sratom; -} - -SRATOM_API -void -sratom_free(Sratom* sratom) -{ - free(sratom); -} - -typedef struct { - char* buf; - size_t len; -} String; - -static size_t -string_sink(const void* buf, size_t len, void* stream) -{ - String* str = (String*)stream; - str->buf = realloc(str->buf, str->len + len); - memcpy(str->buf + str->len, buf, len); - str->len += len; - return len; -} - -static void -gensym(SerdNode* out, char c, unsigned num) -{ - out->n_bytes = out->n_chars = snprintf( - (char*)out->buf, 10, "%c%u", c, num); -} - -static void -list_append(Sratom* sratom, - unsigned* flags, - SerdNode* s, - SerdNode* p, - SerdNode* node, - uint32_t type, - uint32_t size, - void* body) -{ - // Generate a list node - gensym(node, 'l', sratom->next_id); - serd_writer_write_statement(sratom->writer, *flags, NULL, - s, p, node, NULL, NULL); - - // _:node rdf:first value - *flags = SERD_LIST_CONT; - *p = serd_node_from_string(SERD_URI, NS_RDF "first"); - sratom_write(sratom, SERD_LIST_CONT, node, p, type, size, body); - - // Set subject to node and predicate to rdf:rest for next time - gensym(node, 'l', ++sratom->next_id); - *s = *node; - *p = serd_node_from_string(SERD_URI, NS_RDF "rest"); -} - -static void -list_end(SerdWriter* writer, unsigned* flags, SerdNode* s, SerdNode* p) -{ - // _:node rdf:rest rdf:nil - const SerdNode nil = serd_node_from_string(SERD_URI, NS_RDF "nil"); - serd_writer_write_statement(writer, *flags, NULL, - s, p, &nil, NULL, NULL); -} - -static void -start_object(Sratom* sratom, - uint32_t flags, - const SerdNode* subject, - const SerdNode* predicate, - const SerdNode* node, - const char* type) -{ - serd_writer_write_statement( - sratom->writer, flags|SERD_ANON_O_BEGIN, NULL, - subject, predicate, node, NULL, NULL); - if (type) { - SerdNode p = serd_node_from_string(SERD_URI, NS_RDF "type"); - SerdNode o = serd_node_from_string(SERD_URI, USTR(type)); - serd_writer_write_statement( - sratom->writer, SERD_ANON_CONT, NULL, - node, &p, &o, NULL, NULL); - } -} - -SRATOM_API -void -sratom_write(Sratom* sratom, - uint32_t flags, - const SerdNode* subject, - const SerdNode* predicate, - uint32_t type_urid, - uint32_t size, - const void* body) -{ - LV2_URID_Unmap* unmap = sratom->unmap; - const char* const type = unmap->unmap(unmap->handle, type_urid); - uint8_t idbuf[12] = "b0000000000"; - SerdNode id = serd_node_from_string(SERD_BLANK, idbuf); - uint8_t nodebuf[12] = "b0000000000"; - SerdNode node = serd_node_from_string(SERD_BLANK, nodebuf); - SerdNode object = SERD_NODE_NULL; - SerdNode datatype = SERD_NODE_NULL; - SerdNode language = SERD_NODE_NULL; - bool new_node = false; - if (type_urid == 0 && size == 0) { - object = serd_node_from_string(SERD_BLANK, USTR("null")); - } else if (type_urid == sratom->forge.String) { - object = serd_node_from_string(SERD_LITERAL, (const uint8_t*)body); - } else if (type_urid == sratom->forge.Literal) { - LV2_Atom_Literal_Body* lit = (LV2_Atom_Literal_Body*)body; - const uint8_t* str = USTR(lit + 1); - object = serd_node_from_string(SERD_LITERAL, str); - if (lit->datatype) { - datatype = serd_node_from_string( - SERD_URI, USTR(unmap->unmap(unmap->handle, lit->datatype))); - } else if (lit->lang) { - const char* lang = unmap->unmap(unmap->handle, lit->lang); - const char* prefix = "http://lexvo.org/id/iso639-3/"; - const size_t prefix_len = strlen(prefix); - if (lang && !strncmp(lang, prefix, prefix_len)) { - language = serd_node_from_string( - SERD_LITERAL, USTR(lang + prefix_len)); - } else { - fprintf(stderr, "Unknown language URI <%s>\n", lang); - } - } - } else if (type_urid == sratom->forge.URID) { - const uint32_t id = *(const uint32_t*)body; - const uint8_t* str = USTR(unmap->unmap(unmap->handle, id)); - object = serd_node_from_string(SERD_URI, str); - } else if (type_urid == sratom->forge.Path) { - const uint8_t* str = USTR(body); - object = serd_node_from_string(SERD_LITERAL, str); - datatype = serd_node_from_string(SERD_URI, USTR(LV2_ATOM__Path)); - } else if (type_urid == sratom->forge.URI) { - const uint8_t* str = USTR(body); - object = serd_node_from_string(SERD_URI, str); - } else if (type_urid == sratom->forge.Int32) { - new_node = true; - object = serd_node_new_integer(*(int32_t*)body); - datatype = serd_node_from_string(SERD_URI, NS_XSD "int"); - } else if (type_urid == sratom->forge.Int64) { - new_node = true; - object = serd_node_new_integer(*(int64_t*)body); - datatype = serd_node_from_string(SERD_URI, NS_XSD "long"); - } else if (type_urid == sratom->forge.Float) { - new_node = true; - object = serd_node_new_decimal(*(float*)body, 8); - datatype = serd_node_from_string(SERD_URI, NS_XSD "float"); - } else if (type_urid == sratom->forge.Double) { - new_node = true; - object = serd_node_new_decimal(*(double*)body, 16); - datatype = serd_node_from_string(SERD_URI, NS_XSD "double"); - } else if (type_urid == sratom->forge.Bool) { - const int32_t val = *(const int32_t*)body; - datatype = serd_node_from_string(SERD_URI, NS_XSD "boolean"); - object = serd_node_from_string(SERD_LITERAL, - USTR(val ? "true" : "false")); - } else if (type_urid == sratom->midi_MidiEvent) { - new_node = true; - datatype = serd_node_from_string(SERD_URI, NS_MIDI "MidiEvent"); - uint8_t* str = calloc(size * 2, 1); - for (uint32_t i = 0; i < size; ++i) { - sprintf((char*)str + (2 * i), "%02X", - (unsigned)(uint8_t)*((uint8_t*)body + i)); - } - object = serd_node_from_string(SERD_LITERAL, USTR(str)); - } else if (type_urid == sratom->atom_Event) { - const LV2_Atom_Event* ev = (const LV2_Atom_Event*)body; - gensym(&id, 'e', sratom->next_id++); - start_object(sratom, flags, subject, predicate, &id, NULL); - // TODO: beat time - SerdNode p = serd_node_from_string(SERD_URI, USTR(LV2_ATOM__frameTime)); - SerdNode time = serd_node_new_integer(ev->time.frames); - datatype = serd_node_from_string(SERD_URI, NS_XSD "decimal"); - serd_writer_write_statement(sratom->writer, SERD_ANON_CONT, NULL, - &id, &p, &time, - &datatype, &language); - serd_node_free(&time); - - p = serd_node_from_string(SERD_URI, NS_RDF "value"); - sratom_write(sratom, SERD_ANON_CONT, &id, &p, - ev->body.type, ev->body.size, - LV2_ATOM_BODY(&ev->body)); - serd_writer_end_anon(sratom->writer, &id); - } else if (type_urid == sratom->forge.Tuple) { - gensym(&id, 't', sratom->next_id++); - start_object(sratom, flags, subject, predicate, &id, type); - SerdNode p = serd_node_from_string(SERD_URI, NS_RDF "value"); - flags |= SERD_LIST_O_BEGIN; - LV2_TUPLE_BODY_FOREACH(body, size, i) { - list_append(sratom, &flags, &id, &p, &node, - i->type, i->size, LV2_ATOM_BODY(i)); - } - list_end(sratom->writer, &flags, &id, &p); - serd_writer_end_anon(sratom->writer, &id); - } else if (type_urid == sratom->forge.Vector) { - const LV2_Atom_Vector_Body* vec = (const LV2_Atom_Vector_Body*)body; - gensym(&id, 'v', sratom->next_id++); - start_object(sratom, flags, subject, predicate, &id, type); - SerdNode p = serd_node_from_string(SERD_URI, NS_RDF "value"); - const uint32_t content_size = size - sizeof(LV2_Atom_Vector_Body); - const uint32_t elem_size = content_size / vec->elem_count; - flags |= SERD_LIST_O_BEGIN; - for (char* i = (char*)(vec + 1); - i < (char*)vec + size; - i += elem_size) { - list_append(sratom, &flags, &id, &p, &node, - vec->elem_type, elem_size, i); - } - list_end(sratom->writer, &flags, &id, &p); - serd_writer_end_anon(sratom->writer, &id); - } else if (type_urid == sratom->forge.Blank) { - const LV2_Atom_Object_Body* obj = (const LV2_Atom_Object_Body*)body; - const char* otype = unmap->unmap(unmap->handle, obj->otype); - gensym(&id, 'b', sratom->next_id++); - start_object(sratom, flags, subject, predicate, &id, otype); - LV2_OBJECT_BODY_FOREACH(obj, size, i) { - const LV2_Atom_Property_Body* prop = lv2_object_iter_get(i); - const char* const key = unmap->unmap(unmap->handle, prop->key); - SerdNode pred = serd_node_from_string(SERD_URI, USTR(key)); - sratom_write(sratom, flags|SERD_ANON_CONT, &id, &pred, - prop->value.type, prop->value.size, - LV2_ATOM_BODY(&prop->value)); - } - serd_writer_end_anon(sratom->writer, &id); - } else if (type_urid == sratom->forge.Sequence) { - const LV2_Atom_Sequence_Body* seq = (const LV2_Atom_Sequence_Body*)body; - gensym(&id, 'v', sratom->next_id++); - start_object(sratom, flags, subject, predicate, &id, type); - SerdNode p = serd_node_from_string(SERD_URI, NS_RDF "value"); - flags |= SERD_LIST_O_BEGIN; - LV2_SEQUENCE_BODY_FOREACH(seq, size, i) { - LV2_Atom_Event* ev = lv2_sequence_iter_get(i); - list_append(sratom, &flags, &id, &p, &node, - sratom->atom_Event, - sizeof(LV2_Atom_Event) + ev->body.size, - ev); - } - list_end(sratom->writer, &flags, &id, &p); - serd_writer_end_anon(sratom->writer, &id); - } else { - object = serd_node_from_string(SERD_LITERAL, USTR("(unknown)")); - } - - if (object.buf) { - serd_writer_write_statement(sratom->writer, flags, NULL, - subject, predicate, &object, - &datatype, &language); - } - - if (new_node) { - serd_node_free(&object); - } -} - -SRATOM_API -char* -sratom_to_turtle(Sratom* sratom, - const SerdNode* subject, - const SerdNode* predicate, - uint32_t type, - uint32_t size, - const void* body) -{ - SerdURI base_uri = SERD_URI_NULL; - SerdEnv* env = serd_env_new(NULL); - String str = { NULL, 0 }; - - serd_env_set_prefix_from_strings(env, USTR("midi"), NS_MIDI); - serd_env_set_prefix_from_strings(env, USTR("atom"), - USTR(LV2_ATOM_URI "#")); - serd_env_set_prefix_from_strings(env, USTR("rdf"), NS_RDF); - serd_env_set_prefix_from_strings(env, USTR("xsd"), NS_XSD); - serd_env_set_prefix_from_strings(env, USTR("eg"), - USTR("http://example.org/")); - - sratom->writer = serd_writer_new( - SERD_TURTLE, - SERD_STYLE_ABBREVIATED|SERD_STYLE_RESOLVED|SERD_STYLE_CURIED, - env, &base_uri, string_sink, &str); - - sratom_write(sratom, SERD_EMPTY_S, subject, predicate, type, size, body); - serd_writer_finish(sratom->writer); - string_sink("", 1, &str); - - serd_writer_free(sratom->writer); - serd_env_free(env); - free(str.buf); - return str.buf; -} diff --git a/src/sratom.c b/src/sratom.c new file mode 100644 index 0000000..f919f89 --- /dev/null +++ b/src/sratom.c @@ -0,0 +1,348 @@ +/* + Copyright 2012 David Robillard + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#include +#include +#include + +#include "lv2/lv2plug.in/ns/ext/atom/forge.h" +#include "lv2/lv2plug.in/ns/ext/atom/util.h" + +#include "sratom/sratom.h" + +#define NS_RDF (const uint8_t*)"http://www.w3.org/1999/02/22-rdf-syntax-ns#" +#define NS_XSD (const uint8_t*)"http://www.w3.org/2001/XMLSchema#" +#define NS_MIDI (const uint8_t*)"http://lv2plug.in/ns/ext/midi#" + +#define USTR(str) ((const uint8_t*)(str)) + +struct SratomImpl { + SerdWriter* writer; + LV2_URID_Map* map; + LV2_URID_Unmap* unmap; + LV2_Atom_Forge forge; + LV2_URID atom_Event; + LV2_URID midi_MidiEvent; + unsigned next_id; +}; + +SRATOM_API +Sratom* +sratom_new(LV2_URID_Map* map, + LV2_URID_Unmap* unmap) +{ + Sratom* sratom = (Sratom*)malloc(sizeof(Sratom)); + sratom->writer = NULL; + sratom->map = map; + sratom->unmap = unmap; + sratom->atom_Event = map->map(map->handle, LV2_ATOM_URI "#Event"); + sratom->midi_MidiEvent = map->map(map->handle, (const char*)NS_MIDI "MidiEvent"); + sratom->next_id = 0; + lv2_atom_forge_init(&sratom->forge, map); + return sratom; +} + +SRATOM_API +void +sratom_free(Sratom* sratom) +{ + free(sratom); +} + +typedef struct { + char* buf; + size_t len; +} String; + +static size_t +string_sink(const void* buf, size_t len, void* stream) +{ + String* str = (String*)stream; + str->buf = realloc(str->buf, str->len + len); + memcpy(str->buf + str->len, buf, len); + str->len += len; + return len; +} + +static void +gensym(SerdNode* out, char c, unsigned num) +{ + out->n_bytes = out->n_chars = snprintf( + (char*)out->buf, 10, "%c%u", c, num); +} + +static void +list_append(Sratom* sratom, + unsigned* flags, + SerdNode* s, + SerdNode* p, + SerdNode* node, + uint32_t type, + uint32_t size, + void* body) +{ + // Generate a list node + gensym(node, 'l', sratom->next_id); + serd_writer_write_statement(sratom->writer, *flags, NULL, + s, p, node, NULL, NULL); + + // _:node rdf:first value + *flags = SERD_LIST_CONT; + *p = serd_node_from_string(SERD_URI, NS_RDF "first"); + sratom_write(sratom, SERD_LIST_CONT, node, p, type, size, body); + + // Set subject to node and predicate to rdf:rest for next time + gensym(node, 'l', ++sratom->next_id); + *s = *node; + *p = serd_node_from_string(SERD_URI, NS_RDF "rest"); +} + +static void +list_end(SerdWriter* writer, unsigned* flags, SerdNode* s, SerdNode* p) +{ + // _:node rdf:rest rdf:nil + const SerdNode nil = serd_node_from_string(SERD_URI, NS_RDF "nil"); + serd_writer_write_statement(writer, *flags, NULL, + s, p, &nil, NULL, NULL); +} + +static void +start_object(Sratom* sratom, + uint32_t flags, + const SerdNode* subject, + const SerdNode* predicate, + const SerdNode* node, + const char* type) +{ + serd_writer_write_statement( + sratom->writer, flags|SERD_ANON_O_BEGIN, NULL, + subject, predicate, node, NULL, NULL); + if (type) { + SerdNode p = serd_node_from_string(SERD_URI, NS_RDF "type"); + SerdNode o = serd_node_from_string(SERD_URI, USTR(type)); + serd_writer_write_statement( + sratom->writer, SERD_ANON_CONT, NULL, + node, &p, &o, NULL, NULL); + } +} + +SRATOM_API +void +sratom_write(Sratom* sratom, + uint32_t flags, + const SerdNode* subject, + const SerdNode* predicate, + uint32_t type_urid, + uint32_t size, + const void* body) +{ + LV2_URID_Unmap* unmap = sratom->unmap; + const char* const type = unmap->unmap(unmap->handle, type_urid); + uint8_t idbuf[12] = "b0000000000"; + SerdNode id = serd_node_from_string(SERD_BLANK, idbuf); + uint8_t nodebuf[12] = "b0000000000"; + SerdNode node = serd_node_from_string(SERD_BLANK, nodebuf); + SerdNode object = SERD_NODE_NULL; + SerdNode datatype = SERD_NODE_NULL; + SerdNode language = SERD_NODE_NULL; + bool new_node = false; + if (type_urid == 0 && size == 0) { + object = serd_node_from_string(SERD_BLANK, USTR("null")); + } else if (type_urid == sratom->forge.String) { + object = serd_node_from_string(SERD_LITERAL, (const uint8_t*)body); + } else if (type_urid == sratom->forge.Literal) { + LV2_Atom_Literal_Body* lit = (LV2_Atom_Literal_Body*)body; + const uint8_t* str = USTR(lit + 1); + object = serd_node_from_string(SERD_LITERAL, str); + if (lit->datatype) { + datatype = serd_node_from_string( + SERD_URI, USTR(unmap->unmap(unmap->handle, lit->datatype))); + } else if (lit->lang) { + const char* lang = unmap->unmap(unmap->handle, lit->lang); + const char* prefix = "http://lexvo.org/id/iso639-3/"; + const size_t prefix_len = strlen(prefix); + if (lang && !strncmp(lang, prefix, prefix_len)) { + language = serd_node_from_string( + SERD_LITERAL, USTR(lang + prefix_len)); + } else { + fprintf(stderr, "Unknown language URI <%s>\n", lang); + } + } + } else if (type_urid == sratom->forge.URID) { + const uint32_t id = *(const uint32_t*)body; + const uint8_t* str = USTR(unmap->unmap(unmap->handle, id)); + object = serd_node_from_string(SERD_URI, str); + } else if (type_urid == sratom->forge.Path) { + const uint8_t* str = USTR(body); + object = serd_node_from_string(SERD_LITERAL, str); + datatype = serd_node_from_string(SERD_URI, USTR(LV2_ATOM__Path)); + } else if (type_urid == sratom->forge.URI) { + const uint8_t* str = USTR(body); + object = serd_node_from_string(SERD_URI, str); + } else if (type_urid == sratom->forge.Int32) { + new_node = true; + object = serd_node_new_integer(*(int32_t*)body); + datatype = serd_node_from_string(SERD_URI, NS_XSD "int"); + } else if (type_urid == sratom->forge.Int64) { + new_node = true; + object = serd_node_new_integer(*(int64_t*)body); + datatype = serd_node_from_string(SERD_URI, NS_XSD "long"); + } else if (type_urid == sratom->forge.Float) { + new_node = true; + object = serd_node_new_decimal(*(float*)body, 8); + datatype = serd_node_from_string(SERD_URI, NS_XSD "float"); + } else if (type_urid == sratom->forge.Double) { + new_node = true; + object = serd_node_new_decimal(*(double*)body, 16); + datatype = serd_node_from_string(SERD_URI, NS_XSD "double"); + } else if (type_urid == sratom->forge.Bool) { + const int32_t val = *(const int32_t*)body; + datatype = serd_node_from_string(SERD_URI, NS_XSD "boolean"); + object = serd_node_from_string(SERD_LITERAL, + USTR(val ? "true" : "false")); + } else if (type_urid == sratom->midi_MidiEvent) { + new_node = true; + datatype = serd_node_from_string(SERD_URI, NS_MIDI "MidiEvent"); + uint8_t* str = calloc(size * 2, 1); + for (uint32_t i = 0; i < size; ++i) { + sprintf((char*)str + (2 * i), "%02X", + (unsigned)(uint8_t)*((uint8_t*)body + i)); + } + object = serd_node_from_string(SERD_LITERAL, USTR(str)); + } else if (type_urid == sratom->atom_Event) { + const LV2_Atom_Event* ev = (const LV2_Atom_Event*)body; + gensym(&id, 'e', sratom->next_id++); + start_object(sratom, flags, subject, predicate, &id, NULL); + // TODO: beat time + SerdNode p = serd_node_from_string(SERD_URI, USTR(LV2_ATOM__frameTime)); + SerdNode time = serd_node_new_integer(ev->time.frames); + datatype = serd_node_from_string(SERD_URI, NS_XSD "decimal"); + serd_writer_write_statement(sratom->writer, SERD_ANON_CONT, NULL, + &id, &p, &time, + &datatype, &language); + serd_node_free(&time); + + p = serd_node_from_string(SERD_URI, NS_RDF "value"); + sratom_write(sratom, SERD_ANON_CONT, &id, &p, + ev->body.type, ev->body.size, + LV2_ATOM_BODY(&ev->body)); + serd_writer_end_anon(sratom->writer, &id); + } else if (type_urid == sratom->forge.Tuple) { + gensym(&id, 't', sratom->next_id++); + start_object(sratom, flags, subject, predicate, &id, type); + SerdNode p = serd_node_from_string(SERD_URI, NS_RDF "value"); + flags |= SERD_LIST_O_BEGIN; + LV2_TUPLE_BODY_FOREACH(body, size, i) { + list_append(sratom, &flags, &id, &p, &node, + i->type, i->size, LV2_ATOM_BODY(i)); + } + list_end(sratom->writer, &flags, &id, &p); + serd_writer_end_anon(sratom->writer, &id); + } else if (type_urid == sratom->forge.Vector) { + const LV2_Atom_Vector_Body* vec = (const LV2_Atom_Vector_Body*)body; + gensym(&id, 'v', sratom->next_id++); + start_object(sratom, flags, subject, predicate, &id, type); + SerdNode p = serd_node_from_string(SERD_URI, NS_RDF "value"); + const uint32_t content_size = size - sizeof(LV2_Atom_Vector_Body); + const uint32_t elem_size = content_size / vec->elem_count; + flags |= SERD_LIST_O_BEGIN; + for (char* i = (char*)(vec + 1); + i < (char*)vec + size; + i += elem_size) { + list_append(sratom, &flags, &id, &p, &node, + vec->elem_type, elem_size, i); + } + list_end(sratom->writer, &flags, &id, &p); + serd_writer_end_anon(sratom->writer, &id); + } else if (type_urid == sratom->forge.Blank) { + const LV2_Atom_Object_Body* obj = (const LV2_Atom_Object_Body*)body; + const char* otype = unmap->unmap(unmap->handle, obj->otype); + gensym(&id, 'b', sratom->next_id++); + start_object(sratom, flags, subject, predicate, &id, otype); + LV2_OBJECT_BODY_FOREACH(obj, size, i) { + const LV2_Atom_Property_Body* prop = lv2_object_iter_get(i); + const char* const key = unmap->unmap(unmap->handle, prop->key); + SerdNode pred = serd_node_from_string(SERD_URI, USTR(key)); + sratom_write(sratom, flags|SERD_ANON_CONT, &id, &pred, + prop->value.type, prop->value.size, + LV2_ATOM_BODY(&prop->value)); + } + serd_writer_end_anon(sratom->writer, &id); + } else if (type_urid == sratom->forge.Sequence) { + const LV2_Atom_Sequence_Body* seq = (const LV2_Atom_Sequence_Body*)body; + gensym(&id, 'v', sratom->next_id++); + start_object(sratom, flags, subject, predicate, &id, type); + SerdNode p = serd_node_from_string(SERD_URI, NS_RDF "value"); + flags |= SERD_LIST_O_BEGIN; + LV2_SEQUENCE_BODY_FOREACH(seq, size, i) { + LV2_Atom_Event* ev = lv2_sequence_iter_get(i); + list_append(sratom, &flags, &id, &p, &node, + sratom->atom_Event, + sizeof(LV2_Atom_Event) + ev->body.size, + ev); + } + list_end(sratom->writer, &flags, &id, &p); + serd_writer_end_anon(sratom->writer, &id); + } else { + object = serd_node_from_string(SERD_LITERAL, USTR("(unknown)")); + } + + if (object.buf) { + serd_writer_write_statement(sratom->writer, flags, NULL, + subject, predicate, &object, + &datatype, &language); + } + + if (new_node) { + serd_node_free(&object); + } +} + +SRATOM_API +char* +sratom_to_turtle(Sratom* sratom, + const SerdNode* subject, + const SerdNode* predicate, + uint32_t type, + uint32_t size, + const void* body) +{ + SerdURI base_uri = SERD_URI_NULL; + SerdEnv* env = serd_env_new(NULL); + String str = { NULL, 0 }; + + serd_env_set_prefix_from_strings(env, USTR("midi"), NS_MIDI); + serd_env_set_prefix_from_strings(env, USTR("atom"), + USTR(LV2_ATOM_URI "#")); + serd_env_set_prefix_from_strings(env, USTR("rdf"), NS_RDF); + serd_env_set_prefix_from_strings(env, USTR("xsd"), NS_XSD); + serd_env_set_prefix_from_strings(env, USTR("eg"), + USTR("http://example.org/")); + + sratom->writer = serd_writer_new( + SERD_TURTLE, + SERD_STYLE_ABBREVIATED|SERD_STYLE_RESOLVED|SERD_STYLE_CURIED, + env, &base_uri, string_sink, &str); + + sratom_write(sratom, SERD_EMPTY_S, subject, predicate, type, size, body); + serd_writer_finish(sratom->writer); + string_sink("", 1, &str); + + serd_writer_free(sratom->writer); + serd_env_free(env); + free(str.buf); + return str.buf; +} -- cgit v1.2.1