diff options
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | src/collections.c | 4 | ||||
-rw-r--r-- | src/lilv_internal.h | 17 | ||||
-rw-r--r-- | src/node.c | 124 | ||||
-rw-r--r-- | src/plugin.c | 54 | ||||
-rw-r--r-- | src/port.c | 3 | ||||
-rw-r--r-- | src/state.c | 6 | ||||
-rw-r--r-- | src/world.c | 24 |
8 files changed, 108 insertions, 125 deletions
@@ -6,6 +6,7 @@ lilv (9999) unstable; * Fix documentation for ui_type parameter of lilv_ui_is_supported() * Fix crash when lv2info is run with an invalid URI argument * Gracefully handle failure to save plugin state and print error message + * Reduce memory usage (per node) -- David Robillard <d@drobilla.net> diff --git a/src/collections.c b/src/collections.c index dd676e6..f7a035a 100644 --- a/src/collections.c +++ b/src/collections.c @@ -25,8 +25,8 @@ lilv_ptr_cmp(const void* a, const void* b, void* user_data) int lilv_resource_node_cmp(const void* a, const void* b, void* user_data) { - const SordNode* an = ((const LilvNode*)a)->val.uri_val; - const SordNode* bn = ((const LilvNode*)b)->val.uri_val; + const SordNode* an = ((const LilvNode*)a)->node; + const SordNode* bn = ((const LilvNode*)b)->node; return (intptr_t)an - (intptr_t)bn; } diff --git a/src/lilv_internal.h b/src/lilv_internal.h index 51c3863..f23b7a2 100644 --- a/src/lilv_internal.h +++ b/src/lilv_internal.h @@ -201,19 +201,14 @@ typedef enum { } LilvNodeType; struct LilvNodeImpl { - LilvWorld* world; - char* str_val; ///< always present + LilvWorld* world; + SordNode* node; + LilvNodeType type; union { - int int_val; - float float_val; - bool bool_val; - SordNode* uri_val; - struct { - void* buf; - size_t size; - } blob_val; + int int_val; + float float_val; + bool bool_val; } val; - LilvNodeType type; }; struct LilvScalePointImpl { @@ -23,25 +23,24 @@ static void lilv_node_set_numerics_from_string(LilvNode* val, size_t len) { - char* endptr; + const char* str = (const char*)sord_node_get_string(val->node); + char* endptr; switch (val->type) { case LILV_VALUE_URI: case LILV_VALUE_BLANK: case LILV_VALUE_STRING: + case LILV_VALUE_BLOB: break; case LILV_VALUE_INT: - val->val.int_val = strtol(val->str_val, &endptr, 10); + val->val.int_val = strtol(str, &endptr, 10); break; case LILV_VALUE_FLOAT: - val->val.float_val = serd_strtod(val->str_val, &endptr); + val->val.float_val = serd_strtod(str, &endptr); break; case LILV_VALUE_BOOL: - val->val.bool_val = (!strcmp(val->str_val, "true")); + val->val.bool_val = !strcmp(str, "true"); break; - case LILV_VALUE_BLOB: - val->val.blob_val.buf = serd_base64_decode( - (const uint8_t*)val->str_val, len, &val->val.blob_val.size); } } @@ -57,33 +56,35 @@ lilv_node_new(LilvWorld* world, LilvNodeType type, const char* str) val->world = world; val->type = type; + const uint8_t* ustr = (const uint8_t*)str; switch (type) { case LILV_VALUE_URI: - val->val.uri_val = sord_new_uri(world->world, (const uint8_t*)str); + val->node = sord_new_uri(world->world, ustr); break; case LILV_VALUE_BLANK: - val->val.uri_val = sord_new_blank(world->world, (const uint8_t*)str); + val->node = sord_new_blank(world->world, ustr); break; case LILV_VALUE_STRING: + val->node = sord_new_literal(world->world, NULL, ustr, NULL); + break; case LILV_VALUE_INT: + val->node = sord_new_literal( + world->world, world->uris.xsd_integer, ustr, NULL); + break; case LILV_VALUE_FLOAT: + val->node = sord_new_literal( + world->world, world->uris.xsd_decimal, ustr, NULL); + break; case LILV_VALUE_BOOL: + val->node = sord_new_literal( + world->world, world->uris.xsd_boolean, ustr, NULL); + break; case LILV_VALUE_BLOB: - val->str_val = lilv_strdup(str); + val->node = sord_new_literal( + world->world, world->uris.xsd_base64Binary, ustr, NULL); break; } - switch (type) { - case LILV_VALUE_URI: - case LILV_VALUE_BLANK: - if (!val->val.uri_val) { - free(val); - return NULL; - } - val->str_val = (char*)sord_node_get_string(val->val.uri_val); - default: break; - } - return val; } @@ -98,18 +99,16 @@ lilv_node_new_from_node(LilvWorld* world, const SordNode* node) switch (sord_node_get_type(node)) { case SORD_URI: - result = (LilvNode*)malloc(sizeof(LilvNode)); - result->world = (LilvWorld*)world; - result->type = LILV_VALUE_URI; - result->val.uri_val = sord_node_copy(node); - result->str_val = (char*)sord_node_get_string(result->val.uri_val); + result = (LilvNode*)malloc(sizeof(LilvNode)); + result->world = (LilvWorld*)world; + result->type = LILV_VALUE_URI; + result->node = sord_node_copy(node); break; case SORD_BLANK: - result = (LilvNode*)malloc(sizeof(LilvNode)); - result->world = (LilvWorld*)world; - result->type = LILV_VALUE_BLANK; - result->val.uri_val = sord_node_copy(node); - result->str_val = (char*)sord_node_get_string(result->val.uri_val); + result = (LilvNode*)malloc(sizeof(LilvNode)); + result->world = (LilvWorld*)world; + result->type = LILV_VALUE_BLANK; + result->node = sord_node_copy(node); break; case SORD_LITERAL: datatype_uri = sord_node_get_datatype(node); @@ -189,24 +188,15 @@ LILV_API LilvNode* lilv_node_duplicate(const LilvNode* val) { - if (val == NULL) + if (!val) { return NULL; + } LilvNode* result = (LilvNode*)malloc(sizeof(LilvNode)); result->world = val->world; - result->type = val->type; - - switch (val->type) { - case LILV_VALUE_URI: - case LILV_VALUE_BLANK: - result->val.uri_val = sord_node_copy(val->val.uri_val); - result->str_val = (char*)sord_node_get_string(result->val.uri_val); - break; - default: - result->str_val = lilv_strdup(val->str_val); - result->val = val->val; - } - + result->node = sord_node_copy(val->node); + result->val = val->val; + result->type = val->type; return result; } @@ -215,14 +205,7 @@ void lilv_node_free(LilvNode* val) { if (val) { - switch (val->type) { - case LILV_VALUE_URI: - case LILV_VALUE_BLANK: - sord_node_free(val->world->world, val->val.uri_val); - break; - default: - free(val->str_val); - } + sord_node_free(val->world->world, val->node); free(val); } } @@ -240,20 +223,16 @@ lilv_node_equals(const LilvNode* value, const LilvNode* other) switch (value->type) { case LILV_VALUE_URI: - return sord_node_equals(value->val.uri_val, other->val.uri_val); case LILV_VALUE_BLANK: case LILV_VALUE_STRING: - return !strcmp(value->str_val, other->str_val); + case LILV_VALUE_BLOB: + return sord_node_equals(value->node, other->node); case LILV_VALUE_INT: return (value->val.int_val == other->val.int_val); case LILV_VALUE_FLOAT: return (value->val.float_val == other->val.float_val); case LILV_VALUE_BOOL: return (value->val.bool_val == other->val.bool_val); - case LILV_VALUE_BLOB: - return (value->val.blob_val.size == other->val.blob_val.size) - && !memcmp(value->val.blob_val.buf, other->val.blob_val.buf, - value->val.blob_val.size); } return false; /* shouldn't get here */ @@ -263,32 +242,33 @@ LILV_API char* lilv_node_get_turtle_token(const LilvNode* value) { - size_t len = 0; - char* result = NULL; - SerdNode node; + const char* str = (const char*)sord_node_get_string(value->node); + size_t len = 0; + char* result = NULL; + SerdNode node; switch (value->type) { case LILV_VALUE_URI: - len = strlen(value->str_val) + 3; + len = strlen(str) + 3; result = (char*)calloc(len, 1); - snprintf(result, len, "<%s>", value->str_val); + snprintf(result, len, "<%s>", str); break; case LILV_VALUE_BLANK: - len = strlen(value->str_val) + 3; + len = strlen(str) + 3; result = (char*)calloc(len, 1); - snprintf(result, len, "_:%s", value->str_val); + snprintf(result, len, "_:%s", str); break; case LILV_VALUE_STRING: case LILV_VALUE_BOOL: case LILV_VALUE_BLOB: - result = lilv_strdup(value->str_val); + result = lilv_strdup(str); break; case LILV_VALUE_INT: node = serd_node_new_integer(value->val.int_val); result = (char*)node.buf; break; case LILV_VALUE_FLOAT: - node = serd_node_new_decimal(value->val.float_val, 8); + node = serd_node_new_decimal(value->val.float_val, 8); result = (char*)node.buf; break; } @@ -308,14 +288,14 @@ const char* lilv_node_as_uri(const LilvNode* value) { assert(lilv_node_is_uri(value)); - return value->str_val; + return (const char*)sord_node_get_string(value->node); } const SordNode* lilv_node_as_node(const LilvNode* value) { assert(lilv_node_is_uri(value)); - return value->val.uri_val; + return value->node; } LILV_API @@ -330,7 +310,7 @@ const char* lilv_node_as_blank(const LilvNode* value) { assert(lilv_node_is_blank(value)); - return value->str_val; + return (const char*)sord_node_get_string(value->node); } LILV_API @@ -361,7 +341,7 @@ LILV_API const char* lilv_node_as_string(const LilvNode* value) { - return value ? value->str_val : NULL; + return value ? (const char*)sord_node_get_string(value->node) : NULL; } LILV_API diff --git a/src/plugin.c b/src/plugin.c index c32c2fe..758790b 100644 --- a/src/plugin.c +++ b/src/plugin.c @@ -135,7 +135,7 @@ lilv_plugin_get_unique(const LilvPlugin* p, static void lilv_plugin_load(LilvPlugin* p) { - SordNode* bundle_uri_node = p->bundle_uri->val.uri_val; + SordNode* bundle_uri_node = p->bundle_uri->node; const SerdNode* bundle_uri_snode = sord_node_to_serd_node(bundle_uri_node); SerdEnv* env = serd_env_new(bundle_uri_snode); @@ -145,7 +145,7 @@ lilv_plugin_load(LilvPlugin* p) // Parse all the plugin's data files into RDF model LILV_FOREACH(nodes, i, p->data_uris) { const LilvNode* data_uri_val = lilv_nodes_get(p->data_uris, i); - const SordNode* data_uri_node = data_uri_val->val.uri_val; + const SordNode* data_uri_node = data_uri_val->node; const char* data_uri_str = lilv_node_as_uri(data_uri_val); serd_env_set_base_uri(env, sord_node_to_serd_node(data_uri_node)); @@ -164,7 +164,7 @@ lilv_plugin_load(LilvPlugin* p) GetDataFunc get_data_func = (GetDataFunc)lilv_dlfunc( p->dynmanifest->lib, "lv2_dyn_manifest_get_data"); if (get_data_func) { - const SordNode* bundle = p->dynmanifest->bundle->val.uri_val; + const SordNode* bundle = p->dynmanifest->bundle->node; serd_env_set_base_uri(env, sord_node_to_serd_node(bundle)); FILE* fd = tmpfile(); get_data_func(p->dynmanifest->handle, fd, @@ -212,7 +212,7 @@ lilv_plugin_load_ports_if_necessary(const LilvPlugin* const_p) SordIter* ports = lilv_world_query_internal( p->world, - p->plugin_uri->val.uri_val, + p->plugin_uri->node, p->world->uris.lv2_port, NULL); @@ -224,7 +224,8 @@ lilv_plugin_load_ports_if_necessary(const LilvPlugin* const_p) p, port, p->world->uris.lv2_symbol); bool error = false; - if (!lilv_node_is_string(symbol) || !is_symbol(symbol->str_val)) { + if (!lilv_node_is_string(symbol) || + !is_symbol((const char*)sord_node_get_string(symbol->node))) { LILV_ERRORF("Plugin <%s> port symbol `%s' is invalid\n", lilv_node_as_uri(p->plugin_uri), lilv_node_as_string(symbol)); @@ -332,7 +333,7 @@ lilv_plugin_get_library_uri(const LilvPlugin* const_p) // <plugin> lv2:binary ?binary SordIter* results = lilv_world_query_internal( p->world, - p->plugin_uri->val.uri_val, + p->plugin_uri->node, p->world->uris.lv2_binary, NULL); FOREACH_MATCH(results) { @@ -368,7 +369,7 @@ lilv_plugin_get_class(const LilvPlugin* const_p) // <plugin> a ?class SordIter* results = lilv_world_query_internal( p->world, - p->plugin_uri->val.uri_val, + p->plugin_uri->node, p->world->uris.rdf_a, NULL); FOREACH_MATCH(results) { @@ -405,7 +406,7 @@ lilv_plugin_get_value_internal(const LilvPlugin* p, { lilv_plugin_load_if_necessary(p); return lilv_world_query_values_internal( - p->world, p->plugin_uri->val.uri_val, predicate, NULL); + p->world, p->plugin_uri->node, predicate, NULL); } LILV_API @@ -567,7 +568,7 @@ lilv_plugin_has_latency(const LilvPlugin* p) lilv_plugin_load_if_necessary(p); SordIter* ports = lilv_world_query_internal( p->world, - p->plugin_uri->val.uri_val, + p->plugin_uri->node, p->world->uris.lv2_port, NULL); @@ -602,7 +603,7 @@ lilv_plugin_get_port_by_property(const LilvPlugin* plugin, plugin->world, port->node, plugin->world->uris.lv2_portProperty, - port_property->val.uri_val); + port_property->node); const bool found = !sord_iter_end(iter); sord_iter_free(iter); @@ -629,7 +630,7 @@ lilv_plugin_get_port_by_designation(const LilvPlugin* plugin, world, port->node, world->uris.lv2_designation, - designation->val.uri_val); + designation->node); const bool found = !sord_iter_end(iter) && lilv_port_is_a(plugin, port, port_class); @@ -713,15 +714,16 @@ lilv_plugin_has_extension_data(const LilvPlugin* p, const LilvNode* uri) { if (!lilv_node_is_uri(uri)) { - LILV_ERRORF("Extension data `%s' is not a URI\n", uri->str_val); + LILV_ERRORF("Extension data `%s' is not a URI\n", + sord_node_get_string(uri->node)); return false; } SordIter* iter = lilv_world_query_internal( p->world, - p->plugin_uri->val.uri_val, + p->plugin_uri->node, p->world->uris.lv2_extensionData, - uri->val.uri_val); + uri->node); if (iter) { sord_iter_free(iter); @@ -776,7 +778,7 @@ lilv_plugin_get_project(const LilvPlugin* p) SordIter* projects = lilv_world_query_internal( p->world, - p->plugin_uri->val.uri_val, + p->plugin_uri->node, lv2_project, NULL); @@ -802,7 +804,7 @@ lilv_plugin_get_author(const LilvPlugin* p) SordIter* maintainers = lilv_world_query_internal( p->world, - p->plugin_uri->val.uri_val, + p->plugin_uri->node, doap_maintainer, NULL); @@ -816,7 +818,7 @@ lilv_plugin_get_author(const LilvPlugin* p) maintainers = lilv_world_query_internal( p->world, - project->val.uri_val, + project->node, doap_maintainer, NULL); } @@ -891,7 +893,7 @@ lilv_plugin_get_uis(const LilvPlugin* p) LilvUIs* result = lilv_uis_new(); SordIter* uis = lilv_world_query_internal( p->world, - p->plugin_uri->val.uri_val, + p->plugin_uri->node, ui_ui_node, NULL); @@ -940,7 +942,7 @@ lilv_plugin_get_related(const LilvPlugin* plugin, const LilvNode* type) world, NULL, world->uris.lv2_appliesTo, - lilv_plugin_get_uri(plugin)->val.uri_val); + lilv_plugin_get_uri(plugin)->node); if (!type) { return related; @@ -950,10 +952,10 @@ lilv_plugin_get_related(const LilvPlugin* plugin, const LilvNode* type) LILV_FOREACH(nodes, i, related) { LilvNode* node = (LilvNode*)lilv_collection_get((ZixTree*)related, i); SordIter* titer = lilv_world_query_internal( - world, node->val.uri_val, world->uris.rdf_a, type->val.uri_val); + world, node->node, world->uris.rdf_a, type->node); if (!sord_iter_end(titer)) { zix_tree_insert((ZixTree*)matches, - lilv_node_new_from_node(world, node->val.uri_val), + lilv_node_new_from_node(world, node->node), NULL); } sord_iter_free(titer); @@ -1001,7 +1003,7 @@ lilv_plugin_write_description(LilvWorld* world, { const LilvNode* subject = lilv_plugin_get_uri(plugin); const uint32_t num_ports = lilv_plugin_get_num_ports(plugin); - const SerdNode* base = sord_node_to_serd_node(base_uri->val.uri_val); + const SerdNode* base = sord_node_to_serd_node(base_uri->node); SerdEnv* env = new_lv2_env(base); SerdWriter* writer = serd_writer_new( @@ -1017,7 +1019,7 @@ lilv_plugin_write_description(LilvWorld* world, // Write plugin description SordIter* plug_iter = lilv_world_query_internal( - world, subject->val.uri_val, NULL, NULL); + world, subject->node, NULL, NULL); sord_write_iter(plug_iter, writer); // Write port descriptions @@ -1041,7 +1043,7 @@ lilv_plugin_write_manifest_entry(LilvWorld* world, const char* plugin_file_path) { const LilvNode* subject = lilv_plugin_get_uri(plugin); - const SerdNode* base = sord_node_to_serd_node(base_uri->val.uri_val); + const SerdNode* base = sord_node_to_serd_node(base_uri->node); SerdEnv* env = new_lv2_env(base); SerdWriter* writer = serd_writer_new( @@ -1058,7 +1060,7 @@ lilv_plugin_write_manifest_entry(LilvWorld* world, // Write manifest entry serd_writer_write_statement( writer, 0, NULL, - sord_node_to_serd_node(subject->val.uri_val), + sord_node_to_serd_node(subject->node), sord_node_to_serd_node(plugin->world->uris.rdf_a), sord_node_to_serd_node(plugin->world->uris.lv2_Plugin), 0, 0); @@ -1066,7 +1068,7 @@ lilv_plugin_write_manifest_entry(LilvWorld* world, SERD_URI, (const uint8_t*)plugin_file_path); serd_writer_write_statement( writer, 0, NULL, - sord_node_to_serd_node(subject->val.uri_val), + sord_node_to_serd_node(subject->node), sord_node_to_serd_node(plugin->world->uris.rdfs_seeAlso), &file_node, 0, 0); @@ -121,7 +121,8 @@ lilv_port_get_value(const LilvPlugin* p, const LilvNode* predicate) { if (!lilv_node_is_uri(predicate)) { - LILV_ERRORF("Predicate `%s' is not a URI\n", predicate->str_val); + LILV_ERRORF("Predicate `%s' is not a URI\n", + sord_node_get_string(predicate->node)); return NULL; } diff --git a/src/state.c b/src/state.c index 6a6d339..c1ff6c0 100644 --- a/src/state.c +++ b/src/state.c @@ -576,7 +576,7 @@ lilv_state_new_from_world(LilvWorld* world, } LilvState* state = new_state_from_model( - world, map, world->model, node->val.uri_val, NULL); + world, map, world->model, node->node, NULL); return state; } @@ -604,7 +604,7 @@ lilv_state_new_from_file(LilvWorld* world, serd_reader_read_file(reader, node.buf); SordNode* subject_node = (subject) - ? subject->val.uri_val + ? subject->node : sord_node_from_serd_node(world->world, env, &node, NULL, NULL); char* dirname = lilv_dirname(path); @@ -779,7 +779,7 @@ lilv_state_write(LilvWorld* world, SERD_CURIE, USTR("lv2:appliesTo")); const SerdNode* plugin_uri = sord_node_to_serd_node( - state->plugin_uri->val.uri_val); + state->plugin_uri->node); SerdNode subject = serd_node_from_string(SERD_URI, USTR(uri ? uri : "")); diff --git a/src/world.c b/src/world.c index e5aeb31..b34cf3c 100644 --- a/src/world.c +++ b/src/world.c @@ -182,11 +182,13 @@ lilv_world_find_nodes(LilvWorld* world, const LilvNode* object) { if (subject && !lilv_node_is_uri(subject) && !lilv_node_is_blank(subject)) { - LILV_ERRORF("Subject `%s' is not a resource\n", subject->str_val); + LILV_ERRORF("Subject `%s' is not a resource\n", + sord_node_get_string(subject->node)); return NULL; } if (!lilv_node_is_uri(predicate)) { - LILV_ERRORF("Predicate `%s' is not a URI\n", predicate->str_val); + LILV_ERRORF("Predicate `%s' is not a URI\n", + sord_node_get_string(predicate->node)); return NULL; } if (!subject && !object) { @@ -195,15 +197,15 @@ lilv_world_find_nodes(LilvWorld* world, } SordNode* const subject_node = subject - ? sord_node_copy(subject->val.uri_val) + ? sord_node_copy(subject->node) : NULL; SordNode* const object_node = object - ? sord_node_copy(object->val.uri_val) + ? sord_node_copy(object->node) : NULL; LilvNodes* ret = lilv_world_query_values_internal( - world, subject_node, predicate->val.uri_val, object_node); + world, subject_node, predicate->node, object_node); sord_node_free(world->world, subject_node); sord_node_free(world->world, object_node); @@ -498,11 +500,12 @@ void lilv_world_load_bundle(LilvWorld* world, LilvNode* bundle_uri) { if (!lilv_node_is_uri(bundle_uri)) { - LILV_ERRORF("Bundle URI `%s' is not a URI\n", bundle_uri->str_val); + LILV_ERRORF("Bundle URI `%s' is not a URI\n", + sord_node_get_string(bundle_uri->node)); return; } - SordNode* bundle_node = bundle_uri->val.uri_val; + SordNode* bundle_node = bundle_uri->node; SerdNode manifest_uri = lilv_new_uri_relative_to_base( (const uint8_t*)"manifest.ttl", @@ -633,7 +636,7 @@ lilv_world_load_specifications(LilvWorld* world) LILV_FOREACH(nodes, f, spec->data_uris) { LilvNode* file = (LilvNode*)lilv_collection_get(spec->data_uris, f); - const SerdNode* node = sord_node_to_serd_node(file->val.uri_val); + const SerdNode* node = sord_node_to_serd_node(file->node); SerdEnv* env = serd_env_new(node); SerdReader* reader = sord_new_reader(world->model, env, SERD_TURTLE, NULL); @@ -753,13 +756,14 @@ lilv_world_load_resource(LilvWorld* world, const LilvNode* resource) { if (!lilv_node_is_uri(resource) && !lilv_node_is_blank(resource)) { - LILV_ERRORF("Node `%s' is not a resource\n", resource->str_val); + LILV_ERRORF("Node `%s' is not a resource\n", + sord_node_get_string(resource->node)); return -1; } int n_read = 0; SordIter* files = sord_search(world->model, - resource->val.uri_val, + resource->node, world->uris.rdfs_seeAlso, NULL, NULL); FOREACH_MATCH(files) { |