diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/collections.c | 8 | ||||
-rw-r--r-- | src/instance.c | 2 | ||||
-rw-r--r-- | src/lib.c | 5 | ||||
-rw-r--r-- | src/lilv_internal.h | 197 | ||||
-rw-r--r-- | src/node.c | 320 | ||||
-rw-r--r-- | src/plugin.c | 536 | ||||
-rw-r--r-- | src/pluginclass.c | 17 | ||||
-rw-r--r-- | src/port.c | 78 | ||||
-rw-r--r-- | src/query.c | 94 | ||||
-rw-r--r-- | src/state.c | 746 | ||||
-rw-r--r-- | src/util.c | 8 | ||||
-rw-r--r-- | src/world.c | 627 |
12 files changed, 1172 insertions, 1466 deletions
diff --git a/src/collections.c b/src/collections.c index c2c752a..04b0c51 100644 --- a/src/collections.c +++ b/src/collections.c @@ -17,7 +17,7 @@ #include "lilv_internal.h" #include "lilv/lilv.h" -#include "sord/sord.h" +#include "serd/serd.h" #include "zix/common.h" #include "zix/tree.h" @@ -38,10 +38,10 @@ lilv_resource_node_cmp(const void* a, const void* b, const void* user_data) { (void)user_data; - const SordNode* an = ((const LilvNode*)a)->node; - const SordNode* bn = ((const LilvNode*)b)->node; + const SerdNode* const an = (const SerdNode*)a; + const SerdNode* const bn = (const SerdNode*)b; - return (intptr_t)an - (intptr_t)bn; + return serd_node_compare(an, bn); } /* Generic collection functions */ diff --git a/src/instance.c b/src/instance.c index 6a2b856..2c9baa9 100644 --- a/src/instance.c +++ b/src/instance.c @@ -44,7 +44,7 @@ lilv_plugin_instantiate(const LilvPlugin* plugin, } char* const bundle_path = - lilv_file_uri_parse(lilv_node_as_uri(bundle_uri), NULL); + serd_parse_file_uri(lilv_node_as_uri(bundle_uri), NULL); LilvLib* lib = lilv_lib_open(plugin->world, lib_uri, bundle_path, features); if (!lib) { @@ -43,9 +43,8 @@ lilv_lib_open(LilvWorld* world, return llib; } - const char* const lib_uri = lilv_node_as_uri(uri); - char* const lib_path = - (char*)serd_file_uri_parse((const uint8_t*)lib_uri, NULL); + const char* const lib_uri = lilv_node_as_uri(uri); + char* const lib_path = serd_parse_file_uri(lib_uri, NULL); if (!lib_path) { return NULL; } diff --git a/src/lilv_internal.h b/src/lilv_internal.h index 12b56de..89ba122 100644 --- a/src/lilv_internal.h +++ b/src/lilv_internal.h @@ -26,7 +26,6 @@ extern "C" { #include "lilv/lilv.h" #include "lv2/core/lv2.h" #include "serd/serd.h" -#include "sord/sord.h" #include "zix/tree.h" #include <stdbool.h> @@ -64,6 +63,24 @@ dlerror(void) # include "lv2/dynmanifest/dynmanifest.h" #endif +#define LILV_READER_STACK_SIZE 65536 + +#ifndef PAGE_SIZE +# define PAGE_SIZE 4096 +#endif + +#define FOREACH_MATCH(statement_name_, range) \ + for (const SerdStatement* statement_name_ = NULL; \ + !serd_range_empty(range) && \ + (statement_name_ = serd_range_front(range)); \ + serd_range_next(range)) + +#define FOREACH_PAT(name_, model_, s_, p_, o_, g_) \ + for (SerdRange* r_ = serd_model_range(model_, s_, p_, o_, g_); \ + !serd_range_empty(r_) || (serd_range_free(r_), false); \ + serd_range_next(r_)) \ + for (const SerdStatement* name_ = serd_range_front(r_); name_; name_ = NULL) + /* * * Types @@ -80,8 +97,8 @@ struct LilvPortImpl { }; typedef struct LilvSpecImpl { - SordNode* spec; - SordNode* bundle; + SerdNode* spec; + SerdNode* bundle; LilvNodes* data_uris; struct LilvSpecImpl* next; } LilvSpec; @@ -151,8 +168,8 @@ typedef struct { } LilvOptions; struct LilvWorldImpl { - SordWorld* world; - SordModel* model; + SerdWorld* world; + SerdModel* model; SerdReader* reader; unsigned n_read_files; LilvPluginClass* lv2_plugin_class; @@ -163,44 +180,48 @@ struct LilvWorldImpl { LilvNodes* loaded_files; ZixTree* libs; struct { - SordNode* dc_replaces; - SordNode* dman_DynManifest; - SordNode* doap_name; - SordNode* lv2_Plugin; - SordNode* lv2_Specification; - SordNode* lv2_appliesTo; - SordNode* lv2_binary; - SordNode* lv2_default; - SordNode* lv2_designation; - SordNode* lv2_extensionData; - SordNode* lv2_index; - SordNode* lv2_latency; - SordNode* lv2_maximum; - SordNode* lv2_microVersion; - SordNode* lv2_minimum; - SordNode* lv2_minorVersion; - SordNode* lv2_name; - SordNode* lv2_optionalFeature; - SordNode* lv2_port; - SordNode* lv2_portProperty; - SordNode* lv2_reportsLatency; - SordNode* lv2_requiredFeature; - SordNode* lv2_symbol; - SordNode* lv2_prototype; - SordNode* owl_Ontology; - SordNode* pset_value; - SordNode* rdf_a; - SordNode* rdf_value; - SordNode* rdfs_Class; - SordNode* rdfs_label; - SordNode* rdfs_seeAlso; - SordNode* rdfs_subClassOf; - SordNode* xsd_base64Binary; - SordNode* xsd_boolean; - SordNode* xsd_decimal; - SordNode* xsd_double; - SordNode* xsd_integer; - SordNode* null_uri; + SerdNode* dc_replaces; + SerdNode* dman_DynManifest; + SerdNode* doap_name; + SerdNode* lv2_Plugin; + SerdNode* lv2_Specification; + SerdNode* lv2_appliesTo; + SerdNode* lv2_binary; + SerdNode* lv2_default; + SerdNode* lv2_designation; + SerdNode* lv2_extensionData; + SerdNode* lv2_index; + SerdNode* lv2_latency; + SerdNode* lv2_maximum; + SerdNode* lv2_microVersion; + SerdNode* lv2_minimum; + SerdNode* lv2_minorVersion; + SerdNode* lv2_name; + SerdNode* lv2_optionalFeature; + SerdNode* lv2_port; + SerdNode* lv2_portProperty; + SerdNode* lv2_reportsLatency; + SerdNode* lv2_requiredFeature; + SerdNode* lv2_symbol; + SerdNode* lv2_project; + SerdNode* lv2_prototype; + SerdNode* owl_Ontology; + SerdNode* pset_Preset; + SerdNode* pset_value; + SerdNode* rdf_a; + SerdNode* rdf_value; + SerdNode* rdfs_Class; + SerdNode* rdfs_label; + SerdNode* rdfs_seeAlso; + SerdNode* rdfs_subClassOf; + SerdNode* state_state; + SerdNode* xsd_base64Binary; + SerdNode* xsd_boolean; + SerdNode* xsd_decimal; + SerdNode* xsd_double; + SerdNode* xsd_int; + SerdNode* xsd_integer; + SerdNode* null_uri; } uris; LilvOptions opt; }; @@ -215,17 +236,6 @@ typedef enum { LILV_VALUE_BLOB } LilvNodeType; -struct LilvNodeImpl { - LilvWorld* world; - SordNode* node; - LilvNodeType type; - union { - int int_val; - float float_val; - bool bool_val; - } val; -}; - struct LilvScalePointImpl { LilvNode* value; LilvNode* label; @@ -251,46 +261,39 @@ typedef struct LilvVersion { */ LilvPort* -lilv_port_new(LilvWorld* world, - const SordNode* node, - uint32_t index, - const char* symbol); +lilv_port_new(const SerdNode* node, uint32_t index, const char* symbol); void lilv_port_free(const LilvPlugin* plugin, LilvPort* port); LilvPlugin* -lilv_plugin_new(LilvWorld* world, LilvNode* uri, LilvNode* bundle_uri); +lilv_plugin_new(LilvWorld* world, + const LilvNode* uri, + const LilvNode* bundle_uri); void -lilv_plugin_clear(LilvPlugin* plugin, LilvNode* bundle_uri); - +lilv_plugin_clear(LilvPlugin* plugin, const LilvNode* bundle_uri); void lilv_plugin_load_if_necessary(const LilvPlugin* plugin); - void lilv_plugin_free(LilvPlugin* plugin); - LilvNode* lilv_plugin_get_unique(const LilvPlugin* plugin, - const SordNode* subject, - const SordNode* predicate); + const SerdNode* subject, + const SerdNode* predicate); void lilv_collection_free(LilvCollection* collection); - unsigned lilv_collection_size(const LilvCollection* collection); - LilvIter* lilv_collection_begin(const LilvCollection* collection); - void* lilv_collection_get(const LilvCollection* collection, const LilvIter* i); LilvPluginClass* lilv_plugin_class_new(LilvWorld* world, - const SordNode* parent_node, - const SordNode* uri, + const SerdNode* parent_node, + const SerdNode* uri, const char* label); void @@ -324,16 +327,24 @@ LilvUIs* lilv_uis_new(void); LilvNode* +lilv_world_get_manifest_node(LilvWorld* world, const LilvNode* bundle_uri); + +char* +lilv_world_get_manifest_path(LilvWorld* world, const LilvNode* bundle_uri); + +LilvNode* lilv_world_get_manifest_uri(LilvWorld* world, const LilvNode* bundle_uri); -const uint8_t* +const char* lilv_world_blank_node_prefix(LilvWorld* world); SerdStatus lilv_world_load_file(LilvWorld* world, SerdReader* reader, const LilvNode* uri); SerdStatus -lilv_world_load_graph(LilvWorld* world, SordNode* graph, const LilvNode* uri); +lilv_world_load_graph(LilvWorld* world, + const SerdNode* graph, + const LilvNode* uri); LilvUI* lilv_ui_new(LilvWorld* world, @@ -344,12 +355,6 @@ lilv_ui_new(LilvWorld* world, void lilv_ui_free(LilvUI* ui); -LilvNode* -lilv_node_new(LilvWorld* world, LilvNodeType type, const char* str); - -LilvNode* -lilv_node_new_from_node(LilvWorld* world, const SordNode* node); - int lilv_header_compare_by_uri(const void* a, const void* b, const void* user_data); @@ -385,38 +390,22 @@ lilv_scale_point_new(LilvNode* value, LilvNode* label); void lilv_scale_point_free(LilvScalePoint* point); -SordIter* -lilv_world_query_internal(LilvWorld* world, - const SordNode* subject, - const SordNode* predicate, - const SordNode* object); - -bool -lilv_world_ask_internal(LilvWorld* world, - const SordNode* subject, - const SordNode* predicate, - const SordNode* object); - LilvNodes* lilv_world_find_nodes_internal(LilvWorld* world, - const SordNode* subject, - const SordNode* predicate, - const SordNode* object); + const SerdNode* subject, + const SerdNode* predicate, + const SerdNode* object); -SordModel* +SerdModel* lilv_world_filter_model(LilvWorld* world, - SordModel* model, - const SordNode* subject, - const SordNode* predicate, - const SordNode* object, - const SordNode* graph); - -#define FOREACH_MATCH(iter) for (; !sord_iter_end(iter); sord_iter_next(iter)) + SerdModel* model, + const SerdNode* subject, + const SerdNode* predicate, + const SerdNode* object, + const SerdNode* graph); LilvNodes* -lilv_nodes_from_stream_objects(LilvWorld* world, - SordIter* stream, - SordQuadIndex field); +lilv_nodes_from_range(LilvWorld* world, SerdRange* range, SerdField field); char* lilv_strjoin(const char* first, ...); @@ -19,283 +19,103 @@ #include "lilv/lilv.h" #include "serd/serd.h" -#include "sord/sord.h" #include <math.h> #include <stdbool.h> -#include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> -static void -lilv_node_set_numerics_from_string(LilvNode* val) -{ - const char* str = (const char*)sord_node_get_string(val->node); - - 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(str, NULL, 10); - break; - case LILV_VALUE_FLOAT: - val->val.float_val = serd_strtod(str, NULL); - break; - case LILV_VALUE_BOOL: - val->val.bool_val = !strcmp(str, "true"); - break; - } -} - -/** Note that if `type` is numeric or boolean, the returned value is corrupt - * until lilv_node_set_numerics_from_string is called. It is not - * automatically called from here to avoid overhead and imprecision when the - * exact string value is known. - */ -LilvNode* -lilv_node_new(LilvWorld* world, LilvNodeType type, const char* str) -{ - LilvNode* val = (LilvNode*)malloc(sizeof(LilvNode)); - val->world = world; - val->type = type; - - const uint8_t* ustr = (const uint8_t*)str; - switch (type) { - case LILV_VALUE_URI: - val->node = sord_new_uri(world->world, ustr); - break; - case LILV_VALUE_BLANK: - 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->node = - sord_new_literal(world->world, world->uris.xsd_base64Binary, ustr, NULL); - break; - } - - if (!val->node) { - free(val); - return NULL; - } - - return val; -} - -/** Create a new LilvNode from `node`, or return NULL if impossible */ -LilvNode* -lilv_node_new_from_node(LilvWorld* world, const SordNode* node) -{ - if (!node) { - return NULL; - } - - LilvNode* result = NULL; - SordNode* datatype_uri = NULL; - LilvNodeType type = LILV_VALUE_STRING; - - switch (sord_node_get_type(node)) { - case SORD_URI: - result = (LilvNode*)malloc(sizeof(LilvNode)); - result->world = world; - result->type = LILV_VALUE_URI; - result->node = sord_node_copy(node); - break; - case SORD_BLANK: - result = (LilvNode*)malloc(sizeof(LilvNode)); - result->world = world; - result->type = LILV_VALUE_BLANK; - result->node = sord_node_copy(node); - break; - case SORD_LITERAL: - datatype_uri = sord_node_get_datatype(node); - if (datatype_uri) { - if (sord_node_equals(datatype_uri, world->uris.xsd_boolean)) { - type = LILV_VALUE_BOOL; - } else if (sord_node_equals(datatype_uri, world->uris.xsd_decimal) || - sord_node_equals(datatype_uri, world->uris.xsd_double)) { - type = LILV_VALUE_FLOAT; - } else if (sord_node_equals(datatype_uri, world->uris.xsd_integer)) { - type = LILV_VALUE_INT; - } else if (sord_node_equals(datatype_uri, world->uris.xsd_base64Binary)) { - type = LILV_VALUE_BLOB; - } else { - LILV_ERRORF("Unknown datatype `%s'\n", - sord_node_get_string(datatype_uri)); - } - } - result = - lilv_node_new(world, type, (const char*)sord_node_get_string(node)); - lilv_node_set_numerics_from_string(result); - break; - } - - return result; -} - +LILV_API LilvNode* lilv_new_uri(LilvWorld* world, const char* uri) { - return lilv_node_new(world, LILV_VALUE_URI, uri); + (void)world; + return serd_new_uri(SERD_MEASURE_STRING(uri)); } LilvNode* lilv_new_file_uri(LilvWorld* world, const char* host, const char* path) { - char* abs_path = lilv_path_absolute(path); - SerdNode s = serd_node_new_file_uri( - (const uint8_t*)abs_path, (const uint8_t*)host, NULL, true); + (void)world; + + char* abs_path = lilv_path_absolute(path); + SerdNode* s = + serd_new_file_uri(SERD_MEASURE_STRING(abs_path), SERD_MEASURE_STRING(host)); - LilvNode* ret = lilv_node_new(world, LILV_VALUE_URI, (const char*)s.buf); - serd_node_free(&s); free(abs_path); - return ret; + return s; } LilvNode* lilv_new_string(LilvWorld* world, const char* str) { - return lilv_node_new(world, LILV_VALUE_STRING, str); + (void)world; + + return serd_new_string(SERD_MEASURE_STRING(str)); } LilvNode* lilv_new_int(LilvWorld* world, int val) { - char str[32]; - snprintf(str, sizeof(str), "%d", val); - LilvNode* ret = lilv_node_new(world, LILV_VALUE_INT, str); - if (ret) { - ret->val.int_val = val; - } - return ret; + (void)world; + + return serd_new_integer(val, world->uris.xsd_int); } LilvNode* lilv_new_float(LilvWorld* world, float val) { - char str[32]; - snprintf(str, sizeof(str), "%f", val); - LilvNode* ret = lilv_node_new(world, LILV_VALUE_FLOAT, str); - if (ret) { - ret->val.float_val = val; - } - return ret; + (void)world; + + return serd_new_float(val); } LilvNode* lilv_new_bool(LilvWorld* world, bool val) { - LilvNode* ret = lilv_node_new(world, LILV_VALUE_BOOL, val ? "true" : "false"); - if (ret) { - ret->val.bool_val = val; - } - return ret; + (void)world; + + return serd_new_typed_literal(val ? SERD_STATIC_STRING("true") + : SERD_STATIC_STRING("false"), + serd_node_string_view(world->uris.xsd_boolean)); } LilvNode* lilv_node_duplicate(const LilvNode* val) { - if (!val) { - return NULL; - } - - LilvNode* result = (LilvNode*)malloc(sizeof(LilvNode)); - result->world = val->world; - result->node = sord_node_copy(val->node); - result->val = val->val; - result->type = val->type; - return result; + return serd_node_copy(val); } void lilv_node_free(LilvNode* val) { - if (val) { - sord_node_free(val->world->world, val->node); - free(val); - } + serd_node_free(val); } bool lilv_node_equals(const LilvNode* value, const LilvNode* other) { - if (value == NULL && other == NULL) { - return true; - } - - if (value == NULL || other == NULL || value->type != other->type) { - return false; - } - - switch (value->type) { - case LILV_VALUE_URI: - case LILV_VALUE_BLANK: - case LILV_VALUE_STRING: - 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); - } - - return false; /* shouldn't get here */ + return serd_node_equals(value, other); } char* lilv_node_get_turtle_token(const LilvNode* value) { - const char* str = (const char*)sord_node_get_string(value->node); + const char* str = serd_node_string(value); size_t len = 0; char* result = NULL; - SerdNode node; - switch (value->type) { - case LILV_VALUE_URI: + if (lilv_node_is_uri(value)) { len = strlen(str) + 3; result = (char*)calloc(len, 1); snprintf(result, len, "<%s>", str); - break; - case LILV_VALUE_BLANK: + } else if (lilv_node_is_blank(value)) { len = strlen(str) + 3; result = (char*)calloc(len, 1); snprintf(result, len, "_:%s", str); - break; - case LILV_VALUE_STRING: - case LILV_VALUE_BOOL: - case LILV_VALUE_BLOB: + } else { result = lilv_strdup(str); - break; - case LILV_VALUE_INT: - node = serd_node_new_integer(value->val.int_val); - result = lilv_strdup((char*)node.buf); - serd_node_free(&node); - break; - case LILV_VALUE_FLOAT: - node = serd_node_new_decimal(value->val.float_val, 8); - result = lilv_strdup((char*)node.buf); - serd_node_free(&node); - break; } return result; @@ -304,110 +124,108 @@ lilv_node_get_turtle_token(const LilvNode* value) bool lilv_node_is_uri(const LilvNode* value) { - return (value && value->type == LILV_VALUE_URI); + return value && serd_node_type(value) == SERD_URI; } const char* lilv_node_as_uri(const LilvNode* value) { - return (lilv_node_is_uri(value) - ? (const char*)sord_node_get_string(value->node) - : NULL); + return (lilv_node_is_uri(value) ? serd_node_string(value) : NULL); } bool lilv_node_is_blank(const LilvNode* value) { - return (value && value->type == LILV_VALUE_BLANK); + return value && serd_node_type(value) == SERD_BLANK; } const char* lilv_node_as_blank(const LilvNode* value) { - return (lilv_node_is_blank(value) - ? (const char*)sord_node_get_string(value->node) - : NULL); + return (lilv_node_is_blank(value) ? serd_node_string(value) : NULL); } bool lilv_node_is_literal(const LilvNode* value) { - if (!value) { - return false; - } - - switch (value->type) { - case LILV_VALUE_STRING: - case LILV_VALUE_INT: - case LILV_VALUE_FLOAT: - case LILV_VALUE_BLOB: - return true; - default: - return false; - } + return value && serd_node_type(value) == SERD_LITERAL; } bool lilv_node_is_string(const LilvNode* value) { - return (value && value->type == LILV_VALUE_STRING); + return value && + (serd_node_type(value) == SERD_LITERAL && !serd_node_datatype(value)); } const char* lilv_node_as_string(const LilvNode* value) { - return value ? (const char*)sord_node_get_string(value->node) : NULL; + return value ? serd_node_string(value) : NULL; } bool lilv_node_is_int(const LilvNode* value) { - return (value && value->type == LILV_VALUE_INT); + if (!value) { + return false; + } + + const SerdNode* const datatype = serd_node_datatype(value); + return (serd_node_type(value) == SERD_LITERAL && datatype && + (!strcmp(serd_node_string(datatype), LILV_NS_XSD "integer") || + !strcmp(serd_node_string(datatype), LILV_NS_XSD "int"))); } int lilv_node_as_int(const LilvNode* value) { - return lilv_node_is_int(value) ? value->val.int_val : 0; + return lilv_node_is_int(value) ? strtoll(serd_node_string(value), NULL, 10) + : 0; } bool lilv_node_is_float(const LilvNode* value) { - return (value && value->type == LILV_VALUE_FLOAT); + if (!value) { + return false; + } + + const SerdNode* const datatype = serd_node_datatype(value); + return (serd_node_type(value) == SERD_LITERAL && datatype && + (!strcmp(serd_node_string(datatype), LILV_NS_XSD "decimal") || + !strcmp(serd_node_string(datatype), LILV_NS_XSD "float") || + !strcmp(serd_node_string(datatype), LILV_NS_XSD "double"))); } float lilv_node_as_float(const LilvNode* value) { - if (lilv_node_is_float(value)) { - return value->val.float_val; - } - - if (lilv_node_is_int(value)) { - return (float)value->val.int_val; - } - - return NAN; + return serd_get_float(value); } bool lilv_node_is_bool(const LilvNode* value) { - return (value && value->type == LILV_VALUE_BOOL); + if (!value) { + return false; + } + + const SerdNode* const datatype = serd_node_datatype(value); + return (serd_node_type(value) == SERD_LITERAL && datatype && + (!strcmp(serd_node_string(datatype), LILV_NS_XSD "boolean"))); } bool lilv_node_as_bool(const LilvNode* value) { - return lilv_node_is_bool(value) ? value->val.bool_val : false; + return (lilv_node_is_bool(value) && !strcmp(serd_node_string(value), "true")); } char* lilv_node_get_path(const LilvNode* value, char** hostname) { - if (lilv_node_is_uri(value)) { - return lilv_file_uri_parse(lilv_node_as_uri(value), hostname); - } - return NULL; + return lilv_node_is_uri(value) + ? serd_parse_file_uri(lilv_node_as_uri(value), hostname) + : NULL; } diff --git a/src/plugin.c b/src/plugin.c index 9c7cbfd..1b34e44 100644 --- a/src/plugin.c +++ b/src/plugin.c @@ -18,7 +18,6 @@ #include "lilv/lilv.h" #include "serd/serd.h" -#include "sord/sord.h" #include "zix/tree.h" #include "lv2/core/lv2.h" @@ -36,13 +35,18 @@ #include <stdlib.h> #include <string.h> -#define NS_DOAP (const uint8_t*)"http://usefulinc.com/ns/doap#" -#define NS_FOAF (const uint8_t*)"http://xmlns.com/foaf/0.1/" +#define NS_DOAP "http://usefulinc.com/ns/doap#" +#define NS_FOAF "http://xmlns.com/foaf/0.1/" +#define NS_LV2 "http://lv2plug.in/ns/lv2core#" +#define NS_OWL "http://www.w3.org/2002/07/owl#" +#define NS_RDF "http://www.w3.org/1999/02/22-rdf-syntax-ns#" +#define NS_RDFS "http://www.w3.org/2000/01/rdf-schema#" +#define NS_XSD "http://www.w3.org/2001/XMLSchema#" static void -lilv_plugin_init(LilvPlugin* plugin, LilvNode* bundle_uri) +lilv_plugin_init(LilvPlugin* plugin, const LilvNode* bundle_uri) { - plugin->bundle_uri = bundle_uri; + plugin->bundle_uri = lilv_node_duplicate(bundle_uri); plugin->binary_uri = NULL; #ifdef LILV_DYN_MANIFEST plugin->dynmanifest = NULL; @@ -56,21 +60,22 @@ lilv_plugin_init(LilvPlugin* plugin, LilvNode* bundle_uri) plugin->replaced = false; } -/** Ownership of `uri` and `bundle` is taken */ LilvPlugin* -lilv_plugin_new(LilvWorld* world, LilvNode* uri, LilvNode* bundle_uri) +lilv_plugin_new(LilvWorld* world, + const LilvNode* uri, + const LilvNode* bundle_uri) { LilvPlugin* plugin = (LilvPlugin*)malloc(sizeof(LilvPlugin)); plugin->world = world; - plugin->plugin_uri = uri; + plugin->plugin_uri = lilv_node_duplicate(uri); lilv_plugin_init(plugin, bundle_uri); return plugin; } void -lilv_plugin_clear(LilvPlugin* plugin, LilvNode* bundle_uri) +lilv_plugin_clear(LilvPlugin* plugin, const LilvNode* bundle_uri) { lilv_node_free(plugin->bundle_uri); lilv_node_free(plugin->binary_uri); @@ -119,37 +124,23 @@ lilv_plugin_free(LilvPlugin* plugin) static LilvNode* lilv_plugin_get_one(const LilvPlugin* plugin, - const SordNode* subject, - const SordNode* predicate) + const SerdNode* subject, + const SerdNode* predicate) { - /* TODO: This is slower than it could be in some cases, but it's simpler to - use the existing i18n code. */ - - SordIter* stream = - lilv_world_query_internal(plugin->world, subject, predicate, NULL); - - LilvNodes* nodes = - lilv_nodes_from_stream_objects(plugin->world, stream, SORD_OBJECT); - - if (nodes) { - LilvNode* value = lilv_node_duplicate(lilv_nodes_get_first(nodes)); - lilv_nodes_free(nodes); - return value; - } - - return NULL; + return serd_node_copy( + serd_model_get(plugin->world->model, subject, predicate, NULL, NULL)); } LilvNode* lilv_plugin_get_unique(const LilvPlugin* plugin, - const SordNode* subject, - const SordNode* predicate) + const SerdNode* subject, + const SerdNode* predicate) { LilvNode* ret = lilv_plugin_get_one(plugin, subject, predicate); if (!ret) { LILV_ERRORF("No value found for (%s %s ...) property\n", - sord_node_get_string(subject), - sord_node_get_string(predicate)); + serd_node_string(subject), + serd_node_string(predicate)); } return ret; } @@ -157,56 +148,59 @@ lilv_plugin_get_unique(const LilvPlugin* plugin, static void lilv_plugin_load(LilvPlugin* plugin) { - SordNode* bundle_uri_node = plugin->bundle_uri->node; - const SerdNode* bundle_uri_snode = sord_node_to_serd_node(bundle_uri_node); + SerdNode* bundle_uri_node = plugin->bundle_uri; - SerdEnv* env = serd_env_new(bundle_uri_snode); - SerdReader* reader = - sord_new_reader(plugin->world->model, env, SERD_TURTLE, bundle_uri_node); + SerdEnv* env = serd_env_new(serd_node_string_view(bundle_uri_node)); + SerdSink* inserter = serd_inserter_new(plugin->world->model, bundle_uri_node); - SordModel* prots = lilv_world_filter_model(plugin->world, + SerdReader* reader = serd_reader_new(plugin->world->world, + SERD_TURTLE, + 0, + env, + inserter, + LILV_READER_STACK_SIZE); + + SerdModel* prots = lilv_world_filter_model(plugin->world, plugin->world->model, - plugin->plugin_uri->node, + plugin->plugin_uri, plugin->world->uris.lv2_prototype, NULL, NULL); - SordModel* skel = sord_new(plugin->world->world, SORD_SPO, false); - SordIter* iter = sord_begin(prots); - for (; !sord_iter_end(iter); sord_iter_next(iter)) { - const SordNode* t = sord_iter_get_node(iter, SORD_OBJECT); - LilvNode* prototype = lilv_node_new_from_node(plugin->world, t); + SerdModel* skel = serd_model_new(plugin->world->world, SERD_INDEX_SPO); + SerdIter* iter = serd_model_begin(prots); + for (; !serd_iter_equals(iter, serd_model_end(prots)); serd_iter_next(iter)) { + const SerdStatement* statement = serd_iter_get(iter); + const SerdNode* t = serd_statement_object(statement); + LilvNode* prototype = serd_node_copy(t); lilv_world_load_resource(plugin->world, prototype); - SordIter* statements = - sord_search(plugin->world->model, prototype->node, NULL, NULL, NULL); - FOREACH_MATCH (statements) { - SordQuad quad; - sord_iter_get(statements, quad); - quad[0] = plugin->plugin_uri->node; - sord_add(skel, quad); + FOREACH_PAT(s, plugin->world->model, prototype, NULL, NULL, NULL) + { + serd_model_add(skel, + plugin->plugin_uri, + serd_statement_predicate(s), + serd_statement_object(s), + NULL); } - sord_iter_free(statements); lilv_node_free(prototype); } - sord_iter_free(iter); + serd_iter_free(iter); - for (iter = sord_begin(skel); !sord_iter_end(iter); sord_iter_next(iter)) { - SordQuad quad; - sord_iter_get(iter, quad); - sord_add(plugin->world->model, quad); - } - sord_iter_free(iter); - sord_free(skel); - sord_free(prots); + SerdRange* all = serd_model_all(skel, SERD_ORDER_SPO); + serd_model_add_range(plugin->world->model, all); + serd_range_free(all); + + serd_model_free(skel); + serd_model_free(prots); // Parse all the plugin's data files into RDF model SerdStatus st = SERD_SUCCESS; LILV_FOREACH (nodes, i, plugin->data_uris) { const LilvNode* data_uri = lilv_nodes_get(plugin->data_uris, i); - serd_env_set_base_uri(env, sord_node_to_serd_node(data_uri->node)); + serd_env_set_base_uri(env, serd_node_string_view(data_uri)); st = lilv_world_load_file(plugin->world, reader, data_uri); if (st > SERD_FAILURE) { break; @@ -217,6 +211,7 @@ lilv_plugin_load(LilvPlugin* plugin) plugin->loaded = true; plugin->parse_errors = true; serd_reader_free(reader); + serd_sink_free(inserter); serd_env_free(env); return; } @@ -229,8 +224,8 @@ lilv_plugin_load(LilvPlugin* plugin) GetDataFunc get_data_func = (GetDataFunc)lilv_dlfunc( plugin->dynmanifest->lib, "lv2_dyn_manifest_get_data"); if (get_data_func) { - const SordNode* bundle = plugin->dynmanifest->bundle->node; - serd_env_set_base_uri(env, sord_node_to_serd_node(bundle)); + const SerdNode* bundle = plugin->dynmanifest->bundle; + serd_env_set_base_uri(env, bundle); FILE* fd = tmpfile(); get_data_func(plugin->dynmanifest->handle, fd, @@ -238,13 +233,13 @@ lilv_plugin_load(LilvPlugin* plugin) rewind(fd); serd_reader_add_blank_prefix(reader, lilv_world_blank_node_prefix(plugin->world)); - serd_reader_read_file_handle( - reader, fd, (const uint8_t*)"(dyn-manifest)"); + serd_reader_read_file_handle(reader, fd, "(dyn-manifest)"); fclose(fd); } } #endif serd_reader_free(reader); + serd_sink_free(inserter); serd_env_free(env); plugin->loaded = true; @@ -273,22 +268,21 @@ lilv_plugin_load_ports_if_necessary(const LilvPlugin* const_plugin) plugin->ports = (LilvPort**)malloc(sizeof(LilvPort*)); plugin->ports[0] = NULL; - SordIter* ports = lilv_world_query_internal(plugin->world, - plugin->plugin_uri->node, - plugin->world->uris.lv2_port, - NULL); - - FOREACH_MATCH (ports) { - const SordNode* port = sord_iter_get_node(ports, SORD_OBJECT); + SerdRange* ports = serd_model_range(plugin->world->model, + plugin->plugin_uri, + plugin->world->uris.lv2_port, + NULL, + NULL); - LilvNode* index = + FOREACH_MATCH (s, ports) { + const SerdNode* port = serd_statement_object(s); + LilvNode* index = lilv_plugin_get_unique(plugin, port, plugin->world->uris.lv2_index); - LilvNode* symbol = lilv_plugin_get_unique(plugin, port, plugin->world->uris.lv2_symbol); if (!lilv_node_is_string(symbol) || - !is_symbol((const char*)sord_node_get_string(symbol->node))) { + !is_symbol(serd_node_string(symbol))) { LILV_ERRORF("Plugin <%s> port symbol `%s' is invalid\n", lilv_node_as_uri(plugin->plugin_uri), lilv_node_as_string(symbol)); @@ -322,30 +316,29 @@ lilv_plugin_load_ports_if_necessary(const LilvPlugin* const_plugin) // Havn't seen this port yet, add it to array if (!this_port) { - this_port = lilv_port_new( - plugin->world, port, this_index, lilv_node_as_string(symbol)); + this_port = + lilv_port_new(port, this_index, lilv_node_as_string(symbol)); plugin->ports[this_index] = this_port; } - SordIter* types = lilv_world_query_internal( - plugin->world, port, plugin->world->uris.rdf_a, NULL); - FOREACH_MATCH (types) { - const SordNode* type = sord_iter_get_node(types, SORD_OBJECT); - if (sord_node_get_type(type) == SORD_URI) { - zix_tree_insert((ZixTree*)this_port->classes, - lilv_node_new_from_node(plugin->world, type), - NULL); + SerdRange* types = serd_model_range( + plugin->world->model, port, plugin->world->uris.rdf_a, NULL, NULL); + FOREACH_MATCH (t, types) { + const SerdNode* type = serd_statement_object(t); + if (serd_node_type(type) == SERD_URI) { + zix_tree_insert( + (ZixTree*)this_port->classes, serd_node_copy(type), NULL); } else { LILV_WARNF("Plugin <%s> port type is not a URI\n", lilv_node_as_uri(plugin->plugin_uri)); } } - sord_iter_free(types); + serd_range_free(types); lilv_node_free(symbol); lilv_node_free(index); } - sord_iter_free(ports); + serd_range_free(ports); // Check sanity for (uint32_t i = 0; i < plugin->num_ports; ++i) { @@ -387,19 +380,19 @@ lilv_plugin_get_library_uri(const LilvPlugin* plugin) lilv_plugin_load_if_necessary((LilvPlugin*)plugin); if (!plugin->binary_uri) { // <plugin> lv2:binary ?binary - SordIter* i = lilv_world_query_internal(plugin->world, - plugin->plugin_uri->node, - plugin->world->uris.lv2_binary, - NULL); - FOREACH_MATCH (i) { - const SordNode* binary_node = sord_iter_get_node(i, SORD_OBJECT); - if (sord_node_get_type(binary_node) == SORD_URI) { - ((LilvPlugin*)plugin)->binary_uri = - lilv_node_new_from_node(plugin->world, binary_node); + SerdRange* i = serd_model_range(plugin->world->model, + plugin->plugin_uri, + plugin->world->uris.lv2_binary, + NULL, + NULL); + FOREACH_MATCH (s, i) { + const SerdNode* binary_node = serd_statement_object(s); + if (serd_node_type(binary_node) == SERD_URI) { + ((LilvPlugin*)plugin)->binary_uri = serd_node_copy(binary_node); break; } } - sord_iter_free(i); + serd_range_free(i); } if (!plugin->binary_uri) { LILV_WARNF("Plugin <%s> has no lv2:binary\n", @@ -420,15 +413,18 @@ lilv_plugin_get_class(const LilvPlugin* plugin) lilv_plugin_load_if_necessary((LilvPlugin*)plugin); if (!plugin->plugin_class) { // <plugin> a ?class - SordIter* c = lilv_world_query_internal( - plugin->world, plugin->plugin_uri->node, plugin->world->uris.rdf_a, NULL); - FOREACH_MATCH (c) { - const SordNode* class_node = sord_iter_get_node(c, SORD_OBJECT); - if (sord_node_get_type(class_node) != SORD_URI) { + SerdRange* c = serd_model_range(plugin->world->model, + plugin->plugin_uri, + plugin->world->uris.rdf_a, + NULL, + NULL); + FOREACH_MATCH (s, c) { + const SerdNode* class_node = serd_statement_object(s); + if (serd_node_type(class_node) != SERD_URI) { continue; } - LilvNode* klass = lilv_node_new_from_node(plugin->world, class_node); + LilvNode* klass = serd_node_copy(class_node); if (!lilv_node_equals(klass, plugin->world->lv2_plugin_class->uri)) { const LilvPluginClass* pclass = lilv_plugin_classes_get_by_uri(plugin->world->plugin_classes, klass); @@ -442,7 +438,7 @@ lilv_plugin_get_class(const LilvPlugin* plugin) lilv_node_free(klass); } - sord_iter_free(c); + serd_range_free(c); if (plugin->plugin_class == NULL) { ((LilvPlugin*)plugin)->plugin_class = plugin->world->lv2_plugin_class; @@ -453,11 +449,11 @@ lilv_plugin_get_class(const LilvPlugin* plugin) static LilvNodes* lilv_plugin_get_value_internal(const LilvPlugin* plugin, - const SordNode* predicate) + const SerdNode* predicate) { lilv_plugin_load_if_necessary(plugin); return lilv_world_find_nodes_internal( - plugin->world, plugin->plugin_uri->node, predicate, NULL); + plugin->world, plugin->plugin_uri, predicate, NULL); } bool @@ -468,9 +464,7 @@ lilv_plugin_verify(const LilvPlugin* plugin) return false; } - LilvNode* rdf_type = lilv_new_uri(plugin->world, LILV_NS_RDF "type"); - LilvNodes* results = lilv_plugin_get_value(plugin, rdf_type); - lilv_node_free(rdf_type); + LilvNodes* results = lilv_plugin_get_value(plugin, plugin->world->uris.rdf_a); if (!results) { return false; } @@ -637,57 +631,47 @@ bool lilv_plugin_has_latency(const LilvPlugin* plugin) { lilv_plugin_load_if_necessary(plugin); - SordIter* ports = lilv_world_query_internal(plugin->world, - plugin->plugin_uri->node, - plugin->world->uris.lv2_port, - NULL); + + SerdRange* ports = serd_model_range(plugin->world->model, + plugin->plugin_uri, + plugin->world->uris.lv2_port, + NULL, + NULL); bool ret = false; - FOREACH_MATCH (ports) { - const SordNode* port = sord_iter_get_node(ports, SORD_OBJECT); - - SordIter* prop = - lilv_world_query_internal(plugin->world, - port, - plugin->world->uris.lv2_portProperty, - plugin->world->uris.lv2_reportsLatency); - - SordIter* des = - lilv_world_query_internal(plugin->world, - port, - plugin->world->uris.lv2_designation, - plugin->world->uris.lv2_latency); - - const bool latent = !sord_iter_end(prop) || !sord_iter_end(des); - sord_iter_free(prop); - sord_iter_free(des); - if (latent) { + FOREACH_MATCH (s, ports) { + const SerdNode* port = serd_statement_object(s); + if (serd_model_ask(plugin->world->model, + port, + plugin->world->uris.lv2_portProperty, + plugin->world->uris.lv2_reportsLatency, + NULL) || + serd_model_ask(plugin->world->model, + port, + plugin->world->uris.lv2_designation, + plugin->world->uris.lv2_latency, + NULL)) { ret = true; break; } } - sord_iter_free(ports); + serd_range_free(ports); return ret; } static const LilvPort* lilv_plugin_get_port_by_property(const LilvPlugin* plugin, - const SordNode* port_property) + const SerdNode* port_property) { lilv_plugin_load_ports_if_necessary(plugin); for (uint32_t i = 0; i < plugin->num_ports; ++i) { LilvPort* port = plugin->ports[i]; - SordIter* iter = - lilv_world_query_internal(plugin->world, - port->node->node, - plugin->world->uris.lv2_portProperty, - port_property); - - const bool found = !sord_iter_end(iter); - sord_iter_free(iter); - - if (found) { + if (serd_model_ask(plugin->world->model, + port->node, + plugin->world->uris.lv2_portProperty, + port_property, + NULL)) { return port; } } @@ -703,16 +687,12 @@ lilv_plugin_get_port_by_designation(const LilvPlugin* plugin, LilvWorld* world = plugin->world; lilv_plugin_load_ports_if_necessary(plugin); for (uint32_t i = 0; i < plugin->num_ports; ++i) { - LilvPort* port = plugin->ports[i]; - SordIter* iter = lilv_world_query_internal( - world, port->node->node, world->uris.lv2_designation, designation->node); - - const bool found = - !sord_iter_end(iter) && - (!port_class || lilv_port_is_a(plugin, port, port_class)); - sord_iter_free(iter); + LilvPort* port = plugin->ports[i]; + const bool has_designation = serd_model_ask( + world->model, port->node, world->uris.lv2_designation, designation, NULL); - if (found) { + if (has_designation && + (!port_class || lilv_port_is_a(plugin, port, port_class))) { return port; } } @@ -749,13 +729,13 @@ bool lilv_plugin_has_feature(const LilvPlugin* plugin, const LilvNode* feature) { lilv_plugin_load_if_necessary(plugin); - const SordNode* predicates[] = {plugin->world->uris.lv2_requiredFeature, + const SerdNode* predicates[] = {plugin->world->uris.lv2_requiredFeature, plugin->world->uris.lv2_optionalFeature, NULL}; - for (const SordNode** pred = predicates; *pred; ++pred) { - if (lilv_world_ask_internal( - plugin->world, plugin->plugin_uri->node, *pred, feature->node)) { + for (const SerdNode** pred = predicates; *pred; ++pred) { + if (serd_model_ask( + plugin->world->model, plugin->plugin_uri, *pred, feature, NULL)) { return true; } } @@ -778,7 +758,7 @@ lilv_plugin_get_optional_features(const LilvPlugin* plugin) { lilv_plugin_load_if_necessary(plugin); return lilv_world_find_nodes_internal(plugin->world, - plugin->plugin_uri->node, + plugin->plugin_uri, plugin->world->uris.lv2_optionalFeature, NULL); } @@ -788,7 +768,7 @@ lilv_plugin_get_required_features(const LilvPlugin* plugin) { lilv_plugin_load_if_necessary(plugin); return lilv_world_find_nodes_internal(plugin->world, - plugin->plugin_uri->node, + plugin->plugin_uri, plugin->world->uris.lv2_requiredFeature, NULL); } @@ -797,16 +777,16 @@ bool lilv_plugin_has_extension_data(const LilvPlugin* plugin, const LilvNode* uri) { if (!lilv_node_is_uri(uri)) { - LILV_ERRORF("Extension data `%s' is not a URI\n", - sord_node_get_string(uri->node)); + LILV_ERRORF("Extension data `%s' is not a URI\n", serd_node_string(uri)); return false; } lilv_plugin_load_if_necessary(plugin); - return lilv_world_ask_internal(plugin->world, - plugin->plugin_uri->node, - plugin->world->uris.lv2_extensionData, - uri->node); + return serd_model_ask(plugin->world->model, + plugin->plugin_uri, + plugin->world->uris.lv2_extensionData, + uri, + NULL); } LilvNodes* @@ -846,73 +826,51 @@ lilv_plugin_get_project(const LilvPlugin* plugin) { lilv_plugin_load_if_necessary(plugin); - SordNode* lv2_project = - sord_new_uri(plugin->world->world, (const uint8_t*)LV2_CORE__project); - - SordIter* projects = lilv_world_query_internal( - plugin->world, plugin->plugin_uri->node, lv2_project, NULL); - - sord_node_free(plugin->world->world, lv2_project); - - if (sord_iter_end(projects)) { - sord_iter_free(projects); - return NULL; - } - - const SordNode* project = sord_iter_get_node(projects, SORD_OBJECT); - - sord_iter_free(projects); - return lilv_node_new_from_node(plugin->world, project); + return serd_node_copy(serd_model_get(plugin->world->model, + plugin->plugin_uri, + plugin->world->uris.lv2_project, + NULL, + NULL)); } -static const SordNode* +static SerdNode* lilv_plugin_get_author(const LilvPlugin* plugin) { lilv_plugin_load_if_necessary(plugin); - SordNode* doap_maintainer = - sord_new_uri(plugin->world->world, NS_DOAP "maintainer"); - - SordIter* maintainers = lilv_world_query_internal( - plugin->world, plugin->plugin_uri->node, doap_maintainer, NULL); + SerdNode* doap_maintainer = + serd_new_uri(SERD_STATIC_STRING(NS_DOAP "maintainer")); - if (sord_iter_end(maintainers)) { - sord_iter_free(maintainers); + const SerdNode* maintainer = serd_model_get( + plugin->world->model, plugin->plugin_uri, doap_maintainer, NULL, NULL); + if (!maintainer) { LilvNode* project = lilv_plugin_get_project(plugin); if (!project) { - sord_node_free(plugin->world->world, doap_maintainer); + serd_node_free(doap_maintainer); return NULL; } - maintainers = lilv_world_query_internal( - plugin->world, project->node, doap_maintainer, NULL); + maintainer = serd_model_get( + plugin->world->model, project, doap_maintainer, NULL, NULL); lilv_node_free(project); } - sord_node_free(plugin->world->world, doap_maintainer); + serd_node_free(doap_maintainer); - if (sord_iter_end(maintainers)) { - sord_iter_free(maintainers); - return NULL; - } - - const SordNode* author = sord_iter_get_node(maintainers, SORD_OBJECT); - - sord_iter_free(maintainers); - return author; + return maintainer ? serd_node_copy(maintainer) : NULL; } static LilvNode* -lilv_plugin_get_author_property(const LilvPlugin* plugin, const uint8_t* uri) +lilv_plugin_get_author_property(const LilvPlugin* plugin, const char* uri) { - const SordNode* author = lilv_plugin_get_author(plugin); + SerdNode* author = lilv_plugin_get_author(plugin); if (author) { - SordWorld* sworld = plugin->world->world; - SordNode* pred = sord_new_uri(sworld, uri); - LilvNode* ret = lilv_plugin_get_one(plugin, author, pred); - sord_node_free(sworld, pred); + SerdNode* pred = serd_new_uri(SERD_MEASURE_STRING(uri)); + LilvNode* ret = lilv_plugin_get_one(plugin, author, pred); + serd_node_free(pred); + serd_node_free(author); return ret; } return NULL; @@ -947,17 +905,15 @@ lilv_plugin_get_uis(const LilvPlugin* plugin) { lilv_plugin_load_if_necessary(plugin); - SordNode* ui_ui_node = - sord_new_uri(plugin->world->world, (const uint8_t*)LV2_UI__ui); - SordNode* ui_binary_node = - sord_new_uri(plugin->world->world, (const uint8_t*)LV2_UI__binary); + SerdNode* ui_ui_node = serd_new_uri(SERD_STATIC_STRING(LV2_UI__ui)); + SerdNode* ui_binary_node = serd_new_uri(SERD_STATIC_STRING(LV2_UI__binary)); - LilvUIs* result = lilv_uis_new(); - SordIter* uis = lilv_world_query_internal( - plugin->world, plugin->plugin_uri->node, ui_ui_node, NULL); + LilvUIs* result = lilv_uis_new(); + SerdRange* uis = serd_model_range( + plugin->world->model, plugin->plugin_uri, ui_ui_node, NULL, NULL); - FOREACH_MATCH (uis) { - const SordNode* ui = sord_iter_get_node(uis, SORD_OBJECT); + FOREACH_MATCH (s, uis) { + const SerdNode* ui = serd_statement_object(s); LilvNode* type = lilv_plugin_get_unique(plugin, ui, plugin->world->uris.rdf_a); @@ -967,30 +923,30 @@ lilv_plugin_get_uis(const LilvPlugin* plugin) binary = lilv_plugin_get_unique(plugin, ui, ui_binary_node); } - if (sord_node_get_type(ui) != SORD_URI || !lilv_node_is_uri(type) || + if (serd_node_type(ui) != SERD_URI || !lilv_node_is_uri(type) || !lilv_node_is_uri(binary)) { lilv_node_free(binary); lilv_node_free(type); - LILV_ERRORF("Corrupt UI <%s>\n", sord_node_get_string(ui)); + LILV_ERRORF("Corrupt UI <%s>\n", serd_node_string(ui)); continue; } - LilvUI* lilv_ui = lilv_ui_new( - plugin->world, lilv_node_new_from_node(plugin->world, ui), type, binary); + LilvUI* lilv_ui = + lilv_ui_new(plugin->world, serd_node_copy(ui), type, binary); zix_tree_insert((ZixTree*)result, lilv_ui, NULL); } - sord_iter_free(uis); + serd_range_free(uis); - sord_node_free(plugin->world->world, ui_binary_node); - sord_node_free(plugin->world->world, ui_ui_node); + serd_node_free(ui_binary_node); + serd_node_free(ui_ui_node); if (lilv_uis_size(result) > 0) { return result; + } else { + lilv_uis_free(result); + return NULL; } - - lilv_uis_free(result); - return NULL; } LilvNodes* @@ -1000,7 +956,7 @@ lilv_plugin_get_related(const LilvPlugin* plugin, const LilvNode* type) LilvWorld* const world = plugin->world; LilvNodes* const related = lilv_world_find_nodes_internal( - world, NULL, world->uris.lv2_appliesTo, lilv_plugin_get_uri(plugin)->node); + world, NULL, world->uris.lv2_appliesTo, lilv_plugin_get_uri(plugin)); if (!type) { return related; @@ -1009,10 +965,8 @@ lilv_plugin_get_related(const LilvPlugin* plugin, const LilvNode* type) LilvNodes* matches = lilv_nodes_new(); LILV_FOREACH (nodes, i, related) { LilvNode* node = (LilvNode*)lilv_collection_get((ZixTree*)related, i); - if (lilv_world_ask_internal( - world, node->node, world->uris.rdf_a, type->node)) { - zix_tree_insert( - (ZixTree*)matches, lilv_node_new_from_node(world, node->node), NULL); + if (serd_model_ask(world->model, node, world->uris.rdf_a, type, NULL)) { + zix_tree_insert((ZixTree*)matches, serd_node_copy(node), NULL); } } @@ -1023,27 +977,32 @@ lilv_plugin_get_related(const LilvPlugin* plugin, const LilvNode* type) static SerdEnv* new_lv2_env(const SerdNode* base) { - SerdEnv* env = serd_env_new(base); - -#define USTR(s) ((const uint8_t*)(s)) - - serd_env_set_prefix_from_strings(env, USTR("doap"), USTR(LILV_NS_DOAP)); - serd_env_set_prefix_from_strings(env, USTR("foaf"), USTR(LILV_NS_FOAF)); - serd_env_set_prefix_from_strings(env, USTR("lv2"), USTR(LILV_NS_LV2)); - serd_env_set_prefix_from_strings(env, USTR("owl"), USTR(LILV_NS_OWL)); - serd_env_set_prefix_from_strings(env, USTR("rdf"), USTR(LILV_NS_RDF)); - serd_env_set_prefix_from_strings(env, USTR("rdfs"), USTR(LILV_NS_RDFS)); - serd_env_set_prefix_from_strings(env, USTR("xsd"), USTR(LILV_NS_XSD)); + SerdEnv* env = serd_env_new(serd_node_string_view(base)); + + serd_env_set_prefix( + env, SERD_STATIC_STRING("doap"), SERD_STATIC_STRING(NS_DOAP)); + serd_env_set_prefix( + env, SERD_STATIC_STRING("foaf"), SERD_STATIC_STRING(NS_FOAF)); + serd_env_set_prefix( + env, SERD_STATIC_STRING("lv2"), SERD_STATIC_STRING(NS_LV2)); + serd_env_set_prefix( + env, SERD_STATIC_STRING("owl"), SERD_STATIC_STRING(NS_OWL)); + serd_env_set_prefix( + env, SERD_STATIC_STRING("rdf"), SERD_STATIC_STRING(NS_RDF)); + serd_env_set_prefix( + env, SERD_STATIC_STRING("rdfs"), SERD_STATIC_STRING(NS_RDFS)); + serd_env_set_prefix( + env, SERD_STATIC_STRING("xsd"), SERD_STATIC_STRING(NS_XSD)); return env; } static void -maybe_write_prefixes(SerdWriter* writer, SerdEnv* env, FILE* file) +maybe_write_prefixes(const SerdSink* sink, SerdEnv* env, FILE* file) { fseek(file, 0, SEEK_END); if (ftell(file) == 0) { - serd_env_foreach(env, (SerdPrefixSink)serd_writer_set_prefix, writer); + serd_env_write_prefixes(env, sink); } else { fprintf(file, "\n"); } @@ -1057,31 +1016,30 @@ 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->node); + const SerdNode* base = base_uri; SerdEnv* env = new_lv2_env(base); - SerdWriter* writer = - serd_writer_new(SERD_TURTLE, - (SerdStyle)(SERD_STYLE_ABBREVIATED | SERD_STYLE_CURIED), - env, - NULL, - serd_file_sink, - plugin_file); + SerdByteSink* const sink = + serd_byte_sink_new_function((SerdWriteFunc)fwrite, plugin_file, 1); + + SerdWriter* writer = serd_writer_new(world->world, SERD_TURTLE, 0, env, sink); + + const SerdSink* iface = serd_writer_sink(writer); // Write prefixes if this is a new file - maybe_write_prefixes(writer, env, plugin_file); + maybe_write_prefixes(iface, env, plugin_file); // Write plugin description - SordIter* plug_iter = - lilv_world_query_internal(world, subject->node, NULL, NULL); - sord_write_iter(plug_iter, writer); + SerdRange* plug_range = + serd_model_range(world->model, subject, NULL, NULL, NULL); + serd_range_serialise(plug_range, iface, 0); // Write port descriptions for (uint32_t i = 0; i < num_ports; ++i) { const LilvPort* port = plugin->ports[i]; - SordIter* port_iter = - lilv_world_query_internal(world, port->node->node, NULL, NULL); - sord_write_iter(port_iter, writer); + SerdRange* port_range = + serd_model_range(world->model, port->node, NULL, NULL, NULL); + serd_range_serialise(port_range, iface, 0); } serd_writer_free(writer); @@ -1095,45 +1053,37 @@ lilv_plugin_write_manifest_entry(LilvWorld* world, FILE* manifest_file, const char* plugin_file_path) { - (void)world; - const LilvNode* subject = lilv_plugin_get_uri(plugin); - const SerdNode* base = sord_node_to_serd_node(base_uri->node); + const SerdNode* base = base_uri; SerdEnv* env = new_lv2_env(base); - SerdWriter* writer = - serd_writer_new(SERD_TURTLE, - (SerdStyle)(SERD_STYLE_ABBREVIATED | SERD_STYLE_CURIED), - env, - NULL, - serd_file_sink, - manifest_file); + SerdByteSink* const sink = + serd_byte_sink_new_function((SerdWriteFunc)fwrite, manifest_file, 1); + + SerdWriter* writer = serd_writer_new(world->world, SERD_TURTLE, 0, env, sink); + + const SerdSink* iface = serd_writer_sink(writer); // Write prefixes if this is a new file - maybe_write_prefixes(writer, env, manifest_file); + maybe_write_prefixes(iface, env, manifest_file); // Write manifest entry - serd_writer_write_statement( - writer, - 0, - NULL, - 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); - - const SerdNode file_node = - serd_node_from_string(SERD_URI, (const uint8_t*)plugin_file_path); - serd_writer_write_statement( - writer, - 0, - NULL, - sord_node_to_serd_node(subject->node), - sord_node_to_serd_node(plugin->world->uris.rdfs_seeAlso), - &file_node, - 0, - 0); + serd_sink_write(iface, + 0, + subject, + plugin->world->uris.rdf_a, + plugin->world->uris.lv2_Plugin, + NULL); + + const SerdNode* file_node = + serd_new_uri(SERD_MEASURE_STRING(plugin_file_path)); + + serd_sink_write(serd_writer_sink(writer), + 0, + subject, + plugin->world->uris.rdfs_seeAlso, + file_node, + NULL); serd_writer_free(writer); serd_env_free(env); diff --git a/src/pluginclass.c b/src/pluginclass.c index 2f0afe7..96ad2cb 100644 --- a/src/pluginclass.c +++ b/src/pluginclass.c @@ -17,7 +17,7 @@ #include "lilv_internal.h" #include "lilv/lilv.h" -#include "sord/sord.h" +#include "serd/serd.h" #include "zix/tree.h" #include <stdbool.h> @@ -25,16 +25,17 @@ LilvPluginClass* lilv_plugin_class_new(LilvWorld* world, - const SordNode* parent_node, - const SordNode* uri, + const SerdNode* parent_node, + const SerdNode* uri, const char* label) { LilvPluginClass* pc = (LilvPluginClass*)malloc(sizeof(LilvPluginClass)); - pc->world = world; - pc->uri = lilv_node_new_from_node(world, uri); - pc->label = lilv_node_new(world, LILV_VALUE_STRING, label); - pc->parent_uri = - (parent_node ? lilv_node_new_from_node(world, parent_node) : NULL); + + pc->world = world; + pc->uri = serd_node_copy(uri); + pc->label = serd_new_string(SERD_MEASURE_STRING(label)); + pc->parent_uri = (parent_node ? serd_node_copy(parent_node) : NULL); + return pc; } @@ -21,7 +21,7 @@ #include "lv2/event/event.h" #include "lilv/lilv.h" -#include "sord/sord.h" +#include "serd/serd.h" #include "zix/tree.h" #include <assert.h> @@ -31,16 +31,14 @@ #include <stdlib.h> LilvPort* -lilv_port_new(LilvWorld* world, - const SordNode* node, - uint32_t index, - const char* symbol) +lilv_port_new(const SerdNode* node, uint32_t index, const char* symbol) { - LilvPort* port = (LilvPort*)malloc(sizeof(LilvPort)); - port->node = lilv_node_new_from_node(world, node); - port->index = index; - port->symbol = lilv_node_new(world, LILV_VALUE_STRING, symbol); - port->classes = lilv_nodes_new(); + LilvPort* const port = (LilvPort*)malloc(sizeof(LilvPort)); + + port->node = serd_node_copy(node); + port->index = index; + port->symbol = serd_new_string(SERD_MEASURE_STRING(symbol)); + port->classes = lilv_nodes_new(); return port; } @@ -78,10 +76,11 @@ lilv_port_has_property(const LilvPlugin* plugin, const LilvPort* port, const LilvNode* property) { - return lilv_world_ask_internal(plugin->world, - port->node->node, - plugin->world->uris.lv2_portProperty, - property->node); + return serd_model_ask(plugin->world->model, + port->node, + plugin->world->uris.lv2_portProperty, + property, + NULL); } bool @@ -89,15 +88,15 @@ lilv_port_supports_event(const LilvPlugin* plugin, const LilvPort* port, const LilvNode* event_type) { - const uint8_t* predicates[] = {(const uint8_t*)LV2_EVENT__supportsEvent, - (const uint8_t*)LV2_ATOM__supports, - NULL}; - - for (const uint8_t** pred = predicates; *pred; ++pred) { - if (lilv_world_ask_internal(plugin->world, - port->node->node, - sord_new_uri(plugin->world->world, *pred), - event_type->node)) { + const char* predicates[] = { + LV2_EVENT__supportsEvent, LV2_ATOM__supports, NULL}; + + for (const char** pred = predicates; *pred; ++pred) { + if (serd_model_ask(plugin->world->model, + port->node, + serd_new_uri(SERD_MEASURE_STRING(*pred)), + event_type, + NULL)) { return true; } } @@ -107,10 +106,10 @@ lilv_port_supports_event(const LilvPlugin* plugin, static LilvNodes* lilv_port_get_value_by_node(const LilvPlugin* plugin, const LilvPort* port, - const SordNode* predicate) + const SerdNode* predicate) { return lilv_world_find_nodes_internal( - plugin->world, port->node->node, predicate, NULL); + plugin->world, port->node, predicate, NULL); } const LilvNode* @@ -127,12 +126,11 @@ lilv_port_get_value(const LilvPlugin* plugin, const LilvNode* predicate) { if (!lilv_node_is_uri(predicate)) { - LILV_ERRORF("Predicate `%s' is not a URI\n", - sord_node_get_string(predicate->node)); + LILV_ERRORF("Predicate `%s' is not a URI\n", serd_node_string(predicate)); return NULL; } - return lilv_port_get_value_by_node(plugin, port, predicate->node); + return lilv_port_get_value_by_node(plugin, port, predicate); } LilvNode* @@ -231,19 +229,20 @@ lilv_port_get_range(const LilvPlugin* plugin, LilvScalePoints* lilv_port_get_scale_points(const LilvPlugin* plugin, const LilvPort* port) { - SordIter* points = lilv_world_query_internal( - plugin->world, - port->node->node, - sord_new_uri(plugin->world->world, (const uint8_t*)LV2_CORE__scalePoint), - NULL); + SerdRange* points = + serd_model_range(plugin->world->model, + port->node, + serd_new_uri(SERD_STATIC_STRING(LV2_CORE__scalePoint)), + NULL, + NULL); LilvScalePoints* ret = NULL; - if (!sord_iter_end(points)) { + if (!serd_range_empty(points)) { ret = lilv_scale_points_new(); } - FOREACH_MATCH (points) { - const SordNode* point = sord_iter_get_node(points, SORD_OBJECT); + FOREACH_MATCH (s, points) { + const SerdNode* point = serd_statement_object(s); LilvNode* value = lilv_plugin_get_unique(plugin, point, plugin->world->uris.rdf_value); @@ -255,7 +254,7 @@ lilv_port_get_scale_points(const LilvPlugin* plugin, const LilvPort* port) zix_tree_insert((ZixTree*)ret, lilv_scale_point_new(value, label), NULL); } } - sord_iter_free(points); + serd_range_free(points); assert(!ret || lilv_nodes_size(ret) > 0); return ret; @@ -264,9 +263,8 @@ lilv_port_get_scale_points(const LilvPlugin* plugin, const LilvPort* port) LilvNodes* lilv_port_get_properties(const LilvPlugin* plugin, const LilvPort* port) { - LilvNode* pred = lilv_node_new_from_node( - plugin->world, plugin->world->uris.lv2_portProperty); - LilvNodes* ret = lilv_port_get_value(plugin, port, pred); + LilvNode* pred = serd_node_copy(plugin->world->uris.lv2_portProperty); + LilvNodes* ret = lilv_port_get_value(plugin, port, pred); lilv_node_free(pred); return ret; } diff --git a/src/query.c b/src/query.c index eb179f2..b77c2b4 100644 --- a/src/query.c +++ b/src/query.c @@ -17,7 +17,7 @@ #include "lilv_internal.h" #include "lilv/lilv.h" -#include "sord/sord.h" +#include "serd/serd.h" #include "zix/tree.h" #include <stdlib.h> @@ -53,49 +53,48 @@ lilv_lang_matches(const char* a, const char* b) } static LilvNodes* -lilv_nodes_from_stream_objects_i18n(LilvWorld* world, - SordIter* stream, - SordQuadIndex field) +lilv_nodes_from_range_i18n(LilvWorld* world, SerdRange* range, SerdField field) { + (void)world; + LilvNodes* values = lilv_nodes_new(); - const SordNode* nolang = NULL; // Untranslated value - const SordNode* partial = NULL; // Partial language match + const SerdNode* nolang = NULL; // Untranslated value + const SerdNode* partial = NULL; // Partial language match char* syslang = lilv_get_lang(); - FOREACH_MATCH (stream) { - const SordNode* value = sord_iter_get_node(stream, field); - if (sord_node_get_type(value) == SORD_LITERAL) { - const char* lang = sord_node_get_language(value); - - if (!lang) { - nolang = value; + FOREACH_MATCH (s, range) { + const SerdNode* value = serd_statement_node(s, field); + if (serd_node_type(value) == SERD_LITERAL) { + const SerdNode* lang = serd_node_language(value); + LilvLangMatch lm = LILV_LANG_MATCH_NONE; + if (lang) { + lm = (syslang) ? lilv_lang_matches(serd_node_string(lang), syslang) + : LILV_LANG_MATCH_PARTIAL; } else { - switch (lilv_lang_matches(lang, syslang)) { - case LILV_LANG_MATCH_EXACT: - // Exact language match, add to results - zix_tree_insert( - (ZixTree*)values, lilv_node_new_from_node(world, value), NULL); - break; - case LILV_LANG_MATCH_PARTIAL: - // Partial language match, save in case we find no exact - partial = value; - break; - case LILV_LANG_MATCH_NONE: - break; + nolang = value; + if (!syslang) { + lm = LILV_LANG_MATCH_EXACT; } } + + if (lm == LILV_LANG_MATCH_EXACT) { + // Exact language match, add to results + zix_tree_insert((ZixTree*)values, serd_node_copy(value), NULL); + } else if (lm == LILV_LANG_MATCH_PARTIAL) { + // Partial language match, save in case we find no exact + partial = value; + } } else { - zix_tree_insert( - (ZixTree*)values, lilv_node_new_from_node(world, value), NULL); + zix_tree_insert((ZixTree*)values, serd_node_copy(value), NULL); } } - sord_iter_free(stream); + serd_range_free(range); free(syslang); if (lilv_nodes_size(values) > 0) { return values; } - const SordNode* best = nolang; + const SerdNode* best = nolang; if (syslang && partial) { // Partial language match for system language best = partial; @@ -106,8 +105,7 @@ lilv_nodes_from_stream_objects_i18n(LilvWorld* world, } if (best) { - zix_tree_insert( - (ZixTree*)values, lilv_node_new_from_node(world, best), NULL); + zix_tree_insert((ZixTree*)values, serd_node_copy(best), NULL); } else { // No matches whatsoever lilv_nodes_free(values); @@ -118,27 +116,23 @@ lilv_nodes_from_stream_objects_i18n(LilvWorld* world, } LilvNodes* -lilv_nodes_from_stream_objects(LilvWorld* world, - SordIter* stream, - SordQuadIndex field) +lilv_nodes_from_range(LilvWorld* world, SerdRange* range, SerdField field) { - if (sord_iter_end(stream)) { - sord_iter_free(stream); + if (serd_range_empty(range)) { + serd_range_free(range); return NULL; - } - - if (world->opt.filter_language) { - return lilv_nodes_from_stream_objects_i18n(world, stream, field); - } - - LilvNodes* values = lilv_nodes_new(); - FOREACH_MATCH (stream) { - const SordNode* value = sord_iter_get_node(stream, field); - LilvNode* node = lilv_node_new_from_node(world, value); - if (node) { - zix_tree_insert((ZixTree*)values, node, NULL); + } else if (world->opt.filter_language) { + return lilv_nodes_from_range_i18n(world, range, field); + } else { + LilvNodes* values = lilv_nodes_new(); + FOREACH_MATCH (s, range) { + const SerdNode* value = serd_statement_node(s, field); + LilvNode* node = serd_node_copy(value); + if (node) { + zix_tree_insert((ZixTree*)values, node, NULL); + } } + serd_range_free(range); + return values; } - sord_iter_free(stream); - return values; } diff --git a/src/state.c b/src/state.c index d34f761..041d901 100644 --- a/src/state.c +++ b/src/state.c @@ -19,7 +19,6 @@ #include "lilv/lilv.h" #include "serd/serd.h" -#include "sord/sord.h" #include "sratom/sratom.h" #include "zix/tree.h" @@ -38,8 +37,6 @@ #include <stdlib.h> #include <string.h> -#define USTR(s) ((const uint8_t*)(s)) - typedef struct { void* value; ///< Value/Object size_t size; ///< Size of value @@ -127,28 +124,43 @@ path_rel_free(void* ptr) free(ptr); } +static LV2_Atom* +new_atom(const uint32_t size, const uint32_t type, const void* const value) +{ + LV2_Atom* atom = (LV2_Atom*)malloc(sizeof(LV2_Atom) + size); + atom->size = size; + atom->type = type; + memcpy(atom + 1, value, size); + return atom; +} + static PortValue* -append_port_value(LilvState* state, - const char* port_symbol, - const void* value, - uint32_t size, - uint32_t type) +append_port_value(LilvState* state, const char* port_symbol, LV2_Atom* atom) { PortValue* pv = NULL; - if (value) { + if (atom) { state->values = (PortValue*)realloc( state->values, (++state->n_values) * sizeof(PortValue)); - pv = &state->values[state->n_values - 1]; - pv->symbol = lilv_strdup(port_symbol); - pv->atom = (LV2_Atom*)malloc(sizeof(LV2_Atom) + size); - pv->atom->size = size; - pv->atom->type = type; - memcpy(pv->atom + 1, value, size); + pv = &state->values[state->n_values - 1]; + pv->symbol = lilv_strdup(port_symbol); + pv->atom = atom; } return pv; } +static PortValue* +append_port_value_raw(LilvState* state, + const char* port_symbol, + const void* value, + uint32_t size, + uint32_t type) +{ + return value + ? append_port_value(state, port_symbol, new_atom(size, type, value)) + : NULL; +} + static const char* lilv_state_rel2abs(const LilvState* state, const char* path) { @@ -471,7 +483,7 @@ lilv_state_new_from_instance(const LilvPlugin* plugin, uint32_t type = 0; 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); + append_port_value_raw(state, sym, value, size, type); } } lilv_node_free(lv2_ControlPort); @@ -498,9 +510,7 @@ lilv_state_new_from_instance(const LilvPlugin* plugin, } } - if (state->values) { - qsort(state->values, state->n_values, sizeof(PortValue), value_cmp); - } + qsort(state->values, state->n_values, sizeof(PortValue), value_cmp); free(sfeatures); return state; @@ -565,27 +575,62 @@ lilv_state_restore(const LilvState* state, } static void -set_state_dir_from_model(LilvState* state, const SordNode* graph) +set_state_dir_from_model(LilvState* state, const SerdNode* graph) { if (!state->dir && graph) { - const char* uri = (const char*)sord_node_get_string(graph); - char* path = lilv_file_uri_parse(uri, NULL); + const char* const uri = serd_node_string(graph); + char* const path = serd_parse_file_uri(uri, NULL); state->dir = lilv_path_join(path, NULL); - free(path); + serd_free(path); } assert(!state->dir || lilv_path_is_absolute(state->dir)); } +static void +add_object_to_properties(SerdModel* model, + const SerdEnv* env, + LV2_URID_Map* map, + const SerdStatement* s, + SratomLoader* loader, + LV2_URID atom_Path, + PropertyArray* props) +{ + const SerdNode* p = serd_statement_predicate(s); + const SerdNode* o = serd_statement_object(s); + const char* key = serd_node_string(p); + + LV2_Atom* atom = sratom_from_model(loader, serd_env_base_uri(env), model, o); + + Property prop = {malloc(atom->size), + atom->size, + map->map(map->handle, key), + atom->type, + LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE}; + + memcpy(prop.value, LV2_ATOM_BODY_CONST(atom), atom->size); + if (atom->type == atom_Path) { + prop.flags = LV2_STATE_IS_POD; + } + + if (prop.value) { + props->props = + (Property*)realloc(props->props, (++props->n) * sizeof(Property)); + props->props[props->n - 1] = prop; + } + + sratom_free(atom); +} + static LilvState* new_state_from_model(LilvWorld* world, LV2_URID_Map* map, - SordModel* model, - const SordNode* node, + SerdModel* model, + const SerdNode* node, const char* dir) { // Check that we know at least something about this state subject - if (!sord_ask(model, node, 0, 0, 0)) { + if (!serd_model_ask(model, node, 0, 0, 0)) { return NULL; } @@ -593,118 +638,101 @@ new_state_from_model(LilvWorld* world, LilvState* const state = (LilvState*)calloc(1, sizeof(LilvState)); state->dir = lilv_path_join(dir, NULL); state->atom_Path = map->map(map->handle, LV2_ATOM__Path); - state->uri = lilv_node_new_from_node(world, node); + state->uri = serd_node_copy(node); // Get the plugin URI this state applies to - SordIter* i = sord_search(model, node, world->uris.lv2_appliesTo, 0, 0); + SerdIter* i = serd_model_find(model, node, world->uris.lv2_appliesTo, 0, 0); if (i) { - const SordNode* object = sord_iter_get_node(i, SORD_OBJECT); - const SordNode* graph = sord_iter_get_node(i, SORD_GRAPH); - state->plugin_uri = lilv_node_new_from_node(world, object); + const SerdStatement* s = serd_iter_get(i); + const SerdNode* object = serd_statement_object(s); + const SerdNode* graph = serd_statement_graph(s); + state->plugin_uri = serd_node_copy(object); set_state_dir_from_model(state, graph); - sord_iter_free(i); - } else if (sord_ask( + serd_iter_free(i); + } else if (serd_model_ask( model, node, world->uris.rdf_a, world->uris.lv2_Plugin, 0)) { // Loading plugin description as state (default state) - state->plugin_uri = lilv_node_new_from_node(world, node); + state->plugin_uri = serd_node_copy(node); } else { LILV_ERRORF("State %s missing lv2:appliesTo property\n", - sord_node_get_string(node)); + serd_node_string(node)); } // Get the state label - i = sord_search(model, node, world->uris.rdfs_label, NULL, NULL); + i = serd_model_find(model, node, world->uris.rdfs_label, NULL, NULL); if (i) { - const SordNode* object = sord_iter_get_node(i, SORD_OBJECT); - const SordNode* graph = sord_iter_get_node(i, SORD_GRAPH); - state->label = lilv_strdup((const char*)sord_node_get_string(object)); + const SerdStatement* s = serd_iter_get(i); + const SerdNode* object = serd_statement_object(s); + const SerdNode* graph = serd_statement_graph(s); + state->label = lilv_strdup(serd_node_string(object)); set_state_dir_from_model(state, graph); - sord_iter_free(i); + serd_iter_free(i); + } + + SerdEnv* env = serd_env_new(SERD_EMPTY_STRING()); + SratomLoader* loader = sratom_loader_new(world->world, map); + SerdBuffer buffer = {NULL, 0}; + + // Get metadata + SerdRange* meta = serd_model_range(model, node, 0, 0, 0); + FOREACH_MATCH (s, meta) { + const SerdNode* p = serd_statement_predicate(s); + const SerdNode* o = serd_statement_object(s); + if (!serd_node_equals(p, world->uris.state_state) && + !serd_node_equals(p, world->uris.lv2_appliesTo) && + !serd_node_equals(p, world->uris.lv2_port) && + !serd_node_equals(p, world->uris.rdfs_label) && + !serd_node_equals(p, world->uris.rdfs_seeAlso) && + !(serd_node_equals(p, world->uris.rdf_a) && + serd_node_equals(o, world->uris.pset_Preset))) { + add_object_to_properties( + model, env, map, s, loader, state->atom_Path, &state->metadata); + } } - - 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); + serd_range_free(meta); // Get port values - SordIter* ports = sord_search(model, node, world->uris.lv2_port, 0, 0); - FOREACH_MATCH (ports) { - const SordNode* port = sord_iter_get_node(ports, SORD_OBJECT); - - SordNode* label = sord_get(model, port, world->uris.rdfs_label, 0, 0); - SordNode* symbol = sord_get(model, port, world->uris.lv2_symbol, 0, 0); - SordNode* value = sord_get(model, port, world->uris.pset_value, 0, 0); + SerdRange* ports = serd_model_range(model, node, world->uris.lv2_port, 0, 0); + FOREACH_MATCH (s, ports) { + const SerdNode* port = serd_statement_object(s); + + const SerdNode* label = + serd_model_get(model, port, world->uris.rdfs_label, 0, 0); + const SerdNode* symbol = + serd_model_get(model, port, world->uris.lv2_symbol, 0, 0); + const SerdNode* value = + serd_model_get(model, port, world->uris.pset_value, 0, 0); if (!value) { - value = sord_get(model, port, world->uris.lv2_default, 0, 0); + value = serd_model_get(model, port, world->uris.lv2_default, 0, 0); } if (!symbol) { - LILV_ERRORF("State `%s' port missing symbol.\n", - sord_node_get_string(node)); + LILV_ERRORF("State `%s' port missing symbol.\n", serd_node_string(node)); } else if (value) { - chunk.len = 0; - sratom_read(sratom, &forge, world->world, model, value); - const LV2_Atom* atom = (const LV2_Atom*)chunk.buf; - append_port_value(state, - (const char*)sord_node_get_string(symbol), - LV2_ATOM_BODY_CONST(atom), - atom->size, - atom->type); + serd_node_string(symbol), + sratom_from_model(loader, NULL, model, value)); if (label) { - lilv_state_set_label(state, (const char*)sord_node_get_string(label)); + lilv_state_set_label(state, serd_node_string(label)); } } - sord_node_free(world->world, value); - sord_node_free(world->world, symbol); - sord_node_free(world->world, label); } - sord_iter_free(ports); + serd_range_free(ports); // Get properties - SordNode* statep = sord_new_uri(world->world, USTR(LV2_STATE__state)); - SordNode* state_node = sord_get(model, node, statep, NULL, NULL); + const SerdNode* state_node = + serd_model_get(model, node, world->uris.state_state, NULL, NULL); if (state_node) { - SordIter* props = sord_search(model, state_node, 0, 0, 0); - FOREACH_MATCH (props) { - const SordNode* p = sord_iter_get_node(props, SORD_PREDICATE); - const SordNode* o = sord_iter_get_node(props, SORD_OBJECT); - const char* key = (const char*)sord_node_get_string(p); - - chunk.len = 0; - lv2_atom_forge_set_sink( - &forge, sratom_forge_sink, sratom_forge_deref, &chunk); - - sratom_read(sratom, &forge, world->world, model, o); - const LV2_Atom* atom = (const LV2_Atom*)chunk.buf; - uint32_t flags = LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE; - Property prop = {NULL, 0, 0, 0, flags}; - - prop.key = map->map(map->handle, key); - prop.type = atom->type; - prop.size = atom->size; - prop.value = malloc(atom->size); - memcpy(prop.value, LV2_ATOM_BODY_CONST(atom), atom->size); - if (atom->type == forge.Path) { - prop.flags = LV2_STATE_IS_POD; - } - - if (prop.value) { - state->props.props = (Property*)realloc( - state->props.props, (++state->props.n) * sizeof(Property)); - state->props.props[state->props.n - 1] = prop; - } + SerdRange* props = serd_model_range(model, state_node, 0, 0, 0); + FOREACH_MATCH (s, props) { + add_object_to_properties( + model, env, map, s, loader, state->atom_Path, &state->props); } - sord_iter_free(props); + serd_range_free(props); } - sord_node_free(world->world, state_node); - sord_node_free(world->world, statep); - serd_free((void*)chunk.buf); - sratom_free(sratom); + serd_free(buffer.buf); + sratom_loader_free(loader); if (state->props.props) { qsort(state->props.props, state->props.n, sizeof(Property), property_cmp); @@ -727,7 +755,7 @@ lilv_state_new_from_world(LilvWorld* world, return NULL; } - return new_state_from_model(world, map, world->model, node->node, NULL); + return new_state_from_model(world, map, world->model, node, NULL); } LilvState* @@ -742,17 +770,22 @@ lilv_state_new_from_file(LilvWorld* world, return NULL; } - uint8_t* abs_path = (uint8_t*)lilv_path_absolute(path); - SerdNode node = serd_node_new_file_uri(abs_path, NULL, NULL, true); - SerdEnv* env = serd_env_new(&node); - SordModel* model = sord_new(world->world, SORD_SPO, false); - SerdReader* reader = sord_new_reader(model, env, SERD_TURTLE, NULL); + char* abs_path = lilv_path_absolute(path); + SerdNode* node = + serd_new_file_uri(SERD_MEASURE_STRING(abs_path), SERD_EMPTY_STRING()); + SerdEnv* env = serd_env_new(serd_node_string_view(node)); + SerdModel* model = serd_model_new(world->world, SERD_INDEX_SPO); + SerdSink* inserter = serd_inserter_new(model, NULL); + SerdReader* reader = serd_reader_new( + world->world, SERD_TURTLE, 0, env, inserter, LILV_READER_STACK_SIZE); - serd_reader_read_file(reader, node.buf); + SerdByteSource* source = serd_byte_source_new_filename(abs_path, 4096); + serd_reader_start(reader, source); + serd_reader_read_document(reader); + serd_reader_finish(reader); + serd_byte_source_free(source); - SordNode* subject_node = - (subject) ? subject->node - : sord_node_from_serd_node(world->world, env, &node, NULL, NULL); + const SerdNode* subject_node = subject ? subject : node; char* dirname = lilv_path_parent(path); char* real_path = lilv_path_canonical(dirname); @@ -763,10 +796,10 @@ lilv_state_new_from_file(LilvWorld* world, free(real_path); free(dirname); - serd_node_free(&node); + serd_node_free(node); free(abs_path); serd_reader_free(reader); - sord_free(model); + serd_model_free(model); serd_env_free(env); return state; } @@ -774,14 +807,16 @@ lilv_state_new_from_file(LilvWorld* world, static void set_prefixes(SerdEnv* env) { -#define SET_PSET(e, p, u) serd_env_set_prefix_from_strings(e, p, u) - SET_PSET(env, USTR("atom"), USTR(LV2_ATOM_PREFIX)); - SET_PSET(env, USTR("lv2"), USTR(LV2_CORE_PREFIX)); - SET_PSET(env, USTR("pset"), USTR(LV2_PRESETS_PREFIX)); - SET_PSET(env, USTR("rdf"), USTR(LILV_NS_RDF)); - SET_PSET(env, USTR("rdfs"), USTR(LILV_NS_RDFS)); - SET_PSET(env, USTR("state"), USTR(LV2_STATE_PREFIX)); - SET_PSET(env, USTR("xsd"), USTR(LILV_NS_XSD)); +#define SET_PSET(e, p, u) \ + serd_env_set_prefix(e, SERD_STATIC_STRING(p), SERD_STATIC_STRING(u)) + + SET_PSET(env, "atom", LV2_ATOM_PREFIX); + SET_PSET(env, "lv2", LV2_CORE_PREFIX); + SET_PSET(env, "pset", LV2_PRESETS_PREFIX); + SET_PSET(env, "rdf", LILV_NS_RDF); + SET_PSET(env, "rdfs", LILV_NS_RDFS); + SET_PSET(env, "state", LV2_STATE_PREFIX); + SET_PSET(env, "xsd", LILV_NS_XSD); } LilvState* @@ -791,47 +826,43 @@ lilv_state_new_from_string(LilvWorld* world, LV2_URID_Map* map, const char* str) return NULL; } - SerdNode base = SERD_NODE_NULL; - SerdEnv* env = serd_env_new(&base); - SordModel* model = sord_new(world->world, SORD_SPO | SORD_OPS, false); - SerdReader* reader = sord_new_reader(model, env, SERD_TURTLE, NULL); + SerdEnv* env = serd_env_new(SERD_EMPTY_STRING()); + SerdModel* model = + serd_model_new(world->world, SERD_INDEX_SPO | SERD_INDEX_OPS); + SerdSink* inserter = serd_inserter_new(model, NULL); + SerdReader* reader = serd_reader_new( + world->world, SERD_TURTLE, 0, env, inserter, LILV_READER_STACK_SIZE); + SerdByteSource* source = serd_byte_source_new_string(str, NULL); set_prefixes(env); - serd_reader_read_string(reader, USTR(str)); + serd_reader_start(reader, source); + serd_reader_read_document(reader); - SordNode* o = sord_new_uri(world->world, USTR(LV2_PRESETS__Preset)); - SordNode* s = sord_get(model, NULL, world->uris.rdf_a, o, NULL); + SerdNode* o = serd_new_uri(SERD_STATIC_STRING(LV2_PRESETS__Preset)); + const SerdNode* s = serd_model_get(model, NULL, world->uris.rdf_a, o, NULL); LilvState* state = new_state_from_model(world, map, model, s, NULL); - sord_node_free(world->world, s); - sord_node_free(world->world, o); + serd_node_free(o); + serd_byte_source_free(source); serd_reader_free(reader); - sord_free(model); + serd_model_free(model); serd_env_free(env); return state; } static SerdWriter* -ttl_writer(SerdSink sink, void* stream, const SerdNode* base, SerdEnv** new_env) +ttl_writer(SerdWorld* world, + SerdByteSink* const sink, + const SerdNode* base, + SerdEnv** new_env) { - SerdURI base_uri = SERD_URI_NULL; - if (base && base->buf) { - serd_uri_parse(base->buf, &base_uri); - } - - SerdEnv* env = *new_env ? *new_env : serd_env_new(base); + SerdEnv* env = + *new_env ? *new_env : serd_env_new(serd_node_string_view(base)); set_prefixes(env); - SerdWriter* writer = - serd_writer_new(SERD_TURTLE, - (SerdStyle)(SERD_STYLE_RESOLVED | SERD_STYLE_ABBREVIATED | - SERD_STYLE_CURIED), - env, - &base_uri, - sink, - stream); + SerdWriter* writer = serd_writer_new(world, SERD_TURTLE, 0, env, sink); if (!*new_env) { *new_env = env; @@ -841,13 +872,16 @@ ttl_writer(SerdSink sink, void* stream, const SerdNode* base, SerdEnv** new_env) } static SerdWriter* -ttl_file_writer(FILE* fd, const SerdNode* node, SerdEnv** env) +ttl_file_writer(SerdWorld* world, FILE* fd, const SerdNode* node, SerdEnv** env) { - SerdWriter* writer = ttl_writer(serd_file_sink, fd, node, env); + SerdByteSink* const sink = + serd_byte_sink_new_function((SerdWriteFunc)fwrite, fd, 1); + + SerdWriter* const writer = ttl_writer(world, sink, node, env); fseek(fd, 0, SEEK_END); if (ftell(fd) == 0) { - serd_env_foreach(*env, (SerdPrefixSink)serd_writer_set_prefix, writer); + serd_env_write_prefixes(*env, serd_writer_sink(writer)); } else { fprintf(fd, "\n"); } @@ -856,47 +890,27 @@ ttl_file_writer(FILE* fd, const SerdNode* node, SerdEnv** env) } static void -add_to_model(SordWorld* world, - SerdEnv* env, - SordModel* model, - const SerdNode s, - const SerdNode p, - const SerdNode o) +remove_manifest_entry(SerdModel* model, const char* subject) { - SordNode* ss = sord_node_from_serd_node(world, env, &s, NULL, NULL); - SordNode* sp = sord_node_from_serd_node(world, env, &p, NULL, NULL); - SordNode* so = sord_node_from_serd_node(world, env, &o, NULL, NULL); + SerdNode* const s = serd_new_uri(SERD_MEASURE_STRING(subject)); + SerdRange* const r = serd_model_range(model, s, NULL, NULL, NULL); - SordQuad quad = {ss, sp, so, NULL}; - sord_add(model, quad); - - sord_node_free(world, ss); - sord_node_free(world, sp); - sord_node_free(world, so); -} + serd_model_erase_range(model, r); -static void -remove_manifest_entry(SordWorld* world, SordModel* model, const char* subject) -{ - SordNode* s = sord_new_uri(world, USTR(subject)); - SordIter* i = sord_search(model, s, NULL, NULL, NULL); - while (!sord_iter_end(i)) { - sord_erase(model, i); - } - sord_iter_free(i); - sord_node_free(world, s); + serd_range_free(r); + serd_node_free(s); } static int write_manifest(LilvWorld* world, SerdEnv* env, - SordModel* model, + SerdModel* model, const SerdNode* file_uri) { - (void)world; + const char* file_uri_str = serd_node_string(file_uri); + char* const path = serd_parse_file_uri(file_uri_str, NULL); + FILE* const wfd = fopen(path, "w"); - char* const path = (char*)serd_file_uri_parse(file_uri->buf, NULL); - FILE* const wfd = fopen(path, "w"); if (!wfd) { LILV_ERRORF("Failed to open %s for writing (%s)\n", path, strerror(errno)); @@ -904,8 +918,10 @@ write_manifest(LilvWorld* world, return 1; } - SerdWriter* writer = ttl_file_writer(wfd, file_uri, &env); - sord_write(model, writer, NULL); + SerdWriter* writer = ttl_file_writer(world->world, wfd, file_uri, &env); + SerdRange* all = serd_model_all(model, SERD_ORDER_SPO); + serd_range_serialise(all, serd_writer_sink(writer), 0); + serd_range_free(all); serd_writer_free(writer); fclose(wfd); serd_free(path); @@ -919,90 +935,73 @@ add_state_to_manifest(LilvWorld* lworld, const char* state_uri, const char* state_path) { - SordWorld* world = lworld->world; - SerdNode manifest = serd_node_new_file_uri(USTR(manifest_path), 0, 0, 1); - SerdNode file = serd_node_new_file_uri(USTR(state_path), 0, 0, 1); - SerdEnv* env = serd_env_new(&manifest); - SordModel* model = sord_new(world, SORD_SPO, false); + static const SerdStringView empty = {"", 0}; + + const SerdStringView manifest_path_view = SERD_MEASURE_STRING(manifest_path); + const SerdStringView state_path_view = SERD_MEASURE_STRING(state_path); + + SerdWorld* world = lworld->world; + SerdNode* manifest = serd_new_file_uri(manifest_path_view, empty); + SerdNode* file = serd_new_file_uri(state_path_view, empty); + SerdEnv* env = serd_env_new(serd_node_string_view(manifest)); + SerdModel* model = serd_model_new(world, SERD_INDEX_SPO | SERD_INDEX_OPS); + SerdSink* inserter = serd_inserter_new(model, NULL); - if (lilv_path_exists(manifest_path)) { + FILE* const rfd = fopen(manifest_path, "r"); + if (rfd) { // Read manifest into model - SerdReader* reader = sord_new_reader(model, env, SERD_TURTLE, NULL); - SerdStatus st = serd_reader_read_file(reader, manifest.buf); - if (st) { + SerdReader* reader = serd_reader_new( + world, SERD_TURTLE, 0, env, inserter, LILV_READER_STACK_SIZE); + + SerdByteSource* source = + serd_byte_source_new_function((SerdReadFunc)fread, + (SerdStreamErrorFunc)ferror, + rfd, + manifest, + PAGE_SIZE); + + SerdStatus st = SERD_SUCCESS; + if ((st = serd_reader_start(reader, source)) || + (st = serd_reader_read_document(reader))) { LILV_WARNF("Failed to read manifest (%s)\n", serd_strerror(st)); + return st; } + + serd_byte_source_free(source); serd_reader_free(reader); + fclose(rfd); } // Choose state URI (use file URI if not given) if (!state_uri) { - state_uri = (const char*)file.buf; + state_uri = serd_node_string(file); } // Remove any existing manifest entries for this state - remove_manifest_entry(world, model, state_uri); + remove_manifest_entry(model, state_uri); // Add manifest entry for this state to model - SerdNode s = serd_node_from_string(SERD_URI, USTR(state_uri)); - - // <state> a pset:Preset - add_to_model(world, - env, - model, - s, - serd_node_from_string(SERD_URI, USTR(LILV_NS_RDF "type")), - serd_node_from_string(SERD_URI, USTR(LV2_PRESETS__Preset))); + SerdNode* s = serd_new_uri(SERD_MEASURE_STRING(state_uri)); // <state> a pset:Preset - add_to_model(world, - env, - model, - s, - serd_node_from_string(SERD_URI, USTR(LILV_NS_RDF "type")), - serd_node_from_string(SERD_URI, USTR(LV2_PRESETS__Preset))); + serd_model_add(model, s, lworld->uris.rdf_a, lworld->uris.pset_Preset, NULL); // <state> rdfs:seeAlso <file> - add_to_model(world, - env, - model, - s, - serd_node_from_string(SERD_URI, USTR(LILV_NS_RDFS "seeAlso")), - file); + serd_model_add(model, s, lworld->uris.rdfs_seeAlso, file, NULL); // <state> lv2:appliesTo <plugin> - add_to_model( - world, - env, - model, - s, - serd_node_from_string(SERD_URI, USTR(LV2_CORE__appliesTo)), - serd_node_from_string(SERD_URI, USTR(lilv_node_as_string(plugin_uri)))); - - /* Re-open manifest for locked writing. We need to do this because it may - need to be truncated, and the file can only be open once on Windows. */ - - FILE* wfd = fopen(manifest_path, "wb"); - int r = 0; - if (!wfd) { - LILV_ERRORF( - "Failed to open %s for writing (%s)\n", manifest_path, strerror(errno)); - r = 1; - } + serd_model_add(model, s, lworld->uris.lv2_appliesTo, plugin_uri, NULL); - SerdWriter* writer = ttl_file_writer(wfd, &manifest, &env); - lilv_flock(wfd, true, true); - sord_write(model, writer, NULL); - lilv_flock(wfd, false, true); - serd_writer_free(writer); - fclose(wfd); + // Write manifest model to file + write_manifest(lworld, env, model, manifest); - sord_free(model); - serd_node_free(&file); - serd_node_free(&manifest); + serd_node_free(s); + serd_model_free(model); + serd_node_free(file); + serd_node_free(manifest); serd_env_free(env); - return r; + return 0; } static bool @@ -1037,138 +1036,148 @@ maybe_symlink(const char* oldpath, const char* newpath) static void write_property_array(const LilvState* state, const PropertyArray* array, - Sratom* sratom, - uint32_t flags, + const SerdEnv* env, + SratomDumper* dumper, + const SerdSink* sink, const SerdNode* subject, LV2_URID_Unmap* unmap, const char* dir) { + // FIXME: error handling for (uint32_t i = 0; i < array->n; ++i) { Property* prop = &array->props[i]; const char* key = unmap->unmap(unmap->handle, prop->key); - const SerdNode p = serd_node_from_string(SERD_URI, USTR(key)); + SerdNode* p = serd_new_uri(SERD_MEASURE_STRING(key)); if (prop->type == state->atom_Path && !dir) { const char* path = (const char*)prop->value; const char* abs_path = lilv_state_rel2abs(state, path); LILV_WARNF("Writing absolute path %s\n", abs_path); - sratom_write(sratom, - unmap, - flags, - subject, - &p, - prop->type, - strlen(abs_path) + 1, - abs_path); + sratom_dump(dumper, + env, + sink, + subject, + p, + prop->type, + strlen(abs_path) + 1, + abs_path, + 0); } else if (prop->flags & LV2_STATE_IS_POD || prop->type == state->atom_Path) { - sratom_write( - sratom, unmap, flags, subject, &p, prop->type, prop->size, prop->value); + sratom_dump( + dumper, env, sink, subject, p, prop->type, prop->size, prop->value, 0); } else { LILV_WARNF("Lost non-POD property <%s> on save\n", key); } + serd_node_free(p); } } -static int +static SerdStatus lilv_state_write(LilvWorld* world, LV2_URID_Map* map, LV2_URID_Unmap* unmap, const LilvState* state, + const SerdEnv* env, SerdWriter* writer, const char* uri, const char* dir) { - (void)world; + const SerdSink* sink = serd_writer_sink(writer); + const SerdNode* plugin_uri = state->plugin_uri; + SerdNode* subject = + serd_new_uri(uri ? SERD_MEASURE_STRING(uri) : SERD_EMPTY_STRING()); - SerdNode lv2_appliesTo = - serd_node_from_string(SERD_CURIE, USTR("lv2:appliesTo")); - - const SerdNode* plugin_uri = sord_node_to_serd_node(state->plugin_uri->node); - - SerdNode subject = serd_node_from_string(SERD_URI, USTR(uri ? uri : "")); + SerdStatus st = SERD_SUCCESS; // <subject> a pset:Preset - SerdNode p = serd_node_from_string(SERD_URI, USTR(LILV_NS_RDF "type")); - SerdNode o = serd_node_from_string(SERD_URI, USTR(LV2_PRESETS__Preset)); - serd_writer_write_statement(writer, 0, NULL, &subject, &p, &o, NULL, NULL); + if ((st = serd_sink_write( + sink, 0, subject, world->uris.rdf_a, world->uris.pset_Preset, NULL))) { + return st; + } // <subject> lv2:appliesTo <http://example.org/plugin> - serd_writer_write_statement( - writer, 0, NULL, &subject, &lv2_appliesTo, plugin_uri, NULL, NULL); + if ((st = serd_sink_write( + sink, 0, subject, world->uris.lv2_appliesTo, plugin_uri, NULL))) { + return st; + } // <subject> rdfs:label label if (state->label) { - p = serd_node_from_string(SERD_URI, USTR(LILV_NS_RDFS "label")); - o = serd_node_from_string(SERD_LITERAL, USTR(state->label)); - serd_writer_write_statement(writer, 0, NULL, &subject, &p, &o, NULL, NULL); - } + SerdNode* label = serd_new_string(SERD_MEASURE_STRING(state->label)); + if ((st = serd_sink_write( + sink, 0, subject, world->uris.rdfs_label, label, NULL))) { + return st; + } - SerdEnv* env = serd_writer_get_env(writer); - const SerdNode* base = serd_env_get_base_uri(env, NULL); + serd_node_free(label); + } - Sratom* sratom = sratom_new(map); - sratom_set_sink(sratom, - (const char*)base->buf, - (SerdStatementSink)serd_writer_write_statement, - (SerdEndSink)serd_writer_end_anon, - writer); + SratomDumper* dumper = sratom_dumper_new(world->world, map, unmap); - // Write metadata - sratom_set_pretty_numbers(sratom, false); // Use precise types + // Write metadata (with precise types) write_property_array( - state, &state->metadata, sratom, 0, &subject, unmap, dir); + state, &state->metadata, env, dumper, sink, subject, unmap, dir); - // Write port values - sratom_set_pretty_numbers(sratom, true); // Use pretty numbers + // Write port values (with pretty numbers) for (uint32_t i = 0; i < state->n_values; ++i) { PortValue* const value = &state->values[i]; - - const SerdNode port = - serd_node_from_string(SERD_BLANK, USTR(value->symbol)); + SerdNode* port = serd_new_blank(SERD_MEASURE_STRING(value->symbol)); // <> lv2:port _:symbol - p = serd_node_from_string(SERD_URI, USTR(LV2_CORE__port)); - serd_writer_write_statement( - writer, SERD_ANON_O_BEGIN, NULL, &subject, &p, &port, NULL, NULL); + if ((st = serd_sink_write( + sink, SERD_ANON_O, subject, world->uris.lv2_port, port, NULL))) { + return st; + } // _:symbol lv2:symbol "symbol" - p = serd_node_from_string(SERD_URI, USTR(LV2_CORE__symbol)); - o = serd_node_from_string(SERD_LITERAL, USTR(value->symbol)); - serd_writer_write_statement( - writer, SERD_ANON_CONT, NULL, &port, &p, &o, NULL, NULL); + SerdNode* symbol = serd_new_string(SERD_MEASURE_STRING(value->symbol)); + if ((st = serd_sink_write( + sink, 0, port, world->uris.lv2_symbol, symbol, NULL))) { + return st; + } - // _:symbol pset:value value - p = serd_node_from_string(SERD_URI, USTR(LV2_PRESETS__value)); - sratom_write(sratom, - unmap, - SERD_ANON_CONT, - &port, - &p, - value->atom->type, - value->atom->size, - value->atom + 1); + serd_node_free(symbol); - serd_writer_end_anon(writer, &port); + // _:symbol pset:value value + // FIXME: error handling + sratom_dump_atom(dumper, + env, + sink, + port, + world->uris.pset_value, + value->atom, + 0); // SRATOM_PRETTY_NUMBERS); + + if ((st = serd_sink_write_end(sink, port))) { + return st; + } } - // Write properties - const SerdNode body = serd_node_from_string(SERD_BLANK, USTR("body")); + // <> state:state _:body + + SerdNode* body = serd_new_blank(SERD_STATIC_STRING("body")); if (state->props.n > 0) { - p = serd_node_from_string(SERD_URI, USTR(LV2_STATE__state)); - serd_writer_write_statement( - writer, SERD_ANON_O_BEGIN, NULL, &subject, &p, &body, NULL, NULL); + if ((st = serd_sink_write( + sink, SERD_ANON_O, subject, world->uris.state_state, body, NULL))) { + return st; + } } - sratom_set_pretty_numbers(sratom, false); // Use precise types + + // _:body key value ... write_property_array( - state, &state->props, sratom, SERD_ANON_CONT, &body, unmap, dir); + state, &state->props, env, dumper, sink, body, unmap, dir); + // End state body if (state->props.n > 0) { - serd_writer_end_anon(writer, &body); + if ((st = serd_sink_write_end(sink, body))) { + return st; + } } - sratom_free(sratom); - return 0; + serd_node_free(body); + sratom_dumper_free(dumper); + return SERD_SUCCESS; } static void @@ -1229,7 +1238,7 @@ lilv_state_save(LilvWorld* world, return 1; } - char* abs_dir = real_dir(dir); + char* abs_dir = lilv_path_canonical(dir); char* const path = lilv_path_join(abs_dir, filename); FILE* fd = fopen(path, "w"); if (!fd) { @@ -1243,36 +1252,34 @@ lilv_state_save(LilvWorld* world, lilv_state_make_links(state, abs_dir); // Write state to Turtle file - SerdNode file = serd_node_new_file_uri(USTR(path), NULL, NULL, true); - SerdNode node = uri ? serd_node_from_string(SERD_URI, USTR(uri)) : file; - SerdEnv* env = NULL; - SerdWriter* ttl = ttl_file_writer(fd, &file, &env); - int ret = - lilv_state_write(world, map, unmap, state, ttl, (const char*)node.buf, dir); + SerdNode* file = + serd_new_file_uri(SERD_MEASURE_STRING(path), SERD_EMPTY_STRING()); + SerdNode* node = + uri ? serd_new_uri(SERD_MEASURE_STRING(uri)) : serd_node_copy(file); + SerdEnv* env = NULL; + SerdWriter* ttl = ttl_file_writer(world->world, fd, file, &env); + SerdStatus st = lilv_state_write( + world, map, unmap, state, env, ttl, serd_node_string(node), dir); // Set saved dir and uri (FIXME: const violation) free(state->dir); lilv_node_free(state->uri); - ((LilvState*)state)->dir = lilv_strdup(abs_dir); - ((LilvState*)state)->uri = lilv_new_uri(world, (const char*)node.buf); + ((LilvState*)state)->dir = lilv_path_join(abs_dir, NULL); + ((LilvState*)state)->uri = node; - serd_node_free(&file); + serd_node_free(file); serd_writer_free(ttl); serd_env_free(env); fclose(fd); // Add entry to manifest - if (!ret) { - char* const manifest = lilv_path_join(abs_dir, "manifest.ttl"); - - ret = add_state_to_manifest(world, state->plugin_uri, manifest, uri, path); - - free(manifest); - } + char* const manifest = lilv_path_join(abs_dir, "manifest.ttl"); + add_state_to_manifest(world, state->plugin_uri, manifest, uri, path); + free(manifest); free(abs_dir); free(path); - return ret; + return st; } char* @@ -1288,16 +1295,18 @@ lilv_state_to_string(LilvWorld* world, return NULL; } - SerdChunk chunk = {NULL, 0}; - SerdEnv* env = NULL; - SerdNode base = serd_node_from_string(SERD_URI, USTR(base_uri)); - SerdWriter* writer = ttl_writer(serd_chunk_sink, &chunk, &base, &env); + SerdBuffer buffer = {NULL, 0}; + SerdEnv* env = NULL; + SerdNode* base = serd_new_uri(SERD_MEASURE_STRING(base_uri)); + SerdByteSink* sink = serd_byte_sink_new_buffer(&buffer); + SerdWriter* writer = ttl_writer(world->world, sink, base, &env); - lilv_state_write(world, map, unmap, state, writer, uri, NULL); + lilv_state_write(world, map, unmap, state, env, writer, uri, NULL); serd_writer_free(writer); + serd_byte_sink_free(sink); serd_env_free(env); - char* str = (char*)serd_chunk_sink_finish(&chunk); + char* str = serd_buffer_sink_finish(&buffer); char* result = lilv_strdup(str); serd_free(str); return result; @@ -1332,45 +1341,54 @@ lilv_state_delete(LilvWorld* world, const LilvState* state) } LilvNode* bundle = lilv_new_file_uri(world, NULL, state->dir); - LilvNode* manifest = lilv_world_get_manifest_uri(world, bundle); + LilvNode* manifest = lilv_world_get_manifest_node(world, bundle); char* manifest_path = get_canonical_path(manifest); const bool has_manifest = lilv_path_exists(manifest_path); - SordModel* model = sord_new(world->world, SORD_SPO, false); + SerdModel* model = serd_model_new(world->world, SERD_INDEX_SPO); if (has_manifest) { // Read manifest into temporary local model - SerdEnv* env = serd_env_new(sord_node_to_serd_node(manifest->node)); - SerdReader* ttl = sord_new_reader(model, env, SERD_TURTLE, NULL); - serd_reader_read_file(ttl, USTR(manifest_path)); - serd_reader_free(ttl); + SerdEnv* env = serd_env_new(serd_node_string_view(manifest)); + SerdSink* inserter = serd_inserter_new(model, NULL); + SerdReader* reader = serd_reader_new( + world->world, SERD_TURTLE, 0, env, inserter, LILV_READER_STACK_SIZE); + + SerdByteSource* source = + serd_byte_source_new_filename(manifest_path, PAGE_SIZE); + + serd_reader_start(reader, source); + serd_reader_read_document(reader); + serd_byte_source_free(source); + serd_reader_free(reader); serd_env_free(env); } if (state->uri) { - SordNode* file = - sord_get(model, state->uri->node, world->uris.rdfs_seeAlso, NULL, NULL); + const SerdNode* file = + serd_model_get(model, state->uri, world->uris.rdfs_seeAlso, NULL, NULL); if (file) { + char* const path = serd_parse_file_uri(serd_node_string(file), NULL); + char* const real_path = lilv_path_canonical(path); + // Remove state file - const uint8_t* uri = sord_node_get_string(file); - char* path = (char*)serd_file_uri_parse(uri, NULL); - char* real_path = lilv_path_canonical(path); - if (path) { + if (real_path) { try_unlink(state->dir, real_path); } + serd_free(real_path); serd_free(path); } // Remove any existing manifest entries for this state const char* state_uri_str = lilv_node_as_string(state->uri); - remove_manifest_entry(world->world, model, state_uri_str); - remove_manifest_entry(world->world, world->model, state_uri_str); + remove_manifest_entry(model, state_uri_str); + remove_manifest_entry(world->model, state_uri_str); } // Drop bundle from model lilv_world_unload_bundle(world, bundle); - if (sord_num_quads(model) == 0) { + if (serd_model_size(model) == 0) { // Manifest is empty, attempt to remove bundle entirely if (has_manifest) { try_unlink(state->dir, manifest_path); @@ -1403,15 +1421,17 @@ lilv_state_delete(LilvWorld* world, const LilvState* state) } } else { // Still something in the manifest, update and reload bundle - const SerdNode* manifest_node = sord_node_to_serd_node(manifest->node); - SerdEnv* env = serd_env_new(manifest_node); + SerdEnv* env = serd_env_new(serd_node_string_view(manifest)); + + if (write_manifest(world, env, model, manifest)) { + return 1; + } - write_manifest(world, env, model, manifest_node); lilv_world_load_bundle(world, bundle); serd_env_free(env); } - sord_free(model); + serd_model_free(model); lilv_free(manifest_path); lilv_node_free(manifest); lilv_node_free(bundle); @@ -27,8 +27,6 @@ #include <errno.h> #include <stdarg.h> #include <stdbool.h> -#include <stddef.h> -#include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -87,12 +85,6 @@ lilv_strdup(const char* str) return copy; } -char* -lilv_file_uri_parse(const char* uri, char** hostname) -{ - return (char*)serd_file_uri_parse((const uint8_t*)uri, (uint8_t**)hostname); -} - /** Return the current LANG converted to Turtle (i.e. RFC3066) style. * For example, if LANG is set to "en_CA.utf-8", this returns "en-ca". */ diff --git a/src/world.c b/src/world.c index 47dc147..31fa906 100644 --- a/src/world.c +++ b/src/world.c @@ -19,14 +19,13 @@ #include "lilv_internal.h" #include "lilv/lilv.h" +#include "lv2/core/lv2.h" +#include "lv2/presets/presets.h" +#include "lv2/state/state.h" #include "serd/serd.h" -#include "sord/sord.h" #include "zix/common.h" #include "zix/tree.h" -#include "lv2/core/lv2.h" -#include "lv2/presets/presets.h" - #ifdef LILV_DYN_MANIFEST # include "lv2/dynmanifest/dynmanifest.h" # include <dlfcn.h> @@ -34,25 +33,25 @@ #include <assert.h> #include <stdbool.h> -#include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> static int -lilv_world_drop_graph(LilvWorld* world, const SordNode* graph); +lilv_world_drop_graph(LilvWorld* world, const SerdNode* graph); LilvWorld* lilv_world_new(void) { LilvWorld* world = (LilvWorld*)calloc(1, sizeof(LilvWorld)); - world->world = sord_world_new(); + world->world = serd_world_new(); if (!world->world) { goto fail; } - world->model = sord_new(world->world, SORD_SPO | SORD_OPS, true); + world->model = serd_model_new( + world->world, SERD_INDEX_SPO | SERD_INDEX_OPS | SERD_INDEX_GRAPHS); if (!world->model) { goto fail; } @@ -70,7 +69,7 @@ lilv_world_new(void) #define NS_DYNMAN "http://lv2plug.in/ns/ext/dynmanifest#" #define NS_OWL "http://www.w3.org/2002/07/owl#" -#define NEW_URI(uri) sord_new_uri(world->world, (const uint8_t*)(uri)) +#define NEW_URI(uri) serd_new_uri(SERD_STATIC_STRING(uri)) world->uris.dc_replaces = NEW_URI(NS_DCTERMS "replaces"); world->uris.dman_DynManifest = NEW_URI(NS_DYNMAN "DynManifest"); @@ -94,9 +93,11 @@ lilv_world_new(void) world->uris.lv2_portProperty = NEW_URI(LV2_CORE__portProperty); world->uris.lv2_reportsLatency = NEW_URI(LV2_CORE__reportsLatency); world->uris.lv2_requiredFeature = NEW_URI(LV2_CORE__requiredFeature); - world->uris.lv2_symbol = NEW_URI(LV2_CORE__symbol); + world->uris.lv2_project = NEW_URI(LV2_CORE__project); world->uris.lv2_prototype = NEW_URI(LV2_CORE__prototype); + world->uris.lv2_symbol = NEW_URI(LV2_CORE__symbol); world->uris.owl_Ontology = NEW_URI(NS_OWL "Ontology"); + world->uris.pset_Preset = NEW_URI(LV2_PRESETS__Preset); world->uris.pset_value = NEW_URI(LV2_PRESETS__value); world->uris.rdf_a = NEW_URI(LILV_NS_RDF "type"); world->uris.rdf_value = NEW_URI(LILV_NS_RDF "value"); @@ -104,10 +105,12 @@ lilv_world_new(void) world->uris.rdfs_label = NEW_URI(LILV_NS_RDFS "label"); world->uris.rdfs_seeAlso = NEW_URI(LILV_NS_RDFS "seeAlso"); world->uris.rdfs_subClassOf = NEW_URI(LILV_NS_RDFS "subClassOf"); + world->uris.state_state = NEW_URI(LV2_STATE__state); world->uris.xsd_base64Binary = NEW_URI(LILV_NS_XSD "base64Binary"); world->uris.xsd_boolean = NEW_URI(LILV_NS_XSD "boolean"); world->uris.xsd_decimal = NEW_URI(LILV_NS_XSD "decimal"); world->uris.xsd_double = NEW_URI(LILV_NS_XSD "double"); + world->uris.xsd_int = NEW_URI(LILV_NS_XSD "int"); world->uris.xsd_integer = NEW_URI(LILV_NS_XSD "integer"); world->uris.null_uri = NULL; @@ -136,14 +139,14 @@ lilv_world_free(LilvWorld* world) lilv_plugin_class_free(world->lv2_plugin_class); world->lv2_plugin_class = NULL; - for (SordNode** n = (SordNode**)&world->uris; *n; ++n) { - sord_node_free(world->world, *n); + for (SerdNode** n = (SerdNode**)&world->uris; *n; ++n) { + serd_node_free(*n); } for (LilvSpec* spec = world->specs; spec;) { LilvSpec* next = spec->next; - sord_node_free(world->world, spec->spec); - sord_node_free(world->world, spec->bundle); + serd_node_free(spec->spec); + serd_node_free(spec->bundle); lilv_nodes_free(spec->data_uris); free(spec); spec = next; @@ -173,10 +176,10 @@ lilv_world_free(LilvWorld* world) zix_tree_free((ZixTree*)world->plugin_classes); world->plugin_classes = NULL; - sord_free(world->model); + serd_model_free(world->model); world->model = NULL; - sord_world_free(world->world); + serd_world_free(world->world); world->world = NULL; free(world->opt.lv2_path); @@ -212,31 +215,20 @@ 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", - sord_node_get_string(subject->node)); + LILV_ERRORF("Subject `%s' is not a resource\n", serd_node_string(subject)); return NULL; - } - - if (!predicate) { + } else if (!predicate) { LILV_ERROR("Missing required predicate\n"); return NULL; - } - - if (!lilv_node_is_uri(predicate)) { - LILV_ERRORF("Predicate `%s' is not a URI\n", - sord_node_get_string(predicate->node)); + } else if (!lilv_node_is_uri(predicate)) { + LILV_ERRORF("Predicate `%s' is not a URI\n", serd_node_string(predicate)); return NULL; - } - - if (!subject && !object) { + } else if (!subject && !object) { LILV_ERROR("Both subject and object are NULL\n"); return NULL; } - return lilv_world_find_nodes_internal(world, - subject ? subject->node : NULL, - predicate->node, - object ? object->node : NULL); + return lilv_world_find_nodes_internal(world, subject, predicate, object); } LilvNode* @@ -245,52 +237,8 @@ lilv_world_get(LilvWorld* world, const LilvNode* predicate, const LilvNode* object) { - if (!object) { - // TODO: Improve performance (see lilv_plugin_get_one) - SordIter* stream = sord_search(world->model, - subject ? subject->node : NULL, - predicate ? predicate->node : NULL, - NULL, - NULL); - - LilvNodes* nodes = - lilv_nodes_from_stream_objects(world, stream, SORD_OBJECT); - - if (nodes) { - LilvNode* value = lilv_node_duplicate(lilv_nodes_get_first(nodes)); - lilv_nodes_free(nodes); - return value; - } - - return NULL; - } - - SordNode* snode = sord_get(world->model, - subject ? subject->node : NULL, - predicate ? predicate->node : NULL, - object ? object->node : NULL, - NULL); - LilvNode* lnode = lilv_node_new_from_node(world, snode); - sord_node_free(world->world, snode); - return lnode; -} - -SordIter* -lilv_world_query_internal(LilvWorld* world, - const SordNode* subject, - const SordNode* predicate, - const SordNode* object) -{ - return sord_search(world->model, subject, predicate, object, NULL); -} - -bool -lilv_world_ask_internal(LilvWorld* world, - const SordNode* subject, - const SordNode* predicate, - const SordNode* object) -{ - return sord_ask(world->model, subject, predicate, object, NULL); + return serd_node_copy( + serd_model_get(world->model, subject, predicate, object, NULL)); } bool @@ -299,59 +247,44 @@ lilv_world_ask(LilvWorld* world, const LilvNode* predicate, const LilvNode* object) { - return sord_ask(world->model, - subject ? subject->node : NULL, - predicate ? predicate->node : NULL, - object ? object->node : NULL, - NULL); + return serd_model_ask(world->model, subject, predicate, object, NULL); } -SordModel* +SerdModel* lilv_world_filter_model(LilvWorld* world, - SordModel* model, - const SordNode* subject, - const SordNode* predicate, - const SordNode* object, - const SordNode* graph) + SerdModel* model, + const SerdNode* subject, + const SerdNode* predicate, + const SerdNode* object, + const SerdNode* graph) { - SordModel* results = sord_new(world->world, SORD_SPO, false); - SordIter* i = sord_search(model, subject, predicate, object, graph); - for (; !sord_iter_end(i); sord_iter_next(i)) { - SordQuad quad; - sord_iter_get(i, quad); - sord_add(results, quad); + SerdModel* results = serd_model_new(world->world, SERD_INDEX_SPO); + SerdRange* r = serd_model_range(model, subject, predicate, object, graph); + for (; !serd_range_empty(r); serd_range_next(r)) { + serd_model_insert(results, serd_range_front(r)); } - sord_iter_free(i); + serd_range_free(r); return results; } LilvNodes* lilv_world_find_nodes_internal(LilvWorld* world, - const SordNode* subject, - const SordNode* predicate, - const SordNode* object) + const SerdNode* subject, + const SerdNode* predicate, + const SerdNode* object) { - return lilv_nodes_from_stream_objects( + return lilv_nodes_from_range( world, - lilv_world_query_internal(world, subject, predicate, object), - (object == NULL) ? SORD_OBJECT : SORD_SUBJECT); -} - -static SerdNode -lilv_new_uri_relative_to_base(const uint8_t* uri_str, - const uint8_t* base_uri_str) -{ - SerdURI base_uri; - serd_uri_parse(base_uri_str, &base_uri); - return serd_node_new_uri_from_string(uri_str, &base_uri, NULL); + serd_model_range(world->model, subject, predicate, object, NULL), + (object == NULL) ? SERD_OBJECT : SERD_SUBJECT); } -const uint8_t* +const char* lilv_world_blank_node_prefix(LilvWorld* world) { static char str[32]; snprintf(str, sizeof(str), "%u", world->n_read_files++); - return (const uint8_t*)str; + return str; } /** Comparator for sequences (e.g. world->plugins). */ @@ -411,24 +344,21 @@ lilv_collection_get_by_uri(const ZixTree* seq, const LilvNode* uri) static void lilv_world_add_spec(LilvWorld* world, - const SordNode* specification_node, - const SordNode* bundle_node) + const SerdNode* specification_node, + const SerdNode* bundle_node) { LilvSpec* spec = (LilvSpec*)malloc(sizeof(LilvSpec)); - spec->spec = sord_node_copy(specification_node); - spec->bundle = sord_node_copy(bundle_node); + spec->spec = serd_node_copy(specification_node); + spec->bundle = serd_node_copy(bundle_node); spec->data_uris = lilv_nodes_new(); // Add all data files (rdfs:seeAlso) - SordIter* files = sord_search( - world->model, specification_node, world->uris.rdfs_seeAlso, NULL, NULL); - FOREACH_MATCH (files) { - const SordNode* file_node = sord_iter_get_node(files, SORD_OBJECT); - zix_tree_insert((ZixTree*)spec->data_uris, - lilv_node_new_from_node(world, file_node), - NULL); + FOREACH_PAT( + s, world->model, specification_node, world->uris.rdfs_seeAlso, NULL, NULL) + { + const SerdNode* file_node = serd_statement_object(s); + zix_tree_insert((ZixTree*)spec->data_uris, serd_node_copy(file_node), NULL); } - sord_iter_free(files); // Add specification to world specification list spec->next = world->specs; @@ -437,15 +367,12 @@ lilv_world_add_spec(LilvWorld* world, static void lilv_world_add_plugin(LilvWorld* world, - const SordNode* plugin_node, + const SerdNode* plugin_uri, const LilvNode* manifest_uri, void* dynmanifest, - const SordNode* bundle) + const SerdNode* bundle) { - (void)dynmanifest; - - LilvNode* plugin_uri = lilv_node_new_from_node(world, plugin_node); - ZixTreeIter* z = NULL; + ZixTreeIter* z = NULL; LilvPlugin* plugin = (LilvPlugin*)lilv_plugins_get_by_uri(world->plugins, plugin_uri); @@ -454,15 +381,13 @@ lilv_world_add_plugin(LilvWorld* world, // (use the first plugin found in LV2_PATH) const LilvNode* last_bundle = lilv_plugin_get_bundle_uri(plugin); const char* plugin_uri_str = lilv_node_as_uri(plugin_uri); - if (sord_node_equals(bundle, last_bundle->node)) { + if (serd_node_equals(bundle, last_bundle)) { LILV_WARNF("Reloading plugin <%s>\n", plugin_uri_str); plugin->loaded = false; - lilv_node_free(plugin_uri); } else { LILV_WARNF("Duplicate plugin <%s>\n", plugin_uri_str); LILV_WARNF("... found in %s\n", lilv_node_as_string(last_bundle)); - LILV_WARNF("... and %s (ignored)\n", sord_node_get_string(bundle)); - lilv_node_free(plugin_uri); + LILV_WARNF("... and %s (ignored)\n", serd_node_string(bundle)); return; } } else if ((z = lilv_collection_find_by_uri((const ZixTree*)world->zombies, @@ -471,12 +396,10 @@ lilv_world_add_plugin(LilvWorld* world, plugin = (LilvPlugin*)zix_tree_get(z); zix_tree_remove((ZixTree*)world->zombies, z); zix_tree_insert((ZixTree*)world->plugins, plugin, NULL); - lilv_node_free(plugin_uri); - lilv_plugin_clear(plugin, lilv_node_new_from_node(world, bundle)); + lilv_plugin_clear(plugin, bundle); } else { // Add new plugin to the world - plugin = lilv_plugin_new( - world, plugin_uri, lilv_node_new_from_node(world, bundle)); + plugin = lilv_plugin_new(world, plugin_uri, bundle); // Add manifest as plugin data file (as if it were rdfs:seeAlso) zix_tree_insert( @@ -492,37 +415,40 @@ lilv_world_add_plugin(LilvWorld* world, plugin->dynmanifest = (LilvDynManifest*)dynmanifest; ++((LilvDynManifest*)dynmanifest)->refs; } +#else + (void)dynmanifest; #endif // Add all plugin data files (rdfs:seeAlso) - SordIter* files = sord_search( - world->model, plugin_node, world->uris.rdfs_seeAlso, NULL, NULL); - FOREACH_MATCH (files) { - const SordNode* file_node = sord_iter_get_node(files, SORD_OBJECT); - zix_tree_insert((ZixTree*)plugin->data_uris, - lilv_node_new_from_node(world, file_node), - NULL); + FOREACH_PAT(s, world->model, plugin_uri, world->uris.rdfs_seeAlso, NULL, NULL) + { + const SerdNode* file_node = serd_statement_object(s); + zix_tree_insert( + (ZixTree*)plugin->data_uris, serd_node_copy(file_node), NULL); } - sord_iter_free(files); } SerdStatus -lilv_world_load_graph(LilvWorld* world, SordNode* graph, const LilvNode* uri) +lilv_world_load_graph(LilvWorld* world, + const SerdNode* graph, + const LilvNode* uri) { - const SerdNode* base = sord_node_to_serd_node(uri->node); - SerdEnv* env = serd_env_new(base); - SerdReader* reader = sord_new_reader(world->model, env, SERD_TURTLE, graph); + SerdEnv* env = serd_env_new(serd_node_string_view(uri)); + SerdSink* inserter = serd_inserter_new(world->model, graph); + SerdReader* reader = serd_reader_new( + world->world, SERD_TURTLE, 0, env, inserter, LILV_READER_STACK_SIZE); const SerdStatus st = lilv_world_load_file(world, reader, uri); - serd_env_free(env); serd_reader_free(reader); + serd_sink_free(inserter); + serd_env_free(env); return st; } static void lilv_world_load_dyn_manifest(LilvWorld* world, - SordNode* bundle_node, + const SerdNode* bundle_node, const LilvNode* manifest) { #ifdef LILV_DYN_MANIFEST @@ -533,33 +459,33 @@ lilv_world_load_dyn_manifest(LilvWorld* world, LV2_Dyn_Manifest_Handle handle = NULL; // ?dman a dynman:DynManifest bundle_node - SordModel* model = lilv_world_filter_model(world, + SerdModel* model = lilv_world_filter_model(world, world->model, NULL, world->uris.rdf_a, world->uris.dman_DynManifest, bundle_node); - SordIter* iter = sord_begin(model); - for (; !sord_iter_end(iter); sord_iter_next(iter)) { - const SordNode* dmanifest = sord_iter_get_node(iter, SORD_SUBJECT); + SerdIter* iter = serd_begin(model); + for (; !serd_iter_end(iter); serd_iter_next(iter)) { + const SerdNode* dmanifest = serd_iter_get_node(iter, SERD_SUBJECT); // ?dman lv2:binary ?binary - SordIter* binaries = sord_search( + SerdIter* binaries = serd_model_find( world->model, dmanifest, world->uris.lv2_binary, NULL, bundle_node); - if (sord_iter_end(binaries)) { - sord_iter_free(binaries); + if (serd_iter_end(binaries)) { + serd_iter_free(binaries); LILV_ERRORF("Dynamic manifest in <%s> has no binaries, ignored\n", - sord_node_get_string(bundle_node)); + serd_node_string(bundle_node)); continue; } // Get binary path - const SordNode* binary = sord_iter_get_node(binaries, SORD_OBJECT); - const uint8_t* lib_uri = sord_node_get_string(binary); - char* lib_path = lilv_file_uri_parse((const char*)lib_uri, 0); + const SerdNode* const binary = serd_iter_get_node(binaries, SERD_OBJECT); + const char* const lib_uri = serd_node_string(binary); + char* const lib_path = serd_file_uri_parse(lib_uri, 0); if (!lib_path) { LILV_ERROR("No dynamic manifest library path\n"); - sord_iter_free(binaries); + serd_iter_free(binaries); continue; } @@ -569,7 +495,7 @@ lilv_world_load_dyn_manifest(LilvWorld* world, if (!lib) { LILV_ERRORF( "Failed to open dynmanifest library `%s' (%s)\n", lib_path, dlerror()); - sord_iter_free(binaries); + serd_iter_free(binaries); lilv_free(lib_path); continue; } @@ -580,7 +506,7 @@ lilv_world_load_dyn_manifest(LilvWorld* world, OpenFunc dmopen = (OpenFunc)lilv_dlfunc(lib, "lv2_dyn_manifest_open"); if (!dmopen || dmopen(&handle, &dman_features)) { LILV_ERRORF("No `lv2_dyn_manifest_open' in `%s'\n", lib_path); - sord_iter_free(binaries); + serd_iter_free(binaries); dlclose(lib); lilv_free(lib_path); continue; @@ -592,19 +518,19 @@ lilv_world_load_dyn_manifest(LilvWorld* world, (GetSubjectsFunc)lilv_dlfunc(lib, "lv2_dyn_manifest_get_subjects"); if (!get_subjects_func) { LILV_ERRORF("No `lv2_dyn_manifest_get_subjects' in `%s'\n", lib_path); - sord_iter_free(binaries); + serd_iter_free(binaries); dlclose(lib); lilv_free(lib_path); continue; } LilvDynManifest* desc = (LilvDynManifest*)malloc(sizeof(LilvDynManifest)); - desc->bundle = lilv_node_new_from_node(world, bundle_node); + desc->bundle = serd_node_copy(bundle_node); desc->lib = lib; desc->handle = handle; desc->refs = 0; - sord_iter_free(binaries); + serd_iter_free(binaries); // Generate data file FILE* fd = tmpfile(); @@ -613,12 +539,12 @@ lilv_world_load_dyn_manifest(LilvWorld* world, // Parse generated data file into temporary model // FIXME - const SerdNode* base = sord_node_to_serd_node(dmanifest); + const SerdNode* base = dmanifest; SerdEnv* env = serd_env_new(base); - SerdReader* reader = sord_new_reader( - world->model, env, SERD_TURTLE, sord_node_copy(dmanifest)); + SerdReader* reader = serd_model_new_reader( + world->model, env, SERD_TURTLE, serd_node_copy(dmanifest)); serd_reader_add_blank_prefix(reader, lilv_world_blank_node_prefix(world)); - serd_reader_read_file_handle(reader, fd, (const uint8_t*)"(dyn-manifest)"); + serd_reader_read_file_handle(reader, fd, "(dyn-manifest)"); serd_reader_free(reader); serd_env_free(env); @@ -626,32 +552,32 @@ lilv_world_load_dyn_manifest(LilvWorld* world, fclose(fd); // ?plugin a lv2:Plugin - SordModel* plugins = lilv_world_filter_model(world, + SerdModel* plugins = lilv_world_filter_model(world, world->model, NULL, world->uris.rdf_a, world->uris.lv2_Plugin, dmanifest); - SordIter* p = sord_begin(plugins); - FOREACH_MATCH (p) { - const SordNode* plug = sord_iter_get_node(p, SORD_SUBJECT); + SerdIter* p = serd_begin(plugins); + FOREACH_MATCH (s, p) { + const SerdNode* plug = serd_statement_subject(s); lilv_world_add_plugin(world, plug, manifest, desc, bundle_node); } if (desc->refs == 0) { - lilv_dynmanifest_free(desc); + free(desc); } - sord_iter_free(p); - sord_free(plugins); + serd_iter_free(p); + serd_free(plugins); lilv_free(lib_path); } - sord_iter_free(iter); - sord_free(model); + serd_iter_free(iter); + serd_free(model); -#else // LILV_DYN_MANIFEST +#else (void)world; (void)bundle_node; (void)manifest; -#endif +#endif // LILV_DYN_MANIFEST } #ifdef LILV_DYN_MANIFEST @@ -672,67 +598,88 @@ lilv_dynmanifest_free(LilvDynManifest* dynmanifest) #endif // LILV_DYN_MANIFEST LilvNode* -lilv_world_get_manifest_uri(LilvWorld* world, const LilvNode* bundle_uri) +lilv_world_get_manifest_node(LilvWorld* world, const LilvNode* bundle_node) { - SerdNode manifest_uri = lilv_new_uri_relative_to_base( - (const uint8_t*)"manifest.ttl", sord_node_get_string(bundle_uri->node)); - LilvNode* manifest = lilv_new_uri(world, (const char*)manifest_uri.buf); - serd_node_free(&manifest_uri); - return manifest; + (void)world; + + const SerdURIView bundle_uri = serd_node_uri_view(bundle_node); + const SerdURIView manifest_ref = serd_parse_uri("manifest.ttl"); + const SerdURIView manifest_uri = serd_resolve_uri(manifest_ref, bundle_uri); + + return serd_new_parsed_uri(manifest_uri); +} + +char* +lilv_world_get_manifest_path(LilvWorld* world, const LilvNode* bundle_node) +{ + const SerdNode* const node = lilv_world_get_manifest_node(world, bundle_node); + + return serd_parse_file_uri(serd_node_string(node), NULL); } -static SordModel* +static SerdModel* load_plugin_model(LilvWorld* world, const LilvNode* bundle_uri, const LilvNode* plugin_uri) { // Create model and reader for loading into it - SordNode* bundle_node = bundle_uri->node; - SordModel* model = sord_new(world->world, SORD_SPO | SORD_OPS, false); - SerdEnv* env = serd_env_new(sord_node_to_serd_node(bundle_node)); - SerdReader* reader = sord_new_reader(model, env, SERD_TURTLE, NULL); + SerdModel* model = + serd_model_new(world->world, SERD_INDEX_SPO | SERD_INDEX_OPS); + SerdEnv* env = serd_env_new(serd_node_string_view(bundle_uri)); + SerdSink* inserter = serd_inserter_new(model, NULL); + SerdReader* reader = serd_reader_new( + world->world, SERD_TURTLE, 0, env, inserter, LILV_READER_STACK_SIZE); // Load manifest - LilvNode* manifest_uri = lilv_world_get_manifest_uri(world, bundle_uri); + char* manifest_path = lilv_world_get_manifest_path(world, bundle_uri); + SerdByteSource* manifest_source = + serd_byte_source_new_filename(manifest_path, 4096); serd_reader_add_blank_prefix(reader, lilv_world_blank_node_prefix(world)); - serd_reader_read_file(reader, - (const uint8_t*)lilv_node_as_string(manifest_uri)); + serd_reader_start(reader, manifest_source); + serd_reader_read_document(reader); + serd_reader_finish(reader); // Load any seeAlso files - SordModel* files = lilv_world_filter_model( - world, model, plugin_uri->node, world->uris.rdfs_seeAlso, NULL, NULL); - - SordIter* f = sord_begin(files); - FOREACH_MATCH (f) { - const SordNode* file = sord_iter_get_node(f, SORD_OBJECT); - const uint8_t* file_str = sord_node_get_string(file); - if (sord_node_get_type(file) == SORD_URI) { + SerdModel* files = lilv_world_filter_model( + world, model, plugin_uri, world->uris.rdfs_seeAlso, NULL, NULL); + + SerdIter* f = serd_model_begin(files); + for (; !serd_iter_equals(f, serd_model_end(files)); serd_iter_next(f)) { + const SerdNode* file = serd_statement_object(serd_iter_get(f)); + const char* uri_str = serd_node_string(file); + if (serd_node_type(file) == SERD_URI) { + char* path_str = serd_parse_file_uri(uri_str, NULL); + SerdByteSource* source = serd_byte_source_new_filename(path_str, 4096); + serd_reader_add_blank_prefix(reader, lilv_world_blank_node_prefix(world)); - serd_reader_read_file(reader, file_str); + serd_reader_start(reader, source); + serd_reader_read_document(reader); + serd_reader_finish(reader); + + serd_byte_source_free(source); } } - sord_iter_free(f); - sord_free(files); + serd_iter_free(f); + serd_model_free(files); serd_reader_free(reader); serd_env_free(env); - lilv_node_free(manifest_uri); return model; } static LilvVersion -get_version(LilvWorld* world, SordModel* model, const LilvNode* subject) +get_version(LilvWorld* world, SerdModel* model, const LilvNode* subject) { - const SordNode* minor_node = - sord_get(model, subject->node, world->uris.lv2_minorVersion, NULL, NULL); - const SordNode* micro_node = - sord_get(model, subject->node, world->uris.lv2_microVersion, NULL, NULL); + const SerdNode* minor_node = + serd_model_get(model, subject, world->uris.lv2_minorVersion, NULL, NULL); + const SerdNode* micro_node = + serd_model_get(model, subject, world->uris.lv2_microVersion, NULL, NULL); LilvVersion version = {0, 0}; if (minor_node && micro_node) { - version.minor = atoi((const char*)sord_node_get_string(minor_node)); - version.micro = atoi((const char*)sord_node_get_string(micro_node)); + version.minor = atoi(serd_node_string(minor_node)); + version.micro = atoi(serd_node_string(micro_node)); } return version; @@ -742,16 +689,14 @@ void lilv_world_load_bundle(LilvWorld* world, const LilvNode* bundle_uri) { if (!lilv_node_is_uri(bundle_uri)) { - LILV_ERRORF("Bundle URI `%s' is not a URI\n", - sord_node_get_string(bundle_uri->node)); + LILV_ERRORF("Bundle URI `%s' is not a URI\n", serd_node_string(bundle_uri)); return; } - SordNode* bundle_node = bundle_uri->node; - LilvNode* manifest = lilv_world_get_manifest_uri(world, bundle_uri); + LilvNode* manifest = lilv_world_get_manifest_node(world, bundle_uri); - // Read manifest into model with graph = bundle_node - SerdStatus st = lilv_world_load_graph(world, bundle_node, manifest); + // Read manifest into model with graph = bundle_uri + SerdStatus st = lilv_world_load_graph(world, bundle_uri, manifest); if (st > SERD_FAILURE) { LILV_ERRORF("Error reading %s\n", lilv_node_as_string(manifest)); lilv_node_free(manifest); @@ -759,32 +704,32 @@ lilv_world_load_bundle(LilvWorld* world, const LilvNode* bundle_uri) } // ?plugin a lv2:Plugin - SordIter* plug_results = sord_search( - world->model, NULL, world->uris.rdf_a, world->uris.lv2_Plugin, bundle_node); + SerdRange* plug_results = serd_model_range( + world->model, NULL, world->uris.rdf_a, world->uris.lv2_Plugin, bundle_uri); // Find any loaded plugins that will be replaced with a newer version LilvNodes* unload_uris = lilv_nodes_new(); - FOREACH_MATCH (plug_results) { - const SordNode* plug = sord_iter_get_node(plug_results, SORD_SUBJECT); + FOREACH_MATCH (s, plug_results) { + const SerdNode* plug = serd_statement_subject(s); - LilvNode* plugin_uri = lilv_node_new_from_node(world, plug); + LilvNode* plugin_uri = serd_node_copy(plug); const LilvPlugin* plugin = lilv_plugins_get_by_uri(world->plugins, plugin_uri); const LilvNode* last_bundle = plugin ? lilv_plugin_get_bundle_uri(plugin) : NULL; - if (!plugin || sord_node_equals(bundle_node, last_bundle->node)) { + if (!plugin || serd_node_equals(bundle_uri, last_bundle)) { // No previously loaded version, or it's from the same bundle lilv_node_free(plugin_uri); continue; } // Compare versions - SordModel* this_model = load_plugin_model(world, bundle_uri, plugin_uri); + SerdModel* this_model = load_plugin_model(world, bundle_uri, plugin_uri); LilvVersion this_version = get_version(world, this_model, plugin_uri); - SordModel* last_model = load_plugin_model(world, last_bundle, plugin_uri); + SerdModel* last_model = load_plugin_model(world, last_bundle, plugin_uri); LilvVersion last_version = get_version(world, last_model, plugin_uri); - sord_free(this_model); - sord_free(last_model); + serd_model_free(this_model); + serd_model_free(last_model); const int cmp = lilv_version_cmp(&this_version, &last_version); if (cmp > 0) { zix_tree_insert( @@ -792,20 +737,20 @@ lilv_world_load_bundle(LilvWorld* world, const LilvNode* bundle_uri) LILV_WARNF("Replacing version %d.%d of <%s> from <%s>\n", last_version.minor, last_version.micro, - sord_node_get_string(plug), - sord_node_get_string(last_bundle->node)); + serd_node_string(plug), + serd_node_string(last_bundle)); LILV_NOTEF("New version %d.%d found in <%s>\n", this_version.minor, this_version.micro, - sord_node_get_string(bundle_node)); + serd_node_string(bundle_uri)); } else if (cmp < 0) { - LILV_WARNF("Ignoring bundle <%s>\n", sord_node_get_string(bundle_node)); + LILV_WARNF("Ignoring bundle <%s>\n", serd_node_string(bundle_uri)); LILV_NOTEF("Newer version of <%s> loaded from <%s>\n", - sord_node_get_string(plug), - sord_node_get_string(last_bundle->node)); + serd_node_string(plug), + serd_node_string(last_bundle)); lilv_node_free(plugin_uri); - sord_iter_free(plug_results); - lilv_world_drop_graph(world, bundle_node); + serd_range_free(plug_results); + lilv_world_drop_graph(world, bundle_uri); lilv_node_free(manifest); lilv_nodes_free(unload_uris); return; @@ -813,7 +758,7 @@ lilv_world_load_bundle(LilvWorld* world, const LilvNode* bundle_uri) lilv_node_free(plugin_uri); } - sord_iter_free(plug_results); + serd_range_free(plug_results); // Unload any old conflicting plugins LilvNodes* unload_bundles = lilv_nodes_new(); @@ -837,49 +782,46 @@ lilv_world_load_bundle(LilvWorld* world, const LilvNode* bundle_uri) lilv_nodes_free(unload_bundles); // Re-search for plugin results now that old plugins are gone - plug_results = sord_search( - world->model, NULL, world->uris.rdf_a, world->uris.lv2_Plugin, bundle_node); + plug_results = serd_model_range( + world->model, NULL, world->uris.rdf_a, world->uris.lv2_Plugin, bundle_uri); - FOREACH_MATCH (plug_results) { - const SordNode* plug = sord_iter_get_node(plug_results, SORD_SUBJECT); - lilv_world_add_plugin(world, plug, manifest, NULL, bundle_node); + FOREACH_MATCH (s, plug_results) { + const SerdNode* plug = serd_statement_subject(s); + lilv_world_add_plugin(world, plug, manifest, NULL, bundle_uri); } - sord_iter_free(plug_results); + serd_range_free(plug_results); - lilv_world_load_dyn_manifest(world, bundle_node, manifest); + lilv_world_load_dyn_manifest(world, bundle_uri, manifest); // ?spec a lv2:Specification // ?spec a owl:Ontology - const SordNode* spec_preds[] = { + const SerdNode* spec_preds[] = { world->uris.lv2_Specification, world->uris.owl_Ontology, NULL}; - for (const SordNode** p = spec_preds; *p; ++p) { - SordIter* i = - sord_search(world->model, NULL, world->uris.rdf_a, *p, bundle_node); - FOREACH_MATCH (i) { - const SordNode* spec = sord_iter_get_node(i, SORD_SUBJECT); - lilv_world_add_spec(world, spec, bundle_node); + for (const SerdNode** p = spec_preds; *p; ++p) { + FOREACH_PAT(s, world->model, NULL, world->uris.rdf_a, *p, bundle_uri) + { + const SerdNode* spec = serd_statement_subject(s); + lilv_world_add_spec(world, spec, bundle_uri); } - sord_iter_free(i); } lilv_node_free(manifest); } static int -lilv_world_drop_graph(LilvWorld* world, const SordNode* graph) +lilv_world_drop_graph(LilvWorld* world, const SerdNode* graph) { - SordIter* i = sord_search(world->model, NULL, NULL, NULL, graph); - while (!sord_iter_end(i)) { - const SerdStatus st = sord_erase(world->model, i); - if (st) { - LILV_ERRORF("Error removing statement from <%s> (%s)\n", - sord_node_get_string(graph), - serd_strerror(st)); - return st; - } + SerdRange* r = serd_model_range(world->model, NULL, NULL, NULL, graph); + const SerdStatus st = serd_model_erase_range(world->model, r); + + if (st) { + LILV_ERRORF("Error dropping graph <%s> (%s)\n", + serd_node_string(graph), + serd_strerror(st)); + return st; } - sord_iter_free(i); + serd_range_free(r); return 0; } @@ -941,20 +883,25 @@ lilv_world_unload_bundle(LilvWorld* world, const LilvNode* bundle_uri) } // Drop everything in bundle graph - return lilv_world_drop_graph(world, bundle_uri->node); + return lilv_world_drop_graph(world, bundle_uri); } static void load_dir_entry(const char* dir, const char* name, void* data) { LilvWorld* world = (LilvWorld*)data; - char* path = lilv_strjoin(dir, "/", name, "/", NULL); - SerdNode suri = serd_node_new_file_uri((const uint8_t*)path, 0, 0, true); - LilvNode* node = lilv_new_uri(world, (const char*)suri.buf); + if (!strcmp(name, ".") || !strcmp(name, "..")) { + return; + } + + char* path = lilv_strjoin(dir, "/", name, "/", NULL); + SerdNode* suri = + serd_new_file_uri(SERD_MEASURE_STRING(path), SERD_EMPTY_STRING()); + LilvNode* node = lilv_new_uri(world, serd_node_string(suri)); lilv_world_load_bundle(world, node); lilv_node_free(node); - serd_node_free(&suri); + serd_node_free(suri); free(path); } @@ -1025,34 +972,29 @@ lilv_world_load_plugin_classes(LilvWorld* world) is e.g. how a host would build a menu), they won't be seen anyway... */ - SordIter* classes = sord_search( - world->model, NULL, world->uris.rdf_a, world->uris.rdfs_Class, NULL); - FOREACH_MATCH (classes) { - const SordNode* class_node = sord_iter_get_node(classes, SORD_SUBJECT); + FOREACH_PAT( + s, world->model, NULL, world->uris.rdf_a, world->uris.rdfs_Class, NULL) + { + const SerdNode* class_node = serd_statement_subject(s); - SordNode* parent = sord_get( + const SerdNode* parent = serd_model_get( world->model, class_node, world->uris.rdfs_subClassOf, NULL, NULL); - if (!parent || sord_node_get_type(parent) != SORD_URI) { + if (!parent || serd_node_type(parent) != SERD_URI) { continue; } - SordNode* label = - sord_get(world->model, class_node, world->uris.rdfs_label, NULL, NULL); + const SerdNode* label = serd_model_get( + world->model, class_node, world->uris.rdfs_label, NULL, NULL); if (!label) { - sord_node_free(world->world, parent); continue; } - LilvPluginClass* pclass = lilv_plugin_class_new( - world, parent, class_node, (const char*)sord_node_get_string(label)); + LilvPluginClass* pclass = + lilv_plugin_class_new(world, parent, class_node, serd_node_string(label)); if (pclass) { zix_tree_insert((ZixTree*)world->plugin_classes, pclass, NULL); } - - sord_node_free(world->world, label); - sord_node_free(world->world, parent); } - sord_iter_free(classes); } void @@ -1074,11 +1016,11 @@ lilv_world_load_all(LilvWorld* world) (const LilvPlugin*)lilv_collection_get((ZixTree*)world->plugins, p); // ?new dc:replaces plugin - if (sord_ask(world->model, - NULL, - world->uris.dc_replaces, - lilv_plugin_get_uri(plugin)->node, - NULL)) { + if (serd_model_ask(world->model, + NULL, + world->uris.dc_replaces, + lilv_plugin_get_uri(plugin), + NULL)) { // TODO: Check if replacement is a known plugin? (expensive) ((LilvPlugin*)plugin)->replaced = true; } @@ -1092,25 +1034,33 @@ lilv_world_load_all(LilvWorld* world) SerdStatus lilv_world_load_file(LilvWorld* world, SerdReader* reader, const LilvNode* uri) { - ZixTreeIter* iter = NULL; + ZixTreeIter* iter; if (!zix_tree_find((ZixTree*)world->loaded_files, uri, &iter)) { return SERD_FAILURE; // File has already been loaded } - size_t uri_len = 0; - const uint8_t* const uri_str = - sord_node_get_string_counted(uri->node, &uri_len); - if (strncmp((const char*)uri_str, "file:", 5)) { + const char* const uri_str = serd_node_string(uri); + const size_t uri_len = serd_node_length(uri); + if (strncmp(uri_str, "file:", 5)) { return SERD_FAILURE; // Not a local file + } else if (strcmp(uri_str + uri_len - 4, ".ttl")) { + return SERD_FAILURE; // Not a Turtle file } - if (strcmp((const char*)uri_str + uri_len - 4, ".ttl")) { - return SERD_FAILURE; // Not a Turtle file + SerdStatus st = SERD_SUCCESS; + char* hostname = NULL; + char* filename = serd_parse_file_uri(serd_node_string(uri), &hostname); + if (!filename || hostname) { + return SERD_ERR_BAD_ARG; } + SerdByteSource* const source = + serd_byte_source_new_filename(filename, PAGE_SIZE); + serd_reader_add_blank_prefix(reader, lilv_world_blank_node_prefix(world)); - const SerdStatus st = serd_reader_read_file(reader, uri_str); - if (st) { + if ((st = serd_reader_start(reader, source)) || + (st = serd_reader_read_document(reader)) || + (st = serd_reader_finish(reader))) { LILV_ERRORF("Error loading file `%s'\n", lilv_node_as_string(uri)); return st; } @@ -1124,30 +1074,29 @@ int 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", - sord_node_get_string(resource->node)); + LILV_ERRORF("Node `%s' is not a resource\n", serd_node_string(resource)); return -1; } - SordModel* files = lilv_world_filter_model( - world, world->model, resource->node, world->uris.rdfs_seeAlso, NULL, NULL); + SerdModel* files = lilv_world_filter_model( + world, world->model, resource, world->uris.rdfs_seeAlso, NULL, NULL); - SordIter* f = sord_begin(files); + SerdIter* f = serd_model_begin(files); int n_read = 0; - FOREACH_MATCH (f) { - const SordNode* file = sord_iter_get_node(f, SORD_OBJECT); - const uint8_t* file_str = sord_node_get_string(file); - LilvNode* file_node = lilv_node_new_from_node(world, file); - if (sord_node_get_type(file) != SORD_URI) { + for (; !serd_iter_equals(f, serd_model_end(files)); serd_iter_next(f)) { + const SerdNode* file = serd_statement_object(serd_iter_get(f)); + const char* file_str = serd_node_string(file); + LilvNode* file_node = serd_node_copy(file); + if (serd_node_type(file) != SERD_URI) { LILV_ERRORF("rdfs:seeAlso node `%s' is not a URI\n", file_str); - } else if (!lilv_world_load_graph(world, (SordNode*)file, file_node)) { + } else if (!lilv_world_load_graph(world, (SerdNode*)file, file_node)) { ++n_read; } lilv_node_free(file_node); } - sord_iter_free(f); + serd_iter_free(f); - sord_free(files); + serd_model_free(files); return n_read; } @@ -1155,31 +1104,30 @@ int lilv_world_unload_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", - sord_node_get_string(resource->node)); + LILV_ERRORF("Node `%s' is not a resource\n", serd_node_string(resource)); return -1; } - SordModel* files = lilv_world_filter_model( - world, world->model, resource->node, world->uris.rdfs_seeAlso, NULL, NULL); + SerdModel* files = lilv_world_filter_model( + world, world->model, resource, world->uris.rdfs_seeAlso, NULL, NULL); - SordIter* f = sord_begin(files); + SerdIter* f = serd_model_begin(files); int n_dropped = 0; - FOREACH_MATCH (f) { - const SordNode* file = sord_iter_get_node(f, SORD_OBJECT); - LilvNode* file_node = lilv_node_new_from_node(world, file); - if (sord_node_get_type(file) != SORD_URI) { + for (; !serd_iter_equals(f, serd_model_end(files)); serd_iter_next(f)) { + const SerdNode* file = serd_statement_object(serd_iter_get(f)); + LilvNode* file_node = serd_node_copy(file); + if (serd_node_type(file) != SERD_URI) { LILV_ERRORF("rdfs:seeAlso node `%s' is not a URI\n", - sord_node_get_string(file)); - } else if (!lilv_world_drop_graph(world, file_node->node)) { + serd_node_string(file)); + } else if (!lilv_world_drop_graph(world, file_node)) { lilv_world_unload_file(world, file_node); ++n_dropped; } lilv_node_free(file_node); } - sord_iter_free(f); + serd_iter_free(f); - sord_free(files); + serd_model_free(files); return n_dropped; } @@ -1205,13 +1153,11 @@ LilvNode* lilv_world_get_symbol(LilvWorld* world, const LilvNode* subject) { // Check for explicitly given symbol - SordNode* snode = - sord_get(world->model, subject->node, world->uris.lv2_symbol, NULL, NULL); + const SerdNode* snode = + serd_model_get(world->model, subject, world->uris.lv2_symbol, NULL, NULL); if (snode) { - LilvNode* ret = lilv_node_new_from_node(world, snode); - sord_node_free(world->world, snode); - return ret; + return serd_node_copy(snode); } if (!lilv_node_is_uri(subject)) { @@ -1219,16 +1165,15 @@ lilv_world_get_symbol(LilvWorld* world, const LilvNode* subject) } // Find rightmost segment of URI - SerdURI uri; - serd_uri_parse((const uint8_t*)lilv_node_as_uri(subject), &uri); + SerdURIView uri = serd_parse_uri(lilv_node_as_uri(subject)); const char* str = "_"; if (uri.fragment.buf) { - str = (const char*)uri.fragment.buf + 1; + str = uri.fragment.buf + 1; } else if (uri.query.buf) { - str = (const char*)uri.query.buf; + str = uri.query.buf; } else if (uri.path.buf) { - const char* last_slash = strrchr((const char*)uri.path.buf, '/'); - str = last_slash ? (last_slash + 1) : (const char*)uri.path.buf; + const char* last_slash = strrchr(uri.path.buf, '/'); + str = last_slash ? (last_slash + 1) : uri.path.buf; } // Replace invalid characters |