Loading...
Searching...
No Matches
Serializer.h
1/*
2
3 Copyright 2001 - 2017 Markus Peura, Finnish Meteorological Institute (First.Last@fmi.fi)
4
5
6 This file is part of Rack for C++.
7
8 Rack is free software: you can redistribute it and/or modify
9 it under the terms of the GNU Lesser Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 any later version.
12
13 Rack is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU Lesser Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with Rack. If not, see <http://www.gnu.org/licenses/>.
20
21 */
22
23
24//#include <stdlib.h>
25#include <iostream>
26#include <sstream>
27#include <string.h> // plain C strlen
28
29#include <map>
30#include <list>
31#include <set>
32
33#include "drain/StringBuilder.h"
34
35#ifndef DRAIN_SERIALIZER
36#define DRAIN_SERIALIZER
37
38namespace drain {
39
40// consider formatter from T-inherited class: template <class F>
41
46struct Serializer { // : public Formatter {
47
48public:
49
50
51 inline
52 Serializer(){};
53
54 virtual inline
55 ~Serializer(){};
56
57 static const char SINGLE_QUOTE; // '\'';
58 static const char DOUBLE_QUOTE; // '"';
59
60 typedef std::map<char, const char *> conv_map_t;
61
62 static
63 const conv_map_t conversion;
64
65
66 // Object rendering
67 typedef int objType;
68 static const objType NONE=0;
69 static const objType KEY=1;
70 static const objType VALUE=2;
71 static const objType PAIR=KEY|VALUE;
72 static const objType LIST=4;
73 static const objType SET=8;
74 static const objType MAP=16;
75 static const objType MAP_KEY=MAP|KEY;
76 static const objType MAP_VALUE=MAP|VALUE;
77 static const objType MAP_PAIR=MAP|PAIR;
78 static const objType TUPLE=64;
79 static const objType STRING=128;
80
81 // Object rendering
82 // Object rendering
83 // Object rendering
84
85 // Virtual
86 virtual inline
87 void writePrefix(std::ostream & ostr, objType type) const {};
88
89 virtual inline
90 void writeSeparator(std::ostream & ostr, objType type) const {
91 if (type!=STRING)
92 ostr << ',';
93 };
94
95 virtual inline
96 void writeSuffix(std::ostream & ostr, objType type) const {};
97
99 template <class T>
100 void toStream(std::ostream & ostr, const T & x, objType hint=NONE) const ;
101
102 // Sequences are partially templated
103
104 template <class T>
105 void toStream(std::ostream & ostr, const std::list<T> & x) const {
106 this->iterableToStream(ostr, x, LIST);
107 }
108
109 template <class T>
110 void toStream(std::ostream & ostr, const std::set<T> & x) const {
111 this->iterableToStream(ostr, x, SET);
112 }
113
114 template <class K,class V>
115 void toStream(std::ostream & ostr, const std::map<K,V> & x) const {
116 this->iterableToStream(ostr, x, MAP);
117 }
118
119 template <class K,class V>
120 void toStream(std::ostream & ostr, const std::pair<K,V> & x) const {
121 this->pairToStream(ostr, x);
122 }
123
125 template <class K,class V>
126 void entryToStream(std::ostream & ostr, const std::pair<K,V> & x) const {
127 this->pairToStream(ostr, x, MAP_PAIR);
128 }
129
130 template <class T>
131 void entryToStream(std::ostream & ostr, const T & x) const {
132 this->toStream(ostr, x);
133 }
134
135
136 // Consider indent level(s)
137 template <class T>
138 void iterableToStream(std::ostream & ostr, const T & x, objType iterableType = NONE) const {
139 writePrefix(ostr, iterableType);
140 objType separatorType = NONE;
141 for (const auto & entry: x){
142 this->writeSeparator(ostr, separatorType);
143 //this->toStream(ostr, entry); // may be a pair.
144 this->entryToStream(ostr, entry); // may be a pair.
145 separatorType = iterableType;
146 }
147 writeSuffix(ostr, iterableType);
148 }
149
150 template <class K,class V>
151 void pairToStream(std::ostream & ostr, const std::pair<K,V> & x, objType containerType= NONE) const {
152 // DEBUG ostr << "@" << containerType << '|';
153 this->writePrefix(ostr, PAIR|containerType);
154 {
155 this->writePrefix(ostr, KEY|containerType); // PAIR_KEY?
156 this->toStream(ostr, x.first);
157 this->writeSuffix(ostr, KEY|containerType); // PAIR_KEY?
158 }
159 this->writeSeparator(ostr, PAIR|containerType);
160 {
161 this->writePrefix(ostr, VALUE|containerType); // PAIR_VALUE?
162 this->toStream(ostr, x.second);
163 this->writeSuffix(ostr, VALUE|containerType); // PAIR_VALUE?
164 }
165 this->writeSuffix(ostr, PAIR|containerType);
166 }
167
168
169 inline
170 void toStream(std::ostream & ostr, char c) const {
171 this->charToStream(ostr, c);
172 }
173
174 inline
175 void toStream(std::ostream & ostr, const char *x) const {
176 this->stringToStream(ostr, x);
177 }
178
179 inline
180 void toStream(std::ostream & ostr, const std::string &x) const {
181 this->stringToStream(ostr, x);
182 }
183
184 inline
185 void toStream(std::ostream & ostr, bool x) const {
186 this->boolToStream(ostr, x);
187 }
188
189 inline
190 void toStream(std::ostream & ostr, const nullptr_t & t) const {
191 this->nullToStream(ostr);
192 }
193
195 template <class T>
196 inline
197 void toStr(std::string & str, const T & x) const {
198 std::stringstream sstr;
199 toStream(sstr, x);
200 str = sstr.str();
201 }
202
203 // Type specific handlers
204
205 virtual
206 void floatToStream(std::ostream & ostr, double x) const {
207 ostr << x;
208 }
209
210 virtual
211 void intToStream(std::ostream & ostr, int x) const {
212 ostr << x;
213 }
214
215 virtual
216 void boolToStream(std::ostream & ostr, bool x) const {
217 //Logger mout(__FILE__, __FUNCTION__);
218 //ostr << std::ios_base::boolalpha;
219 ostr << std::boolalpha;
220 ostr << x;
221 }
222
223 virtual inline
224 void nullToStream(std::ostream & ostr) const {
225 ostr << "null";
226 }
227
228 virtual inline
229 void charToStream(std::ostream & ostr, char c) const {
230 ostr << c;
231 }
232
233 virtual inline
234 void stringToStream(std::ostream & ostr, const char *x) const {
235 ostr << x;
236 }
237
238 virtual inline
239 void stringToStream(std::ostream & ostr, const std::string & x) const final {
240 stringToStream(ostr, x.c_str());
241 }
242
243
244};
245
246template <class T>
247void Serializer::toStream(std::ostream & ostr, const T & x, objType hint) const {
248
249 if (std::is_floating_point<T>()){
250 this->floatToStream(ostr, x);
251 }
252 else if (std::is_integral<T>()){
253 this->intToStream(ostr, x);
254 }
255 else {
256 ostr << x;
257 }
258}
259
261
262 char prefix = 0;
263 char separator = 0;
264 char suffix = 0;
265 //char quote = 0;
266
267 inline
268 SimpleFormatter(const char *conf=""){
269
270 switch (strlen(conf)){
271 case 3:
272 prefix = conf[0];
273 separator = conf[1];
274 suffix = conf[2];
275 break;
276 case 2:
277 prefix = conf[0];
278 suffix = conf[1];
279 break;
280 case 1:
281 separator = conf[0];
282 break;
283 case 0:
284 break;
285 default:
286 throw std::runtime_error(StringBuilder<':'>(__FILE__, "unsupported conf", conf));
287 }
288
289 }
290
291};
292
294public:
295
296 typedef std::map<objType,SimpleFormatter> char_map_t;
297
298 inline
300
301 inline
302 SimpleSerializer(const char_map_t & chars) : fmtChars(chars){};
303
304 virtual inline
306
307
308
309 virtual inline
310 void writePrefix(std::ostream & ostr, objType type) const override {
311 writePrefix(ostr, getFormatter(type));
312 }
313
314 inline
315 void writePrefix(std::ostream & ostr, const SimpleFormatter & fmt) const {
316 if (fmt.prefix){
317 ostr << fmt.prefix;
318 }
319 };
320
321 virtual
322 void writeSeparator(std::ostream & ostr, objType type) const override {
323 writeSeparator(ostr, getFormatter(type));
324 }
325
326 inline
327 void writeSeparator(std::ostream & ostr, const SimpleFormatter & fmt) const {
328 if (fmt.separator){
329 ostr << fmt.separator;
330 }
331 };
332
333 virtual
334 void writeSuffix(std::ostream & ostr, objType type) const override {
335 writeSuffix(ostr, getFormatter(type));
336 }
337
338 inline
339 void writeSuffix(std::ostream & ostr, const SimpleFormatter & fmt) const {
340 if (fmt.suffix){
341 ostr << fmt.suffix;
342 }
343 };
344
345
346 virtual
347 void stringToStream(std::ostream & ostr, const char * x) const override {
348 charsToStream(ostr, x);
349 }
350
351
358 virtual inline
359 void charToStream(std::ostream & ostr, char c) const override {
360 charsToStream(ostr, c);
361 }
362
363
364
365protected:
366
367 char_map_t fmtChars = {
368 {LIST, "[,]"},
369 {PAIR, "<,>"},
370 {SET, "{,}"},
371 {MAP,"{,}"},
372 {STRING,"''"},
373 };
374
375 virtual
376 const SimpleFormatter & getFormatter(objType t) const;
377
378
379 template <class S>
380 void charsToStream(std::ostream & ostr, const S &s) const;
381
382 virtual
383 void handleChars(std::ostream & ostr, char c) const;
384
385 virtual
386 void handleChars(std::ostream & ostr, const char *c) const;
387
388
389
390};
391
392template <class S>
393void SimpleSerializer::charsToStream(std::ostream & ostr, const S &s) const {
394
395 const SimpleFormatter & fmt = getFormatter(Serializer::STRING);
396 writePrefix(ostr, fmt);
397 handleChars(ostr, s);
398 writeSuffix(ostr, fmt);
399
400}
401
402
403}
404
405#endif
406
407
Definition Serializer.h:293
virtual void charToStream(std::ostream &ostr, char c) const override
Definition Serializer.h:359
Definition StringBuilder.h:58
Definition DataSelector.cpp:1277
Definition Serializer.h:46
void entryToStream(std::ostream &ostr, const std::pair< K, V > &x) const
This is a map entry.
Definition Serializer.h:126
void toStr(std::string &str, const T &x) const
Default handler.
Definition Serializer.h:197
void toStream(std::ostream &ostr, const T &x, objType hint=NONE) const
Default handler.
Definition Serializer.h:247
Definition Serializer.h:260