[Devel] [RFC] URID extension

David Robillard d at drobilla.net
Thu Jul 21 12:04:25 PDT 2011

On Wed, 2011-07-20 at 23:30 -0500, Gabriel Beddingfield wrote:
> In the uri-map extension, uri_to_id's second parameter ("map") is pretty awkward.  Defining URI=>ID mappings /per extension/ seems like overkill and is confusing to plugin implementers.
> I'm proposing a `urid` extension, and would like your comments on it. It proposes a global registry of URI<==>ID mappings.  This registry maps the same URI's and ID's for all extensions and all plugins.

Thanks for the contribution.

> I've pasted the urid.h header below.  The full extension and a sample implementation may be found here:
>    http://gabe.is-a-geek.org/tmp/urid.lv2-rfc-0.1.tar.bz2

> #define LV2_URID_URI "http://example.tmp/rfc/urid"


> /**
>    URID Feature.
>    To support this feature the host must pass an LV2_Feature struct to the
>    plugin's instantiate method with URI "http://example.tmp/rfc/urid"
>    and data pointed to an instance of this struct.
> */

It was a mistake in the past to use the URI of the extension as the URI
of the feature.  A specific URI for the feature itself should be used,
in this case http://example.org/rfc/urid#URIMap or whatever.

(Note that http://example.org is explicitly reserved for examples and
the like, it's okay to use that rather than a fake TLD, but it doesn't
really matter at this point of course)

> typedef struct {
> 	/**
> 	   Opaque pointer to host data.
> 	   The plugin MUST pass this to any call to functions in this struct.
> 	   Otherwise, it must not be interpreted in any way.
> 	*/
> 	LV2_URID_Callback_Data callback_data;
> 	/**
> 	   Get the numeric ID of a URI from the host.
>            If the ID does not already exist, it will be created.
> 	   @param callback_data Must be the callback_data member of this struct.
> 	   @param uri The URI to be mapped to an integer ID.
> 	   This function is referentially transparent; any number of calls with the
> 	   same arguments is guaranteed to return the same value over the life of a
> 	   plugin instance.  However, this function is not necessarily very
> 	   fast or RT-safe: plugins SHOULD cache any IDs they might need in
>            performance critical situations.
> 	   The return value 0 is reserved and indicates that an ID for that URI
> 	   could not be created for whatever reason. Extensions MAY define more
> 	   precisely what this means in a certain context, but in general plugins
> 	   SHOULD handle this situation as gracefully as possible. However, hosts
> 	   SHOULD NOT return 0 from this function in non-exceptional circumstances
> 	   (e.g. the URI map SHOULD be dynamic). Hosts that statically support only
> 	   a fixed set of URIs should not expect plugins to function correctly.
> 	*/
> 	uint32_t (*get_uri_id)(LV2_URID_Callback_Data callback_data,
>                                const char*            uri);
> 	/**
> 	   Get the URI for a given numeric ID from the host.
> 	   @param callback_data Must be the callback_data member of this struct.
> 	   @param id The ID to be mapped back to the URI string.  Must be a valid,
>            ASCII, URI.  If it is not, then the behavior is undefined.
>            Returns 0 if the ID is not yet assigned.  If the ID has been assigned,
>            then it returns the URI in a canonical form.  This may not be the exact
>            same string that was originally passed to get_uri_id(), but it will be
>            an identical string according to the URI spec.  A non-null return will
>            always be the same for the life of the plugin.
> 	*/
>         const char* (*get_uri)(LV2_URID_Callback_Data callback_data,
>                                uint32_t               id);
> } LV2_URID_Feature;

Sure.  Pretty straightforward one.  Some trivial aesthetic comments:

I would use the names currently in use just to keep things clear,
uri_to_id and id_to_uri.  I could also go with map_uri and unmap_uri
(perhaps better because they are shorter).  Very obviously symmetrical
function names are good.

We could use a typedef for uint32_t just for documentation purposes.
Following convention I guess it would be LV2_URID but that's a bit long
and screamey.

One possible non-trivial change would be to use two separate features
(in this one extension) for mapping and unmapping, since it's more
difficult/expensive to implement both... more logistical nuisance,


More information about the Devel mailing list