用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