一个简单易用支持json标准的C++类库

一、前言

      LightJson 1.0版本的推出得众多网友的关注,在此表示感谢。同时,也有网友指出其不足。现在原有的基础上完成json标准化的支持。使用结构体静态绑定的好处是,扫描一眼结构体的定义你就能大概了解json的文档结构,而不需要阅读一大堆代码仍至要画图才能理清json的文档结构。至于有网友指出,结构体的定义改了,需要重新编译包括该头文件的代码。我觉得这问题不大,通常处理json的序列化和反序化的代码都在一个地方(一个cpp文件或一个模块),所以结构体的改变只需要重新编译该cpp即可,如果需要在几个模块中处理json的序列化和反序化,那么你不应该在一个模块中往docment对象中加几个字段,另一模块在往docment对象中加几个字段,这样做你的代码是零乱的,不好维护。当json的字段变了,都不知道去那个模块去修改相应docment对象。而通常的做法是定义一个结构体,各个业务模块填充结构体,然后在统一的地方把结构体序列化为json对象。

 

二、用法

  1)  使用宏JSON_BEGIN,JSON_END,JSON_FIELD,JSON_FIELD_KEY定义结构体如下:

#include "LightJson.h" //包含LightJson唯一的头文件
//嵌套结构体
struct TestJsonSub
{
 JSON_BEGIN()
 JSON_FIELD(bool, m_Bool);
 JSON_FIELD(int, m_int); 
 JSON_END();
};
//结构体
struct TestJsonC
{
 JSON_BEGIN()
 JSON_FIELD_KEY(long long, m_int64,"m_int\n64");
 JSON_FIELD(double, m_float);
 JSON_FIELD(std::string, m_str);
 JSON_FIELD(std::vector<int>, m_vect);
 JSON_FIELD(TestJsonSub, m_Sub);
 JSON_FIELD(int, m_int1);
 JSON_FIELD(int, m_int2);
 JSON_FIELD(int, m_int3);
 JSON_FIELD(int, m_int4);
 JSON_FIELD(int, m_int5);
 JSON_FIELD(std::vector<TestJsonSub>, m_vectSub);
 JSON_END();
};

使用JSON_FIELD宏定义的字段,字段名即是json的key,不支持转义符。而用JSON_FIELD_KEY宏定义的字段,可以用第三个参数指定json的key。同样该方式指定的key,只支持UTF8字符串和UTF16字符串。如果还不能满足需求,可以调用结构体的成员函数设置key,例如:

TestJsonC  objC;
objC.SetKey_m_float(LightJson::UTF8<>::FromString(L"aght有中文")); //设置m_float的key

  2) 像普通结构体一样赋值:

TestJsonC  objC;
 objC.m_int64 = 223356644;
 objC.m_float = 3.1415959;
 objC.m_str = LightJson::UTF8<>::FromString(L"aght有中文哦Json有转义\n\r\t哦!"); 
 for (int i = 0; i < 100; i++)
 {
  TestJsonSub sub;
  sub.m_Bool = i;
  sub.m_int = i;
  objC.m_vectSub.push_back(sub);
  objC.m_vect.push_back(i);
 }
 objC.m_Sub.m_Bool = true;
 objC.m_Sub.m_int = -12562213;
 objC.m_int1 = objC.m_int2 = objC.m_int3 = objC.m_int4 = objC.m_int5 = 2000;

3)序列化及反序列化:

std::string strJson = LightJson::JsonUtil::ToJsonString(objC1); //序列化
   
  TestJsonC objC2;
 //反序列化
  if (LightJson::JsonUtil::FromJsonString(objC2,strJson.data(),strJson.length()) == false)
  {
   return false;
  } 
  
  TestJsonC objC3; //模似使用,把反序化结果objC2的值取出来赋给objC3
  
  if (objC2.Have_m_int64()) //可以用调用成员函数判断该字段是否有赋值
  {
   objC3.m_int64 = objC2.m_int64;
  }
  if (objC2.Have_m_float())
  {   
   objC3.m_float = objC2.m_float ;
  }
  if (objC2.Have_m_str())
  {   
   objC3.m_str = objC2.m_str.c_str();
  }
  if (objC2.Have_m_Sub())
  {
   TestJsonSub & sub = objC2.m_Sub;
   if (sub.Have_m_Bool())
   {
    objC3.m_Sub.m_Bool = sub.m_Bool;
   }
   if (sub.Have_m_int())
   {
    objC3.m_Sub.m_int = sub.m_int;
   }
  }

三、LightJson源代码

#ifndef __LIGHTJSON_H__
#define __LIGHTJSON_H__
/***************************************************************************************************
转载请注明出处,作者联系方式:[email protected]
V 1.2
Date:2015-12-06
update:  
    1)对json标准的支持
 2)反序化后,可调用函数判断该字段是否有设置,不再读取std::bits
/////////////////////////////////////////////////////
V 1.1
Date:2015-12-02
update:浮点数指数部份可以是'e'以及'+'
*****************************************************************************************************/

#include <bitset>
#include<locale>
#include <codecvt>
#pragma warning(disable:4996)
#ifndef _FIELD_DEF_
#define _FIELD_DEF_
template <size_t size>
struct Int2Type
{
 enum { Value = size };
};
#define INT2TYPE(size) Int2Type<size>()
#define ARRAY(type,size) std::array<type,size>
#define FIELD_INDEX_BEGIN() enum {INDEX_BEGIN=__COUNTER__,};
#define FIELD_INDEX_END()   enum {INDEX_END=__COUNTER__,Size=INDEX_END-INDEX_BEGIN-1,};
#define AUTO_INDEX() (__COUNTER__-INDEX_BEGIN)
#define FIELD_BEGIN() FIELD_INDEX_BEGIN()
#define FIELD_END() FIELD_INDEX_END()
#define FIELD(type,name) FIELD_INDEX(AUTO_INDEX(),type,name)
#define FIELD_INDEX(index,type,name)  DEF_VALUE(type,name) GET_VALUE(index,type,name) GET_NAME(index,name)
#define DEF_VALUE(type,name) type name; 
#define GET_VALUE(index,type,name) type & getValue(Int2Type<index>){return name;} const type & getValue(Int2Type<index>) const {return name;}
#define GET_NAME(index,name) const char* getName(Int2Type<index>) const { return #name;}
template<typename T>
struct THaveLeghtField
{
 template<typename type>
 static char __is_field_struct(...);
 template<typename type>
 static int __is_field_struct(typename type::traits_type *);
 template<typename type>
 static int __is_field_struct(Int2Type<type::Size> *);
 enum { Value = (sizeof(__is_field_struct<T>(0)) == sizeof(int)) };
};

