/* lv2_atom.h - C header file for the LV2 Atom extension. * Copyright (C) 2008-2009 David Robillard * * This header is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This header is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this header; if not, write to the Free Software Foundation, * Inc., 59 Temple Place, Suite 330, Boston, MA 01222-1307 USA */ /** @file * C header for the LV2 Atom extension . * 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. */ #ifndef LV2_ATOM_H #define LV2_ATOM_H #define LV2_ATOM_URI "http://lv2plug.in/ns/ext/atom" #define LV2_BLOB_SUPPORT_URI "http://lv2plug.in/ns/ext/atom#blobSupport" #define LV2_ATOM_REFERENCE_TYPE 0 #include #include #define LV2_ATOM_FROM_EVENT(ev) ((LV2_Atom*)&((LV2_Event*)ev)->type) /** An LV2 Atom. * * An "Atom" is a generic chunk of memory with a given type and size. * The type field defines how to interpret an atom. * * All atoms are by definition Plain Old Data (POD) and may be safely * copied (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 LV2 events extension. * The host MAY marshal an LV2_Event to * an LV2_Atom by simply pointing to the * offset of type. The macro LV2_ATOM_FROM_EVENT is provided * in this header for this purpose. */ typedef struct _LV2_Atom { /** The type of this atom. This number is mapped from a URI using * the extension * 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[]; } LV2_Atom; /** Reference, an LV2_Atom with type 0 */ typedef LV2_Atom LV2_Atom_Reference; /** The body of an atom:String */ typedef struct _LV2_Atom_String { uint32_t lang; /**< The ID of the language of this string */ uint8_t str[]; /**< Null-terminated string data in UTF-8 encoding */ } LV2_Atom_String; /** The body of an atom:Vector */ typedef struct _LV2_Atom_Vector { 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 */ } LV2_Atom_Vector; /** The body of an atom:Property */ typedef struct _LV2_Atom_Property { uint32_t key; /**< ID of key (predicate) */ LV2_Atom value; /**< Value (object) */ } LV2_Atom_Property; /** The body of an atom:Resource or atom:Blank */ typedef struct _LV2_Object { uint32_t context; /**< ID of context graph, or 0 for the default context */ uint32_t id; /**< ID for atom:Resource or blank ID for atom:Blank */ uint8_t properties[]; /**< Sequence of LV2_Atom_Property */ } LV2_Object; /* Optional Blob Support */ /** Dynamically Allocated LV2 Blob. * * This is an opaque blob of data of any type, dynamically allocated in memory. * Unlike an LV2_Atom, a blob is not necessarily POD. Plugins MUST only * refer to blobs via a Reference (an LV2_Atom with type 0), there is no * way for a plugin to directly copy or destroy a Blob. * * This is a pointer to host data which is opaque to the plugin. * Plugins MUST NOT interpret this data in any way, except via host-provided * functions in LV2_Blob_Support. */ typedef void* LV2_Blob; typedef void* LV2_Blob_Support_Data; typedef void (*LV2_Blob_Destroy)(LV2_Blob* blob); /** The data field of the LV2_Feature for atom:BlobSupport. * * A host which supports blobs must pass an LV2_Feature to the plugin's * instantiate method with 'URI' = "http://lv2plug.in/ns/ext/atom#BlobSupport" * and 'data' pointing to an instance of this struct. All fields of this * struct MUST be set to non-NULL values by the host, except possibly 'data'. */ typedef struct { /** Pointer to opaque host data. * * The plugin MUST pass this to any call to functions in this struct. * Otherwise, the plugin MUST NOT interpret this value in any way. */ LV2_Blob_Support_Data data; /** The size of a reference, in bytes. * * This value is provided by the host so plugins can allocate large * enough chunks of memory to store references. Note a reference is * an LV2_Atom with type atom:Reference, hence ref_size is a * uint16, like LV2_Atom.size. */ uint16_t ref_size; /** Return the Blob referred to by @a ref. * * The returned value MUST NOT be used in any way other than by calling * methods defined in LV2_Blob_Support (e.g. it MUST NOT be directly * accessed, copied, or destroyed). The actual payload of the blob can * be accessed with LV2_Blob_Support.blob_get. */ LV2_Blob (*ref_get)(LV2_Blob_Support_Data data, LV2_Atom_Reference* ref); /** Copy a reference. * This copies a reference but not the blob it refers to, * i.e. after this call @a dst and @a src refer to the same LV2_Blob. */ void (*ref_copy)(LV2_Blob_Support_Data data, LV2_Atom_Reference* dst, LV2_Atom_Reference* src); /** Reset (release) a reference. * After this call, @a ref is invalid. Implementations must be sure to * call this function when necessary, or memory leaks will result. The * specific times this is necessary MUST be defined by any extensions that * define a mechanism for transporting atoms. The standard semantics are: *
  • Whenever passed a Reference (e.g. via a Port) and run, the * plugin owns that reference.
  • *
  • The plugin owns any reference it creates (e.g. by using blob_new or * ref_copy).
  • *
  • For any reference it owns, the plugin MUST either: *
    • Copy the reference and store it (to be used in future runs and * released later).
    • *
    • Copy the reference to an output port exactly once.
    • *
    • Release it with ref_reset.
  • *
*/ void (*ref_reset)(LV2_Blob_Support_Data data, LV2_Atom_Reference* ref); /** Initialize a reference to point to a newly allocated Blob. * * @param data Must be the data member of this struct. * @param ref Pointer to an area of memory at least as large as * the ref_size field of this struct. On return, this will * be the unique reference to the new blob, which is owned by the * caller. Assumed to be uninitialised, i.e. the caller MUST NOT * pass a valid reference since this could cause a memory leak. * @param destroy Function to destroy this blob. This function * MUST clean up any resources contained in the blob, but MUST NOT * attempt to free the memory pointed to by its LV2_Blob* parameter * (since this is allocated by the host). * @param type ID of type of blob to allocate. * @param size Size of blob to allocate in bytes. */ void (*blob_new)(LV2_Blob_Support_Data data, LV2_Atom_Reference* ref, LV2_Blob_Destroy destroy, uint32_t type, size_t size); /** Get blob's type as an ID. * * The return value may be any type URI, mapped to an integer with the * URI Map extension with context = NULL. */ uint32_t (*blob_type)(LV2_Blob blob); /** Get blob's body. * * Returns a pointer to the start of the blob data. The format of this * data is defined by the return value of the type method. It MUST NOT * be used in any way by code which does not understand that type. */ void* (*blob_data)(LV2_Blob blob); } LV2_Blob_Support; #endif /* LV2_ATOM_H */