SerdStatus sord_inserter_write_statement(SordInserter* inserter, SerdStatementFlags flags, const SerdNode* graph, const SerdNode* subject, const SerdNode* predicate, const SerdNode* object, const SerdNode* object_datatype, const SerdNode* object_lang) { SordWorld* world = sord_get_world(inserter->model); SerdEnv* env = inserter->env; SordNode* g = sord_node_from_serd_node(world, env, graph, NULL, NULL); SordNode* s = sord_node_from_serd_node(world, env, subject, NULL, NULL); SordNode* p = sord_node_from_serd_node(world, env, predicate, NULL, NULL); SordNode* o = sord_node_from_serd_node(world, env, object, object_datatype, object_lang); if (!s || !p || !o) { return SERD_ERR_BAD_ARG; } const SordQuad tup = { s, p, o, g }; sord_add(inserter->model, tup); sord_node_free(world, o); sord_node_free(world, p); sord_node_free(world, s); sord_node_free(world, g); return SERD_SUCCESS; }
LILV_API LilvState* lilv_state_new_from_string(LilvWorld* world, const LV2_URID_Map* map, const char* str) { if (!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); set_prefixes(env); serd_reader_read_string(reader, USTR(str)); SordNode* o = sord_new_uri(world->world, USTR(LV2_PRESETS__Preset)); SordNode* s = sord_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_reader_free(reader); sord_free(model); serd_env_free(env); return state; }
LILV_API void lilv_node_free(LilvNode* val) { if (val) { sord_node_free(val->world->world, val->node); free(val); } }
static void free_node_entry(void* value, void* user_data) { SordNode* node = (SordNode*)value; if (node->node.type == SERD_LITERAL) { sord_node_free((SordWorld*)user_data, node->meta.lit.datatype); } free((uint8_t*)node->node.buf); }
void lilv_port_free(const LilvPlugin* plugin, LilvPort* port) { if (port) { sord_node_free(plugin->world->world, port->node); lilv_nodes_free(port->classes); lilv_node_free(port->symbol); free(port); } }
SordNode* sord_node_from_serd_node(SordWorld* world, SerdEnv* env, const SerdNode* sn, const SerdNode* datatype, const SerdNode* lang) { if (!sn) { return NULL; } SordNode* datatype_node = NULL; SordNode* ret = NULL; switch (sn->type) { case SERD_NOTHING: return NULL; case SERD_LITERAL: datatype_node = sord_node_from_serd_node( world, env, datatype, NULL, NULL), ret = sord_new_literal_counted( world, datatype_node, sn->buf, sn->n_bytes, sn->n_chars, sn->flags, lang ? (const char*)lang->buf : NULL); sord_node_free(world, datatype_node); return ret; case SERD_URI: if (serd_uri_string_has_scheme(sn->buf)) { return sord_new_uri_counted( world, sn->buf, sn->n_bytes, sn->n_chars, true); } else { SerdURI base_uri; serd_env_get_base_uri(env, &base_uri); SerdURI abs_uri; SerdNode abs_uri_node = serd_node_new_uri_from_node( sn, &base_uri, &abs_uri); ret = sord_new_uri_counted(world, abs_uri_node.buf, abs_uri_node.n_bytes, abs_uri_node.n_chars, true); serd_node_free(&abs_uri_node); return ret; } case SERD_CURIE: { SerdChunk uri_prefix; SerdChunk uri_suffix; if (serd_env_expand(env, sn, &uri_prefix, &uri_suffix)) { error(world, SERD_ERR_BAD_CURIE, "failed to expand CURIE `%s'\n", sn->buf); return NULL; } const size_t uri_len = uri_prefix.len + uri_suffix.len; uint8_t* buf = (uint8_t*)malloc(uri_len + 1); memcpy(buf, uri_prefix.buf, uri_prefix.len); memcpy(buf + uri_prefix.len, uri_suffix.buf, uri_suffix.len); buf[uri_len] = '\0'; ret = sord_new_uri_counted( world, buf, uri_prefix.len + uri_suffix.len, uri_prefix.len + uri_suffix.len, false); // FIXME: UTF-8 return ret; } case SERD_BLANK: return sord_new_blank_counted(world, sn->buf, sn->n_bytes, sn->n_chars); } return NULL; }
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; }