aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lv2/lv2plug.in/ns/ext/atom/atom-test.c32
-rw-r--r--lv2/lv2plug.in/ns/ext/atom/atom.ttl19
-rw-r--r--lv2/lv2plug.in/ns/ext/atom/forge.h60
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;
}