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