diff options
-rw-r--r-- | raul/Atom.hpp | 37 | ||||
-rw-r--r-- | raul/AtomRDF.hpp | 48 |
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: |