diff --git a/cpp/utils.cc b/cpp/utils.cc index 88562b0..34de325 100644 --- a/cpp/utils.cc +++ b/cpp/utils.cc @@ -80,6 +80,136 @@ namespace f8 return true; } + static bool JsonToMessage(a8::XObject& jsonobj, google::protobuf::Message* msg) + { + const google::protobuf::Descriptor* descriptor = msg->GetDescriptor(); + const google::protobuf::Reflection* reflection = msg->GetReflection(); + + for (int i = 0; i < descriptor->field_count(); ++i) { + const google::protobuf::FieldDescriptor* field_desc = descriptor->field(i); + const std::string& field_name = field_desc->name(); + if (field_name.empty() || field_name[0] == '_') { + continue; + } + + if (field_desc->is_repeated()) { + std::shared_ptr repeated_field = jsonobj.At(field_name); + for (int i = 0; i < repeated_field->Size(); ++i) { + auto field_value = repeated_field->At(i); + switch (field_desc->cpp_type()) { + case google::protobuf::FieldDescriptor::CPPTYPE_STRING: + { + reflection->AddString(msg, field_desc, field_value->AsXValue()); + } + break; + case google::protobuf::FieldDescriptor::CPPTYPE_INT32: + { + reflection->AddInt32(msg, field_desc, field_value->AsXValue()); + } + break; + case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: + { + reflection->AddUInt32(msg, field_desc, field_value->AsXValue()); + } + break; + case google::protobuf::FieldDescriptor::CPPTYPE_INT64: + { + reflection->AddInt64(msg, field_desc, field_value->AsXValue()); + } + break; + case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: + { + reflection->AddUInt64(msg, field_desc, field_value->AsXValue()); + } + break; + case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: + { + reflection->AddFloat(msg, field_desc, (double)field_value->AsXValue()); + } + break; + case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: + { + reflection->AddDouble(msg, field_desc, field_value->AsXValue()); + } + break; + case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: + { + google::protobuf::Message* p = reflection->AddMessage(msg, field_desc); + JsonToMessage(*field_value, p); + } + break; + default: + { + abort(); + } + break; + }//end switch + } + } else { + switch (field_desc->cpp_type()) { + case google::protobuf::FieldDescriptor::CPPTYPE_STRING: + { + reflection->SetString(msg, field_desc, jsonobj.At(field_name)->AsXValue()); + } + break; + case google::protobuf::FieldDescriptor::CPPTYPE_INT32: + { + reflection->SetInt32(msg, field_desc, jsonobj.At(field_name)->AsXValue()); } + break; + case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: + { + reflection->SetUInt32(msg, field_desc, jsonobj.At(field_name)->AsXValue()); + } + break; + case google::protobuf::FieldDescriptor::CPPTYPE_INT64: + { + reflection->SetInt64(msg, field_desc, jsonobj.At(field_name)->AsXValue()); + } + break; + case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: + { + reflection->SetUInt64(msg, field_desc, jsonobj.At(field_name)->AsXValue()); + } + break; + case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: + { + reflection->SetFloat(msg, field_desc, (double)jsonobj.At(field_name)->AsXValue()); + } + break; + case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: + { + reflection->SetDouble(msg, field_desc, jsonobj.At(field_name)->AsXValue()); + } + break; + case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: + { + google::protobuf::Message* p = reflection->MutableMessage(msg, field_desc); + JsonToMessage(*jsonobj.At(field_name), p); + } + break; + default: + { + abort(); + } + break; + }//end switch + } + } + return true; + } + + bool ReadJsonMetaFile(const std::string& filename, + google::protobuf::Message* prototype, + std::function push_back_func) + { + a8::XObject json_reader; + json_reader.ReadFromJsonFile(filename); + google::protobuf::Message* msg = prototype->New(); + JsonToMessage(json_reader, msg); + push_back_func(msg); + return false; + } + void InitMysqlConnection(a8::mysql::Query* query) { a8::UdpLog::Instance()->Info("show variables like 'character%';", {}); diff --git a/cpp/utils.h b/cpp/utils.h index aca7d55..4dfcebe 100644 --- a/cpp/utils.h +++ b/cpp/utils.h @@ -38,6 +38,24 @@ namespace f8 }); } + bool ReadJsonMetaFile(const std::string& filename, + google::protobuf::Message* prototype, + std::function push_back_func); + + template + bool ReadJsonMetaFile(const std::string& filename, std::list& meta_list) + { + T dummy; + return ReadJsonMetaFile(filename, + &dummy, + [&meta_list] (google::protobuf::Message* msg) + { + T t; + t.CopyFrom(*msg); + meta_list.emplace_back(t); + }); + } + template static void RepeatedFieldToVector(const T1& t1, T2& t2)