#endif
#define DEFINE_HAVE_FUNCTION(func_name) \
template<typename T, typename... Args>struct THave##func_name { private: \
 template<typename U> static auto Check(int) -> decltype(std::declval<U>().##func_name##(std::declval<Args>()...), std::true_type()); \
 template<typename U> static auto Check(...) -> decltype(std::false_type()); \
public:  enum { Value = std::is_same<decltype(Check<T>(0)), std::true_type>::value }; };
DEFINE_HAVE_FUNCTION(JsonParseCallBackFunction)
DEFINE_HAVE_FUNCTION(JsonFieldCallBackFunction)
DEFINE_HAVE_FUNCTION(JsonFieldGetKeyFunction)
DEFINE_HAVE_FUNCTION(JsonGetFieldBitsFunction)
namespace LightJson
{
class JsonUtil
{
public:
 template<typename type, typename Encoding = UTF8<>>
 static bool FromJsonString(type & value, const char* szJsonStr, int len = 0)
 {
  if (len == 0)
  {
   len = strlen(szJsonStr);
  }
  IJsonBuffer<Encoding>  ib(szJsonStr, len);
  if (ib.Read(value) == false)
  {
   return false;
  }
  return true;
 }
 template<typename type, typename Encoding = UTF8<>>
 static bool FromJsonString(type & value, const std::string & strJson)
 {  
  IJsonBuffer<Encoding>  ib(strJson.c_str(), strJson.length());
  if (ib.Read(value) == false)
  {
   return false;
  }
  return true;
 }
 template<typename type, typename Encoding = UTF8<>>
 static std::string ToJsonString(type & value)
 {
  OJsonBuffer<1024, Encoding> ob;
  if (ob.Write(value) == false)
  {
   return "";
  }
  return std::move(ob.ToString());
 }
};

#define Z8 0,0,0,0,0,0,0,0
static const bool IsSeparator[256] = {
 Z8,Z8,
 Z8,Z8,
 Z8,0,0,0,0,',',0,0,0,
 Z8,Z8,Z8,Z8,
 Z8, 0,0,0,0,0,']',0,0,Z8,Z8,
 Z8,0,0,0,0,0,'}',0,0,Z8,Z8,
 Z8,Z8,Z8,Z8,
 Z8,Z8,Z8,Z8,
 Z8,Z8,Z8,Z8,
 Z8,Z8
};
static const bool IsSpace[256] =
{
 Z8,0,'\t','\n',0, 0, '\r',0,0,
 Z8,Z8,
 ' ',0,0,0,0,0,0,0,Z8,
 Z8,Z8,Z8,Z8,
 Z8,Z8,Z8,Z8,
 Z8,Z8,Z8,Z8,
 Z8,Z8,Z8,Z8,
 Z8,Z8,Z8,Z8,
 Z8,Z8,Z8,Z8,
 Z8,Z8
};
 
static const bool IsFloat[256] =
{
 Z8,Z8,Z8,Z8,
 Z8,0,0,0,'+',0,'-','.',0,'0','1','2','3','4','5','6','7', '8','9',0,0,0,0,0,0,
 0,0,0,0,0,'E',0,0,Z8,Z8,Z8,
 0,0,0,0,0,'e',0,0,Z8,Z8,Z8,
 Z8,Z8,Z8,Z8,
 Z8,Z8,Z8,Z8,
 Z8,Z8,Z8,Z8,
 Z8,Z8,Z8,Z8
};
#undef Z8

static const char hexDigits[] = "0123456789ABCDEF";
static const char IsEscape[256] = {
#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
 //0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F
 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'b', 't', 'n', 'u', 'f', 'r', 'u', 'u', // 00
 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', // 10
 0,   0, '"',   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, // 20
 Z16, Z16,                  // 30~4F
 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,'\\',   0,   0,   0, // 50
 Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16        // 60~FF
#undef Z16
};
///////////////////////////////////////////////////////////////////////////////
// UTF8
//! UTF-8 encoding.
/*! http://en.wikipedia.org/wiki/UTF-8
\tparam CharType Type for storing 8-bit UTF-8 data. Default is char.
\implements Encoding
*/
template<typename CharType = char>
struct UTF8 {
 typedef CharType Ch;
 static std::string FromString(const char * src)
 {
  return src;
 }
 static std::string FromString(const wchar_t* src)
 {
     std::wstring_convert<std::codecvt_utf8<wchar_t>> convUtf8;    
     std::string str = convUtf8.to_bytes(src); 
     return std::move(str);
 }
 static Ch* Encode(Ch *buffer, unsigned codepoint) {
  if (codepoint <= 0x7F)
   *buffer++ = codepoint & 0xFF;
  else if (codepoint <= 0x7FF) {
   *buffer++ = 0xC0 | ((codepoint >> 6) & 0xFF);
   *buffer++ = 0x80 | ((codepoint & 0x3F));
  }
  else if (codepoint <= 0xFFFF) {
   *buffer++ = 0xE0 | ((codepoint >> 12) & 0xFF);
   *buffer++ = 0x80 | ((codepoint >> 6) & 0x3F);
   *buffer++ = 0x80 | (codepoint & 0x3F);
  }
  else {
   *buffer++ = 0xF0 | ((codepoint >> 18) & 0xFF);
   *buffer++ = 0x80 | ((codepoint >> 12) & 0x3F);
   *buffer++ = 0x80 | ((codepoint >> 6) & 0x3F);
   *buffer++ = 0x80 | (codepoint & 0x3F);
  }
  return buffer;
 }
};
///////////////////////////////////////////////////////////////////////////////
// UTF16
//! UTF-16 encoding.
/*! http://en.wikipedia.org/wiki/UTF-16
\tparam CharType Type for storing 16-bit UTF-16 data. Default is wchar_t. C++11 may use char16_t instead.
\implements Encoding
*/
template<typename CharType = wchar_t>
struct UTF16 {
 typedef CharType Ch;
  
 static std::string FromString(const char* src)
 {
  std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;
  std::wstring wstr = conv.from_bytes(src);
  std::string str;
  int len = wstr.length() * sizeof(wchar_t);
  str.resize(len);
  memcpy((void*)str.data(),wstr.data(),len);
  return std::move(str);
 }
 static std::string FromString(const wchar_t* src)
 {
  const wchar_t* ptr = src;
  int len = 0;
  while (ptr[len])
  {
   len++;
  }
  std::string str;
  str.resize(len*sizeof(wchar_t));
  memcpy((void*)str.data(), ptr, len*sizeof(wchar_t));
  return std::move(str);
 }
 static Ch* Encode(Ch* buffer, unsigned codepoint) {
  if (codepoint <= 0xFFFF) {
   *buffer++ = static_cast<Ch>(codepoint);
  }
  else {
   unsigned v = codepoint - 0x10000;
   *buffer++ = static_cast<Ch>((v >> 10) + 0xD800);
   *buffer++ = (v & 0x3FF) + 0xDC00;
  }
  return buffer;
 }
};
///////////////////////////////////////////////////////////////////////////////
// UTF32
//! UTF-32 encoding. 
/*! http://en.wikipedia.org/wiki/UTF-32
\tparam Ch Type for storing 32-bit UTF-32 data. Default is unsigned. C++11 may use char32_t instead.
\implements Encoding
*/
template<typename CharType = unsigned>
struct UTF32 {
 typedef CharType Ch;
 static std::string FromString(const char * src)
 {
  std::string str;
  int len = strlen(src) * sizeof(char32_t);
  str.resize(len);
  char32_t * ptr = (char32_t *)str.data();
  while (*src)
  {
   *ptr++ = *src++;
  }
  return std::move(str);
 }

 static std::string FromString(const char32_t* src)
 {
  const char32_t* ptr = src;
  int len = 0;
  while (ptr[len])
  {
   len++;
  }
  std::string str;
  str.resize(len*sizeof(char32_t));
  memcpy((void*)str.data(), ptr, len*sizeof(char32_t));
  return std::move(str);
 }
 static Ch *Encode(Ch* buffer, unsigned codepoint) {
  *buffer++ = codepoint;
  return buffer;
 }
};
template<size_t static_size,typename Encoding=UTF8<>>
class OJsonBuffer
{
   typedef typename Encoding::Ch Ch;
 
public:
 OJsonBuffer()
 {
  __Init();
 }
 explicit OJsonBuffer(char * pData, size_t len)
 {
  __Init();
  this->m_ptrBegin = this->m_ptrCur = (Ch*)pData;
  this->m_Size = len/sizeof(Ch);
 }
 //预分配容量
 explicit OJsonBuffer(size_t len)
 {
  __Init();
  if (len == 0)
  {
   len = 1024;
  }
  ResetCapacity(len);
 }
 //扩展内存
 bool ResetCapacity(size_t len)
 {
  int old_size = this->Size();
  if (old_size >= len)
  {
   return true;
  }
  if ((Ch*)m_strData.data() == m_ptrBegin)
  {
   m_strData.resize(len*sizeof(Ch));
  }
  else
  {
   m_strData.resize(len*sizeof(Ch));
   if (old_size > 0)
   {
    memcpy((char*)m_strData.data(), m_ptrBegin, old_size*sizeof(Ch));
   }
  }
  this->m_Size = len ;
  this->m_ptrBegin = (Ch*)m_strData.data();
  this->m_ptrCur = m_ptrBegin + old_size;
  return true;
 }
 
 ~OJsonBuffer()
 {
  __Init();
 }
 //复位
 void Reset()
 {
  m_bError = false;
  m_Size = 0;
  m_ptrCur = m_ptrBegin = NULL;
 }
 size_t GetStaticSize()
 {
  return static_size;
 }
 //返回从pos开始的内存
 const Ch * Buffer(size_t pos = 0) const
 {
  if (pos >= m_Size)
  {
   return nullptr;
  }
  return m_ptrBegin + pos;
 }
 Ch * CurrentBuffer()
 {
  return m_ptrCur;
 }
 
