C++ 實用技術 - google protobuf反射技術 - 基礎API


使用過java的同學,可能會更容易理解反射的概念。C++語言級別裏面並沒有真正意義上的反射。google protobuf提供了的反射機制。可以讓我們在沒有對應數據的protobuf定義文件的時候,去操作數據。

反射相關的類和API

google::protobuf::Message

接口類,在類MessageLite的基礎上增加了descriptors和reflection

//google::protobuf::Message
const Descriptor* GetDescriptor() const;
const Reflection* GetReflection() const;

google::protobuf::Descriptor

描述一種Message類型(不是一個單獨的message對象)的meta信息

//Descriptor
//返回message的屬性個數
int field_count() const;
//返回第index個屬性
const FieldDescriptor* field(int index) const;
//通過proto文件裏面定義的tag, 返回屬性
const FieldDescriptor* FindFieldByNumber(int number) const;
//通過屬性名,返回屬性
const FieldDescriptor* FindFieldByName(const std::string& name) const;
//通過小寫的屬性名,返回屬性
const FieldDescriptor* FindFieldByLowercaseName(
      const std::string& lowercase_name) const;
//通過駝峯屬性名,返回屬性
const FieldDescriptor* FindFieldByCamelcaseName(
      const std::string& camelcase_name) const;
//返回枚舉類型的數量
int enum_type_count() const;
//返回第index個枚舉類型屬性
const EnumDescriptor* enum_type(int index) const;
//通過名稱,返回枚舉屬性
const EnumDescriptor* FindEnumTypeByName(const std::string& name) const;
//通過屬性值,返回枚舉值屬性
const EnumValueDescriptor* FindEnumValueByName(const std::string& name) const;

google::protobuf::Reflection

接口類,提供方法來動態訪問/修改message中的field的接口類

//檢查message中的非repeated屬性是否存在
bool HasField(const Message& message, const FieldDescriptor* field) const;
//返回message中repeated屬性的長度
int FieldSize(const Message& message, const FieldDescriptor* field) const;
//清除message中的屬性,非repeated屬性HashField返回false,repeated屬性FieldSize返回0
void ClearField(Message* message, const FieldDescriptor* field) const;
//返回message中除Unknown的屬性,包括所有HashField返回爲true,FieldSize非0的屬性
void ListFields(const Message& message,
                  std::vector<const FieldDescriptor*>* output) const;
//返回message對應屬性的,對應類型的返回值
int32 GetInt32(const Message& message, const FieldDescriptor* field) const;
  int64 GetInt64(const Message& message, const FieldDescriptor* field) const;
  uint32 GetUInt32(const Message& message, const FieldDescriptor* field) const;
  uint64 GetUInt64(const Message& message, const FieldDescriptor* field) const;
  float GetFloat(const Message& message, const FieldDescriptor* field) const;
  double GetDouble(const Message& message, const FieldDescriptor* field) const;
  bool GetBool(const Message& message, const FieldDescriptor* field) const;
  std::string GetString(const Message& message,
                        const FieldDescriptor* field) const;
  const EnumValueDescriptor* GetEnum(const Message& message,
                                     const FieldDescriptor* field) const;

//返回message,屬性的value的int類型值
int GetEnumValue(const Message& message, const FieldDescriptor* field) const;
const Message& GetMessage(const Message& message,
                            const FieldDescriptor* field,
                            MessageFactory* factory = nullptr) const;

//設置message,對應屬性的對應類型的值
void SetInt32(Message* message, const FieldDescriptor* field,
                int32 value) const;
  void SetInt64(Message* message, const FieldDescriptor* field,
                int64 value) const;
  void SetUInt32(Message* message, const FieldDescriptor* field,
                 uint32 value) const;
  void SetUInt64(Message* message, const FieldDescriptor* field,
                 uint64 value) const;
  void SetFloat(Message* message, const FieldDescriptor* field,
                float value) const;
  void SetDouble(Message* message, const FieldDescriptor* field,
                 double value) const;
  void SetBool(Message* message, const FieldDescriptor* field,
               bool value) const;
  void SetString(Message* message, const FieldDescriptor* field,
                 const std::string& value) const;
  void SetEnum(Message* message, const FieldDescriptor* field,
               const EnumValueDescriptor* value) const;
  void SetEnumValue(Message* message, const FieldDescriptor* field,
                    int value) const;
  Message* MutableMessage(Message* message, const FieldDescriptor* field,
                          MessageFactory* factory = nullptr) const;

