RAUL  0.7.0
AtomRDF.hpp
00001 /* This file is part of Raul.
00002  * Copyright (C) 2007-2009 David Robillard <http://drobilla.net>
00003  *
00004  * Raul is free software; you can redistribute it and/or modify it under the
00005  * terms of the GNU General Public License as published by the Free Software
00006  * Foundation; either version 2 of the License, or (at your option) any later
00007  * version.
00008  *
00009  * Raul is distributed in the hope that it will be useful, but WITHOUT ANY
00010  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00011  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for details.
00012  *
00013  * You should have received a copy of the GNU General Public License along
00014  * with this program; if not, write to the Free Software Foundation, Inc.,
00015  * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
00016  */
00017 
00018 #ifndef RAUL_ATOM_RDF_HPP
00019 #define RAUL_ATOM_RDF_HPP
00020 
00021 #include <cstring>
00022 #include <string>
00023 #include <sstream>
00024 #include <cmath>
00025 #include <utility>
00026 #include "raul/log.hpp"
00027 #include "raul/Atom.hpp"
00028 #include "redlandmm/Node.hpp"
00029 #include "redlandmm/World.hpp"
00030 #include "redlandmm/Model.hpp"
00031 
00032 #define CUC(x) ((const unsigned char*)(x))
00033 
00034 namespace Raul {
00035 
00040 namespace AtomRDF {
00041 
00043 inline Atom
00044 node_to_atom(Redland::Model& model, const Redland::Node& node)
00045 {
00046     if (node.is_bool()) {
00047         return Atom(bool(node.to_bool()));
00048     } else if (node.is_resource()) {
00049         return Atom(Atom::URI, node.to_c_string());
00050     } else if (node.is_float()) {
00051         return Atom(node.to_float());
00052     } else if (node.is_int()) {
00053         return Atom(node.to_int());
00054     } else if (node.is_blank()) {
00055         Atom::DictValue dict;
00056         librdf_statement* pattern = librdf_new_statement_from_nodes(
00057                 model.world().c_obj(),
00058                 const_cast<librdf_node*>(node.c_obj()),
00059                 NULL,
00060                 NULL);
00061         librdf_stream* results = librdf_model_find_statements(
00062                 const_cast<librdf_model*>(model.c_obj()),
00063                 pattern);
00064         while (!librdf_stream_end(results)) {
00065             librdf_statement* s = librdf_stream_get_object(results);
00066             Redland::Node predicate(model.world(), librdf_statement_get_predicate(s));
00067             Redland::Node object(model.world(), librdf_statement_get_object(s));
00068             dict.insert(std::make_pair(node_to_atom(model, predicate), node_to_atom(model, object)));
00069             librdf_stream_next(results);
00070         }
00071         return Atom(dict);
00072     } else {
00073         return Atom(node.to_c_string());
00074     }
00075 }
00076 
00077 
00081 inline Redland::Node
00082 atom_to_node(Redland::Model& model, const Atom& atom)
00083 {
00084     Redland::World& world = model.world();
00085 
00086     std::ostringstream os;
00087     std::string        str;
00088     librdf_uri*        type = NULL;
00089     librdf_node*       node = NULL;
00090 
00091     switch (atom.type()) {
00092     case Atom::INT:
00093         os << atom.get_int32();
00094         str = os.str();
00095         // xsd:integer -> pretty integer literals in Turtle
00096         type = librdf_new_uri(world.world(), CUC("http://www.w3.org/2001/XMLSchema#integer"));
00097         break;
00098     case Atom::FLOAT:
00099         if (std::isnan(atom.get_float()) || std::isinf(atom.get_float()))
00100             break;
00101         os.precision(8);
00102         os << atom.get_float();
00103         str = os.str();
00104         if (str.find(".") == std::string::npos)
00105             str += ".0";
00106         // xsd:decimal -> pretty decimal (float) literals in Turtle
00107         type = librdf_new_uri(world.world(), CUC("http://www.w3.org/2001/XMLSchema#decimal"));
00108         break;
00109     case Atom::BOOL:
00110         // xsd:boolean -> pretty boolean literals in Turtle
00111         if (atom.get_bool())
00112             str = "true";
00113         else
00114             str = "false";
00115         type = librdf_new_uri(world.world(), CUC("http://www.w3.org/2001/XMLSchema#boolean"));
00116         break;
00117     case Atom::URI:
00118         str = atom.get_uri();
00119         node = librdf_new_node_from_uri_string(world.world(), CUC(world.expand_uri(str).c_str()));
00120         break;
00121     case Atom::STRING:
00122         str = atom.get_string();
00123         break;
00124     case Atom::DICT:
00125         node = librdf_new_node(world.world());
00126         for (Atom::DictValue::const_iterator i = atom.get_dict().begin();
00127                 i != atom.get_dict().end(); ++i) {
00128             model.add_statement(Redland::Node(world, node),
00129                     atom_to_node(model, i->first),
00130                     atom_to_node(model, i->second));
00131         }
00132         break;
00133     case Atom::BLOB:
00134     case Atom::NIL:
00135     default:
00136         warn << "Unserializable Atom" << std::endl;
00137         break;
00138     }
00139 
00140     if (!node && str != "")
00141         node = librdf_new_node_from_typed_literal(world.world(), CUC(str.c_str()), NULL, type);
00142 
00143     return Redland::Node(world, node);
00144 }
00145 
00146 
00147 } // namespace AtomRDF
00148 } // namespace Raul
00149 
00150 #endif // RAUL_ATOM_RDF_HPP
00151