一、前言
LightJson 1.0版本的推出得众多网友的关注,在此表示感谢。同时,也有网友指出其不足。现在原有的基础上完成json标准化的支持。使用结构体静态绑定的好处是,扫描一眼结构体的定义你就能大概了解json的文档结构,而不需要阅读一大堆代码仍至要画图才能理清json的文档结构。至于有网友指出,结构体的定义改了,需要重新编译包括该头文件的代码。我觉得这问题不大,通常处理json的序列化和反序化的代码都在一个地方(一个cpp文件或一个模块),所以结构体的改变只需要重新编译该cpp即可,如果需要在几个模块中处理json的序列化和反序化,那么你不应该在一个模块中往docment对象中加几个字段,另一模块在往docment对象中加几个字段,这样做你的代码是零乱的,不好维护。当json的字段变了,都不知道去那个模块去修改相应docment对象。而通常的做法是定义一个结构体,各个业务模块填充结构体,然后在统一的地方把结构体序列化为json对象。
二、用法
1) 使用宏JSON_BEGIN,JSON_END,JSON_FIELD,JSON_FIELD_KEY定义结构体如下:
#include "LightJson.h" //包含LightJson唯一的头文件
//嵌套结构体
struct TestJsonSub
{
JSON_BEGIN()
JSON_FIELD(bool, m_Bool);
JSON_FIELD(int, m_int);
JSON_END();
};
//结构体
struct TestJsonC
{
JSON_BEGIN()
JSON_FIELD_KEY(long long, m_int64,"m_int\n64");
JSON_FIELD(double, m_float);
JSON_FIELD(std::string, m_str);
JSON_FIELD(std::vector<int>, m_vect);
JSON_FIELD(TestJsonSub, m_Sub);
JSON_FIELD(int, m_int1);
JSON_FIELD(int, m_int2);
JSON_FIELD(int, m_int3);
JSON_FIELD(int, m_int4);
JSON_FIELD(int, m_int5);
JSON_FIELD(std::vector<TestJsonSub>, m_vectSub);
JSON_END();
};
使用JSON_FIELD宏定义的字段,字段名即是json的key,不支持转义符。而用JSON_FIELD_KEY宏定义的字段,可以用第三个参数指定json的key。同样该方式指定的key,只支持UTF8字符串和UTF16字符串。如果还不能满足需求,可以调用结构体的成员函数设置key,例如:
TestJsonC objC;
objC.SetKey_m_float(LightJson::UTF8<>::FromString(L"aght有中文")); //设置m_float的key
2) 像普通结构体一样赋值:
TestJsonC objC;
objC.m_int64 = 223356644;
objC.m_float = 3.1415959;
objC.m_str = LightJson::UTF8<>::FromString(L"aght有中文哦Json有转义\n\r\t哦!");
for (int i = 0; i < 100; i++)
{
TestJsonSub sub;
sub.m_Bool = i;
sub.m_int = i;
objC.m_vectSub.push_back(sub);
objC.m_vect.push_back(i);
}
objC.m_Sub.m_Bool = true;
objC.m_Sub.m_int = -12562213;
objC.m_int1 = objC.m_int2 = objC.m_int3 = objC.m_int4 = objC.m_int5 = 2000;
3)序列化及反序列化:
std::string strJson = LightJson::JsonUtil::ToJsonString(objC1); //序列化
TestJsonC objC2;
//反序列化
if (LightJson::JsonUtil::FromJsonString(objC2,strJson.data(),strJson.length()) == false)
{
return false;
}
TestJsonC objC3; //模似使用,把反序化结果objC2的值取出来赋给objC3
if (objC2.Have_m_int64()) //可以用调用成员函数判断该字段是否有赋值
{
objC3.m_int64 = objC2.m_int64;
}
if (objC2.Have_m_float())
{
objC3.m_float = objC2.m_float ;
}
if (objC2.Have_m_str())
{
objC3.m_str = objC2.m_str.c_str();
}
if (objC2.Have_m_Sub())
{
TestJsonSub & sub = objC2.m_Sub;
if (sub.Have_m_Bool())
{
objC3.m_Sub.m_Bool = sub.m_Bool;
}
if (sub.Have_m_int())
{
objC3.m_Sub.m_int = sub.m_int;
}
}
三、LightJson源代码
#ifndef __LIGHTJSON_H__
#define __LIGHTJSON_H__
/***************************************************************************************************
转载请注明出处,作者联系方式:3181356737@qq.com
V 1.2
Date:2015-12-06
update:
1)对json标准的支持
2)反序化后,可调用函数判断该字段是否有设置,不再读取std::bits
/
V 1.1
Date:2015-12-02
update:浮点数指数部份可以是'e'以及'+'
*****************************************************************************************************/
#include <bitset>
#include<locale>
#include <codecvt>
#pragma warning(disable:4996)
#ifndef _FIELD_DEF_
#define _FIELD_DEF_
template <size_t size>
struct Int2Type
{
enum { Value = size };
};
#define INT2TYPE(size) Int2Type<size>()
#define ARRAY(type,size) std::array<type,size>
#define FIELD_INDEX_BEGIN() enum {INDEX_BEGIN=__COUNTER__,};
#define FIELD_INDEX_END() enum {INDEX_END=__COUNTER__,Size=INDEX_END-INDEX_BEGIN-1,};
#define AUTO_INDEX() (__COUNTER__-INDEX_BEGIN)
#define FIELD_BEGIN() FIELD_INDEX_BEGIN()
#define FIELD_END() FIELD_INDEX_END()
#define FIELD(type,name) FIELD_INDEX(AUTO_INDEX(),type,name)
#define FIELD_INDEX(index,type,name) DEF_VALUE(type,name) GET_VALUE(index,type,name) GET_NAME(index,name)
#define DEF_VALUE(type,name) type name;
#define GET_VALUE(index,type,name) type & getValue(Int2Type<index>){return name;} const type & getValue(Int2Type<index>) const {return name;}
#define GET_NAME(index,name) const char* getName(Int2Type<index>) const { return #name;}
template<typename T>
struct THaveLeghtField
{
template<typename type>
static char __is_field_struct(...);
template<typename type>
static int __is_field_struct(typename type::traits_type *);
template<typename type>
static int __is_field_struct(Int2Type<type::Size> *);
enum { Value = (sizeof(__is_field_struct<T>(0)) == sizeof(int)) };
};
#endif
#define DEFINE_HAVE_FUNCTION(func_name) \
template<typename T, typename... Args>struct THave##func_name { private: \
template<typename U> static auto Check(int) -> decltype(std::declval<U>().##func_name##(std::declval<Args>()...), std::true_type()); \
template<typename U> static auto Check(...) -> decltype(std::false_type()); \
public: enum { Value = std::is_same<decltype(Check<T>(0)), std::true_type>::value }; };
DEFINE_HAVE_FUNCTION(JsonParseCallBackFunction)
DEFINE_HAVE_FUNCTION(JsonFieldCallBackFunction)
DEFINE_HAVE_FUNCTION(JsonFieldGetKeyFunction)
DEFINE_HAVE_FUNCTION(JsonGetFieldBitsFunction)
namespace LightJson
{
class JsonUtil
{
public:
template<typename type, typename Encoding = UTF8<>>
static bool FromJsonString(type & value, const char* szJsonStr, int len = 0)
{
if (len == 0)
{
len = strlen(szJsonStr);
}
IJsonBuffer<Encoding> ib(szJsonStr, len);
if (ib.Read(value) == false)
{
return false;
}
return true;
}
template<typename type, typename Encoding = UTF8<>>
static bool FromJsonString(type & value, const std::string & strJson)
{
IJsonBuffer<Encoding> ib(strJson.c_str(), strJson.length());
if (ib.Read(value) == false)
{
return false;
}
return true;
}
template<typename type, typename Encoding = UTF8<>>
static std::string ToJsonString(type & value)
{
OJsonBuffer<1024, Encoding> ob;
if (ob.Write(value) == false)
{
return "";
}
return std::move(ob.ToString());
}
};
#define Z8 0,0,0,0,0,0,0,0
static const bool IsSeparator[256] = {
Z8,Z8,
Z8,Z8,
Z8,0,0,0,0,',',0,0,0,
Z8,Z8,Z8,Z8,
Z8, 0,0,0,0,0,']',0,0,Z8,Z8,
Z8,0,0,0,0,0,'}',0,0,Z8,Z8,
Z8,Z8,Z8,Z8,
Z8,Z8,Z8,Z8,
Z8,Z8,Z8,Z8,
Z8,Z8
};
static const bool IsSpace[256] =
{
Z8,0,'\t','\n',0, 0, '\r',0,0,
Z8,Z8,
' ',0,0,0,0,0,0,0,Z8,
Z8,Z8,Z8,Z8,
Z8,Z8,Z8,Z8,
Z8,Z8,Z8,Z8,
Z8,Z8,Z8,Z8,
Z8,Z8,Z8,Z8,
Z8,Z8,Z8,Z8,
Z8,Z8
};
static const bool IsFloat[256] =
{
Z8,Z8,Z8,Z8,
Z8,0,0,0,'+',0,'-','.',0,'0','1','2','3','4','5','6','7', '8','9',0,0,0,0,0,0,
0,0,0,0,0,'E',0,0,Z8,Z8,Z8,
0,0,0,0,0,'e',0,0,Z8,Z8,Z8,
Z8,Z8,Z8,Z8,
Z8,Z8,Z8,Z8,
Z8,Z8,Z8,Z8,
Z8,Z8,Z8,Z8
};
#undef Z8
static const char hexDigits[] = "0123456789ABCDEF";
static const char IsEscape[256] = {
#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
//0 1 2 3 4 5 6 7 8 9 A B C D E F
'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'b', 't', 'n', 'u', 'f', 'r', 'u', 'u', // 00
'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', // 10
0, 0, '"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20
Z16, Z16, // 30~4F
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0, // 50
Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16 // 60~FF
#undef Z16
};
///
// UTF8
//! UTF-8 encoding.
/*! http://en.wikipedia.org/wiki/UTF-8
\tparam CharType Type for storing 8-bit UTF-8 data. Default is char.
\implements Encoding
*/
template<typename CharType = char>
struct UTF8 {
typedef CharType Ch;
static std::string FromString(const char * src)
{
return src;
}
static std::string FromString(const wchar_t* src)
{
std::wstring_convert<std::codecvt_utf8<wchar_t>> convUtf8;
std::string str = convUtf8.to_bytes(src);
return std::move(str);
}
static Ch* Encode(Ch *buffer, unsigned codepoint) {
if (codepoint <= 0x7F)
*buffer++ = codepoint & 0xFF;
else if (codepoint <= 0x7FF) {
*buffer++ = 0xC0 | ((codepoint >> 6) & 0xFF);
*buffer++ = 0x80 | ((codepoint & 0x3F));
}
else if (codepoint <= 0xFFFF) {
*buffer++ = 0xE0 | ((codepoint >> 12) & 0xFF);
*buffer++ = 0x80 | ((codepoint >> 6) & 0x3F);
*buffer++ = 0x80 | (codepoint & 0x3F);
}
else {
*buffer++ = 0xF0 | ((codepoint >> 18) & 0xFF);
*buffer++ = 0x80 | ((codepoint >> 12) & 0x3F);
*buffer++ = 0x80 | ((codepoint >> 6) & 0x3F);
*buffer++ = 0x80 | (codepoint & 0x3F);
}
return buffer;
}
};
///
// UTF16
//! UTF-16 encoding.
/*! http://en.wikipedia.org/wiki/UTF-16
\tparam CharType Type for storing 16-bit UTF-16 data. Default is wchar_t. C++11 may use char16_t instead.
\implements Encoding
*/
template<typename CharType = wchar_t>
struct UTF16 {
typedef CharType Ch;
static std::string FromString(const char* src)
{
std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;
std::wstring wstr = conv.from_bytes(src);
std::string str;
int len = wstr.length() * sizeof(wchar_t);
str.resize(len);
memcpy((void*)str.data(),wstr.data(),len);
return std::move(str);
}
static std::string FromString(const wchar_t* src)
{
const wchar_t* ptr = src;
int len = 0;
while (ptr[len])
{
len++;
}
std::string str;
str.resize(len*sizeof(wchar_t));
memcpy((void*)str.data(), ptr, len*sizeof(wchar_t));
return std::move(str);
}
static Ch* Encode(Ch* buffer, unsigned codepoint) {
if (codepoint <= 0xFFFF) {
*buffer++ = static_cast<Ch>(codepoint);
}
else {
unsigned v = codepoint - 0x10000;
*buffer++ = static_cast<Ch>((v >> 10) + 0xD800);
*buffer++ = (v & 0x3FF) + 0xDC00;
}
return buffer;
}
};
///
// UTF32
//! UTF-32 encoding.
/*! http://en.wikipedia.org/wiki/UTF-32
\tparam Ch Type for storing 32-bit UTF-32 data. Default is unsigned. C++11 may use char32_t instead.
\implements Encoding
*/
template<typename CharType = unsigned>
struct UTF32 {
typedef CharType Ch;
static std::string FromString(const char * src)
{
std::string str;
int len = strlen(src) * sizeof(char32_t);
str.resize(len);
char32_t * ptr = (char32_t *)str.data();
while (*src)
{
*ptr++ = *src++;
}
return std::move(str);
}
static std::string FromString(const char32_t* src)
{
const char32_t* ptr = src;
int len = 0;
while (ptr[len])
{
len++;
}
std::string str;
str.resize(len*sizeof(char32_t));
memcpy((void*)str.data(), ptr, len*sizeof(char32_t));
return std::move(str);
}
static Ch *Encode(Ch* buffer, unsigned codepoint) {
*buffer++ = codepoint;
return buffer;
}
};
template<size_t static_size,typename Encoding=UTF8<>>
class OJsonBuffer
{
typedef typename Encoding::Ch Ch;
public:
OJsonBuffer()
{
__Init();
}
explicit OJsonBuffer(char * pData, size_t len)
{
__Init();
this->m_ptrBegin = this->m_ptrCur = (Ch*)pData;
this->m_Size = len/sizeof(Ch);
}
//预分配容量
explicit OJsonBuffer(size_t len)
{
__Init();
if (len == 0)
{
len = 1024;
}
ResetCapacity(len);
}
//扩展内存
bool ResetCapacity(size_t len)
{
int old_size = this->Size();
if (old_size >= len)
{
return true;
}
if ((Ch*)m_strData.data() == m_ptrBegin)
{
m_strData.resize(len*sizeof(Ch));
}
else
{
m_strData.resize(len*sizeof(Ch));
if (old_size > 0)
{
memcpy((char*)m_strData.data(), m_ptrBegin, old_size*sizeof(Ch));
}
}
this->m_Size = len ;
this->m_ptrBegin = (Ch*)m_strData.data();
this->m_ptrCur = m_ptrBegin + old_size;
return true;
}
~OJsonBuffer()
{
__Init();
}
//复位
void Reset()
{
m_bError = false;
m_Size = 0;
m_ptrCur = m_ptrBegin = NULL;
}
size_t GetStaticSize()
{
return static_size;
}
//返回从pos开始的内存
const Ch * Buffer(size_t pos = 0) const
{
if (pos >= m_Size)
{
return nullptr;
}
return m_ptrBegin + pos;
}
Ch * CurrentBuffer()
{
return m_ptrCur;
}
//获得数据大小
size_t Size() const
{
return m_ptrCur - m_ptrBegin;
}
//当前容量
size_t Capacity() const
{
return m_Size;
}
//余下空间
size_t Remain() const
{
return m_Size - (m_ptrCur - m_ptrBegin);
}
bool IsStaticBuffer()
{
return m_ptrCur == this->m_static_data;
}
//注意:内存所有权会转移
std::vector<char> TakeData()
{
std::vector<char> vect;
int len = (m_ptrCur - m_ptrBegin)*sizeof(Ch);
vect.resize(len);
memcpy(vect.data(), m_ptrBegin, len);
return std::move(vect);
}
std::string ToString()
{
Ch * ptr = m_ptrCur;
//*ptr = 0;
if (m_ptrBegin == m_strData.data())
{
m_strData.resize((ptr - m_ptrBegin)*sizeof(Ch));
return std::move(m_strData);
}
else
{
std::string str;
str.resize((ptr - m_ptrBegin)*sizeof(Ch));
memcpy((void*)str.data(), m_ptrBegin, (ptr - m_ptrBegin)*sizeof(Ch));
return std::move(str);
}
}
//是否产生了错误
bool Error() const
{
return m_bError;
}
template< typename type> int Write(type & obj)
{
int byte_size = ByteSize(obj);
if (byte_size+1 <= static_size/sizeof(Ch))
{
this->m_ptrBegin = this->m_ptrCur = (Ch*)this->m_static_data;
this->m_Size = static_size/sizeof(Ch);
}
else
{
this->ResetCapacity(byte_size+1);
}
Write(obj, Int2Type<type::Size>());
return byte_size;
}
template< typename type> bool Write(type & obj, Int2Type<0> ind)
{
*this->m_ptrCur++ = '{';
return true;
}
template<int size, typename type> bool Write(type & obj, Int2Type<size> ind)
{
if (Write(obj, Int2Type<size - 1>()) == false)
{
return false;
}
std::string & strKey = obj.JsonFieldGetKeyFunction(ind, Encoding());
Write(obj.getValue(ind), (const Ch*)strKey.data(), size==1);
if (size == type::Size)
{
*this->m_ptrCur++ = '}';
}
return this->Error() == false;
}
/
template<typename ValueType>
void Write(ValueType & obj,const Ch * szKey,bool bFirst)
{
WriteKey(szKey, bFirst);
Write(obj, Int2Type<ValueType::Size>());
}
void Write(char obj, const Ch * szKey, bool bFirst)
{
WriteKey(szKey, bFirst);
WriteInt32((int)obj);
}
void Write(unsigned char obj, const Ch * szKey, bool bFirst)
{
WriteKey(szKey, bFirst);
WriteInt32((unsigned int)obj);
}
void Write(short obj, const Ch * szKey, bool bFirst)
{
WriteKey(szKey, bFirst);
WriteInt32((int)obj);
}
void Write(unsigned short obj, const Ch * szKey, bool bFirst)
{
WriteKey(szKey, bFirst);
WriteInt32((unsigned int)obj);
}
void Write(int obj, const Ch * szKey, bool bFirst)
{
WriteKey(szKey, bFirst);
WriteInt32(obj);
}
void Write(unsigned int obj, const Ch * szKey, bool bFirst)
{
WriteKey(szKey, bFirst);
WriteInt32(obj);
}
void Write(long obj, const Ch * szKey, bool bFirst)
{
WriteKey(szKey, bFirst);
WriteInt32((int)obj);
}
void Write(unsigned long obj, const Ch * szKey, bool bFirst)
{
WriteKey(szKey, bFirst);
WriteInt32((unsigned int)obj);
}
void Write(long long obj, const Ch * szKey, bool bFirst)
{
WriteKey(szKey, bFirst);
WriteInt64(obj);
}
void Write(unsigned long long obj, const Ch * szKey, bool bFirst)
{
WriteKey(szKey, bFirst);
WriteInt64((long long)obj);
}
void Write(bool obj, const Ch * szKey, bool bFirst)
{
WriteKey(szKey, bFirst);
WriteBool(obj);
}
void Write(float obj, const Ch * szKey, bool bFirst)
{
WriteKey(szKey, bFirst);
WriteFloat(obj);
}
void Write(double obj, const Ch * szKey, bool bFirst)
{
WriteKey(szKey, bFirst);
WriteDouble(obj);
}
void Write(const Ch* obj, const Ch * szKey, bool bFirst)
{
WriteKey(szKey, bFirst);
WriteStr(obj);
}
void Write( Ch* obj, const Ch * szKey, bool bFirst)
{
WriteKey(szKey, bFirst);
WriteStr(obj);
}
void Write(const std::string & obj, const Ch * szKey, bool bFirst)
{
WriteKey(szKey, bFirst);
WriteStr((const Ch*)obj.data());
}
void Write( std::string & obj, const Ch * szKey, bool bFirst)
{
WriteKey(szKey, bFirst);
WriteStr((const Ch*)obj.data());
}
template<typename type>
void Write(std::vector<type> & obj, const Ch * szKey, bool bFirst)
{
int obj_len = obj.size();
WriteKey(szKey, bFirst);
*this->m_ptrCur++ = '[';
for (int i = 0; i < obj_len;i++)
{
Write(obj[i], NULL,i==0);
}
*this->m_ptrCur++ = ']';
}
template<typename type>
void Write(const std::vector<type> & obj, const Ch* szKey, bool bFirst)
{
int obj_len = obj.size();
WriteKey(szKey, bFirst);
*this->m_ptrCur++ = '[';
for (int i = 0; i < obj_len;i++)
{
Write(obj[i], NULL, i == 0);
}
*this->m_ptrCur++ = ']';
}
private:
//push二进制内存
void Push(const void* pData, int len)
{
memcpy(this->m_ptrCur, pData, len);
this->m_ptrCur += len / sizeof(Ch);
}
//写整数
void WriteInt32(int value)
{
unsigned int v;
if (value < 0)
{
*m_ptrCur++ = '-';
v = 0 - value;
}
else
{
v = value;
}
int len = ByteSize(v);
m_ptrCur = m_ptrCur + len;
Ch * ptr = m_ptrCur;
do
{
*(--ptr) = '0' + v % 10;
v /= 10;
} while (v>0);
}
void WriteInt32(unsigned int value)
{
int len = ByteSize(value);
m_ptrCur = m_ptrCur + len;
Ch * ptr = m_ptrCur;
do
{
*(--ptr) = '0' + value % 10;
value /= 10;
} while (value>0);
}
//写整数
void WriteInt64(long long value)
{
unsigned long long v;
if (value < 0)
{
*m_ptrCur++ = '-';
v = 0 - value;
}
else
{
v = value;
}
int len = ByteSize(v);
m_ptrCur = m_ptrCur + len;
Ch * ptr = m_ptrCur;
do
{
*(--ptr) = '0' + v % 10;
v /= 10;
} while (v>0);
}
//写bool
void WriteBool(bool value)
{
if (value)
{
m_ptrCur[0] = 't';
m_ptrCur[1] = 'r';
m_ptrCur[2] = 'u';
m_ptrCur[3] = 'e';
m_ptrCur += 4;
}
else
{
m_ptrCur[0] = 'f';
m_ptrCur[1] = 'a';
m_ptrCur[2] = 'l';
m_ptrCur[3] = 's';
m_ptrCur[4] = 'e';
m_ptrCur += 5;
}
}
//写float
void WriteFloat(float value)
{
WriteDouble(value);
}
//写double
void WriteDouble(double value)
{
char buffer[100];
#if _MSC_VER
int ret = sprintf_s(buffer, sizeof(buffer), "%g", value);
#else
int ret = snprintf(buffer, sizeof(buffer), "%g", value);
#endif
for (int i = 0;i<ret;i++)
{
m_ptrCur[i] = buffer[i];
}
m_ptrCur += ret;
}
//写str
void WriteStr(const Ch* value)
{
*this->m_ptrCur++ = '\"';
for (const Ch* p = value; *p != '\0'; ++p) {
if ((sizeof(Ch) == 1 || *p < 256) && IsEscape[(unsigned char)*p]) {
*this->m_ptrCur++ = '\\';
*this->m_ptrCur++ = (IsEscape[(unsigned char)*p]);
if (IsEscape[(unsigned char)*p] == 'u') {
*this->m_ptrCur++ = ('0');
*this->m_ptrCur++ = ('0');
*this->m_ptrCur++ = (hexDigits[(*p) >> 4]);
*this->m_ptrCur++ = (hexDigits[(*p) & 0xF]);
}
}
else
*this->m_ptrCur++ = (*p);
}
*this->m_ptrCur++ = '\"';
}
int ByteSize(const Ch * szData)
{
int len = 2;
for (const Ch* p = szData; *p != '\0'; ++p) {
if ((sizeof(Ch) == 1 || *p < 256) && IsEscape[(unsigned char)*p]) {
if (IsEscape[(unsigned char)*p] == 'u') {
len += 6;
}
else
{
len += 2;
}
}
else
len++;
}
return len;
}
int ByteSize(const std::string & str)
{
if (str.empty())
{
return 2;
}
return ByteSize((const Ch*)str.data());
}
int ByteSize(std::string & str)
{
if (str.empty())
{
return 2;
}
return ByteSize((const Ch*)str.data());
}
int ByteSize(bool v)
{
if (v)
{
return 4;
}
else
{
return 5;
}
}
int ByteSize(float v)
{
return ByteSize((double)v);
}
int ByteSize(double v)
{
char buffer[100];
#if _MSC_VER
int ret = sprintf_s(buffer, sizeof(buffer), "%g", v);
#else
int ret = snprintf(buffer, sizeof(buffer), "%g", v);
#endif
return ret;
}
int ByteSize(int v)
{
if (v < 0)
{
unsigned int value = 0 - v;
return ByteSize(value) + 1;
}
else
{
return ByteSize((unsigned int)v);
}
}
int ByteSize(unsigned int value)
{
if (value < 100000) //5位
{
if (value < 100) //2位
{
if (value < 10)
{
return 1;
}
else
{
return 2;
}
}
else if (value < 1000)
{
return 3;
}
else if (value < 10000)
{
return 4;
}
else
{
return 5;
}
}
else
{
if (value < 10000000) //7位
{
if (value < 1000000)
{
return 6;
}
else
{
return 7;
}
}
else if (value < 100000000)
{
return 8;
}
else if (value < 1000000000)
{
return 9;
}
else
{
return 10;
}
}
}
int ByteSize(long long v)
{
if (v < 0)
{
unsigned long long value = 0 - v;
return ByteSize(value) + 1;
}
else
{
return ByteSize((unsigned long long)v);
}
}
int ByteSize(unsigned long long value)
{
if (value < 10000000000) //10位
{
if (value < 100000) //5位
{
if (value < 100) //2位
{
if (value < 10)
{
return 1;
}
else
{
return 2;
}
}
else if (value < 1000)
{
return 3;
}
else if (value < 10000)
{
return 4;
}
else
{
return 5;
}
}
else
{
if (value < 10000000) //7位
{
if (value < 1000000)
{
return 6;
}
else
{
return 7;
}
}
else if (value < 100000000)
{
return 8;
}
else if (value < 1000000000)
{
return 9;
}
else
{
return 10;
}
}
}
else
{
if (value < 1000000000000000) //15位
{
if (value < 1000000000000) //12位
{
if (value < 100000000000)
{
return 11;
}
else
{
return 12;
}
}
else if (value < 10000000000000)
{
return 13;
}
else if (value < 100000000000000)
{
return 14;
}
else
{
return 15;
}
}
else
{
if (value < 100000000000000000) //17位
{
if (value < 10000000000000000)
{
return 16;
}
else
{
return 17;
}
}
else if (value < 1000000000000000000)
{
return 18;
}
else if (value < 10000000000000000000)
{
return 19;
}
else
{
return 20;
}
}
}
}
template< typename type> int ByteSize(type & obj)
{
return ByteSize(obj, Int2Type<type::Size>());
}
template< typename type> int ByteSize(std::vector<type> & obj)
{
int size = obj.size();
int len = size + 2;
if (size > 0)
{
len--;
}
for (int i = 0; i < size;i++)
{
len += ByteSize(obj[i]);
}
return len;
}
template< typename type> int ByteSize(const std::vector<type> & obj)
{
int size = obj.size();
int len = size + 2;
if (size > 0)
{
len--;
}
for (int i = 0; i < size;i++)
{
len += ByteSize(obj[i]);
}
return len;
}
template< typename type> int ByteSize(type & obj, Int2Type<0> ind)
{
return 1;
}
template<int size, typename type> int ByteSize(type & obj, Int2Type<size> ind)
{
int len = ByteSize(obj, Int2Type<size - 1>());
if (size >1)
{
len++; //,号
}
len += ByteSize(obj.JsonFieldGetKeyFunction(ind, Encoding())) + 1; //加分号
len += ByteSize(obj.getValue(ind));
if (size == type::Size)
{
len++;
}
return len;
}
void WriteKey(const Ch* szKey, bool bFirst)
{
if (bFirst == false)
{
*this->m_ptrCur++ = ',';
}
if (szKey)
{
WriteStr(szKey);
*this->m_ptrCur++ = ':';
}
}
private:
OJsonBuffer(const OJsonBuffer& Other) = delete;
OJsonBuffer & operator =(const OJsonBuffer&) = delete;
private:
//初始化
void __Init()
{
m_Size = 0;
m_ptrCur = m_ptrBegin = NULL;
m_bError = false;
}
private:
char m_static_data[static_size];
std::string m_strData;
int m_Size;
Ch* m_ptrCur;
Ch* m_ptrBegin;
bool m_bError; //是否产生了错误
};
template<typename CharType>
class TReader
{
const CharType * m_pBegin; //有效数据
const CharType * m_pData; //有效数据
const CharType * m_pEnd; //有效数据
public:
TReader()
{
m_pBegin = m_pData = m_pEnd = NULL;
}
TReader(const CharType * pData,int len=0)
{
m_pBegin = m_pData = pData;
if (len > 0)
{
m_pEnd = m_pBegin + len;
}
else
{
m_pEnd = m_pBegin + INT_MAX;
}
}
void Init(const CharType * pData, int len = 0)
{
m_pBegin = m_pData = pData;
if (len > 0)
{
m_pEnd = m_pBegin + len;
}
else
{
m_pEnd = m_pBegin + INT_MAX;
}
}
CharType Peek() {
return *m_pData;
}
CharType Take() {
if(m_pData<m_pEnd)
return *m_pData++;
return CharType(0);
}
const CharType * Current()
{
return m_pData;
}
private:
};
//输入Buffer
template<typename Encoding>
class IJsonBuffer
{
typedef typename Encoding::Ch Ch;
public:
IJsonBuffer(const char* pData, int len) : m_Reader((const Ch *)pData,len/sizeof(Ch))
{
m_bError = false;
}
IJsonBuffer(const std::vector<char> & vectData) : m_Reader((const Ch *)vectData.data(), vectData.size())
{
m_bError = false;
}
~IJsonBuffer()
{
m_bError = false;
}
//是否产生了错误
bool Error() { return m_bError; }
//读取
template<typename type>
bool Read(type & value, const Ch * pKey=NULL, int len=0)
{
Ch ch = SkipSpace();
if (ch != '{')
{
if (ch == 'n')
{
if (ReadNullValue()==false)
{
return false;
}
value = type();
return true;
}
return false;
}
ch = SkipSpace();
if (ch == '}')
{
return true;
}
do
{
if (ch != '\"')
{
return false;
}
const Ch * pKey = NULL;
int key_len = 0;
std::string strKey;
bool bEscape = false;
if (this->ReadString(pKey, key_len, bEscape, strKey) == NULL)
{
return false;
}
if (bEscape)
{
pKey = (const Ch*)strKey.data();
}
ch = this->SkipSpace();
if (ch != ':')
{
return false;
}
if (CallJsonCallBack(value, pKey, key_len,Int2Type<THaveJsonParseCallBackFunction<type, IJsonBuffer &, const char*, int>::Value>()) == false)
{
m_bError = true;
return false;
}
ch = SkipSpace();
if (ch == '}')
{
break;
}
else if (ch != ',')
{
m_bError = true;
return false;
}
ch = SkipSpace();
} while (true);
return this->m_bError == false;
}
bool Read(bool & value, const Ch * pKey=NULL, int len = 0)
{
value = false;
Ch ch = SkipSpace();
if (ch == 't')
{
if (ReadTrueValue()==false)
{
return false;
}
value = true;
}
else if (ch == 'f')
{
if (ReadFalseValue()==false)
{
return false;
}
value = false;
}
else if (ch == 'n')
{
if (ReadNullValue()==false)
{
return false;
}
value = false;
}
return true;
}
bool Read(char & value, const Ch* pKey = NULL, int len = 0)
{
long long ll = 0;
if (ReadNumber(ll) == false) { return false; }
value = ll;
return true;
}
bool Read(unsigned char & value, const Ch* pKey = NULL, int len = 0)
{
long long ll = 0;
if (ReadNumber(ll) == false) { return false; }
value = ll;
return true;
}
bool Read(short & value, const Ch* pKey = NULL, int len = 0)
{
long long ll = 0;
if (ReadNumber(ll) == false) { return false; }
value = ll;
return true;
}
bool Read(unsigned short & value, const Ch* pKey = NULL, int len = 0)
{
long long ll = 0;
if (ReadNumber(ll) == false) { return false; }
value = ll;
return true;
}
bool Read(int & value, const Ch* pKey = NULL, int len = 0)
{
long long ll = 0;
if (ReadNumber(ll) == false){return false;}
value = ll;
return true;
}
bool Read(unsigned int & value, const Ch* pKey = NULL, int len = 0)
{
long long ll = 0;
if (ReadNumber(ll) == false) { return false; }
value = ll;
return true;
}
bool Read(long & value, const Ch* pKey = NULL, int len = 0)
{
long long ll = 0;
if (ReadNumber(ll) == false) { return false; }
value = ll;
return true;
}
bool Read(unsigned long & value, const Ch* pKey = NULL, int len = 0)
{
long long ll = 0;
if (ReadNumber(ll) == false) { return false; }
value = ll;
return true;
}
bool Read( long long & value, const Ch* pKey = NULL, int len = 0)
{
long long ll = 0;
if (ReadNumber(ll) == false) { return false; }
value = ll;
return true;
}
bool Read(unsigned long long & value, const Ch* pKey = NULL, int len = 0)
{
long long ll = 0;
if (ReadNumber(ll) == false) { return false; }
value = ll;
return true;
}
bool Read(float & value, const Ch* pKey = NULL, int len = 0)
{
char buff[100];
int i = 0;
Ch ch = this->SkipSpace();
if ((ch >= '0'&&ch <= '9')
|| ch == '-')
{
buff[i++] = ch;
}
else if (ch == 'n')
{
if (ReadNullValue()==false)
{
return false;
}
value = 0;
return true;
}
else
{
return false;
}
unsigned char uch;
while (((uch = (unsigned char)this->m_Reader.Peek())!=0)&& i<sizeof(buff))
{
if (IsFloat[uch])
{
buff[i++] = uch;
}
else if(IsSeparator[uch])
{
break;
}
this->m_Reader.Take();
}
buff[i++] = 0;
value = std::atof(buff);
return true;
}
bool Read(double & value, const Ch* pKey = NULL, int len = 0)
{
char buff[100];
int i = 0;
Ch ch = this->SkipSpace();
if ((ch >= '0'&&ch <= '9')
|| ch == '-')
{
buff[i++] = ch;
}
else if (ch == 'n')
{
if (ReadNullValue()==false )
{
return false;
}
value = 0;
return true;
}
else
{
return false;
}
unsigned char uch;
while (((uch= this->m_Reader.Peek())!=0) && i<sizeof(buff))
{
if (IsFloat[uch])
{
buff[i++] = uch;
}
else if (IsSeparator[uch])
{
break;
}
this->m_Reader.Take();
}
buff[i++] = 0;
value = std::atof(buff);
return true;
}
bool Read(std::string & value, const Ch* pKey = NULL, int len = 0)
{
Ch ch = this->SkipSpace();
if (ch != '\"')
{
if (ch == 'n')
{
if (ReadNullValue()==false)
{
return false;
}
value = "";
return true;
}
return false;
}
int lenStr = 0;
bool bEscape = false;
const Ch* ptr = NULL;
if (ReadString(ptr, lenStr, bEscape,value) == false)
{
return false;
}
if (bEscape==false)
{
value.resize(lenStr*sizeof(Ch));
memcpy((void*)value.data(),ptr, lenStr*sizeof(Ch));
}
return true;
}
template<typename type>
bool Read(std::vector<type> & value, const Ch* pKey = NULL, int len = 0)
{
Ch ch = this->SkipSpace();
if (ch != '[')
{
if (ch == 'n')
{
if (ReadNullValue()==false)
{
return false;
}
return true;
}
return false;
}
if (this->m_Reader.Peek() == ']')
{
this->m_Reader.Take();
return true;
}
do
{
value.push_back(type());
if (Read(value.back(), pKey,len) == false)
{
value.resize(value.size()-1);
return false;
}
ch = this->SkipSpace();
if (ch == ']')
{
break;
}
else if (ch != ',')
{
return false;
}
} while (true);
return true;
}
template< typename type>
bool ReadField(type & value, const Ch* pKey , int len )
{
return ReadField(value, Int2Type<1>(), pKey, len);;
}
template<int index, typename type>
bool ReadField(type & value, Int2Type<index> ind,const Ch* pKey, int len )
{
if (CompareKey(value, ind,pKey,len)==true)
{
return CallJsonFieldCallBack(value, ind,pKey, len);
}
return ReadField<index + 1, type>(value, Int2Type<index + 1>(), pKey, len );;
}
template<int index, typename type>
bool ReadField(type & value, Int2Type<type::Size+1> ind, const Ch* pKey, int len)
{
return ReadUnknowField(value, pKey, len);
}
template<typename type>
bool ReadUnknowField(type & value,const Ch* pKey, int len)
{
//json中多出来的字段,需要处理
Ch ch = SkipSpace();
switch (ch)
{
case '{': //处理对象
{
int braces = 1; //大括号数量
while (0 != (ch= this->m_Reader.Take()))
{
if (ch == '}')
{
braces--;
if (braces == 0)
{
return true;
}
}
else if (ch == '{')
{
braces++;
}
else if (ch == '\"')
{
const Ch * pEscapeBegin = false;
const Ch * ptr = this->FindQuotation(pEscapeBegin);
if (ptr == NULL)
{
return false;
}
}
}
return false;
}
break;
case '[': //处理数组
{
int braces = 1; //大括号数量
while (0 != (ch = this->m_Reader.Take()))
{
if (ch == ']')
{
braces--;
if (braces == 0)
{
return true;
}
}
else if (ch == '[')
{
braces++;
}
else if (ch == '\"')
{
const Ch * pEscapeBegin = false;
const Ch * ptr = this->FindQuotation(pEscapeBegin);
if (ptr == NULL)
{
return false;
}
}
}
return false;
}
break;
case '\"': //处理字符串
{
const Ch * pEscapeBegin = false;
const Ch * ptr = this->FindQuotation(pEscapeBegin);
if (ptr == NULL)
{
break;
}
}
break;
case 'n': //处理null值
{
if (ReadNullValue()==false)
{
return false;
}
}
break;
case 't': //处理true值
{
if (ReadTrueValue()==false)
{
return false;
}
}
break;
case 'f': //处理false
{
if (ReadFalseValue()==false )
{
return false;
}
}
break;
default:
if (ch >= '0'&& ch <= '9' || ch == '-')
{
unsigned char uch;
while (0 != (uch = this->m_Reader.Peek()))
{
if (IsFloat[uch])
{
this->m_Reader.Take();
}
else if (IsSeparator[uch])
{
return true;
}
else
{
return false;
}
}
return true;
}
else
{
return false;
}
break;
}
return true;
}
private:
char SkipSpace()
{
while (true)
{
Ch ch = m_Reader.Take();
if (!IsSpace[(unsigned char)ch])
{
return ch;
}
}
return 0;
}
unsigned ParseHex4(const Ch * & stream) {
const Ch * s = stream;
unsigned codepoint = 0;
for (int i = 0; i < 4; i++) {
Ch c = *s++;
codepoint <<= 4;
codepoint += c;
if (c >= '0' && c <= '9')
codepoint -= '0';
else if (c >= 'A' && c <= 'F')
codepoint -= 'A' - 10;
else if (c >= 'a' && c <= 'f')
codepoint -= 'a' - 10;
else
return 0;
}
return codepoint;
}
const Ch * FindQuotation(const Ch* & pEscapeBein)
{
Ch ch;
while (0 != (ch = this->m_Reader.Take()))
{
if (ch == '\\')
{
pEscapeBein = this->m_Reader.Current() - 1;
if (this->m_Reader.Take() == 0)
{
return 0;
}
while (0 != (ch = this->m_Reader.Take()))
{
if (ch == '\\')
{
if (this->m_Reader.Take() == 0)
{
return 0;
}
}
else if (ch == '"')
{
const Ch * ptr = m_Reader.Current();
return --ptr;
}
}
return 0;
}
else if (ch == '"')
{
const Ch * ptr = m_Reader.Current();
return --ptr;
}
}
return 0;
}
bool ReadString(const Ch * & pBegin, int & len, bool & bIncludeEscape, std::string & str)
{
#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
static const char IsEscape[256] = {
Z16, Z16, 0, 0,'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'/',
Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0,
0, 0,'\b', 0, 0, 0,'\f', 0, 0, 0, 0, 0, 0, 0,'\n', 0,
0, 0,'\r', 0,'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16
};
#undef Z16
pBegin = this->m_Reader.Current();
const Ch* pEscapeBegin = NULL;
const Ch* pEnd = this->FindQuotation(pEscapeBegin);
if (pEnd == NULL)
{
return false;
}
if (pEscapeBegin == NULL)
{
bIncludeEscape = false;
len = pEnd - pBegin;
}
else
{
bIncludeEscape = true;
str.resize((pEnd - pBegin)*sizeof(Ch));
len = pEscapeBegin - pBegin;
if (len > 0)
{
memcpy((void*)str.data(), pBegin, len*sizeof(Ch));
}
Ch * pData = (Ch*)(str.data());
while (pEscapeBegin<pEnd)
{
Ch ch = *pEscapeBegin++;
if (ch == '\\')
{
Ch e = *pEscapeBegin++;
if ((sizeof(Ch) == 1 || e < 256) && IsEscape[(unsigned char)e])
pData[len++] = IsEscape[(unsigned char)e];
else if (e == 'u') { // Unicode
unsigned int codepoint = ParseHex4(pEscapeBegin);
if (codepoint >= 0xD800 && codepoint <= 0xDBFF) { // Handle UTF-16 surrogate pair
if (*pEscapeBegin++ != '\\' || *pEscapeBegin++ != 'u') {
return false;
}
unsigned codepoint2 = ParseHex4(pEscapeBegin);
if (codepoint2 < 0xDC00 || codepoint2 > 0xDFFF) {
return false;
}
codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000;
}
//计算剩
Ch buffer[4];
size_t count = size_t(Encoding::Encode(buffer, codepoint) - &buffer[0]);
memcpy(&pData[len], buffer, count * sizeof(Ch));
len += count;
}
else {
return false;
}
}
else if ((unsigned)ch < 0x20)
{
return false;
}
else
{
pData[len++] = ch;
}
}
str.resize((len)*sizeof(Ch));
}
return true;
}
template<typename type>
bool CallJsonCallBack(type & value, const Ch * pKey, int key_len, Int2Type<0> noHaveJsonCallBackFunction)
{
return ReadField(value, Int2Type<1>(), pKey, key_len);
}
template<typename type>
bool CallJsonCallBack(type & value, const Ch * pKey, int key_len, Int2Type<1> haveJsonCallBackFunction)
{
return value.JsonParseCallBackFunction(*this, pKey, key_len);
}
bool ReadNullValue()
{
if (this->m_Reader.Take() != 'u'
|| this->m_Reader.Take() != 'l'
|| this->m_Reader.Take() != 'l'
)
{
return false;
}
return true;
}
bool ReadTrueValue()
{
if (this->m_Reader.Take() != 'r'
|| this->m_Reader.Take() != 'u'
|| this->m_Reader.Take() != 'e'
)
{
return false;
}
return true;
}
bool ReadFalseValue()
{
if (this->m_Reader.Take() != 'a'
|| this->m_Reader.Take() != 'l'
|| this->m_Reader.Take() != 's'
|| this->m_Reader.Take() != 'e'
)
{
return false;
}
return true;
}
template<int index, typename type>
bool CompareKey(type & value, Int2Type<index> ind, const Ch* pKey, int len)
{
if (HavedSet(value, ind))
{
return false;
}
if (CompareKeyHelper(value, ind, pKey, len, Int2Type<THaveJsonFieldGetKeyFunction<type, Int2Type<index>, Encoding&>::Value>()) == true)
{
return true;
}
return false;
}
template<int index, typename type>
bool HavedSet(type & value, Int2Type<index> ind)
{
return HavedSetHelper(value, ind, Int2Type<THaveJsonGetFieldBitsFunction<type>::Value>());
}
template<int index, typename type>
bool HavedSetHelper(type & value, Int2Type<index> ind, Int2Type<false> bNoHaveJsonGetFieldBitsFunction)
{
return false;
}
template<int index, typename type>
bool HavedSetHelper(type & value, Int2Type<index> ind, Int2Type<true> bHaveJsonGetFieldBitsFunction)
{
return value.JsonGetFieldBitsFunction()[index];
}
template<int index, typename type>
bool CompareKeyHelper(type & value, Int2Type<index> ind, const Ch* pKey, int len, Int2Type<false> bNoHaveGetKeyFunction)
{
const Ch* pName = value.getName(ind);
if (strncmp(pName, pKey, len) == 0 && pName[len]==0)
{
return true;
}
return false;
}
template<int index, typename type>
bool CompareKeyHelper(type & value, Int2Type<index> ind, const Ch* pKey, int len, Int2Type<true> bHaveGetKeyFunction)
{
std::string & strKey = value.JsonFieldGetKeyFunction(ind, Encoding());
if (strKey.length() == len*sizeof(Ch) && memcmp(strKey.data(), pKey, len*sizeof(Ch)) == 0)
{
return true;
}
return false;
}
template<typename type, int index>
bool CallJsonFieldCallBack(type & value, Int2Type<index> ind,const Ch* pKey, int key_len)
{
return CallJsonFieldCallBackHelper(value,ind,pKey, key_len, Int2Type<THaveJsonFieldCallBackFunction<type, IJsonBuffer &, const Ch*, int, Int2Type<index> >::Value>());
}
template<typename type,int index>
bool CallJsonFieldCallBackHelper(type & value, Int2Type<index> ind ,const Ch* pKey, int key_len, Int2Type<0> noHaveJsonFieldCallBackFunction)
{
return Read(value.getValue(ind), pKey, key_len);
}
template<typename type, int index>
bool CallJsonFieldCallBackHelper(type & value, Int2Type<index> ind, const Ch* pKey, int key_len, Int2Type<1> haveJsonFieldCallBackFunction)
{
return value.JsonFieldCallBackFunction(*this, pKey, key_len, ind);
}
bool ReadNumber(long long & value)
{
long long obj = 0;
bool bNegative = false;
Ch ch = this->SkipSpace();
if (ch == '-')
{
bNegative = true;
}
else if (ch == 'n')
{
if (ReadNullValue()==false)
{
return false;
}
value = 0;
return true;
}
else
{
obj = ch - '0';
}
unsigned char uch;
while (0 != (uch = this->m_Reader.Peek()))
{
if (uch >= '0' && uch <= '9')
{
obj = obj * 10 + uch - '0';
}
else if (IsSeparator[uch])
{
break;
}
this->m_Reader.Take();
}
if (bNegative)
{
value = 0 - obj;
}
else
{
value = obj;
}
return true;
}
private:
TReader<Ch> m_Reader;
const char * m_pBegin; //有效数据
const char * m_pData; //有效数据
const char * m_pEnd; //有效数据
bool m_bError; //是否产生了错误
};
}
#define FIELD_BITS(FieldBits) std::bitset<Size+1> FieldBits; std::bitset<Size+1>& JsonGetFieldBitsFunction(){ return FieldBits;} \
template <typename EncondingType,int index> \
bool JsonFieldCallBackFunction(LightJson::IJsonBuffer<EncondingType> & IJsonB, const typename EncondingType::Ch * pKey, int len, Int2Type<index> ind) \
{ \
if (IJsonB.Read(this->getValue(ind), pKey, len) == false) { return false; } \
JsonGetFieldBitsFunction().set(index, true); JsonGetFieldBitsFunction().set(0, true); \
return true; \
}
#define JSON_FIELD_INDEX(index,type,name,key) FIELD_INDEX(index,type,name) \
bool Have_##name##(){return JsonGetFieldBitsFunction()[index]; } \
void Set_##name##(bool bValue=true){JsonGetFieldBitsFunction().set(index,bValue);} \
template<typename Encoding> std::string & JsonFieldGetKeyFunction(Int2Type<index>,Encoding & Encoder) { static std::string str = std::move(Encoding::FromString(key)); return str;} \
void SetKey_##name##(std::string & strKey) { JsonFieldGetKeyFunction(Int2Type<index>(),LightJson::UTF8<>()) = std::move(strKey);}
#define JSON_FIELD(type,name) JSON_FIELD_INDEX(AUTO_INDEX(),type,name,#name)
#define JSON_FIELD_KEY(type,name,key) JSON_FIELD_INDEX(AUTO_INDEX(),type,name,key)
#define JSON_BEGIN() FIELD_BEGIN()
#define JSON_END() FIELD_END() FIELD_BITS(m_FieldBits)
#endif
四、一个简单的与rapidjson性能比较的例子
LightJson的json标准化过程中,部份代码参考了rapidjson,没有否定rapidjson的意思。所举的例子,不够全面,并不能完全反应两者的水平。该例子仅供参考。要运行该例子,需要设置你自己的rapidjson项目的目录。注意:需要把编译器O2优化选项打开。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include<time.h>
#include "./ThridParty/rapidjson/document.h"
#include "./ThridParty/rapidjson/stringbuffer.h"
#include "./ThridParty/rapidjson/writer.h"
#include <vector>
#include "LightJson.h"
//
struct TJsonCallBackFunctionSink
{
template<typename Enconding>
bool JsonParseCallBackFunction(LightJson::IJsonBuffer<Enconding> & IJsonB, const typename Enconding::Ch * pKey, int len)
{
if (strncmp("m_int\n64", pKey, len) == 0)
{
long long ll = 0;
if (IJsonB.Read(ll, pKey, len) == false)
{
return false;
}
printf("m_int\\n64[%lld]\n", ll);
}
else if (strncmp("m_Sub", pKey, len) == 0)
{
struct SubSink
{
bool JsonParseCallBackFunction(LightJson::IJsonBuffer<Enconding> & IJsonB, const typename Enconding::Ch * pKey, int len)
{
if (strncmp("m_int", pKey, len) == 0)
{
int ll = 0;
if (IJsonB.Read(ll, pKey, len) == false)
{
return false;
}
printf("Sub.m_int[%d]\n", ll);
}
else
{
return IJsonB.ReadUnknowField(*this, pKey, len);
}
}
}sub;
if (IJsonB.Read(sub, pKey, len) == false)
{
return false;
}
}
else
{
return IJsonB.ReadUnknowField(*this, pKey, len);
}
return true;
}
};
//嵌套结构体
struct TestJsonSub
{
JSON_BEGIN()
JSON_FIELD(bool, m_Bool);
JSON_FIELD(int, m_int);
JSON_END();
};
//结构体
struct TestJsonC
{
JSON_BEGIN()
JSON_FIELD_KEY(long long, m_int64,"m_int\n64");
JSON_FIELD(double, m_float);
JSON_FIELD(std::string, m_str);
JSON_FIELD(std::vector<int>, m_vect);
JSON_FIELD(TestJsonSub, m_Sub);
JSON_FIELD(int, m_int1);
JSON_FIELD(int, m_int2);
JSON_FIELD(int, m_int3);
JSON_FIELD(int, m_int4);
JSON_FIELD(int, m_int5);
JSON_FIELD(std::vector<TestJsonSub>, m_vectSub);
JSON_END();
};
bool TestJson()
{
const int count = 100000;
TestJsonC objC;
objC.m_int64 = 223356644;
objC.m_float = 3.1415959;
objC.m_str = LightJson::UTF8<>::FromString(L"aght有中文哦Json有转义\n\r\t哦!");
for (int i = 0; i < 100; i++)
{
TestJsonSub sub;
sub.m_Bool = i;
sub.m_int = i;
objC.m_vectSub.push_back(sub);
objC.m_vect.push_back(i);
}
objC.m_Sub.m_Bool = true;
objC.m_Sub.m_int = -12562213;
objC.m_int1 = objC.m_int2 = objC.m_int3 = objC.m_int4 = objC.m_int5 = 2000;
clock_t startC = clock();
const int count = 100000;
for (int i = 0; i < count; i++)
{
TestJsonC objC1;
objC1.m_int64 = objC.m_int64;
objC1.m_float = objC.m_float;
objC1.m_str = objC.m_str;
objC1.m_vect = objC.m_vect;
objC1.m_Sub.m_Bool = objC.m_Sub.m_Bool;
objC1.m_Sub.m_int = objC.m_Sub.m_int;
objC1.m_int1 = objC1.m_int2 = objC1.m_int3 = objC1.m_int4 = objC1.m_int5 = objC.m_int1;
objC1.m_vectSub = objC.m_vectSub;
std::string strJson = LightJson::JsonUtil::ToJsonString(objC1);
TestJsonC objC2;
TestJsonC objC3;
if (LightJson::JsonUtil::FromJsonString(objC2,strJson.data(),strJson.length()) == false)
{
return false;
}
if (objC2.Have_m_int64())
{
objC3.m_int64 = objC2.m_int64;
}
if (objC2.Have_m_float())
{
objC3.m_float = objC2.m_float ;
}
if (objC2.Have_m_str())
{
objC3.m_str = objC2.m_str.c_str();
}
if (objC2.Have_m_vect())
{
objC3.m_vect.reserve(objC2.m_vect.size());
for (int i = 0; i < objC2.m_vect.size();i++)
{
objC3.m_vect.push_back(objC2.m_vect[i]);
}
}
if (objC2.Have_m_Sub())
{
TestJsonSub & sub = objC2.m_Sub;
if (sub.Have_m_Bool())
{
objC3.m_Sub.m_Bool = sub.m_Bool;
}
if (sub.Have_m_int())
{
objC3.m_Sub.m_int = sub.m_int;
}
}
if (objC2.Have_m_int1())
{
objC3.m_int1 = objC2.m_int1;
}
if (objC2.Have_m_int2())
{
objC3.m_int2 = objC2.m_int2;
}
if (objC2.Have_m_int3())
{
objC3.m_int3 = objC2.m_int3;
}
if (objC2.Have_m_int4())
{
objC3.m_int4 = objC2.m_int4;
}
if (objC2.Have_m_int5())
{
objC3.m_int5 = objC2.m_int5;
}
if (objC2.Have_m_vectSub())
{
objC3.m_vectSub = objC2.m_vectSub;
}
/*另一种用法,把TJsonCallBackFunctionSink对象做为回调处理者去反列化
TJsonCallBackFunctionSink Sink;
if (LightJson::JsonUtil::FromJsonString(Sink,strJson.data(),strJson.length()) == false)
{
return false;
}*/
}
clock_t endC = clock();
printf("Test Json LightJson time = %u\n", endC - startC);
startC = clock();
for (int i = 0; i < count; i++)
{
rapidjson::Document doc;
doc.SetObject();
{
rapidjson::Value strValue(rapidjson::kNumberType);
strValue.SetInt(objC.m_int1);
doc.AddMember("m_int1", strValue, doc.GetAllocator());
}
{
rapidjson::Value strValue(rapidjson::kNumberType);
strValue.SetInt(objC.m_int2);
doc.AddMember("m_int2", strValue, doc.GetAllocator());
}
{
rapidjson::Value strValue(rapidjson::kNumberType);
strValue.SetInt(objC.m_int3);
doc.AddMember("m_int3", strValue, doc.GetAllocator());
}
{
rapidjson::Value strValue(rapidjson::kNumberType);
strValue.SetInt(objC.m_int4);
doc.AddMember("m_int4", strValue, doc.GetAllocator());
}
{
rapidjson::Value strValue(rapidjson::kNumberType);
strValue.SetInt(objC.m_int5);
doc.AddMember("m_int5", strValue, doc.GetAllocator());
}
{
rapidjson::Value strValue(rapidjson::kNumberType);
strValue.SetInt64(objC.m_int64);
doc.AddMember("m_int64", strValue, doc.GetAllocator());
}
{
rapidjson::Value strValue(rapidjson::kNumberType);
strValue.SetDouble(objC.m_float);
doc.AddMember("m_float", strValue, doc.GetAllocator());
}
{
rapidjson::Value strValue(rapidjson::kStringType);
strValue.SetString(objC.m_str.c_str(), doc.GetAllocator());
doc.AddMember("m_str", strValue, doc.GetAllocator());
}
{
rapidjson::Value strValue(rapidjson::kArrayType);
for (int i = 0;i < objC.m_vect.size();i++)
{
strValue.PushBack(objC.m_vect[i], doc.GetAllocator());
}
doc.AddMember("m_vect", strValue, doc.GetAllocator());
}
{
rapidjson::Value object(rapidjson::kObjectType);
object.AddMember("m_Bool",objC.m_Sub.m_Bool,doc.GetAllocator());
object.AddMember("m_int", objC.m_Sub.m_int, doc.GetAllocator());
doc.AddMember("m_Sub", object, doc.GetAllocator());
}
{
rapidjson::Value strValue(rapidjson::kArrayType);
for (int i = 0;i < objC.m_vectSub.size();i++)
{
rapidjson::Value object(rapidjson::kObjectType);
object.AddMember("m_Bool", objC.m_vectSub[i].m_Bool, doc.GetAllocator());
object.AddMember("m_int", objC.m_vectSub[i].m_int, doc.GetAllocator());
strValue.PushBack(object, doc.GetAllocator());
}
doc.AddMember("m_vectSub", strValue, doc.GetAllocator());
}
rapidjson::StringBuffer buffer;
rapidjson::Writer< rapidjson::StringBuffer > writer(buffer);
doc.Accept(writer);
std::string strJson = buffer.GetString();
TestJsonC objC2;
doc.Parse<0>(strJson.c_str());
if (doc.HasParseError())
{
return false;
}
if (doc.HasMember("m_int64"))
{
rapidjson::Value & value = doc["m_int64"];
objC2.m_int64 = value.GetInt64();
}
if (doc.HasMember("m_float"))
{
rapidjson::Value & value = doc["m_float"];
objC2.m_float = value.GetDouble();
}
if (doc.HasMember("m_str"))
{
rapidjson::Value & value = doc["m_str"];
objC2.m_str = value.GetString();
}
if (doc.HasMember("m_vect"))
{
rapidjson::Value & value = doc["m_vect"];
objC2.m_vect.reserve(value.Size());
for (int i = 0; i < value.Size();i++)
{
objC2.m_vect.push_back(value[i].GetInt());
}
}
if (doc.HasMember("m_Sub"))
{
rapidjson::Value & value = doc["m_Sub"];
if (value.HasMember("m_Bool"))
{
objC2.m_Sub.m_Bool = value["m_Bool"].GetBool();
}
if (value.HasMember("m_int"))
{
objC2.m_Sub.m_int = value["m_int"].GetInt();
}
}
if (doc.HasMember("m_int1"))
{
rapidjson::Value & value = doc["m_int1"];
objC2.m_int1 = value.GetInt();
}
if (doc.HasMember("m_int2"))
{
rapidjson::Value & value = doc["m_int2"];
objC2.m_int2 = value.GetInt();
}
if (doc.HasMember("m_int3"))
{
rapidjson::Value & value = doc["m_int3"];
objC2.m_int3 = value.GetInt();
}
if (doc.HasMember("m_int4"))
{
rapidjson::Value & value = doc["m_int4"];
objC2.m_int4 = value.GetInt();
}
if (doc.HasMember("m_int5"))
{
rapidjson::Value & value = doc["m_int5"];
objC2.m_int5 = value.GetInt();
}
if (doc.HasMember("m_vectSub"))
{
rapidjson::Value & value = doc["m_vectSub"];
objC2.m_vect.reserve(value.Size());
for (int i = 0; i < value.Size();i++)
{
objC2.m_vectSub.push_back(TestJsonSub());
rapidjson::Value & valueSub = value[i];
if (valueSub.HasMember("m_Bool"))
{
objC2.m_vectSub[i].m_Bool = valueSub["m_Bool"].GetBool();
}
if (valueSub.HasMember("m_int"))
{
objC2.m_vectSub[i].m_int = valueSub["m_int"].GetInt();
}
}
}
}
endC = clock();
printf("Test Json rapidjson time = %u\n", endC - startC);
return true;
}
void main()
{
if (TestJson() == false)
{
printf("TestJson Fail!\n");
}
else
{
printf("TestJson OK!\n");
}
getchar();
printf("app exit OK!\n");
return;
}
例子在我的机器上运行结果为: (LightJson耗时约为rapidjson的三分之一)
Test Json LightJson time = 3768
Test Json rapidjson time = 14591
TestJson OK!