static char* abstract_path(LV2_State_Map_Path_Handle handle, const char* abs_path) { LilvState* state = (LilvState*)handle; char* path = NULL; char* real_path = lilv_realpath(abs_path); const PathMap key = { (char*)real_path, NULL }; ZixTreeIter* iter = NULL; if (abs_path[0] == '\0') { return lilv_strdup(abs_path); } else if (!zix_tree_find(state->abs2rel, &key, &iter)) { // Already mapped path in a previous call PathMap* pm = (PathMap*)zix_tree_get(iter); free(real_path); return lilv_strdup(pm->rel); } else if (lilv_path_is_child(real_path, state->dir)) { // File in state directory (loaded, or created by plugin during save path = lilv_path_relative_to(real_path, state->dir); } else if (lilv_path_is_child(real_path, state->file_dir)) { // File created by plugin earlier path = lilv_path_relative_to(real_path, state->file_dir); if (state->copy_dir) { if (!lilv_path_exists(state->copy_dir, NULL)) { lilv_mkdir_p(state->copy_dir); } char* cpath = lilv_path_join(state->copy_dir, path); char* copy = lilv_get_latest_copy(real_path, cpath); if (!copy || !lilv_file_equals(real_path, copy)) { // No recent enough copy, make a new one copy = lilv_find_free_path(cpath, lilv_path_exists, NULL); lilv_copy_file(real_path, copy); } free(real_path); free(cpath); // Refer to the latest copy in plugin state real_path = copy; } } else { // New path outside state directory const char* slash = strrchr(real_path, '/'); const char* name = slash ? (slash + 1) : real_path; // Find a free name in the (virtual) state directory path = lilv_find_free_path(name, lilv_state_has_path, state); } // Add record to path mapping PathMap* pm = (PathMap*)malloc(sizeof(PathMap)); pm->abs = real_path; pm->rel = lilv_strdup(path); zix_tree_insert(state->abs2rel, pm, NULL); zix_tree_insert(state->rel2abs, pm, NULL); return path; }
LilvUI* lilv_ui_new(LilvWorld* world, LilvNode* uri, LilvNode* type_uri, LilvNode* binary_uri) { assert(uri); assert(type_uri); assert(binary_uri); LilvUI* ui = (LilvUI*)malloc(sizeof(LilvUI)); ui->world = world; ui->uri = uri; ui->binary_uri = binary_uri; // FIXME: kludge char* bundle = lilv_strdup(lilv_node_as_string(ui->binary_uri)); char* last_slash = strrchr(bundle, '/') + 1; *last_slash = '\0'; ui->bundle_uri = lilv_new_uri(world, bundle); free(bundle); ui->classes = lilv_nodes_new(); zix_tree_insert((ZixTree*)ui->classes, type_uri, NULL); return ui; }
LILV_API LilvNodes* lilv_ui_get_supported_features(const LilvUI* ui) { LilvNodes* optional = lilv_ui_get_optional_features(ui); LilvNodes* required = lilv_ui_get_required_features(ui); LilvNodes* result = lilv_nodes_new(); LILV_FOREACH(nodes, i, optional) zix_tree_insert((ZixTree*)result, lilv_node_duplicate(lilv_nodes_get(optional, i)), NULL); LILV_FOREACH(nodes, i, required) zix_tree_insert((ZixTree*)result, lilv_node_duplicate(lilv_nodes_get(required, i)), NULL); lilv_nodes_free(optional); lilv_nodes_free(required); return result; }
LilvNodes* lilv_nodes_from_stream_objects(LilvWorld* world, SordIter* stream, SordQuadIndex field) { if (sord_iter_end(stream)) { sord_iter_free(stream); return NULL; } else if (world->opt.filter_language) { return lilv_nodes_from_stream_objects_i18n(world, stream, field); } else { 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); } } sord_iter_free(stream); return values; } }
static LilvNodes* lilv_nodes_from_stream_objects_i18n(LilvWorld* world, SordIter* stream, SordQuadIndex field) { LilvNodes* values = lilv_nodes_new(); const SordNode* nolang = NULL; // Untranslated value const SordNode* 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); LilvLangMatch lm = LILV_LANG_MATCH_NONE; if (lang) { lm = (syslang) ? lilv_lang_matches(lang, syslang) : LILV_LANG_MATCH_PARTIAL; } else { 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, lilv_node_new_from_node(world, 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); } } sord_iter_free(stream); free(syslang); if (lilv_nodes_size(values) > 0) { return values; } const SordNode* best = nolang; if (syslang && partial) { // Partial language match for system language best = partial; } else if (!best) { // No languages matches at all, and no untranslated value // Use any value, if possible best = partial; } if (best) { zix_tree_insert( (ZixTree*)values, lilv_node_new_from_node(world, best), NULL); } else { // No matches whatsoever lilv_nodes_free(values); values = NULL; } return values; }
static inline bool sord_add_to_index(SordModel* sord, const SordNode** tup, SordOrder order) { return !zix_tree_insert(sord->indices[order], tup, NULL); }