summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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: