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 <vector>
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 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 ostr << std::ios_base::boolalpha;
219 ostr << x;
220 }
221
222 virtual inline
223 void nullToStream(std::ostream & ostr) const {
224 ostr << "null";
225 }
226
227 virtual inline
228 void charToStream(std::ostream & ostr, char c) const {
229 ostr << c;
230 }
231
232 virtual inline
233 void stringToStream(std::ostream & ostr, const char *x) const {
234 ostr << x;
235 }
236
237 virtual inline
238 void stringToStream(std::ostream & ostr, const std::string & x) const final {
239 stringToStream(ostr, x.c_str());
240 }
241
242
243};
244
245template <class T>
246void Serializer::toStream(std::ostream & ostr, const T & x, objType hint) const {
247
248 if (std::is_floating_point<T>()){
249 this->floatToStream(ostr, x);
250 }
251 else if (std::is_integral<T>()){
252 this->intToStream(ostr, x);
253 }
254 else {
255 ostr << x;
256 }
257}
258
260
261 char prefix = 0;
262 char separator = 0;
263 char suffix = 0;
264 //char quote = 0;
265
266 inline
267 SimpleFormatter(const char *conf=""){
268
269 switch (strlen(conf)){
270 case 3:
271 prefix = conf[0];
272 separator = conf[1];
273 suffix = conf[2];
274 break;
275 case 2:
276 prefix = conf[0];
277 suffix = conf[1];
278 break;
279 case 1:
280 separator = conf[0];
281 break;
282 case 0:
283 break;
284 default:
285 throw std::runtime_error(StringBuilder<':'>(__FILE__, "unsupported conf", conf));
286 }
287
288 }
289
290};
291
293public:
294
295 typedef std::map<objType,SimpleFormatter> char_map_t;
296
297 inline
299
300 inline
301 SimpleSerializer(const char_map_t & chars) : fmtChars(chars){};
302
303 virtual inline
305
306
307
308 virtual inline
309 void writePrefix(std::ostream & ostr, objType type) const override {
310 writePrefix(ostr, getFormatter(type));
311 }
312
313 inline
314 void writePrefix(std::ostream & ostr, const SimpleFormatter & fmt) const {
315 if (fmt.prefix){
316 ostr << fmt.prefix;
317 }
318 };
319
320 virtual
321 void writeSeparator(std::ostream & ostr, objType type) const override {
322 writeSeparator(ostr, getFormatter(type));
323 }
324
325 inline
326 void writeSeparator(std::ostream & ostr, const SimpleFormatter & fmt) const {
327 if (fmt.separator){
328 ostr << fmt.separator;
329 }
330 };
331
332 virtual
333 void writeSuffix(std::ostream & ostr, objType type) const override {
334 writeSuffix(ostr, getFormatter(type));
335 }
336
337 inline
338 void writeSuffix(std::ostream & ostr, const SimpleFormatter & fmt) const {
339 if (fmt.suffix){
340 ostr << fmt.suffix;
341 }
342 };
343
344
345 virtual
346 void stringToStream(std::ostream & ostr, const char * x) const override {
347 charsToStream(ostr, x);
348 }
349
350
357 virtual inline
358 void charToStream(std::ostream & ostr, char c) const override {
359 charsToStream(ostr, c);
360 }
361
362
363
364protected:
365
366 char_map_t fmtChars = {
367 {LIST, "[,]"},
368 {PAIR, "<,>"},
369 {SET, "{,}"},
370 {MAP,"{,}"},
371 {STRING,"''"},
372 };
373
374 virtual
375 const SimpleFormatter & getFormatter(objType t) const;
376
377
378 template <class S>
379 void charsToStream(std::ostream & ostr, const S &s) const;
380
381 virtual
382 void handleChars(std::ostream & ostr, char c) const;
383
384 virtual
385 void handleChars(std::ostream & ostr, const char *c) const;
386
387
388
389};
390
391template <class S>
392void SimpleSerializer::charsToStream(std::ostream & ostr, const S &s) const {
393
394 const SimpleFormatter & fmt = getFormatter(Serializer::STRING);
395 writePrefix(ostr, fmt);
396 handleChars(ostr, s);
397 writeSuffix(ostr, fmt);
398
399}
400
401
402}
403
404#endif
405
406
Definition Serializer.h:292
virtual void charToStream(std::ostream &ostr, char c) const override
Definition Serializer.h:358
Definition StringBuilder.h:58
Definition DataSelector.cpp:1277
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:246
Definition Serializer.h:259