C++对象的JSON序列化与反序列化探索完结-列表的序列化与反序列化
来源:互联网 发布:java 二叉树容器 编辑:程序博客网 时间:2024/05/15 17:13
在前两篇文章中,我们已经完成对普通对象以及复杂对象嵌套的序列化与反序列化,见如下地址:
C++对象的JSON序列化与反序列化探索
C++对象的JSON序列化与反序列化探索续-复杂对象的序列化与反序列化
经过一番折腾,总算把带有列表的对象的序列化完成了,目前支持 list 和 vector 的列表,以及自定义的其他类型的列表,我们可以先来看看实现的效果。
复杂对象及带列表对象的序列号主要有如下几种:
1. 普通的list列表,如:list<string>
list<string> testList;testList.push_back("33333333");testList.push_back("55555555");tvalue = CJsonObjectBase::DoArraySerialize<list<string>>(&testList);out = CJsonObjectBase::JsonValueToString(tvalue);AfxMessageBox(out.c_str());序列化结果为:
["33333333","55555555"]
2. 复杂对象的列表,如list<CTestStru*>
Json::Value tvalue;std::string out;vector<CSubTestStruct*> testListSpecial;obj = new CSubTestStruct();obj->SubMsgID = 2;obj->SubMsgTitle = "333";testListSpecial.push_back(obj);obj = new CSubTestStruct();obj->SubMsgID = 3;obj->SubMsgTitle = "4444";testListSpecial.push_back(obj);tvalue = CJsonObjectBase::DoArraySerialize<vector<CJsonObjectBase*>>((vector<CJsonObjectBase*>*)&testListSpecial);out = CJsonObjectBase::JsonValueToString(tvalue);AfxMessageBox(out.c_str());
[{"SubMsgID":2,"SubMsgTitle":"333"},{"SubMsgID":3,"SubMsgTitle":"4444"}]此注需要注意的是,使用完毕后,一定要记得销毁列表中的对象:
for (vector<CSubTestStruct*>::iterator it = testListSpecial.begin(); it != testListSpecial.end(); ++ it){delete (*it);}反序列化:
void* GenerateTest(const string& name){return new CSubTestStruct(); }
CString strTest = "";string strTestEx = "[{\"SubMsgID\":2,\"SubMsgTitle\":\"2222\"},{\"SubMsgID\":4444,\"SubMsgTitle\":\"4444\"}]";Json::Reader reader; Json::Value root; if (reader.parse(strTestEx, root)) {vector<CSubTestStruct*> listObjTest;CJsonObjectBase::DoObjArrayDeSerialize<vector<CJsonObjectBase*>>("test", &listObjTest, root, GenerateTest);strTest.Format("count %d\r\nfirst subTitle:%s", listObjTest.size(), listObjTest.size() > 0 ? listObjTest[0]->SubMsgTitle.c_str() : "");AfxMessageBox(strTest);for (vector<CSubTestStruct*>::iterator it = listObjTest.begin(); it != listObjTest.end(); ++ it){delete (*it);}}打印结果:
count 2first subTitle:22223. 在对象中包含普通及复杂的列表,如下:
struct CSubTestStruct : public CJsonObjectBase { CSubTestStruct() { SubMsgID = 0; SetPropertys(); } ULONGLONG SubMsgID; string SubMsgTitle; protected: //子类需要实现此函数,并且将相应的映射关系进行设置 virtual void SetPropertys() { SetProperty("SubMsgID", asUInt64, &SubMsgID); SetProperty("SubMsgTitle", asString, &SubMsgTitle); } }; struct CTestStruct : public CJsonObjectBase { CTestStruct() { SetPropertys(); } ~CTestStruct(){for (vector<CSubTestStruct*>::iterator it = testListSpecial.begin(); it != testListSpecial.end(); ++ it){delete (*it);}}ULONGLONG MsgID; string MsgTitle; string MsgContent; CSubTestStruct subObj; vector<INT> intList;list<string> testList;vector<CSubTestStruct*> testListSpecial;protected: CJsonObjectBase* GenerateJsonObjForDeSerialize(const string& propertyName){if("testListSpecial" == propertyName){return new CSubTestStruct();}return NULL;}//子类需要实现此函数,并且将相应的映射关系进行设置 virtual void SetPropertys() {SetProperty("MsgID", asUInt64, &MsgID); SetProperty("MsgTitle", asString, &MsgTitle); SetProperty("MsgContent", asString, &MsgContent); SetProperty("subObj", asJsonObj, &subObj);SetProperty("intList", asVectorArray, &intList); SetProperty("testList", asListArray, &testList, asString); SetProperty("testListSpecial", asVectorArray, &testListSpecial, asJsonObj);} };序列化代码:
CTestStruct stru;stru.MsgID = 11223344;stru.MsgTitle = "黑黑";stru.MsgContent = "哈哈";stru.testList.push_back("aaaa");stru.testList.push_back("bbbb");stru.intList.push_back(3333);CSubTestStruct* obj = new CSubTestStruct();obj->SubMsgID = 2;obj->SubMsgTitle = "333";stru.testListSpecial.push_back(obj);obj = new CSubTestStruct();obj->SubMsgID = 3;obj->SubMsgTitle = "4444";stru.testListSpecial.push_back(obj);CString strTest = stru.Serialize().c_str();AfxMessageBox(strTest);打印结果:
{"MsgContent":"哈哈","MsgID":11223344,"MsgTitle":"黑黑","intList":[3333],"subObj":{"SubMsgID":0,"SubMsgTitle":""},"testList":["aaaa","bbbb"],"testListSpecial":[{"SubMsgID":2,"SubMsgTitle":"333"},{"SubMsgID":3,"SubMsgTitle":"4444"}]}反序列化代码:
const char* pstr = "{\"MsgContent\":\"哈哈\",\"MsgID\":11223344,\"MsgTitle\":\"黑黑\",\"intList\":[3333],\"subObj\":{\"SubMsgID\":0,\"SubMsgTitle\":\"dddd\"},\"testList\":[\"aaaa\",\"bbbb\"],\"testListSpecial\":[{\"SubMsgID\":2,\"SubMsgTitle\":\"333\"},{\"SubMsgID\":3,\"SubMsgTitle\":\"4444\"}]}"; CTestStruct stru; stru.DeSerialize(pstr); CString strShow = ""; strShow.Format("objlist Size:%d\r\nlistIntCount:%d\r\nMsgID:%I64u\r\nMsgTile:%s\r\nMsgContent:%s\r\nSubMsgTitle:%s\r\nfirst value:%d",stru.testListSpecial.size(), stru.intList.size(), stru.MsgID, stru.MsgTitle.c_str(), stru.MsgContent.c_str(), stru.subObj.SubMsgTitle.c_str(),stru.intList.size() > 0 ? stru.intList[0] : 0); AfxMessageBox(strShow);打印结果:
objlist Size:2listIntCount:1MsgID:11223344MsgTile:黑黑MsgContent:哈哈SubMsgTitle:ddddfirst value:3333目前仅支持vector与list类型的列表,对于其他特殊的列表类型,需要在子类中重载如下函数:
virtual Json::Value DoSpecialArraySerialize(const string& propertyName){ return "";}
至此,对于C++对象以及相关列表的序列化与反序列化均已支持,在此将源码贴出:
#ifndef CJSONOBJECTBASE_H#define CJSONOBJECTBASE_H#include <string> #include <vector> #include <list>#include "json/json.h" using std::string; using std::vector; using std::list;#pragma warning(disable:4267)#define DoArrayDeSerialize_Wrapper(listType, type)\DoArrayDeSerialize<##listType<##type>, ##type>#define Type_Wrapper(listType, type)\(##listType<##type>*)#define DoArraySerialize_Wrapper(listType, type)\DoArraySerialize(Type_Wrapper(listType, type)addr);#define DoObjArrayDeSerialize_Wrapper(listType, type)\DoObjArrayDeSerialize<##listType<type>>typedef void* (*GenerateJsonObjForDeSerializeFromOutSide)(const string& propertyName);struct CJsonObjectBase { protected: enum CEnumJsonTypeMap {asBool = 1, asInt, asUInt, asString, asInt64, asUInt64, asJsonObj,asSpecialArray,asVectorArray,asListArray,}; public: CJsonObjectBase(void){} public: virtual ~CJsonObjectBase(void){} string Serialize() { Json::Value new_item = DoSerialize(); Json::FastWriter writer; std::string out2 = writer.write(new_item); return out2; } bool DeSerialize(const char* str) { Json::Reader reader; Json::Value root; if (reader.parse(str, root)) { return DoDeSerialize(root); } return false; } Json::Value DoSerialize() { Json::Value new_item; int nSize = m_vectorName.size(); for (int i=0; i < nSize; ++i ) { void* pAddr = m_vectorPropertyAddr[i]; switch(m_vectorType[i]) { case asVectorArray:case asListArray:new_item[m_vectorName[i]] = DoArraySerialize(pAddr, m_vectorType[i], m_vectorListParamType[i]);break;case asSpecialArray: new_item[m_vectorName[i]] = DoSpecialArraySerialize(m_vectorName[i]); break; case asJsonObj: new_item[m_vectorName[i]] = ((CJsonObjectBase*)pAddr)->DoSerialize(); break; case asBool: new_item[m_vectorName[i]] = Serialize<bool>(pAddr); case asInt: new_item[m_vectorName[i]] = Serialize<INT>(pAddr); break; case asUInt: new_item[m_vectorName[i]] = Serialize<UINT>(pAddr); break; case asInt64: new_item[m_vectorName[i]] = Serialize<LONGLONG>(pAddr); break; case asUInt64: new_item[m_vectorName[i]] = Serialize<ULONGLONG>(pAddr); break; case asString: new_item[m_vectorName[i]] = Serialize<string>(pAddr); default: //我暂时只支持这几种类型,需要的可以自行添加break; } } return new_item; } protected:bool DoDeSerialize(Json::Value& root) { int nSize = m_vectorName.size(); for (int i=0; i < nSize; ++i ) { void* pAddr = m_vectorPropertyAddr[i]; switch(m_vectorType[i]) { case asListArray:case asVectorArray:{if (root.isNull() || root[m_vectorName[i]].isNull()){break;}DoArrayDeSerialize(m_vectorName[i], pAddr, root[m_vectorName[i]], m_vectorType[i], m_vectorListParamType[i]);}break;case asJsonObj: { if (!root[ m_vectorName[i] ].isNull()) ((CJsonObjectBase*)pAddr)->DoDeSerialize(root[m_vectorName[i]]); } break; case asBool: (*(bool*)pAddr) = root.get(m_vectorName[i], 0).asBool(); break; case asInt: (*(INT*)pAddr) = root.get(m_vectorName[i], 0).asInt(); break; case asUInt: (*(UINT*)pAddr) = root.get(m_vectorName[i], 0).asUInt(); break; case asInt64: (*(LONGLONG*)pAddr) = root.get(m_vectorName[i], 0).asInt64(); break; case asUInt64: (*(ULONGLONG*)pAddr) = root.get(m_vectorName[i], 0).asUInt64(); break; case asString: (*(string*)pAddr) = root.get(m_vectorName[i], "").asString(); default: //我暂时只支持这几种类型,需要的可以自行添加 break; } } return true; } void SetProperty(string name, CEnumJsonTypeMap type, void* addr, CEnumJsonTypeMap listParamType = asInt) { m_vectorName.push_back(name); m_vectorPropertyAddr.push_back(addr); m_vectorType.push_back(type); m_vectorListParamType.push_back(listParamType);} virtual void SetPropertys() = 0; //有特殊对象需要序列化时,请重载此函数 virtual Json::Value DoSpecialArraySerialize(const string& propertyName){ return "";}//在反序列化时,如果对象中嵌套了列表,并且列表中容纳的内容是其他特殊对象时,需要重载此函数,new出真正的对象virtual CJsonObjectBase* GenerateJsonObjForDeSerialize(const string& propertyName){ return NULL;}bool DoArrayDeSerialize(const string& propertyName, void* addr, Json::Value& root, CEnumJsonTypeMap listType, CEnumJsonTypeMap paramType){if (listType == asVectorArray){switch(paramType){ case asJsonObj: { return DoObjArrayDeSerialize_Wrapper(vector, CJsonObjectBase*)(propertyName, addr, root);} break; case asBool: //无 break; case asInt: return DoArrayDeSerialize_Wrapper(vector, INT)(addr, root); case asUInt: return DoArrayDeSerialize_Wrapper(vector, UINT)(addr, root); case asInt64: return DoArrayDeSerialize_Wrapper(vector, LONGLONG)(addr, root); case asUInt64: return DoArrayDeSerialize_Wrapper(vector, ULONGLONG)(addr, root); case asString: return DoArrayDeSerialize_Wrapper(vector, string)(addr, root); default:break; }}else if(listType == asListArray){switch(paramType){ case asJsonObj: {return DoObjArrayDeSerialize_Wrapper(list, CJsonObjectBase*)(propertyName, addr, root);} break; case asBool: return DoArrayDeSerialize_Wrapper(list, bool)(addr, root);case asInt: return DoArrayDeSerialize_Wrapper(list, INT)(addr, root); case asUInt: return DoArrayDeSerialize_Wrapper(list, UINT)(addr, root); case asInt64: return DoArrayDeSerialize_Wrapper(list, LONGLONG)(addr, root); case asUInt64: return DoArrayDeSerialize_Wrapper(list, ULONGLONG)(addr, root); case asString: return DoArrayDeSerialize_Wrapper(list, string)(addr, root); default:break; }}return true;}//特殊对象列表的反序列化template<typename T1>bool DoObjArrayDeSerialize(const string& propertyName, void* addr, Json::Value& node){if (!node.isArray()){return false;}T1* pList = (T1*)addr;int size = node.size();for(int i = 0; i < size; ++i){CJsonObjectBase* pNode = GenerateJsonObjForDeSerialize(propertyName);pNode->DoDeSerialize(node[i]);pList->push_back(pNode);}return true;}public://常见类型列表的反序列化 template <typename T1, typename T2>static bool DoArrayDeSerialize(void* addr, Json::Value& node){if (!node.isArray()){return false;}T1* pList = (T1*)addr;int size = node.size();for(int i = 0; i < size; ++i)pList->push_back( DeSerialize<T2>(node[i]) );return true;}//特殊对象列表的反序列化template<typename T1>static bool DoObjArrayDeSerialize(const string& propertyName, void* addr, Json::Value& node, GenerateJsonObjForDeSerializeFromOutSide funGenerate){if (!node.isArray()){return false;}T1* pList = (T1*)addr;int size = node.size();for(int i = 0; i < size; ++i){CJsonObjectBase* pNode = (CJsonObjectBase*)funGenerate(propertyName);pNode->DoDeSerialize(node[i]);pList->push_back(pNode);}return true;}protected:Json::Value DoArraySerialize(void* addr, CEnumJsonTypeMap listType, CEnumJsonTypeMap paramType){if (listType == asVectorArray){switch(paramType){ case asBool: return "";case asJsonObj:return DoArraySerialize_Wrapper(vector, CJsonObjectBase*);case asInt: return DoArraySerialize_Wrapper(vector, INT);case asUInt: return DoArraySerialize_Wrapper(vector, UINT); case asInt64: return DoArraySerialize_Wrapper(vector, LONGLONG); case asUInt64: return DoArraySerialize_Wrapper(vector, ULONGLONG); case asString: return DoArraySerialize_Wrapper(vector, string);}}else {switch(paramType){ case asBool: return DoArraySerialize_Wrapper(list, bool);case asJsonObj:return DoArraySerialize_Wrapper(list, CJsonObjectBase*);case asInt: return DoArraySerialize_Wrapper(list, INT);case asUInt: return DoArraySerialize_Wrapper(list, UINT); case asInt64: return DoArraySerialize_Wrapper(list, LONGLONG); case asUInt64: return DoArraySerialize_Wrapper(list, ULONGLONG); case asString: return DoArraySerialize_Wrapper(list, string);}}return "";}public:template <typename T1>static Json::Value DoArraySerialize(T1* pList){Json::Value arrayValue;for (T1::iterator it = pList->begin(); it != pList->end(); ++ it){arrayValue.append(*it);}return arrayValue;}template <>static Json::Value DoArraySerialize(vector<CJsonObjectBase*>* pList){Json::Value arrayValue;for (vector<CJsonObjectBase*>::iterator it = pList->begin(); it != pList->end(); ++ it){arrayValue.append((*it)->DoSerialize());}return arrayValue;}template <>static Json::Value DoArraySerialize(list<CJsonObjectBase*>* pList){Json::Value arrayValue;for (list<CJsonObjectBase*>::iterator it = pList->begin(); it != pList->end(); ++ it){arrayValue.append((*it)->DoSerialize());}return arrayValue;}static string JsonValueToString(Json::Value& tvalue){Json::FastWriter writer; return writer.write(tvalue);}private:template <typename T>Json::Value Serialize(void* addr){return (*(T*)addr);}template <typename T>static T DeSerialize(Json::Value& root){return GetData<T>(root);}template <typename T>static T GetData(Json::Value& root){T temp;return temp;}template <>static bool GetData(Json::Value& root){return root.asBool();}template <>static INT GetData(Json::Value& root){return root.asInt();}template <>static UINT GetData(Json::Value& root){return root.asUInt();}template <>static LONGLONG GetData(Json::Value& root){return root.asInt64();}template <>static ULONGLONG GetData(Json::Value& root){return root.asUInt64();}template <>static string GetData(Json::Value& root){return root.asString();}private: vector<string> m_vectorName; vector<void*> m_vectorPropertyAddr; vector<CEnumJsonTypeMap> m_vectorType;vector<CEnumJsonTypeMap> m_vectorListParamType;}; #endif
如果哪位有任何意见建议,敬请回复!
完整的测试程序及DEMO请见:http://download.csdn.net/detail/tragicguy/5649527
- C++对象的JSON序列化与反序列化探索完结-列表的序列化与反序列化
- C++对象的JSON序列化与反序列化探索
- C++对象的JSON序列化与反序列化探索续-复杂对象的序列化与反序列化
- C++序列化与反序列化的简单探索
- POJO与JSON的序列化与反序列化
- Json序列化 与反序列化
- JSON序列化与反序列化
- JSON序列化与反序列化
- Json序列化与反序列化
- Json序列化与反序列化
- JSON序列化与反序列化
- JSON序列化与反序列化
- JSON序列化与反序列化
- JSON序列化 与反序列化
- JSON序列化与反序列化
- JSON序列化与反序列化
- JSON序列化与反序列
- json的序列化与反序列化
- ubuntu下安装matlab时遇到Permission denied问题的解决方案
- 三处乱码问题
- Linux学习-Linux启动过程
- 比特币相关问题
- Linux学习-mount
- C++对象的JSON序列化与反序列化探索完结-列表的序列化与反序列化
- 创业者,你为什么这么着急?
- Oracle ADDM 自动诊断监视工具 介绍
- Linux学习-常用命令总结
- 一个专利描述
- function/bind的救赎(上)
- 可以看看的国外网站
- delphi 文件的读取
- 黑马程序员_控制台应用程序中判断用户是否登录成功