json-cpp 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/archive/2012/06/13/2655387.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    json-cpp longlong 类型的扩展

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/52643

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月9日 上午4:05
下一篇 2023年2月9日 上午4:05

相关推荐