irpas技术客

基于RapidJson的c++类的序列化和反序列化_kupeThinkPoem_rapidjson 反序列化

大大的周 4337

? ? ?

目录

一、rapidjson简介

二、序列化思路

三、C++实体类的的序列化和反序列化

1、RapidjsonHelper帮助类

2、实体类的的序列化和反序列化

? 3、main函数

四、下载


一、rapidjson简介

RapidJSON 是一个 C++ 的 JSON 解析器及生成器。它的灵感来自?RapidXml。

RapidJSON 小而全。它同时支持 SAX 和 DOM 风格的 API。SAX 解析器只有约 500 行代码。RapidJSON 快。它的性能可与?strlen()?相比。可支持 SSE2/SSE4.2 加速。RapidJSON 独立。它不依赖于 BOOST 等外部库。它甚至不依赖于 STL。RapidJSON 对内存友好。在大部分 32/64 位机器上,每个 JSON 值只占 16 字节(除字符串外)。它预设使用一个快速的内存分配器,令分析器可以紧凑地分配内存。RapidJSON 对 Unicode 友好。它支持 UTF-8、UTF-16、UTF-32 (大端序/小端序),并内部支持这些编码的检测、校验及转码。例如,RapidJSON 可以在分析一个 UTF-8 文件至 DOM 时,把当中的 JSON 字符串转码至 UTF-16。它也支持代理对(surrogate pair)及?"\u0000"(空字符)。

? ? ?下载:

RapidJSON: 首页http://rapidjson.org/zh-cn/

https://github.com/Tencent/rapidjson/https://github.com/Tencent/rapidjson/

二、序列化思路

? ? ? 很多人都知道rapidjson这个json库,大家也都知道他的高效,可是你一定也对他的使用方法,函数API接口感受到非常不适应,你一定非常怀念使用java和C#对一个实体类的那么轻松加简单的直接json序列化,本篇博客使用一个RapidJsonHelper类,将帮你实现对一个C++实体类的的序列化和反序列化。

三、C++实体类的的序列化和反序列化 1、RapidjsonHelper帮助类

先看一下如何使用这个RapidjsonHelper帮助类

(1)RapidjsonHelper.h

#ifndef PB_UTILSRAPIDJSON #define PB_UTILSRAPIDJSON #include <iostream> #include <vector> #include <list> #include <functional> #include <algorithm> #include "rapidjson/document.h" #include "rapidjson/writer.h" #include "rapidjson/stringbuffer.h" #define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) #define RapidjsonWriteBegin(writer) {writer.StartObject(); #define RapidjsonWriteEnd() writer.EndObject();} #define RapidjsonWriteString(XXX) writer.Key(#XXX);writer.String(XXX.data()); #define RapidjsonWriteChar(XXX) writer.Key(#XXX);writer.String(XXX,strlen(XXX)); #define RapidjsonWriteInt(XXX) writer.Key(#XXX);writer.Int(XXX); #define RapidjsonWriteInt64(XXX) writer.Key(#XXX);writer.Int64(XXX); #define RapidjsonWriteUInt(XXX) writer.Key(#XXX);writer.UInt(XXX); #define RapidjsonWriteUint64(XXX) writer.Key(#XXX);writer.Uint64(XXX); #define RapidjsonWriteDouble(XXX) writer.Key(#XXX);writer.Double(XXX); #define RapidjsonWriteClass(XXX) writer.Key(#XXX);((JsonBase*)(&XXX))->ToWrite(writer); #define RapidjsonParseBegin(val) for (Value::ConstMemberIterator itr = val.MemberBegin(); itr != val.MemberEnd(); ++itr){ #define RapidjsonParseEnd() } #define RapidjsonParseToString(XXX) if (strcmp(itr->name.GetString(), #XXX) == 0)XXX = itr->value.GetString(); #define RapidjsonParseToInt(XXX) if (strcmp(itr->name.GetString(), #XXX) == 0)XXX = itr->value.GetInt(); #define RapidjsonParseToInt64(XXX) if (strcmp(itr->name.GetString(), #XXX) == 0)XXX = itr->value.GetInt64(); #define RapidjsonParseToUInt(XXX) if (strcmp(itr->name.GetString(), #XXX) == 0)XXX = itr->value.GetUint(); #define RapidjsonParseToUint64(XXX) if (strcmp(itr->name.GetString(), #XXX) == 0)XXX = itr->value.GetUint64(); #define RapidjsonParseToDouble(XXX) if (strcmp(itr->name.GetString(),#XXX) == 0)XXX = itr->value.GetDouble(); #define RapidjsonParseToClass(XXX)if (strcmp(itr->name.GetString(), #XXX) == 0)((JsonBase*)(&XXX))->ParseJson(itr->value); #define RapidjsonParseToChar(XXX)if (strcmp(itr->name.GetString(), #XXX) == 0)\ {\ int size = ARRAY_SIZE(XXX);\ const char *s = itr->value.GetString();\ int len = strlen(s);\ strncpy(XXX, s, std::min(size, len));\ }\ namespace PBLIB { namespace RapidJsonHelper { using namespace rapidjson; class JsonBase { public: JsonBase(){} ~JsonBase(){} std::string ToJson(); static void FromJson(JsonBase *p, const std::string &json); protected: template<typename T> static void ToWriteEvery(Writer<StringBuffer> &writer, T &val){ JsonBase *p = &val; p->ToWrite(writer); } static void ToWriteEvery(Writer<StringBuffer> &writer, int32_t &val); static void ToWriteEvery(Writer<StringBuffer> &writer, int64_t &val); static void ToWriteEvery(Writer<StringBuffer> &writer, uint32_t &val); static void ToWriteEvery(Writer<StringBuffer> &writer, uint64_t &val); static void ToWriteEvery(Writer<StringBuffer> &writer, double &val); static void ToWriteEvery(Writer<StringBuffer> &writer, bool &val); static void ToWriteEvery(Writer<StringBuffer> &writer, std::string &val); static void ToWriteEvery(Writer<StringBuffer> &writer, char * val); template<typename T> static void ToParseEvery(const Value &val, T &t) { JsonBase *p = &t; p->ParseJson(val); } static void ToParseEvery(const Value &val, int32_t &t); static void ToParseEvery(const Value &val, int64_t &t); static void ToParseEvery(const Value &val, uint32_t &t); static void ToParseEvery(const Value &val, uint64_t &t); static void ToParseEvery(const Value &val, double &t); static void ToParseEvery(const Value &val, bool &t); static void ToParseEvery(const Value &val, std::string &t); static void ToParseEvery(const Value &val, char t[]); public: virtual void ToWrite(Writer<StringBuffer> &writer); virtual void ParseJson(const Value& val); }; template<typename T> class JsonArray :public JsonBase { public: std::list<T> arr; JsonArray(){} ~JsonArray(){} public: virtual void ToWrite(Writer<StringBuffer> &writer) { writer.StartArray(); for each (T ent in arr) { ToWriteEvery(writer, ent); } writer.EndArray(); } virtual void ParseJson(const Value& val) { SizeType len = val.Size(); for (size_t i = 0; i < len; i++) { const Value &f = val[i]; T t; ToParseEvery(f, t); arr.push_back(t); } } }; } } #endif

