`
java-mans
  • 浏览: 11427494 次
文章分类
社区版块
存档分类
最新评论

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




分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics