// Copyright (c) 2023, 2024, Oracle and/or its affiliates. // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License, version 2.0, // as published by the Free Software Foundation. // // This program is designed to work with certain software (including // but not limited to OpenSSL) that is licensed under separate terms, // as designated in a particular file or component or in included license // documentation. The authors of MySQL hereby grant you an additional // permission to link the program and your derivative works with the // separately licensed software that they have either included with // the program or referenced in the documentation. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License, version 2.0, for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. #ifndef MYSQL_SERIALIZATION_FIELD_DEFINITION_H #define MYSQL_SERIALIZATION_FIELD_DEFINITION_H #include #include "mysql/serialization/field_functor.h" #include "mysql/serialization/serializable_type_tags.h" #include "mysql/serialization/serialization_types.h" #include "mysql/serialization/unknown_field_policy.h" /// @file /// Experimental API header /// @addtogroup GroupLibsMysqlSerialization /// @{ namespace mysql::serialization { /// @brief Field definition provided by classes implementing Serializable /// interface template class Field_definition { public: using Tag = Field_definition_tag; using Field_type_ref = std::reference_wrapper; /// @brief Constructs field definition object /// @param[in] field Reference to described field object /// externally, serializer may ignore this value or use it to hide some fields /// @param[in] encode_predicate Function that is called for optional fields, /// defines whether field will be encoded /// @param[in] unknown_field_policy What decoder should do in case this /// field definition is unknown to the decoder (error / ignore) /// @param[in] field_missing_functor Function that is called for this /// field in case it is not available in encoded data Field_definition(Field_type &field, Field_encode_predicate encode_predicate, Unknown_field_policy unknown_field_policy, Field_missing_functor field_missing_functor) : Field_definition(field, encode_predicate, unknown_field_policy) { m_field_missing_functor = field_missing_functor; } /// @brief Constructs field definition object /// @param[in] field Reference to described field object /// @param[in] unknown_field_policy What decoder should do in case this /// field definition is unknown to the decoder (error / ignore) Field_definition( Field_type &field, Unknown_field_policy unknown_field_policy = Unknown_field_policy::ignore) : m_ref(field), m_unknown_field_policy(unknown_field_policy) { m_encode_predicate = Field_encode_predicate([]() -> bool { return true; }); m_field_missing_functor = Field_missing_functor([]() -> void {}); } /// @brief Constructs field definition object /// @param[in] field Reference to described field object /// @param[in] unknown_field_policy What decoder should do in case this /// field definition is unknown to the decoder (error / ignore) /// @param[in] encode_predicate Function that is called for optional fields, /// defines whether field will be encoded Field_definition( Field_type &field, Field_encode_predicate encode_predicate, Unknown_field_policy unknown_field_policy = Unknown_field_policy::ignore) : Field_definition(field, unknown_field_policy) { m_encode_predicate = encode_predicate; } /// @brief Constructs field definition object /// @param[in] field Reference to described field object /// @param[in] field_missing_functor Function that is called for this /// field in case it is not available in encoded data Field_definition(Field_type &field, Field_missing_functor field_missing_functor) : Field_definition(field) { m_field_missing_functor = field_missing_functor; } Field_type &get_ref() { return m_ref.get(); } const Field_type &get_ref() const { return m_ref.get(); } /// @brief Runs "field missing functor" in case field is not available in the /// provided encoded data void run_field_missing() const { m_field_missing_functor(); } /// @brief Runs encode predicate functor /// @retval true Encode field /// @retval false Do not encode field bool run_encode_predicate() const { return m_encode_predicate(); } /// @brief Indicates whether this field can be ignored by decoders that /// do not know this field /// @retval true Decoders that do not recognize this field may ignore it /// @retval false Decoders that do not recognize this field should generate /// an error if they find this field in the packet bool is_field_ignorable() const { return m_unknown_field_policy == Unknown_field_policy::ignore; } protected: Field_type_ref m_ref; ///< Field object reference /// Defines what a decoder should do if the field is present but the decoder /// is a version that does not know how to interpret the field. /// Typically the encoder writes this information to the packet as a /// directive that instructs old decoders or third-party decoders how to /// handle the field, if the message definition that they are aware of /// does not include the field. Unknown_field_policy m_unknown_field_policy = Unknown_field_policy::ignore; /// Defines whether field will be encoded Field_encode_predicate m_encode_predicate; /// Function that is called for this field during decoding in case /// field is missing in the encoded message Field_missing_functor m_field_missing_functor; }; } // namespace mysql::serialization /// @} #endif // MYSQL_SERIALIZATION_FIELD_DEFINITION_H