Beispiel #1
0
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;
	}
}
Beispiel #2
0
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;
}
Beispiel #3
0
static LilvState*
new_state_from_model(LilvWorld*       world,
                     LV2_URID_Map*    map,
                     SordModel*       model,
                     const SordNode*  node,
                     const char*      dir)
{
	LilvState* const state = (LilvState*)malloc(sizeof(LilvState));
	memset(state, '\0', sizeof(LilvState));
	state->dir       = lilv_strdup(dir);
	state->atom_Path = map->map(map->handle, LV2_ATOM__Path);

	// Get the plugin URI this state applies to
	SordIter* i = sord_search(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);
		if (!state->dir && graph) {
			state->dir = lilv_strdup((const char*)sord_node_get_string(graph));
		}
		sord_iter_free(i);
	} else if (sord_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);
	} else {
		LILV_ERRORF("State %s missing lv2:appliesTo property\n",
		            sord_node_get_string(node));
	}

	// Get the state label
	i = sord_search(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));
		if (!state->dir) {
			state->dir = lilv_strdup((const char*)sord_node_get_string(graph));
		}
		sord_iter_free(i);
	}

	Sratom*        sratom = sratom_new(map);
	SerdChunk      chunk  = { NULL, 0 };
	LV2_Atom_Forge forge;
	lv2_atom_forge_init(&forge, map);
	lv2_atom_forge_set_sink(
		&forge, sratom_forge_sink, sratom_forge_deref, &chunk);

	// Get port values
	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);
		if (!value) {
			value = sord_get(model, port, world->uris.lv2_default, 0, 0);
		}
		if (!symbol) {
			LILV_ERRORF("State `%s' port missing symbol.\n",
			            sord_node_get_string(node));
		} else if (value) {
			chunk.len = 0;
			sratom_read(sratom, &forge, world->world, model, value);
			LV2_Atom* atom = (LV2_Atom*)chunk.buf;

			append_port_value(state,
			                  (const char*)sord_node_get_string(symbol),
			                  LV2_ATOM_BODY(atom), atom->size, atom->type);

			if (label) {
				lilv_state_set_label(state,
				                     (const char*)sord_node_get_string(label));
			}
		}
		sord_node_free(world->world, value);
		sord_node_free(world->world, symbol);
		sord_node_free(world->world, label);
	}
	sord_iter_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);
	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);

			chunk.len = 0;
			lv2_atom_forge_set_sink(
				&forge, sratom_forge_sink, sratom_forge_deref, &chunk);

			sratom_read(sratom, &forge, world->world, model, o);
			LV2_Atom* atom  = (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, (const char*)sord_node_get_string(p));
			prop.type  = atom->type;
			prop.size  = atom->size;
			prop.value = malloc(atom->size);
			memcpy(prop.value, LV2_ATOM_BODY(atom), atom->size);
			if (atom->type == forge.Path) {
				prop.flags = LV2_STATE_IS_PORTABLE;
			}

			if (prop.value) {
				state->props = (Property*)realloc(
					state->props, (++state->num_props) * sizeof(Property));
				state->props[state->num_props - 1] = prop;
			}
		}
		sord_iter_free(props);
	}
	sord_node_free(world->world, state_node);
	sord_node_free(world->world, statep);

	free((void*)chunk.buf);
	sratom_free(sratom);

	qsort(state->props, state->num_props, sizeof(Property), property_cmp);
	qsort(state->values, state->num_values, sizeof(PortValue), value_cmp);

	return state;
}