libzypp  17.14.0
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 
26 namespace 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  {
323  Object() {}
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
std::string asJSON() const
JSON representation.
Definition: Json.h:344
std::ostream & dumpOn(std::ostream &str) const
Stream output.
Definition: Json.h:287
Array(Iterator begin, Iterator end)
Construct from container iterator.
Definition: Json.h:262
const std::string & asString() const
String representation.
Definition: Json.h:219
static const std::string & nullJSON()
Definition: Json.h:32
std::ostream & operator<<(std::ostream &str, const Object &obj)
Definition: Json.h:371
String(const char *val_r)
Definition: Json.h:248
String related utilities and Regular expression matching.
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
const std::string & asJSON() const
JSON representation.
Definition: Json.h:215
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Definition: Easy.h:28
String(const char val_r)
Definition: Json.h:247
JSON representation of datatypes via toJSON.
Definition: Json.h:202
std::ostream & dumpOn(std::ostream &str) const
Stream output.
Definition: Json.h:352
std::string asString() const
String representation.
Definition: Json.h:348
Value(const Value &rhs)
Copy ctor.
Definition: Json.h:208
JSON object.
Definition: Json.h:321
void add(const std::initializer_list< std::pair< String, Value >> &contents_r)
Definition: Json.h:340
void add(const std::initializer_list< Value > &contents_r)
Definition: Json.h:275
std::ostream & operator<<(std::ostream &str, const Value &obj)
Definition: Json.h:231
std::string toJSON(void)
Definition: Json.h:136
static const std::string & trueJSON()
Definition: Json.h:33
std::string _data
Definition: Json.h:227
std::string strEncode(std::string val_r)
Definition: Json.h:39
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
Definition: String.h:210
std::string asString() const
String representation.
Definition: Json.h:283
std::list< std::string > _data
Definition: Json.h:298
std::ostream & dumpOn(std::ostream &str, std::map< std::string, std::string >::const_iterator val_r) const
Definition: Json.h:364
JSON array.
Definition: Json.h:256
std::string numstring(char n, int w=0)
Definition: String.h:288
SolvableIdType size_type
Definition: PoolMember.h:126
static const std::string & falseJSON()
Definition: Json.h:34
String(const std::string &val_r)
Definition: Json.h:249
void add(const Value &val_r)
Push JSON Value to Array.
Definition: Json.h:271
std::string asJSON() const
JSON representation.
Definition: Json.h:279
std::ostream & dumpOn(std::ostream &str) const
Stream output.
Definition: Json.h:223
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:1
Object(Iterator begin, Iterator end)
Construct from map-iterator.
Definition: Json.h:327
Value(const T &val_r)
Ctor creating a JSON representation of T via toJSON(T)
Definition: Json.h:212
void add(const String &key_r, const Value &val_r)
Add key/value pair.
Definition: Json.h:336
String(std::nullptr_t)
Definition: Json.h:245
std::ostream & operator<<(std::ostream &str, const Array &obj)
Definition: Json.h:302
Value()
Default ctor (null)
Definition: Json.h:205
JSON string Force representation as JSON string, mapping e.g.
Definition: Json.h:242
Array(const std::initializer_list< Value > &contents_r)
Construct from container initializer list { v1, v2,...
Definition: Json.h:266