summaryrefslogtreecommitdiffstats
path: root/src/atom_to_rdf.c
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2012-02-19 06:42:02 +0000
committerDavid Robillard <d@drobilla.net>2012-02-19 06:42:02 +0000
commitee1e682e0a3787a4b293e55a09d2394bd1d47252 (patch)
treef8e7e9595e47d09582fe0212f64111cfc4e1d0a5 /src/atom_to_rdf.c
downloadsratom-ee1e682e0a3787a4b293e55a09d2394bd1d47252.tar.gz
sratom-ee1e682e0a3787a4b293e55a09d2394bd1d47252.tar.bz2
sratom-ee1e682e0a3787a4b293e55a09d2394bd1d47252.zip
Add 'seriatom', an LV2 Atom RDF serialisation library.
git-svn-id: http://svn.drobilla.net/lad/trunk/seriatom@3989 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src/atom_to_rdf.c')
-rw-r--r--src/atom_to_rdf.c173
1 files changed, 173 insertions, 0 deletions
diff --git a/src/atom_to_rdf.c b/src/atom_to_rdf.c
new file mode 100644
index 0000000..f9e3895
--- /dev/null
+++ b/src/atom_to_rdf.c
@@ -0,0 +1,173 @@
+/*
+ Copyright 2012 David Robillard <http://drobilla.net>
+
+ 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 <stdlib.h>
+#include <string.h>
+
+#include "lv2/lv2plug.in/ns/ext/atom/util.h"
+#include "seriatom/seriatom.h"
+
+#define NS_RDF "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+#define NS_XSD "http://www.w3.org/2001/XMLSchema#"
+
+#define USTR(str) ((const uint8_t*)(str))
+
+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;
+}
+
+SERIATOM_API
+void
+atom_to_rdf(SerdWriter* writer,
+ LV2_URID_Unmap* unmap,
+ const SerdNode* subject,
+ const SerdNode* predicate,
+ const LV2_Atom* atom,
+ uint32_t flags)
+{
+ const char* const type = unmap->unmap(unmap->handle, atom->type);
+ SerdNode object = SERD_NODE_NULL;
+ SerdNode datatype = SERD_NODE_NULL;
+ SerdNode language = SERD_NODE_NULL;
+ bool new_node = false;
+ if (atom->type == 0 && atom->size == 0) {
+ object = serd_node_from_string(SERD_BLANK, USTR("null"));
+ } else if (!strcmp(type, LV2_ATOM__String)) {
+ const uint8_t* str = USTR(LV2_ATOM_BODY(atom));
+ object = serd_node_from_string(SERD_LITERAL, str);
+ } else if (!strcmp(type, LV2_ATOM__Literal)) {
+ LV2_Atom_Literal* lit = (LV2_Atom_Literal*)atom;
+ const uint8_t* str = USTR(LV2_ATOM_CONTENTS(LV2_Atom_Literal, lit));
+ 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 (!strcmp(type, LV2_ATOM__URID)) {
+ const uint32_t id = *(const uint32_t*)LV2_ATOM_BODY(atom);
+ const uint8_t* str = USTR(unmap->unmap(unmap->handle, id));
+ object = serd_node_from_string(SERD_URI, str);
+ } else if (!strcmp(type, LV2_ATOM__Path)) {
+ const uint8_t* str = USTR(LV2_ATOM_BODY(atom));
+ object = serd_node_from_string(SERD_LITERAL, str);
+ datatype = serd_node_from_string(SERD_URI, USTR(LV2_ATOM__Path));
+ } else if (!strcmp(type, LV2_ATOM__URI)) {
+ const uint8_t* str = USTR(LV2_ATOM_BODY(atom));
+ object = serd_node_from_string(SERD_URI, str);
+ } else if (!strcmp(type, LV2_ATOM__Int32)) {
+ new_node = true;
+ object = serd_node_new_integer(*(int32_t*)LV2_ATOM_BODY(atom));
+ datatype = serd_node_from_string(SERD_URI, USTR(NS_XSD "int"));
+ } else if (!strcmp(type, LV2_ATOM__Int64)) {
+ new_node = true;
+ object = serd_node_new_integer(*(int64_t*)LV2_ATOM_BODY(atom));
+ datatype = serd_node_from_string(SERD_URI, USTR(NS_XSD "long"));
+ } else if (!strcmp(type, LV2_ATOM__Float)) {
+ new_node = true;
+ object = serd_node_new_decimal(*(float*)LV2_ATOM_BODY(atom), 8);
+ datatype = serd_node_from_string(SERD_URI, USTR(NS_XSD "float"));
+ } else if (!strcmp(type, LV2_ATOM__Double)) {
+ new_node = true;
+ object = serd_node_new_decimal(*(double*)LV2_ATOM_BODY(atom), 16);
+ datatype = serd_node_from_string(SERD_URI, USTR(NS_XSD "double"));
+ } else if (!strcmp(type, LV2_ATOM__Bool)) {
+ const int32_t val = *(const int32_t*)LV2_ATOM_BODY(atom);
+ datatype = serd_node_from_string(SERD_URI, USTR(NS_XSD "boolean"));
+ object = serd_node_from_string(SERD_LITERAL,
+ USTR(val ? "true" : "false"));
+ } else if (!strcmp(type, LV2_ATOM__Blank)) {
+ const LV2_Atom_Object* obj = (const LV2_Atom_Object*)atom;
+ const char* otype = unmap->unmap(unmap->handle, obj->otype);
+ SerdNode idnum = serd_node_new_integer(obj->id);
+ SerdNode id = serd_node_from_string(SERD_BLANK, idnum.buf);
+ serd_writer_write_statement(
+ writer, flags|SERD_ANON_O_BEGIN, NULL,
+ subject, predicate, &id, NULL, NULL);
+ if (otype) {
+ SerdNode p = serd_node_from_string(SERD_URI, USTR(NS_RDF "type"));
+ SerdNode o = serd_node_from_string(SERD_URI, USTR(otype));
+ serd_writer_write_statement(writer, SERD_ANON_CONT, NULL,
+ &id, &p, &o, NULL, NULL);
+ }
+ LV2_OBJECT_FOREACH(obj, 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));
+ atom_to_rdf(writer, unmap, &id, &pred, &prop->value, SERD_ANON_CONT);
+ }
+ serd_writer_end_anon(writer, &id);
+ serd_node_free(&idnum);
+ } else {
+ object = serd_node_from_string(SERD_LITERAL, USTR("(unknown)"));
+ }
+
+ if (object.buf) {
+ serd_writer_write_statement(writer, flags, NULL,
+ subject, predicate, &object,
+ &datatype, &language);
+ }
+
+ if (new_node) {
+ serd_node_free(&object);
+ }
+}
+
+SERIATOM_API
+char*
+atom_to_turtle(LV2_URID_Unmap* unmap,
+ const SerdNode* subject,
+ const SerdNode* predicate,
+ const LV2_Atom* atom)
+{
+ SerdURI base_uri = SERD_URI_NULL;
+ SerdEnv* env = serd_env_new(NULL);
+ String str = { NULL, 0 };
+ SerdWriter* writer = serd_writer_new(
+ SERD_TURTLE,
+ SERD_STYLE_ABBREVIATED|SERD_STYLE_RESOLVED|SERD_STYLE_CURIED,
+ env, &base_uri, string_sink, &str);
+
+ serd_env_set_prefix_from_strings(env, USTR("rdf"), USTR(NS_RDF));
+ serd_env_set_prefix_from_strings(env, USTR("xsd"), USTR(NS_XSD));
+ atom_to_rdf(writer, unmap, subject, predicate, atom, 0);
+ serd_writer_finish(writer);
+ string_sink("", 1, &str);
+
+ serd_writer_free(writer);
+ serd_env_free(env);
+ return str.buf;
+}