Fabcoin Core  0.16.2
P2P Digital Currency
json_spirit_writer_template.h
Go to the documentation of this file.
1 #ifndef JSON_SPIRIT_WRITER_TEMPLATE
2 #define JSON_SPIRIT_WRITER_TEMPLATE
3 
4 // Copyright John W. Wilkinson 2007 - 2009.
5 // Distributed under the MIT License, see accompanying file LICENSE.txt
6 
7 // json spirit version 4.03
8 
9 #include "json_spirit_value.h"
10 
11 #include <cassert>
12 #include <sstream>
13 #include <iomanip>
14 
15 namespace json_spirit
16 {
17  inline char to_hex_char( unsigned int c )
18  {
19  assert( c <= 0xF );
20 
21  const char ch = static_cast< char >( c );
22 
23  if( ch < 10 ) return '0' + ch;
24 
25  return 'A' - 10 + ch;
26  }
27 
28  template< class String_type >
29  String_type non_printable_to_string( unsigned int c )
30  {
31  String_type result( 6, '\\' );
32 
33  result[1] = 'u';
34 
35  result[ 5 ] = to_hex_char( c & 0x000F ); c >>= 4;
36  result[ 4 ] = to_hex_char( c & 0x000F ); c >>= 4;
37  result[ 3 ] = to_hex_char( c & 0x000F ); c >>= 4;
38  result[ 2 ] = to_hex_char( c & 0x000F );
39 
40  return result;
41  }
42 
43  template< typename Char_type, class String_type >
44  bool add_esc_char( Char_type c, String_type& s )
45  {
46  switch( c )
47  {
48  case '"': s += to_str< String_type >( "\\\"" ); return true;
49  case '\\': s += to_str< String_type >( "\\\\" ); return true;
50  case '\b': s += to_str< String_type >( "\\b" ); return true;
51  case '\f': s += to_str< String_type >( "\\f" ); return true;
52  case '\n': s += to_str< String_type >( "\\n" ); return true;
53  case '\r': s += to_str< String_type >( "\\r" ); return true;
54  case '\t': s += to_str< String_type >( "\\t" ); return true;
55  }
56 
57  return false;
58  }
59 
60  template< class String_type >
61  String_type add_esc_chars( const String_type& s )
62  {
63  typedef typename String_type::const_iterator Iter_type;
64  typedef typename String_type::value_type Char_type;
65 
66  String_type result;
67 
68  const Iter_type end( s.end() );
69 
70  for( Iter_type i = s.begin(); i != end; ++i )
71  {
72  const Char_type c( *i );
73 
74  if( add_esc_char( c, result ) ) continue;
75 
76  const wint_t unsigned_c( ( c >= 0 ) ? c : 256 + c );
77 
78  if( iswprint( unsigned_c ) )
79  {
80  result += c;
81  }
82  else
83  {
84  result += non_printable_to_string< String_type >( unsigned_c );
85  }
86  }
87 
88  return result;
89  }
90 
91  // this class generates the JSON text,
92  // it keeps track of the indentation level etc.
93  //
94  template< class Value_type, class Ostream_type >
95  class Generator
96  {
97  typedef typename Value_type::Config_type Config_type;
98  typedef typename Config_type::String_type String_type;
99  typedef typename Config_type::Object_type Object_type;
100  typedef typename Config_type::Array_type Array_type;
101  typedef typename String_type::value_type Char_type;
102  typedef typename Object_type::value_type Obj_member_type;
103 
104  public:
105 
106  Generator( const Value_type& value, Ostream_type& os, bool pretty )
107  : os_( os )
108  , indentation_level_( 0 )
109  , pretty_( pretty )
110  {
111  output( value );
112  }
113 
114  private:
115 
116  void output( const Value_type& value )
117  {
118  switch( value.type() )
119  {
120  case obj_type: output( value.get_obj() ); break;
121  case array_type: output( value.get_array() ); break;
122  case str_type: output( value.get_str() ); break;
123  case bool_type: output( value.get_bool() ); break;
124  case int_type: output_int( value ); break;
125  case real_type: os_ << std::showpoint << std::setprecision( 16 )
126  << value.get_real(); break;
127  case null_type: os_ << "null"; break;
128  default: assert( false );
129  }
130  }
131 
132  void output( const Object_type& obj )
133  {
134  output_array_or_obj( obj, '{', '}' );
135  }
136 
137  void output( const Array_type& arr )
138  {
139  output_array_or_obj( arr, '[', ']' );
140  }
141 
142  void output( const Obj_member_type& member )
143  {
144  output( Config_type::get_name( member ) ); space();
145  os_ << ':'; space();
146  output( Config_type::get_value( member ) );
147  }
148 
149  void output_int( const Value_type& value )
150  {
151  if( value.is_uint64() )
152  {
153  os_ << value.get_uint64();
154  }
155  else
156  {
157  os_ << value.get_int64();
158  }
159  }
160 
161  void output( const String_type& s )
162  {
163  os_ << '"' << add_esc_chars( s ) << '"';
164  }
165 
166  void output( bool b )
167  {
168  os_ << to_str< String_type >( b ? "true" : "false" );
169  }
170 
171  template< class T >
172  void output_array_or_obj( const T& t, Char_type start_char, Char_type end_char )
173  {
174  os_ << start_char; new_line();
175 
177 
178  for( typename T::const_iterator i = t.begin(); i != t.end(); ++i )
179  {
180  indent(); output( *i );
181 
182  typename T::const_iterator next = i;
183 
184  if( ++next != t.end())
185  {
186  os_ << ',';
187  }
188 
189  new_line();
190  }
191 
193 
194  indent(); os_ << end_char;
195  }
196 
197  void indent()
198  {
199  if( !pretty_ ) return;
200 
201  for( int i = 0; i < indentation_level_; ++i )
202  {
203  os_ << " ";
204  }
205  }
206 
207  void space()
208  {
209  if( pretty_ ) os_ << ' ';
210  }
211 
212  void new_line()
213  {
214  if( pretty_ ) os_ << '\n';
215  }
216 
217  Generator& operator=( const Generator& ); // to prevent "assignment operator could not be generated" warning
218 
219  Ostream_type& os_;
221  bool pretty_;
222  };
223 
224  template< class Value_type, class Ostream_type >
225  void write_stream( const Value_type& value, Ostream_type& os, bool pretty )
226  {
228  }
229 
230  template< class Value_type >
231  typename Value_type::String_type write_string( const Value_type& value, bool pretty )
232  {
233  typedef typename Value_type::String_type::value_type Char_type;
234 
235  std::basic_ostringstream< Char_type > os;
236 
237  write_stream( value, os, pretty );
238 
239  return os.str();
240  }
241 }
242 
243 #endif
String_type non_printable_to_string(unsigned int c)
String_type::value_type Char_type
void output(const Obj_member_type &member)
void output_array_or_obj(const T &t, Char_type start_char, Char_type end_char)
void output_int(const Value_type &value)
#define T(i, x)
Config_type::Array_type Array_type
#define c(i)
assert(len-trim+(2 *lenIndices)<=WIDTH)
Config_type::String_type String_type
void output(const Value_type &value)
string pretty(h160 _a, dev::eth::State const &_st)
Definition: main.cpp:227
void write_stream(const Value_type &value, Ostream_type &os, bool pretty)
Object_type::value_type Obj_member_type
bool add_esc_char(Char_type c, String_type &s)
char to_hex_char(unsigned int c)
void output(const Object_type &obj)
Generator(const Value_type &value, Ostream_type &os, bool pretty)
int get_value(const Value &value, Type_to_type< int >)
void output(const Array_type &arr)
#define b(i, j)
Config_type::Object_type Object_type
Value_type::String_type write_string(const Value_type &value, bool pretty)
void output(const String_type &s)
uint32_t ch(uint32_t x, uint32_t y, uint32_t z)
Definition: picosha2.h:73
String_type add_esc_chars(const String_type &s)
Value_type::Config_type Config_type
Generator & operator=(const Generator &)