summaryrefslogtreecommitdiffstats
path: root/src/state.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/state.c')
-rw-r--r--src/state.c746
1 files changed, 383 insertions, 363 deletions
diff --git a/src/state.c b/src/state.c
index d34f761..041d901 100644
--- a/src/state.c
+++ b/src/state.c
@@ -19,7 +19,6 @@
#include "lilv/lilv.h"
#include "serd/serd.h"
-#include "sord/sord.h"
#include "sratom/sratom.h"
#include "zix/tree.h"
@@ -38,8 +37,6 @@
#include <stdlib.h>
#include <string.h>
-#define USTR(s) ((const uint8_t*)(s))
-
typedef struct {
void* value; ///< Value/Object
size_t size; ///< Size of value
@@ -127,28 +124,43 @@ path_rel_free(void* ptr)
free(ptr);
}
+static LV2_Atom*
+new_atom(const uint32_t size, const uint32_t type, const void* const value)
+{
+ LV2_Atom* atom = (LV2_Atom*)malloc(sizeof(LV2_Atom) + size);
+ atom->size = size;
+ atom->type = type;
+ memcpy(atom + 1, value, size);
+ return atom;
+}
+
static PortValue*
-append_port_value(LilvState* state,
- const char* port_symbol,
- const void* value,
- uint32_t size,
- uint32_t type)
+append_port_value(LilvState* state, const char* port_symbol, LV2_Atom* atom)
{
PortValue* pv = NULL;
- if (value) {
+ if (atom) {
state->values = (PortValue*)realloc(
state->values, (++state->n_values) * sizeof(PortValue));
- pv = &state->values[state->n_values - 1];
- pv->symbol = lilv_strdup(port_symbol);
- pv->atom = (LV2_Atom*)malloc(sizeof(LV2_Atom) + size);
- pv->atom->size = size;
- pv->atom->type = type;
- memcpy(pv->atom + 1, value, size);
+ pv = &state->values[state->n_values - 1];
+ pv->symbol = lilv_strdup(port_symbol);
+ pv->atom = atom;
}
return pv;
}
+static PortValue*
+append_port_value_raw(LilvState* state,
+ const char* port_symbol,
+ const void* value,
+ uint32_t size,
+ uint32_t type)
+{
+ return value
+ ? append_port_value(state, port_symbol, new_atom(size, type, value))
+ : NULL;
+}
+
static const char*
lilv_state_rel2abs(const LilvState* state, const char* path)
{
@@ -471,7 +483,7 @@ lilv_state_new_from_instance(const LilvPlugin* plugin,
uint32_t type = 0;
const char* sym = lilv_node_as_string(port->symbol);
const void* value = get_value(sym, user_data, &size, &type);
- append_port_value(state, sym, value, size, type);
+ append_port_value_raw(state, sym, value, size, type);
}
}
lilv_node_free(lv2_ControlPort);
@@ -498,9 +510,7 @@ lilv_state_new_from_instance(const LilvPlugin* plugin,
}
}
- if (state->values) {
- qsort(state->values, state->n_values, sizeof(PortValue), value_cmp);
- }
+ qsort(state->values, state->n_values, sizeof(PortValue), value_cmp);
free(sfeatures);
return state;
@@ -565,27 +575,62 @@ lilv_state_restore(const LilvState* state,
}
static void
-set_state_dir_from_model(LilvState* state, const SordNode* graph)
+set_state_dir_from_model(LilvState* state, const SerdNode* graph)
{
if (!state->dir && graph) {
- const char* uri = (const char*)sord_node_get_string(graph);
- char* path = lilv_file_uri_parse(uri, NULL);
+ const char* const uri = serd_node_string(graph);
+ char* const path = serd_parse_file_uri(uri, NULL);
state->dir = lilv_path_join(path, NULL);
- free(path);
+ serd_free(path);
}
assert(!state->dir || lilv_path_is_absolute(state->dir));
}
+static void
+add_object_to_properties(SerdModel* model,
+ const SerdEnv* env,
+ LV2_URID_Map* map,
+ const SerdStatement* s,
+ SratomLoader* loader,
+ LV2_URID atom_Path,
+ PropertyArray* props)
+{
+ const SerdNode* p = serd_statement_predicate(s);
+ const SerdNode* o = serd_statement_object(s);
+ const char* key = serd_node_string(p);
+
+ LV2_Atom* atom = sratom_from_model(loader, serd_env_base_uri(env), model, o);
+
+ Property prop = {malloc(atom->size),
+ atom->size,
+ map->map(map->handle, key),
+ atom->type,
+ LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE};
+
+ memcpy(prop.value, LV2_ATOM_BODY_CONST(atom), atom->size);
+ if (atom->type == atom_Path) {
+ prop.flags = LV2_STATE_IS_POD;
+ }
+
+ if (prop.value) {
+ props->props =
+ (Property*)realloc(props->props, (++props->n) * sizeof(Property));
+ props->props[props->n - 1] = prop;
+ }
+
+ sratom_free(atom);
+}
+
static LilvState*
new_state_from_model(LilvWorld* world,
LV2_URID_Map* map,
- SordModel* model,
- const SordNode* node,
+ SerdModel* model,
+ const SerdNode* node,
const char* dir)
{
// Check that we know at least something about this state subject
- if (!sord_ask(model, node, 0, 0, 0)) {
+ if (!serd_model_ask(model, node, 0, 0, 0)) {
return NULL;
}
@@ -593,118 +638,101 @@ new_state_from_model(LilvWorld* world,
LilvState* const state = (LilvState*)calloc(1, sizeof(LilvState));
state->dir = lilv_path_join(dir, NULL);
state->atom_Path = map->map(map->handle, LV2_ATOM__Path);
- state->uri = lilv_node_new_from_node(world, node);
+ state->uri = serd_node_copy(node);
// Get the plugin URI this state applies to
- SordIter* i = sord_search(model, node, world->uris.lv2_appliesTo, 0, 0);
+ SerdIter* i = serd_model_find(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);
+ const SerdStatement* s = serd_iter_get(i);
+ const SerdNode* object = serd_statement_object(s);
+ const SerdNode* graph = serd_statement_graph(s);
+ state->plugin_uri = serd_node_copy(object);
set_state_dir_from_model(state, graph);
- sord_iter_free(i);
- } else if (sord_ask(
+ serd_iter_free(i);
+ } else if (serd_model_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);
+ state->plugin_uri = serd_node_copy(node);
} else {
LILV_ERRORF("State %s missing lv2:appliesTo property\n",
- sord_node_get_string(node));
+ serd_node_string(node));
}
// Get the state label
- i = sord_search(model, node, world->uris.rdfs_label, NULL, NULL);
+ i = serd_model_find(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));
+ const SerdStatement* s = serd_iter_get(i);
+ const SerdNode* object = serd_statement_object(s);
+ const SerdNode* graph = serd_statement_graph(s);
+ state->label = lilv_strdup(serd_node_string(object));
set_state_dir_from_model(state, graph);
- sord_iter_free(i);
+ serd_iter_free(i);
+ }
+
+ SerdEnv* env = serd_env_new(SERD_EMPTY_STRING());
+ SratomLoader* loader = sratom_loader_new(world->world, map);
+ SerdBuffer buffer = {NULL, 0};
+
+ // Get metadata
+ SerdRange* meta = serd_model_range(model, node, 0, 0, 0);
+ FOREACH_MATCH (s, meta) {
+ const SerdNode* p = serd_statement_predicate(s);
+ const SerdNode* o = serd_statement_object(s);
+ if (!serd_node_equals(p, world->uris.state_state) &&
+ !serd_node_equals(p, world->uris.lv2_appliesTo) &&
+ !serd_node_equals(p, world->uris.lv2_port) &&
+ !serd_node_equals(p, world->uris.rdfs_label) &&
+ !serd_node_equals(p, world->uris.rdfs_seeAlso) &&
+ !(serd_node_equals(p, world->uris.rdf_a) &&
+ serd_node_equals(o, world->uris.pset_Preset))) {
+ add_object_to_properties(
+ model, env, map, s, loader, state->atom_Path, &state->metadata);
+ }
}
-
- 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);
+ serd_range_free(meta);
// 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);
+ SerdRange* ports = serd_model_range(model, node, world->uris.lv2_port, 0, 0);
+ FOREACH_MATCH (s, ports) {
+ const SerdNode* port = serd_statement_object(s);
+
+ const SerdNode* label =
+ serd_model_get(model, port, world->uris.rdfs_label, 0, 0);
+ const SerdNode* symbol =
+ serd_model_get(model, port, world->uris.lv2_symbol, 0, 0);
+ const SerdNode* value =
+ serd_model_get(model, port, world->uris.pset_value, 0, 0);
if (!value) {
- value = sord_get(model, port, world->uris.lv2_default, 0, 0);
+ value = serd_model_get(model, port, world->uris.lv2_default, 0, 0);
}
if (!symbol) {
- LILV_ERRORF("State `%s' port missing symbol.\n",
- sord_node_get_string(node));
+ LILV_ERRORF("State `%s' port missing symbol.\n", serd_node_string(node));
} else if (value) {
- chunk.len = 0;
- sratom_read(sratom, &forge, world->world, model, value);
- const LV2_Atom* atom = (const LV2_Atom*)chunk.buf;
-
append_port_value(state,
- (const char*)sord_node_get_string(symbol),
- LV2_ATOM_BODY_CONST(atom),
- atom->size,
- atom->type);
+ serd_node_string(symbol),
+ sratom_from_model(loader, NULL, model, value));
if (label) {
- lilv_state_set_label(state, (const char*)sord_node_get_string(label));
+ lilv_state_set_label(state, serd_node_string(label));
}
}
- sord_node_free(world->world, value);
- sord_node_free(world->world, symbol);
- sord_node_free(world->world, label);
}
- sord_iter_free(ports);
+ serd_range_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);
+ const SerdNode* state_node =
+ serd_model_get(model, node, world->uris.state_state, 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);
- const char* key = (const char*)sord_node_get_string(p);
-
- chunk.len = 0;
- lv2_atom_forge_set_sink(
- &forge, sratom_forge_sink, sratom_forge_deref, &chunk);
-
- sratom_read(sratom, &forge, world->world, model, o);
- const LV2_Atom* atom = (const 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, key);
- prop.type = atom->type;
- prop.size = atom->size;
- prop.value = malloc(atom->size);
- memcpy(prop.value, LV2_ATOM_BODY_CONST(atom), atom->size);
- if (atom->type == forge.Path) {
- prop.flags = LV2_STATE_IS_POD;
- }
-
- if (prop.value) {
- state->props.props = (Property*)realloc(
- state->props.props, (++state->props.n) * sizeof(Property));
- state->props.props[state->props.n - 1] = prop;
- }
+ SerdRange* props = serd_model_range(model, state_node, 0, 0, 0);
+ FOREACH_MATCH (s, props) {
+ add_object_to_properties(
+ model, env, map, s, loader, state->atom_Path, &state->props);
}
- sord_iter_free(props);
+ serd_range_free(props);
}
- sord_node_free(world->world, state_node);
- sord_node_free(world->world, statep);
- serd_free((void*)chunk.buf);
- sratom_free(sratom);
+ serd_free(buffer.buf);
+ sratom_loader_free(loader);
if (state->props.props) {
qsort(state->props.props, state->props.n, sizeof(Property), property_cmp);
@@ -727,7 +755,7 @@ lilv_state_new_from_world(LilvWorld* world,
return NULL;
}
- return new_state_from_model(world, map, world->model, node->node, NULL);
+ return new_state_from_model(world, map, world->model, node, NULL);
}
LilvState*
@@ -742,17 +770,22 @@ lilv_state_new_from_file(LilvWorld* world,
return NULL;
}
- uint8_t* abs_path = (uint8_t*)lilv_path_absolute(path);
- SerdNode node = serd_node_new_file_uri(abs_path, NULL, NULL, true);
- SerdEnv* env = serd_env_new(&node);
- SordModel* model = sord_new(world->world, SORD_SPO, false);
- SerdReader* reader = sord_new_reader(model, env, SERD_TURTLE, NULL);
+ char* abs_path = lilv_path_absolute(path);
+ SerdNode* node =
+ serd_new_file_uri(SERD_MEASURE_STRING(abs_path), SERD_EMPTY_STRING());
+ SerdEnv* env = serd_env_new(serd_node_string_view(node));
+ SerdModel* model = serd_model_new(world->world, SERD_INDEX_SPO);
+ SerdSink* inserter = serd_inserter_new(model, NULL);
+ SerdReader* reader = serd_reader_new(
+ world->world, SERD_TURTLE, 0, env, inserter, LILV_READER_STACK_SIZE);
- serd_reader_read_file(reader, node.buf);
+ SerdByteSource* source = serd_byte_source_new_filename(abs_path, 4096);
+ serd_reader_start(reader, source);
+ serd_reader_read_document(reader);
+ serd_reader_finish(reader);
+ serd_byte_source_free(source);
- SordNode* subject_node =
- (subject) ? subject->node
- : sord_node_from_serd_node(world->world, env, &node, NULL, NULL);
+ const SerdNode* subject_node = subject ? subject : node;
char* dirname = lilv_path_parent(path);
char* real_path = lilv_path_canonical(dirname);
@@ -763,10 +796,10 @@ lilv_state_new_from_file(LilvWorld* world,
free(real_path);
free(dirname);
- serd_node_free(&node);
+ serd_node_free(node);
free(abs_path);
serd_reader_free(reader);
- sord_free(model);
+ serd_model_free(model);
serd_env_free(env);
return state;
}
@@ -774,14 +807,16 @@ lilv_state_new_from_file(LilvWorld* world,
static void
set_prefixes(SerdEnv* env)
{
-#define SET_PSET(e, p, u) serd_env_set_prefix_from_strings(e, p, u)
- SET_PSET(env, USTR("atom"), USTR(LV2_ATOM_PREFIX));
- SET_PSET(env, USTR("lv2"), USTR(LV2_CORE_PREFIX));
- SET_PSET(env, USTR("pset"), USTR(LV2_PRESETS_PREFIX));
- SET_PSET(env, USTR("rdf"), USTR(LILV_NS_RDF));
- SET_PSET(env, USTR("rdfs"), USTR(LILV_NS_RDFS));
- SET_PSET(env, USTR("state"), USTR(LV2_STATE_PREFIX));
- SET_PSET(env, USTR("xsd"), USTR(LILV_NS_XSD));
+#define SET_PSET(e, p, u) \
+ serd_env_set_prefix(e, SERD_STATIC_STRING(p), SERD_STATIC_STRING(u))
+
+ SET_PSET(env, "atom", LV2_ATOM_PREFIX);
+ SET_PSET(env, "lv2", LV2_CORE_PREFIX);
+ SET_PSET(env, "pset", LV2_PRESETS_PREFIX);
+ SET_PSET(env, "rdf", LILV_NS_RDF);
+ SET_PSET(env, "rdfs", LILV_NS_RDFS);
+ SET_PSET(env, "state", LV2_STATE_PREFIX);
+ SET_PSET(env, "xsd", LILV_NS_XSD);
}
LilvState*
@@ -791,47 +826,43 @@ lilv_state_new_from_string(LilvWorld* world, LV2_URID_Map* map, const char* 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);
+ SerdEnv* env = serd_env_new(SERD_EMPTY_STRING());
+ SerdModel* model =
+ serd_model_new(world->world, SERD_INDEX_SPO | SERD_INDEX_OPS);
+ SerdSink* inserter = serd_inserter_new(model, NULL);
+ SerdReader* reader = serd_reader_new(
+ world->world, SERD_TURTLE, 0, env, inserter, LILV_READER_STACK_SIZE);
+ SerdByteSource* source = serd_byte_source_new_string(str, NULL);
set_prefixes(env);
- serd_reader_read_string(reader, USTR(str));
+ serd_reader_start(reader, source);
+ serd_reader_read_document(reader);
- SordNode* o = sord_new_uri(world->world, USTR(LV2_PRESETS__Preset));
- SordNode* s = sord_get(model, NULL, world->uris.rdf_a, o, NULL);
+ SerdNode* o = serd_new_uri(SERD_STATIC_STRING(LV2_PRESETS__Preset));
+ const SerdNode* s = serd_model_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_node_free(o);
+ serd_byte_source_free(source);
serd_reader_free(reader);
- sord_free(model);
+ serd_model_free(model);
serd_env_free(env);
return state;
}
static SerdWriter*
-ttl_writer(SerdSink sink, void* stream, const SerdNode* base, SerdEnv** new_env)
+ttl_writer(SerdWorld* world,
+ SerdByteSink* const sink,
+ const SerdNode* base,
+ SerdEnv** new_env)
{
- SerdURI base_uri = SERD_URI_NULL;
- if (base && base->buf) {
- serd_uri_parse(base->buf, &base_uri);
- }
-
- SerdEnv* env = *new_env ? *new_env : serd_env_new(base);
+ SerdEnv* env =
+ *new_env ? *new_env : serd_env_new(serd_node_string_view(base));
set_prefixes(env);
- SerdWriter* writer =
- serd_writer_new(SERD_TURTLE,
- (SerdStyle)(SERD_STYLE_RESOLVED | SERD_STYLE_ABBREVIATED |
- SERD_STYLE_CURIED),
- env,
- &base_uri,
- sink,
- stream);
+ SerdWriter* writer = serd_writer_new(world, SERD_TURTLE, 0, env, sink);
if (!*new_env) {
*new_env = env;
@@ -841,13 +872,16 @@ ttl_writer(SerdSink sink, void* stream, const SerdNode* base, SerdEnv** new_env)
}
static SerdWriter*
-ttl_file_writer(FILE* fd, const SerdNode* node, SerdEnv** env)
+ttl_file_writer(SerdWorld* world, FILE* fd, const SerdNode* node, SerdEnv** env)
{
- SerdWriter* writer = ttl_writer(serd_file_sink, fd, node, env);
+ SerdByteSink* const sink =
+ serd_byte_sink_new_function((SerdWriteFunc)fwrite, fd, 1);
+
+ SerdWriter* const writer = ttl_writer(world, sink, node, env);
fseek(fd, 0, SEEK_END);
if (ftell(fd) == 0) {
- serd_env_foreach(*env, (SerdPrefixSink)serd_writer_set_prefix, writer);
+ serd_env_write_prefixes(*env, serd_writer_sink(writer));
} else {
fprintf(fd, "\n");
}
@@ -856,47 +890,27 @@ ttl_file_writer(FILE* fd, const SerdNode* node, SerdEnv** env)
}
static void
-add_to_model(SordWorld* world,
- SerdEnv* env,
- SordModel* model,
- const SerdNode s,
- const SerdNode p,
- const SerdNode o)
+remove_manifest_entry(SerdModel* model, const char* subject)
{
- SordNode* ss = sord_node_from_serd_node(world, env, &s, NULL, NULL);
- SordNode* sp = sord_node_from_serd_node(world, env, &p, NULL, NULL);
- SordNode* so = sord_node_from_serd_node(world, env, &o, NULL, NULL);
+ SerdNode* const s = serd_new_uri(SERD_MEASURE_STRING(subject));
+ SerdRange* const r = serd_model_range(model, s, NULL, NULL, NULL);
- SordQuad quad = {ss, sp, so, NULL};
- sord_add(model, quad);
-
- sord_node_free(world, ss);
- sord_node_free(world, sp);
- sord_node_free(world, so);
-}
+ serd_model_erase_range(model, r);
-static void
-remove_manifest_entry(SordWorld* world, SordModel* model, const char* subject)
-{
- SordNode* s = sord_new_uri(world, USTR(subject));
- SordIter* i = sord_search(model, s, NULL, NULL, NULL);
- while (!sord_iter_end(i)) {
- sord_erase(model, i);
- }
- sord_iter_free(i);
- sord_node_free(world, s);
+ serd_range_free(r);
+ serd_node_free(s);
}
static int
write_manifest(LilvWorld* world,
SerdEnv* env,
- SordModel* model,
+ SerdModel* model,
const SerdNode* file_uri)
{
- (void)world;
+ const char* file_uri_str = serd_node_string(file_uri);
+ char* const path = serd_parse_file_uri(file_uri_str, NULL);
+ FILE* const wfd = fopen(path, "w");
- char* const path = (char*)serd_file_uri_parse(file_uri->buf, NULL);
- FILE* const wfd = fopen(path, "w");
if (!wfd) {
LILV_ERRORF("Failed to open %s for writing (%s)\n", path, strerror(errno));
@@ -904,8 +918,10 @@ write_manifest(LilvWorld* world,
return 1;
}
- SerdWriter* writer = ttl_file_writer(wfd, file_uri, &env);
- sord_write(model, writer, NULL);
+ SerdWriter* writer = ttl_file_writer(world->world, wfd, file_uri, &env);
+ SerdRange* all = serd_model_all(model, SERD_ORDER_SPO);
+ serd_range_serialise(all, serd_writer_sink(writer), 0);
+ serd_range_free(all);
serd_writer_free(writer);
fclose(wfd);
serd_free(path);
@@ -919,90 +935,73 @@ add_state_to_manifest(LilvWorld* lworld,
const char* state_uri,
const char* state_path)
{
- SordWorld* world = lworld->world;
- SerdNode manifest = serd_node_new_file_uri(USTR(manifest_path), 0, 0, 1);
- SerdNode file = serd_node_new_file_uri(USTR(state_path), 0, 0, 1);
- SerdEnv* env = serd_env_new(&manifest);
- SordModel* model = sord_new(world, SORD_SPO, false);
+ static const SerdStringView empty = {"", 0};
+
+ const SerdStringView manifest_path_view = SERD_MEASURE_STRING(manifest_path);
+ const SerdStringView state_path_view = SERD_MEASURE_STRING(state_path);
+
+ SerdWorld* world = lworld->world;
+ SerdNode* manifest = serd_new_file_uri(manifest_path_view, empty);
+ SerdNode* file = serd_new_file_uri(state_path_view, empty);
+ SerdEnv* env = serd_env_new(serd_node_string_view(manifest));
+ SerdModel* model = serd_model_new(world, SERD_INDEX_SPO | SERD_INDEX_OPS);
+ SerdSink* inserter = serd_inserter_new(model, NULL);
- if (lilv_path_exists(manifest_path)) {
+ FILE* const rfd = fopen(manifest_path, "r");
+ if (rfd) {
// Read manifest into model
- SerdReader* reader = sord_new_reader(model, env, SERD_TURTLE, NULL);
- SerdStatus st = serd_reader_read_file(reader, manifest.buf);
- if (st) {
+ SerdReader* reader = serd_reader_new(
+ world, SERD_TURTLE, 0, env, inserter, LILV_READER_STACK_SIZE);
+
+ SerdByteSource* source =
+ serd_byte_source_new_function((SerdReadFunc)fread,
+ (SerdStreamErrorFunc)ferror,
+ rfd,
+ manifest,
+ PAGE_SIZE);
+
+ SerdStatus st = SERD_SUCCESS;
+ if ((st = serd_reader_start(reader, source)) ||
+ (st = serd_reader_read_document(reader))) {
LILV_WARNF("Failed to read manifest (%s)\n", serd_strerror(st));
+ return st;
}
+
+ serd_byte_source_free(source);
serd_reader_free(reader);
+ fclose(rfd);
}
// Choose state URI (use file URI if not given)
if (!state_uri) {
- state_uri = (const char*)file.buf;
+ state_uri = serd_node_string(file);
}
// Remove any existing manifest entries for this state
- remove_manifest_entry(world, model, state_uri);
+ remove_manifest_entry(model, state_uri);
// Add manifest entry for this state to model
- SerdNode s = serd_node_from_string(SERD_URI, USTR(state_uri));
-
- // <state> a pset:Preset
- add_to_model(world,
- env,
- model,
- s,
- serd_node_from_string(SERD_URI, USTR(LILV_NS_RDF "type")),
- serd_node_from_string(SERD_URI, USTR(LV2_PRESETS__Preset)));
+ SerdNode* s = serd_new_uri(SERD_MEASURE_STRING(state_uri));
// <state> a pset:Preset
- add_to_model(world,
- env,
- model,
- s,
- serd_node_from_string(SERD_URI, USTR(LILV_NS_RDF "type")),
- serd_node_from_string(SERD_URI, USTR(LV2_PRESETS__Preset)));
+ serd_model_add(model, s, lworld->uris.rdf_a, lworld->uris.pset_Preset, NULL);
// <state> rdfs:seeAlso <file>
- add_to_model(world,
- env,
- model,
- s,
- serd_node_from_string(SERD_URI, USTR(LILV_NS_RDFS "seeAlso")),
- file);
+ serd_model_add(model, s, lworld->uris.rdfs_seeAlso, file, NULL);
// <state> lv2:appliesTo <plugin>
- add_to_model(
- world,
- env,
- model,
- s,
- serd_node_from_string(SERD_URI, USTR(LV2_CORE__appliesTo)),
- serd_node_from_string(SERD_URI, USTR(lilv_node_as_string(plugin_uri))));
-
- /* Re-open manifest for locked writing. We need to do this because it may
- need to be truncated, and the file can only be open once on Windows. */
-
- FILE* wfd = fopen(manifest_path, "wb");
- int r = 0;
- if (!wfd) {
- LILV_ERRORF(
- "Failed to open %s for writing (%s)\n", manifest_path, strerror(errno));
- r = 1;
- }
+ serd_model_add(model, s, lworld->uris.lv2_appliesTo, plugin_uri, NULL);
- SerdWriter* writer = ttl_file_writer(wfd, &manifest, &env);
- lilv_flock(wfd, true, true);
- sord_write(model, writer, NULL);
- lilv_flock(wfd, false, true);
- serd_writer_free(writer);
- fclose(wfd);
+ // Write manifest model to file
+ write_manifest(lworld, env, model, manifest);
- sord_free(model);
- serd_node_free(&file);
- serd_node_free(&manifest);
+ serd_node_free(s);
+ serd_model_free(model);
+ serd_node_free(file);
+ serd_node_free(manifest);
serd_env_free(env);
- return r;
+ return 0;
}
static bool
@@ -1037,138 +1036,148 @@ maybe_symlink(const char* oldpath, const char* newpath)
static void
write_property_array(const LilvState* state,
const PropertyArray* array,
- Sratom* sratom,
- uint32_t flags,
+ const SerdEnv* env,
+ SratomDumper* dumper,
+ const SerdSink* sink,
const SerdNode* subject,
LV2_URID_Unmap* unmap,
const char* dir)
{
+ // FIXME: error handling
for (uint32_t i = 0; i < array->n; ++i) {
Property* prop = &array->props[i];
const char* key = unmap->unmap(unmap->handle, prop->key);
- const SerdNode p = serd_node_from_string(SERD_URI, USTR(key));
+ SerdNode* p = serd_new_uri(SERD_MEASURE_STRING(key));
if (prop->type == state->atom_Path && !dir) {
const char* path = (const char*)prop->value;
const char* abs_path = lilv_state_rel2abs(state, path);
LILV_WARNF("Writing absolute path %s\n", abs_path);
- sratom_write(sratom,
- unmap,
- flags,
- subject,
- &p,
- prop->type,
- strlen(abs_path) + 1,
- abs_path);
+ sratom_dump(dumper,
+ env,
+ sink,
+ subject,
+ p,
+ prop->type,
+ strlen(abs_path) + 1,
+ abs_path,
+ 0);
} else if (prop->flags & LV2_STATE_IS_POD ||
prop->type == state->atom_Path) {
- sratom_write(
- sratom, unmap, flags, subject, &p, prop->type, prop->size, prop->value);
+ sratom_dump(
+ dumper, env, sink, subject, p, prop->type, prop->size, prop->value, 0);
} else {
LILV_WARNF("Lost non-POD property <%s> on save\n", key);
}
+ serd_node_free(p);
}
}
-static int
+static SerdStatus
lilv_state_write(LilvWorld* world,
LV2_URID_Map* map,
LV2_URID_Unmap* unmap,
const LilvState* state,
+ const SerdEnv* env,
SerdWriter* writer,
const char* uri,
const char* dir)
{
- (void)world;
+ const SerdSink* sink = serd_writer_sink(writer);
+ const SerdNode* plugin_uri = state->plugin_uri;
+ SerdNode* subject =
+ serd_new_uri(uri ? SERD_MEASURE_STRING(uri) : SERD_EMPTY_STRING());
- 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 : ""));
+ SerdStatus st = SERD_SUCCESS;
// <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);
+ if ((st = serd_sink_write(
+ sink, 0, subject, world->uris.rdf_a, world->uris.pset_Preset, NULL))) {
+ return st;
+ }
// <subject> lv2:appliesTo <http://example.org/plugin>
- serd_writer_write_statement(
- writer, 0, NULL, &subject, &lv2_appliesTo, plugin_uri, NULL, NULL);
+ if ((st = serd_sink_write(
+ sink, 0, subject, world->uris.lv2_appliesTo, plugin_uri, NULL))) {
+ return st;
+ }
// <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);
- }
+ SerdNode* label = serd_new_string(SERD_MEASURE_STRING(state->label));
+ if ((st = serd_sink_write(
+ sink, 0, subject, world->uris.rdfs_label, label, NULL))) {
+ return st;
+ }
- SerdEnv* env = serd_writer_get_env(writer);
- const SerdNode* base = serd_env_get_base_uri(env, NULL);
+ serd_node_free(label);
+ }
- Sratom* sratom = sratom_new(map);
- sratom_set_sink(sratom,
- (const char*)base->buf,
- (SerdStatementSink)serd_writer_write_statement,
- (SerdEndSink)serd_writer_end_anon,
- writer);
+ SratomDumper* dumper = sratom_dumper_new(world->world, map, unmap);
- // Write metadata
- sratom_set_pretty_numbers(sratom, false); // Use precise types
+ // Write metadata (with precise types)
write_property_array(
- state, &state->metadata, sratom, 0, &subject, unmap, dir);
+ state, &state->metadata, env, dumper, sink, subject, unmap, dir);
- // Write port values
- sratom_set_pretty_numbers(sratom, true); // Use pretty numbers
+ // Write port values (with pretty numbers)
for (uint32_t i = 0; i < state->n_values; ++i) {
PortValue* const value = &state->values[i];
-
- const SerdNode port =
- serd_node_from_string(SERD_BLANK, USTR(value->symbol));
+ SerdNode* port = serd_new_blank(SERD_MEASURE_STRING(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);
+ if ((st = serd_sink_write(
+ sink, SERD_ANON_O, subject, world->uris.lv2_port, port, NULL))) {
+ return st;
+ }
// _: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);
+ SerdNode* symbol = serd_new_string(SERD_MEASURE_STRING(value->symbol));
+ if ((st = serd_sink_write(
+ sink, 0, port, world->uris.lv2_symbol, symbol, NULL))) {
+ return st;
+ }
- // _: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->atom->type,
- value->atom->size,
- value->atom + 1);
+ serd_node_free(symbol);
- serd_writer_end_anon(writer, &port);
+ // _:symbol pset:value value
+ // FIXME: error handling
+ sratom_dump_atom(dumper,
+ env,
+ sink,
+ port,
+ world->uris.pset_value,
+ value->atom,
+ 0); // SRATOM_PRETTY_NUMBERS);
+
+ if ((st = serd_sink_write_end(sink, port))) {
+ return st;
+ }
}
- // Write properties
- const SerdNode body = serd_node_from_string(SERD_BLANK, USTR("body"));
+ // <> state:state _:body
+
+ SerdNode* body = serd_new_blank(SERD_STATIC_STRING("body"));
if (state->props.n > 0) {
- p = serd_node_from_string(SERD_URI, USTR(LV2_STATE__state));
- serd_writer_write_statement(
- writer, SERD_ANON_O_BEGIN, NULL, &subject, &p, &body, NULL, NULL);
+ if ((st = serd_sink_write(
+ sink, SERD_ANON_O, subject, world->uris.state_state, body, NULL))) {
+ return st;
+ }
}
- sratom_set_pretty_numbers(sratom, false); // Use precise types
+
+ // _:body key value ...
write_property_array(
- state, &state->props, sratom, SERD_ANON_CONT, &body, unmap, dir);
+ state, &state->props, env, dumper, sink, body, unmap, dir);
+ // End state body
if (state->props.n > 0) {
- serd_writer_end_anon(writer, &body);
+ if ((st = serd_sink_write_end(sink, body))) {
+ return st;
+ }
}
- sratom_free(sratom);
- return 0;
+ serd_node_free(body);
+ sratom_dumper_free(dumper);
+ return SERD_SUCCESS;
}
static void
@@ -1229,7 +1238,7 @@ lilv_state_save(LilvWorld* world,
return 1;
}
- char* abs_dir = real_dir(dir);
+ char* abs_dir = lilv_path_canonical(dir);
char* const path = lilv_path_join(abs_dir, filename);
FILE* fd = fopen(path, "w");
if (!fd) {
@@ -1243,36 +1252,34 @@ lilv_state_save(LilvWorld* world,
lilv_state_make_links(state, abs_dir);
// Write state to Turtle file
- SerdNode file = serd_node_new_file_uri(USTR(path), NULL, NULL, true);
- SerdNode node = uri ? serd_node_from_string(SERD_URI, USTR(uri)) : file;
- SerdEnv* env = NULL;
- SerdWriter* ttl = ttl_file_writer(fd, &file, &env);
- int ret =
- lilv_state_write(world, map, unmap, state, ttl, (const char*)node.buf, dir);
+ SerdNode* file =
+ serd_new_file_uri(SERD_MEASURE_STRING(path), SERD_EMPTY_STRING());
+ SerdNode* node =
+ uri ? serd_new_uri(SERD_MEASURE_STRING(uri)) : serd_node_copy(file);
+ SerdEnv* env = NULL;
+ SerdWriter* ttl = ttl_file_writer(world->world, fd, file, &env);
+ SerdStatus st = lilv_state_write(
+ world, map, unmap, state, env, ttl, serd_node_string(node), dir);
// Set saved dir and uri (FIXME: const violation)
free(state->dir);
lilv_node_free(state->uri);
- ((LilvState*)state)->dir = lilv_strdup(abs_dir);
- ((LilvState*)state)->uri = lilv_new_uri(world, (const char*)node.buf);
+ ((LilvState*)state)->dir = lilv_path_join(abs_dir, NULL);
+ ((LilvState*)state)->uri = node;
- serd_node_free(&file);
+ serd_node_free(file);
serd_writer_free(ttl);
serd_env_free(env);
fclose(fd);
// Add entry to manifest
- if (!ret) {
- char* const manifest = lilv_path_join(abs_dir, "manifest.ttl");
-
- ret = add_state_to_manifest(world, state->plugin_uri, manifest, uri, path);
-
- free(manifest);
- }
+ char* const manifest = lilv_path_join(abs_dir, "manifest.ttl");
+ add_state_to_manifest(world, state->plugin_uri, manifest, uri, path);
+ free(manifest);
free(abs_dir);
free(path);
- return ret;
+ return st;
}
char*
@@ -1288,16 +1295,18 @@ lilv_state_to_string(LilvWorld* world,
return NULL;
}
- SerdChunk chunk = {NULL, 0};
- SerdEnv* env = NULL;
- SerdNode base = serd_node_from_string(SERD_URI, USTR(base_uri));
- SerdWriter* writer = ttl_writer(serd_chunk_sink, &chunk, &base, &env);
+ SerdBuffer buffer = {NULL, 0};
+ SerdEnv* env = NULL;
+ SerdNode* base = serd_new_uri(SERD_MEASURE_STRING(base_uri));
+ SerdByteSink* sink = serd_byte_sink_new_buffer(&buffer);
+ SerdWriter* writer = ttl_writer(world->world, sink, base, &env);
- lilv_state_write(world, map, unmap, state, writer, uri, NULL);
+ lilv_state_write(world, map, unmap, state, env, writer, uri, NULL);
serd_writer_free(writer);
+ serd_byte_sink_free(sink);
serd_env_free(env);
- char* str = (char*)serd_chunk_sink_finish(&chunk);
+ char* str = serd_buffer_sink_finish(&buffer);
char* result = lilv_strdup(str);
serd_free(str);
return result;
@@ -1332,45 +1341,54 @@ lilv_state_delete(LilvWorld* world, const LilvState* state)
}
LilvNode* bundle = lilv_new_file_uri(world, NULL, state->dir);
- LilvNode* manifest = lilv_world_get_manifest_uri(world, bundle);
+ LilvNode* manifest = lilv_world_get_manifest_node(world, bundle);
char* manifest_path = get_canonical_path(manifest);
const bool has_manifest = lilv_path_exists(manifest_path);
- SordModel* model = sord_new(world->world, SORD_SPO, false);
+ SerdModel* model = serd_model_new(world->world, SERD_INDEX_SPO);
if (has_manifest) {
// Read manifest into temporary local model
- SerdEnv* env = serd_env_new(sord_node_to_serd_node(manifest->node));
- SerdReader* ttl = sord_new_reader(model, env, SERD_TURTLE, NULL);
- serd_reader_read_file(ttl, USTR(manifest_path));
- serd_reader_free(ttl);
+ SerdEnv* env = serd_env_new(serd_node_string_view(manifest));
+ SerdSink* inserter = serd_inserter_new(model, NULL);
+ SerdReader* reader = serd_reader_new(
+ world->world, SERD_TURTLE, 0, env, inserter, LILV_READER_STACK_SIZE);
+
+ SerdByteSource* source =
+ serd_byte_source_new_filename(manifest_path, PAGE_SIZE);
+
+ serd_reader_start(reader, source);
+ serd_reader_read_document(reader);
+ serd_byte_source_free(source);
+ serd_reader_free(reader);
serd_env_free(env);
}
if (state->uri) {
- SordNode* file =
- sord_get(model, state->uri->node, world->uris.rdfs_seeAlso, NULL, NULL);
+ const SerdNode* file =
+ serd_model_get(model, state->uri, world->uris.rdfs_seeAlso, NULL, NULL);
if (file) {
+ char* const path = serd_parse_file_uri(serd_node_string(file), NULL);
+ char* const real_path = lilv_path_canonical(path);
+
// Remove state file
- const uint8_t* uri = sord_node_get_string(file);
- char* path = (char*)serd_file_uri_parse(uri, NULL);
- char* real_path = lilv_path_canonical(path);
- if (path) {
+ if (real_path) {
try_unlink(state->dir, real_path);
}
+
serd_free(real_path);
serd_free(path);
}
// Remove any existing manifest entries for this state
const char* state_uri_str = lilv_node_as_string(state->uri);
- remove_manifest_entry(world->world, model, state_uri_str);
- remove_manifest_entry(world->world, world->model, state_uri_str);
+ remove_manifest_entry(model, state_uri_str);
+ remove_manifest_entry(world->model, state_uri_str);
}
// Drop bundle from model
lilv_world_unload_bundle(world, bundle);
- if (sord_num_quads(model) == 0) {
+ if (serd_model_size(model) == 0) {
// Manifest is empty, attempt to remove bundle entirely
if (has_manifest) {
try_unlink(state->dir, manifest_path);
@@ -1403,15 +1421,17 @@ lilv_state_delete(LilvWorld* world, const LilvState* state)
}
} else {
// Still something in the manifest, update and reload bundle
- const SerdNode* manifest_node = sord_node_to_serd_node(manifest->node);
- SerdEnv* env = serd_env_new(manifest_node);
+ SerdEnv* env = serd_env_new(serd_node_string_view(manifest));
+
+ if (write_manifest(world, env, model, manifest)) {
+ return 1;
+ }
- write_manifest(world, env, model, manifest_node);
lilv_world_load_bundle(world, bundle);
serd_env_free(env);
}
- sord_free(model);
+ serd_model_free(model);
lilv_free(manifest_path);
lilv_node_free(manifest);
lilv_node_free(bundle);