BitShares-Core  7.0.2
BitShares blockchain node software and command-line wallet software
json.cpp
Go to the documentation of this file.
1 #include <fc/io/json.hpp>
3 #include <fc/io/iostream.hpp>
5 #include <fc/io/fstream.hpp>
6 #include <fc/io/sstream.hpp>
7 #include <fc/log/logger.hpp>
8 #include <cstdint>
9 #include <iostream>
10 #include <fstream>
11 #include <sstream>
12 
13 #include <boost/filesystem/fstream.hpp>
14 
15 namespace fc
16 {
17  // forward declarations of provided functions
18  template<typename T, json::parse_type parser_type> variant variant_from_stream( T& in, uint32_t max_depth );
19  template<typename T> char parseEscape( T& in );
20  template<typename T> std::string stringFromStream( T& in );
21  template<typename T> bool skip_white_space( T& in );
22  template<typename T> std::string stringFromToken( T& in );
23  template<typename T> variant_object objectFromStreamBase( T& in, std::function<std::string(T&)>& get_key, std::function<variant(T&)>& get_value );
24  template<typename T, json::parse_type parser_type> variant_object objectFromStream( T& in, uint32_t max_depth );
25  template<typename T> variants arrayFromStreamBase( T& in, std::function<variant(T&)>& get_value );
26  template<typename T, json::parse_type parser_type> variants arrayFromStream( T& in, uint32_t max_depth );
27  template<typename T, json::parse_type parser_type> variant number_from_stream( T& in );
28  template<typename T> variant token_from_stream( T& in );
29  void escape_string( const string& str, ostream& os );
30  template<typename T> void to_stream( T& os, const variants& a, json::output_formatting format, uint32_t max_depth );
31  template<typename T> void to_stream( T& os, const variant_object& o, json::output_formatting format, uint32_t max_depth );
32  template<typename T> void to_stream( T& os, const variant& v, json::output_formatting format, uint32_t max_depth );
33  std::string pretty_print( const std::string& v, uint8_t indent );
34 }
35 
36 #if __cplusplus > 201402L
37 #define FALLTHROUGH [[fallthrough]];
38 #else
39 #define FALLTHROUGH
40 #endif
41 
42 #include <fc/io/json_relaxed.hpp>
43 
44 namespace fc
45 {
46  template<typename T>
47  char parseEscape( T& in )
48  {
49  if( in.peek() == '\\' )
50  {
51  try {
52  in.get();
53  switch( in.peek() )
54  {
55  case 't':
56  in.get();
57  return '\t';
58  case 'n':
59  in.get();
60  return '\n';
61  case 'r':
62  in.get();
63  return '\r';
64  case '\\':
65  in.get();
66  return '\\';
67  default:
68  return in.get();
69  }
70  } FC_RETHROW_EXCEPTIONS( info, "Stream ended with '\\'" );
71  }
72  FC_THROW_EXCEPTION( parse_error_exception, "Expected '\\'" );
73  }
74 
75  template<typename T>
76  bool skip_white_space( T& in )
77  {
78  bool skipped = false;
79  while( true )
80  {
81  switch( in.peek() )
82  {
83  case ' ':
84  case '\t':
85  case '\n':
86  case '\r':
87  skipped = true;
88  in.get();
89  break;
90  default:
91  return skipped;
92  }
93  }
94  }
95 
96  template<typename T>
97  std::string stringFromStream( T& in )
98  {
99  fc::stringstream token;
100  try
101  {
102  char c = in.peek();
103 
104  if( c != '"' )
105  FC_THROW_EXCEPTION( parse_error_exception,
106  "Expected '\"' but read '${char}'",
107  ("char", string(&c, (&c) + 1) ) );
108  in.get();
109  while( true )
110  {
111 
112  switch( c = in.peek() )
113  {
114  case '\\':
115  token << parseEscape( in );
116  break;
117  case 0x04:
118  FC_THROW_EXCEPTION( parse_error_exception, "EOF before closing '\"' in string '${token}'",
119  ("token", token.str() ) );
120  case '"':
121  in.get();
122  return token.str();
123  default:
124  token << c;
125  in.get();
126  }
127  }
128  FC_THROW_EXCEPTION( parse_error_exception, "EOF before closing '\"' in string '${token}'",
129  ("token", token.str() ) );
130  } FC_RETHROW_EXCEPTIONS( warn, "while parsing token '${token}'",
131  ("token", token.str() ) );
132  }
133  template<typename T>
134  std::string stringFromToken( T& in )
135  {
136  fc::stringstream token;
137  try
138  {
139  char c = in.peek();
140 
141  while( true )
142  {
143  switch( c = in.peek() )
144  {
145  case '\\':
146  token << parseEscape( in );
147  break;
148  case '\t':
149  case ' ':
150  case '\0':
151  case '\n':
152  in.get();
153  return token.str();
154  default:
155  if( isalnum( c ) || c == '_' || c == '-' || c == '.' || c == ':' || c == '/' )
156  {
157  token << c;
158  in.get();
159  }
160  else return token.str();
161  }
162  }
163  return token.str();
164  }
165  catch( const fc::eof_exception& eof )
166  {
167  return token.str();
168  }
169  catch (const std::ios_base::failure&)
170  {
171  return token.str();
172  }
173 
174  FC_RETHROW_EXCEPTIONS( warn, "while parsing token '${token}'",
175  ("token", token.str() ) );
176  }
177 
178  template<typename T>
179  variant_object objectFromStreamBase( T& in, std::function<std::string(T&)>& get_key, std::function<variant(T&)>& get_value )
180  {
182  try
183  {
184  char c = in.peek();
185  if( c != '{' )
186  FC_THROW_EXCEPTION( parse_error_exception,
187  "Expected '{', but read '${char}'",
188  ("char",string(&c, &c + 1)) );
189  in.get();
190  while( in.peek() != '}' )
191  {
192  if( in.peek() == ',' )
193  {
194  in.get();
195  continue;
196  }
197  if( skip_white_space(in) ) continue;
198  string key = get_key( in );
199  skip_white_space(in);
200  if( in.peek() != ':' )
201  {
202  FC_THROW_EXCEPTION( parse_error_exception, "Expected ':' after key \"${key}\"",
203  ("key", key) );
204  }
205  in.get();
206  auto val = get_value( in );
207 
208  obj(std::move(key),std::move(val));
209  }
210  if( in.peek() == '}' )
211  {
212  in.get();
213  return obj;
214  }
215  FC_THROW_EXCEPTION( parse_error_exception, "Expected '}' after ${variant}", ("variant", obj ) );
216  }
217  catch( const fc::eof_exception& e )
218  {
219  FC_THROW_EXCEPTION( parse_error_exception, "Unexpected EOF: ${e}", ("e", e.to_detail_string() ) );
220  }
221  catch( const std::ios_base::failure& e )
222  {
223  FC_THROW_EXCEPTION( parse_error_exception, "Unexpected EOF: ${e}", ("e", e.what() ) );
224  } FC_RETHROW_EXCEPTIONS( warn, "Error parsing object" );
225  }
226 
227  template<typename T, json::parse_type parser_type>
228  variant_object objectFromStream( T& in, uint32_t max_depth )
229  {
230  std::function<std::string(T&)> get_key = []( T& in ){ return stringFromStream( in ); };
231  std::function<variant(T&)> get_value = [max_depth]( T& in ){ return variant_from_stream<T, parser_type>( in, max_depth ); };
232  return objectFromStreamBase<T>( in, get_key, get_value );
233  }
234 
235  template<typename T>
236  variants arrayFromStreamBase( T& in, std::function<variant(T&)>& get_value )
237  {
238  variants ar;
239  try
240  {
241  if( in.peek() != '[' )
242  FC_THROW_EXCEPTION( parse_error_exception, "Expected '['" );
243  in.get();
244 
245  while( in.peek() != ']' )
246  {
247  if( in.peek() == ',' )
248  {
249  in.get();
250  continue;
251  }
252  if( skip_white_space(in) ) continue;
253  ar.push_back( get_value(in) );
254  }
255  if( in.peek() != ']' )
256  FC_THROW_EXCEPTION( parse_error_exception, "Expected ']' after parsing ${variant}",
257  ("variant", ar) );
258 
259  in.get();
260  } FC_RETHROW_EXCEPTIONS( warn, "Attempting to parse array ${array}",
261  ("array", ar ) );
262  return ar;
263  }
264 
265  template<typename T, json::parse_type parser_type>
266  variants arrayFromStream( T& in, uint32_t max_depth )
267  {
268  std::function<variant(T&)> get_value = [max_depth]( T& in ){ return variant_from_stream<T, parser_type>( in, max_depth ); };
269  return arrayFromStreamBase<T>( in, get_value );
270  }
271 
272  template<typename T, json::parse_type parser_type>
274  {
275  fc::stringstream ss;
276 
277  bool dot = false;
278  bool neg = false;
279  if( in.peek() == '-')
280  {
281  neg = true;
282  ss.put( in.get() );
283  }
284  bool done = false;
285 
286  try
287  {
288  char c;
289  while((c = in.peek()) && !done)
290  {
291 
292  switch( c )
293  {
294  case '.':
295  if (dot)
296  FC_THROW_EXCEPTION(parse_error_exception, "Can't parse a number with two decimal places");
297  dot = true;
299  case '0':
300  case '1':
301  case '2':
302  case '3':
303  case '4':
304  case '5':
305  case '6':
306  case '7':
307  case '8':
308  case '9':
309  ss.put( in.get() );
310  break;
311  default:
312  if( isalnum( c ) )
313  {
314  return ss.str() + stringFromToken( in );
315  }
316  done = true;
317  break;
318  }
319  }
320  }
321  catch (fc::eof_exception&)
322  { // EOF ends the loop
323  }
324  catch (const std::ios_base::failure&)
325  { // read error ends the loop
326  }
327  std::string str = ss.str();
328  if (str == "-." || str == "." || str == "-") // check the obviously wrong things we could have encountered
329  FC_THROW_EXCEPTION(parse_error_exception, "Can't parse token \"${token}\" as a JSON numeric constant", ("token", str));
330  if( dot )
331  return
332 #ifdef WITH_EXOTIC_JSON_PARSERS
333  parser_type == json::legacy_parser_with_string_doubles ? variant(str) :
334 #endif
335  variant(to_double(str));
336  if( neg )
337  return to_int64(str);
338  return to_uint64(str);
339  }
340  template<typename T>
342  {
343  std::stringstream ss;
344  ss.exceptions( std::ifstream::badbit );
345  bool received_eof = false;
346  bool done = false;
347 
348  try
349  {
350  char c;
351  while((c = in.peek()) && !done)
352  {
353  switch( c )
354  {
355  case 'n':
356  case 'u':
357  case 'l':
358  case 't':
359  case 'r':
360  case 'e':
361  case 'f':
362  case 'a':
363  case 's':
364  ss.put( in.get() );
365  break;
366  default:
367  done = true;
368  break;
369  }
370  }
371  }
372  catch (fc::eof_exception&)
373  {
374  received_eof = true;
375  }
376  catch (const std::ios_base::failure&)
377  {
378  received_eof = true;
379  }
380 
381  // we can get here either by processing a delimiter as in "null,"
382  // an EOF like "null<EOF>", or an invalid token like "nullZ"
383  std::string str = ss.str();
384  if( str == "null" )
385  return variant();
386  if( str == "true" )
387  return true;
388  if( str == "false" )
389  return false;
390  else
391  {
392  if (received_eof)
393  {
394  if (str.empty())
395  FC_THROW_EXCEPTION( parse_error_exception, "Unexpected EOF" );
396  else
397  return str;
398  }
399  else
400  {
401  // if we've reached this point, we've either seen a partial
402  // token ("tru<EOF>") or something our simple parser couldn't
403  // make out ("falfe")
404  // A strict JSON parser would signal this as an error, but we
405  // will just treat the malformed token as an un-quoted string.
406  return str + stringFromToken(in);
407  }
408  }
409  }
410 
411 
412  template<typename T, json::parse_type parser_type>
413  variant variant_from_stream( T& in, uint32_t max_depth )
414  {
415  if( max_depth == 0 )
416  FC_THROW_EXCEPTION( parse_error_exception, "Too many nested items in JSON input!" );
417  skip_white_space(in);
418  signed char c = in.peek();
419  switch( c )
420  {
421  case '"':
422  return stringFromStream( in );
423  case '{':
424  return objectFromStream<T, parser_type>( in, max_depth - 1 );
425  case '[':
426  return arrayFromStream<T, parser_type>( in, max_depth - 1 );
427  case '-':
428  case '.':
429  case '0':
430  case '1':
431  case '2':
432  case '3':
433  case '4':
434  case '5':
435  case '6':
436  case '7':
437  case '8':
438  case '9':
439  return number_from_stream<T, parser_type>( in );
440  // null, true, false, or 'warning' / string
441  case 'n':
442  case 't':
443  case 'f':
444  return token_from_stream( in );
445  case 0x04: // ^D end of transmission
446  case EOF:
447  FC_THROW_EXCEPTION( eof_exception, "unexpected end of file" );
448  case 0:
449  if( parser_type == fc::json::broken_nul_parser )
450  return variant();
452  default:
453  FC_THROW_EXCEPTION( parse_error_exception, "Unexpected char '${c}' in \"${s}\"",
454  ("c", c)("s", stringFromToken(in)) );
455  }
456  }
457 
458  variant json::from_string( const std::string& utf8_str, parse_type ptype, uint32_t max_depth )
459  { try {
460  fc::istream_ptr in( new fc::stringstream( utf8_str ) );
461  fc::buffered_istream bin( in );
462  return from_stream( bin, ptype, max_depth );
463  } FC_RETHROW_EXCEPTIONS( warn, "", ("str",utf8_str) ) }
464 
465  variants json::variants_from_string( const std::string& utf8_str, parse_type ptype, uint32_t max_depth )
466  {
467  variants result;
468  try {
469  fc::stringstream in( utf8_str );
470  while( true )
471  result.push_back(json_relaxed::variant_from_stream<fc::stringstream, false>( in, max_depth ));
472  } catch ( const fc::eof_exception& ) {
473  return result;
474  } FC_RETHROW_EXCEPTIONS( warn, "", ("str",utf8_str) )
475  }
476 
494  void escape_string( const string& str, ostream& os )
495  {
496  os << '"';
497  for( auto itr = str.begin(); itr != str.end(); ++itr )
498  {
499  switch( *itr )
500  {
501  case '\b': // \x08
502  os << "\\b";
503  break;
504  case '\f': // \x0c
505  os << "\\f";
506  break;
507  case '\n': // \x0a
508  os << "\\n";
509  break;
510  case '\r': // \x0d
511  os << "\\r";
512  break;
513  case '\t': // \x09
514  os << "\\t";
515  break;
516  case '\\':
517  os << "\\\\";
518  break;
519  case '\"':
520  os << "\\\"";
521  break;
522  case '\x00': os << "\\u0000"; break;
523  case '\x01': os << "\\u0001"; break;
524  case '\x02': os << "\\u0002"; break;
525  case '\x03': os << "\\u0003"; break;
526  case '\x04': os << "\\u0004"; break;
527  case '\x05': os << "\\u0005"; break;
528  case '\x06': os << "\\u0006"; break;
529  case '\x07': os << "\\u0007"; break; // \a is not valid JSON
530  // case '\x08': os << "\\u0008"; break; // \b
531  // case '\x09': os << "\\u0009"; break; // \t
532  // case '\x0a': os << "\\u000a"; break; // \n
533  case '\x0b': os << "\\u000b"; break;
534  // case '\x0c': os << "\\u000c"; break; // \f
535  // case '\x0d': os << "\\u000d"; break; // \r
536  case '\x0e': os << "\\u000e"; break;
537  case '\x0f': os << "\\u000f"; break;
538 
539  case '\x10': os << "\\u0010"; break;
540  case '\x11': os << "\\u0011"; break;
541  case '\x12': os << "\\u0012"; break;
542  case '\x13': os << "\\u0013"; break;
543  case '\x14': os << "\\u0014"; break;
544  case '\x15': os << "\\u0015"; break;
545  case '\x16': os << "\\u0016"; break;
546  case '\x17': os << "\\u0017"; break;
547  case '\x18': os << "\\u0018"; break;
548  case '\x19': os << "\\u0019"; break;
549  case '\x1a': os << "\\u001a"; break;
550  case '\x1b': os << "\\u001b"; break;
551  case '\x1c': os << "\\u001c"; break;
552  case '\x1d': os << "\\u001d"; break;
553  case '\x1e': os << "\\u001e"; break;
554  case '\x1f': os << "\\u001f"; break;
555 
556  default:
557  os << *itr;
558  }
559  }
560  os << '"';
561  }
562  ostream& json::to_stream( ostream& out, const std::string& str )
563  {
564  escape_string( str, out );
565  return out;
566  }
567 
568  template<typename T>
569  void to_stream( T& os, const variants& a, json::output_formatting format, uint32_t max_depth )
570  {
571  os << '[';
572  auto itr = a.begin();
573 
574  while( itr != a.end() )
575  {
576  to_stream( os, *itr, format, max_depth );
577  ++itr;
578  if( itr != a.end() )
579  os << ',';
580  }
581  os << ']';
582  }
583  template<typename T>
584  void to_stream( T& os, const variant_object& o, json::output_formatting format, uint32_t max_depth )
585  {
586  os << '{';
587  auto itr = o.begin();
588 
589  while( itr != o.end() )
590  {
591  escape_string( itr->key(), os );
592  os << ':';
593  to_stream( os, itr->value(), format, max_depth );
594  ++itr;
595  if( itr != o.end() )
596  os << ',';
597  }
598  os << '}';
599  }
600 
601  template<typename T>
602  void to_stream( T& os, const variant& v, json::output_formatting format, uint32_t max_depth )
603  {
604  FC_ASSERT( max_depth > 0, "Too many nested objects!" );
605  switch( v.get_type() )
606  {
607  case variant::null_type:
608  os << "null";
609  return;
610  case variant::int64_type:
612  ( v.as_int64() > INT32_MAX || v.as_int64() < INT32_MIN ) )
613  os << '"'<<v.as_string()<<'"';
614  else
615  os << v.as_int64();
616  return;
619  v.as_uint64() > 0xffffffff )
620  os << '"'<<v.as_string()<<'"';
621  else
622  os << v.as_uint64();
623  return;
626  os << '"'<<v.as_string()<<'"';
627  else
628  os << v.as_string();
629  return;
630  case variant::bool_type:
631  os << v.as_string();
632  return;
634  escape_string( v.get_string(), os );
635  return;
636  case variant::blob_type:
637  escape_string( v.as_string(), os );
638  return;
639  case variant::array_type:
640  to_stream( os, v.get_array(), format, max_depth - 1 );
641  return;
643  to_stream(os, v.get_object(), format, max_depth - 1 );
644  return;
645  default:
646  FC_THROW_EXCEPTION( fc::invalid_arg_exception, "Unsupported variant type: ${type}", ( "type", v.get_type() ) );
647  }
648  }
649 
650  std::string json::to_string( const variant& v, output_formatting format, uint32_t max_depth )
651  {
652  fc::stringstream ss;
653  fc::to_stream( ss, v, format, max_depth );
654  return ss.str();
655  }
656 
657 
658  std::string pretty_print( const std::string& v, uint8_t indent ) {
659  int level = 0;
660  fc::stringstream ss;
661  bool first = false;
662  bool quote = false;
663  bool escape = false;
664  for( uint32_t i = 0; i < v.size(); ++i ) {
665  switch( v[i] ) {
666  case '\\':
667  if( !escape ) {
668  if( quote )
669  escape = true;
670  } else { escape = false; }
671  ss<<v[i];
672  break;
673  case ':':
674  if( !quote ) {
675  ss<<": ";
676  } else {
677  ss<<':';
678  }
679  break;
680  case '"':
681  if( first ) {
682  ss<<'\n';
683  for( int i = 0; i < level*indent; ++i ) ss<<' ';
684  first = false;
685  }
686  if( !escape ) {
687  quote = !quote;
688  }
689  escape = false;
690  ss<<'"';
691  break;
692  case '{':
693  case '[':
694  ss<<v[i];
695  if( !quote ) {
696  ++level;
697  first = true;
698  }else {
699  escape = false;
700  }
701  break;
702  case '}':
703  case ']':
704  if( !quote ) {
705  if( v[i-1] != '[' && v[i-1] != '{' ) {
706  ss<<'\n';
707  }
708  --level;
709  if( !first ) {
710  for( int i = 0; i < level*indent; ++i ) ss<<' ';
711  }
712  first = false;
713  ss<<v[i];
714  break;
715  } else {
716  escape = false;
717  ss<<v[i];
718  }
719  break;
720  case ',':
721  if( !quote ) {
722  ss<<',';
723  first = true;
724  } else {
725  escape = false;
726  ss<<',';
727  }
728  break;
729  case 'n':
730  //If we're in quotes and see a \n, just print it literally but unset the escape flag.
731  if( quote && escape )
732  escape = false;
734  default:
735  if( first ) {
736  ss<<'\n';
737  for( int i = 0; i < level*indent; ++i ) ss<<' ';
738  first = false;
739  }
740  ss << v[i];
741  }
742  }
743  return ss.str();
744  }
745 
746 
747 
748  std::string json::to_pretty_string( const variant& v, output_formatting format, uint32_t max_depth )
749  {
750  return pretty_print(to_string(v, format, max_depth), 2);
751  }
752 
753  void json::save_to_file( const variant& v, const fc::path& fi, bool pretty, output_formatting format, uint32_t max_depth )
754  {
755  if( pretty )
756  {
757  auto str = json::to_pretty_string( v, format, max_depth );
758  fc::ofstream o(fi);
759  o.write( str.c_str(), str.size() );
760  }
761  else
762  {
763  fc::ofstream o(fi);
764  fc::to_stream( o, v, format, max_depth );
765  }
766  }
767  variant json::from_file( const fc::path& p, parse_type ptype, uint32_t max_depth )
768  {
769  fc::istream_ptr in( new fc::ifstream( p ) );
770  fc::buffered_istream bin( in );
771  return from_stream( bin, ptype, max_depth );
772  }
773  variant json::from_stream( buffered_istream& in, parse_type ptype, uint32_t max_depth )
774  {
775  switch( ptype )
776  {
777  case legacy_parser:
778  return variant_from_stream<fc::buffered_istream, legacy_parser>( in, max_depth );
779 #ifdef WITH_EXOTIC_JSON_PARSERS
780  case legacy_parser_with_string_doubles:
781  return variant_from_stream<fc::buffered_istream, legacy_parser_with_string_doubles>( in, max_depth );
782  case strict_parser:
783  return json_relaxed::variant_from_stream<buffered_istream, true>( in, max_depth );
784  case relaxed_parser:
785  return json_relaxed::variant_from_stream<buffered_istream, false>( in, max_depth );
786 #endif
787  case broken_nul_parser:
788  return variant_from_stream<fc::buffered_istream, broken_nul_parser>( in, max_depth );
789  default:
790  FC_ASSERT( false, "Unknown JSON parser type {ptype}", ("ptype", ptype) );
791  }
792  }
793 
794  ostream& json::to_stream( ostream& out, const variant& v, output_formatting format, uint32_t max_depth )
795  {
796  fc::to_stream( out, v, format, max_depth );
797  return out;
798  }
799  ostream& json::to_stream( ostream& out, const variants& v, output_formatting format, uint32_t max_depth )
800  {
801  fc::to_stream( out, v, format, max_depth );
802  return out;
803  }
804  ostream& json::to_stream( ostream& out, const variant_object& v, output_formatting format, uint32_t max_depth )
805  {
806  fc::to_stream( out, v, format, max_depth );
807  return out;
808  }
809 
810  bool json::is_valid( const std::string& utf8_str, parse_type ptype, uint32_t max_depth )
811  {
812  if( utf8_str.size() == 0 ) return false;
813  fc::istream_ptr in( new fc::stringstream( utf8_str ) );
814  fc::buffered_istream bin( in );
815  from_stream( bin, ptype, max_depth );
816  try { bin.peek(); } catch ( const eof_exception& e ) { return true; }
817  return false;
818  }
819 
820 } // fc
fc::json::legacy_parser
@ legacy_parser
Definition: json.hpp:22
fc::variant::get_type
type_id get_type() const
Definition: variant.cpp:304
fc::variant_object
An order-perserving dictionary of variant's.
Definition: variant_object.hpp:20
fc::parseEscape
char parseEscape(T &in)
Definition: json.cpp:47
fc::variant::array_type
@ array_type
Definition: variant.hpp:209
fc::variant::get_array
variants & get_array()
Definition: variant.cpp:496
fc::json::output_formatting
output_formatting
Definition: json.hpp:30
fc::mutable_variant_object
An order-perserving dictionary of variant's.
Definition: variant_object.hpp:108
fc::variant_from_stream
variant variant_from_stream(T &in, uint32_t max_depth)
Definition: json.cpp:413
fc::typelist::first
at< List, 0 > first
Get the type at the beginning of the list.
Definition: typelist.hpp:190
fc::to_int64
int64_t to_int64(const std::string &)
Definition: string.cpp:34
fc::json::broken_nul_parser
@ broken_nul_parser
Definition: json.hpp:28
fc::variant::as_uint64
uint64_t as_uint64() const
Definition: variant.cpp:398
fc::stringstream::peek
char peek()
Definition: sstream.cpp:79
fc
Definition: api.hpp:15
fc::variant::get_string
const std::string & get_string() const
Definition: variant.cpp:575
fc::json::from_string
static variant from_string(const string &utf8_str, parse_type ptype=legacy_parser, uint32_t max_depth=DEFAULT_MAX_RECURSION_DEPTH)
Definition: json.cpp:458
fc::json::to_pretty_string
static string to_pretty_string(const variant &v, output_formatting format=stringify_large_ints_and_doubles, uint32_t max_depth=DEFAULT_MAX_RECURSION_DEPTH)
Definition: json.cpp:748
fc::objectFromStreamBase
variant_object objectFromStreamBase(T &in, std::function< std::string(T &)> &get_key, std::function< variant(T &)> &get_value)
Definition: json.cpp:179
fc::variant::as_string
std::string as_string() const
Definition: variant.cpp:469
fc::stringFromToken
std::string stringFromToken(T &in)
Definition: json.cpp:134
fc::istream_ptr
std::shared_ptr< istream > istream_ptr
Definition: iostream.hpp:35
fc::variant::blob_type
@ blob_type
Definition: variant.hpp:211
fc::variant_object::begin
iterator begin() const
Definition: variant_object.cpp:53
fc::variant::object_type
@ object_type
Definition: variant.hpp:210
fc::variant::string_type
@ string_type
Definition: variant.hpp:208
fc::stringFromStream
std::string stringFromStream(T &in)
Definition: json.cpp:97
fc::stringstream::str
std::string str()
Definition: sstream.cpp:33
fc::skip_white_space
bool skip_white_space(T &in)
Definition: json.cpp:76
fc::buffered_istream::peek
virtual char peek() const
Definition: buffered_iostream.cpp:112
fc::json::to_string
static string to_string(const variant &v, output_formatting format=stringify_large_ints_and_doubles, uint32_t max_depth=DEFAULT_MAX_RECURSION_DEPTH)
Definition: json.cpp:650
fc::variant::double_type
@ double_type
Definition: variant.hpp:206
buffered_iostream.hpp
fc::to_stream
void to_stream(T &os, const variants &a, json::output_formatting format, uint32_t max_depth)
Definition: json.cpp:569
fc::json::stringify_large_ints_and_doubles
@ stringify_large_ints_and_doubles
Definition: json.hpp:32
fc::ifstream
Definition: fstream.hpp:27
fc::istream::get
virtual char get()
Definition: iostream.cpp:267
fc::variant::null_type
@ null_type
Definition: variant.hpp:203
fc::ostream::put
void put(char c)
Definition: iostream.hpp:50
fc::variant::bool_type
@ bool_type
Definition: variant.hpp:207
iostream.hpp
fc::number_from_stream
variant number_from_stream(T &in)
Definition: json.cpp:273
fc::path
wraps boost::filesystem::path to provide platform independent path manipulation.
Definition: filesystem.hpp:28
fc::to_double
double to_double(const std::string &)
Definition: string.cpp:60
fc::token_from_stream
variant token_from_stream(T &in)
Definition: json.cpp:341
fc::variants
std::vector< variant > variants
Definition: variant.hpp:170
sstream.hpp
fc::escape_string
void escape_string(const string &str, ostream &os)
Escape a string.
Definition: json.cpp:494
fc::arrayFromStreamBase
variants arrayFromStreamBase(T &in, std::function< variant(T &)> &get_value)
Definition: json.cpp:236
fc::arrayFromStream
variants arrayFromStream(T &in, uint32_t max_depth)
Definition: json.cpp:266
FALLTHROUGH
#define FALLTHROUGH
Definition: json.cpp:39
fc::ostream
Definition: iostream.hpp:41
fc::to_uint64
uint64_t to_uint64(const std::string &)
Definition: string.cpp:47
fc::json::save_to_file
static void save_to_file(const T &v, const fc::path &fi, bool pretty=true, output_formatting format=stringify_large_ints_and_doubles, uint32_t max_depth=DEFAULT_MAX_RECURSION_DEPTH)
Definition: json.hpp:51
fc::buffered_istream
Reads data from an unbuffered stream and enables peek functionality.
Definition: buffered_iostream.hpp:16
json_relaxed.hpp
fc::json::is_valid
static bool is_valid(const std::string &json_str, parse_type ptype=legacy_parser, uint32_t max_depth=DEFAULT_MAX_RECURSION_DEPTH)
Definition: json.cpp:810
json.hpp
fc::objectFromStream
variant_object objectFromStream(T &in, uint32_t max_depth)
Definition: json.cpp:228
FC_ASSERT
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
Definition: exception.hpp:345
fc::ofstream
Definition: fstream.hpp:9
fc::variant::as_int64
int64_t as_int64() const
Definition: variant.cpp:377
fc::variant::get_object
variant_object & get_object()
Definition: variant.cpp:554
fc::variant
stores null, int64, uint64, double, bool, string, std::vector<variant>, and variant_object's.
Definition: variant.hpp:198
exception.hpp
Defines exception's used by fc.
FC_RETHROW_EXCEPTIONS
#define FC_RETHROW_EXCEPTIONS(LOG_LEVEL, FORMAT,...)
Catchs all exception's, std::exceptions, and ... and rethrows them after appending the provided log m...
Definition: exception.hpp:464
logger.hpp
fstream.hpp
fc::variant::uint64_type
@ uint64_type
Definition: variant.hpp:205
fc::ostream::write
ostream & write(const char *buf, size_t len)
Definition: iostream.cpp:290
fc::pretty_print
std::string pretty_print(const std::string &v, uint8_t indent)
Definition: json.cpp:658
fc::json::from_file
static variant from_file(const fc::path &p, parse_type ptype=legacy_parser, uint32_t max_depth=DEFAULT_MAX_RECURSION_DEPTH)
Definition: json.cpp:767
FC_THROW_EXCEPTION
#define FC_THROW_EXCEPTION(EXCEPTION, FORMAT,...)
Definition: exception.hpp:379
fc::stringstream
Definition: sstream.hpp:7
fc::variant_object::end
iterator end() const
Definition: variant_object.cpp:59
fc::json::to_stream
static ostream & to_stream(ostream &out, const std::string &)
Definition: json.cpp:562
fc::json::variants_from_string
static variants variants_from_string(const string &utf8_str, parse_type ptype=legacy_parser, uint32_t max_depth=DEFAULT_MAX_RECURSION_DEPTH)
Definition: json.cpp:465
fc::json::parse_type
parse_type
Definition: json.hpp:20
fc::json::from_stream
static variant from_stream(buffered_istream &in, parse_type ptype=legacy_parser, uint32_t max_depth=DEFAULT_MAX_RECURSION_DEPTH)
Definition: json.cpp:773
fc::variant::int64_type
@ int64_type
Definition: variant.hpp:204