这段时间突发奇想,觉得可以弄一个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的序列化相关的代码。