 //获得数据大小
 size_t Size() const
 {
  return m_ptrCur - m_ptrBegin;
 }
 //当前容量
 size_t Capacity() const
 {
  return m_Size;
 }
 //余下空间
 size_t Remain() const
 {
  return m_Size - (m_ptrCur - m_ptrBegin);
 }
 bool IsStaticBuffer()
 {
  return m_ptrCur == this->m_static_data;
 }
 //注意:内存所有权会转移
 std::vector<char> TakeData()
 {
  std::vector<char> vect;
  int  len = (m_ptrCur - m_ptrBegin)*sizeof(Ch);
  vect.resize(len);
  memcpy(vect.data(), m_ptrBegin, len);
  return std::move(vect);
 }
 std::string ToString()
 {
  Ch * ptr = m_ptrCur;
  //*ptr = 0;
  if (m_ptrBegin == m_strData.data())
  {   
   m_strData.resize((ptr - m_ptrBegin)*sizeof(Ch));
   return std::move(m_strData);
  }
  else
  {
   std::string str;
   str.resize((ptr - m_ptrBegin)*sizeof(Ch));
   memcpy((void*)str.data(), m_ptrBegin, (ptr - m_ptrBegin)*sizeof(Ch));
   return std::move(str);
  }
 }
 
 //是否产生了错误
 bool Error() const
 {
  return m_bError;
 }
 template< typename type> int Write(type & obj)
 {
  int byte_size = ByteSize(obj);
  if (byte_size+1 <= static_size/sizeof(Ch))
  {
   this->m_ptrBegin = this->m_ptrCur = (Ch*)this->m_static_data;
   this->m_Size = static_size/sizeof(Ch);   
  }
  else
  {
   this->ResetCapacity(byte_size+1);
  }
  Write(obj, Int2Type<type::Size>());
  return byte_size;
  
 }
 template< typename type> bool Write(type & obj, Int2Type<0> ind)
 {
  *this->m_ptrCur++ = '{';
  return true;
 }
 template<int size, typename type> bool Write(type & obj, Int2Type<size> ind)
 {
  if (Write(obj, Int2Type<size - 1>()) == false)
  {
   return false;
  }    
  std::string & strKey = obj.JsonFieldGetKeyFunction(ind, Encoding());
  Write(obj.getValue(ind), (const Ch*)strKey.data(), size==1);
  if (size == type::Size)
  {
   *this->m_ptrCur++ = '}';
  }
  return this->Error() == false;
 }

 /////////////////////////////////////////////////
 template<typename ValueType>
 void Write(ValueType & obj,const Ch * szKey,bool bFirst)
 {
  WriteKey(szKey, bFirst);    
  Write(obj, Int2Type<ValueType::Size>());
 }
 
 void Write(char  obj, const Ch * szKey, bool bFirst)
 {
  WriteKey(szKey, bFirst);
  WriteInt32((int)obj);
 }
 void Write(unsigned char  obj, const Ch * szKey, bool bFirst)
 {
  WriteKey(szKey, bFirst);
  WriteInt32((unsigned int)obj);
 }
 void Write(short  obj, const Ch * szKey, bool bFirst)
 {
  WriteKey(szKey, bFirst);
  WriteInt32((int)obj);
 }
 void Write(unsigned short  obj, const Ch * szKey, bool bFirst)
 {
  WriteKey(szKey, bFirst);
  WriteInt32((unsigned int)obj);
 }
 void Write(int  obj, const Ch * szKey, bool bFirst)
 {
  WriteKey(szKey, bFirst);
  WriteInt32(obj);
 }
 void Write(unsigned int  obj, const Ch * szKey, bool bFirst)
 {
  WriteKey(szKey, bFirst);
  WriteInt32(obj);
 }
 void Write(long  obj, const Ch * szKey, bool bFirst)
 {
  WriteKey(szKey, bFirst);
  WriteInt32((int)obj);
 }
 void Write(unsigned long  obj, const Ch * szKey, bool bFirst)
 {
  WriteKey(szKey, bFirst);
  WriteInt32((unsigned int)obj);
 }
 
 void Write(long long  obj, const Ch * szKey, bool bFirst)
 {
  WriteKey(szKey, bFirst);
  WriteInt64(obj);
 }
 void Write(unsigned long long  obj, const Ch * szKey, bool bFirst)
 {
  WriteKey(szKey, bFirst);
  WriteInt64((long long)obj);
 }
 
 void Write(bool  obj, const Ch * szKey, bool bFirst)
 {
  WriteKey(szKey, bFirst);
  WriteBool(obj);
 }
 void Write(float  obj, const Ch * szKey, bool bFirst)
 {
  WriteKey(szKey, bFirst);
  WriteFloat(obj);
 }
 void Write(double  obj, const Ch * szKey, bool bFirst)
 {
  WriteKey(szKey, bFirst);
  WriteDouble(obj);
 }
 void Write(const Ch*  obj, const Ch * szKey, bool bFirst)
 {
  WriteKey(szKey, bFirst);
  WriteStr(obj);
 }
 void Write( Ch*  obj, const Ch * szKey, bool bFirst)
 {
  WriteKey(szKey, bFirst);
  WriteStr(obj);
 }
 void Write(const std::string &  obj, const Ch * szKey, bool bFirst)
 {
  WriteKey(szKey, bFirst);
  WriteStr((const Ch*)obj.data());
 }
 void Write( std::string &  obj, const Ch * szKey, bool bFirst)
 {
  WriteKey(szKey, bFirst);
  WriteStr((const Ch*)obj.data());
 }
 template<typename type>
 void Write(std::vector<type> & obj, const Ch * szKey, bool bFirst)
 {
  int obj_len = obj.size();
    
  WriteKey(szKey, bFirst);
 
  *this->m_ptrCur++ = '[';
  for (int i = 0; i < obj_len;i++)
  {
    Write(obj[i], NULL,i==0);
  }
  *this->m_ptrCur++ = ']';
 }
 template<typename type>
 void Write(const std::vector<type> & obj, const Ch* szKey, bool bFirst)
 {
  int obj_len = obj.size();
  
  WriteKey(szKey, bFirst);
  *this->m_ptrCur++ = '[';
  for (int i = 0; i < obj_len;i++)
  {
   Write(obj[i], NULL, i == 0);
  }
  *this->m_ptrCur++ = ']';
 }
 
private:
 //push二进制内存
 void Push(const void* pData, int len)
 {
  memcpy(this->m_ptrCur, pData, len);
  this->m_ptrCur += len / sizeof(Ch);
 }
 //写整数
 void WriteInt32(int value)
 {
  unsigned int v;
  if (value < 0)
  {
   *m_ptrCur++ = '-';
   v = 0 - value;
  }
  else
  {
   v = value;
  }
  int len = ByteSize(v);
  m_ptrCur = m_ptrCur + len;
  Ch * ptr = m_ptrCur;
  do
  {
   *(--ptr) = '0' + v % 10;
   v /= 10;
  } while (v>0);
 }
 void WriteInt32(unsigned int value)
 {
  int len = ByteSize(value);
  m_ptrCur = m_ptrCur + len;
  Ch * ptr = m_ptrCur;
  do
  {
   *(--ptr) = '0' + value % 10;
   value /= 10;
  } while (value>0);
 }
 //写整数
 void WriteInt64(long long value)
 {
  unsigned long long v;
  if (value < 0)
  {
   *m_ptrCur++ = '-';
   v = 0 - value;
  }
  else
  {
   v = value;
  }
  int len = ByteSize(v);
  m_ptrCur = m_ptrCur + len;
  Ch * ptr = m_ptrCur;
  do
  {
   *(--ptr) = '0' + v % 10;
   v /= 10;
  } while (v>0);
 }
 //写bool
 void WriteBool(bool value)
 {
  if (value)
  {
   m_ptrCur[0] = 't';
   m_ptrCur[1] = 'r';
   m_ptrCur[2] = 'u';
   m_ptrCur[3] = 'e';
   m_ptrCur += 4;
  }
  else
  {
   m_ptrCur[0] = 'f';
   m_ptrCur[1] = 'a';
   m_ptrCur[2] = 'l';
   m_ptrCur[3] = 's';
   m_ptrCur[4] = 'e';
   m_ptrCur += 5;
  }
 }
 //写float
 void WriteFloat(float value)
 {
  WriteDouble(value);
 }
 //写double
 void WriteDouble(double value)
 {
  char buffer[100];
#if _MSC_VER
  int ret = sprintf_s(buffer, sizeof(buffer), "%g", value);
#else
  int ret = snprintf(buffer, sizeof(buffer), "%g", value);
#endif
  for (int i = 0;i<ret;i++)
  {
   m_ptrCur[i] = buffer[i];
  }
  m_ptrCur += ret;
 }
 //写str
 void WriteStr(const Ch* value)
 {
  *this->m_ptrCur++ = '\"';
  for (const Ch* p = value; *p != '\0'; ++p) {
   if ((sizeof(Ch) == 1 || *p < 256) && IsEscape[(unsigned char)*p]) {
    *this->m_ptrCur++ = '\\';
    *this->m_ptrCur++ = (IsEscape[(unsigned char)*p]);
    if (IsEscape[(unsigned char)*p] == 'u') {
     *this->m_ptrCur++ = ('0');
     *this->m_ptrCur++ = ('0');
     *this->m_ptrCur++ = (hexDigits[(*p) >> 4]);
     *this->m_ptrCur++ = (hexDigits[(*p) & 0xF]);
    }
   }
   else
    *this->m_ptrCur++ = (*p);
  }
  *this->m_ptrCur++ = '\"';
 }
 int ByteSize(const Ch * szData)
 {
  int len = 2;
  for (const Ch* p = szData; *p != '\0'; ++p) {
   if ((sizeof(Ch) == 1 || *p < 256) && IsEscape[(unsigned char)*p]) {
    if (IsEscape[(unsigned char)*p] == 'u') {
     len += 6;
    }
    else
    {
     len += 2;
    }
   }
   else
    len++;
  }
  return len;
 }