(2)RapidjsonHelper.cpp

#include "RapidjsonHelper.h" namespace PBLIB { namespace RapidJsonHelper { using namespace rapidjson; void JsonBase::ToWriteEvery(Writer<StringBuffer> &writer, int32_t &val) { writer.Int(val); } void JsonBase::ToWriteEvery(Writer<StringBuffer> &writer, int64_t &val) { writer.Int64(val); } void JsonBase::ToWriteEvery(Writer<StringBuffer> &writer, uint32_t &val) { writer.Uint(val); } void JsonBase::ToWriteEvery(Writer<StringBuffer> &writer, uint64_t &val) { writer.Uint64(val); } void JsonBase::ToWriteEvery(Writer<StringBuffer> &writer, double &val) { writer.Double(val); } void JsonBase::ToWriteEvery(Writer<StringBuffer> &writer, bool &val) { writer.Bool(val); } void JsonBase::ToWriteEvery(Writer<StringBuffer> &writer, std::string &val) { writer.String(val.data()); } void JsonBase::ToWriteEvery(Writer<StringBuffer> &writer, char * val) { writer.String(val, strlen(val)); } void JsonBase::ToParseEvery(const Value &val, int32_t &t) { t = val.GetInt(); } void JsonBase::ToParseEvery(const Value &val, int64_t &t) { t = val.GetInt64(); } void JsonBase::ToParseEvery(const Value &val, uint32_t &t) { t = val.GetUint(); } void JsonBase::ToParseEvery(const Value &val, uint64_t &t) { t = val.GetUint64(); } void JsonBase::ToParseEvery(const Value &val, double &t) { t = val.GetDouble(); } void JsonBase::ToParseEvery(const Value &val, bool &t) { t = val.GetBool(); } void JsonBase::ToParseEvery(const Value &val, std::string &t) { t = val.GetString(); } void JsonBase::ToParseEvery(const Value &val, char t[]) { int size = ARRAY_SIZE(t); const char *s = val.GetString(); int len = strlen(s); strncpy(t, s, std::min(size, len)); } std::string JsonBase::ToJson(){ StringBuffer s; Writer<StringBuffer> writer(s); this->ToWrite(writer); return s.GetString(); } void JsonBase::FromJson(JsonBase *p, const std::string &json){ Document document; document.Parse(json.data()); const Value &val = document; p->ParseJson(val); } void JsonBase::ToWrite(Writer<StringBuffer> &writer) { } void JsonBase::ParseJson(const Value& val) { } } } 2、实体类的的序列化和反序列化

