From e45691df6be3f9a14cab019437ce2f2e8a54427e Mon Sep 17 00:00:00 2001 From: David Robillard Date: Tue, 6 Mar 2012 05:05:40 +0000 Subject: Use raw type/size/value instead of LilvNode for port values. Remove use of half-baked node_to_serd() and use sratom for port values as well. git-svn-id: http://svn.drobilla.net/lad/trunk/lilv@4023 a436a847-0d15-0410-975c-d299462d15a1 --- lilv/lilv.h | 29 +++++++++++---- src/state.c | 108 ++++++++++++++++++++++++------------------------------- test/lilv_test.c | 35 ++++++++++++------ wscript | 2 +- 4 files changed, 94 insertions(+), 80 deletions(-) diff --git a/lilv/lilv.h b/lilv/lilv.h index ae5c557..5634835 100644 --- a/lilv/lilv.h +++ b/lilv/lilv.h @@ -1156,10 +1156,18 @@ lilv_state_new_from_file(LilvWorld* world, /** Function to get a port value. - @return A node the caller (lilv) takes ownership of and must free. + @param port_symbol The symbol of the port. + @param user_data The user_data passed to lilv_state_new_from_instance(). + @param size (Output) The size of the returned value. + @param type (Output) The URID of the type of the returned value. + @return A pointer to the port value. + + This function MUST set @p size and @p type appropriately. */ -typedef LilvNode* (*LilvGetPortValueFunc)(const char* port_symbol, - void* user_data); +typedef const void* (*LilvGetPortValueFunc)(const char* port_symbol, + void* user_data, + uint32_t* size, + uint32_t* type); /** Create a new state snapshot from a plugin instance. @@ -1277,10 +1285,17 @@ lilv_state_set_label(LilvState* state, /** Function to set a port value. -*/ -typedef void (*LilvSetPortValueFunc)(const char* port_symbol, - const LilvNode* value, - void* user_data); + @param port_symbol The symbol of the port. + @param user_data The user_data passed to lilv_state_restore(). + @param size The size of @p value. + @param type The URID of the type of @p value. + @param value A pointer to the port value. +*/ +typedef void (*LilvSetPortValueFunc)(const char* port_symbol, + void* user_data, + const void* value, + uint32_t size, + uint32_t type); /** Restore a plugin instance from a state snapshot. diff --git a/src/state.c b/src/state.c index a9bd1ec..23c4f96 100644 --- a/src/state.c +++ b/src/state.c @@ -36,16 +36,18 @@ #define USTR(s) ((const uint8_t*)(s)) typedef struct { - void* value; - size_t size; - uint32_t key; - uint32_t type; - uint32_t flags; + void* value; ///< Value/Object + size_t size; ///< Size of value + uint32_t key; ///< Key/Predicate (URID) + uint32_t type; ///< Type of value (URID) + uint32_t flags; ///< State flags (POD, etc) } Property; typedef struct { - char* symbol; ///< Symbol of port - LilvNode* value; ///< Value of port + char* symbol; ///< Symbol of port + void* value; ///< Value of port + uint32_t size; ///< Size of value + uint32_t type; ///< Type of value (URID) } PortValue; typedef struct { @@ -103,14 +105,21 @@ path_rel_free(void* ptr) } static PortValue* -append_port_value(LilvState* state, const char* port_symbol, LilvNode* value) +append_port_value(LilvState* state, + const char* port_symbol, + const void* value, + uint32_t size, + uint32_t type) { if (value) { state->values = (PortValue*)realloc( state->values, (++state->num_values) * sizeof(PortValue)); PortValue* pv = &state->values[state->num_values - 1]; pv->symbol = lilv_strdup(port_symbol); - pv->value = value; + pv->value = malloc(size); + pv->size = size; + pv->type = type; + memcpy(pv->value, value, size); return pv; } return NULL; @@ -362,8 +371,10 @@ lilv_state_new_from_instance(const LilvPlugin* plugin, const LilvPort* const port = plugin->ports[i]; if (lilv_port_is_a(plugin, port, lv2_ControlPort) && lilv_port_is_a(plugin, port, lv2_InputPort)) { - const char* sym = lilv_node_as_string(port->symbol); - append_port_value(state, sym, get_value(sym, user_data)); + uint32_t size, type; + const char* sym = lilv_node_as_string(port->symbol); + const void* value = get_value(sym, user_data, &size, &type); + append_port_value(state, sym, value, size, type); } } lilv_node_free(lv2_ControlPort); @@ -423,9 +434,9 @@ lilv_state_restore(const LilvState* state, if (set_value) { for (uint32_t i = 0; i < state->num_values; ++i) { - set_value(state->values[i].symbol, - state->values[i].value, - user_data); + const PortValue* val = &state->values[i]; + set_value(val->symbol, user_data, + val->value, val->size, val->type); } } } @@ -482,6 +493,13 @@ new_state_from_model(LilvWorld* world, sord_iter_free(i); } + Sratom* sratom = sratom_new(map); + SerdChunk chunk = { NULL, 0 }; + LV2_Atom_Forge forge; + lv2_atom_forge_init(&forge, map); + lv2_atom_forge_set_sink( + &forge, sratom_forge_sink, sratom_forge_deref, &chunk); + // Get port values const SordQuad ppat = { node, world->uris.lv2_port, NULL, NULL }; SordIter* ports = sord_find(model, ppat); @@ -498,9 +516,13 @@ new_state_from_model(LilvWorld* world, sord_node_get_string(symbol), sord_node_get_string(node)); } else { + chunk.len = 0; + sratom_read(sratom, &forge, world->world, model, value); + LV2_Atom* atom = (LV2_Atom*)chunk.buf; + append_port_value(state, (const char*)sord_node_get_string(symbol), - lilv_node_new_from_node(world, value)); + LV2_ATOM_BODY(atom), atom->size, atom->type); if (label) { lilv_state_set_label(state, @@ -521,10 +543,6 @@ new_state_from_model(LilvWorld* world, if (state_node) { const SordQuad spat = { state_node, NULL, NULL }; SordIter* props = sord_find(model, spat); - Sratom* sratom = sratom_new(map); - SerdChunk chunk = { NULL, 0 }; - LV2_Atom_Forge forge; - lv2_atom_forge_init(&forge, map); FOREACH_MATCH(props) { const SordNode* p = sord_iter_get_node(props, SORD_PREDICATE); @@ -563,13 +581,14 @@ new_state_from_model(LilvWorld* world, } } sord_iter_free(props); - sratom_free(sratom); } sord_node_free(world->world, statep); #ifdef HAVE_LV2_STATE sord_node_free(world->world, atom_path_node); #endif + sratom_free(sratom); + qsort(state->props, state->num_props, sizeof(Property), property_cmp); qsort(state->values, state->num_values, sizeof(PortValue), value_cmp); @@ -634,38 +653,6 @@ lilv_state_new_from_file(LilvWorld* world, return state; } -static void -node_to_serd(const LilvNode* node, SerdNode* value, SerdNode* type) -{ - const char* type_uri = NULL; - switch (node->type) { - case LILV_VALUE_URI: - *value = serd_node_from_string(SERD_URI, USTR(node->str_val)); - break; - case LILV_VALUE_BLANK: - *value = serd_node_from_string(SERD_BLANK, USTR(node->str_val)); - break; - default: - *value = serd_node_from_string(SERD_LITERAL, USTR(node->str_val)); - switch (node->type) { - case LILV_VALUE_BOOL: - type_uri = LILV_NS_XSD "boolean"; - break; - case LILV_VALUE_INT: - type_uri = LILV_NS_XSD "integer"; - break; - case LILV_VALUE_FLOAT: - type_uri = LILV_NS_XSD "decimal"; - break; - default: - break; - } - } - *type = (type_uri) - ? serd_node_from_string(SERD_URI, USTR(type_uri)) - : SERD_NODE_NULL; -} - static SerdWriter* ttl_writer(SerdSink sink, void* stream, const uint8_t* uri, SerdEnv** new_env) { @@ -822,6 +809,8 @@ lilv_state_write(LilvWorld* world, NULL, &subject, &p, &o, NULL, NULL); } + Sratom* sratom = sratom_new(map); + // Write port values for (uint32_t i = 0; i < state->num_values; ++i) { PortValue* const value = &state->values[i]; @@ -842,10 +831,8 @@ lilv_state_write(LilvWorld* world, // _:symbol pset:value value p = serd_node_from_string(SERD_URI, USTR(NS_PSET "value")); - SerdNode t; - node_to_serd(value->value, &o, &t); - serd_writer_write_statement(writer, SERD_ANON_CONT, NULL, - &port, &p, &o, &t, NULL); + sratom_write(sratom, unmap, writer, SERD_ANON_CONT, &port, &p, + value->type, value->size, value->value); serd_writer_end_anon(writer, &port); } @@ -858,7 +845,6 @@ lilv_state_write(LilvWorld* world, serd_writer_write_statement(writer, SERD_ANON_O_BEGIN, NULL, &subject, &p, &state_node, NULL, NULL); } - Sratom* sratom = sratom_new(map); for (uint32_t i = 0; i < state->num_props; ++i) { Property* prop = &state->props[i]; const char* key = unmap->unmap(unmap->handle, prop->key); @@ -1001,7 +987,7 @@ lilv_state_free(LilvState* state) free(state->props[i].value); } for (uint32_t i = 0; i < state->num_values; ++i) { - lilv_node_free(state->values[i].value); + free(state->values[i].value); free(state->values[i].symbol); } lilv_node_free(state->plugin_uri); @@ -1032,9 +1018,9 @@ lilv_state_equals(const LilvState* a, const LilvState* b) for (uint32_t i = 0; i < a->num_values; ++i) { PortValue* const av = &a->values[i]; PortValue* const bv = &b->values[i]; - if (strcmp(av->symbol, bv->symbol)) { - return false; - } else if (!lilv_node_equals(av->value, bv->value)) { + if (av->size != bv->size || av->type != bv->type + || strcmp(av->symbol, bv->symbol) + || memcmp(av->value, bv->value, av->size)) { return false; } } diff --git a/test/lilv_test.c b/test/lilv_test.c index 2352150..db2dca5 100644 --- a/test/lilv_test.c +++ b/test/lilv_test.c @@ -1070,32 +1070,43 @@ test_ui(void) /*****************************************************************************/ -float in = 1.0; -float out = 42.0; - -LilvNode* -get_port_value(const char* port_symbol, void* user_data) +uint32_t atom_Float = 0; +float in = 1.0; +float out = 42.0; + +const void* +get_port_value(const char* port_symbol, + void* user_data, + uint32_t* size, + uint32_t* type) { if (!strcmp(port_symbol, "input")) { - return lilv_new_float((LilvWorld*)user_data, in); + *size = sizeof(float); + *type = atom_Float; + return ∈ } else if (!strcmp(port_symbol, "output")) { - return lilv_new_float((LilvWorld*)user_data, out); + *size = sizeof(float); + *type = atom_Float; + return &out; } else { fprintf(stderr, "error: get_port_value for nonexistent port `%s'\n", port_symbol); + *size = *type = 0; return NULL; } } void set_port_value(const char* port_symbol, - const LilvNode* value, - void* user_data) + void* user_data, + const void* value, + uint32_t size, + uint32_t type) { if (!strcmp(port_symbol, "input")) { - in = lilv_node_as_float(value); + in = *(float*)value; } else if (!strcmp(port_symbol, "output")) { - out = lilv_node_as_float(value); + out = *(float*)value; } else { fprintf(stderr, "error: set_port_value for nonexistent port `%s'\n", port_symbol); @@ -1158,6 +1169,8 @@ test_state(void) LV2_Feature unmap_feature = { LV2_URID_UNMAP_URI, &unmap }; const LV2_Feature* features[] = { &map_feature, &unmap_feature, NULL }; + atom_Float = map.map(map.handle, "http://lv2plug.in/ns/ext/atom#Float"); + LilvNode* num = lilv_new_int(world, 5); LilvState* nostate = lilv_state_new_from_file(world, &map, num, "/junk"); TEST_ASSERT(!nostate); diff --git a/wscript b/wscript index fc8252e..680f07c 100644 --- a/wscript +++ b/wscript @@ -8,7 +8,7 @@ import waflib.Options as Options import waflib.Logs as Logs # Version of this package (even if built as a child) -LILV_VERSION = '0.11.0' +LILV_VERSION = '0.12.0' LILV_MAJOR_VERSION = '0' # Library version (UNIX style major, minor, micro) -- cgit v1.2.1