Partial adoption of contributions by Giuseppe:
[libdai.git] / src / properties.cpp
1 /* Copyright (C) 2006-2008 Joris Mooij [j dot mooij at science dot ru dot nl]
2 Radboud University Nijmegen, The Netherlands
3
4 This file is part of libDAI.
5
6 libDAI is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 libDAI is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with libDAI; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21
22 #include <iostream>
23 #include <dai/properties.h>
24 #include <dai/alldai.h>
25
26
27 namespace dai {
28
29
30 /// Sends a single Property object to an output stream
31 std::ostream& operator<< (std::ostream & os, const Property & p) {
32 os << p.first << "=";
33 if( p.second.type() == typeid(size_t) )
34 os << boost::any_cast<size_t>(p.second);
35 else if( p.second.type() == typeid(std::string) )
36 os << boost::any_cast<std::string>(p.second);
37 else if( p.second.type() == typeid(double) )
38 os << boost::any_cast<double>(p.second);
39 else if( p.second.type() == typeid(bool) )
40 os << boost::any_cast<bool>(p.second);
41 else if( p.second.type() == typeid(Properties) )
42 os << boost::any_cast<Properties>(p.second);
43 else if( p.second.type() == typeid(BP::UpdateType) )
44 os << boost::any_cast<BP::UpdateType>(p.second);
45 else if( p.second.type() == typeid(HAK::ClustersType) )
46 os << boost::any_cast<HAK::ClustersType>(p.second);
47 else if( p.second.type() == typeid(JTree::UpdateType) )
48 os << boost::any_cast<JTree::UpdateType>(p.second);
49 else if( p.second.type() == typeid(MR::UpdateType) )
50 os << boost::any_cast<MR::UpdateType>(p.second);
51 else if( p.second.type() == typeid(MR::InitType) )
52 os << boost::any_cast<MR::InitType>(p.second);
53 else if( p.second.type() == typeid(TreeEP::TypeType) )
54 os << boost::any_cast<TreeEP::TypeType>(p.second);
55 else if( p.second.type() == typeid(LC::CavityType) )
56 os << boost::any_cast<LC::CavityType>(p.second);
57 else if( p.second.type() == typeid(LC::UpdateType) )
58 os << boost::any_cast<LC::UpdateType>(p.second);
59 else
60 throw "Unknown property type";
61 return( os );
62 }
63
64
65 /// Sends a Properties object to an output stream
66 std::ostream& operator<< (std::ostream & os, const Properties & ps) {
67 os << "[";
68 for( Properties::const_iterator p = ps.begin(); p != ps.end(); p++ ) {
69 if( p != ps.begin() )
70 os << ",";
71 os << *p;
72 }
73 os << "]";
74 return os;
75 }
76
77
78 /// Reads a Properties object from an input stream, storing values as strings
79 std::istream& operator >> (std::istream& is, Properties & ps) {
80 ps = Properties();
81
82 std::string s;
83 is >> s;
84
85 // Check whether s is of the form "[.*]"
86 if( (s.length() < 2) || (s.at(0) != '[') || (s.at(s.length()-1)) != ']' )
87 throw "Malformed property";
88
89 size_t N = s.length() - 1;
90 for( size_t token_start = 1; token_start < N; ) {
91 size_t token_end;
92
93 // scan until '=' is found
94 for( token_end = token_start + 1; token_end < N; token_end++ )
95 if( s[token_end] == '=' )
96 break;
97 if( token_end == N )
98 throw "Malformed property key";
99 // we found a key
100 std::string key = s.substr(token_start, token_end - token_start);
101
102 token_start = token_end + 1;
103 // scan until matching ',' is found
104 int level = 0;
105 for( token_end = token_start; token_end < N; token_end++ ) {
106 if( s[token_end] == '[' )
107 level++;
108 else if( s[token_end] == ']' )
109 level--;
110 else if( (s[token_end] == ',') && (level == 0) )
111 break;
112 }
113 if( !(level == 0) )
114 throw "Malformed property value";
115 // we found a vlue
116 std::string value = s.substr(token_start, token_end - token_start);
117
118 // store the key,value pair
119 ps.Set(key,value);
120
121 // go on with the next one
122 token_start = token_end + 1;
123 }
124
125 return is;
126 }
127
128
129 } // end of namespace dai