? ? ? 先创建两个实体类MyClass3和MyClass分别引用上RapidjsonHelper.h文件,继承好JsonBase这个父类,实现两个虚函数。

#pragma once #include "RapidjsonHelper.h" using namespace PBLIB::RapidJsonHelper; class MyClass3 :public JsonBase { public: int age; char name[100]; std::string text; double money; MyClass3(){ memset(name, 0, ARRAY_SIZE(name)); } ~MyClass3(){} void ToWrite(Writer<StringBuffer> &writer) { RapidjsonWriteBegin(writer); RapidjsonWriteString(text); RapidjsonWriteChar(name); RapidjsonWriteInt(age); RapidjsonWriteDouble(money); RapidjsonWriteEnd(); } void ParseJson(const Value &val) { RapidjsonParseBegin(val); RapidjsonParseToString(text); RapidjsonParseToInt(age); RapidjsonParseToDouble(money); RapidjsonParseToChar(name); RapidjsonParseEnd(); } };

? ? ?

#include "RapidjsonHelper.h" #include "MyClass3.h" using namespace PBLIB::RapidJsonHelper; class MyClass :public JsonBase { public: MyClass(){ memset(name, 0, ARRAY_SIZE(name)); } ~MyClass(){} int age; char name[100]; std::string text; double money; JsonArray<int> lst; JsonArray<MyClass3> lst2; void ToWrite(Writer<StringBuffer> &writer) { RapidjsonWriteBegin(writer); RapidjsonWriteString(text); RapidjsonWriteChar(name); RapidjsonWriteInt(age); RapidjsonWriteDouble(money); RapidjsonWriteClass(lst); RapidjsonWriteClass(lst2); RapidjsonWriteEnd(); } void ParseJson(const Value& val) { RapidjsonParseBegin(val); RapidjsonParseToString(text); RapidjsonParseToInt(age); RapidjsonParseToDouble(money); RapidjsonParseToChar(name); RapidjsonParseToClass(lst); RapidjsonParseToClass(lst2); RapidjsonParseEnd(); } }; ? 3、main函数

? ? ? ? 实体类有了序列化和反序列化的功能,?现在看主函数如何使用

// PB_RapidJsonHelper.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include "MyClass.h" int main(int argc, _TCHAR* argv[]) { MyClass mylclass2; mylclass2.age = 10; strcpy(mylclass2.name, "tt"); mylclass2.text = "myclass2"; mylclass2.money = 6; for (unsigned i = 0; i <10; i++) { MyClass3 tmp; tmp.age = 10; strcpy(tmp.name, "myclass3"); tmp.text = "123456"; tmp.money = 8; mylclass2.lst2.arr.push_back(tmp); } for (unsigned i = 0; i < 10; i++) { mylclass2.lst.arr.push_back(i); } //构造完成 //Json序列化 std::string str = mylclass2.ToJson();//序列化完成 std::cout<<str.c_str(); MyClass mylclass4; MyClass::FromJson(&mylclass4, str);//反序列化完成 return 0; }

??

? ? ? ?JsonBase类和JsonArray类作为基类封装了序列化和反序列化的逻辑,派生类只需要实现ToWrite和ParseJson方法。RapidjsonHelper.h和RapidjsonHelper.cpp实现了大部分逻辑和调用RaidJson方法。 主函数整个过程,看不到RapidJson的影子,这样以后即使换一个Json库,可以保持逻辑代码不用改,不足之处就是没有把接口抽象出来,接口抽象出来换成其它库就更方便了。整个实现过程,主要利用C++ 模板和重载,宏和以及虚方法,封装业务逻辑。

? ? ? 关于这个封装,还有性能可以提升,JsonArray对象里面的实现现在是用list,但是其实应该自己实现一个更高效list。比如可以使用vector或者kfifo。

四、下载C++序列化和反序列化-C++文档类资源-CSDN下载?很多人都知道rapidjson这个json库,大家也都知道他的高效,可是你一定也对他的使用方法,更多下载资源、学习资料请访问CSDN下载频道.https://download.csdn.net/download/kupe87826/84250701 五、参考

C++ 封装RapidJson把一个类Json序列化和反序列化_lightspear的专栏-CSDN博客_c++ json 序列化很多人都知道rapidjson这个json库,大家也都知道他的高效,可是你一定也对他的使用方法,函数API接口感受到非常不适应,你一定非常怀念使用java和C#对一个实体类的那么轻松加简单的直接json序列化,是的本篇博客将免费开源一个我自己平时做项目研发使用的一个RapidJsonHelper类,将帮你实现对一个C++实体类的的序列化和反序列化。先贴上可完美可运行测试源码(含rapidjsohttps://blog.csdn.net/lightspear/article/details/54836656#


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #rapidjson #反序列化 #是一个 #C # #JSON