Пример #1
0
   variant variant_from_stream( T& in, uint32_t depth )
   {
      depth++;
      FC_ASSERT( depth <= JSON_MAX_RECURSION_DEPTH );
      skip_white_space( in, depth );
      variant var;
      while( true )
      {
         signed char c = in.peek();
         switch( c )
         {
            case ' ':
            case '\t':
            case '\n':
            case '\r':
              in.get();
              continue;
            case '"':
              return stringFromStream( in, depth );
            case '{':
              return objectFromStream<T, parser_type>( in, depth );
            case '[':
              return arrayFromStream<T, parser_type>( in, depth );
            case '-':
            case '.':
            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
              return number_from_stream<T, parser_type>( in, depth );
            // null, true, false, or 'warning' / string
            case 'n':
            case 't':
            case 'f':
              return token_from_stream( in, depth );
            case 0x04: // ^D end of transmission
            case EOF:
            case 0:
              FC_THROW_EXCEPTION( eof_exception, "unexpected end of file" );
            default:
              FC_THROW_EXCEPTION( parse_error_exception, "Unexpected char '${c}' in \"${s}\"",
                                 ("c", c)("s", stringFromToken( in, depth )) );
         }
      }
	  return variant();
   }
Пример #2
0
 variant variant_from_stream( T& in, uint32_t max_depth )
 {
    if( max_depth == 0 )
        FC_THROW_EXCEPTION( parse_error_exception, "Too many nested items in JSON input!" );
    skip_white_space(in);
    signed char c = in.peek();
    switch( c )
    {
       case '"':
          return json_relaxed::stringFromStream<T, strict>( in );
       case '{':
          return json_relaxed::objectFromStream<T, strict>( in, max_depth - 1 );
       case '[':
          return json_relaxed::arrayFromStream<T, strict>( in, max_depth - 1 );
       case '-':
       case '+':
       case '.':
       case '0':
       case '1':
       case '2':
       case '3':
       case '4':
       case '5':
       case '6':
       case '7':
       case '8':
       case '9':
          return json_relaxed::numberFromStream<T, strict>( in );
       // null, true, false, or 'warning' / string
       case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h':
       case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p':
       case 'q': case 'r': case 's': case 't': case 'u': case 'v': case 'w': case 'x':
       case 'y': case 'z':
       case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H':
       case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P':
       case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
       case 'Y': case 'Z':
       case '_':                               case '/':
          return json_relaxed::wordFromStream<T, strict>( in );
       case 0x04: // ^D end of transmission
       case EOF:
          FC_THROW_EXCEPTION( eof_exception, "unexpected end of file" );
       case 0:
       default:
          FC_THROW_EXCEPTION( parse_error_exception, "Unexpected char '${c}' in \"${s}\"",
                              ("c", c)("s", stringFromToken(in)) );
    }
 }
Пример #3
0
  variant variant_from_stream( T& in, uint32_t max_depth )
  {
     if( max_depth == 0 )
         FC_THROW_EXCEPTION( parse_error_exception, "Too many nested items in JSON input!" );
     skip_white_space(in);
     signed char c = in.peek();
     switch( c )
     {
        case '"':
           return stringFromStream( in );
        case '{':
           return objectFromStream<T, parser_type>( in, max_depth - 1 );
        case '[':
           return arrayFromStream<T, parser_type>( in, max_depth - 1 );
        case '-':
        case '.':
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
           return number_from_stream<T, parser_type>( in );
        // null, true, false, or 'warning' / string
        case 'n':
        case 't':
        case 'f':
           return token_from_stream( in );
        case 0x04: // ^D end of transmission
        case EOF:
           FC_THROW_EXCEPTION( eof_exception, "unexpected end of file" );
        case 0:
           if( parser_type == fc::json::broken_nul_parser )
              return variant();
           FALLTHROUGH
        default:
           FC_THROW_EXCEPTION( parse_error_exception, "Unexpected char '${c}' in \"${s}\"",
                               ("c", c)("s", stringFromToken(in)) );
     }
 }
Пример #4
0
   variant token_from_stream( T& in )
   {
      std::stringstream ss;
      ss.exceptions( std::ifstream::badbit );
      bool received_eof = false;
      bool done = false;

      try
      {
        char c;
        while((c = in.peek()) && !done)
        {
           switch( c )
           {
              case 'n':
              case 'u':
              case 'l':
              case 't':
              case 'r':
              case 'e':
              case 'f':
              case 'a':
              case 's':
                 ss.put( in.get() );
                 break;
              default:
                 done = true;
                 break;
           }
        }
      }
      catch (fc::eof_exception&)
      {
        received_eof = true;
      }
      catch (const std::ios_base::failure&)
      {
        received_eof = true;
      }

      // we can get here either by processing a delimiter as in "null,"
      // an EOF like "null<EOF>", or an invalid token like "nullZ"
      std::string str = ss.str();
      if( str == "null" )
        return variant();
      if( str == "true" )
        return true;
      if( str == "false" ) 
        return false;
      else
      {
        if (received_eof)
        {
          if (str.empty())
            FC_THROW_EXCEPTION( parse_error_exception, "Unexpected EOF" );
          else
            return str;
        }
        else
        {
          // if we've reached this point, we've either seen a partial
          // token ("tru<EOF>") or something our simple parser couldn't
          // make out ("falfe")
          // A strict JSON parser would signal this as an error, but we
          // will just treat the malformed token as an un-quoted string.
          return str + stringFromToken(in);
        }
      }
   }
Пример #5
0
   variant number_from_stream( T& in )
   {
      fc::stringstream ss;

      bool  dot = false;
      bool  neg = false;
      if( in.peek() == '-')
      {
        neg = true;
        ss.put( in.get() );
      }
      bool done = false;

      try
      {
        char c;
        while((c = in.peek()) && !done)
        {

          switch( c )
          {
              case '.':
                 if (dot)
                    FC_THROW_EXCEPTION(parse_error_exception, "Can't parse a number with two decimal places");
                 dot = true;
                 FALLTHROUGH
              case '0':
              case '1':
              case '2':
              case '3':
              case '4':
              case '5':
              case '6':
              case '7':
              case '8':
              case '9':
                 ss.put( in.get() );
                 break;
              default:
                 if( isalnum( c ) )
                 {
                    return ss.str() + stringFromToken( in );
                 }
                done = true;
                break;
          }
        }
      }
      catch (fc::eof_exception&)
      { // EOF ends the loop
      }
      catch (const std::ios_base::failure&)
      { // read error ends the loop
      }
      std::string str = ss.str();
      if (str == "-." || str == "." || str == "-") // check the obviously wrong things we could have encountered
        FC_THROW_EXCEPTION(parse_error_exception, "Can't parse token \"${token}\" as a JSON numeric constant", ("token", str));
      if( dot )
        return
#ifdef WITH_EXOTIC_JSON_PARSERS
              parser_type == json::legacy_parser_with_string_doubles ? variant(str) :
#endif
                  variant(to_double(str));
      if( neg )
        return to_int64(str);
      return to_uint64(str);
   }