一個比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