summaryrefslogtreecommitdiffstats
path: root/raul
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2010-02-03 04:46:56 +0000
committerDavid Robillard <d@drobilla.net>2010-02-03 04:46:56 +0000
commit6476e54f48d1642e1c7cb55277c8f564dfe25bb6 (patch)
tree8ac8501cf02bf65564f4f2a6534314c5d30c0d2f /raul
parent36573e798c986e298c62daabed6036b12ea0314d (diff)
downloadraul-6476e54f48d1642e1c7cb55277c8f564dfe25bb6.tar.gz
raul-6476e54f48d1642e1c7cb55277c8f564dfe25bb6.tar.bz2
raul-6476e54f48d1642e1c7cb55277c8f564dfe25bb6.zip
Comprehensive use of cached URIs and more advanced Value (Atom) system.
Atoms (e.g. property values or port values) can now be an Atom::DICT, which maps directly to/from an RDF resource. This is now used to store control bindings as a port property, eliminating the special API. Full interned URIs used everywhere, instead of CURIEs pretending to be URIs. Avoid converting string literals to URIs all over the place. Support for binding MIDI pitch bender and MIDI channel pressure. Saving/restoring of MIDI bindings as a free side-effect of the above. git-svn-id: http://svn.drobilla.net/lad/trunk/raul@2409 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'raul')
-rw-r--r--raul/Atom.hpp37
-rw-r--r--raul/AtomRDF.hpp48
2 files changed, 71 insertions, 14 deletions
diff --git a/raul/Atom.hpp b/raul/Atom.hpp
index 3451604..04ff4cb 100644
--- a/raul/Atom.hpp
+++ b/raul/Atom.hpp
@@ -23,6 +23,7 @@
#include <cassert>
#include <cstring>
#include <string>
+#include <map>
#include <ostream>
#include <glib.h>
@@ -47,7 +48,8 @@ public:
BOOL,
URI,
STRING,
- BLOB
+ BLOB,
+ DICT
};
Atom() : _type(NIL), _blob_val(0) {}
@@ -66,6 +68,9 @@ public:
Atom(const char* type_uri, size_t size, void* val)
: _type(BLOB), _blob_val(new BlobValue(type_uri, size, val)) {}
+ typedef std::map<Raul::Atom, Raul::Atom> DictValue;
+ Atom(const DictValue& dict) : _type(DICT), _dict_val(new DictValue(dict)) {}
+
~Atom() { dealloc(); }
Atom(const Atom& copy)
@@ -79,6 +84,7 @@ public:
case URI: _string_val = copy._string_val; break;
case STRING: _string_val = strdup(copy._string_val); break;
case BLOB: _blob_val = new BlobValue(*copy._blob_val); break;
+ case DICT: _dict_val = new DictValue(*copy._dict_val); break;
}
}
@@ -94,6 +100,7 @@ public:
case URI: _string_val = other._string_val; break;
case STRING: _string_val = strdup(other._string_val); break;
case BLOB: _blob_val = new BlobValue(*other._blob_val); break;
+ case DICT: _dict_val = new DictValue(*other._dict_val); break;
}
return *this;
}
@@ -108,6 +115,7 @@ public:
case URI: return _string_val == other._string_val;
case STRING: return strcmp(_string_val, other._string_val) == 0;
case BLOB: return _blob_val == other._blob_val;
+ case DICT: return *_dict_val == *other._dict_val;
}
}
return false;
@@ -123,8 +131,12 @@ public:
case FLOAT: return _float_val < other._float_val;
case BOOL: return _bool_val < other._bool_val;
case URI:
+ if (_string_val == other._string_val) {
+ return false;
+ } // else fall through to STRING
case STRING: return strcmp(_string_val, other._string_val) < 0;
case BLOB: return _blob_val < other._blob_val;
+ case DICT: return *_dict_val < *other._dict_val;
}
}
return _type < other.type();
@@ -139,6 +151,7 @@ public:
case URI:
case STRING: return strlen(_string_val);
case BLOB: return _blob_val->size();
+ case DICT: return 0; // FIXME ?
}
return 0;
}
@@ -159,6 +172,8 @@ public:
inline const char* get_blob_type() const { assert(_type == BLOB); return _blob_val->type(); }
inline const void* get_blob() const { assert(_type == BLOB); return _blob_val->data(); }
+ inline const DictValue& get_dict() const { assert(_type == DICT); return *_dict_val; }
+
private:
Type _type;
@@ -212,11 +227,12 @@ private:
};
union {
- int32_t _int_val;
- float _float_val;
- bool _bool_val;
- const char* _string_val;
- BlobValue* _blob_val;
+ int32_t _int_val;
+ float _float_val;
+ bool _bool_val;
+ const char* _string_val;
+ BlobValue* _blob_val;
+ const DictValue* _dict_val;
};
};
@@ -233,6 +249,14 @@ static inline std::ostream& operator<<(std::ostream& os, const Raul::Atom& atom)
case Raul::Atom::URI: return os << "<" << atom.get_uri() << ">";
case Raul::Atom::STRING: return os << atom.get_string();
case Raul::Atom::BLOB: return os << atom.get_blob();
+ case Raul::Atom::DICT:
+ os << "{";
+ for (Raul::Atom::DictValue::const_iterator i = atom.get_dict().begin();
+ i != atom.get_dict().end(); ++i) {
+ os << " " << i->first << " " << i->second << ";";
+ }
+ os << " }";
+ return os;
}
return os;
}
@@ -247,6 +271,7 @@ static inline std::ostream& operator<<(std::ostream& os, Raul::Atom::Type type)
case Raul::Atom::URI: return os << "URI";
case Raul::Atom::STRING: return os << "String";
case Raul::Atom::BLOB: return os << "Blob";
+ case Raul::Atom::DICT: return os << "Dict";
}
return os;
}
diff --git a/raul/AtomRDF.hpp b/raul/AtomRDF.hpp
index 0b961d2..2a15fe3 100644
--- a/raul/AtomRDF.hpp
+++ b/raul/AtomRDF.hpp
@@ -22,10 +22,12 @@
#include <string>
#include <sstream>
#include <cmath>
+#include <utility>
#include "raul/log.hpp"
#include "raul/Atom.hpp"
#include "redlandmm/Node.hpp"
#include "redlandmm/World.hpp"
+#include "redlandmm/Model.hpp"
#define CUC(x) ((const unsigned char*)(x))
@@ -39,18 +41,37 @@ namespace AtomRDF {
/** Convert a Redland::Node to a Raul::Atom */
inline Atom
-node_to_atom(const Redland::Node& node)
+node_to_atom(Redland::Model& model, const Redland::Node& node)
{
- if (node.is_bool())
+ if (node.is_bool()) {
return Atom(bool(node.to_bool()));
- else if (node.is_resource())
- return Atom(Atom::URI, node.world()->qualify(node.to_c_string()));
- else if (node.is_float())
+ } else if (node.is_resource()) {
+ return Atom(Atom::URI, node.to_c_string());
+ } else if (node.is_float()) {
return Atom(node.to_float());
- else if (node.is_int())
+ } else if (node.is_int()) {
return Atom(node.to_int());
- else
+ } else if (node.is_blank()) {
+ Atom::DictValue dict;
+ librdf_statement* pattern = librdf_new_statement_from_nodes(
+ model.world().c_obj(),
+ const_cast<librdf_node*>(node.c_obj()),
+ NULL,
+ NULL);
+ librdf_stream* results = librdf_model_find_statements(
+ const_cast<librdf_model*>(model.c_obj()),
+ pattern);
+ while (!librdf_stream_end(results)) {
+ librdf_statement* s = librdf_stream_get_object(results);
+ Redland::Node predicate(model.world(), librdf_statement_get_predicate(s));
+ Redland::Node object(model.world(), librdf_statement_get_object(s));
+ dict.insert(std::make_pair(node_to_atom(model, predicate), node_to_atom(model, object)));
+ librdf_stream_next(results);
+ }
+ return Atom(dict);
+ } else {
return Atom(node.to_c_string());
+ }
}
@@ -58,8 +79,10 @@ node_to_atom(const Redland::Node& node)
* Note that not all Atoms are serialisable, the returned node should
* be checked (can be treated as a bool) before use. */
inline Redland::Node
-atom_to_node(Redland::World& world, const Atom& atom)
+atom_to_node(Redland::Model& model, const Atom& atom)
{
+ Redland::World& world = model.world();
+
std::ostringstream os;
std::string str;
librdf_uri* type = NULL;
@@ -98,6 +121,15 @@ atom_to_node(Redland::World& world, const Atom& atom)
case Atom::STRING:
str = atom.get_string();
break;
+ case Atom::DICT:
+ node = librdf_new_node(world.world());
+ for (Atom::DictValue::const_iterator i = atom.get_dict().begin();
+ i != atom.get_dict().end(); ++i) {
+ model.add_statement(Redland::Node(world, node),
+ atom_to_node(model, i->first),
+ atom_to_node(model, i->second));
+ }
+ break;
case Atom::BLOB:
case Atom::NIL:
default: