Jsonlizer,一个把C++各类数据转成 Json 结构体的玩意儿
这段时间突发奇想,觉得可以弄一个Json和C++各种数据类型互转的工具,因为Json在进行数据储存的时候,有一些先天的优势,传统的C++的序列化方式是将数据序列化到流数据里面,而流数据是典型的串行结构(或则说是一维结构),因此,流数据对数据的位置特别的敏感,一旦序列化的元素有调整,就会导致原来存储的流数据完全失效。这一点在游戏开发时非常的麻烦,我们不得不将各个接口进行拆分,让接口对应其独自的流数据,做到局部的隔离。但是这个办法也不是万能,因为,一旦接口内某些元素顺序因为开始时过于简单而并没有做拆分时,隐藏的风险种子就种下了。随着时间推移,一旦需要更改这些元素时,就会发现被锁死了手脚!
Json具有结构化的特征,涵盖了原型,数组,对象等数据类型,用来做存储是非常理想的,如果项目中存储的数据用Json存储,然后再序列化到二进制流数据内,这样似乎就结合了两者的优点,结合了速度和可扩展性。而我自己写的CJson类本身就是可以序列化到流数据的。而且从流数据恢复的速度远比解析Json字符串的速度快几倍,那么现在欠缺的就是如何将C++数据转换成CJson类。
思考了一段时间,我意识到 Jsonlizer 和 Serializer 有本质的区别,一个是构建层次结构,一个是构建一维结构,我本来想尽可能的复用Serializer的代码,但我意识到,这是不可能的。我能利用的,可能仅仅是一部分最基本的,被称为 trait 模板代码。
而想复用Serialize函数的想法是不可能的。毕竟一个是结构化的数据,一个是一维数据。于是我改变了策略,重新构造了Jsonlizer。首先要做的是重写整个Jsonlizer的模板代码。这部分代码非常的关键,就是用于识别C++的各类数据。
这几个文件的代码如下:
#ifndef TAGPJSONLIZERRIMITIVE_H
#define TAGPJSONLIZERRIMITIVE_H
//Begin section for file tagJsonPrimitive.h
//TODO: Add definitions that you want preserved
//End section for file tagJsonPrimitive.h
namespace atom
{
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
template <class A, class T, bool save>
struct tagJsonPrimitive
{
//Begin section for si::tagJsonPrimitive
//TODO: Add attributes that you want preserved
//End section for si::tagJsonPrimitive
public:
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline static void Invoke(A & node, T & t)
{
//TODO Auto-generated method stub
node.Bind( t );
}
}; //end struct tagJsonPrimitive
} // end namespace atom
#endif
原型非常简单,没什么好说的。
#ifndef TAGJSONLIZERINVALID_H
#define TAGJSONLIZERINVALID_H
//Begin section for file tagJsonInvalid.h
//TODO: Add definitions that you want preserved
//End section for file tagJsonInvalid.h
namespace atom
{
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
template <class A, class T, bool save>
struct tagJsonInvalid
{
//Begin section for si::tagJsonInvalid
//TODO: Add attributes that you want preserved
//End section for si::tagJsonInvalid
public:
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline static void Invoke(A & n, T & t)
{
UNREFERENCED_PARAMETER(n);
UNREFERENCED_PARAMETER(t);
//TODO Auto-generated method stub
printf( "Jsonlization NOT support these keyword: mutable\n" );
}
}; //end struct tagJsonInvalid
} // end namespace atom
#endif
不支持的类型就是输出提示。
#ifndef TAGJSONLIZERARRAY_H
#define TAGJSONLIZERARRAY_H
//Begin section for file tagJsonArray.h
//TODO: Add definitions that you want preserved
//End section for file tagJsonArray.h
#include "../../../serialization/trait/array_trait.h"
namespace atom
{
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
template <class A, class T, bool save>
struct tagJsonArray
{
//Begin section for si::tagJsonArray
//TODO: Add attributes that you want preserved
//End section for si::tagJsonArray
public:
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline static void Invoke(A & jr, T & t)
{
//TODO Auto-generated method stub
// 读取或写入数组的长度;
U32 bound = static_cast<U32>( array_trait<T>::bound );
U32 limit = bound;
CJson node = jr.GetCurrentNode();
if( save == false ) {
bound = static_cast<U32>( node.Length() );
}
// 确认数组的长度是否越界;
bound = atom_min( bound, limit );
// 读取或写入数组的元素;
for( size_t i = 0; i < bound; ++ i )
{
CJson child( true );
if( save == false ) {
child = node[i];
}
jr.Push( child );
jr.Bind( t[i] );
jr.Pop();
if( save ) {
node.Push( child );
}
}
}
}; //end struct tagJsonArray
} // end namespace atom
#endif
数组开始有点东西了,其中能看到 Jsonlizer 有几个函数:Push,Pop,GetCurrentNode。这几个函数其实就是维护一个节点堆栈,堆栈内放入的是被操作的节点列表。顶部的节点就是最新需要被操作的节点。
#ifndef TAGJSONLIZERCLASS_H
#define TAGJSONLIZERCLASS_H
//Begin section for file tagJsonClass.h
//TODO: Add definitions that you want preserved
//End section for file tagJsonClass.h
// 为序列化类而特别准备的缺省模板函数。
template<class A, class T>
inline void Jsonlize(A & jr, T & t, bool save)
{
t.Jsonlize( jr, save );
}
namespace atom
{
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
template <class A, class T, bool save>
struct tagJsonClass
{
//Begin section for si::tagJsonClass
//TODO: Add attributes that you want preserved
//End section for si::tagJsonClass
public:
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline static void Invoke(A & jr, T & t)
{
//TODO Auto-generated method stub
Jsonlize( jr, t, save );
}
}; //end struct tagJsonClass
} // end namespace atom
#endif
类的代码其实不复杂,因为类的代码需要用户自己完成。
#ifndef TAGJSONLIZER_H
#define TAGJSONLIZER_H
//Begin section for file tagJsonlizer.h
//TODO: Add definitions that you want preserved
//End section for file tagJsonlizer.h
#include "../../../serialization/trait/is_primitive.h"
#include "../../../serialization/trait/is_array.h"
#include "../../../serialization/trait/is_class.h"
#include "../../../serialization/trait/is_pointer.h"
#include "../../../serialization/trait/if_else.h"
#include "../../../serialization/trait/degradation_trait.h"
#include "tagJsonPrimitive.h"
#include "tagJsonArray.h"
#include "tagJsonClass.h"
#include "tagJsonInvalid.h"
namespace atom
{
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
template <class A, class T, bool B>
struct tagJsonlizer
{
//Begin section for si::tagJsonlizer
//TODO: Add attributes that you want preserved
//End section for si::tagJsonlizer
public:
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline static void Jsonlize(A & json, T & data)
{
//TODO Auto-generated method stub
typedef typename
degradation_trait<T>::type C;
typedef
typename
if_else<is_array<C>::value,
tagJsonArray<A, C, B>,
typename
if_else<is_class<C>::value,
tagJsonClass<A, C, B>,
typename
if_else<is_primitive<C>::value,
tagJsonPrimitive<A, C, B>,
tagJsonInvalid <A, C, B>
>::type
>::type
>::type Invoker;
Invoker::Invoke( json, type_cast(data) );
}
}; //end struct tagJsonlizer
} // end namespace atom
#endif
这个就是Jsonlizer模板的入口了,接下来就是导入,导出类的代码。
#ifndef CJSONIMPORTER_H
#define CJSONIMPORTER_H
//Begin section for file CJsonImporter.h
//TODO: Add definitions that you want preserved
//End section for file CJsonImporter.h
#include "../../../Common.h"
#include "../../../interface/IEmbedInterface.h"
#include "../../../interface/IInterface.h"
#include "../../../interface/IJsonlizerRoot.h"
#include "../../../enumeration/INTERFACE_ID.h"
#include "../../../os/character/CCharset.h"
#include "../../stl/a_string.h"
#include "../../stl/a_wstring.h"
#include "../../hex/hex.h"
#include "../../tool/CInterface.h"
#include "tagJsonlizer.h"
namespace atom
{
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
class CJsonImporter : public IEmbedInterface
{
//Begin section for atom::CJsonImporter
//TODO: Add attributes that you want preserved
//End section for atom::CJsonImporter
private:
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
IInterface * nest;
#ifdef _SHIPPING_
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
IReferencedInterface * cast;
#endif
public:
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
CJsonImporter();
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
virtual ~CJsonImporter();
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
virtual int IncRef();
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
virtual int DecRef();
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
virtual int GetRef();
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
virtual IInterface * QueryInterface(U32 iid);
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
virtual void SetNest(IInterface * nest);
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline CJson GetCurrentNode()
{
// TODO Auto-generated method stub
CJson result;
CInterface<IJsonlizerRoot> root;
if( root.Mount(this, IID_JSONLIZER_ROOT) ) {
result = root -> GetCurrentNode();
}
return result;
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline void Push(CJson & node)
{
// TODO Auto-generated method stub
CInterface<IJsonlizerRoot> root;
if( root.Mount(this, IID_JSONLIZER_ROOT) ) {
root -> Push( node );
}
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline void Pop()
{
// TODO Auto-generated method stub
CInterface<IJsonlizerRoot> root;
if( root.Mount(this, IID_JSONLIZER_ROOT) ) {
root -> Pop();
}
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline void Bind(bool & value)
{
// TODO Auto-generated method stub
CInterface<IJsonlizerRoot> root;
if( root.Mount(this, IID_JSONLIZER_ROOT) )
{
CJson node = root -> GetCurrentNode();
value = static_cast<bool>( node );
}
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline void Bind(char & value)
{
// TODO Auto-generated method stub
CInterface<IJsonlizerRoot> root;
if( root.Mount(this, IID_JSONLIZER_ROOT) )
{
CJson node = root -> GetCurrentNode();
value = static_cast<U08>( node );
}
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline void Bind(I08 & value)
{
// TODO Auto-generated method stub
CInterface<IJsonlizerRoot> root;
if( root.Mount(this, IID_JSONLIZER_ROOT) )
{
CJson node = root -> GetCurrentNode();
value = static_cast<I08>( node );
}
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline void Bind(I16 & value)
{
// TODO Auto-generated method stub
CInterface<IJsonlizerRoot> root;
if( root.Mount(this, IID_JSONLIZER_ROOT) )
{
CJson node = root -> GetCurrentNode();
value = static_cast<I16>( node );
}
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline void Bind(I32 & value)
{
// TODO Auto-generated method stub
CInterface<IJsonlizerRoot> root;
if( root.Mount(this, IID_JSONLIZER_ROOT) )
{
CJson node = root -> GetCurrentNode();
value = static_cast<I32>( node );
}
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline void Bind(I64 & value)
{
// TODO Auto-generated method stub
CInterface<IJsonlizerRoot> root;
if( root.Mount(this, IID_JSONLIZER_ROOT) )
{
CJson node = root -> GetCurrentNode();
value = static_cast<I64>( node );
}
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline void Bind(U08 & value)
{
// TODO Auto-generated method stub
CInterface<IJsonlizerRoot> root;
if( root.Mount(this, IID_JSONLIZER_ROOT) )
{
CJson node = root -> GetCurrentNode();
value = static_cast<U08>( node );
}
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline void Bind(U16 & value)
{
// TODO Auto-generated method stub
CInterface<IJsonlizerRoot> root;
if( root.Mount(this, IID_JSONLIZER_ROOT) )
{
CJson node = root -> GetCurrentNode();
value = static_cast<U16>( node );
}
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline void Bind(U32 & value)
{
// TODO Auto-generated method stub
CInterface<IJsonlizerRoot> root;
if( root.Mount(this, IID_JSONLIZER_ROOT) )
{
CJson node = root -> GetCurrentNode();
value = static_cast<U32>( node );
}
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline void Bind(U64 & value)
{
// TODO Auto-generated method stub
CInterface<IJsonlizerRoot> root;
if( root.Mount(this, IID_JSONLIZER_ROOT) )
{
CJson node = root -> GetCurrentNode();
value = static_cast<U64>( node );
}
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline void Bind(float & value)
{
// TODO Auto-generated method stub
CInterface<IJsonlizerRoot> root;
if( root.Mount(this, IID_JSONLIZER_ROOT) )
{
CJson node = root -> GetCurrentNode();
value = static_cast<float>( node );
}
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline void Bind(double & value)
{
// TODO Auto-generated method stub
CInterface<IJsonlizerRoot> root;
if( root.Mount(this, IID_JSONLIZER_ROOT) )
{
CJson node = root -> GetCurrentNode();
value = static_cast<double>( node );
}
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline void Bind(a_string & value)
{
// TODO Auto-generated method stub
CInterface<IJsonlizerRoot> root;
if( root.Mount(this, IID_JSONLIZER_ROOT) )
{
CJson node = root -> GetCurrentNode();
value = static_cast<a_string>( node );
}
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline void Bind(a_wstring & value)
{
// TODO Auto-generated method stub
CInterface<IJsonlizerRoot> root;
if( root.Mount(this, IID_JSONLIZER_ROOT) )
{
CJson node = root -> GetCurrentNode();
a_string text = node;
CCharset charset( text.c_str() );
value = charset.FromUtf8.ToUnicode;
}
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline void Bind(void * buffer, U64 length)
{
// TODO Auto-generated method stub
if( buffer && length )
{
CInterface<IJsonlizerRoot> root;
if( root.Mount(this, IID_JSONLIZER_ROOT) )
{
CJson node = root -> GetCurrentNode();
a_string text = node;
FromHex( text, buffer, length );
}
}
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
template<class T>
inline void Bind(T & value)
{
//TODO Auto-generated method stub
tagJsonlizer<CJsonImporter, T, false>::Jsonlize( *this, value );
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
template<class T>
inline void Bind(const char * name, T & value)
{
//TODO Auto-generated method stub
if( name )
{
CInterface<IJsonlizerRoot> root;
if( root.Mount(this, IID_JSONLIZER_ROOT) )
{
CJson node = root -> GetCurrentNode();
CJson child = node[name];
root -> Push( child );
Bind( value );
root -> Pop();
}
}
}
}; //end class CJsonImporter
} //end namespace atom
#endif
#ifndef CJSONEXPORTER_H
#define CJSONEXPORTER_H
//Begin section for file CJsonExporter.h
//TODO: Add definitions that you want preserved
//End section for file CJsonExporter.h
#include "../../../Common.h"
#include "../../../interface/IEmbedInterface.h"
#include "../../../interface/IInterface.h"
#include "../../../interface/IJsonlizerRoot.h"
#include "../../../enumeration/INTERFACE_ID.h"
#include "../../../os/character/CCharset.h"
#include "../../stl/a_string.h"
#include "../../stl/a_wstring.h"
#include "../../hex/hex.h"
#include "../../tool/CInterface.h"
#include "tagJsonlizer.h"
namespace atom
{
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
class CJsonExporter : public IEmbedInterface
{
//Begin section for atom::CJsonExporter
//TODO: Add attributes that you want preserved
//End section for atom::CJsonExporter
private:
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
IInterface * nest;
#ifdef _SHIPPING_
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
IReferencedInterface * cast;
#endif
public:
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
CJsonExporter();
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
virtual ~CJsonExporter();
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
virtual int IncRef();
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
virtual int DecRef();
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
virtual int GetRef();
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
virtual IInterface * QueryInterface(U32 iid);
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
virtual void SetNest(IInterface * nest);
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline CJson GetCurrentNode()
{
// TODO Auto-generated method stub
CJson result;
CInterface<IJsonlizerRoot> root;
if( root.Mount(this, IID_JSONLIZER_ROOT) ) {
result = root -> GetCurrentNode();
}
return result;
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline void Push(CJson & node)
{
// TODO Auto-generated method stub
CInterface<IJsonlizerRoot> root;
if( root.Mount(this, IID_JSONLIZER_ROOT) ) {
root -> Push( node );
}
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline void Pop()
{
// TODO Auto-generated method stub
CInterface<IJsonlizerRoot> root;
if( root.Mount(this, IID_JSONLIZER_ROOT) ) {
root -> Pop();
}
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline void Bind(bool & value)
{
//TODO Auto-generated method stub
CInterface<IJsonlizerRoot> root;
if( root.Mount(this, IID_JSONLIZER_ROOT) )
{
CJson node = root -> GetCurrentNode();
node = value;
}
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline void Bind(char & value)
{
//TODO Auto-generated method stub
CInterface<IJsonlizerRoot> root;
if( root.Mount(this, IID_JSONLIZER_ROOT) )
{
CJson node = root -> GetCurrentNode();
node = value;
}
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline void Bind(I08 & value)
{
//TODO Auto-generated method stub
CInterface<IJsonlizerRoot> root;
if( root.Mount(this, IID_JSONLIZER_ROOT) )
{
CJson node = root -> GetCurrentNode();
node = value;
}
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline void Bind(I16 & value)
{
//TODO Auto-generated method stub
CInterface<IJsonlizerRoot> root;
if( root.Mount(this, IID_JSONLIZER_ROOT) )
{
CJson node = root -> GetCurrentNode();
node = value;
}
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline void Bind(I32 & value)
{
//TODO Auto-generated method stub
CInterface<IJsonlizerRoot> root;
if( root.Mount(this, IID_JSONLIZER_ROOT) )
{
CJson node = root -> GetCurrentNode();
node = value;
}
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline void Bind(I64 & value)
{
//TODO Auto-generated method stub
CInterface<IJsonlizerRoot> root;
if( root.Mount(this, IID_JSONLIZER_ROOT) )
{
CJson node = root -> GetCurrentNode();
node = value;
}
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline void Bind(U08 & value)
{
//TODO Auto-generated method stub
CInterface<IJsonlizerRoot> root;
if( root.Mount(this, IID_JSONLIZER_ROOT) )
{
CJson node = root -> GetCurrentNode();
node = value;
}
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline void Bind(U16 & value)
{
//TODO Auto-generated method stub
CInterface<IJsonlizerRoot> root;
if( root.Mount(this, IID_JSONLIZER_ROOT) )
{
CJson node = root -> GetCurrentNode();
node = value;
}
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline void Bind(U32 & value)
{
//TODO Auto-generated method stub
CInterface<IJsonlizerRoot> root;
if( root.Mount(this, IID_JSONLIZER_ROOT) )
{
CJson node = root -> GetCurrentNode();
node = value;
}
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline void Bind(U64 & value)
{
//TODO Auto-generated method stub
CInterface<IJsonlizerRoot> root;
if( root.Mount(this, IID_JSONLIZER_ROOT) )
{
CJson node = root -> GetCurrentNode();
node = value;
}
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline void Bind(float & value)
{
//TODO Auto-generated method stub
CInterface<IJsonlizerRoot> root;
if( root.Mount(this, IID_JSONLIZER_ROOT) )
{
CJson node = root -> GetCurrentNode();
node = value;
}
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline void Bind(double & value)
{
//TODO Auto-generated method stub
CInterface<IJsonlizerRoot> root;
if( root.Mount(this, IID_JSONLIZER_ROOT) )
{
CJson node = root -> GetCurrentNode();
node = value;
}
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline void Bind(const char * value)
{
//TODO Auto-generated method stub
if( value )
{
CInterface<IJsonlizerRoot> root;
if( root.Mount(this, IID_JSONLIZER_ROOT) )
{
CJson node = root -> GetCurrentNode();
node = value;
}
}
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline void Bind(const wchar_t * value)
{
//TODO Auto-generated method stub
if( value )
{
CInterface<IJsonlizerRoot> root;
if( root.Mount(this, IID_JSONLIZER_ROOT) )
{
CJson node = root -> GetCurrentNode();
CCharset charset( value );
a_string text = charset.ToUtf8;
node = text.c_str();
}
}
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline void Bind(a_string & value)
{
//TODO Auto-generated method stub
CInterface<IJsonlizerRoot> root;
if( root.Mount(this, IID_JSONLIZER_ROOT) )
{
CJson node = root -> GetCurrentNode();
node = value.c_str();
}
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline void Bind(a_wstring & value)
{
//TODO Auto-generated method stub
CInterface<IJsonlizerRoot> root;
if( root.Mount(this, IID_JSONLIZER_ROOT) )
{
CJson node = root -> GetCurrentNode();
CCharset charset( value.c_str() );
a_string text = charset.ToUtf8;
node = text.c_str();
}
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline void Bind(void * buffer, U64 length)
{
//TODO Auto-generated method stub
if( buffer && length )
{
CInterface<IJsonlizerRoot> root;
if( root.Mount(this, IID_JSONLIZER_ROOT) )
{
a_string text = ToHex( buffer, length );
CJson node = root -> GetCurrentNode();
node = text.c_str();
}
}
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
template<class T>
inline void Bind(T & value)
{
//TODO Auto-generated method stub
tagJsonlizer<CJsonExporter, T, true>::Jsonlize( * this, value );
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
template<class T>
inline void Bind(const T & value)
{
//TODO Auto-generated method stub
Bind( const_cast<T &>(value) );
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
template<class T>
inline void Bind(const char * name, T & value)
{
//TODO Auto-generated method stub
if( name )
{
CInterface<IJsonlizerRoot> root;
if( root.Mount(this, IID_JSONLIZER_ROOT) )
{
CJson node = root -> GetCurrentNode();
CJson child = node[name];
root -> Push( child );
Bind( value );
root -> Pop();
}
}
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
template<class T>
inline void Bind(const char * name, const T & value)
{
//TODO Auto-generated method stub
Bind( name, const_cast<T &>(value) );
}
}; //end class CJsonExporter
} //end namespace atom
#endif
导入导出的类有一个特殊的函数:
inline void Bind(const char * name, T & value)
这个函数带了一个name的参数,其实就是针对类的成员变量而设的。
#ifndef CJSONLIZER_H
#define CJSONLIZER_H
//Begin section for file CJsonlizer.h
//TODO: Add definitions that you want preserved
//End section for file CJsonlizer.h
#include "../../../Common.h"
#include "CJsonExporter.h"
#include "CJsonImporter.h"
#include "CJsonlizerRoot.h"
#include "../CJson.h"
inline const char * last_dot(const char * value)
{
const char * result(value);
if( value )
{
for( ;; ++ value )
{
if( *value == 0 ) break;
if( *value == '.' ) {
result = value + 1;
}
}
}
return result;
}
#define JKV(V) make_pair(a_string(#V), V)
#define JBD(A,V) A.Bind(last_dot(#V), V)
namespace atom
{
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
class CJsonlizer : public IInterface
{
//Begin section for atom::CJsonlizer
//TODO: Add attributes that you want preserved
//End section for atom::CJsonlizer
private:
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
CJsonExporter exporter;
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
CJsonImporter importer;
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
CJsonlizerRoot root;
public:
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
CJsonlizer();
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
virtual ~CJsonlizer();
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
virtual IInterface * QueryInterface(U32 iid);
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
bool Assign(CJson & data);
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
bool Obtain(CJson & data);
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
void Clear();
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline CJson GetCurrentNode()
{
//TODO Auto-generated method stub
root.GetCurrentNode();
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline void Push(CJson & node)
{
//TODO Auto-generated method stub
root.Push( node );
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
inline void Pop()
{
//TODO Auto-generated method stub
root.Pop();
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
template<class T>
inline CJsonlizer & operator <<(const T & value)
{
//TODO Auto-generated method stub
exporter.Bind( value );
return( * this );
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
template<class T>
inline CJsonlizer & operator <<(const pair<a_string, T> & value)
{
//TODO Auto-generated method stub
exporter.Bind( value.first.c_str(), value.second );
return( * this );
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
template<class T>
inline CJsonlizer & operator >>(T & value)
{
//TODO Auto-generated method stub
importer.Bind( value );
return( * this );
}
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
template<class T>
inline CJsonlizer & operator >>(pair<a_string, T> & value)
{
//TODO Auto-generated method stub
importer.Bind( value.first.c_str(), value.second );
return( * this );
}
}; //end class CJsonlizer
} //end namespace atom
#endif
最后就是最终的绑定接口了,接下来我展示一个简单的例子:
struct tagTest
{
U32 index;
a_string name;
tagTest():index(0) {
}
~tagTest() {
}
};
struct tagTest2
{
U32 index;
tagTest value[4];
tagTest2():index(0) {
}
~tagTest2() {
}
};
template<class A>
inline void Jsonlize(A & jr, tagTest & t, bool save)
{
JBD( jr, t.index );
JBD( jr, t.name );
}
template<class A>
inline void Jsonlize(A & jr, tagTest2 & t, bool save)
{
JBD( jr, t.index );
JBD( jr, t.value );
}
准备了两个类,这两个类有聚合关系。然后我初始化这两个类,然后用Jsonizer将这个类导出成Json数据结构。
tagTest2 in, out;
in.index = 1;
in.value[0].index = 101;
in.value[0].name = "101";
in.value[1].index = 102;
in.value[1].name = "102";
in.value[2].index = 103;
in.value[2].name = "103";
in.value[3].index = 104;
in.value[3].name = "104";
CJsonlizer jr;
jr << in;
CJson json;
jr.Obtain( json );
a_string value = json.Stringify();
printf( "%s\n", value.c_str() );
运行的结果如下:
其实并不困难。大家也可以试试,其中 trait 的那些代码可以去看看boost的序列化相关的代码。