From 2813b3f9f6a778641b3ff409a43e969cd8a8fc20 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Mon, 3 Oct 2016 22:56:05 -0400 Subject: Add lv2_atom_object_get_typed() --- lv2/lv2plug.in/ns/ext/atom/lv2-atom.doap.ttl | 9 +++++ lv2/lv2plug.in/ns/ext/atom/manifest.ttl | 2 +- lv2/lv2plug.in/ns/ext/atom/util.h | 56 ++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 1 deletion(-) diff --git a/lv2/lv2plug.in/ns/ext/atom/lv2-atom.doap.ttl b/lv2/lv2plug.in/ns/ext/atom/lv2-atom.doap.ttl index 496124b..0d5d653 100644 --- a/lv2/lv2plug.in/ns/ext/atom/lv2-atom.doap.ttl +++ b/lv2/lv2plug.in/ns/ext/atom/lv2-atom.doap.ttl @@ -12,6 +12,15 @@ doap:created "2007-00-00" ; doap:developer ; doap:release [ + doap:revision "2.1" ; + doap:created "2016-10-03" ; + dcs:blame ; + dcs:changeset [ + dcs:item [ + rdfs:label "Add lv2_atom_object_get_typed() for easy type-safe access to object properties." + ] + ] + ] , [ doap:revision "2.0" ; doap:created "2014-08-08" ; doap:file-release ; diff --git a/lv2/lv2plug.in/ns/ext/atom/manifest.ttl b/lv2/lv2plug.in/ns/ext/atom/manifest.ttl index a672894..ebdf111 100644 --- a/lv2/lv2plug.in/ns/ext/atom/manifest.ttl +++ b/lv2/lv2plug.in/ns/ext/atom/manifest.ttl @@ -4,5 +4,5 @@ a lv2:Specification ; lv2:minorVersion 2 ; - lv2:microVersion 0 ; + lv2:microVersion 1 ; rdfs:seeAlso . diff --git a/lv2/lv2plug.in/ns/ext/atom/util.h b/lv2/lv2plug.in/ns/ext/atom/util.h index 8ac8f28..5574e9b 100644 --- a/lv2/lv2plug.in/ns/ext/atom/util.h +++ b/lv2/lv2plug.in/ns/ext/atom/util.h @@ -441,6 +441,62 @@ lv2_atom_object_get(const LV2_Atom_Object* object, ...) return matches; } +/** + Variable argument version of lv2_atom_object_query() with types. + + This is like lv2_atom_object_get(), but each entry has an additional + parameter to specify the required type. Only atoms with a matching type + will be selected. + + The arguments should be a series of uint32_t key, const LV2_Atom**, uint32_t + type triples, terminated by a zero key. The value pointers MUST be + initialized to NULL. For example: + + @code + const LV2_Atom_String* name = NULL; + const LV2_Atom_Int* age = NULL; + lv2_atom_object_get(obj, + uris.name_key, &name, uris.atom_String, + uris.age_key, &age, uris.atom_Int + 0); + @endcode +*/ +static inline int +lv2_atom_object_get_typed(const LV2_Atom_Object* object, ...) +{ + int matches = 0; + int n_queries = 0; + + /* Count number of keys so we can short-circuit when done */ + va_list args; + va_start(args, object); + for (n_queries = 0; va_arg(args, uint32_t); ++n_queries) { + if (!va_arg(args, const LV2_Atom**) || + !va_arg(args, uint32_t)) { + return -1; + } + } + va_end(args); + + LV2_ATOM_OBJECT_FOREACH(object, prop) { + va_start(args, object); + for (int i = 0; i < n_queries; ++i) { + const uint32_t qkey = va_arg(args, uint32_t); + const LV2_Atom** qval = va_arg(args, const LV2_Atom**); + const uint32_t qtype = va_arg(args, uint32_t); + if (!*qval && qkey == prop->key && qtype == prop->value.type) { + *qval = &prop->value; + if (++matches == n_queries) { + return matches; + } + break; + } + } + va_end(args); + } + return matches; +} + /** @} @} -- cgit v1.2.1