 int ByteSize(const std::string & str)
 {
  if (str.empty())
  {
   return 2;
  }
  return ByteSize((const Ch*)str.data());
 }

 int ByteSize(std::string & str)
 {
  if (str.empty())
  {
   return 2;
  }
  return ByteSize((const Ch*)str.data());
 }
 int ByteSize(bool v)
 {
  if (v)
  {
   return 4;
  }
  else
  {
   return 5;
  }
 }
 int ByteSize(float v)
 {
  return ByteSize((double)v);
 }
 int ByteSize(double v)
 {
  char buffer[100];
#if _MSC_VER
  int ret = sprintf_s(buffer, sizeof(buffer), "%g", v);
#else
  int ret = snprintf(buffer, sizeof(buffer), "%g", v);
#endif
  return ret;
 }
 int ByteSize(int v)
 {
  if (v < 0)
  {
   unsigned int value = 0 - v;
   return ByteSize(value) + 1;
  }
  else
  {
   return ByteSize((unsigned int)v);
  }
 }
 int ByteSize(unsigned  int value)
 {
  if (value < 100000) //5位
  {
   if (value < 100) //2位
   {
    if (value < 10)
    {
     return 1;
    }
    else
    {
     return 2;
    }
   }
   else if (value < 1000)
   {
    return 3;
   }
   else if (value < 10000)
   {
    return 4;
   }
   else
   {
    return 5;
   }
  }
  else
  {
   if (value < 10000000) //7位
   {
    if (value < 1000000)
    {
     return 6;
    }
    else
    {
     return 7;
    }
   }
   else if (value < 100000000)
   {
    return 8;
   }
   else if (value < 1000000000)
   {
    return 9;
   }
   else
   {
    return 10;
   }
  }
 }

 int ByteSize(long long v)
 {
  if (v < 0)
  {
   unsigned long long value = 0 - v;
   return ByteSize(value) + 1;
  }
  else
  {
   return ByteSize((unsigned long long)v);
  }
 }

 int ByteSize(unsigned long long value)
 {
  if (value < 10000000000) //10位
  {
   if (value < 100000) //5位
   {
    if (value < 100) //2位
    {
     if (value < 10)
     {
      return 1;
     }
     else
     {
      return 2;
     }
    }
    else if (value < 1000)
    {
     return 3;
    }
    else if (value < 10000)
    {
     return 4;
    }
    else
    {
     return 5;
    }
   }
   else
   {
    if (value < 10000000) //7位
    {
     if (value < 1000000)
     {
      return 6;
     }
     else
     {
      return 7;
     }
    }
    else if (value < 100000000)
    {
     return 8;
    }
    else if (value < 1000000000)
    {
     return 9;
    }
    else
    {
     return 10;
    }
   }
  }
  else
  {
   if (value < 1000000000000000) //15位
   {
    if (value < 1000000000000) //12位
    {
     if (value < 100000000000)
     {
      return 11;
     }
     else
     {
      return 12;
     }
    }
    else if (value < 10000000000000)
    {
     return 13;
    }
    else if (value < 100000000000000)
    {
     return 14;
    }
    else
    {
     return 15;
    }
   }
   else
   {
    if (value < 100000000000000000) //17位
    {
     if (value < 10000000000000000)
     {
      return 16;
     }
     else
     {
      return 17;
     }
    }
    else if (value < 1000000000000000000)
    {
     return 18;
    }
    else if (value < 10000000000000000000)
    {
     return 19;
    }
    else
    {
     return 20;
    }
   }
  }
 }

 template< typename type> int ByteSize(type & obj)
 {
  return ByteSize(obj, Int2Type<type::Size>());
 }
 template< typename type> int ByteSize(std::vector<type> & obj)
 {
  int size = obj.size();
  int len = size + 2;
  if (size > 0)
  {
   len--;
  }
  for (int i = 0; i < size;i++)
  {
   len += ByteSize(obj[i]);
  }
  return len;
 }
 template< typename type> int ByteSize(const std::vector<type> & obj)
 {
  int size = obj.size();
  int len = size + 2;
  if (size > 0)
  {
   len--;
  }
  for (int i = 0; i < size;i++)
  {
   len += ByteSize(obj[i]);
  }
  return len;
 }
 template< typename type> int ByteSize(type & obj, Int2Type<0> ind)
 {
  return 1;
 }
 template<int size, typename type> int ByteSize(type & obj, Int2Type<size> ind)
 {
  int len = ByteSize(obj, Int2Type<size - 1>());
  if (size >1)
  {
   len++; //,号
  }
  len += ByteSize(obj.JsonFieldGetKeyFunction(ind, Encoding())) + 1; //加分号

  len += ByteSize(obj.getValue(ind));
  if (size == type::Size)
  {
   len++;
  }
  return len;
 }
 
 void WriteKey(const Ch* szKey, bool bFirst)
 {
  if (bFirst == false)
  {
   *this->m_ptrCur++ = ',';
  }
  if (szKey)
  {
   WriteStr(szKey);
   *this->m_ptrCur++ = ':';
  }  
 }
   
private:
 OJsonBuffer(const OJsonBuffer& Other) = delete;
 OJsonBuffer & operator =(const OJsonBuffer&) = delete;
private:
 //初始化
 void __Init()
 {
  m_Size = 0;
  m_ptrCur = m_ptrBegin = NULL;
  m_bError = false;
 }
private:
 char m_static_data[static_size];
 std::string m_strData;
 int m_Size;
 Ch* m_ptrCur;
 Ch* m_ptrBegin;
 bool           m_bError;   //是否产生了错误
};
 
template<typename CharType>
class TReader
{
 const CharType * m_pBegin;  //有效数据
 const CharType * m_pData;  //有效数据
 const CharType * m_pEnd;  //有效数据 
public:
 TReader()
 {
  m_pBegin = m_pData = m_pEnd = NULL;
 }
 TReader(const CharType * pData,int len=0)
 {
  m_pBegin = m_pData = pData;
  if (len > 0)
  {
   m_pEnd = m_pBegin + len;
  }
  else
  {
   m_pEnd = m_pBegin + INT_MAX;
  }
 }
 void Init(const CharType * pData, int len = 0)
 {
  m_pBegin = m_pData = pData;
  if (len > 0)
  {
   m_pEnd = m_pBegin + len;
  }
  else
  {
   m_pEnd = m_pBegin + INT_MAX;
  }
 }
 CharType Peek() {
  return *m_pData;
 }
 CharType Take() {
  if(m_pData<m_pEnd)
   return *m_pData++;
  return CharType(0);
 }
 const CharType * Current()
 {
  return m_pData;
 }
private:
};
//输入Buffer
template<typename Encoding>
class IJsonBuffer
{ 
 typedef typename Encoding::Ch Ch;
 
public:
 
 IJsonBuffer(const char* pData, int len) : m_Reader((const Ch *)pData,len/sizeof(Ch))
 {
  m_bError = false;
 }
 IJsonBuffer(const std::vector<char> & vectData) : m_Reader((const Ch *)vectData.data(), vectData.size())
 {    
  m_bError = false;
 }
 
 ~IJsonBuffer()
 {  
  m_bError = false;
 }

 //是否产生了错误
 bool Error() { return m_bError; }
    
