一个比rapidjson还要快的json类库

jopen 8年前

一个简单,易用,性能更好的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());   }

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