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