  //读取
 template<typename type>
 bool Read(type & value, const Ch * pKey=NULL, int len=0)
 {
  Ch ch = SkipSpace();
  if (ch != '{')
  {
   if (ch == 'n')
   { 
    if (ReadNullValue()==false)
    {
     return false;
    }
    value = type();
    return true;
   }
   return false;
  }
   ch = SkipSpace();
  if (ch == '}')
  {  
   return true;
  }
 
  do
  {
   if (ch != '\"')
   {
    return false;
   }
   
   const Ch * pKey = NULL;
   int key_len = 0;
   std::string strKey;
   bool bEscape = false;
   if (this->ReadString(pKey, key_len, bEscape, strKey) == NULL)
   {
    return false;
   }
   
   if (bEscape)
   {
    pKey = (const Ch*)strKey.data();
   }
     
   ch = this->SkipSpace();
   if (ch != ':')
   {
    return false;
   }
     
   if (CallJsonCallBack(value, pKey, key_len,Int2Type<THaveJsonParseCallBackFunction<type, IJsonBuffer &, const char*, int>::Value>()) == false)
   {
    m_bError = true;
    return false;
   }
   ch = SkipSpace();
   if (ch == '}')
   {
    break;
   }
   else if (ch != ',')
   {
    m_bError = true;
    return false;
   }
   ch = SkipSpace();
  } while (true);
    
  return this->m_bError == false;
 }
 
 bool Read(bool & value, const Ch * pKey=NULL, int len = 0)
 {
  value = false;
  Ch ch = SkipSpace();
  if (ch == 't')
  {   
   if (ReadTrueValue()==false)
   {
    return false;
   }
   
   value = true;
  }
  else if (ch == 'f')
  {   
   if (ReadFalseValue()==false)
   {
    return false;
   }
  
   value = false;
  }
  else if (ch == 'n')
  {
   if (ReadNullValue()==false)
   {
    return false;
   }
   
   value = false;
  }
      
  return true;
 }
 bool Read(char & value, const Ch* pKey = NULL, int len = 0)
 {
  long long ll = 0;
  if (ReadNumber(ll) == false) { return false; }
  value = ll;
  return true;
 }
 bool Read(unsigned char & value, const Ch* pKey = NULL, int len = 0)
 {
  long long ll = 0;
  if (ReadNumber(ll) == false) { return false; }
  value = ll;
  return true;
 }
 bool Read(short & value, const Ch* pKey = NULL, int len = 0)
 {
  long long ll = 0;
  if (ReadNumber(ll) == false) { return false; }
  value = ll;
  return true;
 }
 bool Read(unsigned short & value, const Ch* pKey = NULL, int len = 0)
 {
  long long ll = 0;
  if (ReadNumber(ll) == false) { return false; }
  value = ll;
  return true;
 }
 bool Read(int & value, const Ch* pKey = NULL, int len = 0)
 {
  long long ll = 0;
  if (ReadNumber(ll) == false){return false;}
  value = ll;
  return true;
 }
 bool Read(unsigned int & value, const Ch* pKey = NULL, int len = 0)
 {
  long long ll = 0;
  if (ReadNumber(ll) == false) { return false; }
  value = ll;
  return true;
 }
 bool Read(long  & value, const Ch* pKey = NULL, int len = 0)
 {
  long long ll = 0;
  if (ReadNumber(ll) == false) { return false; }
  value = ll;
  return true;
 }
 bool Read(unsigned long & value, const Ch* pKey = NULL, int len = 0)
 {
  long long ll = 0;
  if (ReadNumber(ll) == false) { return false; }
  value = ll;
  return true;
 }
 bool Read( long long & value, const Ch* pKey = NULL, int len = 0)
 {
  long long ll = 0;
  if (ReadNumber(ll) == false) { return false; }
  value = ll;
  return true;
 }
 bool Read(unsigned long long & value, const Ch* pKey = NULL, int len = 0)
 {
  long long ll = 0;
  if (ReadNumber(ll) == false) { return false; }
  value = ll;
  return true;
 }
 bool Read(float & value, const Ch* pKey = NULL, int len = 0)
 {
  char buff[100];
  int i = 0;
  Ch ch = this->SkipSpace();
  if ((ch >= '0'&&ch <= '9')      
   || ch == '-')
  {
   buff[i++] = ch;
  }
  else if (ch == 'n')
  {
   if (ReadNullValue()==false)
   {
    return false;
   }      
   value = 0;
   return true;
  }
  else
  {
   return false;
  }
  unsigned char uch;
  while (((uch = (unsigned char)this->m_Reader.Peek())!=0)&& i<sizeof(buff))
  {   
   if (IsFloat[uch])
   {
    buff[i++] = uch;
   }   
   else if(IsSeparator[uch])
   {
    break;
   }
   
   this->m_Reader.Take();
  }
  buff[i++] = 0;
  value = std::atof(buff);
  return true;
 }
 
 bool Read(double & value, const Ch* pKey = NULL, int len = 0)
 {
  char buff[100];
  int i = 0;
  Ch ch = this->SkipSpace();
  if ((ch >= '0'&&ch <= '9')
   || ch == '-')
  {
   buff[i++] = ch;
  }
  else if (ch == 'n')
  {   
   if (ReadNullValue()==false )
   {
    return false;
   }
      
   value = 0;
   return true;
  }
  else
  {
   return false;
  }
  unsigned char uch;
  while (((uch= this->m_Reader.Peek())!=0) && i<sizeof(buff))
  {
   if (IsFloat[uch])
   {
    buff[i++] = uch;
   }
   else if (IsSeparator[uch])
   {    
    break;
   }
   
   this->m_Reader.Take();
  } 
   
  buff[i++] = 0;
  value = std::atof(buff);
  return true;
 }
 bool Read(std::string & value, const Ch* pKey = NULL, int len = 0)
 {
  Ch ch = this->SkipSpace();
  
  if (ch != '\"')
  {
    if (ch == 'n')
   {
   if (ReadNullValue()==false)
   {
    return false;
   }
      
   value = "";
   return true;
    }
   return false;
  }
 
  int lenStr = 0;
  bool bEscape = false;
  const Ch* ptr = NULL;
  if (ReadString(ptr, lenStr, bEscape,value) == false)
  {
   return false;
  }
  if (bEscape==false)
  {
   value.resize(lenStr*sizeof(Ch));
   memcpy((void*)value.data(),ptr, lenStr*sizeof(Ch));
  }
  return true;
 }
  
 template<typename type>
 bool Read(std::vector<type> & value, const Ch* pKey = NULL, int len = 0)
 {
  Ch ch = this->SkipSpace();
  if (ch != '[')
  {
   if (ch == 'n')
   {
    if (ReadNullValue()==false)
    {
     return false;
    }
         
    return true;
   }
   return false;
  }
    
  if (this->m_Reader.Peek() == ']')
  {
   this->m_Reader.Take();
   return true;
  }
 
  do
  {
   value.push_back(type());
   if (Read(value.back(), pKey,len) == false)
   {
    value.resize(value.size()-1);
    return false;
   }
   
   ch = this->SkipSpace();
   if (ch == ']')
   {
    break;
   }
   else if (ch != ',')
   {
    return false;
   }
  } while (true);
  
  return true;
 }
 template< typename type>
 bool ReadField(type & value, const Ch* pKey , int len )
 {
  return ReadField(value, Int2Type<1>(), pKey, len);;
 }
 template<int index, typename type>
 bool ReadField(type & value, Int2Type<index> ind,const Ch* pKey, int len  )
 {
  if (CompareKey(value, ind,pKey,len)==true)
  {
   return CallJsonFieldCallBack(value, ind,pKey, len);
  }
  return ReadField<index + 1, type>(value, Int2Type<index + 1>(), pKey, len );;
 }
 template<int index, typename type>
 bool ReadField(type & value, Int2Type<type::Size+1> ind, const Ch* pKey, int len)
 {
  return ReadUnknowField(value, pKey, len);
 }
  
