summaryrefslogtreecommitdiffstats
path: root/src/serialisation
diff options
context:
space:
mode:
Diffstat (limited to 'src/serialisation')
-rw-r--r--src/serialisation/Parser.cpp652
-rw-r--r--src/serialisation/Parser.hpp128
-rw-r--r--src/serialisation/Serialiser.cpp167
-rw-r--r--src/serialisation/Serialiser.hpp116
-rw-r--r--src/serialisation/names.hpp24
-rw-r--r--src/serialisation/serialisation.cpp4
6 files changed, 469 insertions, 622 deletions
diff --git a/src/serialisation/Parser.cpp b/src/serialisation/Parser.cpp
index 198a520e..27110c9d 100644
--- a/src/serialisation/Parser.cpp
+++ b/src/serialisation/Parser.cpp
@@ -38,8 +38,7 @@
#include "shared/World.hpp"
#include "shared/LV2URIMap.hpp"
-#include "Parser.hpp"
-#include "names.hpp"
+#include "ingen/serialisation/Parser.hpp"
#define LOG(s) s << "[Parser] "
@@ -102,226 +101,6 @@ skip_property(const Sord::Node& predicate)
|| predicate.to_string() == "http://lv2plug.in/ns/lv2core#port");
}
-Parser::Parser(Ingen::Shared::World& world)
-{
-}
-
-Parser::PatchRecords
-Parser::find_patches(Ingen::Shared::World* world,
- SerdEnv* env,
- const Glib::ustring& manifest_uri)
-{
- const Sord::URI ingen_Patch (*world->rdf_world(), NS_INGEN "Patch");
- const Sord::URI rdf_type (*world->rdf_world(), NS_RDF "type");
- const Sord::URI rdfs_seeAlso(*world->rdf_world(), NS_RDFS "seeAlso");
-
- Sord::Model model(*world->rdf_world(), manifest_uri);
- model.load_file(env, SERD_TURTLE, manifest_uri);
-
- std::list<PatchRecord> records;
- for (Sord::Iter i = model.find(nil, rdf_type, ingen_Patch); !i.end(); ++i) {
- const Sord::Node patch = i.get_subject();
- Sord::Iter f = model.find(patch, rdfs_seeAlso, nil);
- if (!f.end()) {
- records.push_back(PatchRecord(patch.to_c_string(),
- f.get_object().to_c_string()));
- } else {
- LOG(error) << "Patch has no rdfs:seeAlso" << endl;
- }
- }
- return records;
-}
-
-/** Parse a patch from RDF into a CommonInterface (engine or client).
- * @return whether or not load was successful.
- */
-bool
-Parser::parse_file(Ingen::Shared::World* world,
- Ingen::CommonInterface* target,
- Glib::ustring file_uri,
- boost::optional<Raul::Path> parent,
- boost::optional<Raul::Symbol> symbol,
- boost::optional<GraphObject::Properties> data)
-{
- const size_t colon = file_uri.find(":");
- if (colon != Glib::ustring::npos) {
- const Glib::ustring scheme = file_uri.substr(0, colon);
- if (scheme != "file") {
- LOG(error) << (boost::format("Unsupported URI scheme `%1%'")
- % scheme) << endl;
- return false;
- }
- } else {
- file_uri = Glib::ustring("file://") + file_uri;
- }
-
- const bool is_bundle = (file_uri.substr(file_uri.length() - 4) != ".ttl");
-
- if (is_bundle && file_uri[file_uri.length() - 1] != '/') {
- file_uri.append("/");
- }
-
- SerdNode base_node = serd_node_from_string(
- SERD_URI, (const uint8_t*)file_uri.c_str());
- SerdEnv* env = serd_env_new(&base_node);
-
- if (file_uri.substr(file_uri.length() - 4) != ".ttl") {
- // Not a Turtle file, try to open it as a bundle
- if (file_uri[file_uri.length() - 1] != '/') {
- file_uri.append("/");
- }
- Parser::PatchRecords records = find_patches(world, env, file_uri + "manifest.ttl");
- if (!records.empty()) {
- file_uri = records.front().file_uri;
- }
- }
-
- base_node = serd_node_from_string(
- SERD_URI, (const uint8_t*)file_uri.c_str());
- serd_env_set_base_uri(env, &base_node);
-
- // Load patch file into model
- Sord::Model model(*world->rdf_world(), file_uri);
- model.load_file(env, SERD_TURTLE, file_uri);
-
- serd_env_free(env);
-
- LOG(info) << "Parsing " << file_uri << endl;
- if (parent)
- LOG(info) << "Parent: " << *parent << endl;
- if (symbol)
- LOG(info) << "Symbol: " << *symbol << endl;
-
- boost::optional<Path> parsed_path
- = parse(world, target, model, file_uri, Path("/"), parent, symbol, data);
-
- if (parsed_path) {
- target->set_property(*parsed_path, "http://drobilla.net/ns/ingen#document",
- Atom(Atom::URI, file_uri.c_str()));
- } else {
- LOG(warn) << "Document URI lost" << endl;
- }
-
- return parsed_path;
-}
-
-bool
-Parser::parse_string(Ingen::Shared::World* world,
- Ingen::CommonInterface* target,
- const Glib::ustring& str,
- const Glib::ustring& base_uri,
- boost::optional<Raul::Path> parent,
- boost::optional<Raul::Symbol> symbol,
- boost::optional<GraphObject::Properties> data)
-{
- // Load string into model
- Sord::Model model(*world->rdf_world(), base_uri);
- SerdEnv* env = serd_env_new(NULL);
- model.load_string(env, SERD_TURTLE, str.c_str(), str.length(), base_uri);
- serd_env_free(env);
-
- LOG(info) << "Parsing string";
- if (!base_uri.empty())
- info << " (base " << base_uri << ")";
- info << endl;
-
- boost::optional<Raul::Path> data_path;
- bool ret = parse(world, target, model, base_uri, data_path, parent, symbol, data);
- Sord::URI subject(*world->rdf_world(), base_uri);
- parse_connections(world, target, model, subject, parent ? *parent : "/");
-
- return ret;
-}
-
-boost::optional<Path>
-Parser::parse(Ingen::Shared::World* world,
- Ingen::CommonInterface* target,
- Sord::Model& model,
- Glib::ustring document_uri,
- boost::optional<Raul::Path> data_path,
- boost::optional<Raul::Path> parent,
- boost::optional<Raul::Symbol> symbol,
- boost::optional<GraphObject::Properties> data)
-{
- const Sord::URI patch_class (*world->rdf_world(), NS_INGEN "Patch");
- const Sord::URI node_class (*world->rdf_world(), NS_INGEN "Node");
- const Sord::URI port_class (*world->rdf_world(), NS_INGEN "Port");
- const Sord::URI internal_class(*world->rdf_world(), NS_INGEN "Internal");
- const Sord::URI in_port_class (*world->rdf_world(), NS_LV2 "InputPort");
- const Sord::URI out_port_class(*world->rdf_world(), NS_LV2 "OutputPort");
- const Sord::URI lv2_class (*world->rdf_world(), NS_LV2 "Plugin");
- const Sord::URI rdf_type (*world->rdf_world(), NS_RDF "type");
-
- Sord::Node subject = nil;
- if (data_path && data_path->is_root()) {
- subject = model.base_uri();
- } else if (data_path) {
- subject = Sord::URI(*world->rdf_world(), data_path->chop_start("/"));
- }
-
- Raul::Path path("/");
- if (data_path) {
- path = *data_path;
- } else if (parent && symbol) {
- path = parent->child(*symbol);
- }
-
- // Get all subjects and their types (?subject a ?type)
- typedef std::map< Sord::Node, std::set<Sord::Node> > Subjects;
- 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());
- Subjects::iterator s = subjects.find(subject);
- if (s == subjects.end()) {
- std::set<Sord::Node> types;
- types.insert(rdf_class);
- subjects.insert(make_pair(subject, types));
- } else {
- s->second.insert(rdf_class);
- }
- }
-
- // Parse and create each subject
- boost::optional<Path> ret;
- boost::optional<Path> root_path;
- for (Subjects::const_iterator i = subjects.begin(); i != subjects.end(); ++i) {
- const Sord::Node& subject = i->first;
- const std::set<Sord::Node>& types = i->second;
- if (types.find(patch_class) != types.end()) {
- ret = parse_patch(world, target, model, subject, parent, symbol, data);
- } else if (types.find(node_class) != types.end()) {
- ret = parse_node(world, target, model,
- subject, path.child(subject.to_string()),
- data);
- } else if (types.find(port_class) != types.end()) {
- parse_properties(world, target, model, subject, path, data);
- ret = path;
- } else {
- LOG(error) << "Subject has no known types" << endl;
- }
-
- if (!ret) {
- LOG(error) << "Failed to parse " << path << endl;
- LOG(error) << "Types:" << endl;
- for (std::set<Sord::Node>::const_iterator t = types.begin();
- t != types.end(); ++t) {
- LOG(error) << " :: " << *t << endl;
- assert((*t).is_uri());
- }
- return boost::optional<Path>();
- }
-
- if (data_path && subject.to_string() == data_path->str()) {
- root_path = ret;
- }
- }
-
- return path;
-}
-
static Resource::Properties
get_properties(Sord::Model& model,
const Sord::Node& subject)
@@ -376,14 +155,122 @@ get_port(Ingen::Shared::World* world,
return index;
}
-boost::optional<Path>
-Parser::parse_patch(Ingen::Shared::World* world,
- Ingen::CommonInterface* target,
- Sord::Model& model,
- const Sord::Node& subject_node,
- boost::optional<Raul::Path> parent,
- boost::optional<Raul::Symbol> a_symbol,
- boost::optional<GraphObject::Properties> data)
+static boost::optional<Raul::Path>
+parse(
+ Shared::World* world,
+ CommonInterface* target,
+ Sord::Model& model,
+ Glib::ustring document_uri,
+ boost::optional<Raul::Path> data_path = boost::optional<Raul::Path>(),
+ boost::optional<Raul::Path> parent = boost::optional<Raul::Path>(),
+ boost::optional<Raul::Symbol> symbol = boost::optional<Raul::Symbol>(),
+ boost::optional<Resource::Properties> data = boost::optional<Resource::Properties>());
+
+static boost::optional<Raul::Path>
+parse_patch(
+ Shared::World* world,
+ CommonInterface* target,
+ Sord::Model& model,
+ const Sord::Node& subject,
+ boost::optional<Raul::Path> parent = boost::optional<Raul::Path>(),
+ boost::optional<Raul::Symbol> symbol = boost::optional<Raul::Symbol>(),
+ boost::optional<Resource::Properties> data = boost::optional<Resource::Properties>());
+
+
+static boost::optional<Raul::Path>
+parse_node(
+ Shared::World* world,
+ CommonInterface* target,
+ Sord::Model& model,
+ const Sord::Node& subject,
+ const Raul::Path& path,
+ boost::optional<Resource::Properties> data = boost::optional<Resource::Properties>());
+
+
+static bool
+parse_properties(
+ Shared::World* world,
+ CommonInterface* target,
+ Sord::Model& model,
+ const Sord::Node& subject,
+ const Raul::URI& uri,
+ boost::optional<Resource::Properties> data = boost::optional<Resource::Properties>());
+
+static bool
+parse_connections(
+ Shared::World* world,
+ CommonInterface* target,
+ Sord::Model& model,
+ const Sord::Node& subject,
+ const Raul::Path& patch);
+
+static boost::optional<Path>
+parse_node(Ingen::Shared::World* world,
+ Ingen::CommonInterface* target,
+ Sord::Model& model,
+ const Sord::Node& subject,
+ const Raul::Path& path,
+ boost::optional<GraphObject::Properties> data)
+{
+ const LV2URIMap& uris = *world->uris().get();
+
+ Sord::URI rdf_instanceOf(*world->rdf_world(), NS_RDF "instanceOf");
+
+ Sord::Iter i = model.find(subject, rdf_instanceOf, nil);
+ if (i.end() || i.get_object().type() != Sord::Node::URI) {
+ LOG(error) << "Node missing mandatory rdf:instanceOf" << endl;
+ return boost::optional<Path>();
+ }
+
+ const std::string type_uri = relative_uri(
+ model.base_uri().to_string(),
+ i.get_object().to_string(),
+ false);
+
+ if (!serd_uri_string_has_scheme((const uint8_t*)type_uri.c_str())) {
+ SerdURI base_uri;
+ serd_uri_parse(model.base_uri().to_u_string(), &base_uri);
+
+ SerdURI ignored;
+ SerdNode sub_uri = serd_node_new_uri_from_string(
+ i.get_object().to_u_string(),
+ &base_uri,
+ &ignored);
+
+ const std::string sub_uri_str((const char*)sub_uri.buf);
+ std::string basename = get_basename(sub_uri_str);
+
+ const std::string sub_file =
+ string((const char*)sub_uri.buf) + "/" + basename + ".ttl";
+
+ Sord::Model sub_model(*world->rdf_world(), sub_file);
+ SerdEnv* env = serd_env_new(NULL);
+ sub_model.load_file(env, SERD_TURTLE, sub_file);
+ serd_env_free(env);
+
+ Sord::URI sub_node(*world->rdf_world(), sub_file);
+ parse_patch(world, target, sub_model, sub_node,
+ path.parent(), Raul::Symbol(path.symbol()));
+
+ parse_patch(world, target, model, subject,
+ path.parent(), Raul::Symbol(path.symbol()));
+ } else {
+ Resource::Properties props = get_properties(model, subject);
+ props.insert(make_pair(uris.rdf_type,
+ Raul::URI(uris.ingen_Node)));
+ target->put(path, props);
+ }
+ return path;
+}
+
+static boost::optional<Path>
+parse_patch(Ingen::Shared::World* world,
+ Ingen::CommonInterface* target,
+ Sord::Model& model,
+ const Sord::Node& subject_node,
+ boost::optional<Raul::Path> parent,
+ boost::optional<Raul::Symbol> a_symbol,
+ boost::optional<GraphObject::Properties> data)
{
const Sord::URI ingen_node(*world->rdf_world(), NS_INGEN "node");
const Sord::URI ingen_polyphony(*world->rdf_world(), NS_INGEN "polyphony");
@@ -494,71 +381,12 @@ Parser::parse_patch(Ingen::Shared::World* world,
return patch_path;
}
-boost::optional<Path>
-Parser::parse_node(Ingen::Shared::World* world,
- Ingen::CommonInterface* target,
- Sord::Model& model,
- const Sord::Node& subject,
- const Raul::Path& path,
- boost::optional<GraphObject::Properties> data)
-{
- const LV2URIMap& uris = *world->uris().get();
-
- Sord::URI rdf_instanceOf(*world->rdf_world(), NS_RDF "instanceOf");
-
- Sord::Iter i = model.find(subject, rdf_instanceOf, nil);
- if (i.end() || i.get_object().type() != Sord::Node::URI) {
- LOG(error) << "Node missing mandatory rdf:instanceOf" << endl;
- return boost::optional<Path>();
- }
-
- const std::string type_uri = relative_uri(
- model.base_uri().to_string(),
- i.get_object().to_string(),
- false);
-
- if (!serd_uri_string_has_scheme((const uint8_t*)type_uri.c_str())) {
- SerdURI base_uri;
- serd_uri_parse(model.base_uri().to_u_string(), &base_uri);
-
- SerdURI ignored;
- SerdNode sub_uri = serd_node_new_uri_from_string(
- i.get_object().to_u_string(),
- &base_uri,
- &ignored);
-
- const std::string sub_uri_str((const char*)sub_uri.buf);
- std::string basename = get_basename(sub_uri_str);
-
- const std::string sub_file =
- string((const char*)sub_uri.buf) + "/" + basename + ".ttl";
-
- Sord::Model sub_model(*world->rdf_world(), sub_file);
- SerdEnv* env = serd_env_new(NULL);
- sub_model.load_file(env, SERD_TURTLE, sub_file);
- serd_env_free(env);
-
- Sord::URI sub_node(*world->rdf_world(), sub_file);
- parse_patch(world, target, sub_model, sub_node,
- path.parent(), Raul::Symbol(path.symbol()));
-
- parse_patch(world, target, model, subject,
- path.parent(), Raul::Symbol(path.symbol()));
- } else {
- Resource::Properties props = get_properties(model, subject);
- props.insert(make_pair(uris.rdf_type,
- Raul::URI(uris.ingen_Node)));
- target->put(path, props);
- }
- return path;
-}
-
-bool
-Parser::parse_connections(Ingen::Shared::World* world,
- Ingen::CommonInterface* target,
- Sord::Model& model,
- const Sord::Node& subject,
- const Raul::Path& parent)
+static bool
+parse_connections(Ingen::Shared::World* world,
+ Ingen::CommonInterface* target,
+ Sord::Model& model,
+ const Sord::Node& subject,
+ const Raul::Path& parent)
{
Sord::URI ingen_connection(*world->rdf_world(), NS_INGEN "connection");
Sord::URI ingen_source(*world->rdf_world(), NS_INGEN "source");
@@ -602,13 +430,13 @@ Parser::parse_connections(Ingen::Shared::World* world,
return true;
}
-bool
-Parser::parse_properties(Ingen::Shared::World* world,
- Ingen::CommonInterface* target,
- Sord::Model& model,
- const Sord::Node& subject,
- const Raul::URI& uri,
- boost::optional<GraphObject::Properties> data)
+static bool
+parse_properties(Ingen::Shared::World* world,
+ Ingen::CommonInterface* target,
+ Sord::Model& model,
+ const Sord::Node& subject,
+ const Raul::URI& uri,
+ boost::optional<GraphObject::Properties> data)
{
Resource::Properties properties;
for (Sord::Iter i = model.find(subject, nil, nil); !i.end(); ++i) {
@@ -629,6 +457,226 @@ Parser::parse_properties(Ingen::Shared::World* world,
return true;
}
+static boost::optional<Path>
+parse(Ingen::Shared::World* world,
+ Ingen::CommonInterface* target,
+ Sord::Model& model,
+ Glib::ustring document_uri,
+ boost::optional<Raul::Path> data_path,
+ boost::optional<Raul::Path> parent,
+ boost::optional<Raul::Symbol> symbol,
+ boost::optional<GraphObject::Properties> data)
+{
+ const Sord::URI patch_class (*world->rdf_world(), NS_INGEN "Patch");
+ const Sord::URI node_class (*world->rdf_world(), NS_INGEN "Node");
+ const Sord::URI port_class (*world->rdf_world(), NS_INGEN "Port");
+ const Sord::URI internal_class(*world->rdf_world(), NS_INGEN "Internal");
+ const Sord::URI in_port_class (*world->rdf_world(), NS_LV2 "InputPort");
+ const Sord::URI out_port_class(*world->rdf_world(), NS_LV2 "OutputPort");
+ const Sord::URI lv2_class (*world->rdf_world(), NS_LV2 "Plugin");
+ const Sord::URI rdf_type (*world->rdf_world(), NS_RDF "type");
+
+ Sord::Node subject = nil;
+ if (data_path && data_path->is_root()) {
+ subject = model.base_uri();
+ } else if (data_path) {
+ subject = Sord::URI(*world->rdf_world(), data_path->chop_start("/"));
+ }
+
+ Raul::Path path("/");
+ if (data_path) {
+ path = *data_path;
+ } else if (parent && symbol) {
+ path = parent->child(*symbol);
+ }
+
+ // Get all subjects and their types (?subject a ?type)
+ typedef std::map< Sord::Node, std::set<Sord::Node> > Subjects;
+ 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());
+ Subjects::iterator s = subjects.find(subject);
+ if (s == subjects.end()) {
+ std::set<Sord::Node> types;
+ types.insert(rdf_class);
+ subjects.insert(make_pair(subject, types));
+ } else {
+ s->second.insert(rdf_class);
+ }
+ }
+
+ // Parse and create each subject
+ boost::optional<Path> ret;
+ boost::optional<Path> root_path;
+ for (Subjects::const_iterator i = subjects.begin(); i != subjects.end(); ++i) {
+ const Sord::Node& subject = i->first;
+ const std::set<Sord::Node>& types = i->second;
+ if (types.find(patch_class) != types.end()) {
+ ret = parse_patch(world, target, model, subject, parent, symbol, data);
+ } else if (types.find(node_class) != types.end()) {
+ ret = parse_node(world, target, model,
+ subject, path.child(subject.to_string()),
+ data);
+ } else if (types.find(port_class) != types.end()) {
+ parse_properties(world, target, model, subject, path, data);
+ ret = path;
+ } else {
+ LOG(error) << "Subject has no known types" << endl;
+ }
+
+ if (!ret) {
+ LOG(error) << "Failed to parse " << path << endl;
+ LOG(error) << "Types:" << endl;
+ for (std::set<Sord::Node>::const_iterator t = types.begin();
+ t != types.end(); ++t) {
+ LOG(error) << " :: " << *t << endl;
+ assert((*t).is_uri());
+ }
+ return boost::optional<Path>();
+ }
+
+ if (data_path && subject.to_string() == data_path->str()) {
+ root_path = ret;
+ }
+ }
+
+ return path;
+}
+
+Parser::Parser(Ingen::Shared::World& world)
+{
+}
+
+Parser::PatchRecords
+Parser::find_patches(Ingen::Shared::World* world,
+ SerdEnv* env,
+ const Glib::ustring& manifest_uri)
+{
+ const Sord::URI ingen_Patch (*world->rdf_world(), NS_INGEN "Patch");
+ const Sord::URI rdf_type (*world->rdf_world(), NS_RDF "type");
+ const Sord::URI rdfs_seeAlso(*world->rdf_world(), NS_RDFS "seeAlso");
+
+ Sord::Model model(*world->rdf_world(), manifest_uri);
+ model.load_file(env, SERD_TURTLE, manifest_uri);
+
+ std::list<PatchRecord> records;
+ for (Sord::Iter i = model.find(nil, rdf_type, ingen_Patch); !i.end(); ++i) {
+ const Sord::Node patch = i.get_subject();
+ Sord::Iter f = model.find(patch, rdfs_seeAlso, nil);
+ if (!f.end()) {
+ records.push_back(PatchRecord(patch.to_c_string(),
+ f.get_object().to_c_string()));
+ } else {
+ LOG(error) << "Patch has no rdfs:seeAlso" << endl;
+ }
+ }
+ return records;
+}
+
+/** Parse a patch from RDF into a CommonInterface (engine or client).
+ * @return whether or not load was successful.
+ */
+bool
+Parser::parse_file(Ingen::Shared::World* world,
+ Ingen::CommonInterface* target,
+ Glib::ustring file_uri,
+ boost::optional<Raul::Path> parent,
+ boost::optional<Raul::Symbol> symbol,
+ boost::optional<GraphObject::Properties> data)
+{
+ const size_t colon = file_uri.find(":");
+ if (colon != Glib::ustring::npos) {
+ const Glib::ustring scheme = file_uri.substr(0, colon);
+ if (scheme != "file") {
+ LOG(error) << (boost::format("Unsupported URI scheme `%1%'")
+ % scheme) << endl;
+ return false;
+ }
+ } else {
+ file_uri = Glib::ustring("file://") + file_uri;
+ }
+
+ const bool is_bundle = (file_uri.substr(file_uri.length() - 4) != ".ttl");
+
+ if (is_bundle && file_uri[file_uri.length() - 1] != '/') {
+ file_uri.append("/");
+ }
+
+ SerdNode base_node = serd_node_from_string(
+ SERD_URI, (const uint8_t*)file_uri.c_str());
+ SerdEnv* env = serd_env_new(&base_node);
+
+ if (file_uri.substr(file_uri.length() - 4) != ".ttl") {
+ // Not a Turtle file, try to open it as a bundle
+ if (file_uri[file_uri.length() - 1] != '/') {
+ file_uri.append("/");
+ }
+ Parser::PatchRecords records = find_patches(world, env, file_uri + "manifest.ttl");
+ if (!records.empty()) {
+ file_uri = records.front().file_uri;
+ }
+ }
+
+ base_node = serd_node_from_string(
+ SERD_URI, (const uint8_t*)file_uri.c_str());
+ serd_env_set_base_uri(env, &base_node);
+
+ // Load patch file into model
+ Sord::Model model(*world->rdf_world(), file_uri);
+ model.load_file(env, SERD_TURTLE, file_uri);
+
+ serd_env_free(env);
+
+ LOG(info) << "Parsing " << file_uri << endl;
+ if (parent)
+ LOG(info) << "Parent: " << *parent << endl;
+ if (symbol)
+ LOG(info) << "Symbol: " << *symbol << endl;
+
+ boost::optional<Path> parsed_path
+ = parse(world, target, model, file_uri, Path("/"), parent, symbol, data);
+
+ if (parsed_path) {
+ target->set_property(*parsed_path, "http://drobilla.net/ns/ingen#document",
+ Atom(Atom::URI, file_uri.c_str()));
+ } else {
+ LOG(warn) << "Document URI lost" << endl;
+ }
+
+ return parsed_path;
+}
+
+bool
+Parser::parse_string(Ingen::Shared::World* world,
+ Ingen::CommonInterface* target,
+ const Glib::ustring& str,
+ const Glib::ustring& base_uri,
+ boost::optional<Raul::Path> parent,
+ boost::optional<Raul::Symbol> symbol,
+ boost::optional<GraphObject::Properties> data)
+{
+ // Load string into model
+ Sord::Model model(*world->rdf_world(), base_uri);
+ SerdEnv* env = serd_env_new(NULL);
+ model.load_string(env, SERD_TURTLE, str.c_str(), str.length(), base_uri);
+ serd_env_free(env);
+
+ LOG(info) << "Parsing string";
+ if (!base_uri.empty())
+ info << " (base " << base_uri << ")";
+ info << endl;
+
+ boost::optional<Raul::Path> data_path;
+ bool ret = parse(world, target, model, base_uri, data_path, parent, symbol, data);
+ Sord::URI subject(*world->rdf_world(), base_uri);
+ parse_connections(world, target, model, subject, parent ? *parent : "/");
+
+ return ret;
+}
+
} // namespace Serialisation
} // namespace Ingen
diff --git a/src/serialisation/Parser.hpp b/src/serialisation/Parser.hpp
deleted file mode 100644
index 30c04bab..00000000
--- a/src/serialisation/Parser.hpp
+++ /dev/null
@@ -1,128 +0,0 @@
-/* This file is part of Ingen.
- * Copyright 2007-2011 David Robillard <http://drobilla.net>
- *
- * Ingen is free software; you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option) any later
- * version.
- *
- * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef INGEN_SERIALISATION_PARSER_HPP
-#define INGEN_SERIALISATION_PARSER_HPP
-
-#include <string>
-#include <list>
-
-#include <boost/optional.hpp>
-#include <glibmm/ustring.h>
-
-#include "raul/Path.hpp"
-#include "serd/serd.h"
-
-#include "ingen/GraphObject.hpp"
-
-namespace Sord { class World; class Model; class Node; }
-
-namespace Ingen {
-
-class CommonInterface;
-
-namespace Shared { class World; }
-
-namespace Serialisation {
-
-class Parser {
-public:
- Parser(Shared::World& world);
-
- virtual ~Parser() {}
-
- typedef GraphObject::Properties Properties;
-
- virtual bool parse_file(
- Shared::World* world,
- CommonInterface* target,
- Glib::ustring document_uri,
- boost::optional<Raul::Path> parent = boost::optional<Raul::Path>(),
- boost::optional<Raul::Symbol> symbol = boost::optional<Raul::Symbol>(),
- boost::optional<Properties> data = boost::optional<Properties>());
-
- virtual bool parse_string(
- Shared::World* world,
- CommonInterface* target,
- const Glib::ustring& str,
- const Glib::ustring& base_uri,
- boost::optional<Raul::Path> parent = boost::optional<Raul::Path>(),
- boost::optional<Raul::Symbol> symbol = boost::optional<Raul::Symbol>(),
- boost::optional<Properties> data = boost::optional<Properties>());
-
- struct PatchRecord {
- PatchRecord(const Raul::URI& u, const Glib::ustring& f)
- : patch_uri(u), file_uri(f)
- {}
- const Raul::URI patch_uri;
- const Glib::ustring file_uri;
- };
-
- typedef std::list<PatchRecord> PatchRecords;
-
- virtual PatchRecords find_patches(Shared::World* world,
- SerdEnv* env,
- const Glib::ustring& manifest_uri);
-
-private:
- boost::optional<Raul::Path> parse(
- Shared::World* world,
- CommonInterface* target,
- Sord::Model& model,
- Glib::ustring document_uri,
- boost::optional<Raul::Path> data_path = boost::optional<Raul::Path>(),
- boost::optional<Raul::Path> parent = boost::optional<Raul::Path>(),
- boost::optional<Raul::Symbol> symbol = boost::optional<Raul::Symbol>(),
- boost::optional<Properties> data = boost::optional<Properties>());
-
- boost::optional<Raul::Path> parse_patch(
- Shared::World* world,
- CommonInterface* target,
- Sord::Model& model,
- const Sord::Node& subject,
- boost::optional<Raul::Path> parent = boost::optional<Raul::Path>(),
- boost::optional<Raul::Symbol> symbol = boost::optional<Raul::Symbol>(),
- boost::optional<Properties> data = boost::optional<Properties>());
-
- boost::optional<Raul::Path> parse_node(
- Shared::World* world,
- CommonInterface* target,
- Sord::Model& model,
- const Sord::Node& subject,
- const Raul::Path& path,
- boost::optional<Properties> data = boost::optional<Properties>());
-
- bool parse_properties(
- Shared::World* world,
- CommonInterface* target,
- Sord::Model& model,
- const Sord::Node& subject,
- const Raul::URI& uri,
- boost::optional<Properties> data = boost::optional<Properties>());
-
- bool parse_connections(
- Shared::World* world,
- CommonInterface* target,
- Sord::Model& model,
- const Sord::Node& subject,
- const Raul::Path& patch);
-};
-
-} // namespace Serialisation
-} // namespace Ingen
-
-#endif // INGEN_SERIALISATION_PARSER_HPP
diff --git a/src/serialisation/Serialiser.cpp b/src/serialisation/Serialiser.cpp
index 253791d2..ae1a6416 100644
--- a/src/serialisation/Serialiser.cpp
+++ b/src/serialisation/Serialiser.cpp
@@ -23,6 +23,7 @@
#include <cstdlib>
#include <cstring>
#include <fstream>
+#include <map>
#include <stdexcept>
#include <string>
#include <utility>
@@ -49,12 +50,12 @@
#include "ingen/Patch.hpp"
#include "ingen/Plugin.hpp"
#include "ingen/Port.hpp"
-#include "shared/World.hpp"
#include "shared/LV2URIMap.hpp"
#include "shared/ResourceImpl.hpp"
+#include "shared/Store.hpp"
+#include "shared/World.hpp"
-#include "Serialiser.hpp"
-#include "names.hpp"
+#include "ingen/serialisation/Serialiser.hpp"
#define LOG(s) s << "[Serialiser] "
@@ -69,19 +70,66 @@ using namespace Ingen::Shared;
namespace Ingen {
namespace Serialisation {
+struct Serialiser::Impl {
+ Impl(Shared::World& world, SharedPtr<Shared::Store> store)
+ : _root_path("/")
+ , _store(store)
+ , _world(world)
+ {}
+
+ enum Mode { TO_FILE, TO_STRING };
+
+ void start_to_filename(const std::string& filename);
+
+ void serialise_patch(SharedPtr<const Patch> p,
+ const Sord::Node& id);
+
+ void serialise_node(SharedPtr<const Node> n,
+ const Sord::Node& class_id,
+ const Sord::Node& id);
+
+ void serialise_port(const Port* p,
+ Resource::Graph context,
+ const Sord::Node& id);
+
+ void serialise_properties(const GraphObject* o,
+ Resource::Graph context,
+ Sord::Node id);
+
+ void write_bundle(SharedPtr<const Patch> patch,
+ const std::string& uri);
+
+ Sord::Node path_rdf_node(const Raul::Path& path);
+
+ void write_manifest(const std::string& bundle_path,
+ SharedPtr<const Patch> patch,
+ const std::string& patch_symbol);
+
+ void serialise_connection(const Sord::Node& parent,
+ SharedPtr<const Connection> c)
+ throw (std::logic_error);
+
+ std::string finish();
+
+ Raul::Path _root_path;
+ SharedPtr<Shared::Store> _store;
+ Mode _mode;
+ std::string _base_uri;
+ Shared::World& _world;
+ Sord::Model* _model;
+};
+
+
Serialiser::Serialiser(Shared::World& world, SharedPtr<Shared::Store> store)
- : _root_path("/")
- , _store(store)
- , _world(world)
-{
-}
+ : me(new Impl(world, store))
+{}
void
Serialiser::to_file(SharedPtr<const GraphObject> object,
const std::string& filename)
{
- _root_path = object->path();
- start_to_filename(filename);
+ me->_root_path = object->path();
+ me->start_to_filename(filename);
serialise(object);
finish();
}
@@ -96,9 +144,9 @@ uri_to_symbol(const std::string& uri)
}
void
-Serialiser::write_manifest(const std::string& bundle_path,
- SharedPtr<const Patch> patch,
- const std::string& patch_symbol)
+Serialiser::Impl::write_manifest(const std::string& bundle_path,
+ SharedPtr<const Patch> patch,
+ const std::string& patch_symbol)
{
const string manifest_path(Glib::build_filename(bundle_path, "manifest.ttl"));
const string binary_path(Glib::Module::build_path("", "ingen_lv2"));
@@ -107,7 +155,7 @@ Serialiser::write_manifest(const std::string& bundle_path,
Sord::World& world = _model->world();
- const string filename(patch_symbol + INGEN_PATCH_FILE_EXT);
+ const string filename(patch_symbol + ".ttl");
const Sord::URI subject(world, filename);
_model->add_statement(subject,
@@ -150,6 +198,13 @@ void
Serialiser::write_bundle(SharedPtr<const Patch> patch,
const std::string& uri)
{
+ me->write_bundle(patch, uri);
+}
+
+void
+Serialiser::Impl::write_bundle(SharedPtr<const Patch> patch,
+ const std::string& uri)
+{
Glib::ustring path = "";
try {
path = Glib::filename_from_uri(uri);
@@ -169,7 +224,7 @@ Serialiser::write_bundle(SharedPtr<const Patch> patch,
g_mkdir_with_parents(path.c_str(), 0744);
const string symbol = uri_to_symbol(uri);
- const string root_file = path + symbol + INGEN_PATCH_FILE_EXT;
+ const string root_file = path + symbol + ".ttl";
start_to_filename(root_file);
const Path old_root_path = _root_path;
@@ -189,12 +244,12 @@ Serialiser::to_string(SharedPtr<const GraphObject> object,
start_to_string(object->path(), base_uri);
serialise(object);
- Sord::URI base_rdf_node(_model->world(), base_uri);
+ Sord::URI base_rdf_node(me->_model->world(), base_uri);
for (GraphObject::Properties::const_iterator v = extra_rdf.begin();
v != extra_rdf.end(); ++v) {
- _model->add_statement(base_rdf_node,
- AtomRDF::atom_to_node(*_model, v->first),
- AtomRDF::atom_to_node(*_model, v->second));
+ me->_model->add_statement(base_rdf_node,
+ AtomRDF::atom_to_node(*me->_model, v->first),
+ AtomRDF::atom_to_node(*me->_model, v->second));
}
return finish();
@@ -205,7 +260,7 @@ Serialiser::to_string(SharedPtr<const GraphObject> object,
* This must be called before any serializing methods.
*/
void
-Serialiser::start_to_filename(const string& filename)
+Serialiser::Impl::start_to_filename(const string& filename)
{
setlocale(LC_NUMERIC, "C");
@@ -235,20 +290,21 @@ Serialiser::start_to_string(const Raul::Path& root, const string& base_uri)
{
setlocale(LC_NUMERIC, "C");
- _root_path = root;
- _base_uri = base_uri;
- _model = new Sord::Model(*_world.rdf_world(), base_uri);
- _mode = TO_STRING;
+ me->_root_path = root;
+ me->_base_uri = base_uri;
+ me->_model = new Sord::Model(*me->_world.rdf_world(), base_uri);
+ me->_mode = Impl::TO_STRING;
}
-/** Finish a serialization.
- *
- * If this was a serialization to a string, the serialization output
- * will be returned, otherwise the empty string is returned.
- */
-string
+std::string
Serialiser::finish()
{
+ return me->finish();
+}
+
+std::string
+Serialiser::Impl::finish()
+{
string ret = "";
if (_mode == TO_FILE) {
_model->write_to_file(_base_uri, SERD_TURTLE);
@@ -264,7 +320,7 @@ Serialiser::finish()
}
Sord::Node
-Serialiser::path_rdf_node(const Path& path)
+Serialiser::Impl::path_rdf_node(const Path& path)
{
assert(_model);
assert(path == _root_path || path.is_child_of(_root_path));
@@ -275,26 +331,26 @@ Serialiser::path_rdf_node(const Path& path)
void
Serialiser::serialise(SharedPtr<const GraphObject> object) throw (std::logic_error)
{
- if (!_model)
+ if (!me->_model)
throw std::logic_error("serialise called without serialization in progress");
SharedPtr<const Patch> patch = PtrCast<const Patch>(object);
if (patch) {
- const Sord::URI patch_id(_model->world(), "");
- serialise_patch(patch, patch_id);
+ const Sord::URI patch_id(me->_model->world(), "");
+ me->serialise_patch(patch, patch_id);
return;
}
SharedPtr<const Node> node = PtrCast<const Node>(object);
if (node) {
- const Sord::URI plugin_id(_model->world(), node->plugin()->uri().str());
- serialise_node(node, plugin_id, path_rdf_node(node->path()));
+ const Sord::URI plugin_id(me->_model->world(), node->plugin()->uri().str());
+ me->serialise_node(node, plugin_id, me->path_rdf_node(node->path()));
return;
}
SharedPtr<const Port> port = PtrCast<const Port>(object);
if (port) {
- serialise_port(port.get(), Resource::DEFAULT, path_rdf_node(port->path()));
+ me->serialise_port(port.get(), Resource::DEFAULT, me->path_rdf_node(port->path()));
return;
}
@@ -303,7 +359,8 @@ Serialiser::serialise(SharedPtr<const GraphObject> object) throw (std::logic_err
}
void
-Serialiser::serialise_patch(SharedPtr<const Patch> patch, const Sord::Node& patch_id)
+Serialiser::Impl::serialise_patch(SharedPtr<const Patch> patch,
+ const Sord::Node& patch_id)
{
assert(_model);
Sord::World& world = _model->world();
@@ -413,9 +470,9 @@ Serialiser::serialise_patch(SharedPtr<const Patch> patch, const Sord::Node& patc
}
void
-Serialiser::serialise_node(SharedPtr<const Node> node,
- const Sord::Node& class_id,
- const Sord::Node& node_id)
+Serialiser::Impl::serialise_node(SharedPtr<const Node> node,
+ const Sord::Node& class_id,
+ const Sord::Node& node_id)
{
_model->add_statement(node_id,
Sord::Curie(_model->world(), "rdf:type"),
@@ -440,9 +497,9 @@ Serialiser::serialise_node(SharedPtr<const Node> node,
}
void
-Serialiser::serialise_port(const Port* port,
- Resource::Graph context,
- const Sord::Node& port_id)
+Serialiser::Impl::serialise_port(const Port* port,
+ Resource::Graph context,
+ const Sord::Node& port_id)
{
Sord::World& world = _model->world();
@@ -491,15 +548,25 @@ Serialiser::serialise_port(const Port* port,
}
void
-Serialiser::serialise_connection(const Sord::Node& parent,
- SharedPtr<const Connection> connection) throw (std::logic_error)
+Serialiser::serialise_connection(const Sord::Node& parent,
+ SharedPtr<const Connection> connection)
+ throw (std::logic_error)
{
- Sord::World& world = _model->world();
+ return me->serialise_connection(parent, connection);
+}
+void
+Serialiser::Impl::serialise_connection(const Sord::Node& parent,
+ SharedPtr<const Connection> connection)
+ throw (std::logic_error)
+{
if (!_model)
throw std::logic_error(
"serialise_connection called without serialization in progress");
+
+ Sord::World& world = _model->world();
+
const Sord::Node src = path_rdf_node(connection->src_port_path());
const Sord::Node dst = path_rdf_node(connection->dst_port_path());
const Sord::Node connection_id = Sord::Node::blank_id(*_world.rdf_world());
@@ -522,9 +589,9 @@ skip_property(const Sord::Node& predicate)
}
void
-Serialiser::serialise_properties(const GraphObject* o,
- Ingen::Resource::Graph context,
- Sord::Node id)
+Serialiser::Impl::serialise_properties(const GraphObject* o,
+ Ingen::Resource::Graph context,
+ Sord::Node id)
{
const GraphObject::Properties props = o->properties(context);
diff --git a/src/serialisation/Serialiser.hpp b/src/serialisation/Serialiser.hpp
deleted file mode 100644
index fdc7b423..00000000
--- a/src/serialisation/Serialiser.hpp
+++ /dev/null
@@ -1,116 +0,0 @@
-/* This file is part of Ingen.
- * Copyright 2007-2011 David Robillard <http://drobilla.net>
- *
- * Ingen is free software; you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option) any later
- * version.
- *
- * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef INGEN_SERIALISATION_SERIALISER_HPP
-#define INGEN_SERIALISATION_SERIALISER_HPP
-
-#include <cassert>
-#include <map>
-#include <stdexcept>
-#include <string>
-#include <utility>
-
-#include "raul/Path.hpp"
-#include "raul/SharedPtr.hpp"
-
-#include "sord/sordmm.hpp"
-
-#include "ingen/GraphObject.hpp"
-#include "shared/Store.hpp"
-
-namespace Ingen {
-
-class Plugin;
-class GraphObject;
-class Patch;
-class Node;
-class Port;
-class Connection;
-
-namespace Shared { class World; }
-
-namespace Serialisation {
-
-/** Serialises Ingen objects (patches, nodes, etc) to RDF.
- *
- * \ingroup IngenClient
- */
-class Serialiser
-{
-public:
- Serialiser(Shared::World& world, SharedPtr<Shared::Store> store);
-
- typedef GraphObject::Properties Properties;
-
- void to_file(SharedPtr<const GraphObject> object,
- const std::string& filename);
-
- void write_bundle(SharedPtr<const Patch> patch,
- const std::string& uri);
-
- std::string to_string(SharedPtr<const GraphObject> object,
- const std::string& base_uri,
- const Properties& extra_rdf);
-
- void start_to_string(const Raul::Path& root,
- const std::string& base_uri);
-
- void serialise(SharedPtr<const GraphObject> object) throw (std::logic_error);
-
- void serialise_connection(const Sord::Node& parent,
- SharedPtr<const Connection> c) throw (std::logic_error);
-
- std::string finish();
-
-private:
- enum Mode { TO_FILE, TO_STRING };
-
- void start_to_filename(const std::string& filename);
-
- void serialise_patch(SharedPtr<const Patch> p,
- const Sord::Node& id);
-
- void serialise_node(SharedPtr<const Node> n,
- const Sord::Node& class_id,
- const Sord::Node& id);
-
- void serialise_port(const Port* p,
- Resource::Graph context,
- const Sord::Node& id);
-
- void serialise_properties(const GraphObject* o,
- Resource::Graph context,
- Sord::Node id);
-
- Sord::Node path_rdf_node(const Raul::Path& path);
-
- void write_manifest(const std::string& bundle_path,
- SharedPtr<const Patch> patch,
- const std::string& patch_symbol);
-
- Raul::Path _root_path;
- SharedPtr<Shared::Store> _store;
- Mode _mode;
- std::string _base_uri;
- Shared::World& _world;
- Sord::Model* _model;
-};
-
-} // namespace Serialisation
-} // namespace Ingen
-
-#endif // INGEN_SERIALISATION_SERIALISER_HPP
diff --git a/src/serialisation/names.hpp b/src/serialisation/names.hpp
deleted file mode 100644
index a65058c4..00000000
--- a/src/serialisation/names.hpp
+++ /dev/null
@@ -1,24 +0,0 @@
-/* This file is part of Ingen.
- * Copyright 2010-2011 David Robillard <http://drobilla.net>
- *
- * Ingen is free software; you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option) any later
- * version.
- *
- * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef INGEN_SERIALISATION_NAMES_HPP
-#define INGEN_SERIALISATION_NAMES_HPP
-
-#define INGEN_PATCH_FILE_EXT ".ttl"
-#define INGEN_BUNDLE_EXT ".ingen"
-
-#endif // INGEN_SERIALISATION_NAMES_HPP
diff --git a/src/serialisation/serialisation.cpp b/src/serialisation/serialisation.cpp
index 48911b66..af6a9a6d 100644
--- a/src/serialisation/serialisation.cpp
+++ b/src/serialisation/serialisation.cpp
@@ -18,8 +18,8 @@
#include "shared/Module.hpp"
#include "shared/World.hpp"
-#include "Parser.hpp"
-#include "Serialiser.hpp"
+#include "ingen/serialisation/Parser.hpp"
+#include "ingen/serialisation/Serialiser.hpp"
using namespace Ingen;