summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ingen/Parser.hpp1
-rw-r--r--ingen/URI.hpp7
-rw-r--r--src/Parser.cpp106
-rw-r--r--src/URI.cpp24
4 files changed, 67 insertions, 71 deletions
diff --git a/ingen/Parser.hpp b/ingen/Parser.hpp
index 96e21c51..5a361cd3 100644
--- a/ingen/Parser.hpp
+++ b/ingen/Parser.hpp
@@ -36,7 +36,6 @@ namespace Ingen {
class Interface;
class World;
-class URI;
/**
Parser for reading graphs from Turtle files or strings.
diff --git a/ingen/URI.hpp b/ingen/URI.hpp
index 30aeb7cc..3c6d38d1 100644
--- a/ingen/URI.hpp
+++ b/ingen/URI.hpp
@@ -38,7 +38,8 @@ public:
explicit URI(const std::string& str);
explicit URI(const char* str);
URI(const std::string& str, const URI& base);
- explicit URI(const Sord::Node& node);
+ URI(const Sord::Node& node);
+ URI(SerdNode node);
explicit URI(const FilePath& path);
URI(const URI& uri);
@@ -49,6 +50,8 @@ public:
~URI();
+ URI make_relative(const URI& base) const;
+
bool empty() const { return !_node.buf; }
std::string string() const { return std::string(c_str(), _node.n_bytes); }
@@ -80,6 +83,8 @@ public:
}
private:
+ URI(SerdNode node, SerdURI uri);
+
static Chunk make_chunk(const SerdChunk& chunk) {
return Chunk((const char*)chunk.buf, chunk.len);
}
diff --git a/src/Parser.cpp b/src/Parser.cpp
index e15f58ec..a8c53701 100644
--- a/src/Parser.cpp
+++ b/src/Parser.cpp
@@ -25,6 +25,7 @@
#include "ingen/Interface.hpp"
#include "ingen/Log.hpp"
#include "ingen/Parser.hpp"
+#include "ingen/URI.hpp"
#include "ingen/URIMap.hpp"
#include "ingen/URIs.hpp"
#include "ingen/World.hpp"
@@ -66,49 +67,29 @@ Parser::find_resources(Sord::World& world,
file_path = (const char*)p;
free(p);
}
- resources.insert(ResourceRecord(URI(resource.to_string()), file_path));
+ resources.insert(ResourceRecord(resource, file_path));
}
serd_env_free(env);
return resources;
}
-static std::string
-relative_uri(const std::string& base, const std::string& uri, bool leading_slash)
+static boost::optional<Raul::Path>
+get_path(const URI base, const URI uri)
{
- std::string ret;
- if (uri != base) {
- SerdURI base_uri;
- serd_uri_parse((const uint8_t*)base.c_str(), &base_uri);
-
- SerdURI normal_base_uri;
- SerdNode normal_base_uri_node = serd_node_new_uri_from_string(
- (const uint8_t*)".", &base_uri, &normal_base_uri);
-
- std::string normal_base_str((const char*)normal_base_uri_node.buf);
-
- ret = uri;
- if (uri.length() >= normal_base_str.length()
- && uri.substr(0, normal_base_str.length()) == normal_base_str) {
- ret = uri.substr(normal_base_str.length());
- }
-
- serd_node_free(&normal_base_uri_node);
- }
-
- if (leading_slash && ret[0] != '/') {
- ret = std::string("/").append(ret);
- }
- return ret;
+ const URI relative = uri.make_relative(base);
+ const std::string uri_str = "/" + relative.string();
+ 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)
{
- return (predicate.to_string() == INGEN__file ||
- predicate == uris.ingen_arc ||
- predicate == uris.ingen_block ||
- predicate == uris.lv2_port);
+ return (predicate == INGEN__file ||
+ predicate == uris.ingen_arc ||
+ predicate == uris.ingen_block ||
+ predicate == uris.lv2_port);
}
static Properties
@@ -136,8 +117,7 @@ get_properties(Ingen::World* world,
Atom atomm;
atomm = world->forge().alloc(
atom->size, atom->type, LV2_ATOM_BODY_CONST(atom));
- props.emplace(URI(i.get_predicate().to_string()),
- Property(atomm, ctx));
+ props.emplace(i.get_predicate(), Property(atomm, ctx));
}
}
@@ -204,7 +184,7 @@ parse(
World* world,
Interface* target,
Sord::Model& model,
- const std::string& base_uri,
+ const URI& base_uri,
Sord::Node& subject,
boost::optional<Raul::Path> parent = boost::optional<Raul::Path>(),
boost::optional<Raul::Symbol> symbol = boost::optional<Raul::Symbol>(),
@@ -215,7 +195,7 @@ parse_graph(
World* world,
Interface* target,
Sord::Model& model,
- const std::string& base_uri,
+ const URI& base_uri,
const Sord::Node& subject,
Resource::Graph ctx,
boost::optional<Raul::Path> parent = boost::optional<Raul::Path>(),
@@ -227,7 +207,7 @@ parse_block(
World* world,
Interface* target,
Sord::Model& model,
- const std::string& base_uri,
+ const URI& base_uri,
const Sord::Node& subject,
const Raul::Path& path,
boost::optional<Properties> data = boost::optional<Properties>());
@@ -247,7 +227,7 @@ parse_arcs(
World* world,
Interface* target,
Sord::Model& model,
- const std::string& base_uri,
+ const URI& base_uri,
const Sord::Node& subject,
const Raul::Path& graph);
@@ -255,7 +235,7 @@ static boost::optional<Raul::Path>
parse_block(Ingen::World* world,
Ingen::Interface* target,
Sord::Model& model,
- const std::string& base_uri,
+ const URI& base_uri,
const Sord::Node& subject,
const Raul::Path& path,
boost::optional<Properties> data)
@@ -280,7 +260,7 @@ parse_block(Ingen::World* world,
if (!prototype.is_valid()) {
world->log().error(
fmt("Block %1% (%2%) missing mandatory lv2:prototype\n") %
- subject.to_string() % path);
+ subject % path);
return boost::optional<Raul::Path>();
}
@@ -309,7 +289,7 @@ parse_block(Ingen::World* world,
serd_env_free(env);
Sord::URI sub_node(*world->rdf_world(), sub_file);
- parse_graph(world, target, sub_model, (const char*)sub_base.buf,
+ parse_graph(world, target, sub_model, sub_base,
sub_node, Resource::Graph::INTERNAL,
path.parent(), Raul::Symbol(path.symbol()));
@@ -330,7 +310,7 @@ static boost::optional<Raul::Path>
parse_graph(Ingen::World* world,
Ingen::Interface* target,
Sord::Model& model,
- const std::string& base_uri,
+ const URI& base_uri,
const Sord::Node& subject,
Resource::Graph ctx,
boost::optional<Raul::Path> parent,
@@ -345,28 +325,21 @@ parse_graph(Ingen::World* world,
const Sord::Node& graph = subject;
const Sord::Node nil;
- std::string graph_path_str = relative_uri(
- base_uri, subject.to_string(), true);
+ // Build graph path and symbol
+ Raul::Path graph_path;
if (parent && symbol) {
- graph_path_str = parent->child(*symbol);
+ graph_path = parent->child(*symbol);
} else if (parent) {
- graph_path_str = *parent;
+ graph_path = *parent;
} else {
- graph_path_str = "/";
+ graph_path = Raul::Path("/");
}
if (!symbol) {
symbol = Raul::Symbol("_");
}
- if (!Raul::Path::is_valid(graph_path_str)) {
- world->log().error(fmt("Graph %1% has invalid path\n")
- % graph_path_str);
- return boost::optional<Raul::Path>();
- }
-
// Create graph
- Raul::Path graph_path(graph_path_str);
Properties props = get_properties(world, model, subject, ctx);
target->put(path_to_uri(graph_path), props, ctx);
@@ -408,7 +381,7 @@ 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 = URI(node.to_string());
+ 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()));
@@ -453,7 +426,7 @@ static bool
parse_arc(Ingen::World* world,
Ingen::Interface* target,
Sord::Model& model,
- const std::string& base_uri,
+ const URI& base_uri,
const Sord::Node& subject,
const Raul::Path& graph)
{
@@ -474,16 +447,16 @@ parse_arc(Ingen::World* world,
return false;
}
- const std::string tail_str = relative_uri(
- base_uri, t.get_object().to_string(), true);
- if (!Raul::Path::is_valid(tail_str)) {
+ const boost::optional<Raul::Path> tail_path = get_path(
+ base_uri, t.get_object());
+ if (!tail_path) {
world->log().error("Arc tail has invalid URI\n");
return false;
}
- const std::string head_str = relative_uri(
- base_uri, h.get_object().to_string(), true);
- if (!Raul::Path::is_valid(head_str)) {
+ const boost::optional<Raul::Path> head_path = get_path(
+ base_uri, h.get_object());
+ if (!head_path) {
world->log().error("Arc head has invalid URI\n");
return false;
}
@@ -496,8 +469,7 @@ parse_arc(Ingen::World* world,
return false;
}
- target->connect(graph.child(Raul::Path(tail_str)),
- graph.child(Raul::Path(head_str)));
+ target->connect(graph.child(*tail_path), graph.child(*head_path));
return true;
}
@@ -506,7 +478,7 @@ static bool
parse_arcs(Ingen::World* world,
Ingen::Interface* target,
Sord::Model& model,
- const std::string& base_uri,
+ const URI& base_uri,
const Sord::Node& subject,
const Raul::Path& graph)
{
@@ -545,7 +517,7 @@ static boost::optional<Raul::Path>
parse(Ingen::World* world,
Ingen::Interface* target,
Sord::Model& model,
- const std::string& base_uri,
+ const URI& base_uri,
Sord::Node& subject,
boost::optional<Raul::Path> parent,
boost::optional<Raul::Symbol> symbol,
@@ -593,7 +565,7 @@ parse(Ingen::World* world,
const Sord::Node& s = i.first;
const std::set<Sord::Node>& types = i.second;
boost::optional<Raul::Path> ret;
- const Raul::Path rel_path(relative_uri(base_uri, s.to_string(), true));
+ const Raul::Path rel_path(*get_path(base_uri, s));
const Raul::Path path = parent ? parent->child(rel_path) : rel_path;
if (types.find(graph_class) != types.end()) {
ret = parse_graph(world, target, model, base_uri,
@@ -692,7 +664,7 @@ Parser::parse_file(Ingen::World* world,
Sord::Node subject(*world->rdf_world(), Sord::Node::URI, uri.string());
boost::optional<Raul::Path> parsed_path
- = parse(world, target, model, model.base_uri().to_string(),
+ = parse(world, target, model, model.base_uri(),
subject, parent, symbol, data);
if (parsed_path) {
diff --git a/src/URI.cpp b/src/URI.cpp
index a9c12223..3e2d2a29 100644
--- a/src/URI.cpp
+++ b/src/URI.cpp
@@ -42,10 +42,22 @@ URI::URI(const std::string& str, const URI& base)
&_uri))
{}
+URI::URI(SerdNode node)
+ : _node(serd_node_new_uri_from_node(&node, NULL, &_uri))
+{
+ assert(node.type == SERD_URI);
+}
+
+URI::URI(SerdNode node, SerdURI uri)
+ : _node(node)
+ , _uri(uri)
+{
+ assert(node.type == SERD_URI);
+}
+
URI::URI(const Sord::Node& node)
- : _node(serd_node_new_uri_from_node(node.to_serd_node(), NULL, &_uri))
+ : URI(*node.to_serd_node())
{
- assert(node.type() == Sord::Node::URI);
}
URI::URI(const FilePath& path)
@@ -90,4 +102,12 @@ URI::~URI()
serd_node_free(&_node);
}
+URI
+URI::make_relative(const URI& base) const
+{
+ SerdURI uri;
+ SerdNode node = serd_node_new_relative_uri(&_uri, &base._uri, NULL, &uri);
+ return URI(node, uri);
+}
+
} // namespace Ingen