// Copyright 2007-2019 David Robillard // SPDX-License-Identifier: ISC #include "lilv_internal.h" #include "lv2/atom/atom.h" #include "lv2/core/lv2.h" #include "lv2/event/event.h" #include "lilv/lilv.h" #include "sord/sord.h" #include "zix/tree.h" #include #include #include #include #include LilvPort* lilv_port_new(LilvWorld* world, const SordNode* 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(); return port; } void lilv_port_free(const LilvPlugin* plugin, LilvPort* port) { (void)plugin; if (port) { lilv_node_free(port->node); lilv_nodes_free(port->classes); lilv_node_free(port->symbol); free(port); } } bool lilv_port_is_a(const LilvPlugin* plugin, const LilvPort* port, const LilvNode* port_class) { (void)plugin; LILV_FOREACH (nodes, i, port->classes) { if (lilv_node_equals(lilv_nodes_get(port->classes, i), port_class)) { return true; } } return false; } bool 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); } bool 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)) { return true; } } return false; } static LilvNodes* lilv_port_get_value_by_node(const LilvPlugin* plugin, const LilvPort* port, const SordNode* predicate) { return lilv_world_find_nodes_internal( plugin->world, port->node->node, predicate, NULL); } const LilvNode* lilv_port_get_node(const LilvPlugin* plugin, const LilvPort* port) { (void)plugin; return port->node; } LilvNodes* lilv_port_get_value(const LilvPlugin* plugin, const LilvPort* port, const LilvNode* predicate) { if (!lilv_node_is_uri(predicate)) { LILV_ERRORF("Predicate `%s' is not a URI\n", sord_node_get_string(predicate->node)); return NULL; } return lilv_port_get_value_by_node(plugin, port, predicate->node); } LilvNode* lilv_port_get(const LilvPlugin* plugin, const LilvPort* port, const LilvNode* predicate) { LilvNodes* values = lilv_port_get_value(plugin, port, predicate); LilvNode* value = lilv_node_duplicate(values ? lilv_nodes_get_first(values) : NULL); lilv_nodes_free(values); return value; } uint32_t lilv_port_get_index(const LilvPlugin* plugin, const LilvPort* port) { (void)plugin; return port->index; } const LilvNode* lilv_port_get_symbol(const LilvPlugin* plugin, const LilvPort* port) { (void)plugin; return port->symbol; } LilvNode* lilv_port_get_name(const LilvPlugin* plugin, const LilvPort* port) { LilvNodes* results = lilv_port_get_value_by_node(plugin, port, plugin->world->uris.lv2_name); LilvNode* ret = NULL; if (results) { const LilvNode* val = lilv_nodes_get_first(results); if (lilv_node_is_string(val)) { ret = lilv_node_duplicate(val); } lilv_nodes_free(results); } if (!ret) { LILV_WARNF("Plugin <%s> port has no (mandatory) doap:name\n", lilv_node_as_string(lilv_plugin_get_uri(plugin))); } return ret; } const LilvNodes* lilv_port_get_classes(const LilvPlugin* plugin, const LilvPort* port) { (void)plugin; return port->classes; } void lilv_port_get_range(const LilvPlugin* plugin, const LilvPort* port, LilvNode** def, LilvNode** min, LilvNode** max) { if (def) { LilvNodes* defaults = lilv_port_get_value_by_node( plugin, port, plugin->world->uris.lv2_default); *def = defaults ? lilv_node_duplicate(lilv_nodes_get_first(defaults)) : NULL; lilv_nodes_free(defaults); } if (min) { LilvNodes* minimums = lilv_port_get_value_by_node( plugin, port, plugin->world->uris.lv2_minimum); *min = minimums ? lilv_node_duplicate(lilv_nodes_get_first(minimums)) : NULL; lilv_nodes_free(minimums); } if (max) { LilvNodes* maximums = lilv_port_get_value_by_node( plugin, port, plugin->world->uris.lv2_maximum); *max = maximums ? lilv_node_duplicate(lilv_nodes_get_first(maximums)) : NULL; lilv_nodes_free(maximums); } } 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); if (sord_iter_end(points)) { return NULL; } LilvScalePoints* ret = lilv_scale_points_new(); FOREACH_MATCH (points) { const SordNode* point = sord_iter_get_node(points, SORD_OBJECT); LilvNode* value = lilv_plugin_get_unique(plugin, point, plugin->world->uris.rdf_value); LilvNode* label = lilv_plugin_get_unique(plugin, point, plugin->world->uris.rdfs_label); if (value && label) { zix_tree_insert((ZixTree*)ret, lilv_scale_point_new(value, label), NULL); } } sord_iter_free(points); assert(lilv_nodes_size(ret) > 0); return ret; } 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); lilv_node_free(pred); return ret; }