 template<typename type>
 bool ReadUnknowField(type & value,const Ch* pKey, int len)
 {
  //json中多出来的字段,需要处理
  Ch ch = SkipSpace();
  switch (ch)
  {
  case '{': //处理对象
  {
   int braces = 1; //大括号数量
   while (0 != (ch= this->m_Reader.Take()))
   {  
    if (ch == '}')
    {     
     braces--;
     if (braces == 0)
     {
      return true;
     }
    }
    else if (ch == '{')
    {     
     braces++;
    }
    else if (ch == '\"')
    {     
     const Ch * pEscapeBegin = false;
     const Ch * ptr = this->FindQuotation(pEscapeBegin);
     if (ptr == NULL)
     {
      return false;
     }
    }    
   }
   return false;
  }
  break;
  case '[': //处理数组
  {
   int braces = 1; //大括号数量
   while (0 != (ch = this->m_Reader.Take()))
   {   
    if (ch == ']')
    {
    
     braces--;
     if (braces == 0)
     {
      return true;
     }
    }
    else if (ch == '[')
    {
     
     braces++;
    }
    else if (ch == '\"')
    {
     const Ch * pEscapeBegin = false;
     const Ch * ptr = this->FindQuotation(pEscapeBegin);
     
     if (ptr == NULL)
     {
      return false;
     }
    }    
   }
   return false;
  }
  break;
  case '\"': //处理字符串
  {
   const Ch * pEscapeBegin = false;
   const Ch * ptr = this->FindQuotation(pEscapeBegin);
   if (ptr == NULL)
   {
    break;
   }
  }
  break;
  case 'n': //处理null值
  {
   if (ReadNullValue()==false)
   {
    return false;
   }
  }
  break;
  case 't': //处理true值
  {
   if (ReadTrueValue()==false)
   {
    return false;
   }
  }
  break;
  case 'f': //处理false
  {
   if (ReadFalseValue()==false )
   {
    return false;
   }
  }
  break;
  default:
   if (ch >= '0'&& ch <= '9' || ch == '-')
   {
    unsigned char uch;
    while (0 != (uch = this->m_Reader.Peek()))
    {  
     if (IsFloat[uch])
     {       
      this->m_Reader.Take();      
     }
     else if (IsSeparator[uch])
     {
      return true;
     }
     else
     {
      return false;
     }
    }
    return true;
   }
   else
   {
    return false;
   }
   break;
  }
  return true;
 }
private:
 char SkipSpace()
 {
  while (true)
  {
   Ch ch = m_Reader.Take();
   if (!IsSpace[(unsigned char)ch])
   {
    return ch;
   }
  }
  return 0;
 }
 unsigned ParseHex4(const Ch * & stream) {
  const Ch * s = stream;
  unsigned codepoint = 0;
  for (int i = 0; i < 4; i++) {
   Ch c = *s++;
   codepoint <<= 4;
   codepoint += c;
   if (c >= '0' && c <= '9')
    codepoint -= '0';
   else if (c >= 'A' && c <= 'F')
    codepoint -= 'A' - 10;
   else if (c >= 'a' && c <= 'f')
    codepoint -= 'a' - 10;
   else
    return 0;
  }
  return codepoint;
 }
 const Ch * FindQuotation(const Ch* & pEscapeBein)
 {
  Ch ch;
  while (0 != (ch = this->m_Reader.Take()))
  {
   if (ch == '\\')
   {
    pEscapeBein = this->m_Reader.Current() - 1;
    if (this->m_Reader.Take() == 0)
    {
     return 0;
    }
    while (0 != (ch = this->m_Reader.Take()))
    {
     if (ch == '\\')
     {
      if (this->m_Reader.Take() == 0)
      {
       return 0;
      }
     }
     else if (ch == '"')
     {
      const Ch * ptr = m_Reader.Current();
      return --ptr;
     }
    }
    return 0;
   }
   else if (ch == '"')
   {
    const Ch * ptr = m_Reader.Current();
    return --ptr;
   }
  }
  return 0;
 }
 bool ReadString(const Ch * & pBegin, int & len, bool & bIncludeEscape, std::string & str)
 {
#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  static const char IsEscape[256] = {
   Z16, Z16, 0, 0,'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'/',
   Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0,
   0, 0,'\b', 0, 0, 0,'\f', 0, 0, 0, 0, 0, 0, 0,'\n', 0,
   0, 0,'\r', 0,'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16
  };
#undef Z16
 
  pBegin = this->m_Reader.Current();
  const Ch* pEscapeBegin = NULL;
  const Ch* pEnd = this->FindQuotation(pEscapeBegin);
  if (pEnd == NULL)
  {
   return false;
  }
  if (pEscapeBegin == NULL)
  {
   bIncludeEscape = false;
   len = pEnd - pBegin;
  }
  else
  {
   bIncludeEscape = true;
   str.resize((pEnd - pBegin)*sizeof(Ch));
   len = pEscapeBegin - pBegin;
   if (len > 0)
   {
    memcpy((void*)str.data(), pBegin, len*sizeof(Ch));
   }
   Ch * pData = (Ch*)(str.data());
   while (pEscapeBegin<pEnd)
   {
    Ch ch = *pEscapeBegin++;
    if (ch == '\\')
    {
     Ch e = *pEscapeBegin++;
     if ((sizeof(Ch) == 1 || e < 256) && IsEscape[(unsigned char)e])
      pData[len++] = IsEscape[(unsigned char)e];
     else if (e == 'u') { // Unicode
      unsigned int codepoint = ParseHex4(pEscapeBegin);
      if (codepoint >= 0xD800 && codepoint <= 0xDBFF) { // Handle UTF-16 surrogate pair
       if (*pEscapeBegin++ != '\\' || *pEscapeBegin++ != 'u') {
        return false;
       }
       unsigned codepoint2 = ParseHex4(pEscapeBegin);
       if (codepoint2 < 0xDC00 || codepoint2 > 0xDFFF) {
        return false;
       }
       codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000;
      }

      //计算剩
      Ch buffer[4];
      size_t count = size_t(Encoding::Encode(buffer, codepoint) - &buffer[0]);
      memcpy(&pData[len], buffer, count * sizeof(Ch));
      len += count;
     }
     else {
      return false;
     }
    }
    else if ((unsigned)ch < 0x20)
    {
     return false;
    }
    else
    {
     pData[len++] = ch;
    }
   }
   str.resize((len)*sizeof(Ch));
  }

  return true;
 }
 template<typename type>
 bool CallJsonCallBack(type & value, const Ch * pKey, int key_len, Int2Type<0> noHaveJsonCallBackFunction)
 {
  return ReadField(value, Int2Type<1>(), pKey, key_len);
 }
 template<typename type>
 bool CallJsonCallBack(type & value, const Ch * pKey, int key_len, Int2Type<1> haveJsonCallBackFunction)
 {
  return value.JsonParseCallBackFunction(*this, pKey, key_len);
 }
 bool ReadNullValue()
 {
  if (this->m_Reader.Take() != 'u'
   || this->m_Reader.Take() != 'l'
   || this->m_Reader.Take() != 'l'
   )
  {
   return false;
  }
  return true;
 }
 bool ReadTrueValue()
 {
  if (this->m_Reader.Take() != 'r'
   || this->m_Reader.Take() != 'u'
   || this->m_Reader.Take() != 'e'
   )
  {
   return false;
  }
  return true;
 }
 bool ReadFalseValue()
 {
  if (this->m_Reader.Take() != 'a'
   || this->m_Reader.Take() != 'l'
   || this->m_Reader.Take() != 's'
   || this->m_Reader.Take() != 'e'
   )
  {
   return false;
  }
  return true;
 }
 template<int index, typename type>
 bool CompareKey(type & value, Int2Type<index> ind, const Ch* pKey, int len)
 {
  if (HavedSet(value, ind))
  {
   return false;
  }
  if (CompareKeyHelper(value, ind, pKey, len, Int2Type<THaveJsonFieldGetKeyFunction<type, Int2Type<index>, Encoding&>::Value>()) == true)
  {
   return true;
  }
  return false;
 }
 template<int index, typename type>
 bool HavedSet(type & value, Int2Type<index> ind)
 {
  return HavedSetHelper(value, ind, Int2Type<THaveJsonGetFieldBitsFunction<type>::Value>());
 }
 template<int index, typename type>
 bool HavedSetHelper(type & value, Int2Type<index> ind, Int2Type<false> bNoHaveJsonGetFieldBitsFunction)
 {
  return false;
 }
 template<int index, typename type>
 bool HavedSetHelper(type & value, Int2Type<index> ind, Int2Type<true> bHaveJsonGetFieldBitsFunction)
 {
  return value.JsonGetFieldBitsFunction()[index];
 }
 template<int index, typename type>
 bool CompareKeyHelper(type & value, Int2Type<index> ind, const Ch* pKey, int len, Int2Type<false> bNoHaveGetKeyFunction)
 {
  if (strncmp(value.getName(ind), pKey, len) == 0)
  {
   return true;
  }
  return false;
 }
 template<int index, typename type>
 bool CompareKeyHelper(type & value, Int2Type<index> ind, const Ch* pKey, int len, Int2Type<true> bHaveGetKeyFunction)
 {
  std::string & strKey = value.JsonFieldGetKeyFunction(ind, Encoding());
  if (strKey.length() == len*sizeof(Ch) && memcmp(strKey.data(), pKey, len*sizeof(Ch)) == 0)
  {
   return true;
  }
  return false;
 }
 template<typename type, int index>
 bool CallJsonFieldCallBack(type & value, Int2Type<index> ind,const Ch* pKey, int key_len)
 {
  return CallJsonFieldCallBackHelper(value,ind,pKey, key_len, Int2Type<THaveJsonFieldCallBackFunction<type, IJsonBuffer &, const Ch*, int, Int2Type<index> >::Value>());
 }
 template<typename type,int index>
 bool CallJsonFieldCallBackHelper(type & value,  Int2Type<index> ind ,const Ch* pKey, int key_len, Int2Type<0> noHaveJsonFieldCallBackFunction)
 {
  return Read(value.getValue(ind), pKey, key_len);
 }
 template<typename type, int index>
 bool CallJsonFieldCallBackHelper(type & value, Int2Type<index> ind, const Ch* pKey, int key_len, Int2Type<1> haveJsonFieldCallBackFunction)
 {
  return value.JsonFieldCallBackFunction(*this, pKey, key_len, ind);
 }
   
