libzypp 17.31.23
Json.h
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8\---------------------------------------------------------------------*/
12#ifndef ZYPP_BASE_JSON_H
13#define ZYPP_BASE_JSON_H
14
15#include <iosfwd>
16#include <string>
17#include <vector>
18#include <list>
19#include <set>
20#include <map>
21
22#include <zypp/base/Easy.h>
23#include <zypp/base/String.h>
24
26namespace zypp
27{
29 namespace json
30 {
31 // JSN Keywords
32 inline static const std::string & nullJSON() { static const std::string _s( "null" ); return _s; }
33 inline static const std::string & trueJSON() { static const std::string _s( "true" ); return _s; }
34 inline static const std::string & falseJSON() { static const std::string _s( "false" ); return _s; }
35
37 namespace detail
38 {
39 inline std::string strEncode( std::string val_r )
40 {
41 typedef unsigned char uchar;
42
43 std::string::size_type add = 2; // enclosing "s
44 for_( r, val_r.begin(), val_r.end() )
45 {
46 if ( uchar(*r) < 32u )
47 {
48 switch ( *r )
49 {
50 case '\b':
51 case '\f':
52 case '\n':
53 case '\r':
54 case '\t':
55 add += 1; // "\c"
56 break;
57 default:
58 add += 5; // "\uXXXX"
59 break;
60 }
61 }
62 else
63 {
64 switch ( *r )
65 {
66 case '"':
67 case '/':
68 case '\\':
69 add += 1; // \-escape
70 break;
71 }
72 }
73 }
74
75 val_r.resize( val_r.size() + add, '@' );
76 auto w( val_r.rbegin() );
77 auto r( w + add );
78
79 *w++ = '"';
80 for ( ; r != val_r.rend(); ++r )
81 {
82 if ( uchar(*r) < 32u )
83 {
84 static const char * digit = "0123456789abcdef";
85 switch ( *r )
86 {
87 case '\b': // "\c"
88 *w++ = 'b';
89 *w++ = '\\';
90 break;
91 case '\f': // "\c"
92 *w++ = 'f';
93 *w++ = '\\';
94 break;
95 case '\n': // "\c"
96 *w++ = 'n';
97 *w++ = '\\';
98 break;
99 case '\r': // "\c"
100 *w++ = 'r';
101 *w++ = '\\';
102 break;
103 case '\t': // "\c"
104 *w++ = 't';
105 *w++ = '\\';
106 break;
107 default: // "\uXXXX"
108 *w++ = digit[uchar(*r) % 15];
109 *w++ = digit[uchar(*r) / 16];
110 *w++ = '0';
111 *w++ = '0';
112 *w++ = 'u';
113 *w++ = '\\';
114 break;
115 }
116 }
117 else
118 {
119 switch ( (*w++ = *r) )
120 {
121 case '"':
122 case '/':
123 case '\\': // \-escape
124 *w++ = '\\';
125 break;
126 }
127 }
128 }
129 *w++ = '"';
130 return val_r;
131 }
132 } // namespace detail
134
135 // null
136 inline std::string toJSON( void ) { return nullJSON(); }
137 inline std::string toJSON( std::nullptr_t ) { return nullJSON(); }
138
139 // bool
140 inline std::string toJSON( bool val_r ) { return val_r ? trueJSON() : falseJSON(); }
141 inline std::string toJSON( const void * val_r ) { return val_r ? trueJSON() : falseJSON(); }
142
143 // numbers
144 inline std::string toJSON( short val_r ) { return str::numstring( val_r ); }
145 inline std::string toJSON( unsigned short val_r ) { return str::numstring( val_r ); }
146 inline std::string toJSON( int val_r ) { return str::numstring( val_r ); }
147 inline std::string toJSON( unsigned val_r ) { return str::numstring( val_r ); }
148 inline std::string toJSON( long val_r ) { return str::numstring( val_r ); }
149 inline std::string toJSON( unsigned long val_r ) { return str::numstring( val_r ); }
150 inline std::string toJSON( long long val_r ) { return str::numstring( val_r ); }
151 inline std::string toJSON( unsigned long long val_r ){ return str::numstring( val_r ); }
152
153 // strings
154 inline std::string toJSON( const char val_r ) { return detail::strEncode( std::string( 1, val_r ) ); }
155 inline std::string toJSON( const char * val_r ) { return val_r ? detail::strEncode( val_r ) : nullJSON(); }
156 inline std::string toJSON( const std::string & val_r ){ return detail::strEncode( val_r ); }
157
158 // container to Array
159 template <class V> std::string toJSON( const std::vector<V> & cont_r );
160 template <class V> std::string toJSON( const std::list<V> & cont_r );
161 template <class V> std::string toJSON( const std::set<V> & cont_r );
162
163 // map to Object
164 template <class K, class V> std::string toJSON( const std::map<K,V> & cont_r );
165
175 template <class T>
176 std::string toJSON( const T & val_r ) { return val_r.asJSON(); }
177
202 struct Value
203 {
205 Value() : _data( toJSON() ) {}
206
208 Value( const Value & rhs ) : _data( rhs._data ) {}
209
211 template <class T>
212 Value( const T & val_r ) : _data( toJSON( val_r ) ) {}
213
215 const std::string & asJSON() const
216 { return _data; }
217
219 const std::string & asString() const
220 { return asJSON(); }
221
223 std::ostream & dumpOn( std::ostream & str ) const
224 { return str << _data; }
225
226 private:
227 std::string _data;
228 };
229
231 inline std::ostream & operator<<( std::ostream & str, const Value & obj )
232 { return obj.dumpOn( str ); }
233
235
242 struct String : public Value
243 {
244 String() : Value( "" ) {}
245 String( std::nullptr_t ) : Value( "" ) {}
246
247 String( const char val_r ) : Value( val_r ) {}
248 String( const char * val_r ) : Value( val_r ? val_r : "" ) {}
249 String( const std::string & val_r ): Value( val_r ) {}
250 };
251
256 struct Array
257 {
258 Array() {}
259
261 template <class Iterator>
262 Array( Iterator begin, Iterator end )
263 { for_( it, begin, end ) add( *it ); }
264
266 Array( const std::initializer_list<Value> & contents_r )
267 : Array( contents_r.begin(), contents_r.end() )
268 {}
269
271 void add( const Value & val_r )
272 { _data.push_back( val_r.asJSON() ); }
273
275 void add( const std::initializer_list<Value> & contents_r )
276 { for_( it, contents_r.begin(), contents_r.end() ) add( *it ); }
277
279 std::string asJSON() const
280 { return str::Str() << *this; }
281
283 std::string asString() const
284 { return asJSON(); }
285
287 std::ostream & dumpOn( std::ostream & str ) const
288 {
289 if ( _data.empty() )
290 return str << "[]";
291 str << '[' << *_data.begin();
292 for_( val, ++_data.begin(), _data.end() )
293 str << ", " << *val;
294 return str << ']';
295 }
296
297 private:
298 std::list<std::string> _data;
299 };
300
302 inline std::ostream & operator<<( std::ostream & str, const Array & obj )
303 { return obj.dumpOn( str ); }
304
305 template <class V>
306 std::string toJSON( const std::vector<V> & cont_r )
307 { return json::Array( cont_r.begin(), cont_r.end() ).asJSON(); }
308
309 template <class V>
310 std::string toJSON( const std::list<V> & cont_r )
311 { return json::Array( cont_r.begin(), cont_r.end() ).asJSON(); }
312
313 template <class V>
314 std::string toJSON( const std::set<V> & cont_r )
315 { return json::Array( cont_r.begin(), cont_r.end() ).asJSON(); }
316
321 struct Object
322 {
324
326 template <class Iterator>
327 Object( Iterator begin, Iterator end )
328 { for_( it, begin, end ) add( it->first, it->second ); }
329
331 Object( const std::initializer_list<std::pair<String, Value>> & contents_r )
332 : Object( contents_r.begin(), contents_r.end() )
333 {}
334
336 void add( const String & key_r, const Value & val_r )
337 { _data[key_r.asJSON()] = val_r.asJSON(); }
338
340 void add( const std::initializer_list<std::pair<String, Value>> & contents_r )
341 { for_( it, contents_r.begin(), contents_r.end() ) add( it->first, it->second ); }
342
344 std::string asJSON() const
345 { return str::Str() << *this; }
346
348 std::string asString() const
349 { return asJSON(); }
350
352 std::ostream & dumpOn( std::ostream & str ) const
353 {
354 using std::endl;
355 if ( _data.empty() )
356 return str << "{}";
357 dumpOn( str << '{' << endl, _data.begin() );
358 for_ ( val, ++_data.begin(), _data.end() )
359 dumpOn( str << ',' << endl, val );
360 return str << endl << '}';
361 }
362
363 private:
364 std::ostream & dumpOn( std::ostream & str, std::map<std::string,std::string>::const_iterator val_r ) const
365 { return str << val_r->first << ": " << val_r->second; }
366
367 std::map<std::string,std::string> _data;
368 };
369
371 inline std::ostream & operator<<( std::ostream & str, const Object & obj )
372 { return obj.dumpOn( str ); }
373
374 template <class K, class V>
375 std::string toJSON( const std::map<K,V> & cont_r )
376 { return json::Object( cont_r.begin(), cont_r.end() ).asJSON(); }
377
378
379 } // namespace json
381} // namespace zypp
383#endif // ZYPP_BASE_JSON_H
String related utilities and Regular expression matching.
std::string strEncode(std::string val_r)
Definition: Json.h:39
static const std::string & falseJSON()
Definition: Json.h:34
static const std::string & trueJSON()
Definition: Json.h:33
std::string toJSON(void)
Definition: Json.h:136
static const std::string & nullJSON()
Definition: Json.h:32
std::string numstring(char n, int w=0)
Definition: String.h:289
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:2
JSON array.
Definition: Json.h:257
std::ostream & dumpOn(std::ostream &str) const
Stream output.
Definition: Json.h:287
void add(const std::initializer_list< Value > &contents_r)
Definition: Json.h:275
std::string asJSON() const
JSON representation.
Definition: Json.h:279
std::ostream & operator<<(std::ostream &str, const Array &obj)
Stream output.
Definition: Json.h:302
std::list< std::string > _data
Definition: Json.h:298
std::string asString() const
String representation.
Definition: Json.h:283
Array(Iterator begin, Iterator end)
Construct from container iterator.
Definition: Json.h:262
void add(const Value &val_r)
Push JSON Value to Array.
Definition: Json.h:271
Array(const std::initializer_list< Value > &contents_r)
Construct from container initializer list { v1, v2,... }.
Definition: Json.h:266
JSON object.
Definition: Json.h:322
Object(Iterator begin, Iterator end)
Construct from map-iterator.
Definition: Json.h:327
void add(const String &key_r, const Value &val_r)
Add key/value pair.
Definition: Json.h:336
std::string asJSON() const
JSON representation.
Definition: Json.h:344
std::ostream & dumpOn(std::ostream &str, std::map< std::string, std::string >::const_iterator val_r) const
Definition: Json.h:364
std::ostream & dumpOn(std::ostream &str) const
Stream output.
Definition: Json.h:352
std::ostream & operator<<(std::ostream &str, const Object &obj)
Stream output.
Definition: Json.h:371
void add(const std::initializer_list< std::pair< String, Value > > &contents_r)
Definition: Json.h:340
std::string asString() const
String representation.
Definition: Json.h:348
std::map< std::string, std::string > _data
Definition: Json.h:367
Object(const std::initializer_list< std::pair< String, Value > > &contents_r)
Construct from map-initializer list { {k1,v1}, {k2,v2},... }.
Definition: Json.h:331
JSON string Force representation as JSON string, mapping e.g.
Definition: Json.h:243
String(std::nullptr_t)
Definition: Json.h:245
String(const char *val_r)
Definition: Json.h:248
String(const char val_r)
Definition: Json.h:247
String(const std::string &val_r)
Definition: Json.h:249
JSON representation of datatypes via toJSON.
Definition: Json.h:203
std::ostream & dumpOn(std::ostream &str) const
Stream output.
Definition: Json.h:223
std::ostream & operator<<(std::ostream &str, const Value &obj)
Stream output.
Definition: Json.h:231
Value()
Default ctor (null)
Definition: Json.h:205
const std::string & asString() const
String representation.
Definition: Json.h:219
const std::string & asJSON() const
JSON representation.
Definition: Json.h:215
std::string _data
Definition: Json.h:227
Value(const Value &rhs)
Copy ctor.
Definition: Json.h:208
Value(const T &val_r)
Ctor creating a JSON representation of T via toJSON(T)
Definition: Json.h:212
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
Definition: String.h:212
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Definition: Easy.h:28