diff options
-rw-r--r-- | lv2/lv2plug.in/ns/ext/atom/atom-test.c | 32 | ||||
-rw-r--r-- | lv2/lv2plug.in/ns/ext/atom/atom.ttl | 19 | ||||
-rw-r--r-- | lv2/lv2plug.in/ns/ext/atom/forge.h | 60 |
3 files changed, 89 insertions, 22 deletions
diff --git a/lv2/lv2plug.in/ns/ext/atom/atom-test.c b/lv2/lv2plug.in/ns/ext/atom/atom-test.c index 563e574..55d453c 100644 --- a/lv2/lv2plug.in/ns/ext/atom/atom-test.c +++ b/lv2/lv2plug.in/ns/ext/atom/atom-test.c @@ -73,6 +73,7 @@ main() 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_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_literal = urid_map(NULL, "http://example.org/literal"); LV2_URID eg_tuple = urid_map(NULL, "http://example.org/tuple"); @@ -80,7 +81,7 @@ main() LV2_URID eg_seq = urid_map(NULL, "http://example.org/seq"); #define BUF_SIZE 1024 -#define NUM_PROPS 12 +#define NUM_PROPS 13 uint8_t buf[BUF_SIZE]; lv2_atom_forge_set_buffer(&forge, buf, BUF_SIZE); @@ -130,20 +131,31 @@ main() return test_fail("%ld != 0 (false)\n", f->value); } - // eg_uri = (URID)"http://example.org/value" - LV2_URID eg_value = urid_map(NULL, "http://example.org/value"); + // eg_uri = (URI)"http://example.org/value" + const uint8_t* ustr = (const uint8_t*)"http://example.org/value"; + const size_t ustr_len = strlen((const char*)ustr); lv2_atom_forge_property_head(&forge, obj, eg_uri, 0); - LV2_Atom_URID* uri = lv2_atom_forge_urid(&forge, obj, eg_value); - if (uri->id != eg_value) { - return test_fail("%u != %u\n", uri->id, eg_value); + LV2_Atom_String* uri = lv2_atom_forge_uri(&forge, obj, ustr, ustr_len); + uint8_t* body = (uint8_t*)LV2_ATOM_BODY(uri); + if (strcmp((const char*)body, (const char*)ustr)) { + return test_fail("%s != \"%s\"\n", + (const char*)body, (const char*)ustr); + } + + // eg_urid = (URID)"http://example.org/value" + LV2_URID eg_value = urid_map(NULL, "http://example.org/value"); + lv2_atom_forge_property_head(&forge, obj, eg_urid, 0); + LV2_Atom_URID* urid = lv2_atom_forge_urid(&forge, obj, eg_value); + if (urid->id != eg_value) { + return test_fail("%u != %u\n", urid->id, eg_value); } // eg_string = (String)"hello" lv2_atom_forge_property_head(&forge, obj, eg_string, 0); LV2_Atom_String* string = lv2_atom_forge_string( &forge, obj, (const uint8_t*)"hello", strlen("hello")); - uint8_t* body = (uint8_t*)LV2_ATOM_BODY(string); - if (strcmp((const char*)body, "hello")) { + uint8_t* sbody = (uint8_t*)LV2_ATOM_BODY(string); + if (strcmp((const char*)sbody, "hello")) { return test_fail("%s != \"hello\"\n", (const char*)body); } @@ -250,6 +262,7 @@ main() const LV2_Atom* affirmative; const LV2_Atom* negative; const LV2_Atom* uri; + const LV2_Atom* urid; const LV2_Atom* string; const LV2_Atom* literal; const LV2_Atom* tuple; @@ -266,7 +279,7 @@ main() { eg_four, &matches.four }, { eg_true, &matches.affirmative }, { eg_false, &matches.negative }, - { eg_uri, &matches.uri }, + { eg_urid, &matches.urid }, { eg_string, &matches.string }, { eg_literal, &matches.literal }, { eg_tuple, &matches.tuple }, @@ -314,6 +327,7 @@ main() eg_true, &matches.affirmative, eg_false, &matches.negative, eg_uri, &matches.uri, + eg_urid, &matches.urid, eg_string, &matches.string, eg_literal, &matches.literal, eg_tuple, &matches.tuple, diff --git a/lv2/lv2plug.in/ns/ext/atom/atom.ttl b/lv2/lv2plug.in/ns/ext/atom/atom.ttl index 9a396bf..b19425f 100644 --- a/lv2/lv2plug.in/ns/ext/atom/atom.ttl +++ b/lv2/lv2plug.in/ns/ext/atom/atom.ttl @@ -218,6 +218,24 @@ void set_to_turtle_string(LV2_Atom_Literal* lit, const char* ttl) { </pre> """ . +atom:URI + a rdfs:Class ; + rdfs:subClassOf atom:String ; + rdfs:label "URI string" ; + lv2:documentation """ +<p>A URI string. This is identical in format to atom:String, except the string +is a URI. This is occasionally useful when a URI is needed but mapping it is +inappropriate. URIs should never be expressed as atom:String, because this +makes it impossible to distinguish URIs from arbitrary strings, which makes +functionality like mapping or rewriting URIs impossible. Similarly, there is +deliberately no atom type for filesystem paths. To refer to a filename, use a +complete file URI, with hostname if at all possible. This allows hosts to +properly handle paths in situations like serialisation or network +transmission.</p> + +<p>Pedantically, this is an <q>IRI</q>, since UTF-8 characters are allowed.</p> +""" . + atom:URID a rdfs:Class ; rdfs:subClassOf atom:Atom ; @@ -392,7 +410,6 @@ atom:ValuePort rdfs:subClassOf atom:AtomPort ; rdfs:label "Value Port" ; lv2:documentation """ - <p>An AtomPort that contains a persistent <em>value</em>. A <q>value</q> is time-independent and may be used numerous times. A ValuePort is <q>pure</q> in the sense that it may affect output but MUST NOT affect persistent plugin state diff --git a/lv2/lv2plug.in/ns/ext/atom/forge.h b/lv2/lv2plug.in/ns/ext/atom/forge.h index 65ab352..9735302 100644 --- a/lv2/lv2plug.in/ns/ext/atom/forge.h +++ b/lv2/lv2plug.in/ns/ext/atom/forge.h @@ -76,6 +76,7 @@ typedef struct { LV2_URID Sequence; LV2_URID String; LV2_URID Tuple; + LV2_URID URI; LV2_URID URID; LV2_URID Vector; } LV2_Atom_Forge; @@ -122,6 +123,7 @@ lv2_atom_forge_init(LV2_Atom_Forge* forge, LV2_URID_Map* map) forge->Sequence = map->map(map->handle, LV2_ATOM_URI "#Sequence"); forge->String = map->map(map->handle, LV2_ATOM_URI "#String"); forge->Tuple = map->map(map->handle, LV2_ATOM_URI "#Tuple"); + forge->URI = map->map(map->handle, LV2_ATOM_URI "#URI"); forge->URID = map->map(map->handle, LV2_ATOM_URI "#URID"); forge->Vector = map->map(map->handle, LV2_ATOM_URI "#Vector"); } @@ -216,6 +218,21 @@ lv2_atom_forge_urid(LV2_Atom_Forge* forge, LV2_Atom* parent, LV2_URID id) return (LV2_Atom_URID*)lv2_atom_forge_write(forge, parent, &a, sizeof(a)); } +/** Write a string body. Used internally. */ +static inline uint8_t* +lv2_atom_forge_string_body(LV2_Atom_Forge* forge, + LV2_Atom* parent, + const uint8_t* str, + size_t len) +{ + uint8_t* out = NULL; + if ((out = lv2_atom_forge_write_nopad(forge, parent, str, len)) + && (out = lv2_atom_forge_write_nopad(forge, parent, "", 1))) { + lv2_atom_forge_pad(forge, parent, len + 1); + } + return out; +} + /** Write an atom:String. Note that @p str need not be NULL terminated. */ static inline LV2_Atom_String* lv2_atom_forge_string(LV2_Atom_Forge* forge, @@ -226,16 +243,38 @@ lv2_atom_forge_string(LV2_Atom_Forge* forge, const LV2_Atom_String a = { { forge->String, len + 1 } }; LV2_Atom_String* out = (LV2_Atom_String*) lv2_atom_forge_write_nopad(forge, parent, &a, sizeof(a)); + if (out) { + if (!lv2_atom_forge_string_body(forge, parent, str, len)) { + out->atom.type = 0; + out->atom.size = 0; + out = NULL; + } + } + return out; +} + +/** + Write an atom:URI. Note that @p uri need not be NULL terminated. + This does not map the URI, but writes the complete URI string. To write + a mapped URI, use lv2_atom_forge_urid(). +*/ +static inline LV2_Atom_String* +lv2_atom_forge_uri(LV2_Atom_Forge* forge, + LV2_Atom* parent, + const uint8_t* uri, + size_t len) +{ + const LV2_Atom_String a = { { forge->URI, len + 1 } }; + LV2_Atom_String* out = (LV2_Atom_String*) + lv2_atom_forge_write_nopad(forge, parent, &a, sizeof(a)); if (!out) { return NULL; } - if (!lv2_atom_forge_write_nopad(forge, parent, str, len) - || !lv2_atom_forge_write_nopad(forge, parent, "", 1)) { + if (!lv2_atom_forge_string_body(forge, parent, uri, len)) { out->atom.type = 0; out->atom.size = 0; return NULL; } - lv2_atom_forge_pad(forge, parent, len + 1); return out; } @@ -256,16 +295,13 @@ lv2_atom_forge_literal(LV2_Atom_Forge* forge, }; LV2_Atom_Literal* out = (LV2_Atom_Literal*) lv2_atom_forge_write_nopad(forge, parent, &a, sizeof(a)); - if (!out) { - return NULL; - } - if (!lv2_atom_forge_write_nopad(forge, parent, str, len) - || !lv2_atom_forge_write_nopad(forge, parent, "", 1)) { - out->atom.type = 0; - out->atom.size = 0; - return NULL; + if (out) { + if (!lv2_atom_forge_string_body(forge, parent, str, len)) { + out->atom.type = 0; + out->atom.size = 0; + out = NULL; + } } - lv2_atom_forge_pad(forge, parent, len + 1); return out; } |