Feathercoin  0.5.0
P2P Digital Currency
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
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  // Silence the warning: typedef ‘Char_type’ locally defined but not used [-Wunused-local-typedefs]
32  // typedef typename String_type::value_type Char_type;
33 
34  String_type result( 6, '\\' );
35 
36  result[1] = 'u';
37 
38  result[ 5 ] = to_hex_char( c & 0x000F ); c >>= 4;
39  result[ 4 ] = to_hex_char( c & 0x000F ); c >>= 4;
40  result[ 3 ] = to_hex_char( c & 0x000F ); c >>= 4;
41  result[ 2 ] = to_hex_char( c & 0x000F );
42 
43  return result;
44  }
45 
46  template< typename Char_type, class String_type >
47  bool add_esc_char( Char_type c, String_type& s )
48  {
49  switch( c )
50  {
51  case '"': s += to_str< String_type >( "\\\"" ); return true;
52  case '\\': s += to_str< String_type >( "\\\\" ); return true;
53  case '\b': s += to_str< String_type >( "\\b" ); return true;
54  case '\f': s += to_str< String_type >( "\\f" ); return true;
55  case '\n': s += to_str< String_type >( "\\n" ); return true;
56  case '\r': s += to_str< String_type >( "\\r" ); return true;
57  case '\t': s += to_str< String_type >( "\\t" ); return true;
58  }
59 
60  return false;
61  }
62 
63  template< class String_type >
64  String_type add_esc_chars( const String_type& s )
65  {
66  typedef typename String_type::const_iterator Iter_type;
67  typedef typename String_type::value_type Char_type;
68 
69  String_type result;
70 
71  const Iter_type end( s.end() );
72 
73  for( Iter_type i = s.begin(); i != end; ++i )
74  {
75  const Char_type c( *i );
76 
77  if( add_esc_char( c, result ) ) continue;
78 
79  const wint_t unsigned_c( ( c >= 0 ) ? c : 256 + c );
80 
81  if( iswprint( unsigned_c ) )
82  {
83  result += c;
84  }
85  else
86  {
87  result += non_printable_to_string< String_type >( unsigned_c );
88  }
89  }
90 
91  return result;
92  }
93 
94  // this class generates the JSON text,
95  // it keeps track of the indentation level etc.
96  //
97  template< class Value_type, class Ostream_type >
98  class Generator
99  {
100  typedef typename Value_type::Config_type Config_type;
101  typedef typename Config_type::String_type String_type;
102  typedef typename Config_type::Object_type Object_type;
103  typedef typename Config_type::Array_type Array_type;
104  typedef typename String_type::value_type Char_type;
105  typedef typename Object_type::value_type Obj_member_type;
106 
107  public:
108 
109  Generator( const Value_type& value, Ostream_type& os, bool pretty )
110  : os_( os )
111  , indentation_level_( 0 )
112  , pretty_( pretty )
113  {
114  output( value );
115  }
116 
117  private:
118 
119  void output( const Value_type& value )
120  {
121  switch( value.type() )
122  {
123  case obj_type: output( value.get_obj() ); break;
124  case array_type: output( value.get_array() ); break;
125  case str_type: output( value.get_str() ); break;
126  case bool_type: output( value.get_bool() ); break;
127  case int_type: output_int( value ); break;
128 
130  case real_type: os_ << std::showpoint << std::fixed << std::setprecision(8)
131  << value.get_real(); break;
132 
133  case null_type: os_ << "null"; break;
134  default: assert( false );
135  }
136  }
137 
138  void output( const Object_type& obj )
139  {
140  output_array_or_obj( obj, '{', '}' );
141  }
142 
143  void output( const Array_type& arr )
144  {
145  output_array_or_obj( arr, '[', ']' );
146  }
147 
148  void output( const Obj_member_type& member )
149  {
150  output( Config_type::get_name( member ) ); space();
151  os_ << ':'; space();
152  output( Config_type::get_value( member ) );
153  }
154 
155  void output_int( const Value_type& value )
156  {
157  if( value.is_uint64() )
158  {
159  os_ << value.get_uint64();
160  }
161  else
162  {
163  os_ << value.get_int64();
164  }
165  }
166 
167  void output( const String_type& s )
168  {
169  os_ << '"' << add_esc_chars( s ) << '"';
170  }
171 
172  void output( bool b )
173  {
174  os_ << to_str< String_type >( b ? "true" : "false" );
175  }
176 
177  template< class T >
178  void output_array_or_obj( const T& t, Char_type start_char, Char_type end_char )
179  {
180  os_ << start_char; new_line();
181 
183 
184  for( typename T::const_iterator i = t.begin(); i != t.end(); ++i )
185  {
186  indent(); output( *i );
187 
188  typename T::const_iterator next = i;
189 
190  if( ++next != t.end())
191  {
192  os_ << ',';
193  }
194 
195  new_line();
196  }
197 
199 
200  indent(); os_ << end_char;
201  }
202 
203  void indent()
204  {
205  if( !pretty_ ) return;
206 
207  for( int i = 0; i < indentation_level_; ++i )
208  {
209  os_ << " ";
210  }
211  }
212 
213  void space()
214  {
215  if( pretty_ ) os_ << ' ';
216  }
217 
218  void new_line()
219  {
220  if( pretty_ ) os_ << '\n';
221  }
222 
223  Generator& operator=( const Generator& ); // to prevent "assignment operator could not be generated" warning
224 
225  Ostream_type& os_;
227  bool pretty_;
228  };
229 
230  template< class Value_type, class Ostream_type >
231  void write_stream( const Value_type& value, Ostream_type& os, bool pretty )
232  {
234  }
235 
236  template< class Value_type >
237  typename Value_type::String_type write_string( const Value_type& value, bool pretty )
238  {
239  typedef typename Value_type::String_type::value_type Char_type;
240 
241  std::basic_ostringstream< Char_type > os;
242 
243  write_stream( value, os, pretty );
244 
245  return os.str();
246  }
247 }
248 
249 #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)
std::string * value
Definition: version_set.cc:270
Config_type::Array_type Array_type
Config_type::String_type String_type
void output(const Value_type &value)
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)
LRUHandle * next
Definition: cache.cc:29
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)
Config_type::Object_type Object_type
Value_type::String_type write_string(const Value_type &value, bool pretty)
void output(const String_type &s)
String_type add_esc_chars(const String_type &s)
Value_type::Config_type Config_type
Generator & operator=(const Generator &)