in aios/hippo/src/http_client/PBJson.cpp [103:251]
int PBJson::json2field(const rapidjson::Value* json,
google::protobuf::Message* msg,
const google::protobuf::FieldDescriptor *field,
std::string& err){
const Reflection *ref = msg->GetReflection();
const bool repeated = field->is_repeated();
switch (field->cpp_type()){
case FieldDescriptor::CPPTYPE_INT32:{
if (json->GetType() != rapidjson::kNumberType){
RETURN_ERR(ERR_INVALID_JSON, "Not a number");
}
if (repeated){
ref->AddInt32(msg, field, (int32_t) json->GetInt());
}
else{
ref->SetInt32(msg, field, (int32_t) json->GetInt());
}
break;
}
case FieldDescriptor::CPPTYPE_UINT32:{
if (json->GetType() != rapidjson::kNumberType){
RETURN_ERR(ERR_INVALID_JSON, "Not a number");
}
if (repeated){
ref->AddUInt32(msg, field, json->GetUint());
}
else{
ref->SetUInt32(msg, field, json->GetUint());
}
break;
}
case FieldDescriptor::CPPTYPE_INT64:{
if (json->GetType() != rapidjson::kNumberType){
RETURN_ERR(ERR_INVALID_JSON, "Not a number");
}
if (repeated){
ref->AddInt64(msg, field, json->GetInt64());
}
else{
ref->SetInt64(msg, field, json->GetInt64());
}
break;
}
case FieldDescriptor::CPPTYPE_UINT64:{
if (json->GetType() != rapidjson::kNumberType){
RETURN_ERR(ERR_INVALID_JSON, "Not a number");
}
if (repeated){
ref->AddUInt64(msg, field, json->GetUint64());
}
else{
ref->SetUInt64(msg, field, json->GetUint64());
}
break;
}
case FieldDescriptor::CPPTYPE_DOUBLE:{
if (json->GetType() != rapidjson::kNumberType){
RETURN_ERR(ERR_INVALID_JSON, "Not a number");
}
if (repeated){
ref->AddDouble(msg, field, json->GetDouble());
}
else{
ref->SetDouble(msg, field, json->GetDouble());
}
break;
}
case FieldDescriptor::CPPTYPE_FLOAT:{
if (json->GetType() != rapidjson::kNumberType){
RETURN_ERR(ERR_INVALID_JSON, "Not a number");
}
if (repeated){
ref->AddFloat(msg, field, json->GetDouble());
}
else{
ref->SetFloat(msg, field, json->GetDouble());
}
break;
}
case FieldDescriptor::CPPTYPE_BOOL:{
if (json->GetType() != rapidjson::kTrueType &&
json->GetType() != rapidjson::kFalseType){
RETURN_ERR(ERR_INVALID_JSON, "Not a bool");
}
bool v = json->GetBool();
if (repeated){
ref->AddBool(msg, field, v);
}
else{
ref->SetBool(msg, field, v);
}
break;
}
case FieldDescriptor::CPPTYPE_STRING:{
if (json->GetType() != rapidjson::kStringType){
RETURN_ERR(ERR_INVALID_JSON, "Not a string");
}
const char* value = json->GetString();
uint32_t str_size = json->GetStringLength();
std::string str_value(value, str_size);
if (field->type() == FieldDescriptor::TYPE_BYTES){
if (repeated){
ref->AddString(msg, field, b64_decode(str_value));
}
else{
ref->SetString(msg, field, b64_decode(str_value));
}
}
else{
if (repeated){
ref->AddString(msg, field, str_value);
}
else{
ref->SetString(msg, field, str_value);
}
}
break;
}
case FieldDescriptor::CPPTYPE_MESSAGE:{
Message *mf = (repeated) ? ref->AddMessage(msg, field) :
ref->MutableMessage(msg, field);
return parse_json(json, mf, err);
}
case FieldDescriptor::CPPTYPE_ENUM:{
const EnumDescriptor *ed = field->enum_type();
const EnumValueDescriptor *ev = 0;
if (json->GetType() == rapidjson::kNumberType){
ev = ed->FindValueByNumber(json->GetInt());
}
else if (json->GetType() == rapidjson::kStringType){
ev = ed->FindValueByName(json->GetString());
}
else
RETURN_ERR(ERR_INVALID_JSON, "Not an integer or string");
if (!ev)
RETURN_ERR(ERR_INVALID_JSON, "Enum value not found");
if (repeated){
ref->AddEnum(msg, field, ev);
}
else{
ref->SetEnum(msg, field, ev);
}
break;
}
default:
break;
}
return 0;
}