一、前言
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__ /*************************************************************************************************** 转载请注明出处,作者联系方式:[email protected] 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) { if (strncmp(value.getName(ind), pKey, 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!