一個比rapidjson還要快的json類庫

jopen 10年前發布 | 66K 次閱讀 JSON開發包 RapidJSON

一個簡單,易用,性能更好的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

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!