13 #include <boost/filesystem/fstream.hpp>
18 template<
typename T, json::parse_type parser_type> variant
variant_from_stream( T& in, uint32_t max_depth );
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 );
27 template<
typename T, json::parse_type parser_type> variant
number_from_stream( T& in );
33 std::string
pretty_print(
const std::string& v, uint8_t indent );
36 #if __cplusplus > 201402L
37 #define FALLTHROUGH [[fallthrough]];
49 if( in.peek() ==
'\\' )
106 "Expected '\"' but read '${char}'",
107 (
"char",
string(&c, (&c) + 1) ) );
112 switch( c = in.peek() )
118 FC_THROW_EXCEPTION( parse_error_exception,
"EOF before closing '\"' in string '${token}'",
119 (
"token", token.
str() ) );
128 FC_THROW_EXCEPTION( parse_error_exception,
"EOF before closing '\"' in string '${token}'",
129 (
"token", token.
str() ) );
131 (
"token", token.
str() ) );
143 switch( c = in.peek() )
155 if( isalnum( c ) || c ==
'_' || c ==
'-' || c ==
'.' || c ==
':' || c ==
'/' )
160 else return token.
str();
165 catch(
const fc::eof_exception& eof )
169 catch (
const std::ios_base::failure&)
175 (
"token", token.
str() ) );
187 "Expected '{', but read '${char}'",
188 (
"char",
string(&c, &c + 1)) );
190 while( in.peek() !=
'}' )
192 if( in.peek() ==
',' )
198 string key = get_key( in );
200 if( in.peek() !=
':' )
206 auto val = get_value( in );
208 obj(std::move(key),std::move(val));
210 if( in.peek() ==
'}' )
215 FC_THROW_EXCEPTION( parse_error_exception,
"Expected '}' after ${variant}", (
"variant", obj ) );
217 catch(
const fc::eof_exception& e )
219 FC_THROW_EXCEPTION( parse_error_exception,
"Unexpected EOF: ${e}", (
"e", e.to_detail_string() ) );
221 catch(
const std::ios_base::failure& e )
223 FC_THROW_EXCEPTION( parse_error_exception,
"Unexpected EOF: ${e}", (
"e", e.what() ) );
227 template<
typename T, json::parse_type parser_type>
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 );
241 if( in.peek() !=
'[' )
245 while( in.peek() !=
']' )
247 if( in.peek() ==
',' )
253 ar.push_back( get_value(in) );
255 if( in.peek() !=
']' )
265 template<
typename T, json::parse_type parser_type>
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 );
272 template<
typename T, json::parse_type parser_type>
279 if( in.peek() ==
'-')
289 while((c = in.peek()) && !done)
296 FC_THROW_EXCEPTION(parse_error_exception,
"Can't parse a number with two decimal places");
321 catch (fc::eof_exception&)
324 catch (
const std::ios_base::failure&)
327 std::string str = ss.
str();
328 if (str ==
"-." || str ==
"." || str ==
"-")
329 FC_THROW_EXCEPTION(parse_error_exception,
"Can't parse token \"${token}\" as a JSON numeric constant", (
"token", str));
332 #ifdef WITH_EXOTIC_JSON_PARSERS
333 parser_type == json::legacy_parser_with_string_doubles ?
variant(str) :
343 std::stringstream ss;
344 ss.exceptions( std::ifstream::badbit );
345 bool received_eof =
false;
351 while((c = in.peek()) && !done)
372 catch (fc::eof_exception&)
376 catch (
const std::ios_base::failure&)
383 std::string str = ss.str();
412 template<
typename T, json::parse_type parser_type>
418 signed char c = in.peek();
424 return objectFromStream<T, parser_type>( in, max_depth - 1 );
426 return arrayFromStream<T, parser_type>( in, max_depth - 1 );
439 return number_from_stream<T, parser_type>( in );
471 result.push_back(json_relaxed::variant_from_stream<fc::stringstream, false>( in, max_depth ));
472 }
catch (
const fc::eof_exception& ) {
497 for(
auto itr = str.begin(); itr != str.end(); ++itr )
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;
533 case '\x0b': os <<
"\\u000b";
break;
536 case '\x0e': os <<
"\\u000e";
break;
537 case '\x0f': os <<
"\\u000f";
break;
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;
572 auto itr = a.begin();
574 while( itr != a.end() )
576 to_stream( os, *itr, format, max_depth );
587 auto itr = o.
begin();
589 while( itr != o.
end() )
593 to_stream( os, itr->value(), format, max_depth );
604 FC_ASSERT( max_depth > 0,
"Too many nested objects!" );
664 for( uint32_t i = 0; i < v.size(); ++i ) {
670 }
else { escape =
false; }
683 for(
int i = 0; i < level*indent; ++i ) ss<<
' ';
705 if( v[i-1] !=
'[' && v[i-1] !=
'{' ) {
710 for(
int i = 0; i < level*indent; ++i ) ss<<
' ';
731 if( quote && escape )
737 for(
int i = 0; i < level*indent; ++i ) ss<<
' ';
759 o.
write( str.c_str(), str.size() );
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 );
783 return json_relaxed::variant_from_stream<buffered_istream, true>( in, max_depth );
785 return json_relaxed::variant_from_stream<buffered_istream, false>( in, max_depth );
788 return variant_from_stream<fc::buffered_istream, broken_nul_parser>( in, max_depth );
790 FC_ASSERT(
false,
"Unknown JSON parser type {ptype}", (
"ptype", ptype) );
812 if( utf8_str.size() == 0 )
return false;
816 try { bin.
peek(); }
catch (
const eof_exception& e ) {
return true; }