/*
* data: 2018-04-14
* author: cc509a
* email:
* protocol buffer and json convert each other
* support array ,enum
*/
#ifndef MYLIB_JSON_2_PB
# define MYLIB_JSON_2_PB
#include "json.h"
#include <google/protobuf/descriptor.h>
#include <google/protobuf/message.h>
namespace mylib {
class MylibJson2Pb {
public:
typedef ::google::protobuf::Message ProtobufMsg;
typedef ::google::protobuf::Reflection ProtobufReflection;
typedef ::google::protobuf::FieldDescriptor ProtobufFieldDescriptor;
typedef ::google::protobuf::Descriptor ProtobufDescriptor;
public:
/* 枚举是字符串 enum2str 传true */
static void PbMsg2JsonStr(const ProtobufMsg& src, std::string& dst, bool enum2str = false)
{
Json::Value value;
PbMsg2Json(src, value, enum2str);
Json::FastWriter writer;
dst = writer.write(value);
}
static bool JsonStr2PbMsg(const std::string& src, ProtobufMsg& dst, bool str2enum = false)
{
Json::Value value;
Json::Reader reader(Json::Features::strictMode());
if (!reader.parse(src, value))
{
LOG_ERROR("parse json string is fail,str=%s", src.c_str());
return false;
}
if(true != Json2PbMsg(value, dst, str2enum))
{
LOG_ERROR("pb convert error");
return false;
}
return true;
}
static bool Json2PbMsg(const Json::Value& src, ProtobufMsg& dst, bool str2enum = false)
{
const ProtobufDescriptor* descriptor = dst.GetDescriptor();
const ProtobufReflection* reflection = dst.GetReflection();
if (NULL == descriptor || NULL == reflection) return false;
int32_t count = descriptor->field_count();
for (int32_t i = 0; i < count; ++i)
{
const ProtobufFieldDescriptor* field = descriptor->field(i);
if (NULL == field) continue;
if(!src.isMember(field->name()))
{
continue;
}
const Json::Value& value = src[field->name()];
if (field->is_repeated())
{
if (!value.isArray())
{
LOG_ERROR("pb error");
return false;
}
else
{
Json2RepeatedMessage(value, dst, field, reflection, str2enum);
continue;
}
}
switch (field->type())
{
case ProtobufFieldDescriptor::TYPE_BOOL:
{
if (value.isBool())
{
reflection->SetBool(&dst, field, value.asBool());
}
else if (value.isInt())
{
reflection->SetBool(&dst, field, value.isInt());
}
else if (value.isString())
{
if (value.asString() == "true")
reflection->SetBool(&dst, field, true);
else if (value.asString() == "false")
reflection->SetBool(&
c++ json与protobuf 转换
最新推荐文章于 2023-10-27 19:15:00 发布