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