#ifndef TAG_PARSER_TAGFIELD_H #define TAG_PARSER_TAGFIELD_H #include "./tagvalue.h" namespace TagParser { template class TagField; /*! * \class TagParser::TagFieldTraits * \brief Defines traits for the specified \a ImplementationType. * * A template specialization for each TagField subclass must be provided. */ template class TagFieldTraits {}; /*! * \brief The TagField class is used by FieldMapBasedTag to store the fields. * * A TagField consists of an identifier and a value. An additional type info * might be assigned as well. The usage of the type info depends on the * particular tag implementation. * * \tparam ImplementationType Specifies the type of the actual implementation. * \remarks This template class is intended to be subclassed using * with the "Curiously recurring template pattern". */ template class TAG_PARSER_EXPORT TagField { friend class TagFieldTraits; public: using IdentifierType = typename TagFieldTraits::IdentifierType; using TypeInfoType = typename TagFieldTraits::TypeInfoType; TagField(); TagField(const IdentifierType &id, const TagValue &value); ~TagField(); IdentifierType &id(); const IdentifierType &id() const; std::string idToString() const; void setId(const IdentifierType &id); void clearId(); TagValue &value(); const TagValue &value() const; void setValue(const TagValue &value); void clearValue(); const TypeInfoType &typeInfo() const; void setTypeInfo(const TypeInfoType &typeInfo); void removeTypeInfo(); bool isTypeInfoAssigned() const; bool isDefault() const; void setDefault(bool isDefault); void clear(); bool isAdditionalTypeInfoUsed() const; const std::vector &nestedFields() const; std::vector &nestedFields(); bool supportsNestedFields() const; protected: void internallyClearValue(); void internallyClearFurtherData(); private: IdentifierType m_id; TagValue m_value; TypeInfoType m_typeInfo; bool m_typeInfoAssigned; bool m_default; std::vector m_nestedFields; }; /*! * \brief Constructs an empty TagField. */ template TagField::TagField() : m_id(IdentifierType()) , m_value(TagValue()) , m_typeInfo(TypeInfoType()) , m_typeInfoAssigned(false) , m_default(false) { } /*! * \brief Constructs a new TagField with the specified \a id and \a value. */ template TagField::TagField(const IdentifierType &id, const TagValue &value) : m_id(id) , m_value(value) , m_typeInfo(TypeInfoType()) , m_typeInfoAssigned(false) , m_default(false) { } /*! * \brief Destroys the TagField. */ template TagField::~TagField() { } /*! * \brief Returns the id of the current TagField. */ template inline typename TagField::IdentifierType &TagField::id() { return m_id; } /*! * \brief Returns the id of the current TagField. */ template inline const typename TagField::IdentifierType &TagField::id() const { return m_id; } /*! * \brief Returns the id of the current TagField as string. */ template inline std::string TagField::idToString() const { return ImplementationType::fieldIdToString(m_id); } /*! * \brief Sets the id of the current Tag Field. */ template inline void TagField::setId(const IdentifierType &id) { m_id = id; } /*! * \brief Clears the id of the current TagField. */ template inline void TagField::clearId() { m_id = IdentifierType(); } /*! * \brief Returns the value of the current TagField. */ template inline TagValue &TagField::value() { return m_value; } /*! * \brief Returns the value of the current TagField. */ template inline const TagValue &TagField::value() const { return m_value; } /*! * \brief Sets the value of the current TagField. */ template inline void TagField::setValue(const TagValue &value) { m_value = value; } /*! * \brief Clears the value of the current TagField. */ template inline void TagField::clearValue() { static_cast(this)->internallyClearValue(); } /*! * \brief Returns the type info of the current TagField. */ template inline const typename TagField::TypeInfoType &TagField::typeInfo() const { return m_typeInfo; } /*! * \brief Sets the type info of the current TagField. */ template inline void TagField::setTypeInfo(const TypeInfoType &typeInfo) { m_typeInfo = typeInfo; m_typeInfoAssigned = true; } /*! * \brief Removes the type info from the current TagField. */ template inline void TagField::removeTypeInfo() { m_typeInfo = TypeInfoType(); m_typeInfoAssigned = false; } /*! * \brief Returns an indication whether a type info is assigned. */ template inline bool TagField::isTypeInfoAssigned() const { return m_typeInfoAssigned; } /*! * \brief Returns an indication whether the field is labeled as default. */ template inline bool TagField::isDefault() const { return m_default; } /*! * \brief Sets whether the field is labeled as default. */ template inline void TagField::setDefault(bool isDefault) { m_default = isDefault; } /*! * \brief Clears id, value, type info, sets default flag to false and resets further implementation specific values. */ template void TagField::clear() { clearId(); clearValue(); static_cast(this)->internallyClearFurtherData(); m_typeInfo = TypeInfoType(); m_typeInfoAssigned = false; m_default = true; } /*! * \brief Returns an indication whether the additional type info is used. * * The default implementation always returns false. The method might be reimplemented * when subclassing. */ template inline bool TagField::isAdditionalTypeInfoUsed() const { return static_cast(this)->isAdditionalTypeInfoUsed(); } /*! * \brief Returns the nested fields. */ template const std::vector &TagField::nestedFields() const { return m_nestedFields; } /*! * \brief Returns the nested fields. * \remarks Might be modified. Not all implementations support nested fields. * \sa supportsNestedFields() */ template inline std::vector &TagField::nestedFields() { return m_nestedFields; } /*! * \brief Returns whether nested fields are supported by the implementation. */ template inline bool TagField::supportsNestedFields() const { return static_cast(this)->supportsNestedFields(); } /*! * \brief Clears the assigned value; called via clearValue() and clear(). * \remarks Shadow when subclassing to customize clearning a value. */ template void TagField::internallyClearValue() { m_value.clearDataAndMetadata(); } /*! * \brief Clears further data; called via clear(). * \remarks Shadow when subclassing to clear further data the subclass has. */ template void TagField::internallyClearFurtherData() { } } // namespace TagParser #endif // TAG_PARSER_TAGFIELD_H