aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2011-11-09 01:08:14 +0000
committerDavid Robillard <d@drobilla.net>2011-11-09 01:08:14 +0000
commit7b90f2dac53b7cd17fb9499c4cedf2b301d90129 (patch)
tree7e7c6a42dede9a090de04093f289ac4056e0610b
parent672ba53efd1b6a39748b919f015761a7ef270d66 (diff)
downloadlv2-7b90f2dac53b7cd17fb9499c4cedf2b301d90129.tar.xz
Define types as complete objects, not just atom bodies.
Improve helper API.
-rw-r--r--ext/atom.lv2/atom-buffer.h21
-rw-r--r--ext/atom.lv2/atom-helpers.h72
-rw-r--r--ext/atom.lv2/atom.h138
-rw-r--r--ext/atom.lv2/forge.h75
4 files changed, 170 insertions, 136 deletions
diff --git a/ext/atom.lv2/atom-buffer.h b/ext/atom.lv2/atom-buffer.h
index 2ac71e3..f4b90dd 100644
--- a/ext/atom.lv2/atom-buffer.h
+++ b/ext/atom.lv2/atom-buffer.h
@@ -28,20 +28,10 @@
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
-#include <assert.h>
#include "lv2/lv2plug.in/ns/ext/atom/atom.h"
/**
- Pad a size to 64 bits.
-*/
-static inline uint32_t
-lv2_atom_pad_size(uint32_t size)
-{
- return (size + 7) & (~7);
-}
-
-/**
Initialize an existing atom buffer.
All fields of @c buf are reset, except capacity which is unmodified.
*/
@@ -111,9 +101,10 @@ lv2_atom_buffer_is_valid(LV2_Atom_Buffer_Iterator i)
static inline LV2_Atom_Buffer_Iterator
lv2_atom_buffer_next(LV2_Atom_Buffer_Iterator i)
{
- assert(lv2_atom_buffer_is_valid(i));
- const LV2_Atom_Event* const ev = (LV2_Atom_Event*)(
- i.buf->data + i.offset);
+ if (!lv2_atom_buffer_is_valid(i)) {
+ return i;
+ }
+ const LV2_Atom_Event* const ev = (LV2_Atom_Event*)(i.buf->data + i.offset);
i.offset += lv2_atom_pad_size(sizeof(LV2_Atom_Event) + ev->body.size);
return i;
}
@@ -124,7 +115,9 @@ lv2_atom_buffer_next(LV2_Atom_Buffer_Iterator i)
static inline LV2_Atom_Event*
lv2_atom_buffer_get(LV2_Atom_Buffer_Iterator i)
{
- assert(lv2_event_is_valid(i));
+ if (!lv2_atom_buffer_is_valid(i)) {
+ return NULL;
+ }
return (LV2_Atom_Event*)(i.buf->data + i.offset);
}
diff --git a/ext/atom.lv2/atom-helpers.h b/ext/atom.lv2/atom-helpers.h
index ae4bc6f..9d48a29 100644
--- a/ext/atom.lv2/atom-helpers.h
+++ b/ext/atom.lv2/atom-helpers.h
@@ -34,27 +34,20 @@
#include "lv2/lv2plug.in/ns/ext/atom/atom.h"
-/** Pad a size to 4 bytes (32 bits) */
-static inline uint16_t
-lv2_atom_pad_size(uint16_t size)
-{
- return (size + 3) & (~3);
-}
-
typedef LV2_Atom_Property* LV2_Object_Iter;
/** Get an iterator pointing to @c prop in some LV2_Object */
static inline LV2_Object_Iter
-lv2_object_begin(const LV2_Atom* obj)
+lv2_object_begin(const LV2_Object* obj)
{
- return (LV2_Object_Iter)(((const LV2_Object*)obj->body)->properties);
+ return (LV2_Object_Iter)(obj->properties);
}
/** Return true iff @c iter has reached the end of @c object */
static inline bool
-lv2_object_iter_is_end(const LV2_Atom* object, LV2_Object_Iter iter)
+lv2_object_iter_is_end(const LV2_Object* obj, LV2_Object_Iter iter)
{
- return (uint8_t*)iter >= ((uint8_t*)object->body + object->size);
+ return (uint8_t*)iter >= ((uint8_t*)obj + sizeof(LV2_Atom) + obj->size);
}
/** Return true iff @c l points to the same property as @c r */
@@ -113,14 +106,15 @@ lv2_object_iter_get(LV2_Object_Iter iter)
Atom type that contains headerless 32-bit aligned properties.
*/
static inline LV2_Atom_Property*
-lv2_atom_append_property(LV2_Atom* object,
- uint32_t key,
- uint16_t value_type,
- uint16_t value_size,
- const uint8_t* value_body)
+lv2_object_append(LV2_Object* object,
+ uint32_t key,
+ uint32_t value_type,
+ uint32_t value_size,
+ const void* value_body)
{
object->size = lv2_atom_pad_size(object->size);
- LV2_Atom_Property* prop = (LV2_Atom_Property*)(object->body + object->size);
+ LV2_Atom_Property* prop = (LV2_Atom_Property*)(
+ (uint8_t*)object + sizeof(LV2_Atom) + object->size);
prop->key = key;
prop->value.type = value_type;
prop->value.size = value_size;
@@ -136,44 +130,14 @@ lv2_atom_is_null(LV2_Atom* atom)
return !atom || (atom->type == 0 && atom->size == 0);
}
-/** Return true iff @c object has rdf:type @c type */
-static inline bool
-lv2_atom_is_a(LV2_Atom* object,
- uint32_t rdf_type,
- uint32_t atom_URIInt,
- uint32_t atom_Object,
- uint32_t type)
-{
- if (lv2_atom_is_null(object))
- return false;
-
- if (object->type == type)
- return true;
-
- if (object->type == atom_Object) {
- LV2_OBJECT_FOREACH(object, o) {
- LV2_Atom_Property* prop = lv2_object_iter_get(o);
- if (prop->key == rdf_type) {
- if (prop->value.type == atom_URIInt) {
- const uint32_t object_type = *(uint32_t*)prop->value.body;
- if (object_type == type)
- return true;
- } else {
- fprintf(stderr, "error: rdf:type is not a URIInt\n");
- }
- }
- }
- }
-
- return false;
-}
-
/** A single entry in an Object query. */
typedef struct {
- uint32_t key; /**< Key to query (input set by user) */
- const LV2_Atom* value; /**< Found value (output set by query function) */
+ uint32_t key; /**< Key to query (input set by user) */
+ const LV2_Atom** value; /**< Found value (output set by query function) */
} LV2_Object_Query;
+static const LV2_Object_Query LV2_OBJECT_QUERY_END = { 0, NULL };
+
/**
"Query" an object, getting a pointer to the values for various keys.
@@ -184,7 +148,7 @@ typedef struct {
quickly without allocating any memory. This function is realtime safe.
*/
static inline int
-lv2_object_query(const LV2_Atom* object, LV2_Object_Query* query)
+lv2_object_query(const LV2_Object* object, LV2_Object_Query* query)
{
int matches = 0;
int n_queries = 0;
@@ -196,8 +160,8 @@ lv2_object_query(const LV2_Atom* object, LV2_Object_Query* query)
LV2_OBJECT_FOREACH(object, o) {
const LV2_Atom_Property* prop = lv2_object_iter_get(o);
for (LV2_Object_Query* q = query; q->key; ++q) {
- if (q->key == prop->key && !q->value) {
- q->value = &prop->value;
+ if (q->key == prop->key && !*q->value) {
+ *q->value = &prop->value;
if (++matches == n_queries)
return matches;
break;
diff --git a/ext/atom.lv2/atom.h b/ext/atom.lv2/atom.h
index 61482c7..d617435 100644
--- a/ext/atom.lv2/atom.h
+++ b/ext/atom.lv2/atom.h
@@ -18,11 +18,8 @@
@file atom.h C header for the LV2 Atom extension
<http://lv2plug.in/ns/ext/atom>.
- This extension defines convenience structs that should match the definition
- of the built-in types of the atom extension. The layout of atoms in this
- header must match the description in RDF. The RDF description of an atom
- type should be considered normative. This header is a non-normative (but
- hopefully accurate) implementation of that specification.
+ This header describes the binary layout of various types defined in the
+ atom extension.
*/
#ifndef LV2_ATOM_H
@@ -35,6 +32,10 @@
#include <stdint.h>
#include <stddef.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/**
An LV2 Atom.
@@ -45,70 +46,76 @@
(e.g. with memcpy) using the size field, except atoms with type 0. An atom
with type 0 is a reference, and may only be used via the functions provided
in LV2_Blob_Support (e.g. it MUST NOT be manually copied).
-
- Note that an LV2_Atom is the latter two fields of an LV2_Event as defined by
- the <a href="http://lv2plug.in/ns/ext/event">LV2 events extension</a>. The
- host MAY marshal an LV2_Event to an LV2_Atom by simply pointing to the
- offset of <code>type</code>. The macro LV2_ATOM_FROM_EVENT is provided in
- this header for this purpose.
*/
typedef struct {
-
- /**
- The type of this atom.
-
- This number is mapped from a URI using the extension
- <http://lv2plug.in/ns/ext/uri-map> with 'map' =
- "http://lv2plug.in/ns/ext/atom". Type 0 is a special case which
- indicates this atom is a reference and MUST NOT be copied manually.
- */
- uint16_t type;
-
- /**
- The size of this atom, not including this header, in bytes.
- */
- uint16_t size;
-
- /**
- Size bytes of data follow here.
- */
- uint8_t body[];
-
+ uint32_t type; /**< Type of this atom (mapped URI). */
+ uint32_t size; /**< Size in bytes, not including type and size. */
+ uint8_t body[]; /**< Body of length @ref size bytes. */
} LV2_Atom;
/**
- The body of an atom:Literal.
+ An atom:String.
+ This type may safely be cast to LV2_Atom.
*/
typedef struct {
- uint32_t datatype; /**< The ID of the datatype of this literal */
- uint32_t lang; /**< The ID of the language of this literal */
- uint8_t str[]; /**< Null-terminated string data in UTF-8 encoding */
+ uint32_t type; /**< Type of this atom (mapped URI). */
+ uint32_t size; /**< Size in bytes, not including type and size. */
+ uint8_t str[]; /**< Null-terminated string data in UTF-8 encoding. */
+} LV2_Atom_String;
+
+/**
+ An atom:Literal.
+ This type may safely be cast to LV2_Atom.
+*/
+typedef struct {
+ uint32_t type; /**< Type of this atom (mapped URI). */
+ uint32_t size; /**< Size in bytes, not including type and size. */
+ uint32_t datatype; /**< The ID of the datatype of this literal. */
+ uint32_t lang; /**< The ID of the language of this literal. */
+ uint8_t str[]; /**< Null-terminated string data in UTF-8 encoding. */
} LV2_Atom_Literal;
/**
- The body of an atom:Vector.
+ An atom:ID.
+ This type may safely be cast to LV2_Atom.
*/
typedef struct {
- uint16_t elem_count; /**< The number of elements in the vector */
- uint16_t elem_type; /**< The type of each element in the vector */
- uint8_t elems[]; /**< Sequence of element bodies */
+ uint32_t type; /**< Type of this atom (mapped URI). */
+ uint32_t size; /**< Size in bytes, not including type and size. */
+ uint32_t id; /**< Value, a URI mapped to an integer. */
+} LV2_Atom_ID;
+
+/**
+ An atom:Vector.
+ This type may safely be cast to LV2_Atom.
+*/
+typedef struct {
+ uint32_t type; /**< Type of this atom (mapped URI). */
+ uint32_t size; /**< Size in bytes, not including type and size. */
+ uint32_t elem_count; /**< The number of elements in the vector */
+ uint32_t elem_type; /**< The type of each element in the vector */
+ uint8_t elems[]; /**< Sequence of element bodies */
} LV2_Atom_Vector;
/**
The body of an atom:Property.
+ Note this type is not an LV2_Atom.
*/
typedef struct _LV2_Atom_Property {
- uint32_t key; /**< ID of key (predicate) */
- LV2_Atom value; /**< Value (object) */
+ uint32_t key; /**< Key (predicate) (mapped URI). */
+ LV2_Atom value; /**< Value (object) */
} LV2_Atom_Property;
/**
- The body of an atom:Resource or atom:Blank.
+ An atom:Object (atom:Resource or atom:Blank).
+ This type may safely be cast to LV2_Atom.
*/
typedef struct {
- uint32_t context; /**< ID of context graph, or 0 for default */
- uint32_t id; /**< URID (for Resource) or blank ID (for Blank) */
- uint8_t properties[]; /**< Sequence of LV2_Atom_Property */
+ uint32_t type; /**< Type of this atom (mapped URI). */
+ uint32_t size; /**< Size in bytes, not including type and size. */
+ uint32_t context; /**< ID of context graph, or 0 for default */
+ uint32_t id; /**< URID (for Resource) or blank ID (for Blank) */
+ uint8_t properties[]; /**< Sequence of LV2_Atom_Property */
} LV2_Object;
/**
@@ -121,27 +128,9 @@ typedef struct {
the @ref body field of the Event.
*/
typedef struct {
-
- /**
- The frames portion of timestamp. The unit of this value may depend on
- context, but for events processed by LV2_Descriptor::run() the unit is
- audio frames relative to this block (e.g. frame 0 is the first frame in
- this call to run())
- */
- uint32_t frames;
-
- /**
- The sub-frames portion of timestamp. The unit of this value may depend
- on context, but for events processed by LV2_Descriptor::run() the unit
- is 1/(2^32) of an audio frame.
- */
- uint32_t subframes;
-
- /**
- The body of this event.
- */
- LV2_Atom body;
-
+ uint32_t frames; /**< Time in frames relative to this block. */
+ uint32_t subframes; /**< Fractional time in 1/(2^32)ths of a frame. */
+ LV2_Atom body; /**< Event body. */
} LV2_Atom_Event;
/**
@@ -208,4 +197,17 @@ typedef struct {
} LV2_Atom_Buffer;
-#endif /* LV2_ATOM_H */
+/**
+ Pad a size to 64 bits.
+*/
+static inline uint32_t
+lv2_atom_pad_size(uint32_t size)
+{
+ return (size + 7) & (~7);
+}
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* LV2_ATOM_H */
diff --git a/ext/atom.lv2/forge.h b/ext/atom.lv2/forge.h
new file mode 100644
index 0000000..f1ffb03
--- /dev/null
+++ b/ext/atom.lv2/forge.h
@@ -0,0 +1,75 @@
+/*
+ Copyright 2008-2011 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.
+*/
+
+/**
+ @file forge.h Helper constructor functions for LV2 atoms.
+*/
+
+#ifndef LV2_ATOM_FORGE_H
+#define LV2_ATOM_FORGE_H
+
+#include "lv2/lv2plug.in/ns/ext/atom/atom.h"
+#include "lv2/lv2plug.in/ns/ext/urid/urid.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ uint32_t ID;
+ uint32_t Message;
+ uint32_t Property;
+} LV2_Atom_Forge;
+
+static inline LV2_Atom_Forge*
+lv2_atom_forge_new(LV2_URID_Mapper* mapper)
+{
+ LV2_Atom_Forge* forge = (LV2_Atom_Forge*)malloc(sizeof(LV2_Atom_Forge));
+ forge->ID = mapper->map_uri(mapper->handle, LV2_ATOM_URI "#ID");
+ forge->Message = mapper->map_uri(mapper->handle, LV2_ATOM_URI "#Message");
+ forge->Property = mapper->map_uri(mapper->handle, LV2_ATOM_URI "#Property");
+ return forge;
+}
+
+static inline void
+lv2_atom_forge_free(LV2_Atom_Forge* forge)
+{
+ free(forge);
+}
+
+static inline LV2_Atom_ID
+lv2_atom_forge_make_id(LV2_Atom_Forge* forge, uint32_t id)
+{
+ const LV2_Atom_ID atom = { forge->ID, sizeof(uint32_t), id };
+ return atom;
+}
+
+static inline void
+lv2_atom_forge_set_message(LV2_Atom_Forge* forge,
+ LV2_Object* msg,
+ uint32_t id)
+{
+ msg->type = forge->Message;
+ msg->size = sizeof(LV2_Object) - sizeof(LV2_Atom);
+ msg->context = 0;
+ msg->id = id;
+}
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* LV2_ATOM_FORGE_H */