RAUL 0.8.0
|
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 <cmath> 00022 #include <cstring> 00023 #include <sstream> 00024 #include <string> 00025 #include <utility> 00026 00027 #include "raul/Atom.hpp" 00028 #include "raul/log.hpp" 00029 #include "redlandmm/Model.hpp" 00030 #include "redlandmm/Node.hpp" 00031 #include "redlandmm/World.hpp" 00032 00033 #define CUC(x) ((const unsigned char*)(x)) 00034 00035 namespace Raul { 00036 00041 namespace AtomRDF { 00042 00044 inline Atom 00045 node_to_atom(Redland::Model& model, const Redland::Node& node) 00046 { 00047 if (node.is_bool()) { 00048 return Atom(bool(node.to_bool())); 00049 } else if (node.is_resource()) { 00050 return Atom(Atom::URI, node.to_c_string()); 00051 } else if (node.is_float()) { 00052 return Atom(node.to_float()); 00053 } else if (node.is_int()) { 00054 return Atom(node.to_int()); 00055 } else if (node.is_blank()) { 00056 Atom::DictValue dict; 00057 librdf_statement* pattern = librdf_new_statement_from_nodes( 00058 model.world().c_obj(), 00059 const_cast<librdf_node*>(node.c_obj()), 00060 NULL, 00061 NULL); 00062 librdf_stream* results = librdf_model_find_statements( 00063 const_cast<librdf_model*>(model.c_obj()), 00064 pattern); 00065 while (!librdf_stream_end(results)) { 00066 librdf_statement* s = librdf_stream_get_object(results); 00067 Redland::Node predicate(model.world(), librdf_statement_get_predicate(s)); 00068 Redland::Node object(model.world(), librdf_statement_get_object(s)); 00069 dict.insert(std::make_pair(node_to_atom(model, predicate), node_to_atom(model, object))); 00070 librdf_stream_next(results); 00071 } 00072 return Atom(dict); 00073 } else { 00074 return Atom(node.to_c_string()); 00075 } 00076 } 00077 00078 00082 inline Redland::Node 00083 atom_to_node(Redland::Model& model, const Atom& atom) 00084 { 00085 Redland::World& world = model.world(); 00086 00087 std::ostringstream os; 00088 std::string str; 00089 librdf_uri* type = NULL; 00090 librdf_node* node = NULL; 00091 00092 switch (atom.type()) { 00093 case Atom::INT: 00094 os << atom.get_int32(); 00095 str = os.str(); 00096 // xsd:integer -> pretty integer literals in Turtle 00097 type = librdf_new_uri(world.world(), CUC("http://www.w3.org/2001/XMLSchema#integer")); 00098 break; 00099 case Atom::FLOAT: 00100 if (std::isnan(atom.get_float()) || std::isinf(atom.get_float())) 00101 break; 00102 os.precision(8); 00103 os << atom.get_float(); 00104 str = os.str(); 00105 if (str.find(".") == std::string::npos) 00106 str += ".0"; 00107 // xsd:decimal -> pretty decimal (float) literals in Turtle 00108 type = librdf_new_uri(world.world(), CUC("http://www.w3.org/2001/XMLSchema#decimal")); 00109 break; 00110 case Atom::BOOL: 00111 // xsd:boolean -> pretty boolean literals in Turtle 00112 if (atom.get_bool()) 00113 str = "true"; 00114 else 00115 str = "false"; 00116 type = librdf_new_uri(world.world(), CUC("http://www.w3.org/2001/XMLSchema#boolean")); 00117 break; 00118 case Atom::URI: 00119 str = atom.get_uri(); 00120 node = librdf_new_node_from_uri_string(world.world(), CUC(world.expand_uri(str).c_str())); 00121 break; 00122 case Atom::STRING: 00123 str = atom.get_string(); 00124 break; 00125 case Atom::DICT: 00126 node = librdf_new_node(world.world()); 00127 for (Atom::DictValue::const_iterator i = atom.get_dict().begin(); 00128 i != atom.get_dict().end(); ++i) { 00129 model.add_statement(Redland::Node(world, node), 00130 atom_to_node(model, i->first), 00131 atom_to_node(model, i->second)); 00132 } 00133 break; 00134 case Atom::BLOB: 00135 case Atom::NIL: 00136 default: 00137 warn << "Unserializable Atom" << std::endl; 00138 break; 00139 } 00140 00141 if (!node && str != "") 00142 node = librdf_new_node_from_typed_literal(world.world(), CUC(str.c_str()), NULL, type); 00143 00144 return Redland::Node(world, node); 00145 } 00146 00147 00148 } // namespace AtomRDF 00149 } // namespace Raul 00150 00151 #endif // RAUL_ATOM_RDF_HPP 00152