当前位置: 首页 > article >正文

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的序列化相关的代码。


http://www.kler.cn/a/455641.html

相关文章:

  • 【视觉惯性SLAM:八、ORB-SLAM2:特征匹配】
  • 一种寻路的应用
  • Leetcode打卡:查询数组中元素出现的位置
  • JVM调优实践篇
  • SQL 实战:日期与时间函数 – 统计数据的时间跨度与趋势
  • vue之axios基本使用
  • asp.net core系统记录当前在线人数
  • 组建基于IPV6的网络
  • 更新本地项目到最新git版本脚本
  • 每天40分玩转Django:Django Email
  • 微服务网关路由
  • node.js高级用法
  • LeetCode -Hot100 - 56. 合并区间
  • 【centos8 镜像修改】centos8 镜像修改阿里云
  • c++编译过程初识
  • 【Java 代码审计入门-03】XSS 漏洞原理与实际案例介绍
  • MFC扩展库BCGControlBar Pro v36.0 - 可视化管理器等全新升级
  • Vision Transformer (ViT) 论文的第二句话
  • 踏踏实实练SQLday2-3连续12345
  • 机器学习2-NumPy
  • 华为 IPD,究竟有什么特点?(二)
  • scala图书借阅系统完整代码
  • 基于Docker的ETCD分布式集群
  • SQL-leetcode-180. 连续出现的数字
  • ctfshow web 笔记
  • 分布式 I/O 配合高冗余 PLC,打造高效控制新典范