 bool ReadNumber(long long & value)
 {  
  long long obj = 0;
  bool bNegative = false;
  Ch ch = this->SkipSpace();
  if (ch == '-')
  {
   bNegative = true;   
  }
  else  if (ch == 'n')
  {
   if (ReadNullValue()==false)
   {
    return false;
   }   
   value = 0;
   return true;
  }
  else
  {
   obj = ch - '0';
  }
    
  unsigned char uch;
  while (0 != (uch = this->m_Reader.Peek()))
  {    
   if (uch >= '0' && uch <= '9')
   {
    obj = obj * 10 + uch - '0';
   }
   else if (IsSeparator[uch])
   {
    break;
   }
  
   this->m_Reader.Take();
  }
  if (bNegative)
  {
   value = 0 - obj;
  }
  else
  {
   value = obj;
  }
  return true;
 }
private:
 TReader<Ch> m_Reader;
 const char * m_pBegin;  //有效数据
 const char * m_pData;  //有效数据
 const char * m_pEnd;  //有效数据 
 bool   m_bError;   //是否产生了错误 
};
}
#define FIELD_BITS(FieldBits) std::bitset<Size+1> FieldBits; std::bitset<Size+1>& JsonGetFieldBitsFunction(){ return FieldBits;} \
template <typename EncondingType,int index>  \
bool JsonFieldCallBackFunction(LightJson::IJsonBuffer<EncondingType> & IJsonB, const typename EncondingType::Ch * pKey, int len, Int2Type<index> ind) \
{  \
 if (IJsonB.Read(this->getValue(ind), pKey, len) == false)  {  return false; } \
 JsonGetFieldBitsFunction().set(index, true); JsonGetFieldBitsFunction().set(0, true); \
 return true; \
}
#define JSON_FIELD_INDEX(index,type,name,key) FIELD_INDEX(index,type,name) \
bool Have_##name##(){return JsonGetFieldBitsFunction()[index]; } \
void Set_##name##(bool bValue=true){JsonGetFieldBitsFunction().set(index,bValue);} \
template<typename Encoding> std::string & JsonFieldGetKeyFunction(Int2Type<index>,Encoding & Encoder) { static std::string str = std::move(Encoding::FromString(key)); return str;} \
void SetKey_##name##(std::string & strKey) { JsonFieldGetKeyFunction(Int2Type<index>(),LightJson::UTF8<>()) = std::move(strKey);}
#define JSON_FIELD(type,name) JSON_FIELD_INDEX(AUTO_INDEX(),type,name,#name)
#define JSON_FIELD_KEY(type,name,key) JSON_FIELD_INDEX(AUTO_INDEX(),type,name,key)
#define JSON_BEGIN() FIELD_BEGIN()
#define JSON_END() FIELD_END() FIELD_BITS(m_FieldBits)
#endif

四、一个简单的与rapidjson性能比较的例子

    LightJson的json标准化过程中,部份代码参考了rapidjson,没有否定rapidjson的意思。所举的例子,不够全面,并不能完全反应两者的水平。该例子仅供参考。要运行该例子,需要设置你自己的rapidjson项目的目录。注意:需要把编译器O2优化选项打开。

 
#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>
#include <iostream>
#include<time.h>
#include "./ThridParty/rapidjson/document.h"
#include "./ThridParty/rapidjson/stringbuffer.h"
#include "./ThridParty/rapidjson/writer.h"
#include <vector>
#include "LightJson.h"

//

struct TJsonCallBackFunctionSink
{
 template<typename Enconding>
 bool JsonParseCallBackFunction(LightJson::IJsonBuffer<Enconding> & IJsonB, const typename Enconding::Ch * pKey, int len)
 {
  if (strncmp("m_int\n64", pKey, len) == 0)
  {
   long long ll = 0;
   if (IJsonB.Read(ll, pKey, len) == false)
   {
    return false;
   }
   printf("m_int\\n64[%lld]\n", ll);
  }
  else if (strncmp("m_Sub", pKey, len) == 0)
  {
   struct SubSink
   {
    bool JsonParseCallBackFunction(LightJson::IJsonBuffer<Enconding> & IJsonB, const typename Enconding::Ch * pKey, int len)
    {
     if (strncmp("m_int", pKey, len) == 0)
     {
      int ll = 0;
      if (IJsonB.Read(ll, pKey, len) == false)
      {
       return false;
      }
      printf("Sub.m_int[%d]\n", ll);
     }
              else
              {
                  return IJsonB.ReadUnknowField(*this, pKey, len);
              }
    }
   }sub;
   if (IJsonB.Read(sub, pKey, len) == false)
   {
    return false;
   }
  }
  else
  {
   return IJsonB.ReadUnknowField(*this, pKey, len);
  }
    
  return true;
 } 
};
//嵌套结构体
struct TestJsonSub
{
 JSON_BEGIN()
 JSON_FIELD(bool, m_Bool);
 JSON_FIELD(int, m_int); 
 JSON_END();
};
//结构体
struct TestJsonC
{
 JSON_BEGIN()
 JSON_FIELD_KEY(long long, m_int64,"m_int\n64");
 JSON_FIELD(double, m_float);
 JSON_FIELD(std::string, m_str);
 JSON_FIELD(std::vector<int>, m_vect);
 JSON_FIELD(TestJsonSub, m_Sub);
 JSON_FIELD(int, m_int1);
 JSON_FIELD(int, m_int2);
 JSON_FIELD(int, m_int3);
 JSON_FIELD(int, m_int4);
 JSON_FIELD(int, m_int5);
 JSON_FIELD(std::vector<TestJsonSub>, m_vectSub);
 JSON_END();
};

