int PBJson::json2field()

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