summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/AtomWriter.cpp15
-rw-r--r--src/Configuration.cpp106
-rw-r--r--src/FilePath.cpp2
-rw-r--r--src/Forge.cpp2
-rw-r--r--src/Parser.cpp355
-rw-r--r--src/Serialiser.cpp358
-rw-r--r--src/SocketReader.cpp119
-rw-r--r--src/SocketWriter.cpp7
-rw-r--r--src/StreamWriter.cpp9
-rw-r--r--src/TurtleWriter.cpp93
-rw-r--r--src/URI.cpp91
-rw-r--r--src/URIs.cpp13
-rw-r--r--src/World.cpp32
-rw-r--r--src/client/ClientStore.cpp1
-rw-r--r--src/client/PluginModel.cpp13
-rw-r--r--src/client/PluginUI.cpp6
-rw-r--r--src/client/wscript2
-rw-r--r--src/gui/App.cpp13
-rw-r--r--src/gui/ConnectWindow.cpp2
-rw-r--r--src/gui/GraphCanvas.cpp4
-rw-r--r--src/gui/LoadPluginWindow.cpp2
-rw-r--r--src/gui/NodeMenu.cpp4
-rw-r--r--src/gui/NodeMenu.hpp2
-rw-r--r--src/gui/Port.cpp4
-rw-r--r--src/gui/PropertiesWindow.cpp3
-rw-r--r--src/gui/ingen_gui_lv2.cpp1
-rw-r--r--src/gui/wscript7
-rw-r--r--src/ingen/ingen.cpp29
-rw-r--r--src/server/Engine.cpp59
-rw-r--r--src/server/Event.hpp2
-rw-r--r--src/server/LV2Plugin.cpp2
-rw-r--r--src/server/PreProcessor.cpp2
-rw-r--r--src/server/SocketListener.cpp4
-rw-r--r--src/server/SocketServer.hpp6
-rw-r--r--src/server/UndoStack.cpp153
-rw-r--r--src/server/UndoStack.hpp22
-rw-r--r--src/server/events/Copy.cpp5
-rw-r--r--src/server/events/Delta.cpp8
-rw-r--r--src/server/ingen_lv2.cpp24
-rw-r--r--src/server/wscript2
-rw-r--r--src/wscript2
41 files changed, 697 insertions, 889 deletions
diff --git a/src/AtomWriter.cpp b/src/AtomWriter.cpp
index 27f224fc..e2c0f252 100644
--- a/src/AtomWriter.cpp
+++ b/src/AtomWriter.cpp
@@ -74,11 +74,14 @@
namespace ingen {
-AtomWriter::AtomWriter(URIMap& map, URIs& uris, AtomSink& sink)
- : _map(map)
- , _uris(uris)
- , _sink(sink)
- , _forge(map.urid_map_feature()->urid_map)
+AtomWriter::AtomWriter(serd::World& world,
+ URIMap& map,
+ URIs& uris,
+ AtomSink& sink)
+ : _map(map)
+ , _uris(uris)
+ , _sink(sink)
+ , _forge(world, map.urid_map_feature()->urid_map)
{
}
@@ -135,7 +138,7 @@ AtomWriter::operator()(const BundleEnd& message)
void
AtomWriter::forge_uri(const URI& uri)
{
- if (serd_uri_string_has_scheme((const uint8_t*)uri.c_str())) {
+ if (serd_uri_string_has_scheme(uri.c_str())) {
lv2_atom_forge_urid(&_forge, _map.map_uri(uri.c_str()));
} else {
lv2_atom_forge_uri(&_forge, uri.c_str(), uri.length());
diff --git a/src/Configuration.cpp b/src/Configuration.cpp
index 5178e97a..611d949b 100644
--- a/src/Configuration.cpp
+++ b/src/Configuration.cpp
@@ -22,10 +22,8 @@
#include "ingen/ingen.h"
#include "ingen/runtime_paths.hpp"
#include "lv2/urid/urid.h"
-#include "serd/serd.h"
-#include "sord/sord.h"
-#include "sord/sordmm.hpp"
-#include "sratom/sratom.h"
+#include "serd/serd.hpp"
+#include "sratom/sratom.hpp"
#include <algorithm>
#include <cassert>
@@ -33,6 +31,7 @@
#include <cstdint>
#include <cstdlib>
#include <cstring>
+#include <fstream>
#include <memory>
#include <thread>
#include <utility>
@@ -226,43 +225,40 @@ Configuration::parse(int argc, char** argv)
}
bool
-Configuration::load(const FilePath& path)
+Configuration::load(serd::World& world, const FilePath& path)
{
if (!filesystem::exists(path)) {
return false;
}
- SerdNode node = serd_node_new_file_uri(
- (const uint8_t*)path.c_str(), nullptr, nullptr, true);
- const std::string uri((const char*)node.buf);
-
- Sord::World world;
- Sord::Model model(world, uri, SORD_SPO, false);
- SerdEnv* env = serd_env_new(&node);
- model.load_file(env, SERD_TURTLE, uri, uri);
-
- Sord::Node nodemm(world, Sord::Node::URI, (const char*)node.buf);
- Sord::Node nil;
- for (Sord::Iter i = model.find(nodemm, nil, nil); !i.end(); ++i) {
- const Sord::Node& pred = i.get_predicate();
- const Sord::Node& obj = i.get_object();
- if (pred.to_string().substr(0, sizeof(INGEN_NS) - 1) == INGEN_NS) {
- const std::string key = pred.to_string().substr(sizeof(INGEN_NS) - 1);
- const Keys::iterator k = _keys.find(key);
- if (k != _keys.end() && obj.type() == Sord::Node::LITERAL) {
+ const serd::Node uri(serd::make_file_uri(path.c_str(), nullptr));
+ serd::Env env(uri);
+ serd::Model model(world, serd::ModelFlag::index_SPO);
+ serd::Inserter inserter(model, env);
+ serd::Reader reader(world, serd::Syntax::Turtle, {}, inserter.sink(), 4096);
+ reader.start_file(uri);
+ reader.read_document();
+ reader.finish();
+
+ for (const auto& s : model.range(uri, {}, {})) {
+ const auto& pred = s.predicate();
+ const auto& obj = s.object();
+ if (pred.str().substr(0, sizeof(INGEN_NS) - 1) == INGEN_NS) {
+ const auto key = pred.str().substr(sizeof(INGEN_NS) - 1);
+ const Keys::iterator k = _keys.find(key.str());
+ if (k != _keys.end() && obj.type() == serd::NodeType::literal) {
set_value_from_string(_options.find(k->second)->second,
- obj.to_string());
+ std::string(obj));
}
}
}
- serd_node_free(&node);
- serd_env_free(env);
return true;
}
FilePath
-Configuration::save(URIMap& uri_map,
+Configuration::save(serd::World& world,
+ URIMap& uri_map,
const std::string& app,
const FilePath& filename,
unsigned scopes)
@@ -281,41 +277,33 @@ Configuration::save(URIMap& uri_map,
}
// Attempt to open file for writing
- std::unique_ptr<FILE, decltype(&fclose)> file{fopen(path.c_str(), "w"),
- &fclose};
- if (!file) {
+ std::ofstream file(path);
+ if (!file.good()) {
throw FileError(fmt("Failed to open file %1% (%2%)",
path, strerror(errno)));
}
// Use the file's URI as the base URI
- SerdURI base_uri;
- SerdNode base = serd_node_new_file_uri(
- (const uint8_t*)path.c_str(), nullptr, &base_uri, true);
+ serd::Node base = serd::make_file_uri(path.c_str());
// Create environment with ingen prefix
- SerdEnv* env = serd_env_new(&base);
- serd_env_set_prefix_from_strings(
- env, (const uint8_t*)"ingen", (const uint8_t*)INGEN_NS);
+ serd::Env env(base);
+ env.set_prefix("ingen", INGEN_NS);
// Create Turtle writer
- SerdWriter* writer = serd_writer_new(
- SERD_TURTLE,
- (SerdStyle)(SERD_STYLE_RESOLVED|SERD_STYLE_ABBREVIATED),
- env,
- &base_uri,
- serd_file_sink,
- file.get());
+ serd::Writer writer(world,
+ serd::Syntax::Turtle,
+ {},
+ env,
+ file);
// Write a prefix directive for each prefix in the environment
- serd_env_foreach(env, (SerdPrefixSink)serd_writer_set_prefix, writer);
+ env.write_prefixes(writer.sink());
// Create an atom serialiser and connect it to the Turtle writer
- Sratom* sratom = sratom_new(&uri_map.urid_map_feature()->urid_map);
- sratom_set_pretty_numbers(sratom, true);
- sratom_set_sink(sratom, (const char*)base.buf,
- (SerdStatementSink)serd_writer_write_statement, nullptr,
- writer);
+ sratom::Streamer streamer{world,
+ uri_map.urid_map_feature()->urid_map,
+ uri_map.urid_unmap_feature()->urid_unmap};
// Write a statement for each valid option
for (const auto& o : _options) {
@@ -327,35 +315,31 @@ Configuration::save(URIMap& uri_map,
}
const std::string key(std::string("ingen:") + o.second.key);
- SerdNode pred = serd_node_from_string(
- SERD_CURIE, (const uint8_t*)key.c_str());
- sratom_write(sratom, &uri_map.urid_unmap_feature()->urid_unmap, 0,
- &base, &pred, value.type(), value.size(), value.get_body());
+ const serd::Node pred = serd::make_curie(key);
+ streamer.write(
+ writer.sink(), base, pred, *value.atom(), sratom::Flag::pretty_numbers);
}
- sratom_free(sratom);
- serd_writer_free(writer);
- serd_env_free(env);
- serd_node_free(&base);
-
return path;
}
std::list<FilePath>
-Configuration::load_default(const std::string& app, const FilePath& filename)
+Configuration::load_default(serd::World& world,
+ const std::string& app,
+ const FilePath& filename)
{
std::list<FilePath> loaded;
const std::vector<FilePath> dirs = system_config_dirs();
for (const auto& d : dirs) {
const FilePath path = d / app / filename;
- if (load(path)) {
+ if (load(world, path)) {
loaded.push_back(path);
}
}
const FilePath path = user_config_dir() / app / filename;
- if (load(path)) {
+ if (load(world, path)) {
loaded.push_back(path);
}
diff --git a/src/FilePath.cpp b/src/FilePath.cpp
index d16c133c..33b1b937 100644
--- a/src/FilePath.cpp
+++ b/src/FilePath.cpp
@@ -89,7 +89,7 @@ FilePath::operator+=(value_type chr)
}
FilePath&
-FilePath::operator+=(boost::basic_string_view<value_type> sv)
+FilePath::operator+=(serd::StringView sv)
{
_str.append(sv.data(), sv.size());
return *this;
diff --git a/src/Forge.cpp b/src/Forge.cpp
index cc1b12c8..d9390e08 100644
--- a/src/Forge.cpp
+++ b/src/Forge.cpp
@@ -35,7 +35,7 @@ Forge::Forge(URIMap& map)
Atom
Forge::make_urid(const ingen::URI& u)
{
- const LV2_URID urid = _map.map_uri(u.string());
+ const LV2_URID urid = _map.map_uri(u.c_str());
return Atom(sizeof(int32_t), URID, &urid);
}
diff --git a/src/Parser.cpp b/src/Parser.cpp
index 5cc1dedd..936f1b9f 100644
--- a/src/Parser.cpp
+++ b/src/Parser.cpp
@@ -16,6 +16,9 @@
#include "ingen/Parser.hpp"
+#include <boost/optional/optional.hpp>
+#include <boost/optional/optional_io.hpp>
+
#include "ingen/Atom.hpp"
#include "ingen/AtomForge.hpp"
#include "ingen/Forge.hpp"
@@ -35,9 +38,7 @@
#include "lv2/urid/urid.h"
#include "raul/Path.hpp"
#include "raul/Symbol.hpp"
-#include "serd/serd.h"
-#include "sord/sord.h"
-#include "sord/sordmm.hpp"
+#include "serd/serd.hpp"
#include <cassert>
#include <cstdint>
@@ -52,36 +53,43 @@
namespace ingen {
+static void
+load_file(serd::World& world,
+ serd::Model& model,
+ serd::Env& env,
+ const URI& file_uri)
+{
+ serd::Inserter inserter(model, env);
+ serd::Reader reader(world, serd::Syntax::Turtle, {}, inserter.sink(), 4096);
+
+ reader.start_file(file_uri.str());
+ reader.read_document();
+ reader.finish();
+}
+
std::set<Parser::ResourceRecord>
-Parser::find_resources(Sord::World& world,
- const URI& manifest_uri,
- const URI& type_uri)
+Parser::find_resources(const URI& manifest_uri, const URI& type_uri)
{
- const Sord::URI base (world, manifest_uri.string());
- const Sord::URI type (world, type_uri.string());
- const Sord::URI rdf_type (world, NS_RDF "type");
- const Sord::URI rdfs_seeAlso(world, NS_RDFS "seeAlso");
- const Sord::Node nil;
+ const auto rdf_type = serd::make_uri(NS_RDF "type");
+ const auto rdfs_seeAlso = serd::make_uri(NS_RDFS "seeAlso");
+
+ serd::World world;
+ serd::Env env{serd::Node(manifest_uri)};
+ serd::Model model{world,
+ serd::ModelFlag::index_SPO | serd::ModelFlag::index_OPS};
- SerdEnv* env = serd_env_new(sord_node_to_serd_node(base.c_obj()));
- Sord::Model model(world, manifest_uri.string());
- model.load_file(env, SERD_TURTLE, manifest_uri.string());
+ load_file(world, model, env, manifest_uri);
std::set<ResourceRecord> resources;
- for (Sord::Iter i = model.find(nil, rdf_type, type); !i.end(); ++i) {
- const Sord::Node resource = i.get_subject();
- const std::string resource_uri = resource.to_c_string();
- Sord::Iter f = model.find(resource, rdfs_seeAlso, nil);
- std::string file_path;
- if (!f.end()) {
- uint8_t* p = serd_file_uri_parse(f.get_object().to_u_string(), nullptr);
- file_path = (const char*)p;
- serd_free(p);
- }
+ for (const auto& s : model.range({}, rdf_type, type_uri)) {
+ const auto& resource = s.subject();
+ const auto f = model.find(resource, rdfs_seeAlso, {});
+ const FilePath file_path =
+ ((f != model.end() ? serd::file_uri_parse((*f).object().str())
+ : ""));
resources.insert(ResourceRecord(resource, file_path));
}
- serd_env_free(env);
return resources;
}
@@ -89,13 +97,14 @@ static boost::optional<Raul::Path>
get_path(const URI& base, const URI& uri)
{
const URI relative = uri.make_relative(base);
- const std::string uri_str = "/" + relative.string();
+ const std::string uri_str = relative.string();
+ // assert(Raul::Path::is_valid(uri_str));
return Raul::Path::is_valid(uri_str) ? Raul::Path(uri_str)
: boost::optional<Raul::Path>();
}
static bool
-skip_property(ingen::URIs& uris, const Sord::Node& predicate)
+skip_property(ingen::URIs& uris, const serd::Node& predicate)
{
return (predicate == INGEN__file ||
predicate == uris.ingen_arc ||
@@ -105,25 +114,20 @@ skip_property(ingen::URIs& uris, const Sord::Node& predicate)
static Properties
get_properties(ingen::World& world,
- Sord::Model& model,
- const Sord::Node& subject,
+ serd::Model& model,
+ const serd::Node& subject,
Resource::Graph ctx,
const boost::optional<Properties>& data = {})
{
- AtomForge forge(world.uri_map().urid_map_feature()->urid_map);
-
- const Sord::Node nil;
- Properties props;
- for (Sord::Iter i = model.find(subject, nil, nil); !i.end(); ++i) {
- if (!skip_property(world.uris(), i.get_predicate())) {
- forge.clear();
- forge.read(
- *world.rdf_world(), model.c_obj(), i.get_object().c_obj());
- const LV2_Atom* atom = forge.atom();
- Atom atomm;
- atomm = world.forge().alloc(
- atom->size, atom->type, LV2_ATOM_BODY_CONST(atom));
- props.emplace(i.get_predicate(), Property(atomm, ctx));
+ AtomForge forge(world.rdf_world(),
+ world.uri_map().urid_map_feature()->urid_map);
+
+ Properties props;
+ for (const auto& s : model.range(subject, {}, {})) {
+ if (!skip_property(world.uris(), s.predicate())) {
+ auto atom = forge.read(model, s.object());
+ props.emplace(s.predicate(),
+ Property(world.forge().alloc(atom), ctx));
}
}
@@ -151,8 +155,8 @@ using PortRecord = std::pair<Raul::Path, Properties>;
static boost::optional<PortRecord>
get_port(ingen::World& world,
- Sord::Model& model,
- const Sord::Node& subject,
+ serd::Model& model,
+ const serd::Node& subject,
Resource::Graph ctx,
const Raul::Path& parent,
uint32_t* index)
@@ -180,8 +184,8 @@ get_port(ingen::World& world,
if (s != props.end() && s->second.type() == world.forge().String) {
sym = s->second.ptr<char>();
} else {
- const std::string subject_str = subject.to_string();
- const size_t last_slash = subject_str.find_last_of('/');
+ const std::string subject_str{subject.str()};
+ const size_t last_slash{subject_str.find_last_of('/')};
sym = ((last_slash == std::string::npos)
? subject_str
@@ -204,9 +208,8 @@ static boost::optional<Raul::Path>
parse(
World& world,
Interface& target,
- Sord::Model& model,
+ serd::Model& model,
const URI& base_uri,
- Sord::Node& subject,
const boost::optional<Raul::Path>& parent = boost::optional<Raul::Path>(),
const boost::optional<Raul::Symbol>& symbol = boost::optional<Raul::Symbol>(),
const boost::optional<Properties>& data = boost::optional<Properties>());
@@ -215,9 +218,9 @@ static boost::optional<Raul::Path>
parse_graph(
World& world,
Interface& target,
- Sord::Model& model,
+ serd::Model& model,
const URI& base_uri,
- const Sord::Node& subject,
+ const serd::Node& subject,
Resource::Graph ctx,
const boost::optional<Raul::Path>& parent = boost::optional<Raul::Path>(),
const boost::optional<Raul::Symbol>& symbol = boost::optional<Raul::Symbol>(),
@@ -227,9 +230,9 @@ static boost::optional<Raul::Path>
parse_block(
World& world,
Interface& target,
- Sord::Model& model,
+ serd::Model& model,
const URI& base_uri,
- const Sord::Node& subject,
+ const serd::Node& subject,
const Raul::Path& path,
const boost::optional<Properties>& data = boost::optional<Properties>());
@@ -237,70 +240,58 @@ static bool
parse_arcs(
World& world,
Interface& target,
- Sord::Model& model,
+ serd::Model& model,
const URI& base_uri,
- const Sord::Node& subject,
+ const serd::Node& subject,
const Raul::Path& graph);
static boost::optional<Raul::Path>
parse_block(ingen::World& world,
ingen::Interface& target,
- Sord::Model& model,
+ serd::Model& model,
const URI& base_uri,
- const Sord::Node& subject,
+ const serd::Node& subject,
const Raul::Path& path,
const boost::optional<Properties>& data)
{
const URIs& uris = world.uris();
// Try lv2:prototype and old ingen:prototype for backwards compatibility
- const Sord::URI prototype_predicates[] = {
- Sord::URI(*world.rdf_world(), uris.lv2_prototype),
- Sord::URI(*world.rdf_world(), uris.ingen_prototype)
- };
+ const serd::Node prototype_predicates[] = {uris.lv2_prototype,
+ uris.ingen_prototype};
// Get prototype
- Sord::Node prototype;
- for (const Sord::URI& pred : prototype_predicates) {
- prototype = model.get(subject, pred, Sord::Node());
- if (prototype.is_valid()) {
+ serd::Optional<serd::NodeView> prototype;
+ for (const auto& pred : prototype_predicates) {
+ prototype = model.get(subject, pred, {});
+ if (prototype) {
break;
}
}
- if (!prototype.is_valid()) {
- world.log().error("Block %1% (%2%) missing mandatory lv2:prototype\n",
- subject, path);
+ if (!prototype) {
+ world.log().error(
+ fmt("Block %1% (%2%) missing mandatory lv2:prototype\n",
+ subject, path));
return boost::optional<Raul::Path>();
}
- const auto* type_uri = (const uint8_t*)prototype.to_c_string();
- if (!serd_uri_string_has_scheme(type_uri) ||
- !strncmp((const char*)type_uri, "file:", 5)) {
+ const char* type_uri = prototype->c_str();
+ if (!serd_uri_string_has_scheme(type_uri) || !strncmp(type_uri, "file:", 5)) {
// Prototype is a file, subgraph
- SerdURI base_uri_parts;
- serd_uri_parse((const uint8_t*)base_uri.c_str(), &base_uri_parts);
-
- SerdURI ignored;
- SerdNode sub_uri = serd_node_new_uri_from_string(
- type_uri,
- &base_uri_parts,
- &ignored);
-
- const std::string sub_uri_str = (const char*)sub_uri.buf;
- const std::string sub_file = sub_uri_str + "/main.ttl";
+ serd::Node sub_uri = serd::make_relative_uri(type_uri, base_uri);
- const SerdNode sub_base = serd_node_from_string(
- SERD_URI, (const uint8_t*)sub_file.c_str());
+ const URI sub_file{sub_uri.str().str() + "/main.ttl"};
+ const serd::Node sub_base = serd::make_uri(sub_file.c_str());
- Sord::Model sub_model(*world.rdf_world(), sub_file);
- SerdEnv* env = serd_env_new(&sub_base);
- sub_model.load_file(env, SERD_TURTLE, sub_file);
- serd_env_free(env);
+ serd::Model sub_model(world.rdf_world(),
+ serd::ModelFlag::index_SPO |
+ serd::ModelFlag::index_OPS);
+ serd::Env env(sub_base);
+ load_file(world.rdf_world(), sub_model, env, sub_file);
- Sord::URI sub_node(*world.rdf_world(), sub_file);
parse_graph(world, target, sub_model, sub_base,
- sub_node, Resource::Graph::INTERNAL,
+ sub_uri, Resource::Graph::INTERNAL,
path.parent(), Raul::Symbol(path.symbol()), data);
parse_graph(world, target, model, base_uri,
@@ -319,9 +310,9 @@ parse_block(ingen::World& world,
static boost::optional<Raul::Path>
parse_graph(ingen::World& world,
ingen::Interface& target,
- Sord::Model& model,
+ serd::Model& model,
const URI& base_uri,
- const Sord::Node& subject,
+ const serd::Node& subject,
Resource::Graph ctx,
const boost::optional<Raul::Path>& parent,
const boost::optional<Raul::Symbol>& symbol,
@@ -329,11 +320,9 @@ parse_graph(ingen::World& world,
{
const URIs& uris = world.uris();
- const Sord::URI ingen_block(*world.rdf_world(), uris.ingen_block);
- const Sord::URI lv2_port(*world.rdf_world(), LV2_CORE__port);
+ const serd::Node lv2_port = serd::make_uri(LV2_CORE__port);
- const Sord::Node& graph = subject;
- const Sord::Node nil;
+ const serd::Node& graph = subject;
// Build graph path and symbol
Raul::Path graph_path;
@@ -352,8 +341,8 @@ parse_graph(ingen::World& world,
// For each port on this graph
using PortRecords = std::map<uint32_t, PortRecord>;
PortRecords ports;
- for (Sord::Iter p = model.find(graph, lv2_port, nil); !p.end(); ++p) {
- Sord::Node port = p.get_object();
+ for (const auto& s : model.range(graph, lv2_port, {})) {
+ const auto& port = s.object();
// Get all properties
uint32_t index = 0;
@@ -385,9 +374,9 @@ parse_graph(ingen::World& world,
}
// For each block in this graph
- for (Sord::Iter n = model.find(subject, ingen_block, nil); !n.end(); ++n) {
- Sord::Node node = n.get_object();
- URI node_uri = node;
+ for (const auto& b : model.range(subject, uris.ingen_block, {})) {
+ const auto& node = b.object();
+ URI node_uri = node;
assert(!node_uri.path().empty() && node_uri.path() != "/");
const Raul::Path block_path = graph_path.child(
Raul::Symbol(FilePath(node_uri.path()).stem().string()));
@@ -397,13 +386,12 @@ parse_graph(ingen::World& world,
boost::optional<Properties>());
// For each port on this block
- for (Sord::Iter p = model.find(node, lv2_port, nil); !p.end(); ++p) {
- Sord::Node port = p.get_object();
+ for (const auto& p : model.range(node, lv2_port, {})) {
+ const auto& port = p.object();
Resource::Graph subctx = Resource::Graph::DEFAULT;
- if (!model.find(node,
- Sord::URI(*world.rdf_world(), uris.rdf_type),
- Sord::URI(*world.rdf_world(), uris.ingen_Graph)).end()) {
+ if (model.find(node, uris.rdf_type, uris.ingen_Graph) ==
+ model.end()) {
subctx = Resource::Graph::EXTERNAL;
}
@@ -431,50 +419,38 @@ parse_graph(ingen::World& world,
static bool
parse_arc(ingen::World& world,
ingen::Interface& target,
- Sord::Model& model,
+ serd::Model& model,
const URI& base_uri,
- const Sord::Node& subject,
+ const serd::Node& subject,
const Raul::Path& graph)
{
const URIs& uris = world.uris();
- const Sord::URI ingen_tail(*world.rdf_world(), uris.ingen_tail);
- const Sord::URI ingen_head(*world.rdf_world(), uris.ingen_head);
- const Sord::Node nil;
+ const auto& tail = model.get(subject, uris.ingen_tail, {});
+ const auto& head = model.get(subject, uris.ingen_head, {});
- Sord::Iter t = model.find(subject, ingen_tail, nil);
- Sord::Iter h = model.find(subject, ingen_head, nil);
-
- if (t.end()) {
+ if (!tail) {
world.log().error("Arc has no tail\n");
return false;
- } else if (h.end()) {
+ } else if (!head) {
world.log().error("Arc has no head\n");
return false;
}
const boost::optional<Raul::Path> tail_path = get_path(
- base_uri, t.get_object());
+ base_uri, *tail);
if (!tail_path) {
world.log().error("Arc tail has invalid URI\n");
return false;
}
const boost::optional<Raul::Path> head_path = get_path(
- base_uri, h.get_object());
+ base_uri, *head);
if (!head_path) {
world.log().error("Arc head has invalid URI\n");
return false;
}
- if (!(++t).end()) {
- world.log().error("Arc has multiple tails\n");
- return false;
- } else if (!(++h).end()) {
- world.log().error("Arc has multiple heads\n");
- return false;
- }
-
target.connect(graph.child(*tail_path), graph.child(*head_path));
return true;
@@ -483,16 +459,13 @@ parse_arc(ingen::World& world,
static bool
parse_arcs(ingen::World& world,
ingen::Interface& target,
- Sord::Model& model,
+ serd::Model& model,
const URI& base_uri,
- const Sord::Node& subject,
+ const serd::Node& subject,
const Raul::Path& graph)
{
- const Sord::URI ingen_arc(*world.rdf_world(), world.uris().ingen_arc);
- const Sord::Node nil;
-
- for (Sord::Iter i = model.find(subject, ingen_arc, nil); !i.end(); ++i) {
- parse_arc(world, target, model, base_uri, i.get_object(), graph);
+ for (const auto& s : model.range(subject, world.uris().ingen_arc, {})) {
+ parse_arc(world, target, model, base_uri, s.object(), graph);
}
return true;
@@ -501,72 +474,56 @@ parse_arcs(ingen::World& world,
static boost::optional<Raul::Path>
parse(ingen::World& world,
ingen::Interface& target,
- Sord::Model& model,
+ serd::Model& model,
const URI& base_uri,
- Sord::Node& subject,
const boost::optional<Raul::Path>& parent,
const boost::optional<Raul::Symbol>& symbol,
const boost::optional<Properties>& data)
{
- const URIs& uris = world.uris();
+ using Subjects = std::map<serd::Node, std::set<serd::Node>>;
- const Sord::URI graph_class (*world.rdf_world(), uris.ingen_Graph);
- const Sord::URI block_class (*world.rdf_world(), uris.ingen_Block);
- const Sord::URI arc_class (*world.rdf_world(), uris.ingen_Arc);
- const Sord::URI internal_class(*world.rdf_world(), uris.ingen_Internal);
- const Sord::URI in_port_class (*world.rdf_world(), LV2_CORE__InputPort);
- const Sord::URI out_port_class(*world.rdf_world(), LV2_CORE__OutputPort);
- const Sord::URI lv2_class (*world.rdf_world(), LV2_CORE__Plugin);
- const Sord::URI rdf_type (*world.rdf_world(), uris.rdf_type);
- const Sord::Node nil;
-
- // Parse explicit subject graph
- if (subject.is_valid()) {
- return parse_graph(world, target, model, base_uri,
- subject, Resource::Graph::INTERNAL,
- parent, symbol, data);
- }
+ const URIs& uris = world.uris();
// Get all subjects and their types (?subject a ?type)
- using Subjects = std::map< Sord::Node, std::set<Sord::Node> >;
Subjects subjects;
- for (Sord::Iter i = model.find(subject, rdf_type, nil); !i.end(); ++i) {
- const Sord::Node& subject = i.get_subject();
- const Sord::Node& rdf_class = i.get_object();
-
- assert(rdf_class.is_uri());
- auto s = subjects.find(subject);
- if (s == subjects.end()) {
- std::set<Sord::Node> types;
+ for (const auto& s : model.range({}, uris.rdf_type, {})) {
+ const auto& subject = s.subject();
+ const auto& rdf_class = s.object();
+
+ assert(rdf_class.type() == serd::NodeType::URI);
+ auto t = subjects.find(subject);
+ if (t == subjects.end()) {
+ std::set<serd::Node> types;
types.insert(rdf_class);
subjects.emplace(subject, types);
} else {
- s->second.insert(rdf_class);
+ t->second.insert(rdf_class);
}
}
// Parse and create each subject
for (const auto& i : subjects) {
- const Sord::Node& s = i.first;
- const std::set<Sord::Node>& types = i.second;
+ const auto& s = i.first;
+ const auto& types = i.second;
+
boost::optional<Raul::Path> ret;
- if (types.find(graph_class) != types.end()) {
+ if (types.find(uris.ingen_Graph) != types.end()) {
ret = parse_graph(world, target, model, base_uri,
s, Resource::Graph::INTERNAL,
parent, symbol, data);
- } else if (types.find(block_class) != types.end()) {
+ } else if (types.find(uris.ingen_Block) != types.end()) {
const Raul::Path rel_path(*get_path(base_uri, s));
const Raul::Path path = parent ? parent->child(rel_path) : rel_path;
ret = parse_block(world, target, model, base_uri, s, path, data);
- } else if (types.find(in_port_class) != types.end() ||
- types.find(out_port_class) != types.end()) {
+ } else if (types.find(uris.lv2_InputPort) != types.end() ||
+ types.find(uris.lv2_OutputPort) != types.end()) {
const Raul::Path rel_path(*get_path(base_uri, s));
const Raul::Path path = parent ? parent->child(rel_path) : rel_path;
const Properties properties = get_properties(
world, model, s, Resource::Graph::DEFAULT, data);
target.put(path_to_uri(path), properties);
ret = path;
- } else if (types.find(arc_class) != types.end()) {
+ } else if (types.find(uris.ingen_Arc) != types.end()) {
Raul::Path parent_path(parent ? parent.get() : Raul::Path("/"));
parse_arc(world, target, model, base_uri, s, parent_path);
} else {
@@ -599,8 +556,8 @@ Parser::parse_file(ingen::World& world,
URI manifest_uri(manifest_path);
// Find graphs in manifest
- const std::set<ResourceRecord> resources = find_resources(
- *world.rdf_world(), manifest_uri, URI(INGEN__Graph));
+ const std::set<ResourceRecord> resources =
+ find_resources(manifest_uri, URI(INGEN__Graph));
if (resources.empty()) {
world.log().error("No graphs found in %1%\n", path);
@@ -610,7 +567,7 @@ Parser::parse_file(ingen::World& world,
/* Choose the graph to load. If this is a manifest, then there should only be
one, but if this is a graph file, subgraphs will be returned as well.
In this case, choose the one with the file URI. */
- URI uri;
+ boost::optional<URI> uri;
for (const ResourceRecord& r : resources) {
if (r.uri == URI(manifest_path)) {
uri = r.uri;
@@ -619,7 +576,7 @@ Parser::parse_file(ingen::World& world,
}
}
- if (uri.empty()) {
+ if (!uri) {
// Didn't find a graph with the same URI as the file, use the first
uri = (*resources.begin()).uri;
file_path = (*resources.begin()).filename;
@@ -631,15 +588,13 @@ Parser::parse_file(ingen::World& world,
}
// Initialise parsing environment
- const URI file_uri = URI(file_path);
- const auto* uri_c_str = (const uint8_t*)uri.c_str();
- SerdNode base_node = serd_node_from_string(SERD_URI, uri_c_str);
- SerdEnv* env = serd_env_new(&base_node);
+ const URI file_uri(file_path);
+ serd::Env env(*uri);
// Load graph into model
- Sord::Model model(*world.rdf_world(), uri.string(), SORD_SPO|SORD_PSO, false);
- model.load_file(env, SERD_TURTLE, file_uri);
- serd_env_free(env);
+ serd::Model model(world.rdf_world(),
+ serd::ModelFlag::index_SPO | serd::ModelFlag::index_OPS);
+ load_file(world.rdf_world(), model, env, file_uri);
world.log().info("Loading %1% from %2%\n", uri, file_path);
if (parent) {
@@ -649,15 +604,21 @@ Parser::parse_file(ingen::World& world,
world.log().info("Symbol: %1%\n", symbol->c_str());
}
- Sord::Node subject(*world.rdf_world(), Sord::Node::URI, uri.string());
- boost::optional<Raul::Path> parsed_path
- = parse(world, target, model, model.base_uri(),
- subject, parent, symbol, data);
+ boost::optional<Raul::Path> parsed_path =
+ parse_graph(world,
+ target,
+ model,
+ *uri,
+ *uri,
+ Resource::Graph::INTERNAL,
+ parent,
+ symbol,
+ data);
if (parsed_path) {
target.set_property(path_to_uri(*parsed_path),
URI(INGEN__file),
- world.forge().alloc_uri(uri.string()));
+ world.forge().alloc_uri(uri->string()));
return true;
} else {
world.log().warn("Document URI lost\n");
@@ -675,23 +636,27 @@ Parser::parse_string(ingen::World& world,
const boost::optional<Properties>& data)
{
// Load string into model
- Sord::Model model(*world.rdf_world(), base_uri, SORD_SPO|SORD_PSO, false);
+ serd::Model model(world.rdf_world(),
+ serd::ModelFlag::index_SPO | serd::ModelFlag::index_OPS);
- SerdEnv* env = serd_env_new(nullptr);
+ serd::Env env;
if (!base_uri.empty()) {
- const SerdNode base = serd_node_from_string(
- SERD_URI, (const uint8_t*)base_uri.c_str());
- serd_env_set_base_uri(env, &base);
+ env.set_base_uri(base_uri);
}
- model.load_string(env, SERD_TURTLE, str.c_str(), str.length(), base_uri);
- URI actual_base((const char*)serd_env_get_base_uri(env, nullptr)->buf);
- serd_env_free(env);
+ serd::Inserter inserter(model, env);
+ serd::Reader reader(
+ world.rdf_world(), serd::Syntax::Turtle, {}, inserter.sink(), 4096);
+
+ reader.start_string(str);
+ reader.read_document();
+ reader.finish();
+
+ URI actual_base(env.base_uri());
world.log().info("Parsing string (base %1%)\n", base_uri);
- Sord::Node subject;
- parse(world, target, model, actual_base, subject, parent, symbol, data);
+ parse(world, target, model, actual_base, parent, symbol, data);
return actual_base;
}
diff --git a/src/Serialiser.cpp b/src/Serialiser.cpp
index f0b5009e..3ac18fe2 100644
--- a/src/Serialiser.cpp
+++ b/src/Serialiser.cpp
@@ -38,15 +38,16 @@
#include "raul/Path.hpp"
#include "raul/Symbol.hpp"
#include "serd/serd.h"
-#include "sord/sord.h"
-#include "sord/sordmm.hpp"
-#include "sratom/sratom.h"
+#include "serd/serd.hpp"
+#include "sratom/sratom.hpp"
#include <cassert>
#include <cstdint>
#include <cstring>
+#include <fstream>
#include <map>
#include <set>
+#include <sstream>
#include <stdexcept>
#include <string>
#include <utility>
@@ -55,15 +56,14 @@ namespace ingen {
struct Serialiser::Impl {
explicit Impl(World& world)
- : _root_path("/")
- , _mode(Mode::TO_FILE)
- , _world(world)
- , _model(nullptr)
- , _sratom(sratom_new(&_world.uri_map().urid_map_feature()->urid_map))
- {}
-
- ~Impl() {
- sratom_free(_sratom);
+ : _root_path("/")
+ , _mode(Mode::TO_STRING)
+ , _base_uri("ingen:")
+ , _world(world)
+ , _streamer(_world.rdf_world(),
+ _world.uri_map().urid_map_feature()->urid_map,
+ _world.uri_map().urid_unmap_feature()->urid_unmap)
+ {
}
Impl(const Impl&) = delete;
@@ -77,22 +77,22 @@ struct Serialiser::Impl {
const FilePath& filename);
std::set<const Resource*> serialise_graph(const SPtr<const Node>& graph,
- const Sord::Node& graph_id);
+ const serd::Node& graph_id);
void serialise_block(const SPtr<const Node>& block,
- const Sord::Node& class_id,
- const Sord::Node& block_id);
+ const serd::Node& class_id,
+ const serd::Node& block_id);
void serialise_port(const Node* port,
Resource::Graph context,
- const Sord::Node& port_id);
+ const serd::Node& port_id);
- void serialise_properties(Sord::Node id,
+ void serialise_properties(serd::Node id,
const Properties& props);
void write_bundle(const SPtr<const Node>& graph, const URI& uri);
- Sord::Node path_rdf_node(const Raul::Path& path);
+ serd::Node path_rdf_node(const Raul::Path& path);
void write_manifest(const FilePath& bundle_path,
const SPtr<const Node>& graph);
@@ -100,18 +100,18 @@ struct Serialiser::Impl {
void write_plugins(const FilePath& bundle_path,
const std::set<const Resource*>& plugins);
- void serialise_arc(const Sord::Node& parent,
- const SPtr<const Arc>& arc);
+ void serialise_arc(const serd::Optional<serd::Node>& parent,
+ const SPtr<const Arc>& arc);
std::string finish();
- Raul::Path _root_path;
- Mode _mode;
- URI _base_uri;
- FilePath _basename;
- World& _world;
- Sord::Model* _model;
- Sratom* _sratom;
+ Raul::Path _root_path;
+ Mode _mode;
+ URI _base_uri;
+ FilePath _basename;
+ World& _world;
+ UPtr<serd::Model> _model;
+ sratom::Streamer _streamer;
};
Serialiser::Serialiser(World& world)
@@ -129,24 +129,17 @@ Serialiser::Impl::write_manifest(const FilePath& bundle_path,
start_to_file(Raul::Path("/"), manifest_path);
- Sord::World& world = _model->world();
- const URIs& uris = _world.uris();
+ const URIs& uris = _world.uris();
const std::string filename("main.ttl");
- const Sord::URI subject(world, filename, _base_uri);
-
- _model->add_statement(subject,
- Sord::URI(world, uris.rdf_type),
- Sord::URI(world, uris.ingen_Graph));
- _model->add_statement(subject,
- Sord::URI(world, uris.rdf_type),
- Sord::URI(world, uris.lv2_Plugin));
- _model->add_statement(subject,
- Sord::URI(world, uris.rdfs_seeAlso),
- Sord::URI(world, filename, _base_uri));
- _model->add_statement(subject,
- Sord::URI(world, uris.lv2_prototype),
- Sord::URI(world, uris.ingen_GraphPrototype));
+ const serd::Node subject = serd::make_resolved_uri(filename, _base_uri);
+
+ _model->insert(subject, uris.rdf_type, uris.ingen_Graph);
+ _model->insert(subject, uris.rdf_type, uris.lv2_Plugin);
+ _model->insert(subject, uris.lv2_prototype, uris.ingen_GraphPrototype);
+ _model->insert(subject,
+ uris.rdfs_seeAlso,
+ serd::make_resolved_uri(filename, _base_uri));
finish();
}
@@ -159,24 +152,21 @@ Serialiser::Impl::write_plugins(const FilePath& bundle_path,
start_to_file(Raul::Path("/"), plugins_path);
- Sord::World& world = _model->world();
- const URIs& uris = _world.uris();
+ const URIs& uris = _world.uris();
for (const auto& p : plugins) {
const Atom& minor = p->get_property(uris.lv2_minorVersion);
const Atom& micro = p->get_property(uris.lv2_microVersion);
- _model->add_statement(Sord::URI(world, p->uri()),
- Sord::URI(world, uris.rdf_type),
- Sord::URI(world, uris.lv2_Plugin));
+ _model->insert(p->uri(), uris.rdf_type, uris.lv2_Plugin);
if (minor.is_valid() && micro.is_valid()) {
- _model->add_statement(Sord::URI(world, p->uri()),
- Sord::URI(world, uris.lv2_minorVersion),
- Sord::Literal::integer(world, minor.get<int32_t>()));
- _model->add_statement(Sord::URI(world, p->uri()),
- Sord::URI(world, uris.lv2_microVersion),
- Sord::Literal::integer(world, micro.get<int32_t>()));
+ _model->insert(p->uri(),
+ uris.lv2_minorVersion,
+ serd::make_integer(minor.get<int32_t>()));
+ _model->insert(p->uri(),
+ uris.lv2_microVersion,
+ serd::make_integer(micro.get<int32_t>()));
}
}
@@ -207,7 +197,7 @@ Serialiser::Impl::write_bundle(const SPtr<const Node>& graph, const URI& uri)
std::set<const Resource*> plugins = serialise_graph(
graph,
- Sord::URI(_model->world(), main_file, _base_uri));
+ serd::make_resolved_uri(main_file.c_str(), _base_uri));
finish();
write_manifest(path, graph);
@@ -230,9 +220,11 @@ Serialiser::Impl::start_to_file(const Raul::Path& root,
_basename = filename.parent_path().stem();
}
- _model = new Sord::Model(*_world.rdf_world(), _base_uri);
- _mode = Mode::TO_FILE;
_root_path = root;
+ _mode = Mode::TO_FILE;
+ _model = make_unique<serd::Model>(_world.rdf_world(),
+ serd::ModelFlag::index_SPO |
+ serd::ModelFlag::index_OPS);
}
void
@@ -240,8 +232,10 @@ Serialiser::start_to_string(const Raul::Path& root, const URI& base_uri)
{
me->_root_path = root;
me->_base_uri = base_uri;
- me->_model = new Sord::Model(*me->_world.rdf_world(), base_uri);
me->_mode = Impl::Mode::TO_STRING;
+ me->_model = make_unique<serd::Model>(me->_world.rdf_world(),
+ serd::ModelFlag::index_SPO |
+ serd::ModelFlag::index_OPS);
}
void
@@ -259,32 +253,54 @@ Serialiser::finish()
std::string
Serialiser::Impl::finish()
{
- std::string ret;
+ std::string ret{};
+ serd::Env env{_world.env()};
+
+ env.set_base_uri(_base_uri);
+
if (_mode == Mode::TO_FILE) {
- SerdStatus st = _model->write_to_file(_base_uri, SERD_TURTLE);
- if (st) {
- _world.log().error("Error writing file %1% (%2%)\n",
- _base_uri, serd_strerror(st));
+ const std::string path = serd::file_uri_parse(_base_uri.string());
+ std::ofstream file(path);
+ serd::Writer writer(
+ _world.rdf_world(), serd::Syntax::Turtle, {}, env, file);
+
+ env.write_prefixes(writer.sink());
+ const serd::Status st = _model->all().serialise(writer.sink());
+
+ if (st != serd::Status::success) {
+ _world.log().error(fmt("Error writing file %1% (%2%)\n",
+ _base_uri, serd::strerror(st)));
}
} else {
- ret = _model->write_to_string(_base_uri, SERD_TURTLE);
+ std::stringstream ss;
+ serd::Writer writer(
+ _world.rdf_world(), serd::Syntax::Turtle, {}, env, ss);
+
+ env.write_prefixes(writer.sink());
+ const serd::Status st = _model->all().serialise(writer.sink());
+
+ writer.finish();
+ ret = ss.str();
+
+ if (st != serd::Status::success) {
+ _world.log().error(fmt("Error writing string (%2%)\n",
+ serd::strerror(st)));
+ }
}
- delete _model;
- _model = nullptr;
- _base_uri = URI();
+ _model.reset();
+ _base_uri = URI("ingen:");
return ret;
}
-Sord::Node
+serd::Node
Serialiser::Impl::path_rdf_node(const Raul::Path& path)
{
assert(_model);
assert(path == _root_path || path.is_child_of(_root_path));
- return Sord::URI(_model->world(),
- path.substr(_root_path.base().length()),
- _base_uri);
+ return serd::make_resolved_uri(path.substr(_root_path.base().length()),
+ _base_uri);
}
void
@@ -297,8 +313,9 @@ Serialiser::serialise(const SPtr<const Node>& object, Resource::Graph context)
if (object->graph_type() == Node::GraphType::GRAPH) {
me->serialise_graph(object, me->path_rdf_node(object->path()));
} else if (object->graph_type() == Node::GraphType::BLOCK) {
- const Sord::URI plugin_id(me->_model->world(), object->plugin()->uri());
- me->serialise_block(object, plugin_id, me->path_rdf_node(object->path()));
+ me->serialise_block(object,
+ object->plugin()->uri(),
+ me->path_rdf_node(object->path()));
} else if (object->graph_type() == Node::GraphType::PORT) {
me->serialise_port(
object.get(), context, me->path_rdf_node(object->path()));
@@ -310,32 +327,27 @@ Serialiser::serialise(const SPtr<const Node>& object, Resource::Graph context)
std::set<const Resource*>
Serialiser::Impl::serialise_graph(const SPtr<const Node>& graph,
- const Sord::Node& graph_id)
+ const serd::Node& graph_id)
{
- Sord::World& world = _model->world();
- const URIs& uris = _world.uris();
+ const URIs& uris = _world.uris();
- _model->add_statement(graph_id,
- Sord::URI(world, uris.rdf_type),
- Sord::URI(world, uris.ingen_Graph));
+ _model->insert(graph_id, uris.rdf_type, uris.ingen_Graph);
- _model->add_statement(graph_id,
- Sord::URI(world, uris.rdf_type),
- Sord::URI(world, uris.lv2_Plugin));
+ _model->insert(graph_id, uris.rdf_type, uris.lv2_Plugin);
- _model->add_statement(graph_id,
- Sord::URI(world, uris.lv2_extensionData),
- Sord::URI(world, LV2_STATE__interface));
+ _model->insert(graph_id,
+ uris.lv2_extensionData,
+ serd::make_uri(LV2_STATE__interface));
- _model->add_statement(graph_id,
- Sord::URI(world, LV2_UI__ui),
- Sord::URI(world, "http://drobilla.net/ns/ingen#GraphUIGtk2"));
+ _model->insert(graph_id,
+ serd::make_uri(LV2_UI__ui),
+ serd::make_uri("http://drobilla.net/ns/ingen#GraphUIGtk2"));
// If the graph has no doap:name (required by LV2), use the basename
if (graph->properties().find(uris.doap_name) == graph->properties().end()) {
- _model->add_statement(graph_id,
- Sord::URI(world, uris.doap_name),
- Sord::Literal(world, _basename));
+ _model->insert(graph_id,
+ uris.doap_name,
+ serd::make_string((std::string)_basename));
}
const Properties props = graph->properties(Resource::Graph::INTERNAL);
@@ -352,45 +364,33 @@ Serialiser::Impl::serialise_graph(const SPtr<const Node>& graph,
if (n->second->graph_type() == Node::GraphType::GRAPH) {
SPtr<Node> subgraph = n->second;
- SerdURI base_uri;
- serd_uri_parse((const uint8_t*)_base_uri.c_str(), &base_uri);
-
const std::string sub_bundle_path = subgraph->path().substr(1) + ".ingen";
- SerdURI subgraph_uri;
- SerdNode subgraph_node = serd_node_new_uri_from_string(
- (const uint8_t*)sub_bundle_path.c_str(),
- &base_uri,
- &subgraph_uri);
-
- const Sord::URI subgraph_id(world, (const char*)subgraph_node.buf);
+ serd::Node subgraph_node = serd::make_resolved_uri(
+ sub_bundle_path,
+ _base_uri);
// Save our state
- URI my_base_uri = _base_uri;
- Sord::Model* my_model = _model;
+ URI my_base_uri = _base_uri;
+ auto my_model = std::move(_model);
// Write child bundle within this bundle
- write_bundle(subgraph, subgraph_id);
+ write_bundle(subgraph, subgraph_node);
// Restore our state
_base_uri = my_base_uri;
- _model = my_model;
+ _model = std::move(my_model);
// Serialise reference to graph block
- const Sord::Node block_id(path_rdf_node(subgraph->path()));
- _model->add_statement(graph_id,
- Sord::URI(world, uris.ingen_block),
- block_id);
- serialise_block(subgraph, subgraph_id, block_id);
+ const serd::Node block_id(path_rdf_node(subgraph->path()));
+ _model->insert(graph_id, uris.ingen_block, block_id);
+ serialise_block(subgraph, subgraph_node, block_id);
} else if (n->second->graph_type() == Node::GraphType::BLOCK) {
SPtr<const Node> block = n->second;
- const Sord::URI class_id(world, block->plugin()->uri());
- const Sord::Node block_id(path_rdf_node(n->second->path()));
- _model->add_statement(graph_id,
- Sord::URI(world, uris.ingen_block),
- block_id);
- serialise_block(block, class_id, block_id);
+ const serd::Node block_id(path_rdf_node(n->second->path()));
+ _model->insert(graph_id, uris.ingen_block, block_id);
+ serialise_block(block, block->plugin()->uri(), block_id);
plugins.insert(block->plugin());
}
@@ -398,7 +398,7 @@ Serialiser::Impl::serialise_graph(const SPtr<const Node>& graph,
for (uint32_t i = 0; i < graph->num_ports(); ++i) {
Node* p = graph->port(i);
- const Sord::Node port_id = path_rdf_node(p->path());
+ const serd::Node port_id = path_rdf_node(p->path());
// Ensure lv2:name always exists so Graph is a valid LV2 plugin
if (p->properties().find(uris.lv2_name) == p->properties().end()) {
@@ -406,9 +406,7 @@ Serialiser::Impl::serialise_graph(const SPtr<const Node>& graph,
_world.forge().alloc(p->symbol().c_str()));
}
- _model->add_statement(graph_id,
- Sord::URI(world, LV2_CORE__port),
- port_id);
+ _model->insert(graph_id, serd::make_uri(LV2_CORE__port), port_id);
serialise_port(p, Resource::Graph::DEFAULT, port_id);
serialise_port(p, Resource::Graph::INTERNAL, port_id);
}
@@ -422,17 +420,13 @@ Serialiser::Impl::serialise_graph(const SPtr<const Node>& graph,
void
Serialiser::Impl::serialise_block(const SPtr<const Node>& block,
- const Sord::Node& class_id,
- const Sord::Node& block_id)
+ const serd::Node& class_id,
+ const serd::Node& block_id)
{
const URIs& uris = _world.uris();
- _model->add_statement(block_id,
- Sord::URI(_model->world(), uris.rdf_type),
- Sord::URI(_model->world(), uris.ingen_Block));
- _model->add_statement(block_id,
- Sord::URI(_model->world(), uris.lv2_prototype),
- class_id);
+ _model->insert(block_id, uris.rdf_type, uris.ingen_Block);
+ _model->insert(block_id, uris.lv2_prototype, class_id);
// Serialise properties, but remove possibly stale state:state (set again below)
Properties props = block->properties();
@@ -445,36 +439,33 @@ Serialiser::Impl::serialise_block(const SPtr<const Node>& block,
const FilePath state_dir = graph_dir / block->symbol();
const FilePath state_file = state_dir / "state.ttl";
if (block->save_state(state_dir)) {
- _model->add_statement(block_id,
- Sord::URI(_model->world(), uris.state_state),
- Sord::URI(_model->world(), URI(state_file)));
+ _model->insert(block_id,
+ uris.state_state,
+ serd::make_uri((std::string)state_file));
}
}
for (uint32_t i = 0; i < block->num_ports(); ++i) {
Node* const p = block->port(i);
- const Sord::Node port_id = path_rdf_node(p->path());
+ const serd::Node port_id = path_rdf_node(p->path());
serialise_port(p, Resource::Graph::DEFAULT, port_id);
- _model->add_statement(block_id,
- Sord::URI(_model->world(), uris.lv2_port),
- port_id);
+ _model->insert(block_id, uris.lv2_port, port_id);
}
}
void
Serialiser::Impl::serialise_port(const Node* port,
Resource::Graph context,
- const Sord::Node& port_id)
+ const serd::Node& port_id)
{
- URIs& uris = _world.uris();
- Sord::World& world = _model->world();
+ URIs& uris = _world.uris();
Properties props = port->properties(context);
if (context == Resource::Graph::INTERNAL) {
// Always write lv2:symbol for Graph ports (required for lv2:Plugin)
- _model->add_statement(port_id,
- Sord::URI(world, uris.lv2_symbol),
- Sord::Literal(world, port->path().symbol()));
+ _model->insert(port_id,
+ uris.lv2_symbol,
+ serd::make_string(port->path().symbol()));
} else if (context == Resource::Graph::EXTERNAL) {
// Never write lv2:index for plugin instances (not persistent/stable)
props.erase(uris.lv2_index);
@@ -500,47 +491,38 @@ Serialiser::Impl::serialise_port(const Node* port,
}
void
-Serialiser::serialise_arc(const Sord::Node& parent,
- const SPtr<const Arc>& arc)
+Serialiser::serialise_arc(const serd::Optional<serd::Node>& parent,
+ const SPtr<const Arc>& arc)
{
return me->serialise_arc(parent, arc);
}
void
-Serialiser::Impl::serialise_arc(const Sord::Node& parent,
- const SPtr<const Arc>& arc)
+Serialiser::Impl::serialise_arc(const serd::Optional<serd::Node>& parent,
+ const SPtr<const Arc>& arc)
{
if (!_model) {
throw std::logic_error(
"serialise_arc called without serialisation in progress");
}
- Sord::World& world = _model->world();
- const URIs& uris = _world.uris();
-
- const Sord::Node src = path_rdf_node(arc->tail_path());
- const Sord::Node dst = path_rdf_node(arc->head_path());
- const Sord::Node arc_id = Sord::Node::blank_id(*_world.rdf_world());
- _model->add_statement(arc_id,
- Sord::URI(world, uris.ingen_tail),
- src);
- _model->add_statement(arc_id,
- Sord::URI(world, uris.ingen_head),
- dst);
-
- if (parent.is_valid()) {
- _model->add_statement(parent,
- Sord::URI(world, uris.ingen_arc),
- arc_id);
+ const URIs& uris = _world.uris();
+
+ const serd::Node src = path_rdf_node(arc->tail_path());
+ const serd::Node dst = path_rdf_node(arc->head_path());
+ const serd::Node arc_id = _world.rdf_world().get_blank();
+ _model->insert(arc_id, uris.ingen_tail, src);
+ _model->insert(arc_id, uris.ingen_head, dst);
+
+ if (parent) {
+ _model->insert(*parent, uris.ingen_arc, arc_id);
} else {
- _model->add_statement(arc_id,
- Sord::URI(world, uris.rdf_type),
- Sord::URI(world, uris.ingen_Arc));
+ _model->insert(arc_id, uris.rdf_type, uris.ingen_Arc);
}
}
static bool
-skip_property(ingen::URIs& uris, const Sord::Node& predicate)
+skip_property(ingen::URIs& uris, const serd::Node& predicate)
{
return (predicate == INGEN__file ||
predicate == uris.ingen_arc ||
@@ -549,45 +531,37 @@ skip_property(ingen::URIs& uris, const Sord::Node& predicate)
}
void
-Serialiser::Impl::serialise_properties(Sord::Node id,
+Serialiser::Impl::serialise_properties(serd::Node id,
const Properties& props)
{
- LV2_URID_Unmap* unmap = &_world.uri_map().urid_unmap_feature()->urid_unmap;
- SerdNode base = serd_node_from_string(SERD_URI,
- (const uint8_t*)_base_uri.c_str());
- SerdEnv* env = serd_env_new(&base);
- SordInserter* inserter = sord_inserter_new(_model->c_obj(), env);
-
- sratom_set_sink(_sratom, _base_uri.c_str(),
- (SerdStatementSink)sord_inserter_write_statement, nullptr,
- inserter);
-
- sratom_set_pretty_numbers(_sratom, true);
+ serd::Env env{_base_uri};
+ serd::Inserter inserter{*_model, env, {}};
for (const auto& p : props) {
- const Sord::URI key(_model->world(), p.first);
+ const serd::Node key = serd::make_uri(p.first.c_str());
if (!skip_property(_world.uris(), key)) {
if (p.second.type() == _world.uris().atom_URI &&
- !strncmp((const char*)p.second.get_body(), "ingen:/main/", 13)) {
+ !strncmp(
+ (const char*)p.second.get_body(), "ingen:/main/", 13)) {
/* Value is a graph URI relative to the running engine.
Chop the prefix and save the path relative to the graph file.
This allows saving references to bundle resources. */
- sratom_write(_sratom, unmap, 0,
- sord_node_to_serd_node(id.c_obj()),
- sord_node_to_serd_node(key.c_obj()),
- p.second.type(), p.second.size(),
- (const char*)p.second.get_body() + 13);
+ _streamer.write(inserter.sink(),
+ id,
+ key,
+ p.second.type(),
+ p.second.size(),
+ (const char*)p.second.get_body() + 13,
+ sratom::Flag::pretty_numbers);
} else {
- sratom_write(_sratom, unmap, 0,
- sord_node_to_serd_node(id.c_obj()),
- sord_node_to_serd_node(key.c_obj()),
- p.second.type(), p.second.size(), p.second.get_body());
+ _streamer.write(inserter.sink(),
+ id,
+ key,
+ *p.second.atom(),
+ sratom::Flag::pretty_numbers);
}
}
}
-
- sord_inserter_free(inserter);
- serd_env_free(env);
}
} // namespace ingen
diff --git a/src/SocketReader.cpp b/src/SocketReader.cpp
index 443c418f..273c9e49 100644
--- a/src/SocketReader.cpp
+++ b/src/SocketReader.cpp
@@ -21,10 +21,11 @@
#include "ingen/Log.hpp"
#include "ingen/URIMap.hpp"
#include "ingen/World.hpp"
+#include "ingen/types.hpp"
#include "lv2/atom/forge.h"
#include "lv2/urid/urid.h"
#include "raul/Socket.hpp"
-#include "sord/sordmm.hpp"
+#include "serd/serd.hpp"
#include <cerrno>
#include <cstdint>
@@ -42,9 +43,6 @@ SocketReader::SocketReader(ingen::World& world,
SPtr<Raul::Socket> sock)
: _world(world)
, _iface(iface)
- , _env()
- , _inserter(nullptr)
- , _msg_node(nullptr)
, _socket(std::move(sock))
, _exit_flag(false)
, _thread(&SocketReader::run, this)
@@ -57,46 +55,10 @@ SocketReader::~SocketReader()
_thread.join();
}
-SerdStatus
-SocketReader::set_base_uri(SocketReader* iface,
- const SerdNode* uri_node)
-{
- return sord_inserter_set_base_uri(iface->_inserter, uri_node);
-}
-
-SerdStatus
-SocketReader::set_prefix(SocketReader* iface,
- const SerdNode* name,
- const SerdNode* uri_node)
-{
- return sord_inserter_set_prefix(iface->_inserter, name, uri_node);
-}
-
-SerdStatus
-SocketReader::write_statement(SocketReader* iface,
- SerdStatementFlags flags,
- const SerdNode* graph,
- const SerdNode* subject,
- const SerdNode* predicate,
- const SerdNode* object,
- const SerdNode* object_datatype,
- const SerdNode* object_lang)
-{
- if (!iface->_msg_node) {
- iface->_msg_node = sord_node_from_serd_node(
- iface->_world.rdf_world()->c_obj(), iface->_env, subject, nullptr, nullptr);
- }
-
- return sord_inserter_write_statement(
- iface->_inserter, flags, graph,
- subject, predicate, object,
- object_datatype, object_lang);
-}
-
void
SocketReader::run()
{
- Sord::World* world = _world.rdf_world();
+ serd::World& world = _world.rdf_world();
LV2_URID_Map& map = _world.uri_map().urid_map_feature()->urid_map;
// Open socket as a FILE for reading directly with serd
@@ -111,33 +73,51 @@ SocketReader::run()
}
// Set up a forge to build LV2 atoms from model
- SordNode* base_uri = nullptr;
- SordModel* model = nullptr;
- AtomForge forge(map);
+ AtomForge forge(world, map);
+ serd::Optional<serd::Node> base_uri;
+ serd::Optional<serd::Model> model;
+ serd::Env env;
+ UPtr<serd::Inserter> inserter;
+ serd::Optional<serd::Node> msg_node;
{
// Lock RDF world
std::lock_guard<std::mutex> lock(_world.rdf_mutex());
// Use <ingen:/> as base URI, so relative URIs are like bundle paths
- base_uri = sord_new_uri(world->c_obj(), (const uint8_t*)"ingen:/");
+ base_uri = serd::make_uri("ingen:/");
// Make a model and reader to parse the next Turtle message
- _env = world->prefixes().c_obj();
- model = sord_new(world->c_obj(), SORD_SPO, false);
+ env = _world.env();
+ model = serd::Model(world, serd::ModelFlag::index_SPO);
// Create an inserter for writing incoming triples to model
- _inserter = sord_inserter_new(model, _env);
+ inserter = UPtr<serd::Inserter>{new serd::Inserter(*model, env)};
}
- SerdReader* reader = serd_reader_new(
- SERD_TURTLE, this, nullptr,
- (SerdBaseSink)set_base_uri,
- (SerdPrefixSink)set_prefix,
- (SerdStatementSink)write_statement,
- nullptr);
+ serd::Sink sink;
+
+ sink.set_base_func([&](const serd::Node& uri) {
+ return inserter->sink().base(uri);
+ });
+
+ sink.set_prefix_func([&](const serd::Node& name, const serd::Node& uri) {
+ return inserter->sink().prefix(name, uri);
+ });
+
+ sink.set_statement_func([&](const serd::StatementFlags flags,
+ const serd::Statement& statement) {
+ if (!msg_node) {
+ msg_node = statement.subject();
+ }
+
+ return inserter->sink().statement(flags, statement);
+ });
+
+ serd::Reader reader(world, serd::Syntax::Turtle, {}, sink, 4096);
- serd_env_set_base_uri(_env, sord_node_to_serd_node(base_uri));
- serd_reader_start_stream(reader, f.get(), (const uint8_t*)"(socket)", false);
+ serd::Node name = serd::make_string("(socket)");
+ env.set_base_uri(*base_uri);
+ reader.start_stream(f.get(), name, 1);
// Make an AtomReader to call Ingen Interface methods based on Atom
AtomReader ar(_world.uri_map(), _world.uris(), _world.log(), _iface);
@@ -165,24 +145,22 @@ SocketReader::run()
std::lock_guard<std::mutex> lock(_world.rdf_mutex());
// Read until the next '.'
- SerdStatus st = serd_reader_read_chunk(reader);
- if (st == SERD_FAILURE || !_msg_node) {
- continue; // Read nothing, e.g. just whitespace
- } else if (st) {
- _world.log().error("Read error: %1%\n", serd_strerror(st));
+ auto st = reader.read_chunk();
+ if (st == serd::Status::failure || !msg_node) {
+ continue; // Read no node (e.g. a directive)
+ } else if (st != serd::Status::success) {
+ _world.log().error("Read error: %1%\n", serd::strerror(st));
continue;
}
- // Build an LV2_Atom at chunk.buf from the message
- forge.read(*world, model, _msg_node);
+ // Build an LV2_Atom from the message
+ auto atom = forge.read(*model, *msg_node);
- // Call _iface methods based on atom content
- ar.write(forge.atom());
+ // Call _iface methods with forged atom
+ ar.write(atom);
// Reset everything for the next iteration
- forge.clear();
- sord_node_free(world->c_obj(), _msg_node);
- _msg_node = nullptr;
+ msg_node.reset();
}
// Lock RDF world
@@ -190,10 +168,7 @@ SocketReader::run()
// Destroy everything
f.reset();
- sord_inserter_free(_inserter);
- serd_reader_end_stream(reader);
- serd_reader_free(reader);
- sord_free(model);
+ reader.finish();
_socket.reset();
}
diff --git a/src/SocketWriter.cpp b/src/SocketWriter.cpp
index 910f67f3..41254ef3 100644
--- a/src/SocketWriter.cpp
+++ b/src/SocketWriter.cpp
@@ -31,12 +31,13 @@
namespace ingen {
-SocketWriter::SocketWriter(URIMap& map,
+SocketWriter::SocketWriter(serd::World& world,
+ URIMap& map,
URIs& uris,
const URI& uri,
SPtr<Raul::Socket> sock)
- : TurtleWriter(map, uris, uri)
- , _socket(std::move(sock))
+ : TurtleWriter(world, map, uris, uri)
+ , _socket(std::move(sock))
{}
void
diff --git a/src/StreamWriter.cpp b/src/StreamWriter.cpp
index d8a93a0b..32831601 100644
--- a/src/StreamWriter.cpp
+++ b/src/StreamWriter.cpp
@@ -21,14 +21,15 @@
namespace ingen {
-StreamWriter::StreamWriter(URIMap& map,
+StreamWriter::StreamWriter(serd::World& world,
+ URIMap& map,
URIs& uris,
const URI& uri,
FILE* stream,
ColorContext::Color color)
- : TurtleWriter(map, uris, uri)
- , _stream(stream)
- , _color(color)
+ : TurtleWriter(world, map, uris, uri)
+ , _stream(stream)
+ , _color(color)
{}
size_t
diff --git a/src/TurtleWriter.cpp b/src/TurtleWriter.cpp
index 1deb2e13..e8a38561 100644
--- a/src/TurtleWriter.cpp
+++ b/src/TurtleWriter.cpp
@@ -19,72 +19,43 @@
#include "ingen/URIMap.hpp"
#include "lv2/atom/atom.h"
-#define USTR(s) ((const uint8_t*)(s))
-
namespace ingen {
-static size_t
-c_text_sink(const void* buf, size_t len, void* stream)
-{
- auto* writer = static_cast<TurtleWriter*>(stream);
- return writer->text_sink(buf, len);
-}
-
-static SerdStatus
-write_prefix(void* handle, const SerdNode* name, const SerdNode* uri)
-{
- serd_writer_set_prefix((SerdWriter*)handle, name, uri);
- return SERD_SUCCESS;
-}
-
-TurtleWriter::TurtleWriter(URIMap& map, URIs& uris, URI uri)
- : AtomWriter(map, uris, *this)
+TurtleWriter::TurtleWriter(serd::World& world,
+ URIMap& map,
+ URIs& uris,
+ const URI& uri)
+ : AtomWriter(world, map, uris, *this)
, _map(map)
- , _sratom(sratom_new(&map.urid_map_feature()->urid_map))
- , _base(SERD_NODE_NULL)
- , _base_uri(SERD_URI_NULL)
- , _uri(std::move(uri))
+ , _streamer(world,
+ map.urid_map_feature()->urid_map,
+ map.urid_unmap_feature()->urid_unmap)
+ , _base(serd::make_uri("ingen:/")) // Make relative URIs like bundle paths
+ , _env(_base)
+ , _writer(world,
+ serd::Syntax::Turtle,
+ {},
+ _env,
+ [&](const char* str, size_t len) { return text_sink(str, len); })
+ , _uri(uri)
, _wrote_prefixes(false)
{
- // Use <ingen:/> as base URI, so relative URIs are like bundle paths
- _base = serd_node_from_string(SERD_URI, (const uint8_t*)"ingen:/");
- serd_uri_parse(_base.buf, &_base_uri);
-
- // Set up serialisation environment
- _env = serd_env_new(&_base);
- serd_env_set_prefix_from_strings(_env, USTR("atom"), USTR("http://lv2plug.in/ns/ext/atom#"));
- serd_env_set_prefix_from_strings(_env, USTR("doap"), USTR("http://usefulinc.com/ns/doap#"));
- serd_env_set_prefix_from_strings(_env, USTR("ingen"), USTR(INGEN_NS));
- serd_env_set_prefix_from_strings(_env, USTR("lv2"), USTR("http://lv2plug.in/ns/lv2core#"));
- serd_env_set_prefix_from_strings(_env, USTR("midi"), USTR("http://lv2plug.in/ns/ext/midi#"));
- serd_env_set_prefix_from_strings(_env, USTR("owl"), USTR("http://www.w3.org/2002/07/owl#"));
- serd_env_set_prefix_from_strings(_env, USTR("patch"), USTR("http://lv2plug.in/ns/ext/patch#"));
- serd_env_set_prefix_from_strings(_env, USTR("rdf"), USTR("http://www.w3.org/1999/02/22-rdf-syntax-ns#"));
- serd_env_set_prefix_from_strings(_env, USTR("rdfs"), USTR("http://www.w3.org/2000/01/rdf-schema#"));
- serd_env_set_prefix_from_strings(_env, USTR("xsd"), USTR("http://www.w3.org/2001/XMLSchema#"));
-
- // Make a Turtle writer that writes to text_sink
- _writer = serd_writer_new(
- SERD_TURTLE,
- (SerdStyle)(SERD_STYLE_RESOLVED|SERD_STYLE_ABBREVIATED|SERD_STYLE_CURIED),
- _env,
- &_base_uri,
- c_text_sink,
- this);
-
- // Configure sratom to write directly to the writer (and thus text_sink)
- sratom_set_sink(_sratom,
- (const char*)_base.buf,
- (SerdStatementSink)serd_writer_write_statement,
- (SerdEndSink)serd_writer_end_anon,
- _writer);
+ // Set namespace prefixes
+ _env.set_prefix("atom", "http://lv2plug.in/ns/ext/atom#");
+ _env.set_prefix("doap", "http://usefulinc.com/ns/doap#");
+ _env.set_prefix("ingen", INGEN_NS);
+ _env.set_prefix("lv2", "http://lv2plug.in/ns/lv2core#");
+ _env.set_prefix("midi", "http://lv2plug.in/ns/ext/midi#");
+ _env.set_prefix("owl", "http://www.w3.org/2002/07/owl#");
+ _env.set_prefix("patch", "http://lv2plug.in/ns/ext/patch#");
+ _env.set_prefix("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#");
+ _env.set_prefix("rdfs", "http://www.w3.org/2000/01/rdf-schema#");
+ _env.set_prefix("xsd", "http://www.w3.org/2001/XMLSchema#");
}
TurtleWriter::~TurtleWriter()
{
- sratom_free(_sratom);
- serd_writer_free(_writer);
- serd_env_free(_env);
+ _writer.finish();
}
bool
@@ -92,13 +63,13 @@ TurtleWriter::write(const LV2_Atom* msg, int32_t)
{
if (!_wrote_prefixes) {
// Write namespace prefixes once to reduce traffic
- serd_env_foreach(_env, write_prefix, _writer);
+ _env.write_prefixes(_writer.sink());
+ _writer.finish();
_wrote_prefixes = true;
}
- sratom_write(_sratom, &_map.urid_unmap_feature()->urid_unmap, 0,
- nullptr, nullptr, msg->type, msg->size, LV2_ATOM_BODY_CONST(msg));
- serd_writer_finish(_writer);
+ _streamer.write(_writer.sink(), *msg);
+ _writer.finish();
return true;
}
diff --git a/src/URI.cpp b/src/URI.cpp
index f7b64209..fd649393 100644
--- a/src/URI.cpp
+++ b/src/URI.cpp
@@ -22,102 +22,39 @@
namespace ingen {
-URI::URI()
- : _uri(SERD_URI_NULL)
- , _node(SERD_NODE_NULL)
-{}
-
URI::URI(const std::string& str)
- : _uri(SERD_URI_NULL)
- , _node(serd_node_new_uri_from_string((const uint8_t*)str.c_str(),
- nullptr,
- &_uri))
-{}
-
-URI::URI(const char* str)
- : _uri(SERD_URI_NULL)
- , _node(serd_node_new_uri_from_string((const uint8_t*)str, nullptr, &_uri))
-{}
-
-URI::URI(const std::string& str, const URI& base)
- : _uri(SERD_URI_NULL)
- , _node(serd_node_new_uri_from_string((const uint8_t*)str.c_str(),
- &base._uri,
- &_uri))
-{}
-
-URI::URI(SerdNode node)
- : _uri(SERD_URI_NULL)
- , _node(serd_node_new_uri_from_node(&node, nullptr, &_uri))
+ : serd::Node{serd::make_uri(str)}
{
- assert(node.type == SERD_URI);
}
-URI::URI(SerdNode node, SerdURI uri)
- : _uri(uri)
- , _node(node)
-{
- assert(node.type == SERD_URI);
-}
-
-URI::URI(const Sord::Node& node)
- : URI(*node.to_serd_node())
-{
-}
-
-URI::URI(const FilePath& path)
- : _uri(SERD_URI_NULL)
- , _node(serd_node_new_file_uri((const uint8_t*)path.c_str(),
- nullptr,
- &_uri,
- true))
-{}
-
-URI::URI(const URI& uri)
- : _uri(SERD_URI_NULL)
- , _node(serd_node_new_uri(&uri._uri, nullptr, &_uri))
-{}
-
-URI&
-URI::operator=(const URI& uri)
+URI::URI(const char* str)
+ : serd::Node{serd::make_uri(str)}
{
- if (&uri != this) {
- serd_node_free(&_node);
- _node = serd_node_new_uri(&uri._uri, nullptr, &_uri);
- }
-
- return *this;
}
-URI::URI(URI&& uri) noexcept
- : _uri(uri._uri)
- , _node(uri._node)
+URI::URI(const serd::NodeView& node)
+ : serd::Node{node}
{
- uri._node = SERD_NODE_NULL;
- uri._uri = SERD_URI_NULL;
+ assert(cobj());
+ assert(node.type() == serd::NodeType::URI);
}
-URI&
-URI::operator=(URI&& uri) noexcept
+URI::URI(const serd::Node& node)
+ : serd::Node{node}
{
- _node = uri._node;
- _uri = uri._uri;
- uri._node = SERD_NODE_NULL;
- uri._uri = SERD_URI_NULL;
- return *this;
+ assert(cobj());
+ assert(node.type() == serd::NodeType::URI);
}
-URI::~URI()
+URI::URI(const FilePath& path)
+ : serd::Node{serd::make_file_uri(path.string())}
{
- serd_node_free(&_node);
}
URI
URI::make_relative(const URI& base) const
{
- SerdURI uri;
- SerdNode node = serd_node_new_relative_uri(&_uri, &base._uri, nullptr, &uri);
- return URI(node, uri);
+ return URI(serd::make_relative_uri(std::string(*this), base));
}
} // namespace ingen
diff --git a/src/URIs.cpp b/src/URIs.cpp
index dfe6b867..9c83a637 100644
--- a/src/URIs.cpp
+++ b/src/URIs.cpp
@@ -43,21 +43,8 @@ URIs::Quark::Quark(Forge& forge,
: URI(str)
, urid(forge.make_urid(URI(str)))
, uri(forge.alloc_uri(str))
- , lnode(lilv_new_uri(lworld, str))
{}
-URIs::Quark::Quark(const Quark& copy)
- : URI(copy)
- , urid(copy.urid)
- , uri(copy.uri)
- , lnode(lilv_node_duplicate(copy.lnode))
-{}
-
-URIs::Quark::~Quark()
-{
- lilv_node_free(lnode);
-}
-
#define NS_RDF "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
#define NS_RDFS "http://www.w3.org/2000/01/rdf-schema#"
diff --git a/src/World.cpp b/src/World.cpp
index 41e69826..12d10bb2 100644
--- a/src/World.cpp
+++ b/src/World.cpp
@@ -37,7 +37,7 @@
#include "lilv/lilv.h"
#include "lv2/log/log.h"
#include "lv2/urid/urid.h"
-#include "sord/sordmm.hpp"
+#include "serd/serd.hpp"
#include <cstdint>
#include <list>
@@ -90,7 +90,6 @@ public:
: argc(nullptr)
, argv(nullptr)
, lv2_features(nullptr)
- , rdf_world(new Sord::World())
, lilv_world(lilv_world_new(), lilv_world_free)
, uri_map(log, map, unmap)
, forge(uri_map)
@@ -108,16 +107,16 @@ public:
lilv_world_load_all(lilv_world.get());
// Set up RDF namespaces
- rdf_world->add_prefix("atom", "http://lv2plug.in/ns/ext/atom#");
- rdf_world->add_prefix("doap", "http://usefulinc.com/ns/doap#");
- rdf_world->add_prefix("ingen", INGEN_NS);
- rdf_world->add_prefix("lv2", "http://lv2plug.in/ns/lv2core#");
- rdf_world->add_prefix("midi", "http://lv2plug.in/ns/ext/midi#");
- rdf_world->add_prefix("owl", "http://www.w3.org/2002/07/owl#");
- rdf_world->add_prefix("patch", "http://lv2plug.in/ns/ext/patch#");
- rdf_world->add_prefix("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#");
- rdf_world->add_prefix("rdfs", "http://www.w3.org/2000/01/rdf-schema#");
- rdf_world->add_prefix("xsd", "http://www.w3.org/2001/XMLSchema#");
+ env.set_prefix("atom", "http://lv2plug.in/ns/ext/atom#");
+ env.set_prefix("doap", "http://usefulinc.com/ns/doap#");
+ env.set_prefix("ingen", INGEN_NS);
+ env.set_prefix("lv2", "http://lv2plug.in/ns/lv2core#");
+ env.set_prefix("midi", "http://lv2plug.in/ns/ext/midi#");
+ env.set_prefix("owl", "http://www.w3.org/2002/07/owl#");
+ env.set_prefix("patch", "http://lv2plug.in/ns/ext/patch#");
+ env.set_prefix("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#");
+ env.set_prefix("rdfs", "http://www.w3.org/2000/01/rdf-schema#");
+ env.set_prefix("xsd", "http://www.w3.org/2001/XMLSchema#");
// Load internal 'plugin' information into lilv world
LilvNode* rdf_type = lilv_new_uri(
@@ -183,7 +182,8 @@ public:
int* argc;
char*** argv;
LV2Features* lv2_features;
- UPtr<Sord::World> rdf_world;
+ serd::World rdf_world;
+ serd::Env env;
LilvWorldUPtr lilv_world;
URIMap uri_map;
Forge forge;
@@ -219,7 +219,8 @@ World::load_configuration(int& argc, char**& argv)
_impl->argv = &argv;
// Parse default configuration files
- const auto files = _impl->conf.load_default("ingen", "options.ttl");
+ const auto files =
+ _impl->conf.load_default(rdf_world(), "ingen", "options.ttl");
for (const auto& f : files) {
_impl->log.info("Loaded configuration %1%\n", f);
}
@@ -247,7 +248,8 @@ Log& World::log() { return _impl->log; }
std::mutex& World::rdf_mutex() { return _impl->rdf_mutex; }
-Sord::World* World::rdf_world() { return _impl->rdf_world.get(); }
+serd::World& World::rdf_world() { return _impl->rdf_world; }
+serd::Env& World::env() { return _impl->env; }
LilvWorld* World::lilv_world() { return _impl->lilv_world.get(); }
LV2Features& World::lv2_features() { return *_impl->lv2_features; }
diff --git a/src/client/ClientStore.cpp b/src/client/ClientStore.cpp
index a42efd16..2fdfa4a7 100644
--- a/src/client/ClientStore.cpp
+++ b/src/client/ClientStore.cpp
@@ -59,6 +59,7 @@ ClientStore::clear()
void
ClientStore::add_object(SPtr<ObjectModel> object)
{
+ _log.info("Add object %1%\n", object->path());
// If we already have "this" object, merge the existing one into the new
// one (with precedence to the new values).
auto existing = find(object->path());
diff --git a/src/client/PluginModel.cpp b/src/client/PluginModel.cpp
index f0e3c3a0..b0a2c5cb 100644
--- a/src/client/PluginModel.cpp
+++ b/src/client/PluginModel.cpp
@@ -38,8 +38,6 @@ namespace client {
LilvWorld* PluginModel::_lilv_world = nullptr;
const LilvPlugins* PluginModel::_lilv_plugins = nullptr;
-Sord::World* PluginModel::_rdf_world = nullptr;
-
PluginModel::PluginModel(URIs& uris,
const URI& uri,
const Atom& type,
@@ -65,7 +63,7 @@ PluginModel::PluginModel(URIs& uris,
if (uris.ingen_Internal == _type) {
set_property(uris.doap_name,
- uris.forge.alloc(std::string(uri.fragment().substr(1))));
+ uris.forge.alloc(uri.fragment().substr(1)));
}
}
@@ -103,7 +101,7 @@ PluginModel::get_property(const URI& key) const
// No lv2:symbol from data or engine, invent one
if (key == _uris.lv2_symbol) {
- string str = this->uri();
+ string str = this->uri().str();
size_t last_delim = last_uri_delim(str);
while (last_delim != string::npos &&
!contains_alpha_after(str, last_delim)) {
@@ -264,12 +262,13 @@ heading(const std::string& text, bool html, unsigned level)
}
static std::string
-link(const std::string& addr, bool html)
+link(const URI& addr, bool html)
{
if (html) {
- return std::string("<a href=\"") + addr + "\">" + addr + "</a>";
+ return std::string("<a href=\"") + addr.str() + "\">" + addr.str() +
+ "</a>";
} else {
- return addr;
+ return addr.str();
}
}
diff --git a/src/client/PluginUI.cpp b/src/client/PluginUI.cpp
index a997d716..72a1fba0 100644
--- a/src/client/PluginUI.cpp
+++ b/src/client/PluginUI.cpp
@@ -224,9 +224,9 @@ PluginUI::create(ingen::World& world,
bool
PluginUI::instantiate()
{
- const URIs& uris = _world.uris();
- const std::string plugin_uri = _block->plugin()->uri();
- LilvWorld* lworld = _world.lilv_world();
+ const URIs& uris = _world.uris();
+ const URI& plugin_uri = _block->plugin()->uri();
+ LilvWorld* lworld = _world.lilv_world();
// Load seeAlso files to access data like portNotification descriptions
lilv_world_load_resource(lworld, lilv_ui_get_uri(_ui));
diff --git a/src/client/wscript b/src/client/wscript
index 394c9e4d..c42046e1 100644
--- a/src/client/wscript
+++ b/src/client/wscript
@@ -10,7 +10,7 @@ def build(bld):
target = 'ingen_client',
install_path = '${LIBDIR}',
use = 'libingen',
- uselib = 'GLIBMM LV2 LILV SUIL RAUL SERD SORD SIGCPP')
+ uselib = 'GLIBMM LV2 LILV SUIL RAUL SERD SIGCPP')
obj.source = '''
BlockModel.cpp
diff --git a/src/gui/App.cpp b/src/gui/App.cpp
index dfa34998..0e2292eb 100644
--- a/src/gui/App.cpp
+++ b/src/gui/App.cpp
@@ -87,7 +87,7 @@ App::App(ingen::World& world)
, _requested_plugins(false)
, _is_plugin(false)
{
- _world.conf().load_default("ingen", "gui.ttl");
+ _world.conf().load_default(_world.rdf_world(), "ingen", "gui.ttl");
WidgetFactory::get_widget_derived("connect_win", _connect_window);
WidgetFactory::get_widget_derived("messages_win", _messages_window);
@@ -99,7 +99,6 @@ App::App(ingen::World& world)
_about_dialog->property_program_name() = "Ingen";
_about_dialog->property_logo_icon_name() = "ingen";
- PluginModel::set_rdf_world(*world.rdf_world());
PluginModel::set_lilv_world(world.lilv_world());
using namespace std::placeholders;
@@ -178,7 +177,8 @@ App::attach(SPtr<ingen::Interface> client)
}
if (_world.conf().option("dump").get<int32_t>()) {
- _dumper = SPtr<StreamWriter>(new StreamWriter(_world.uri_map(),
+ _dumper = SPtr<StreamWriter>(new StreamWriter(_world.rdf_world(),
+ _world.uri_map(),
_world.uris(),
URI("ingen:/client"),
stderr,
@@ -469,8 +469,11 @@ App::quit(Gtk::Window* dialog_parent)
Gtk::Main::quit();
try {
- const std::string path = _world.conf().save(
- _world.uri_map(), "ingen", "gui.ttl", Configuration::GUI);
+ const std::string path = _world.conf().save(_world.rdf_world(),
+ _world.uri_map(),
+ "ingen",
+ "gui.ttl",
+ Configuration::GUI);
std::cout << fmt("Saved GUI settings to %1%\n", path);
} catch (const std::exception& e) {
std::cerr << fmt("Error saving GUI settings (%1%)\n", e.what());
diff --git a/src/gui/ConnectWindow.cpp b/src/gui/ConnectWindow.cpp
index 209475e0..a7b2cbf7 100644
--- a/src/gui/ConnectWindow.cpp
+++ b/src/gui/ConnectWindow.cpp
@@ -228,7 +228,7 @@ ConnectWindow::connect(bool existing)
if (_mode == Mode::CONNECT_REMOTE) {
std::string uri_str = world.conf().option("connect").ptr<char>();
if (existing) {
- uri_str = world.interface()->uri();
+ uri_str = world.interface()->uri().str();
_connect_stage = 1;
SPtr<client::SocketClient> client = dynamic_ptr_cast<client::SocketClient>(
world.interface());
diff --git a/src/gui/GraphCanvas.cpp b/src/gui/GraphCanvas.cpp
index 13b17bdf..40373a1a 100644
--- a/src/gui/GraphCanvas.cpp
+++ b/src/gui/GraphCanvas.cpp
@@ -636,7 +636,7 @@ serialise_arc(GanvEdge* arc, void* data)
gui::Arc* garc = dynamic_cast<gui::Arc*>(Glib::wrap(GANV_EDGE(arc)));
if (garc) {
- serialiser->serialise_arc(Sord::Node(), garc->model());
+ serialiser->serialise_arc({}, garc->model());
}
}
@@ -690,7 +690,7 @@ GraphCanvas::paste()
// Figure out the copy graph base path
Raul::Path copy_root("/");
if (base_uri) {
- std::string base = *base_uri;
+ std::string base = base_uri->str();
if (base[base.size() - 1] == '/') {
base = base.substr(0, base.size() - 1);
}
diff --git a/src/gui/LoadPluginWindow.cpp b/src/gui/LoadPluginWindow.cpp
index bb84f96f..32a35c65 100644
--- a/src/gui/LoadPluginWindow.cpp
+++ b/src/gui/LoadPluginWindow.cpp
@@ -459,7 +459,7 @@ LoadPluginWindow::filter_changed()
field = get_author_name(plugin);
break;
case CriteriaColumns::Criteria::URI:
- field = plugin->uri();
+ field = plugin->uri().str();
break;
}
diff --git a/src/gui/NodeMenu.cpp b/src/gui/NodeMenu.cpp
index e2478592..ef0e80dc 100644
--- a/src/gui/NodeMenu.cpp
+++ b/src/gui/NodeMenu.cpp
@@ -235,11 +235,11 @@ NodeMenu::on_save_preset_activated()
}
void
-NodeMenu::on_preset_activated(const std::string& uri)
+NodeMenu::on_preset_activated(const URI& uri)
{
_app->set_property(block()->uri(),
_app->uris().pset_preset,
- _app->forge().make_urid(URI(uri)));
+ _app->forge().make_urid(uri));
}
bool
diff --git a/src/gui/NodeMenu.hpp b/src/gui/NodeMenu.hpp
index 2a3268b4..799abef3 100644
--- a/src/gui/NodeMenu.hpp
+++ b/src/gui/NodeMenu.hpp
@@ -60,7 +60,7 @@ protected:
void on_menu_enabled();
void on_menu_randomize();
void on_save_preset_activated();
- void on_preset_activated(const std::string& uri);
+ void on_preset_activated(const URI& uri);
Gtk::MenuItem* _popup_gui_menuitem;
Gtk::CheckMenuItem* _embed_gui_menuitem;
diff --git a/src/gui/Port.cpp b/src/gui/Port.cpp
index 14f87fc1..63e90bdd 100644
--- a/src/gui/Port.cpp
+++ b/src/gui/Port.cpp
@@ -289,8 +289,8 @@ Port::build_uri_menu()
// Add a menu item for each such class
for (const auto& v : values) {
if (!v.first.empty()) {
- const std::string qname = world.rdf_world()->prefixes().qualify(v.second);
- const std::string label = qname + " - " + v.first;
+ const auto qname = world.env().qualify(v.second);
+ const std::string label = std::string(*qname) + " - " + v.first;
menu->items().push_back(Gtk::Menu_Helpers::MenuElem(label));
Gtk::MenuItem* menu_item = &(menu->items().back());
menu_item->signal_activate().connect(
diff --git a/src/gui/PropertiesWindow.cpp b/src/gui/PropertiesWindow.cpp
index 9912f73a..32ed24e5 100644
--- a/src/gui/PropertiesWindow.cpp
+++ b/src/gui/PropertiesWindow.cpp
@@ -114,7 +114,8 @@ PropertiesWindow::add_property(const URI& key, const Atom& value)
LilvNode* prop = lilv_new_uri(world.lilv_world(), key.c_str());
std::string name = rdfs::label(world, prop);
if (name.empty()) {
- name = world.rdf_world()->prefixes().qualify(key);
+ const auto qname = world.env().qualify(key);
+ name = qname ? std::string(*qname) : key.str();
}
Gtk::Label* label = new Gtk::Label(
std::string("<a href=\"") + key.string() + "\">" + name + "</a>",
diff --git a/src/gui/ingen_gui_lv2.cpp b/src/gui/ingen_gui_lv2.cpp
index 4817e9ae..4107d5c0 100644
--- a/src/gui/ingen_gui_lv2.cpp
+++ b/src/gui/ingen_gui_lv2.cpp
@@ -143,6 +143,7 @@ instantiate(const LV2UI_Descriptor* descriptor,
// Set up an engine interface that writes LV2 atoms
ui->engine = SPtr<ingen::Interface>(
new ingen::AtomWriter(
+ ui->world->rdf_world(),
ui->world->uri_map(), ui->world->uris(), *ui->sink));
ui->world->set_interface(ui->engine);
diff --git a/src/gui/wscript b/src/gui/wscript
index b33bd31e..2a52849e 100644
--- a/src/gui/wscript
+++ b/src/gui/wscript
@@ -57,11 +57,10 @@ def build(bld):
LILV
LV2
RAUL
- SIGCPP
SERD
- SORD
- SRATOM
+ SIGCPP
SOUP
+ SRATOM
SUIL
WEBKIT
''')
@@ -124,4 +123,4 @@ def build(bld):
target = 'ingen_gui_lv2',
install_path = '${LV2DIR}/ingen.lv2/',
use = 'libingen libingen_gui',
- uselib = 'LV2 SERD SORD SRATOM LILV RAUL GLIBMM GTKMM')
+ uselib = 'LV2 SERD SRATOM LILV RAUL GLIBMM GTKMM')
diff --git a/src/ingen/ingen.cpp b/src/ingen/ingen.cpp
index 15544c10..214e9e01 100644
--- a/src/ingen/ingen.cpp
+++ b/src/ingen/ingen.cpp
@@ -200,31 +200,26 @@ main(int argc, char** argv)
*world, *engine_interface, graph, parent, symbol);
} else if (conf.option("server-load").is_valid()) {
const char* path = conf.option("server-load").ptr<char>();
- if (serd_uri_string_has_scheme((const uint8_t*)path)) {
+ if (serd_uri_string_has_scheme(path)) {
std::cout << "Loading " << path << " (server side)" << std::endl;
engine_interface->copy(URI(path), main_uri());
} else {
- SerdNode uri = serd_node_new_file_uri(
- (const uint8_t*)path, nullptr, nullptr, true);
- std::cout << "Loading " << (const char*)uri.buf
- << " (server side)" << std::endl;
- engine_interface->copy(URI((const char*)uri.buf), main_uri());
- serd_node_free(&uri);
+ serd::Node uri = serd::make_file_uri(path);
+ std::cout << "Loading " << uri << " (server side)" << std::endl;
+ engine_interface->copy(URI(uri), main_uri());
}
}
// Save the currently loaded graph
if (conf.option("save").is_valid()) {
const char* path = conf.option("save").ptr<char>();
- if (serd_uri_string_has_scheme((const uint8_t*)path)) {
+ if (serd_uri_string_has_scheme(path)) {
std::cout << "Saving to " << path << std::endl;
engine_interface->copy(main_uri(), URI(path));
} else {
- SerdNode uri = serd_node_new_file_uri(
- (const uint8_t*)path, nullptr, nullptr, true);
- std::cout << "Saving to " << (const char*)uri.buf << std::endl;
- engine_interface->copy(main_uri(), URI((const char*)uri.buf));
- serd_node_free(&uri);
+ serd::Node uri = serd::make_file_uri(path);
+ std::cout << "Saving to " << uri << std::endl;
+ engine_interface->copy(main_uri(), URI(uri));
}
}
@@ -256,8 +251,12 @@ main(int argc, char** argv)
}
// Save configuration to restore preferences on next run
- const std::string path = conf.save(
- world->uri_map(), "ingen", "options.ttl", Configuration::GLOBAL);
+ const std::string path = conf.save(world->rdf_world(),
+ world->uri_map(),
+ "ingen",
+ "options.ttl",
+ Configuration::GLOBAL);
+
std::cout << fmt("Saved configuration to %1%\n", path);
engine_interface.reset();
diff --git a/src/server/Engine.cpp b/src/server/Engine.cpp
index 8256981b..f1a86792 100644
--- a/src/server/Engine.cpp
+++ b/src/server/Engine.cpp
@@ -68,31 +68,37 @@ INGEN_THREAD_LOCAL unsigned ThreadManager::flags(0);
bool ThreadManager::single_threaded(true);
Engine::Engine(ingen::World& world)
- : _world(world)
- , _options(new LV2Options(world.uris()))
- , _buffer_factory(new BufferFactory(*this, world.uris()))
- , _maid(new Raul::Maid)
- , _worker(new Worker(world.log(), event_queue_size()))
- , _sync_worker(new Worker(world.log(), event_queue_size(), true))
- , _broadcaster(new Broadcaster())
- , _control_bindings(new ControlBindings(*this))
- , _block_factory(new BlockFactory(world))
- , _undo_stack(new UndoStack(world.uris(), world.uri_map()))
- , _redo_stack(new UndoStack(world.uris(), world.uri_map()))
- , _post_processor(new PostProcessor(*this))
- , _pre_processor(new PreProcessor(*this))
- , _event_writer(new EventWriter(*this))
- , _interface(_event_writer)
- , _atom_interface(
- new AtomReader(world.uri_map(), world.uris(), world.log(), *_interface))
- , _root_graph(nullptr)
- , _cycle_start_time(0)
- , _rand_engine(reinterpret_cast<uintptr_t>(this))
- , _uniform_dist(0.0f, 1.0f)
- , _quit_flag(false)
- , _reset_load_flag(false)
- , _atomic_bundles(world.conf().option("atomic-bundles").get<int32_t>())
- , _activated(false)
+ : _world(world)
+ , _options(new LV2Options(world.uris()))
+ , _buffer_factory(new BufferFactory(*this, world.uris()))
+ , _maid(new Raul::Maid)
+ , _worker(new Worker(world.log(), event_queue_size()))
+ , _sync_worker(new Worker(world.log(), event_queue_size(), true))
+ , _broadcaster(new Broadcaster())
+ , _control_bindings(new ControlBindings(*this))
+ , _block_factory(new BlockFactory(world))
+ , _undo_stack(new UndoStack(world.rdf_world(),
+ world.uris(),
+ world.uri_map()))
+ , _redo_stack(new UndoStack(world.rdf_world(),
+ world.uris(),
+ world.uri_map()))
+ , _post_processor(new PostProcessor(*this))
+ , _pre_processor(new PreProcessor(*this))
+ , _event_writer(new EventWriter(*this))
+ , _interface(_event_writer)
+ , _atom_interface(new AtomReader(world.uri_map(),
+ world.uris(),
+ world.log(),
+ *_interface))
+ , _root_graph(nullptr)
+ , _cycle_start_time(0)
+ , _rand_engine(reinterpret_cast<uintptr_t>(this))
+ , _uniform_dist(0.0f, 1.0f)
+ , _quit_flag(false)
+ , _reset_load_flag(false)
+ , _atomic_bundles(world.conf().option("atomic-bundles").get<int32_t>())
+ , _activated(false)
{
if (!world.store()) {
world.set_store(std::make_shared<ingen::Store>());
@@ -125,7 +131,8 @@ Engine::Engine(ingen::World& world)
_interface = std::make_shared<Tee>(
Tee::Sinks{
_event_writer,
- std::make_shared<StreamWriter>(world.uri_map(),
+ std::make_shared<StreamWriter>(world.rdf_world(),
+ world.uri_map(),
world.uris(),
URI("ingen:/engine"),
stderr,
diff --git a/src/server/Event.hpp b/src/server/Event.hpp
index 7da4b955..f5c826b4 100644
--- a/src/server/Event.hpp
+++ b/src/server/Event.hpp
@@ -133,7 +133,7 @@ protected:
}
inline bool pre_process_done(Status st, const URI& subject) {
- _err_subject = subject;
+ _err_subject = std::string{subject};
return pre_process_done(st);
}
diff --git a/src/server/LV2Plugin.cpp b/src/server/LV2Plugin.cpp
index 01357d8d..40ba34e7 100644
--- a/src/server/LV2Plugin.cpp
+++ b/src/server/LV2Plugin.cpp
@@ -68,7 +68,7 @@ LV2Plugin::update_properties()
Raul::Symbol
LV2Plugin::symbol() const
{
- std::string working = uri();
+ std::string working(uri());
if (working.back() == '/') {
working = working.substr(0, working.length() - 1);
}
diff --git a/src/server/PreProcessor.cpp b/src/server/PreProcessor.cpp
index 872302c0..76e0ac73 100644
--- a/src/server/PreProcessor.cpp
+++ b/src/server/PreProcessor.cpp
@@ -176,8 +176,10 @@ PreProcessor::run()
UndoStack& undo_stack = *_engine.undo_stack();
UndoStack& redo_stack = *_engine.redo_stack();
AtomWriter undo_writer(
+ _engine.world().rdf_world(),
_engine.world().uri_map(), _engine.world().uris(), undo_stack);
AtomWriter redo_writer(
+ _engine.world().rdf_world(),
_engine.world().uri_map(), _engine.world().uris(), redo_stack);
ThreadManager::set_flag(THREAD_PRE_PROCESS);
diff --git a/src/server/SocketListener.cpp b/src/server/SocketListener.cpp
index b4b50a14..51e07b2b 100644
--- a/src/server/SocketListener.cpp
+++ b/src/server/SocketListener.cpp
@@ -92,7 +92,7 @@ ingen_listen(Engine* engine, Raul::Socket* unix_sock, Raul::Socket* net_sock)
// Bind UNIX socket and create PID-less symbolic link
const URI unix_uri(unix_scheme + unix_path);
bool make_link = true;
- if (!unix_sock->bind(unix_uri) || !unix_sock->listen()) {
+ if (!unix_sock->bind(unix_uri.str()) || !unix_sock->listen()) {
world.log().error("Failed to create UNIX socket\n");
unix_sock->close();
make_link = false;
@@ -130,7 +130,7 @@ ingen_listen(Engine* engine, Raul::Socket* unix_sock, Raul::Socket* net_sock)
const int port = world.conf().option("engine-port").get<int32_t>();
std::ostringstream ss;
ss << "tcp://*:" << port;
- if (!net_sock->bind(URI(ss.str())) || !net_sock->listen()) {
+ if (!net_sock->bind(ss.str()) || !net_sock->listen()) {
world.log().error("Failed to create TCP socket\n");
net_sock->close();
} else {
diff --git a/src/server/SocketServer.hpp b/src/server/SocketServer.hpp
index f3f02a26..86f81d65 100644
--- a/src/server/SocketServer.hpp
+++ b/src/server/SocketServer.hpp
@@ -43,14 +43,16 @@ public:
, _sink(world.conf().option("dump").get<int32_t>()
? SPtr<Interface>(
new Tee({SPtr<Interface>(new EventWriter(engine)),
- SPtr<Interface>(new StreamWriter(world.uri_map(),
+ SPtr<Interface>(new StreamWriter(world.rdf_world(),
+ world.uri_map(),
world.uris(),
URI("ingen:/engine"),
stderr,
ColorContext::Color::CYAN))}))
: SPtr<Interface>(new EventWriter(engine)))
, _reader(new SocketReader(world, *_sink.get(), sock))
- , _writer(new SocketWriter(world.uri_map(),
+ , _writer(new SocketWriter(world.rdf_world(),
+ world.uri_map(),
world.uris(),
URI(sock->uri()),
sock))
diff --git a/src/server/UndoStack.cpp b/src/server/UndoStack.cpp
index a94617a5..d6829200 100644
--- a/src/server/UndoStack.cpp
+++ b/src/server/UndoStack.cpp
@@ -23,15 +23,14 @@
#include "lv2/patch/patch.h"
#include "lv2/urid/urid.h"
#include "serd/serd.h"
-#include "sratom/sratom.h"
+#include "sratom/sratom.hpp"
#include <ctime>
+#include <fstream>
#include <iterator>
#include <memory>
-#define NS_RDF (const uint8_t*)"http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-
-#define USTR(s) ((const uint8_t*)(s))
+#define NS_RDF "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
namespace ingen {
namespace server {
@@ -120,9 +119,9 @@ UndoStack::pop()
struct BlankIDs {
explicit BlankIDs(char c='b') : c(c) {}
- SerdNode get() {
+ serd::Node get() {
snprintf(buf, sizeof(buf), "%c%u", c, n++);
- return serd_node_from_string(SERD_BLANK, USTR(buf));
+ return serd::make_blank(buf);
}
char buf[16]{};
@@ -131,126 +130,120 @@ struct BlankIDs {
};
struct ListContext {
- explicit ListContext(BlankIDs& ids, unsigned flags, const SerdNode* s, const SerdNode* p)
- : ids(ids)
- , s(*s)
- , p(*p)
- , flags(flags | SERD_LIST_O_BEGIN)
+ explicit ListContext(BlankIDs& ids,
+ serd::StatementFlags flags,
+ const serd::Node& s,
+ const serd::Node& p)
+ : ids(ids)
+ , s(s)
+ , p(p)
+ , flags(flags | serd::StatementFlag::list_O)
{}
- SerdNode start_node(SerdWriter* writer) {
- const SerdNode node = ids.get();
- serd_writer_write_statement(writer, flags, nullptr, &s, &p, &node, nullptr, nullptr);
+ serd::Node start_node(serd::Writer& writer) {
+ const serd::Node node = ids.get();
+ writer.sink().write(flags, s, p, node);
return node;
}
- void append(SerdWriter* writer, unsigned oflags, const SerdNode* value) {
+ void append(serd::Writer& writer,
+ serd::StatementFlags oflags,
+ const serd::Node& value)
+ {
// s p node
- const SerdNode node = start_node(writer);
+ const serd::Node node = start_node(writer);
// node rdf:first value
- p = serd_node_from_string(SERD_URI, NS_RDF "first");
- flags = SERD_LIST_CONT;
- serd_writer_write_statement(writer, flags|oflags, nullptr, &node, &p, value, nullptr, nullptr);
+ p = serd::make_uri(NS_RDF "first");
+ flags = {};
+ writer.sink().write(flags | oflags, node, p, value);
- end_node(writer, &node);
+ end_node(writer, node);
}
- void end_node(SerdWriter*, const SerdNode* node) {
+ void end_node(serd::Writer&, const serd::Node& node) {
// Prepare for next call: node rdf:rest ...
- s = *node;
- p = serd_node_from_string(SERD_URI, NS_RDF "rest");
+ s = node;
+ p = serd::make_uri(NS_RDF "rest");
}
- void end(SerdWriter* writer) {
- const SerdNode nil = serd_node_from_string(SERD_URI, NS_RDF "nil");
- serd_writer_write_statement(writer, flags, nullptr, &s, &p, &nil, nullptr, nullptr);
+ void end(serd::Writer& writer) {
+ const serd::Node nil = serd::make_uri(NS_RDF "nil");
+ writer.sink().write(flags, s, p, nil);
}
- BlankIDs& ids;
- SerdNode s;
- SerdNode p;
- unsigned flags;
+ BlankIDs& ids;
+ serd::Node s;
+ serd::Node p;
+ serd::StatementFlags flags;
};
void
-UndoStack::write_entry(Sratom* sratom,
- SerdWriter* writer,
- const SerdNode* const subject,
+UndoStack::write_entry(sratom::Streamer& streamer,
+ serd::Writer& writer,
+ const serd::Node& subject,
const UndoStack::Entry& entry)
{
char time_str[24];
strftime(time_str, sizeof(time_str), "%FT%T", gmtime(&entry.time));
- // entry rdf:type ingen:UndoEntry
- SerdNode p = serd_node_from_string(SERD_URI, USTR(INGEN_NS "time"));
- SerdNode o = serd_node_from_string(SERD_LITERAL, USTR(time_str));
- serd_writer_write_statement(writer, SERD_ANON_CONT, nullptr, subject, &p, &o, nullptr, nullptr);
+ writer.sink().write({},
+ subject,
+ serd::make_uri(INGEN_NS "time"),
+ serd::make_string(time_str));
- p = serd_node_from_string(SERD_URI, USTR(INGEN_NS "events"));
+ serd::Node p = serd::make_uri(INGEN_NS "events");
BlankIDs ids('e');
- ListContext ctx(ids, SERD_ANON_CONT, subject, &p);
+ ListContext ctx(ids, {}, subject, p);
for (const LV2_Atom* atom : entry.events) {
- const SerdNode node = ctx.start_node(writer);
-
- p = serd_node_from_string(SERD_URI, NS_RDF "first");
- ctx.flags = SERD_LIST_CONT;
- sratom_write(sratom, &_map.urid_unmap_feature()->urid_unmap, SERD_LIST_CONT,
- &node, &p,
- atom->type, atom->size, LV2_ATOM_BODY_CONST(atom));
+ const serd::Node node = ctx.start_node(writer);
- ctx.end_node(writer, &node);
+ p = serd::make_uri(NS_RDF "first");
+ ctx.flags = {};
+ streamer.write(writer.sink(), node, p, *atom);
+ ctx.end_node(writer, node);
}
ctx.end(writer);
}
void
-UndoStack::save(FILE* stream, const char* name)
+UndoStack::save(std::ofstream& stream, const char* name)
{
- SerdEnv* env = serd_env_new(nullptr);
- serd_env_set_prefix_from_strings(env, USTR("atom"), USTR(LV2_ATOM_PREFIX));
- serd_env_set_prefix_from_strings(env, USTR("ingen"), USTR(INGEN_NS));
- serd_env_set_prefix_from_strings(env, USTR("patch"), USTR(LV2_PATCH_PREFIX));
-
- const SerdNode base = serd_node_from_string(SERD_URI, USTR("ingen:/"));
- SerdURI base_uri;
- serd_uri_parse(base.buf, &base_uri);
-
- SerdWriter* writer = serd_writer_new(
- SERD_TURTLE,
- (SerdStyle)(SERD_STYLE_RESOLVED|SERD_STYLE_ABBREVIATED|SERD_STYLE_CURIED),
- env,
- &base_uri,
- serd_file_sink,
- stream);
+ serd::Env env;
+ env.set_prefix("atom", LV2_ATOM_PREFIX);
+ env.set_prefix("ingen", INGEN_NS);
+ env.set_prefix("patch", LV2_PATCH_PREFIX);
+
+ const serd::Node base = serd::make_uri("ingen:/");
+
+ serd::Writer writer(_world,
+ serd::Syntax::Turtle,
+ {},
+ env,
+ stream);
// Configure sratom to write directly to the writer (and thus the socket)
- Sratom* sratom = sratom_new(&_map.urid_map_feature()->urid_map);
- sratom_set_sink(sratom,
- (const char*)base.buf,
- (SerdStatementSink)serd_writer_write_statement,
- (SerdEndSink)serd_writer_end_anon,
- writer);
+ sratom::Streamer streamer{_world,
+ _map.urid_map_feature()->urid_map,
+ _map.urid_unmap_feature()->urid_unmap};
- SerdNode s = serd_node_from_string(SERD_BLANK, (const uint8_t*)name);
- SerdNode p = serd_node_from_string(SERD_URI, USTR(INGEN_NS "entries"));
+ serd::Node s = serd::make_blank(name);
+ serd::Node p = serd::make_uri(INGEN_NS "entries");
BlankIDs ids('u');
- ListContext ctx(ids, 0, &s, &p);
+ ListContext ctx(ids, {}, s, p);
for (const Entry& e : _stack) {
- const SerdNode entry = ids.get();
- ctx.append(writer, SERD_ANON_O_BEGIN, &entry);
- write_entry(sratom, writer, &entry, e);
- serd_writer_end_anon(writer, &entry);
+ const serd::Node entry = ids.get();
+ ctx.append(writer, serd::StatementFlag::anon_O, entry);
+ write_entry(streamer, writer, entry, e);
+ writer.sink().end(entry);
}
ctx.end(writer);
- sratom_free(sratom);
- serd_writer_finish(writer);
- serd_writer_free(writer);
+ writer.finish();
}
} // namespace server
diff --git a/src/server/UndoStack.hpp b/src/server/UndoStack.hpp
index 04021b99..7d79e7fc 100644
--- a/src/server/UndoStack.hpp
+++ b/src/server/UndoStack.hpp
@@ -21,8 +21,7 @@
#include "ingen/ingen.h"
#include "lv2/atom/atom.h"
#include "lv2/atom/util.h"
-#include "serd/serd.h"
-#include "sratom/sratom.h"
+#include "serd/serd.hpp"
#include <cstdint>
#include <cstdio>
@@ -30,6 +29,9 @@
#include <cstring>
#include <ctime>
#include <deque>
+#include <iosfwd>
+
+namespace sratom { class Streamer; }
namespace ingen {
@@ -80,7 +82,10 @@ public:
std::deque<LV2_Atom*> events;
};
- UndoStack(URIs& uris, URIMap& map) : _uris(uris), _map(map), _depth(0) {}
+ UndoStack(serd::World& world, URIs& uris, URIMap& map)
+ : _world(world), _uris(uris), _map(map), _depth(0)
+ {
+ }
int start_entry();
bool write(const LV2_Atom* msg, int32_t default_id=0) override;
@@ -89,17 +94,18 @@ public:
bool empty() const { return _stack.empty(); }
Entry pop();
- void save(FILE* stream, const char* name="undo");
+ void save(std::ofstream& stream, const char* name="undo");
private:
bool ignore_later_event(const LV2_Atom* first,
const LV2_Atom* second) const;
- void write_entry(Sratom* sratom,
- SerdWriter* writer,
- const SerdNode* subject,
- const Entry& entry);
+ void write_entry(sratom::Streamer& streamer,
+ serd::Writer& writer,
+ const serd::Node& subject,
+ const Entry& entry);
+ serd::World& _world;
URIs& _uris;
URIMap& _map;
std::deque<Entry> _stack;
diff --git a/src/server/events/Copy.cpp b/src/server/events/Copy.cpp
index 5418af4b..5ac31f55 100644
--- a/src/server/events/Copy.cpp
+++ b/src/server/events/Copy.cpp
@@ -131,9 +131,10 @@ Copy::engine_to_engine(PreProcessContext& ctx)
}
static bool
-ends_with(const std::string& str, const std::string& end)
+ends_with(const URI& uri, const std::string& end)
{
- if (str.length() >= end.length()) {
+ const auto& str = uri.str();
+ if (str.length() >= end.length()) {
return !str.compare(str.length() - end.length(), end.length(), end);
}
return false;
diff --git a/src/server/events/Delta.cpp b/src/server/events/Delta.cpp
index 0a7b05ea..ab751b76 100644
--- a/src/server/events/Delta.cpp
+++ b/src/server/events/Delta.cpp
@@ -35,6 +35,8 @@
#include "ingen/World.hpp"
#include "raul/Maid.hpp"
+#include <boost/optional/optional_io.hpp>
+
#include <mutex>
#include <set>
#include <string>
@@ -364,7 +366,7 @@ Delta::pre_process(PreProcessContext& ctx)
_status = Status::BAD_VALUE_TYPE;
}
} else if (key == uris.pset_preset) {
- URI uri;
+ boost::optional<URI> uri;
if (uris.forge.is_uri(value)) {
const std::string uri_str = uris.forge.str(value, false);
if (URI::is_valid(uri_str)) {
@@ -374,9 +376,9 @@ Delta::pre_process(PreProcessContext& ctx)
uri = URI(FilePath(value.ptr<char>()));
}
- if (!uri.empty()) {
+ if (uri) {
op = SpecialType::PRESET;
- if ((_state = block->load_preset(uri))) {
+ if ((_state = block->load_preset(*uri))) {
lilv_state_emit_port_values(
_state, s_add_set_event, this);
} else {
diff --git a/src/server/ingen_lv2.cpp b/src/server/ingen_lv2.cpp
index 57663344..8a639765 100644
--- a/src/server/ingen_lv2.cpp
+++ b/src/server/ingen_lv2.cpp
@@ -60,8 +60,7 @@
#include "raul/RingBuffer.hpp"
#include "raul/Semaphore.hpp"
#include "raul/Symbol.hpp"
-#include "serd/serd.h"
-#include "sord/sordmm.hpp"
+#include "serd/serd.hpp"
#include <algorithm>
#include <cstdint>
@@ -123,7 +122,8 @@ public:
engine.world().uris(),
engine.world().log(),
*engine.world().interface().get())
- , _writer(engine.world().uri_map(),
+ , _writer(engine.world().rdf_world(),
+ engine.world().uri_map(),
engine.world().uris(),
*this)
, _from_ui(ui_ring_size(block_length))
@@ -460,11 +460,10 @@ struct IngenPlugin {
static Lib::Graphs
find_graphs(const URI& manifest_uri)
{
- Sord::World world;
+ serd::World world;
Parser parser;
const std::set<Parser::ResourceRecord> resources = parser.find_resources(
- world,
manifest_uri,
URI(INGEN__Graph));
@@ -512,11 +511,8 @@ ingen_instantiate(const LV2_Descriptor* descriptor,
set_bundle_path(bundle_path);
const std::string manifest_path = ingen::bundle_file_path("manifest.ttl");
- SerdNode manifest_node = serd_node_new_file_uri(
- (const uint8_t*)manifest_path.c_str(), nullptr, nullptr, true);
-
- Lib::Graphs graphs = find_graphs(URI((const char*)manifest_node.buf));
- serd_node_free(&manifest_node);
+ serd::Node manifest_node = serd::make_file_uri(manifest_path);
+ Lib::Graphs graphs = find_graphs(URI(manifest_node));
const LV2Graph* graph = nullptr;
for (const auto& g : graphs) {
@@ -823,13 +819,9 @@ LV2Graph::LV2Graph(Parser::ResourceRecord record)
Lib::Lib(const char* bundle_path)
{
ingen::set_bundle_path(bundle_path);
- const std::string manifest_path = ingen::bundle_file_path("manifest.ttl");
- SerdNode manifest_node = serd_node_new_file_uri(
- (const uint8_t*)manifest_path.c_str(), nullptr, nullptr, true);
-
- graphs = find_graphs(URI((const char*)manifest_node.buf));
- serd_node_free(&manifest_node);
+ const auto manifest_path = ingen::bundle_file_path("manifest.ttl");
+ graphs = find_graphs(serd::make_file_uri(manifest_path.string()));
}
static void
diff --git a/src/server/wscript b/src/server/wscript
index 00588915..137b85c9 100644
--- a/src/server/wscript
+++ b/src/server/wscript
@@ -53,7 +53,7 @@ def build(bld):
mix.cpp
'''
- core_libs = 'LV2 LILV RAUL SERD SORD SRATOM'
+ core_libs = 'LV2 LILV RAUL SERD SRATOM'
bld(features = 'cxx cxxshlib',
source = core_source,
diff --git a/src/wscript b/src/wscript
index 72c7d48c..39789778 100644
--- a/src/wscript
+++ b/src/wscript
@@ -41,7 +41,7 @@ def build(bld):
vnum = bld.env.INGEN_VERSION,
install_path = '${LIBDIR}',
lib = lib,
- uselib = 'LV2 LILV RAUL SERD SORD SRATOM',
+ uselib = 'LV2 LILV RAUL SERD SRATOM',
cxxflags = (['-fvisibility=hidden'] +
bld.env.PTHREAD_CFLAGS + bld.env.INGEN_TEST_CXXFLAGS),
linkflags = bld.env.PTHREAD_LINKFLAGS + bld.env.INGEN_TEST_LINKFLAGS)