]> Dogcows Code - chaz/yoink/blob - src/Moof/Serializable.hh
e91660d53d3752937d7e2f342607acced3d57719
[chaz/yoink] / src / Moof / Serializable.hh
1
2 /*******************************************************************************
3
4 Copyright (c) 2009, Charles McGarvey
5 All rights reserved.
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9
10 * Redistributions of source code must retain the above copyright notice,
11 this list of conditions and the following disclaimer.
12 * Redistributions in binary form must reproduce the above copyright notice,
13 this list of conditions and the following disclaimer in the documentation
14 and/or other materials provided with the distribution.
15
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
20 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27 *******************************************************************************/
28
29 #ifndef _MOOF_SERIALIZABLE_HH_
30 #define _MOOF_SERIALIZABLE_HH_
31
32 #include <iostream>
33 #include <map>
34 #include <string>
35 #include <vector>
36
37 #include <Moof/Deserializer.hh>
38 #include <Moof/Serializer.hh>
39 #include <Moof/StringTools.hh>
40
41
42 namespace Mf {
43
44
45 /**
46 * Interface for a type which can be serialized and deserialized.
47 */
48
49 struct Serializable
50 {
51 // basic types which are serializable
52 typedef long Integer;
53 typedef double Float;
54 typedef bool Boolean;
55 typedef std::string String;
56 typedef std::wstring WideString;
57 typedef std::vector<SerializableP> Array;
58 typedef std::map<String,SerializableP> Map;
59
60
61 virtual ~Serializable();
62
63 virtual void serialize(Serializer& out) const = 0;
64 virtual void deserialize(Deserializer& in) = 0;
65
66 virtual void print() const = 0;
67
68 virtual bool get(Integer& value);
69 virtual bool get(Float& value);
70 virtual bool get(Boolean& value);
71 virtual bool get(String& value);
72 virtual bool get(WideString& value);
73 virtual bool get(Array& value);
74 virtual bool get(Map& value);
75
76 /*
77 * To get a number value which may have been parsed as either an integer or
78 * double, use these getters instead.
79 */
80
81 bool getNumber(Integer& value);
82 bool getNumber(Float& value);
83
84 virtual bool isNull();
85 };
86
87
88 template <class T>
89 class SerializableBasic : public Serializable
90 {
91 T value_;
92
93 public:
94
95 SerializableBasic() {}
96 SerializableBasic(const T& value) :
97 value_(value) {}
98
99 void serialize(Serializer& out) const;
100 void deserialize(Deserializer& in);
101
102 void print() const;
103 bool get(T& value);
104 };
105
106
107 struct SerializableNull : public Serializable
108 {
109 SerializableNull() {}
110
111 void serialize(Serializer& out) const;
112 void deserialize(Deserializer& in);
113
114 void print() const;
115 bool isNull();
116 };
117
118
119 template <class T>
120 inline void SerializableBasic<T>::serialize(Serializer& out) const
121 {
122 out.push(value_);
123 }
124
125 template <>
126 inline void
127 SerializableBasic<Serializable::Array>::serialize(Serializer& out) const
128 {
129 out.pushArrayHead();
130
131 std::vector<SerializableP>::const_iterator it;
132 for (it = value_.begin(); it < value_.end(); ++it)
133 {
134 (*it)->serialize(out);
135 }
136
137 out.pushArrayTail();
138 }
139
140 template <>
141 inline void
142 SerializableBasic<Serializable::Map>::serialize(Serializer& out) const
143 {
144 out.pushMapHead();
145
146 for (Map::const_iterator it = value_.begin(); it != value_.end(); ++it)
147 {
148 out.push((*it).first);
149 (*it).second->serialize(out);
150 }
151
152 out.pushMapTail();
153 }
154
155 inline void SerializableNull::serialize(Serializer& out) const
156 {
157 out.pushNull();
158 }
159
160
161 template <class T>
162 inline void SerializableBasic<T>::deserialize(Deserializer& in)
163 {
164 in.pop();
165 }
166
167 template <>
168 inline void
169 SerializableBasic<Serializable::Array>::deserialize(Deserializer& in)
170 {
171 SerializableP obj;
172
173 in.pop();
174
175 while (obj = in.deserialize())
176 {
177 value_.push_back(obj);
178 }
179
180 in.pop();
181 }
182
183 template <>
184 inline void
185 SerializableBasic<Serializable::Map>::deserialize(Deserializer& in)
186 {
187 SerializableP obj;
188
189 in.pop();
190
191 while (obj = in.deserialize())
192 {
193 std::string key;
194 if (obj->get(key))
195 {
196 value_[key] = in.deserialize();
197 }
198 }
199
200 in.pop();
201 }
202
203 inline void SerializableNull::deserialize(Deserializer& in)
204 {
205 in.pop();
206 }
207
208
209 template <class T>
210 inline void SerializableBasic<T>::print() const
211 {
212 std::cout << std::boolalpha << typeid(T).name() << "(" << value_ << ")";
213 }
214
215 template <>
216 inline void SerializableBasic<Serializable::WideString>::print() const
217 {
218 std::wcout << value_;
219 }
220
221 template <>
222 inline void SerializableBasic<Serializable::Array>::print() const
223 {
224 std::cout << "array";
225 }
226
227 template <>
228 inline void SerializableBasic<Serializable::Map>::print() const
229 {
230 std::cout << "map";
231 }
232
233 inline void SerializableNull::print() const
234 {
235 std::cout << "null";
236 }
237
238
239 template <class T>
240 inline bool SerializableBasic<T>::get(T& value)
241 {
242 value = value_;
243 return true;
244 }
245
246 inline bool SerializableNull::isNull()
247 {
248 return true;
249 }
250
251
252 } // namespace Mf
253
254 #endif // _MOOF_SERIALIZABLE_HH_
255
256 /** vim: set ts=4 sw=4 tw=80: *************************************************/
257
This page took 0.040318 seconds and 3 git commands to generate.