From 1bdb879eebbacf0af12a6d10e07756a1d5ae9082 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 18 Dec 2011 04:24:05 +0000 Subject: persist.c => state.c. git-svn-id: http://svn.drobilla.net/lad/trunk/jalv@3885 a436a847-0d15-0410-975c-d299462d15a1 --- src/persist.c | 299 ---------------------------------------------------------- 1 file changed, 299 deletions(-) delete mode 100644 src/persist.c (limited to 'src/persist.c') diff --git a/src/persist.c b/src/persist.c deleted file mode 100644 index f87ed6f..0000000 --- a/src/persist.c +++ /dev/null @@ -1,299 +0,0 @@ -/* - Copyright 2007-2011 David Robillard - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ - -#include -#include -#include -#include -#include - -#ifdef HAVE_LV2_STATE -# include "lv2/lv2plug.in/ns/ext/state/state.h" -#endif - -#include "jalv-config.h" -#include "jalv_internal.h" - -#define NS_ATOM (const uint8_t*)"http://lv2plug.in/ns/ext/atom#" -#define NS_JALV (const uint8_t*)"http://drobilla.net/ns/jalv#" -#define NS_LV2 (const uint8_t*)"http://lv2plug.in/ns/lv2core#" -#define NS_PSET (const uint8_t*)"http://lv2plug.in/ns/ext/presets#" -#define NS_STATE (const uint8_t*)"http://lv2plug.in/ns/ext/state#" -#define NS_XSD (const uint8_t*)"http://www.w3.org/2001/XMLSchema#" -#define NS_RDFS (const uint8_t*)"http://www.w3.org/2000/01/rdf-schema#" - -#define USTR(s) ((const uint8_t*)s) - -static int -property_cmp(const void* a, const void* b) -{ - const struct Property* pa = (const struct Property*)a; - const struct Property* pb = (const struct Property*)b; - return pa->key - pb->key; -} - -#ifdef HAVE_LV2_STATE -static int -store_callback(void* host_data, - uint32_t key, - const void* value, - size_t size, - uint32_t type, - uint32_t flags) -{ - Jalv* jalv = (Jalv*)host_data; - const char* key_uri = symap_unmap(jalv->symap, key); - const char* type_uri = symap_unmap(jalv->symap, type); - if (strcmp(type_uri, (const char*)(NS_ATOM "String"))) { - fprintf(stderr, "error: Unsupported (not atom:String) value stored\n"); - return 1; - } - - if (key_uri && type_uri && value) { - const SerdNode p = serd_node_from_string(SERD_URI, USTR(key_uri)); - const SerdNode o = serd_node_from_string(SERD_LITERAL, USTR(value)); - const SerdNode t = serd_node_from_string(SERD_URI, USTR(type_uri)); - - serd_writer_write_statement(jalv->writer, SERD_ANON_CONT, NULL, - &jalv->state_node, &p, &o, &t, NULL); - - return 0; - } - - fprintf(stderr, "error: Failed to store property (key %d)\n", key); - return 1; -} - -static const void* -retrieve_callback(void* host_data, - uint32_t key, - size_t* size, - uint32_t* type, - uint32_t* flags) -{ - Jalv* jalv = (Jalv*)host_data; - struct Property search_key = { key, SERD_NODE_NULL, SERD_NODE_NULL }; - struct Property* prop = (struct Property*)bsearch( - &search_key, jalv->props, jalv->num_props, - sizeof(struct Property), property_cmp); - - if (prop) { - *size = prop->value.n_bytes; - *type = symap_map(jalv->symap, (const char*)(NS_ATOM "String")); - *flags = 0; - return prop->value.buf; - } - - return NULL; - -} -#endif // HAVE_LV2_STATE - -static size_t -file_sink(const void* buf, size_t len, void* stream) -{ - FILE* file = (FILE*)stream; - return fwrite(buf, 1, len, file); -} - -void -jalv_save(Jalv* jalv, const char* dir) -{ - assert(!jalv->writer); - - // Set numeric locale to C so snprintf %f is Turtle compatible - char* locale = jalv_strdup(setlocale(LC_NUMERIC, NULL)); - setlocale(LC_NUMERIC, "C"); - - const size_t dir_len = strlen(dir); - const char* const filename = "state.ttl"; - const size_t path_len = dir_len + strlen(filename); - char* const path = (char*)malloc(path_len + 1); - - snprintf(path, path_len + 1, "%s%s", dir, filename); - FILE* out_fd = fopen(path, "w"); - - SerdEnv* env = serd_env_new(NULL); - serd_env_set_prefix_from_strings(env, USTR("atom"), USTR(NS_ATOM)); - serd_env_set_prefix_from_strings(env, USTR("jalv"), USTR(NS_JALV)); - serd_env_set_prefix_from_strings(env, USTR("lv2"), USTR(NS_LV2)); - serd_env_set_prefix_from_strings(env, USTR("pset"), USTR(NS_PSET)); - serd_env_set_prefix_from_strings(env, USTR("rdfs"), USTR(NS_RDFS)); - serd_env_set_prefix_from_strings(env, USTR("state"), USTR(NS_STATE)); - - SerdNode jalv_plugin = serd_node_from_string(SERD_URI, NS_JALV "plugin"); - - SerdNode plugin_uri = serd_node_from_string(SERD_URI, USTR(lilv_node_as_uri( - lilv_plugin_get_uri(jalv->plugin)))); - - - SerdNode subject = serd_node_from_string(SERD_URI, USTR("")); - - jalv->writer = serd_writer_new( - SERD_TURTLE, - SERD_STYLE_ABBREVIATED|SERD_STYLE_CURIED, - env, - &SERD_URI_NULL, - file_sink, - out_fd); - - serd_env_foreach(env, (SerdPrefixSink)serd_writer_set_prefix, jalv->writer); - - // <> jalv:plugin - serd_writer_write_statement(jalv->writer, 0, NULL, - &subject, - &jalv_plugin, - &plugin_uri, NULL, NULL); - - jalv_save_port_values(jalv, jalv->writer, &subject); - -#ifdef HAVE_LV2_STATE - assert(jalv->symap); - const LV2_State_Interface* state = (const LV2_State_Interface*) - lilv_instance_get_extension_data(jalv->instance, LV2_STATE_INTERFACE_URI); - - if (state) { - SerdNode state_instanceState = serd_node_from_string( - SERD_URI, (NS_STATE "instanceState")); - - // [] state:instanceState [ - jalv->state_node = serd_node_from_string(SERD_BLANK, USTR("state")); - serd_writer_write_statement(jalv->writer, SERD_ANON_O_BEGIN, NULL, - &subject, - &state_instanceState, - &jalv->state_node, NULL, NULL); - - // Write properties to state blank node - state->save(lilv_instance_get_handle(jalv->instance), - store_callback, - jalv, - LV2_STATE_IS_POD|LV2_STATE_IS_PORTABLE, - NULL); - - // ] - serd_writer_end_anon(jalv->writer, &jalv->state_node); - jalv->state_node = SERD_NODE_NULL; - } -#endif // HAVE_LV2_STATE - - // Close state file and clean up Serd - serd_writer_free(jalv->writer); - jalv->writer = NULL; - fclose(out_fd); - serd_env_free(env); - - // Reset numeric locale to original value - setlocale(LC_NUMERIC, locale); - free(locale); - - free(path); -} - -static SerdStatus -on_statement(void* handle, - SerdStatementFlags flags, - const SerdNode* graph, - const SerdNode* subject, - const SerdNode* predicate, - const SerdNode* object, - const SerdNode* object_datatype, - const SerdNode* object_lang) -{ - Jalv* jalv = (Jalv*)handle; - if (jalv->in_state) { - jalv->props = (struct Property*)realloc( - jalv->props, - sizeof(struct Property) * (++jalv->num_props)); - struct Property* prop = &jalv->props[jalv->num_props - 1]; - prop->key = symap_map(jalv->symap, (const char*)predicate->buf); - prop->value = serd_node_copy(object); - prop->datatype = serd_node_copy(object_datatype); - } else if (!strcmp((const char*)predicate->buf, "jalv:plugin")) { - const LilvPlugins* plugins = lilv_world_get_all_plugins(jalv->world); - LilvNode* plugin_uri = lilv_new_uri(jalv->world, - (const char*)object->buf); - jalv->plugin = lilv_plugins_get_by_uri(plugins, plugin_uri); - lilv_node_free(plugin_uri); - - jalv->num_ports = lilv_plugin_get_num_ports(jalv->plugin); - jalv->ports = calloc((size_t)jalv->num_ports, sizeof(struct Port)); - - jalv_create_ports(jalv); - } else if (!strcmp((const char*)predicate->buf, "lv2:symbol")) { - serd_node_free(&jalv->last_sym); - jalv->last_sym = serd_node_copy(object); - } else if (!strcmp((const char*)predicate->buf, "pset:value")) { - const char* sym = (const char*)jalv->last_sym.buf; - struct Port* port = jalv_port_by_symbol(jalv, sym); - if (port) { - port->control = atof((const char*)object->buf); // FIXME: Check type - } else { - fprintf(stderr, "error: Failed to find port `%s'\n", sym); - } - } else if (!strcmp((const char*)predicate->buf, "state:instanceState")) { - jalv->in_state = true; - } - - return SERD_SUCCESS; -} - -void -jalv_restore(Jalv* jalv, const char* dir) -{ - jalv->reader = serd_reader_new( - SERD_TURTLE, - jalv, NULL, - NULL, - NULL, - on_statement, - NULL); - - const size_t dir_len = strlen(dir); - const size_t state_uri_len = strlen("file:///state.ttl") + dir_len + 1; - char* state_uri = (char*)malloc(state_uri_len); - snprintf(state_uri, state_uri_len, "file://%s/state.ttl", dir); - - SerdStatus st = serd_reader_read_file(jalv->reader, USTR(state_uri)); - serd_node_free(&jalv->last_sym); - if (st) { - fprintf(stderr, "Error reading state from %s (%s)\n", - state_uri, serd_strerror(st)); - return; - } - - serd_reader_free(jalv->reader); - jalv->reader = NULL; - jalv->in_state = false; - - if (jalv->props) { - qsort(jalv->props, jalv->num_props, sizeof(struct Property), property_cmp); - } -} - -void -jalv_restore_instance(Jalv* jalv, const char* dir) -{ -#ifdef HAVE_LV2_STATE - const LV2_State_Interface* state_iface = (const LV2_State_Interface*) - lilv_instance_get_extension_data(jalv->instance, LV2_STATE_INTERFACE_URI); - - if (state_iface) { - state_iface->restore(lilv_instance_get_handle(jalv->instance), - retrieve_callback, - jalv, 0, NULL); - } -#endif // HAVE_LV2_STATE -} -- cgit v1.2.1