summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2012-03-02 03:34:54 +0000
committerDavid Robillard <d@drobilla.net>2012-03-02 03:34:54 +0000
commit8e241b6b299f3edc2d3e73b4b3a9e4235a949e33 (patch)
treeb9b61e98d908f9f6acaf1f1a9f06e8f37b00913d
parent9e0d9390050410bf05e943ccbb7c545e8a849044 (diff)
downloadsratom-8e241b6b299f3edc2d3e73b4b3a9e4235a949e33.tar.gz
sratom-8e241b6b299f3edc2d3e73b4b3a9e4235a949e33.tar.bz2
sratom-8e241b6b299f3edc2d3e73b4b3a9e4235a949e33.zip
Full round-trip support for every atom type, and midi:MidiEvent.
git-svn-id: http://svn.drobilla.net/lad/trunk/sratom@4009 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r--src/sratom.c49
-rw-r--r--tests/sratom_test.c43
2 files changed, 59 insertions, 33 deletions
diff --git a/src/sratom.c b/src/sratom.c
index 43fcc66..4a15911 100644
--- a/src/sratom.c
+++ b/src/sratom.c
@@ -443,7 +443,8 @@ sratom_read_internal(Sratom* sratom,
const SordNode* node,
ReadMode mode)
{
- const char* str = (const char*)sord_node_get_string(node);
+ LV2_URID_Map* map = sratom->map;
+ const char* str = (const char*)sord_node_get_string(node);
if (sord_node_get_type(node) == SORD_LITERAL) {
char* endptr;
SordNode* datatype = sord_node_get_datatype(node);
@@ -457,9 +458,20 @@ sratom_read_internal(Sratom* sratom,
} else if (!strcmp(type_uri, (char*)NS_XSD "float")) {
lv2_atom_forge_float(forge, serd_strtod(str, &endptr));
} else if (!strcmp(type_uri, (char*)NS_XSD "double")) {
- lv2_atom_forge_float(forge, serd_strtod(str, &endptr));
+ lv2_atom_forge_double(forge, serd_strtod(str, &endptr));
} else if (!strcmp(type_uri, (char*)NS_XSD "boolean")) {
lv2_atom_forge_bool(forge, !strcmp(str, "true"));
+ } else if (!strcmp(type_uri, (char*)NS_MIDI "MidiEvent")) {
+ const size_t len = strlen(str);
+ lv2_atom_forge_atom(forge, len / 2, sratom->midi_MidiEvent);
+ for (const char* s = str; s < str + len; s += 2) {
+ unsigned num;
+ sscanf(s, "%2X", &num);
+ assert(num < UINT8_MAX);
+ const uint8_t c = num;
+ lv2_atom_forge_raw(forge, &c, 1);
+ }
+ lv2_atom_forge_pad(forge, len / 2);
} else {
lv2_atom_forge_literal(
forge, (const uint8_t*)str, strlen(str),
@@ -479,9 +491,12 @@ sratom_read_internal(Sratom* sratom,
lv2_atom_forge_string(forge, (const uint8_t*)str, strlen(str));
}
} else if (sord_node_get_type(node) == SORD_URI) {
- lv2_atom_forge_uri(forge, (const uint8_t*)str, strlen(str));
+ if (serd_uri_string_has_scheme((const uint8_t*)str)) {
+ lv2_atom_forge_urid(forge, map->map(map->handle, str));
+ } else {
+ lv2_atom_forge_uri(forge, (const uint8_t*)str, strlen(str));
+ }
} else {
- LV2_URID_Map* map = sratom->map;
const SordNode* type = get_object(model, node, sratom->nodes.rdf_type);
const uint8_t* type_uri = NULL;
@@ -525,20 +540,23 @@ sratom_read_internal(Sratom* sratom,
read_list_value(sratom, forge, world, model, value, MODE_NORMAL);
}
} else {
- lv2_atom_forge_blank(forge, &frame, 1, type_urid);
+ lv2_atom_forge_blank(forge, &frame, sratom->next_id++, type_urid);
+ SordQuad match;
- SordQuad q = { node, 0, 0, 0 };
- for (SordIter* i = sord_find(model, q);
+ SordQuad q2 = { node, 0, 0, 0 };
+ for (SordIter* i = sord_find(model, q2);
!sord_iter_end(i);
sord_iter_next(i)) {
- SordQuad quad;
- sord_iter_get(i, quad);
- const SordNode* key = quad[SORD_PREDICATE];
- lv2_atom_forge_property_head(
- forge,
- map->map(map->handle, (const char*)sord_node_get_string(key)),
- 0);
- sratom_read_internal(sratom, forge, world, model, quad[SORD_OBJECT], MODE_NORMAL);
+ sord_iter_get(i, match);
+ const SordNode* p = match[SORD_PREDICATE];
+ const char* p_uri = (const char*)sord_node_get_string(p);
+ uint32_t p_urid = map->map(map->handle, p_uri);
+ if (!sord_node_equals(p, sratom->nodes.rdf_type)) {
+ // TODO: This will lose multiple rdf:type properties
+ lv2_atom_forge_property_head(forge, p_urid, 0);
+ sratom_read_internal(sratom, forge, world, model,
+ match[SORD_OBJECT], MODE_NORMAL);
+ }
}
}
if (frame.ref) {
@@ -562,6 +580,7 @@ sratom_read(Sratom* sratom,
sratom->nodes.rdf_type = sord_new_uri(world, NS_RDF "type");
sratom->nodes.rdf_value = sord_new_uri(world, NS_RDF "value");
+ sratom->next_id = 1;
sratom_read_internal(sratom, forge, world, model, node, MODE_NORMAL);
sord_node_free(world, sratom->nodes.rdf_value);
diff --git a/tests/sratom_test.c b/tests/sratom_test.c
index 973819e..4ae3f9a 100644
--- a/tests/sratom_test.c
+++ b/tests/sratom_test.c
@@ -85,22 +85,22 @@ main()
Sratom* sratom = sratom_new(&map, &unmap);
LV2_URID eg_Object = urid_map(NULL, "http://example.org/Object");
- LV2_URID eg_one = urid_map(NULL, "http://example.org/one");
- LV2_URID eg_two = urid_map(NULL, "http://example.org/two");
- LV2_URID eg_three = urid_map(NULL, "http://example.org/three");
- LV2_URID eg_four = urid_map(NULL, "http://example.org/four");
- LV2_URID eg_true = urid_map(NULL, "http://example.org/true");
- LV2_URID eg_false = urid_map(NULL, "http://example.org/false");
- LV2_URID eg_path = urid_map(NULL, "http://example.org/path");
- LV2_URID eg_uri = urid_map(NULL, "http://example.org/uri");
- LV2_URID eg_urid = urid_map(NULL, "http://example.org/urid");
- LV2_URID eg_string = urid_map(NULL, "http://example.org/string");
- LV2_URID eg_langlit = urid_map(NULL, "http://example.org/langlit");
- LV2_URID eg_typelit = urid_map(NULL, "http://example.org/typelit");
- LV2_URID eg_blank = urid_map(NULL, "http://example.org/blank");
- LV2_URID eg_tuple = urid_map(NULL, "http://example.org/tuple");
- LV2_URID eg_vector = urid_map(NULL, "http://example.org/vector");
- LV2_URID eg_seq = urid_map(NULL, "http://example.org/seq");
+ LV2_URID eg_one = urid_map(NULL, "http://example.org/a-one");
+ LV2_URID eg_two = urid_map(NULL, "http://example.org/b-two");
+ LV2_URID eg_three = urid_map(NULL, "http://example.org/c-three");
+ LV2_URID eg_four = urid_map(NULL, "http://example.org/d-four");
+ LV2_URID eg_true = urid_map(NULL, "http://example.org/e-true");
+ LV2_URID eg_false = urid_map(NULL, "http://example.org/f-false");
+ LV2_URID eg_path = urid_map(NULL, "http://example.org/g-path");
+ LV2_URID eg_uri = urid_map(NULL, "http://example.org/h-uri");
+ LV2_URID eg_urid = urid_map(NULL, "http://example.org/i-urid");
+ LV2_URID eg_string = urid_map(NULL, "http://example.org/j-string");
+ LV2_URID eg_langlit = urid_map(NULL, "http://example.org/k-langlit");
+ LV2_URID eg_typelit = urid_map(NULL, "http://example.org/l-typelit");
+ LV2_URID eg_blank = urid_map(NULL, "http://example.org/m-blank");
+ LV2_URID eg_tuple = urid_map(NULL, "http://example.org/n-tuple");
+ LV2_URID eg_vector = urid_map(NULL, "http://example.org/o-vector");
+ LV2_URID eg_seq = urid_map(NULL, "http://example.org/p-seq");
uint8_t buf[1024];
lv2_atom_forge_set_buffer(&forge, buf, sizeof(buf));
@@ -139,8 +139,8 @@ main()
lv2_atom_forge_property_head(&forge, eg_path, 0);
lv2_atom_forge_uri(&forge, pstr, pstr_len);
- // eg_uri = (URI)"http://example.org/value"
- const uint8_t* ustr = (const uint8_t*)"http://example.org/value";
+ // eg_uri = (URI)"a/relative/uri"
+ const uint8_t* ustr = (const uint8_t*)"a/relative/uri";
const size_t ustr_len = strlen((const char*)ustr);
lv2_atom_forge_property_head(&forge, eg_uri, 0);
lv2_atom_forge_uri(&forge, ustr, ustr_len);
@@ -213,11 +213,18 @@ main()
printf("# Atom => Turtle\n\n%s", outstr);
LV2_Atom* parsed = sratom_from_turtle(sratom, &s, &p, outstr);
+ if (!lv2_atom_equals(obj, parsed)) {
+ return test_fail("Parsed atom does not match original\n");
+ }
char* instr = sratom_to_turtle(
sratom, &s, &p, parsed->type, parsed->size, LV2_ATOM_BODY(parsed));
printf("# Turtle => Atom\n\n%s", instr);
+ if (strcmp(outstr, instr)) {
+ return test_fail("Re-serialised string differs from original\n");
+ }
+
printf("All tests passed.\n");
sratom_free(sratom);
for (uint32_t i = 0; i < n_uris; ++i) {