jsoncpp longlong 类型的扩展

          用cocos2dx做跨平台项目的时候,自然就用了c++版本的json库,这个json-cpp是用的比较多的,总体用起来还算可以,有一个很不方便的地方就是不支持long long(int64)类型,一开始我使用double类型来强制转换,后来出了bug,double精度只有16位,超过20位的就会被四舍五入,试过了官网上bug列表里的方法都不行,

没办法,花点时间添加longValue才解决这个问题,加地方实在太多了,附上主要扩展代码备忘:


一,定义一个long类型

//lancer add long

   typedef long long Long;


二、

//类型里添加longValue   

   enum ValueType

   {

      nullValue = 0, ///< 'null' value

      intValue,      ///< signed integer value

      uintValue,     ///< unsigned integer value

      //lancer add for longlong

      longValue,     //signed int 64

      realValue,     ///< double value

      stringValue,   ///< UTF-8 string value

      booleanValue,  ///< bool value

      arrayValue,    ///< array value (ordered list)

      objectValue    ///< object value (collection of name/value pairs).


   };


三、添加一个解析long类型的方法

bool 

Reader::decodeLongLong( Token &token )

{

    Long value = 0;

    const int bufferSize = 32;

    int count;

    int length = int(token.end_ - token.start_);

    if ( length <= bufferSize )

    {

        Char buffer[bufferSize];

        memcpy( buffer, token.start_, length );

        buffer[length] = 0;

        count = sscanf( buffer, "%lld", &value );

    }

    else

    {

        std::string buffer( token.start_, token.end_ );

        count = sscanf( buffer.c_str(), "%lld", &value );

    }

    

    if ( count != 1 )

        return addError( "'" + std::string( token.start_, token.end_ ) + "' is not a number.", token );

    currentValue() = value;

    return true;

}


四、解析数字

bool 

Reader::decodeNumber( Token &token )方法里,超出int型数据范围的时候使用decodeLongLong方法,而不是之前的decodeDouble

   while ( current < token.end_ )

   {

      Char c = *current++;

      if ( c < '0'  ||  c > '9' )

         return addError( "'" + std::string( token.start_, token.end_ ) + "' is not a number.", token );

      if ( value >= threshold )

//         return decodeDouble( token );

          //lancer add for long long

          return decodeLongLong( token );

      value = value * 10 + Value::UInt(c - '0');

   }


五,添加一个asLongLong方法供调用

//lancer as long

Long Value::asLongLong() const

{

    switch ( type_ )

    {

        case nullValue:

            return 0;

        case intValue:

            return value_.int_;

        case uintValue:

            JSON_ASSERT_MESSAGE( value_.uint_ < (unsigned)maxInt, "integer out of signed integer range" );

            return value_.uint_;

        case longValue:

            return value_.long_;

        case realValue:

            JSON_ASSERT_MESSAGE( value_.real_ >= minLong  &&  value_.real_ <= maxLong, "Real out of signed long range" );

            return Long( value_.real_ );

        case booleanValue:

            return value_.bool_ ? 1 : 0;

        case stringValue:

        {

            //lancer safe long long

            return atoll(value_.string_);

        }

        case arrayValue:

        case objectValue:

            JSON_ASSERT_MESSAGE( false, "Type is not convertible to int" );

        default:

            JSON_ASSERT_UNREACHABLE;

    }

    return 0; // unreachable;    

}


其他地方细节要改的太多了,我都是全局搜索realValue,然后对应的地方改掉


另外,由于后台传输数据的时候数字可能会被传成字符串,所以解析数字的地方都需要加上对字符串的判断,

比如:

Value::Int 

Value::asInt() const

{

   switch ( type_ )

   {

case stringValue:

    {

      //lancer safe int

      return atoi(value_.string_);

    }


转载请保留以下信息:

作者(Author):smilelance

出处( From ):http://blog.csdn.net/smilelance




原文地址:https://www.cnblogs.com/secbook/p/2655387.html