//返回message對應屬性repeated字段的index位置的值
int32 GetRepeatedInt32(const Message& message, const FieldDescriptor* field,
                         int index) const;
  int64 GetRepeatedInt64(const Message& message, const FieldDescriptor* field,
                         int index) const;
  uint32 GetRepeatedUInt32(const Message& message, const FieldDescriptor* field,
                           int index) const;
  uint64 GetRepeatedUInt64(const Message& message, const FieldDescriptor* field,
                           int index) const;
  float GetRepeatedFloat(const Message& message, const FieldDescriptor* field,
                         int index) const;
  double GetRepeatedDouble(const Message& message, const FieldDescriptor* field,
                           int index) const;
  bool GetRepeatedBool(const Message& message, const FieldDescriptor* field,
                       int index) const;
  std::string GetRepeatedString(const Message& message,
                                const FieldDescriptor* field, int index) const;
  const EnumValueDescriptor* GetRepeatedEnum(const Message& message,
                                             const FieldDescriptor* field,
                                             int index) const;
  int GetRepeatedEnumValue(const Message& message, const FieldDescriptor* field,
                           int index) const;
  const Message& GetRepeatedMessage(const Message& message,
                                    const FieldDescriptor* field,
                                    int index) const;
//設置message的repeated屬性的index位置對應類型的value的值
void SetRepeatedInt32(Message* message, const FieldDescriptor* field,
                        int index, int32 value) const;
  void SetRepeatedInt64(Message* message, const FieldDescriptor* field,
                        int index, int64 value) const;
  void SetRepeatedUInt32(Message* message, const FieldDescriptor* field,
                         int index, uint32 value) const;
  void SetRepeatedUInt64(Message* message, const FieldDescriptor* field,
                         int index, uint64 value) const;
  void SetRepeatedFloat(Message* message, const FieldDescriptor* field,
                        int index, float value) const;
  void SetRepeatedDouble(Message* message, const FieldDescriptor* field,
                         int index, double value) const;
  void SetRepeatedBool(Message* message, const FieldDescriptor* field,
                       int index, bool value) const;
  void SetRepeatedString(Message* message, const FieldDescriptor* field,
                         int index, const std::string& value) const;
  void SetRepeatedEnum(Message* message, const FieldDescriptor* field,
                       int index, const EnumValueDescriptor* value) const;
  void SetRepeatedEnumValue(Message* message, const FieldDescriptor* field,
                            int index, int value) const;
  Message* MutableRepeatedMessage(Message* message,
                                  const FieldDescriptor* field,
                                  int index) const;

google::protobuf::FieldDescriptor

Message類的具體屬性的描述,包含類型,名稱,label,tag,proto文件等等信息

  //是否是必須的
  bool is_required() const;  // shorthand for label() == LABEL_REQUIRED
  //是否是可選的
  bool is_optional() const;  // shorthand for label() == LABEL_OPTIONAL
  //是否是repeated
  bool is_repeated() const;  // shorthand for label() == LABEL_REPEATED
  //是否可以pack
  bool is_packable() const;  // shorthand for is_repeated() &&
                             //               IsTypePackable(type())
  //是否是packed
  bool is_packed() const;    // shorthand for is_packable() &&
                             //               options().packed()
  //是否是message
  bool is_map() const;       // shorthand for type() == TYPE_MESSAGE &&
                             // message_type()->options().map_entry()
 //屬性在message的索引位置
 int index() const;

google::protobuf::UnknownFieldSet

保存協議中未知的屬性集合

  //返回UnknownField的數量
  inline int field_count() const;
  //返回index位置的UnknownField
  inline const UnknownField& field(int index) const;
  //返回index位置的UnknownField指針,可修改
  inline UnknownField* mutable_field(int index);
  //添加UnknownField
  void AddVarint(int number, uint64 value);
  void AddFixed32(int number, uint32 value);
  void AddFixed64(int number, uint64 value);
  void AddLengthDelimited(int number, const std::string& value);
  std::string* AddLengthDelimited(int number);

  // Adds an unknown field from another set.
  void AddField(const UnknownField& field);

其他相關

C++ Google Protobuf 反射技術基礎API
C++ 實用技術 – google protobuf反射技術 – 轉成JSON格式
C++ 實用技術 - google protobuf反射技術 - 轉成YAML格式

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章