bool TestJson()
{ 
 const int count = 100000;
 TestJsonC  objC;
 objC.m_int64 = 223356644;
 objC.m_float = 3.1415959;
 objC.m_str = LightJson::UTF8<>::FromString(L"aght有中文哦Json有转义\n\r\t哦!"); 
 for (int i = 0; i < 100; i++)
 {
  TestJsonSub sub;
  sub.m_Bool = i;
  sub.m_int = i;
  objC.m_vectSub.push_back(sub);
  objC.m_vect.push_back(i);
 }
 objC.m_Sub.m_Bool = true;
 objC.m_Sub.m_int = -12562213;
 objC.m_int1 = objC.m_int2 = objC.m_int3 = objC.m_int4 = objC.m_int5 = 2000;
 
 clock_t startC = clock();
 const int count = 100000;
 for (int i = 0; i < count; i++)
 {
  TestJsonC objC1;
  objC1.m_int64 = objC.m_int64;
  objC1.m_float = objC.m_float;
  objC1.m_str = objC.m_str;
  objC1.m_vect = objC.m_vect;
  objC1.m_Sub.m_Bool = objC.m_Sub.m_Bool;
  objC1.m_Sub.m_int = objC.m_Sub.m_int;
  objC1.m_int1 = objC1.m_int2 = objC1.m_int3 = objC1.m_int4 = objC1.m_int5 = objC.m_int1;
  objC1.m_vectSub = objC.m_vectSub;
  std::string strJson = LightJson::JsonUtil::ToJsonString(objC1);
      
   TestJsonC objC2;
  TestJsonC objC3;
  if (LightJson::JsonUtil::FromJsonString(objC2,strJson.data(),strJson.length()) == false)
  {
   return false;
  }
     
  if (objC2.Have_m_int64())
  {
   objC3.m_int64 = objC2.m_int64;
  }
  if (objC2.Have_m_float())
  {   
   objC3.m_float = objC2.m_float ;
  }
  if (objC2.Have_m_str())
  {   
   objC3.m_str = objC2.m_str.c_str();
  }
  if (objC2.Have_m_vect())
  {   
   objC3.m_vect.reserve(objC2.m_vect.size());
   for (int i = 0; i < objC2.m_vect.size();i++)
   {
    objC3.m_vect.push_back(objC2.m_vect[i]);
   }
  }
  if (objC2.Have_m_Sub())
  {
   TestJsonSub & sub = objC2.m_Sub;
   if (sub.Have_m_Bool())
   {
    objC3.m_Sub.m_Bool = sub.m_Bool;
   }
   if (sub.Have_m_int())
   {
    objC3.m_Sub.m_int = sub.m_int;
   }
  }
  if (objC2.Have_m_int1())
  {
   objC3.m_int1 = objC2.m_int1;
  }
  if (objC2.Have_m_int2())
  {
   objC3.m_int2 = objC2.m_int2;
  }
  if (objC2.Have_m_int3())
  {
   objC3.m_int3 = objC2.m_int3;
  }
  if (objC2.Have_m_int4())
  {
   objC3.m_int4 = objC2.m_int4;
  }
  if (objC2.Have_m_int5())
  {
   objC3.m_int5 = objC2.m_int5;
  }
  if (objC2.Have_m_vectSub())
  {
   objC3.m_vectSub = objC2.m_vectSub;
  }
  
  /*另一种用法,把TJsonCallBackFunctionSink对象做为回调处理者去反列化
   TJsonCallBackFunctionSink Sink;
   if (LightJson::JsonUtil::FromJsonString(Sink,strJson.data(),strJson.length()) == false)
  {
       return false;
    }*/

 }
 
 clock_t endC = clock();
 printf("Test Json LightJson time = %u\n", endC - startC);
 
   
 startC = clock();
 for (int i = 0; i < count; i++)
 {
  rapidjson::Document doc;
  doc.SetObject();
 
  {
   rapidjson::Value strValue(rapidjson::kNumberType);
   strValue.SetInt(objC.m_int1);
   doc.AddMember("m_int1", strValue, doc.GetAllocator());
  }
  {
   rapidjson::Value strValue(rapidjson::kNumberType);
   strValue.SetInt(objC.m_int2);
   doc.AddMember("m_int2", strValue, doc.GetAllocator());
  }
  {
   rapidjson::Value strValue(rapidjson::kNumberType);
   strValue.SetInt(objC.m_int3);
   doc.AddMember("m_int3", strValue, doc.GetAllocator());
  }
  {
   rapidjson::Value strValue(rapidjson::kNumberType);
   strValue.SetInt(objC.m_int4);
   doc.AddMember("m_int4", strValue, doc.GetAllocator());
  }
  {
   rapidjson::Value strValue(rapidjson::kNumberType);
   strValue.SetInt(objC.m_int5);
   doc.AddMember("m_int5", strValue, doc.GetAllocator());
  }
  {
   rapidjson::Value strValue(rapidjson::kNumberType);
   strValue.SetInt64(objC.m_int64);
   doc.AddMember("m_int64", strValue, doc.GetAllocator());
  }
  {
   rapidjson::Value strValue(rapidjson::kNumberType);
   strValue.SetDouble(objC.m_float);
   doc.AddMember("m_float", strValue, doc.GetAllocator());
  }
  {
   rapidjson::Value strValue(rapidjson::kStringType);
   strValue.SetString(objC.m_str.c_str(), doc.GetAllocator());
   doc.AddMember("m_str", strValue, doc.GetAllocator());
  }
  
  {
   rapidjson::Value strValue(rapidjson::kArrayType);
   for (int i = 0;i < objC.m_vect.size();i++)
   {
    strValue.PushBack(objC.m_vect[i], doc.GetAllocator());
   }
   doc.AddMember("m_vect", strValue, doc.GetAllocator());
  }
  {
   rapidjson::Value object(rapidjson::kObjectType);
   object.AddMember("m_Bool",objC.m_Sub.m_Bool,doc.GetAllocator());
   object.AddMember("m_int", objC.m_Sub.m_int, doc.GetAllocator());
   doc.AddMember("m_Sub", object, doc.GetAllocator());
  }
  {
   rapidjson::Value strValue(rapidjson::kArrayType);
   for (int i = 0;i < objC.m_vectSub.size();i++)
   {
    rapidjson::Value object(rapidjson::kObjectType);
    object.AddMember("m_Bool", objC.m_vectSub[i].m_Bool, doc.GetAllocator());
    object.AddMember("m_int", objC.m_vectSub[i].m_int, doc.GetAllocator());
    
    strValue.PushBack(object, doc.GetAllocator());
   }
   doc.AddMember("m_vectSub", strValue, doc.GetAllocator());
  }
 
  rapidjson::StringBuffer buffer;
  rapidjson::Writer< rapidjson::StringBuffer > writer(buffer);
  doc.Accept(writer);
  std::string strJson = buffer.GetString();
  TestJsonC objC2;
    
  doc.Parse<0>(strJson.c_str());
  if (doc.HasParseError())
  {
   return false;
  }
   
  if (doc.HasMember("m_int64"))
  {
   rapidjson::Value & value = doc["m_int64"];
   objC2.m_int64 = value.GetInt64();
  }
  if (doc.HasMember("m_float"))
  {
   rapidjson::Value & value = doc["m_float"];
   objC2.m_float = value.GetDouble();
  }
  
  if (doc.HasMember("m_str"))
  {
   rapidjson::Value & value = doc["m_str"];
   objC2.m_str = value.GetString();
  }
  if (doc.HasMember("m_vect"))
  {
   rapidjson::Value & value = doc["m_vect"];
   objC2.m_vect.reserve(value.Size());
   for (int i = 0; i < value.Size();i++)
   {
    objC2.m_vect.push_back(value[i].GetInt());
   }
  }
  if (doc.HasMember("m_Sub"))
  {
   rapidjson::Value & value = doc["m_Sub"];
   if (value.HasMember("m_Bool"))
   {
    objC2.m_Sub.m_Bool = value["m_Bool"].GetBool();
   }
   if (value.HasMember("m_int"))
   {
    objC2.m_Sub.m_int = value["m_int"].GetInt();
   }
  }
  if (doc.HasMember("m_int1"))
  {
   rapidjson::Value & value = doc["m_int1"];
   objC2.m_int1 = value.GetInt();
  }
  if (doc.HasMember("m_int2"))
  {
   rapidjson::Value & value = doc["m_int2"];
   objC2.m_int2 = value.GetInt();
  }
  if (doc.HasMember("m_int3"))
  {
   rapidjson::Value & value = doc["m_int3"];
   objC2.m_int3 = value.GetInt();
  }
  if (doc.HasMember("m_int4"))
  {
   rapidjson::Value & value = doc["m_int4"];
   objC2.m_int4 = value.GetInt();
  }
  if (doc.HasMember("m_int5"))
  {
   rapidjson::Value & value = doc["m_int5"];
   objC2.m_int5 = value.GetInt();
  }
  if (doc.HasMember("m_vectSub"))
  {
   rapidjson::Value & value = doc["m_vectSub"];
   objC2.m_vect.reserve(value.Size());
   for (int i = 0; i < value.Size();i++)
   {
    objC2.m_vectSub.push_back(TestJsonSub());
    rapidjson::Value & valueSub = value[i];
    if (valueSub.HasMember("m_Bool"))
    {
     objC2.m_vectSub[i].m_Bool = valueSub["m_Bool"].GetBool();
    }
    if (valueSub.HasMember("m_int"))
    {
     objC2.m_vectSub[i].m_int = valueSub["m_int"].GetInt();
    }
    
   }
  }
 }
 endC = clock();
 printf("Test Json rapidjson time = %u\n", endC - startC);
 return true;
}
 
void main()
{ 
 if (TestJson() == false)
 {
  printf("TestJson Fail!\n"); 
 }
 else
 {
  printf("TestJson OK!\n");
 }
 getchar();
  
 printf("app exit OK!\n");
 return;
}

  例子在我的机器上运行结果为: (LightJson耗时约为rapidjson的三分之一)

    Test Json LightJson time = 3768

    Test Json rapidjson time = 14591

    TestJson OK!

你可能感兴趣的:(C++,json,模板,c++静态反射)