RAUL 0.7.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 <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