一个比rapidjson还要快的json类库
一个简单,易用,性能更好的json C++类库,整个类库只包括一个.h头文件。
这次挑战的是腾讯的开源项目:rapidjson。初步测试,性能要比rapidjson快一倍(需要打开编译器O2优化项,切记!)。
用法说明:
1 包含类库唯一的头文件
#include "LightJson.h"
2 使用宏FIELD_BEGIN,FIELD,JSON_END来定义结构体:
//嵌套结构体 struct TestJsonSub { FIELD_BEGIN() FIELD(bool, m_Bool); //注意,字段名即是json的key FIELD(int, m_int); JSON_END(m_FieldBits); }; //结构体 struct TestJsonC { FIELD_BEGIN() FIELD(long long, m_int64); FIELD(double, m_float); FIELD(std::string, m_str); FIELD(std::vector<int>,m_vect); FIELD(TestJsonSub,m_Sub); JSON_END(m_FieldBits); };
其中TestJsonC结构体包含有5个需要序列化为json字符的字段以及一个不参数序列化的字m_FieldBits,其原型为: std::bitset<6> m_FieldBits; 在从json字符串反序列化为TestJsonC结构体时,m_FieldBits记录那些字段有被赋值。
3 给结构体赋值:
TestJsonC objC; objC.m_int64 = 223356644; objC.m_float = 3.1415959; objC.m_str = "abd我爱你lightJson!"; for (int i = 0; i < 100; i++) { objC.m_vect.push_back(i); } objC.m_Sub.m_Bool = true; objC.m_Sub.m_int = -12562213;
4 对结构体序列化:
std::string strJson = JsonUtil::ToJsonString(objC); //只调用个函数
strJson的值为:
{"m_int64":223356644,"m_float":3.141596,"m_str":"abd我爱你lightJson!","m_vect":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99],"m_Sub":{"m_Bool":true,"m_int":-12562213}}
5 对strJson反序列化:
TestJsonC objC2; if (JsonUtil::FromJsonString(objC2, strJson) == false) { printf("fail!\n"); } if (objC2.m_FieldBits[1]) //第一个字段有被赋值 { printf("m_int64 = %lld ", objC2.m_int64); } if (objC2.m_FieldBits[3]) //第三个字段有被赋值 { printf("m_str = %s ", objC2.m_str.c_str()); }
6 LightJson需要优化的地方:
没有处理转义符,需要支持c++ 0x11的编译器。
7 LightJson.h文件
#ifndef __LIGHTJSON_H__ #define __LIGHTJSON_H__ /*************************************************************************************************** 转载请注明出处,作者联系方式:3181356737@qq.com V 1.0 Date:2015-11-26 *****************************************************************************************************/ #include <bitset> #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 template<typename T, typename... Args>struct THaveJsonParseCallBackFunction { private: template<typename U> static auto Check(int) -> decltype(std::declval<U>().JsonParseCallBackFunction(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 }; }; template<typename T, typename... Args>struct THaveJsonFieldCallBackFunction { private: template<typename U> static auto Check(int) -> decltype(std::declval<U>().JsonFieldCallBackFunction(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 }; }; class JsonUtil { public: template<typename type> static bool FromJsonString(type & value, const char* szJsonStr, int len = 0) { if (len == 0) { len = strlen(szJsonStr); } IJsonBuffer ib(szJsonStr, len); if (ib.Read(value) == false) { return false; } return true; } template<typename type> static bool FromJsonString(type & value, const std::string & strJson) { IJsonBuffer ib(strJson.c_str(), strJson.length()); if (ib.Read(value) == false) { return false; } return true; } template<typename type> static std::string ToJsonString(type & value) { OJsonBuffer<1> ob; if (ob.Write(value) == false) { return ""; } return std::move(ob.ToString()); } }; template<size_t static_size> class OJsonBuffer { public: public: OJsonBuffer() { __Init(); } explicit OJsonBuffer(char * pData, size_t len) { __Init(); this->m_ptrBegin = this->m_ptrCur = pData; this->m_Size = len; } //预分配容量 explicit OJsonBuffer(size_t len) { __Init(); if (len == 0) { len = 1024; } ResetCapacity(len); } ~OJsonBuffer() { __Init(); } //复位 void Reset() { m_bError = false; m_Size = 0; m_ptrCur = m_ptrBegin = NULL; } size_t GetStaticSize() { return static_size; } //返回从pos开始的内存 const char * Buffer(size_t pos = 0) const { if (pos >= m_Size) { return nullptr; } return m_ptrBegin + pos; } char * CurrentBuffer() { return m_ptrCur; } char * Skip(size_t len) { char* pOld = m_ptrCur; m_ptrCur += len; return pOld; } //获得数据大小 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; vect.insert(vect.begin(), m_ptrBegin, m_ptrCur); return std::move(vect); } std::string ToString() { char * ptr = m_ptrCur; *ptr++ = 0; if (m_ptrBegin == m_strData.data()) { m_strData.resize(ptr - m_ptrBegin); return std::move(m_strData); } else { return std::move(std::string(m_ptrBegin, ptr)); } } //扩展内存 bool ResetCapacity(size_t len) { int old_size = this->Size(); if (old_size >= len) { return true; } if (m_strData.data() == m_ptrBegin) { m_strData.resize(len); } else { m_strData.resize(len); if (old_size > 0) { memcpy((char*)m_strData.data(), m_ptrBegin, old_size); } } this->m_Size = len; this->m_ptrBegin = (char*)m_strData.data(); this->m_ptrCur = m_ptrBegin + old_size; return true; } //是否产生了错误 bool Error() const { return m_bError; } //push二进制内存 void Push(const void* pData, int len) { memcpy(this->m_ptrCur, pData, len); this->m_ptrCur += len; } //写整数 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; char * 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; char * 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; char * 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) { char buff[100]; sprintf(buff, "%f", value); for (int i = 0; (*m_ptrCur = buff[i]) != 0;i++) { m_ptrCur++; } } //写double void WriteDouble(double value) { char buff[100]; sprintf(buff, "%f", value); for (int i = 0; (*m_ptrCur = buff[i]) != 0;i++) { m_ptrCur++; } } //写str void WriteStr(const char* value) { int len = ByteSize(value); sprintf(m_ptrCur, "\"%s\"", value); m_ptrCur += len; } int ByteSize(const char * szData) { return strlen(szData) + 2; } int ByteSize(const std::string & str) { return str.length() + 2; } int ByteSize( std::string & str) { return str.length() + 2; } int ByteSize(bool v) { if (v) { return 4; } else { return 5; } } int ByteSize(float v) { char buff[100]; sprintf(buff,"%f",v); return strlen(buff); } int ByteSize(double v) { char buff[100]; sprintf(buff, "%f", v); return strlen(buff); } 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 += strlen(obj.getName(ind)) + 3; len += ByteSize(obj.getValue(ind)); if (size == type::Size) { len++; } return len; } public: template< typename type> int Write(type & obj) { int byte_size = ByteSize(obj); if (byte_size+1 <= static_size) { this->m_ptrBegin = this->m_ptrCur = this->m_static_data; this->m_Size = static_size; } 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; } Write(obj.getValue(ind), obj.getName(ind), size==1); if (size == type::Size) { *this->m_ptrCur++ = '}'; } return this->Error() == false; } ///////////////////////////////////////////////// template<typename ValueType> void Write(ValueType & obj,const char * szKey,bool bFirst) { WriteKey(szKey, bFirst); Write(obj, Int2Type<ValueType::Size>()); } void Write(char obj, const char * szKey, bool bFirst) { WriteKey(szKey, bFirst); WriteInt32((int)obj); } void Write(unsigned char obj, const char * szKey, bool bFirst) { WriteKey(szKey, bFirst); WriteInt32((unsigned int)obj); } void Write(short obj, const char * szKey, bool bFirst) { WriteKey(szKey, bFirst); WriteInt32((int)obj); } void Write(unsigned short obj, const char * szKey, bool bFirst) { WriteKey(szKey, bFirst); WriteInt32((unsigned int)obj); } void Write(int obj, const char * szKey, bool bFirst) { WriteKey(szKey, bFirst); WriteInt32(obj); } void Write(unsigned int obj, const char * szKey, bool bFirst) { WriteKey(szKey, bFirst); WriteInt32(obj); } void Write(long obj, const char * szKey, bool bFirst) { WriteKey(szKey, bFirst); WriteInt32((int)obj); } void Write(unsigned long obj, const char * szKey, bool bFirst) { WriteKey(szKey, bFirst); WriteInt32((unsigned int)obj); } void Write(long long obj, const char * szKey, bool bFirst) { WriteKey(szKey, bFirst); WriteInt64(obj); } void Write(unsigned long long obj, const char * szKey, bool bFirst) { WriteKey(szKey, bFirst); WriteInt64((long long)obj); } void Write(bool obj, const char * szKey, bool bFirst) { WriteKey(szKey, bFirst); WriteBool(obj); } void Write(float obj, const char * szKey, bool bFirst) { WriteKey(szKey, bFirst); WriteFloat(obj); } void Write(double obj, const char * szKey, bool bFirst) { WriteKey(szKey, bFirst); WriteDouble(obj); } void Write(const char* obj, const char * szKey, bool bFirst) { WriteKey(szKey, bFirst); WriteStr(obj); } void Write( char* obj, const char * szKey, bool bFirst) { WriteKey(szKey, bFirst); WriteStr(obj); } void Write(const std::string & obj, const char * szKey, bool bFirst) { WriteKey(szKey, bFirst); WriteStr(obj.c_str()); } void Write( std::string & obj, const char * szKey, bool bFirst) { WriteKey(szKey, bFirst); WriteStr(obj.c_str()); } template<typename type> void Write(std::vector<type> & obj, const char * 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 char * 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: void WriteKey(const char* szKey, bool bFirst) { if (bFirst == false) { *this->m_ptrCur++ = ','; } if (szKey) { *this->m_ptrCur++ = '\"'; while ((*this->m_ptrCur = *szKey++) != 0) { m_ptrCur++; } *this->m_ptrCur++ = '\"'; *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; char* m_ptrCur; char* m_ptrBegin; bool m_bError; //是否产生了错误 }; #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,'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, Z8,Z8,Z8,Z8, Z8,Z8,Z8,Z8, Z8,Z8,Z8,Z8, Z8,Z8,Z8,Z8, Z8,Z8,Z8,Z8 }; #undef Z8 //输入Buffer class IJsonBuffer { public: IJsonBuffer(const char* pData, int len) { m_pBegin = m_pData = pData; m_pEnd = m_pBegin + len; m_bError = false; } IJsonBuffer(const std::vector<char> & vectData) { m_pBegin = m_pData = vectData.data(); m_pEnd = m_pBegin + vectData.size(); m_bError = false; } template<size_t size> IJsonBuffer(const OJsonBuffer<size> & ob) { m_pBegin = m_pData = ob.Buffer(); m_pEnd = m_pBegin + ob.Size(); m_Size = 0; m_bError = false; } ~IJsonBuffer() { m_pEnd = m_pBegin = m_pData = 0; m_bError = false; } //总长度 int Capacity() { return m_pEnd - m_pBegin; } //余下未读数据 int Remain() { return m_pEnd - m_pData; } //已读数据 int Size() const { return m_pData - m_pBegin; } //返回从len字节开始的内存 const char * Buffer(int len = 0) { if (m_pBegin + len >m_pEnd) return NULL; return m_pBegin + len; } //返回未读buffer const char * CurrentBuffer() { return m_pData ; } //跳过len字节,返回移动前的地址 const char * Skip(int len) { if (m_pData + len>m_pEnd) { m_bError = true; return NULL; } const char * ptr = m_pData; m_pData += len; return ptr; } //是否产生了错误 bool Error() { return m_bError; } char SkipSpace() { while (m_pData < m_pEnd) { char ch = *m_pData++; if (!IsSpace[(unsigned char)ch]) { return ch; } } return 0; } const char* FindQuotation() { const char * pBegin = m_pData; while (m_pData < m_pEnd) { if (*m_pData == '\"' && ((pBegin==m_pData)||(*pBegin != '\\'))) { return m_pData++; } m_pData++; } return 0; } //读取 template<typename type> bool Read(type & value, const char* pKey=NULL, int len=0) { char ch = SkipSpace(); if (ch != '{') { if (ch == 'n') { if (this->m_pData + 3 > this->m_pEnd) { return false; } if (m_pData[0] != 'u' || m_pData[1] != 'l' || m_pData[2] != 'l' ) { return false; } m_pData += 3; return true; } return false; } if (this->Remain() == 0) { return false; } if (*this->CurrentBuffer() == '}') { this->m_pData++; return true; } do { pKey = FindQuotation(); if (pKey == NULL) { return false; } pKey++; const char* ptr = FindQuotation(); if (ptr == NULL) { return false; } int key_len = ptr - pKey; 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; } } while (true); return this->m_bError == false; } template<typename type> bool CallJsonCallBack(type & value,const char* pKey,int key_len,Int2Type<0> noHaveJsonCallBackFunction) { return ReadField(value, Int2Type<type::Size>(), pKey, key_len); } template<typename type> bool CallJsonCallBack(type & value, const char* pKey, int key_len, Int2Type<1> haveJsonCallBackFunction) { return value.JsonParseCallBackFunction(*this, pKey, key_len); } bool Read(bool & value, const char* pKey=NULL, int len = 0) { value = false; char ch = SkipSpace(); if (ch == 't') { if (this->m_pData + 3 > this->m_pEnd) { return false; } if (m_pData[0] != 'r' || m_pData[1] != 'u' || m_pData[2] != 'e' ) { return false; } m_pData += 3; value = true; } else if (ch == 'f') { if (this->m_pData + 4 > this->m_pEnd) { return false; } if (m_pData[0] != 'a' || m_pData[1] != 'l' || m_pData[2] != 's' || m_pData[3] != 'e' ) { return false; } m_pData += 4; value = false; } else if (ch == 'n') { if (this->m_pData + 3 > this->m_pEnd) { return false; } if (m_pData[0] != 'u' || m_pData[1] != 'l' || m_pData[2] != 'l' ) { return false; } m_pData += 3; value = false; } return true; } bool Read(char & value, const char* 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 char* pKey = NULL, int len = 0) { long long ll = 0; if (ReadNumber(ll) == false) { return false; } value = ll; return true; } bool Read(short & value, const char* 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 char* pKey = NULL, int len = 0) { long long ll = 0; if (ReadNumber(ll) == false) { return false; } value = ll; return true; } bool Read(int & value, const char* 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 char* pKey = NULL, int len = 0) { long long ll = 0; if (ReadNumber(ll) == false) { return false; } value = ll; return true; } bool Read(long & value, const char* 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 char* 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 char* 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 char* pKey = NULL, int len = 0) { long long ll = 0; if (ReadNumber(ll) == false) { return false; } value = ll; return true; } bool Read(float & value, const char* pKey = NULL, int len = 0) { char buff[30]; int i = 0; char ch = this->SkipSpace(); if ((ch >= '0'&&ch <= '9') || ch == '-') { buff[i++] = ch; } else if (ch == 'n') { if (this->m_pData + 3 > this->m_pEnd) { return false; } if (m_pData[0] != 'u' || m_pData[1] != 'l' || m_pData[2] != 'l' ) { return false; } m_pData += 3; value = 0; return true; } else { return false; } while (this->m_pData < this->m_pEnd && i<sizeof(buff)) { unsigned char uch = (unsigned char)*this->m_pData;; if (IsFloat[uch]) { buff[i++] = uch; } else if(IsSeparator[uch]) { break; } else if (!IsSpace[uch]) { return false; } this->m_pData++; } buff[i++] = 0; value = atof(buff); return true; } bool Read(double & value, const char* pKey = NULL, int len = 0) { char buff[30]; int i = 0; char ch = this->SkipSpace(); if ((ch >= '0'&&ch <= '9') || ch == '-') { buff[i++] = ch; } else if (ch == 'n') { if (this->m_pData + 3 > this->m_pEnd) { return false; } if (m_pData[0] != 'u' || m_pData[1] != 'l' || m_pData[2] != 'l' ) { return false; } m_pData += 3; value = 0; return true; } else { return false; } while (this->m_pData < this->m_pEnd && i<sizeof(buff)) { unsigned char uch = (unsigned char)*this->m_pData; if (IsFloat[uch]) { buff[i++] = uch; } else if (IsSeparator[uch]) { break; } else if (!IsSpace[uch]) { return false; } this->m_pData++; } buff[i++] = 0; value = atof(buff); return true; } bool Read(std::string & value, const char* pKey = NULL, int len = 0) { char ch = this->SkipSpace(); if (ch != '\"') { if (ch == 'n') { if (this->m_pData + 3 > this->m_pEnd) { return false; } if (m_pData[0] != 'u' || m_pData[1] != 'l' || m_pData[2] != 'l' ) { return false; } m_pData += 3; value = ""; return true; } return false; } const char* begin = this->CurrentBuffer(); const char* ptr = FindQuotation(); if (ptr == NULL) { return false; } if (ptr > begin) { value.assign(begin, ptr + 1); value.at(ptr - begin) = 0; } return true; } template<typename type> bool Read(std::vector<type> & value, const char* pKey = NULL, int len = 0) { char ch = this->SkipSpace(); if (ch != '[') { if (ch == 'n') { if (this->m_pData + 3 > this->m_pEnd) { return false; } if (m_pData[0] != 'u' || m_pData[1] != 'l' || m_pData[2] != 'l' ) { return false; } m_pData += 3; return true; } return false; } if (this->Remain() == 0) { return false; } if (*this->CurrentBuffer() == ']') { this->m_pData++; 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 char* pKey , int len ) { return ReadField(value, Int2Type<type::Size>(), pKey, len);; } template<int index, typename type> bool ReadField(type & value, Int2Type<index> ind,const char* pKey, int len ) { if (strncmp(value.getName(ind),pKey,len) == 0) { return CallJsonFieldCallBack(value, ind,pKey, len); } return ReadField<index - 1, type>(value, Int2Type<index - 1>(), pKey, len );; } template<typename type> bool ReadUnknowField(type & value,const char* pKey, int len) { //json中多出来的字段,需要处理 char ch = SkipSpace(); switch (ch) { case '{': //处理对象 { int braces = 1; //大括号数量 while (this->m_pData < this->m_pEnd) { ch = *this->m_pData; if (ch == '}') { this->m_pData++; braces--; if (braces == 0) { return true; } } else if (ch == '{') { this->m_pData++; braces++; } else if (ch == '\"') { this->m_pData++; const char * ptr = this->FindQuotation(); if (ptr == NULL) { return false; } } else { m_pData++; } } return false; } break; case '[': //处理数组 { int braces = 1; //大括号数量 while (this->m_pData < this->m_pEnd) { ch = *this->m_pData; if (ch == ']') { this->m_pData++; braces--; if (braces == 0) { return true; } } else if (ch == '[') { this->m_pData++; braces++; } else if (ch == '\"') { this->m_pData++; const char * ptr = this->FindQuotation(); if (ptr == NULL) { return false; } } else { m_pData++; } } return false; } break; case '\"': //处理字符串 { const char * ptr = this->FindQuotation(); if (ptr == NULL) { break; } } break; case 'n': //处理null值 { if (this->Remain() < 3) { return false; } this->m_pData += 3; } break; case 't': //处理true值 { if (this->Remain() < 3) { return false; } this->m_pData += 3; } break; case 'f': //处理false { if (this->Remain() < 4) { return false; } this->m_pData += 4; } break; default: if (ch >= '0'&& ch <= '9' || ch == '-') { while (this->m_pData < this->m_pEnd) { unsigned char uch = (unsigned char)*this->m_pData; if (IsFloat[uch]) { m_pData++; continue; } else if (IsSeparator[uch]) { return true; } else { return false; } } return this->m_pData < this->m_pEnd; } else { return false; } break; } return true; } template<int index, typename type> bool ReadField(type & value, Int2Type<0> ind,const char* pKey, int len) { return ReadUnknowField(value,pKey,len); } template<typename type, int index> bool CallJsonFieldCallBack(type & value, Int2Type<index> ind,const char* pKey, int key_len) { return CallJsonFieldCallBackHelper(value,ind,pKey, key_len, Int2Type<THaveJsonFieldCallBackFunction<type, IJsonBuffer &, const char*, int, Int2Type<index> >::Value>()); } template<typename type,int index> bool CallJsonFieldCallBackHelper(type & value, Int2Type<index> ind ,const char* 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 char* pKey, int key_len, Int2Type<1> haveJsonFieldCallBackFunction) { return value.JsonFieldCallBackFunction(*this, pKey, key_len, ind); } private: bool ReadNumber(long long & value) { long long obj = 0; bool bNegative = false; char ch = this->SkipSpace(); if (ch == '-') { bNegative = true; } else if (ch == 'n') { if (this->m_pData + 3 > this->m_pEnd) { return false; } if (m_pData[0] != 'u' || m_pData[1] != 'l' || m_pData[2] != 'l' ) { return false; } m_pData += 3; value = 0; return true; } else { obj = ch - '0'; } while (m_pData < m_pEnd) { unsigned char uch = (unsigned char)*m_pData; if (uch >= '0' && uch <= '9') { obj = obj * 10 + uch - '0'; } else if (IsSeparator[uch]) { break; } else if (!IsSpace[uch]) { this->m_bError = true; return false; } m_pData++; } if (bNegative) { value = 0 - obj; } else { value = obj; } return true; } private: const char * m_pBegin; //有效数据 const char * m_pData; //有效数据 const char * m_pEnd; //有效数据 bool m_bError; //是否产生了错误 }; #define FIELD_BITS(FieldBits) std::bitset<Size+1> FieldBits; \ template <int index> \ bool JsonFieldCallBackFunction(IJsonBuffer & IJsonB, const char* pKey, int len, Int2Type<index> ind) \ { \ if (IJsonB.Read(this->getValue(ind), pKey, len) == false) { return false; } \ FieldBits.set(index, true); FieldBits.set(0, true); \ return true; \ } #define JSON_END(FieldBits) FIELD_END() FIELD_BITS(FieldBits) #endif
8 一个和rapidjson性能比较的例子:
#include<time.h> #include "rapidjson/document.h" #include "rapidjson/stringbuffer.h" #include "rapidjson/writer.h" const int count = 1000000; bool TestJson() { TestJsonC objC; objC.m_int64 = 223356644; objC.m_float = 3.1415959; objC.m_str = "abd我爱你lightJson!"; for (int i = 0; i < 100; i++) { objC.m_vect.push_back(i); } objC.m_Sub.m_Bool = true; objC.m_Sub.m_int = -12562213; clock_t startC = clock(); 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; OJsonBuffer<1024> ob; if (ob.Write(objC1) == false) { return false; } TestJsonC objC2; TestJsonC objC3; if (JsonUtil::FromJsonString(objC2, ob.Buffer(),ob.Size()) == false) { return false; } if (objC2.m_FieldBits[1]) { objC3.m_int64 = objC2.m_int64; } if (objC2.m_FieldBits[2]) { objC3.m_float = objC2.m_float ; } if (objC2.m_FieldBits[3]) { objC3.m_str = objC2.m_str.c_str(); } if (objC2.m_FieldBits[4]) { 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.m_FieldBits[5]) { TestJsonSub & sub = objC2.m_Sub; if (sub.m_FieldBits[1]) { objC2.m_Sub.m_Bool = sub.m_Bool; } if (sub.m_FieldBits[2]) { objC2.m_Sub.m_int = sub.m_int; } } } clock_t endC = clock(); printf("Test Json C 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.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::StringBuffer buffer; rapidjson::Writer< rapidjson::StringBuffer > writer(buffer); doc.Accept(writer); const char* str = buffer.GetString(); TestJsonC objC2; doc.Parse<0>(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(); } } } endC = clock(); printf("Test Json rapidjson time = %u\n", endC - startC); return true; }
在我的机子上运行结果为:
Test Json C time = 5352
Test Json rapidjson time = 10678
9 上篇文章中用PB_BEGIN()和PB_END()宏定义的结构体,同样可以调用
std::string str = JsonUtil::ToJsonString(objC);
进行序列化。可以轻松实现google pb 到json的转换。
来自:http://my.oschina.net/u/2504104/blog/536095