C++11 json的强制结构化定义与rapidjson的JsonObject对象封装

1 篇文章 0 订阅
1 篇文章 0 订阅

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; }
};

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值