SocketWriter::~SocketWriter() { sratom_free(_sratom); serd_writer_free(_writer); serd_env_free(_env); }
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; }
static int lilv_state_write(LilvWorld* world, LV2_URID_Map* map, LV2_URID_Unmap* unmap, const LilvState* state, SerdWriter* writer, const char* uri, const char* dir) { 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 : "")); // <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); // <subject> lv2:appliesTo <http://example.org/plugin> serd_writer_write_statement(writer, 0, NULL, &subject, &lv2_appliesTo, plugin_uri, NULL, NULL); // <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); } SerdEnv* env = serd_writer_get_env(writer); const SerdNode* base = serd_env_get_base_uri(env, NULL); Sratom* sratom = sratom_new(map); sratom_set_sink(sratom, (const char*)base->buf, (SerdStatementSink)serd_writer_write_statement, (SerdEndSink)serd_writer_end_anon, writer); // Write port values as pretty numbers sratom_set_pretty_numbers(sratom, true); // Write port values for (uint32_t i = 0; i < state->num_values; ++i) { PortValue* const value = &state->values[i]; const SerdNode port = serd_node_from_string( SERD_BLANK, USTR(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); // _: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); // _: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->type, value->size, value->value); serd_writer_end_anon(writer, &port); } // Write property values with precise types sratom_set_pretty_numbers(sratom, false); // Write properties const SerdNode state_node = serd_node_from_string(SERD_BLANK, USTR("2state")); if (state->num_props > 0) { p = serd_node_from_string(SERD_URI, USTR(LV2_STATE__state)); serd_writer_write_statement(writer, SERD_ANON_O_BEGIN, NULL, &subject, &p, &state_node, NULL, NULL); } for (uint32_t i = 0; i < state->num_props; ++i) { Property* prop = &state->props[i]; const char* key = unmap->unmap(unmap->handle, prop->key); p = serd_node_from_string(SERD_URI, USTR(key)); if (prop->type == state->atom_Path && !dir) { const char* path = (const char*)prop->value; const char* abs_path = lilv_state_rel2abs(state, path); sratom_write(sratom, unmap, SERD_ANON_CONT, &state_node, &p, prop->type, strlen(abs_path) + 1, abs_path); } else { sratom_write(sratom, unmap, SERD_ANON_CONT, &state_node, &p, prop->type, prop->size, prop->value); } } if (state->num_props > 0) { serd_writer_end_anon(writer, &state_node); } sratom_free(sratom); return 0; }
SocketWriter::~SocketWriter() { sratom_free(_sratom); }