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#include <stddef.h> // null_ptr_t
29
30#include <map>
31#include <list>
32#include <set>
33
34#include "drain/StringBuilder.h"
35
36#ifndef DRAIN_SERIALIZER
37#define DRAIN_SERIALIZER
38
39namespace drain {
40
41// consider formatter from T-inherited class: template <class F>
42
47struct Serializer { // : public Formatter {
48
49public:
50
51
52 inline
53 Serializer(){};
54
55 virtual inline
56 ~Serializer(){};
57
58 static const char SINGLE_QUOTE; // '\'';
59 static const char DOUBLE_QUOTE; // '"';
60
61 typedef std::map<char, const char *> conv_map_t;
62
63 static
64 const conv_map_t conversion;
65
66
67 // Object rendering
68 typedef int objType;
69 static const objType NONE=0;
70 static const objType KEY=1;
71 static const objType VALUE=2;
72 static const objType PAIR=KEY|VALUE;
73 static const objType LIST=4;
74 static const objType SET=8;
75 static const objType MAP=16;
76 static const objType MAP_KEY=MAP|KEY;
77 static const objType MAP_VALUE=MAP|VALUE;
78 static const objType MAP_PAIR=MAP|PAIR;
79 static const objType TUPLE=64;
80 static const objType STRING=128;
81
82 // Object rendering
83 // Object rendering
84 // Object rendering
85
86 // Virtual
87 virtual inline
88 void writePrefix(std::ostream & ostr, objType type) const {};
89
90 virtual inline
91 void writeSeparator(std::ostream & ostr, objType type) const {
92 if (type!=STRING)
93 ostr << ',';
94 };
95
96 virtual inline
97 void writeSuffix(std::ostream & ostr, objType type) const {};
98
100 template <class T>
101 void toStream(std::ostream & ostr, const T & x, objType hint=NONE) const ;
102
103 // Sequences are partially templated
104
105 template <class T>
106 void toStream(std::ostream & ostr, const std::list<T> & x) const {
107 this->iterableToStream(ostr, x, LIST);
108 }
109
110 template <class T>
111 void toStream(std::ostream & ostr, const std::set<T> & x) const {
112 this->iterableToStream(ostr, x, SET);
113 }
114
115 template <class K,class V>
116 void toStream(std::ostream & ostr, const std::map<K,V> & x) const {
117 this->iterableToStream(ostr, x, MAP);
118 }
119
120 template <class K,class V>
121 void toStream(std::ostream & ostr, const std::pair<K,V> & x) const {
122 this->pairToStream(ostr, x);
123 }
124
126 template <class K,class V>
127 void entryToStream(std::ostream & ostr, const std::pair<K,V> & x) const {
128 this->pairToStream(ostr, x, MAP_PAIR);
129 }
130
131 template <class T>
132 void entryToStream(std::ostream & ostr, const T & x) const {
133 this->toStream(ostr, x);
134 }
135
136
137 // Consider indent level(s)
138 template <class T>
139 void iterableToStream(std::ostream & ostr, const T & x, objType iterableType = NONE) const {
140 writePrefix(ostr, iterableType);
141 objType separatorType = NONE;
142 for (const auto & entry: x){
143 this->writeSeparator(ostr, separatorType);
144 //this->toStream(ostr, entry); // may be a pair.
145 this->entryToStream(ostr, entry); // may be a pair.
146 separatorType = iterableType;
147 }
148 writeSuffix(ostr, iterableType);
149 }
150
151 template <class K,class V>
152 void pairToStream(std::ostream & ostr, const std::pair<K,V> & x, objType containerType= NONE) const {
153 // DEBUG ostr << "@" << containerType << '|';
154 this->writePrefix(ostr, PAIR|containerType);
155 {
156 this->writePrefix(ostr, KEY|containerType); // PAIR_KEY?
157 this->toStream(ostr, x.first);
158 this->writeSuffix(ostr, KEY|containerType); // PAIR_KEY?
159 }
160 this->writeSeparator(ostr, PAIR|containerType);
161 {
162 this->writePrefix(ostr, VALUE|containerType); // PAIR_VALUE?
163 this->toStream(ostr, x.second);
164 this->writeSuffix(ostr, VALUE|containerType); // PAIR_VALUE?
165 }
166 this->writeSuffix(ostr, PAIR|containerType);
167 }
168
169
170 inline
171 void toStream(std::ostream & ostr, char c) const {
172 this->charToStream(ostr, c);
173 }
174
175 inline
176 void toStream(std::ostream & ostr, const char *x) const {
177 this->stringToStream(ostr, x);
178 }
179
180 inline
181 void toStream(std::ostream & ostr, const std::string &x) const {
182 this->stringToStream(ostr, x);
183 }
184
185 inline
186 void toStream(std::ostream & ostr, bool x) const {
187 this->boolToStream(ostr, x);
188 }
189
190 inline
191 void toStream(std::ostream & ostr, const std::nullptr_t & t) const {
192 this->nullToStream(ostr);
193 }
194
196 template <class T>
197 inline
198 void toStr(std::string & str, const T & x) const {
199 std::stringstream sstr;
200 toStream(sstr, x);
201 str = sstr.str();
202 }
203
204 // Type specific handlers
205
206 virtual
207 void floatToStream(std::ostream & ostr, double x) const {
208 ostr << x;
209 }
210
211 virtual
212 void intToStream(std::ostream & ostr, int x) const {
213 ostr << x;
214 }
215
216 virtual
217 void boolToStream(std::ostream & ostr, bool x) const {
218 //Logger mout(__FILE__, __FUNCTION__);
219 //ostr << std::ios_base::boolalpha;
220 ostr << std::boolalpha;
221 ostr << x;
222 }
223
224 virtual inline
225 void nullToStream(std::ostream & ostr) const {
226 ostr << "null";
227 }
228
229 virtual inline
230 void charToStream(std::ostream & ostr, char c) const {
231 ostr << c;
232 }
233
234 virtual inline
235 void stringToStream(std::ostream & ostr, const char *x) const {
236 ostr << x;
237 }
238
239 virtual inline
240 void stringToStream(std::ostream & ostr, const std::string & x) const final {
241 stringToStream(ostr, x.c_str());
242 }
243
244
245};
246
247template <class T>
248void Serializer::toStream(std::ostream & ostr, const T & x, objType hint) const {
249
250 if (std::is_floating_point<T>()){
251 this->floatToStream(ostr, x);
252 }
253 else if (std::is_integral<T>()){
254 this->intToStream(ostr, x);
255 }
256 else {
257 ostr << x;
258 }
259}
260
263
264 char prefix = 0;
265 char separator = 0;
266 char suffix = 0;
267 //char quote = 0;
268
269 inline
270 SimpleFormatter(const char *conf=""){
271
272 switch (strlen(conf)){
273 case 3:
274 prefix = conf[0];
275 separator = conf[1];
276 suffix = conf[2];
277 break;
278 case 2:
279 prefix = conf[0];
280 suffix = conf[1];
281 break;
282 case 1:
283 separator = conf[0];
284 break;
285 case 0:
286 break;
287 default:
288 throw std::runtime_error(StringBuilder<':'>(__FILE__, "unsupported conf", conf));
289 }
290
291 }
292
293};
294
297public:
298
299 typedef std::map<objType,SimpleFormatter> char_map_t;
300
301 inline
303
304 inline
305 SimpleSerializer(const char_map_t & chars) : fmtChars(chars){};
306
307 virtual inline
309
310
311
312 virtual inline
313 void writePrefix(std::ostream & ostr, objType type) const override {
314 writePrefix(ostr, getFormatter(type));
315 }
316
317 inline
318 void writePrefix(std::ostream & ostr, const SimpleFormatter & fmt) const {
319 if (fmt.prefix){
320 ostr << fmt.prefix;
321 }
322 };
323
324 virtual
325 void writeSeparator(std::ostream & ostr, objType type) const override {
326 writeSeparator(ostr, getFormatter(type));
327 }
328
329 inline
330 void writeSeparator(std::ostream & ostr, const SimpleFormatter & fmt) const {
331 if (fmt.separator){
332 ostr << fmt.separator;
333 }
334 };
335
336 virtual
337 void writeSuffix(std::ostream & ostr, objType type) const override {
338 writeSuffix(ostr, getFormatter(type));
339 }
340
341 inline
342 void writeSuffix(std::ostream & ostr, const SimpleFormatter & fmt) const {
343 if (fmt.suffix){
344 ostr << fmt.suffix;
345 }
346 };
347
348
349 virtual
350 void stringToStream(std::ostream & ostr, const char * x) const override {
351 charsToStream(ostr, x);
352 }
353
354
361 virtual inline
362 void charToStream(std::ostream & ostr, char c) const override {
363 charsToStream(ostr, c);
364 }
365
366
367
368protected:
369
370 char_map_t fmtChars = {
371 {LIST, "[,]"},
372 {PAIR, "<,>"},
373 {SET, "{,}"},
374 {MAP,"{,}"},
375 {STRING,"''"},
376 };
377
378 virtual
379 const SimpleFormatter & getFormatter(objType t) const;
380
381
382 template <class S>
383 void charsToStream(std::ostream & ostr, const S &s) const;
384
385 virtual
386 void handleChars(std::ostream & ostr, char c) const;
387
388 virtual
389 void handleChars(std::ostream & ostr, const char *c) const;
390
391
392
393};
394
395template <class S>
396void SimpleSerializer::charsToStream(std::ostream & ostr, const S &s) const {
397
398 const SimpleFormatter & fmt = getFormatter(Serializer::STRING);
399 writePrefix(ostr, fmt);
400 handleChars(ostr, s);
401 writeSuffix(ostr, fmt);
402
403}
404
405
406}
407
408#endif
409
410
DOC: Add class description.
Definition Serializer.h:296
virtual void charToStream(std::ostream &ostr, char c) const override
Definition Serializer.h:362
Definition StringBuilder.h:58
Definition Data.h:1473
Definition Serializer.h:47
void entryToStream(std::ostream &ostr, const std::pair< K, V > &x) const
This is a map entry.
Definition Serializer.h:127
void toStr(std::string &str, const T &x) const
Default handler.
Definition Serializer.h:198
void toStream(std::ostream &ostr, const T &x, objType hint=NONE) const
Default handler.
Definition Serializer.h:248
DOC: Add class description.
Definition Serializer.h:262