rapidjson,是C++里性能最好JSON解析库,在自己笔记本上每秒可解析十万次普通规模JSON,非常适合对性能有要求的服务器开发。
但使用起来有些麻烦。所以我封装了下,更方便使用,增加开发效率。
第一步,封装rapidjson为JsonObject,像使用脚本语言一样get set = ,封装函数getIntValue,getStringValue,getBoolValue,getArrValue及对应的set
下面是Object .h代码
#ifndef OBJECT_H
#define OBJECT_H
#pragma once
#include <memory>
class Object : public std::enable_shared_from_this<Object>
{
public:
Object();
virtual ~Object();
virtual void setBindObject(std::shared_ptr<Object> pObject) { m_pBindObject = pObject; }
virtual std::shared_ptr<Object> getBindObject() { return m_pBindObject; }
std::shared_ptr<Object> m_pBindObject;
};
#endif // !OBJECT_H
#include "Object.h"
Object::Object()
{
}
Object::~Object()
{
}
下面是JsonObject代码
#ifndef JSONOBJECT_H
#define JSONOBJECT_H
#pragma once
#include "rapidjson/document.h"
#include "rapidjson/writer.h"
#include "rapidjson/stringbuffer.h"
#include <vector>
#include<memory>
#include "Object.h"
using namespace rapidjson;
using namespace std;
class JsonObject :public Object
{
public:
JsonObject();
//JsonObject(shared_ptr<Document> pDoc, Value* pValue);
virtual bool init(shared_ptr<Document> pDoc, Value* pValue);
virtual void onInit() {};
JsonObject& operator=(const JsonObject& cls);
bool operator==(const JsonObject& cls);
bool Parse(const char* pStrJson);
bool isNotNull();
shared_ptr<JsonObject> getObject(const char *pName);
shared_ptr<JsonObject> setObject(const char* pName,const JsonObject& value);
JsonObject makeObject(const char* pName);
template<class T> shared_ptr<T> getObject(const char* pName)
{
Value::MemberIterator member = m_pValue->FindMember(pName);
if (member == m_pValue->MemberEnd())
{
return nullptr;
}
//T newObject;
auto newObject =std::make_shared<T>();
newObject->init(m_pJsonDoc, &member->value);
return newObject;
}
template<class T> shared_ptr<T> setObject(const char* pName, const T* pValue)
{
if ((this) == pValue) {
return dynamic_pointer_cast<T>(shared_from_this());
}
rapidjson::Value obj(rapidjson::kObjectType);
obj.CopyFrom(*pValue->m_pValue, m_pJsonDoc->GetAllocator());
auto& all = m_pJsonDoc->GetAllocator();
m_pValue->AddMember(StringRef(pName), obj, all);
return getObject<T>(pName);
}
template<class T> shared_ptr<T> makeObject(const char* pName);
bool haveValue(const char* pName);
int getIntValue(const char* pName);
const char* getStringValue(const char* pName);
bool setIntValue(const char* pName,int value);
bool setStrValue(const char* pName, const char* value);
bool setLongValue(const char* pName, long long value);
long long getLongValue(const char* pName);
bool getBoolValue(const char* pName);
void setBoolValue(const char* pName,bool value);
bool setArrValue(const char* pName, const std::vector<std::string>& arrvalue);
void addArrValue(const char* pName,const char *pValue);
void addArrObjectValue(const char* pName, const JsonObject *pValue);
std::vector<std::string> getArrValue(const char* pName);
virtual std::string toString();
virtual std::string preToString();
std::shared_ptr<Document> m_pJsonDoc;
Value* m_pValue;
std::vector<shared_ptr<Value>> m_vectOutValue;
std::string m_strJson;
};
#endif // !JSONOBJECT_H
下面是CPP代码
#include "JsonObject.h"
JsonObject::JsonObject()
{
m_pJsonDoc = nullptr;
m_pValue = nullptr;
init(nullptr, nullptr);
}
bool JsonObject::init(shared_ptr<Document> pDoc, Value* pValue)
{
if (m_pJsonDoc != pDoc) {
m_pJsonDoc = pDoc;
}
if (m_pValue != pValue) {
m_pValue = pValue;
}
if (m_pJsonDoc == nullptr) {
auto pDoc = std::make_shared<Document>();
pDoc->SetObject();
m_pJsonDoc = pDoc;
m_pValue = pDoc.get();
}
this->onInit();
return true;
}
JsonObject& JsonObject::operator=(const JsonObject& cls)
{
if (this != &cls)
{
this->m_pJsonDoc = cls.m_pJsonDoc;
this->m_pValue = cls.m_pValue;
}
return *this;
}
bool JsonObject::operator==(const JsonObject& cls)
{
if (this == &cls) {
return true;
}
if (this->m_pJsonDoc == cls.m_pJsonDoc && this->m_pValue == cls.m_pValue) {
return true;
}
return false;
}
bool JsonObject::Parse(const char* pStrJson)
{
if (m_pJsonDoc) {
//return false;
}
auto pDoc = m_pJsonDoc;
pDoc->Parse(pStrJson);
//auto pValue = pDoc.get();
//this->init(pDoc,pValue);
return true;
}
bool JsonObject::isNotNull()
{
if (m_pJsonDoc && m_pValue) {
return true;
}
return false;
}
shared_ptr<JsonObject> JsonObject::getObject(const char* pName)
{
Value::MemberIterator member = m_pValue->FindMember(pName);
if (member == m_pValue->MemberEnd())
{
return nullptr;
}
//shared_ptr<Value> pValue2(&member->value);
//m_vectOutValue.push_back(pValue2);
auto obj = std::make_shared<JsonObject>();
obj->init(m_pJsonDoc, &member->value);
return obj;
}
shared_ptr<JsonObject> JsonObject::setObject(const char* pName, const JsonObject& value)
{
if ((*this) == value) {
return dynamic_pointer_cast<JsonObject>(shared_from_this());
}
rapidjson::Value obj(rapidjson::kObjectType);
if (value.m_pJsonDoc != nullptr && value.m_pValue != nullptr) {
obj.CopyFrom(*value.m_pValue, m_pJsonDoc->GetAllocator());
}
auto& all = m_pJsonDoc->GetAllocator();
m_pValue->AddMember(StringRef(pName), obj, all);
return getObject(pName);
}
template<class T> shared_ptr<T> JsonObject::makeObject(const char* pName)
{
Value::MemberIterator member = m_pValue->FindMember(pName);
if (member == m_pValue->MemberEnd())
{
auto& all = m_pJsonDoc->GetAllocator();
rapidjson::Value obj(rapidjson::kObjectType);
m_pValue->AddMember(StringRef(pName), obj, all);
}
member = m_pValue->FindMember(pName);
if (member == m_pValue->MemberEnd()) {
assert(false);
std::string str = "JsonObject::makeObject Failed Key:";
str += pName;
throw std::invalid_argument(str);
}
shared_ptr<Value> pValue2(&member->value);
m_vectOutValue.push_back(pValue2);
T newObject;
newObject.init(m_pJsonDoc, pValue2);
rapidjson::Value obj;
return newObject;
}
JsonObject JsonObject::makeObject(const char* pName)
{
Value::MemberIterator member = m_pValue->FindMember(pName);
if (member == m_pValue->MemberEnd())
{
auto& all = m_pJsonDoc->GetAllocator();
rapidjson::Value obj(rapidjson::kObjectType);
m_pValue->AddMember(StringRef(pName), obj, all);
}
member = m_pValue->FindMember(pName);
if (member == m_pValue->MemberEnd()) {
assert(false);
std::string str = "JsonObject::makeObject Failed Key:";
str += pName;
throw std::invalid_argument(str);
}
//shared_ptr<Value> pValue2(&member->value);
//m_vectOutValue.push_back(pValue2);
JsonObject obj;
obj.init(m_pJsonDoc, &member->value);
return obj;
}
bool JsonObject::haveValue(const char* pName)
{
Value::MemberIterator member = m_pValue->FindMember(pName);
if (member == m_pValue->MemberEnd())
{
return false;
}
return false;
}
int JsonObject::getIntValue(const char* pName)
{
Value::MemberIterator member = m_pValue->FindMember(pName);
if (member == m_pValue->MemberEnd())
{
//assert(false);
return 0;
}
Value& obj = member->value;
return obj.GetInt();
}
const char* JsonObject::getStringValue(const char* pName)
{
Value::MemberIterator member = m_pValue->FindMember(pName);
if (member == m_pValue->MemberEnd())
{
return nullptr;
}
Value& obj = member->value;
return obj.GetString();
}
bool JsonObject::setIntValue(const char* pName, int value)
{
Value::MemberIterator member = m_pValue->FindMember(pName);
if (member == m_pValue->MemberEnd())
{
auto& all = m_pJsonDoc->GetAllocator();
m_pValue->AddMember(StringRef(pName), rapidjson::Value(value), all);
}
else {
member->value.SetInt(value);
}
return true;
}
bool JsonObject::setLongValue(const char* pName, long long value)
{
Value::MemberIterator member = m_pValue->FindMember(pName);
if (member == m_pValue->MemberEnd())
{
auto& all = m_pJsonDoc->GetAllocator();
m_pValue->AddMember(StringRef(pName), rapidjson::Value(value), all);
}
else {
member->value.SetInt64(value);
}
return true;
}
long long JsonObject::getLongValue(const char* pName)
{
Value::MemberIterator member = m_pValue->FindMember(pName);
if (member == m_pValue->MemberEnd())
{
assert(false);
}
Value& obj = member->value;
return obj.GetInt64();
}
bool JsonObject::getBoolValue(const char* pName)
{
Value::MemberIterator member = m_pValue->FindMember(pName);
if (member == m_pValue->MemberEnd())
{
//assert(false);
}
Value& obj = member->value;
return obj.GetBool();
}
void JsonObject::setBoolValue(const char* pName, bool value)
{
Value::MemberIterator member = m_pValue->FindMember(pName);
if (member == m_pValue->MemberEnd())
{
auto& all = m_pJsonDoc->GetAllocator();
m_pValue->AddMember(StringRef(pName), rapidjson::Value(value), all);
}
else {
member->value.SetBool(value);
}
}
bool JsonObject::setArrValue(const char* pName, const std::vector<std::string>& arrvalue)
{
Value::MemberIterator member = m_pValue->FindMember(pName);
if (member == m_pValue->MemberEnd())
{
auto& all = m_pJsonDoc->GetAllocator();
rapidjson::Value obj(rapidjson::kArrayType);
m_pValue->AddMember(StringRef(pName), obj, all);
auto iter = arrvalue.begin();
for (; iter != arrvalue.end(); iter++) {
obj.PushBack(StringRef(iter->c_str()), all);
}
}
else {
member->value.SetArray();
auto& all = m_pJsonDoc->GetAllocator();
auto iter = arrvalue.begin();
for (; iter != arrvalue.end(); iter++) {
member->value.PushBack(StringRef(iter->c_str()), all);
}
}
return true;
}
void JsonObject::addArrValue(const char* pName, const char *pValue)
{
Value::MemberIterator member = m_pValue->FindMember(pName);
if (member == m_pValue->MemberEnd())
{
auto& all = m_pJsonDoc->GetAllocator();
rapidjson::Value obj(rapidjson::kArrayType);
m_pValue->AddMember(StringRef(pName), obj, all);
obj.PushBack(StringRef(pValue), all);
}
else {
auto &value = member->value;
auto& all = m_pJsonDoc->GetAllocator();
if (value.IsArray()) {
value.PushBack(StringRef(pValue), all);
}
}
}
void JsonObject::addArrObjectValue(const char* pName, const JsonObject *pValue)
{
Value::MemberIterator member = m_pValue->FindMember(pName);
if (member == m_pValue->MemberEnd())
{
auto& all = m_pJsonDoc->GetAllocator();
rapidjson::Value obj(rapidjson::kArrayType);
rapidjson::Value iterValue(rapidjson::kObjectType);
iterValue.CopyFrom((*pValue->m_pValue), all);
obj.PushBack(iterValue, all);
m_pValue->AddMember(StringRef(pName), obj, all);
}
else {
auto &value = member->value;
auto& all = m_pJsonDoc->GetAllocator();
if (value.IsArray()) {
rapidjson::Value iterValue(rapidjson::kObjectType);
iterValue.CopyFrom((*pValue->m_pValue), all);
value.PushBack(iterValue, all);
}
}
}
std::vector<std::string> JsonObject::getArrValue(const char* pName)
{
Value::MemberIterator member = m_pValue->FindMember(pName);
if (member == m_pValue->MemberEnd())
{
}
else {
auto &value = member->value;
auto& all = m_pJsonDoc->GetAllocator();
if (value.IsArray()) {
std::vector<std::string> arrValue;
auto iter = value.Begin();
for (; iter != value.End(); iter++) {
arrValue.push_back(iter->GetString());
}
return arrValue;
}
}
return std::vector<std::string>();
}
bool JsonObject::setStrValue(const char* pName, const char* value)
{
if (!value) {
return false;
}
Value::MemberIterator member = m_pValue->FindMember(pName);
if (member == m_pValue->MemberEnd())
{
auto& all = m_pJsonDoc->GetAllocator();
rapidjson::Value setvalue(rapidjson::kStringType);
setvalue.SetString(value, all);
m_pValue->AddMember(StringRef(pName), setvalue, all);
}
else {
auto& all = m_pJsonDoc->GetAllocator();
member->value.SetString(StringRef(value), all);
}
return true;
}
std::string JsonObject::toString()
{
if (m_strJson.size()) {
return m_strJson;
}
StringBuffer buffer;
Writer<StringBuffer> writer(buffer);
m_pValue->Accept(writer);
return buffer.GetString();
}
std::string JsonObject::preToString()
{
StringBuffer buffer;
Writer<StringBuffer> writer(buffer);
m_pValue->Accept(writer);
m_strJson = buffer.GetString();
return m_strJson;
}
第二部、强制结构定义实现,主要用C++11宏方式,下面是使用方式。
class NetPack_sendmsg : public JsonObjectDef
{
public:
JSON_STR(sessiontype);
JSON_STR(fromuserid);
JSON_STR(touserid);
JSON_STR(msgtype);
JSON_STR(msgdata);
JSON_BOOL(boffline);
};
NetPack_sendmsg *pMsg = new NetPack_sendmsg;
pMsg->get_sessiontypeWithStr();
pMsg->set_sessiontypeWithStr("");
pMsg->get_bofflineWithBool();
pMsg->set_bofflineWithBool(true);
下面是源码文件:
#include "JsonObject.h"
#define JSON_GETSTR(name) const char* get_##name##WithStr(){return this->getStringValue(#name);}
#define JSON_GETINT(name) int get_##name##WithInt(){return this->getIntValue(#name);}
#define JSON_SETSTR(name) void set_##name##WithStr(const char *pValue){this->setStrValue(#name,pValue);}
#define JSON_SETINT(name) void set_##name##WithInt(int value){this->setIntValue(#name,value);}
#define JSON_SETCLASS(name,classname) classname set_##name##WithObject(const classname& invalue){this->setObject<classname>(#name,invalue);}
#define JSON_GETCLASS(name,classname) classname get_##name##WithObject(){return this->getObject<classname>(#name);}
#define JSON_MAKEOBJECT(name,classname) classname make_##name##WithObject(){return this->makeObject<classname>(#name);}
#define JSON_GETLONG(name) long long get_##name##WithLong(){return this->getLongValue(#name);}
#define JSON_SETLONG(name) void set_##name##WithLong(long long value){this->setLongValue(#name,value);}
#define JSON_GETBOOL(name) bool get_##name##WithBool(){return this->getBoolValue(#name);}
#define JSON_SETBOOL(name) void set_##name##WithBool(bool value){this->setBoolValue(#name,value);}
#define JSON_GETARR(name) std::vector<std::string> get_##name##WithArr(){return this->getArrValue(#name);}
#define JSON_SETARR(name) void set_##name##WithArr(const std::vector<std::string>& arrvalue){this->setArrValue(#name,arrvalue);}
#define JSON_ARRADDVALUE(name) void add_##name##ArrValue(const char *pValue){this->addArrValue(#name,pValue);}
#define JSON_ARRADDOBJVALUE(name) void add_##name##ArrObjValue(const JsonObject *pValue){this->addArrObjectValue(#name,pValue);}
#define JSON_INT(name) JSON_GETINT(name) JSON_SETINT(name);
#define JSON_LONG(name) JSON_GETLONG(name) JSON_SETLONG(name);
#define JSON_STR(name) JSON_GETSTR(name) JSON_SETSTR(name);
#define JSON_ARR(name) JSON_GETARR(name) JSON_SETARR(name) JSON_ARRADDVALUE(name)
#define JSON_BOOL(name) JSON_GETBOOL(name) JSON_SETBOOL(name);
#define JSON_CMD(name) virtual std::string getCmdStr() { return MsgType::##name##; }
class JsonObjectDef :
public JsonObject
{
public:
virtual std::string getCmdStr() { return MsgType::nulldef; }
};