Restructure FieldMapBasedTag to use CRTP
This commit is contained in:
parent
11d881a41e
commit
138fa32f29
156
fieldbasedtag.h
156
fieldbasedtag.h
|
@ -8,6 +8,16 @@
|
|||
|
||||
namespace Media {
|
||||
|
||||
/*!
|
||||
* \class Media::FieldMapBasedTagTraits
|
||||
* \brief Defines traits for the specified \a ImplementationType.
|
||||
*
|
||||
* A template specialization for each FieldMapBasedTag subclass must be provided.
|
||||
*/
|
||||
template<typename ImplementationType>
|
||||
class FieldMapBasedTagTraits
|
||||
{};
|
||||
|
||||
/*!
|
||||
* \class Media::FieldMapBasedTag
|
||||
* \brief The FieldMapBasedTag provides a generic implementation of Tag which stores
|
||||
|
@ -21,38 +31,46 @@ namespace Media {
|
|||
*
|
||||
* \tparam Compare Specifies the key comparsion function. Default is std::less.
|
||||
*/
|
||||
template <class FieldType, class Compare = std::less<typename FieldType::identifierType> >
|
||||
template <class ImplementationType>
|
||||
class FieldMapBasedTag : public Tag
|
||||
{
|
||||
public:
|
||||
friend class FieldMapBasedTagTraits<ImplementationType>;
|
||||
typedef typename FieldMapBasedTagTraits<ImplementationType>::implementationType implementationType;
|
||||
typedef typename FieldMapBasedTagTraits<ImplementationType>::fieldType fieldType;
|
||||
typedef typename FieldMapBasedTagTraits<ImplementationType>::fieldType::identifierType identifierType;
|
||||
typedef typename FieldMapBasedTagTraits<ImplementationType>::compare compare;
|
||||
|
||||
FieldMapBasedTag();
|
||||
|
||||
virtual const TagValue &value(const typename FieldType::identifierType &id) const; // FIXME: use static polymorphism
|
||||
TagType type() const;
|
||||
const char *typeName() const;
|
||||
TagTextEncoding proposedTextEncoding() const;
|
||||
virtual const TagValue &value(const identifierType &id) const; // FIXME: use static polymorphism
|
||||
const TagValue &value(KnownField field) const;
|
||||
std::vector<const TagValue *> values(const typename FieldType::identifierType &id) const;
|
||||
std::vector<const TagValue *> values(const identifierType &id) const;
|
||||
std::vector<const TagValue *> values(KnownField field) const;
|
||||
virtual bool setValue(const typename FieldType::identifierType &id, const TagValue &value); // FIXME: use static polymorphism
|
||||
virtual bool setValue(const identifierType &id, const TagValue &value); // FIXME: use static polymorphism
|
||||
bool setValue(KnownField field, const TagValue &value);
|
||||
bool setValues(const typename FieldType::identifierType &id, const std::vector<TagValue> &values);
|
||||
bool setValues(const identifierType &id, const std::vector<TagValue> &values);
|
||||
bool setValues(KnownField field, const std::vector<TagValue> &values);
|
||||
bool hasField(KnownField field) const;
|
||||
virtual bool hasField(const typename FieldType::identifierType &id) const; // FIXME: use static polymorphism
|
||||
virtual bool hasField(const identifierType &id) const; // FIXME: use static polymorphism
|
||||
void removeAllFields();
|
||||
const std::multimap<typename FieldType::identifierType, FieldType, Compare> &fields() const;
|
||||
std::multimap<typename FieldType::identifierType, FieldType, Compare> &fields();
|
||||
const std::multimap<identifierType, fieldType, compare> &fields() const;
|
||||
std::multimap<identifierType, fieldType, compare> &fields();
|
||||
unsigned int fieldCount() const;
|
||||
virtual typename FieldType::identifierType fieldId(KnownField value) const = 0; // FIXME: use static polymorphism
|
||||
virtual KnownField knownField(const typename FieldType::identifierType &id) const = 0; // FIXME: use static polymorphism
|
||||
virtual identifierType fieldId(KnownField value) const = 0; // FIXME: use static polymorphism
|
||||
virtual KnownField knownField(const identifierType &id) const = 0; // FIXME: use static polymorphism
|
||||
bool supportsField(KnownField field) const;
|
||||
using Tag::proposedDataType;
|
||||
virtual TagDataType proposedDataType(const typename FieldType::identifierType &id) const; // FIXME: use static polymorphism
|
||||
int insertFields(const FieldMapBasedTag<FieldType, Compare> &from, bool overwrite);
|
||||
virtual TagDataType proposedDataType(const identifierType &id) const; // FIXME: use static polymorphism
|
||||
int insertFields(const FieldMapBasedTag<ImplementationType> &from, bool overwrite);
|
||||
unsigned int insertValues(const Tag &from, bool overwrite);
|
||||
void ensureTextValuesAreProperlyEncoded();
|
||||
typedef FieldType fieldType;
|
||||
|
||||
private:
|
||||
std::multimap<typename FieldType::identifierType, FieldType, Compare> m_fields;
|
||||
std::multimap<identifierType, fieldType, compare> m_fields;
|
||||
};
|
||||
|
||||
/*!
|
||||
|
@ -72,23 +90,41 @@ private:
|
|||
/*!
|
||||
* \brief Constructs a new FieldMapBasedTag.
|
||||
*/
|
||||
template <class FieldType, class Compare>
|
||||
FieldMapBasedTag<FieldType, Compare>::FieldMapBasedTag()
|
||||
template <class ImplementationType>
|
||||
FieldMapBasedTag<ImplementationType>::FieldMapBasedTag()
|
||||
{}
|
||||
|
||||
template <class ImplementationType>
|
||||
TagType FieldMapBasedTag<ImplementationType>::type() const
|
||||
{
|
||||
return ImplementationType::tagType;
|
||||
}
|
||||
|
||||
template <class ImplementationType>
|
||||
const char *FieldMapBasedTag<ImplementationType>::typeName() const
|
||||
{
|
||||
return ImplementationType::tagName;
|
||||
}
|
||||
|
||||
template<class ImplementationType>
|
||||
TagTextEncoding FieldMapBasedTag<ImplementationType>::proposedTextEncoding() const
|
||||
{
|
||||
return ImplementationType::defaultTextEncoding;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the value of the field with the specified \a id.
|
||||
* \sa Tag::value()
|
||||
*/
|
||||
template <class FieldType, class Compare>
|
||||
inline const TagValue &FieldMapBasedTag<FieldType, Compare>::value(const typename FieldType::identifierType &id) const
|
||||
template <class ImplementationType>
|
||||
inline const TagValue &FieldMapBasedTag<ImplementationType>::value(const identifierType &id) const
|
||||
{
|
||||
auto i = m_fields.find(id);
|
||||
return i != m_fields.end() ? i->second.value() : TagValue::empty();
|
||||
}
|
||||
|
||||
template <class FieldType, class Compare>
|
||||
inline const TagValue &FieldMapBasedTag<FieldType, Compare>::value(KnownField field) const
|
||||
template <class ImplementationType>
|
||||
inline const TagValue &FieldMapBasedTag<ImplementationType>::value(KnownField field) const
|
||||
{
|
||||
return value(fieldId(field));
|
||||
}
|
||||
|
@ -97,8 +133,8 @@ inline const TagValue &FieldMapBasedTag<FieldType, Compare>::value(KnownField fi
|
|||
* \brief Returns the values of the field with the specified \a id.
|
||||
* \sa Tag::values()
|
||||
*/
|
||||
template <class FieldType, class Compare>
|
||||
inline std::vector<const TagValue *> FieldMapBasedTag<FieldType, Compare>::values(const typename FieldType::identifierType &id) const
|
||||
template <class ImplementationType>
|
||||
inline std::vector<const TagValue *> FieldMapBasedTag<ImplementationType>::values(const identifierType &id) const
|
||||
{
|
||||
auto range = m_fields.equal_range(id);
|
||||
std::vector<const TagValue *> values;
|
||||
|
@ -110,14 +146,14 @@ inline std::vector<const TagValue *> FieldMapBasedTag<FieldType, Compare>::value
|
|||
return values;
|
||||
}
|
||||
|
||||
template <class FieldType, class Compare>
|
||||
inline std::vector<const TagValue *> FieldMapBasedTag<FieldType, Compare>::values(KnownField field) const
|
||||
template <class ImplementationType>
|
||||
inline std::vector<const TagValue *> FieldMapBasedTag<ImplementationType>::values(KnownField field) const
|
||||
{
|
||||
return values(fieldId(field));
|
||||
}
|
||||
|
||||
template <class FieldType, class Compare>
|
||||
inline bool FieldMapBasedTag<FieldType, Compare>::setValue(KnownField field, const TagValue &value)
|
||||
template <class ImplementationType>
|
||||
inline bool FieldMapBasedTag<ImplementationType>::setValue(KnownField field, const TagValue &value)
|
||||
{
|
||||
return setValue(fieldId(field), value);
|
||||
}
|
||||
|
@ -126,14 +162,14 @@ inline bool FieldMapBasedTag<FieldType, Compare>::setValue(KnownField field, con
|
|||
* \brief Assigns the given \a value to the field with the specified \a id.
|
||||
* \sa Tag::setValue()
|
||||
*/
|
||||
template <class FieldType, class Compare>
|
||||
bool FieldMapBasedTag<FieldType, Compare>::setValue(const typename FieldType::identifierType &id, const Media::TagValue &value)
|
||||
template <class ImplementationType>
|
||||
bool FieldMapBasedTag<ImplementationType>::setValue(const identifierType &id, const Media::TagValue &value)
|
||||
{
|
||||
auto i = m_fields.find(id);
|
||||
if(i != m_fields.end()) { // field already exists -> set its value
|
||||
i->second.setValue(value);
|
||||
} else if(!value.isEmpty()) { // field doesn't exist -> create new one if value is not null
|
||||
m_fields.insert(std::make_pair(id, FieldType(id, value)));
|
||||
m_fields.insert(std::make_pair(id, fieldType(id, value)));
|
||||
} else { // otherwise return false
|
||||
return false;
|
||||
}
|
||||
|
@ -146,8 +182,8 @@ bool FieldMapBasedTag<FieldType, Compare>::setValue(const typename FieldType::id
|
|||
* method will replace all currently assigned values with the specified \a values.
|
||||
* \sa Tag::setValues()
|
||||
*/
|
||||
template <class FieldType, class Compare>
|
||||
bool FieldMapBasedTag<FieldType, Compare>::setValues(const typename FieldType::identifierType &id, const std::vector<TagValue> &values)
|
||||
template <class ImplementationType>
|
||||
bool FieldMapBasedTag<ImplementationType>::setValues(const identifierType &id, const std::vector<TagValue> &values)
|
||||
{
|
||||
auto valuesIterator = values.cbegin();
|
||||
auto range = m_fields.equal_range(id);
|
||||
|
@ -161,7 +197,7 @@ bool FieldMapBasedTag<FieldType, Compare>::setValues(const typename FieldType::i
|
|||
}
|
||||
// add remaining specified values (there are more specified values than existing ones)
|
||||
for(; valuesIterator != values.cend(); ++valuesIterator) {
|
||||
m_fields.insert(std::make_pair(id, FieldType(id, *valuesIterator)));
|
||||
m_fields.insert(std::make_pair(id, fieldType(id, *valuesIterator)));
|
||||
}
|
||||
// remove remaining existing values (there are more existing values than specified ones)
|
||||
for(; range.first != range.second; ++range.first) {
|
||||
|
@ -176,14 +212,14 @@ bool FieldMapBasedTag<FieldType, Compare>::setValues(const typename FieldType::i
|
|||
* method will replace all currently assigned values with the specified \a values.
|
||||
* \sa Tag::setValues()
|
||||
*/
|
||||
template <class FieldType, class Compare>
|
||||
bool FieldMapBasedTag<FieldType, Compare>::setValues(KnownField field, const std::vector<TagValue> &values)
|
||||
template <class ImplementationType>
|
||||
bool FieldMapBasedTag<ImplementationType>::setValues(KnownField field, const std::vector<TagValue> &values)
|
||||
{
|
||||
return setValues(fieldId(field), values);
|
||||
}
|
||||
|
||||
template <class FieldType, class Compare>
|
||||
inline bool FieldMapBasedTag<FieldType, Compare>::hasField(KnownField field) const
|
||||
template <class ImplementationType>
|
||||
inline bool FieldMapBasedTag<ImplementationType>::hasField(KnownField field) const
|
||||
{
|
||||
return hasField(fieldId(field));
|
||||
}
|
||||
|
@ -191,8 +227,8 @@ inline bool FieldMapBasedTag<FieldType, Compare>::hasField(KnownField field) con
|
|||
/*!
|
||||
* \brief Returns an indication whether the field with the specified \a id is present.
|
||||
*/
|
||||
template <class FieldType, class Compare>
|
||||
inline bool FieldMapBasedTag<FieldType, Compare>::hasField(const typename FieldType::identifierType &id) const
|
||||
template <class ImplementationType>
|
||||
inline bool FieldMapBasedTag<ImplementationType>::hasField(const identifierType &id) const
|
||||
{
|
||||
for (auto range = m_fields.equal_range(id); range.first != range.second; ++range.first) {
|
||||
if(!range.first->second.value().isEmpty()) {
|
||||
|
@ -202,8 +238,8 @@ inline bool FieldMapBasedTag<FieldType, Compare>::hasField(const typename FieldT
|
|||
return false;
|
||||
}
|
||||
|
||||
template <class FieldType, class Compare>
|
||||
inline void FieldMapBasedTag<FieldType, Compare>::removeAllFields()
|
||||
template <class ImplementationType>
|
||||
inline void FieldMapBasedTag<ImplementationType>::removeAllFields()
|
||||
{
|
||||
m_fields.clear();
|
||||
}
|
||||
|
@ -211,8 +247,8 @@ inline void FieldMapBasedTag<FieldType, Compare>::removeAllFields()
|
|||
/*!
|
||||
* \brief Returns the fields of the tag by providing direct access to the field map of the tag.
|
||||
*/
|
||||
template <class FieldType, class Compare>
|
||||
inline const std::multimap<typename FieldType::identifierType, FieldType, Compare> &FieldMapBasedTag<FieldType, Compare>::fields() const
|
||||
template <class ImplementationType>
|
||||
inline auto FieldMapBasedTag<ImplementationType>::fields() const -> const std::multimap<identifierType, fieldType, compare> &
|
||||
{
|
||||
return m_fields;
|
||||
}
|
||||
|
@ -220,14 +256,14 @@ inline const std::multimap<typename FieldType::identifierType, FieldType, Compar
|
|||
/*!
|
||||
* \brief Returns the fields of the tag by providing direct access to the field map of the tag.
|
||||
*/
|
||||
template <class FieldType, class Compare>
|
||||
inline std::multimap<typename FieldType::identifierType, FieldType, Compare> &FieldMapBasedTag<FieldType, Compare>::fields()
|
||||
template <class ImplementationType>
|
||||
inline auto FieldMapBasedTag<ImplementationType>::fields() -> std::multimap<identifierType, fieldType, compare> &
|
||||
{
|
||||
return m_fields;
|
||||
}
|
||||
|
||||
template <class FieldType, class Compare>
|
||||
unsigned int FieldMapBasedTag<FieldType, Compare>::fieldCount() const
|
||||
template <class ImplementationType>
|
||||
unsigned int FieldMapBasedTag<ImplementationType>::fieldCount() const
|
||||
{
|
||||
unsigned int count = 0;
|
||||
for(const auto &field : m_fields) {
|
||||
|
@ -238,18 +274,18 @@ unsigned int FieldMapBasedTag<FieldType, Compare>::fieldCount() const
|
|||
return count;
|
||||
}
|
||||
|
||||
template <class FieldType, class Compare>
|
||||
inline bool FieldMapBasedTag<FieldType, Compare>::supportsField(KnownField field) const
|
||||
template <class ImplementationType>
|
||||
inline bool FieldMapBasedTag<ImplementationType>::supportsField(KnownField field) const
|
||||
{
|
||||
static typename FieldType::identifierType def;
|
||||
static identifierType def;
|
||||
return fieldId(field) != def;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the proposed data type for the field with the specified \a id.
|
||||
*/
|
||||
template <class FieldType, class Compare>
|
||||
inline TagDataType FieldMapBasedTag<FieldType, Compare>::proposedDataType(const typename FieldType::identifierType &id) const
|
||||
template <class ImplementationType>
|
||||
inline TagDataType FieldMapBasedTag<ImplementationType>::proposedDataType(const identifierType &id) const
|
||||
{
|
||||
return Tag::proposedDataType(knownField(id));
|
||||
}
|
||||
|
@ -260,18 +296,18 @@ inline TagDataType FieldMapBasedTag<FieldType, Compare>::proposedDataType(const
|
|||
* \param overwrite Indicates whether existing fields should be overwritten.
|
||||
* \return Returns the number of fields that have been inserted.
|
||||
*/
|
||||
template <class FieldType, class Compare>
|
||||
int FieldMapBasedTag<FieldType, Compare>::insertFields(const FieldMapBasedTag<FieldType, Compare> &from, bool overwrite)
|
||||
template <class ImplementationType>
|
||||
int FieldMapBasedTag<ImplementationType>::insertFields(const FieldMapBasedTag<ImplementationType> &from, bool overwrite)
|
||||
{
|
||||
int fieldsInserted = 0;
|
||||
for(const auto &pair : from.fields()) {
|
||||
const FieldType &fromField = pair.second;
|
||||
const fieldType &fromField = pair.second;
|
||||
if(fromField.value().isEmpty())
|
||||
continue;
|
||||
bool fieldInserted = false;
|
||||
auto range = fields().equal_range(fromField.id());
|
||||
for(auto i = range.first; i != range.second; ++i) {
|
||||
FieldType &ownField = i->second;
|
||||
fieldType &ownField = i->second;
|
||||
if((fromField.isTypeInfoAssigned() && ownField.isTypeInfoAssigned()
|
||||
&& fromField.typeInfo() == ownField.typeInfo())
|
||||
|| (!fromField.isTypeInfoAssigned() && ! ownField.isTypeInfoAssigned())) {
|
||||
|
@ -291,19 +327,19 @@ int FieldMapBasedTag<FieldType, Compare>::insertFields(const FieldMapBasedTag<Fi
|
|||
return fieldsInserted;
|
||||
}
|
||||
|
||||
template <class FieldType, class Compare>
|
||||
unsigned int FieldMapBasedTag<FieldType, Compare>::insertValues(const Tag &from, bool overwrite)
|
||||
template <class ImplementationType>
|
||||
unsigned int FieldMapBasedTag<ImplementationType>::insertValues(const Tag &from, bool overwrite)
|
||||
{
|
||||
if(type() == from.type()) {
|
||||
// the tags are of the same type, we can insert the fields directly
|
||||
return insertFields(static_cast<const FieldMapBasedTag<FieldType, Compare> &>(from), overwrite);
|
||||
return insertFields(static_cast<const FieldMapBasedTag<ImplementationType> &>(from), overwrite);
|
||||
} else {
|
||||
return Tag::insertValues(from, overwrite);
|
||||
}
|
||||
}
|
||||
|
||||
template <class FieldType, class Compare>
|
||||
void FieldMapBasedTag<FieldType, Compare>::ensureTextValuesAreProperlyEncoded()
|
||||
template <class ImplementationType>
|
||||
void FieldMapBasedTag<ImplementationType>::ensureTextValuesAreProperlyEncoded()
|
||||
{
|
||||
for(auto &field : fields()) {
|
||||
field.second.value().convertDataEncodingForTag(this);
|
||||
|
|
|
@ -12,7 +12,7 @@ class TagField;
|
|||
* \class Media::TagFieldTraits
|
||||
* \brief Defines traits for the specified \a ImplementationType.
|
||||
*
|
||||
* A template specialization for each TagField derivat must be provided.
|
||||
* A template specialization for each TagField subclass must be provided.
|
||||
*/
|
||||
template<typename ImplementationType>
|
||||
class TagFieldTraits
|
||||
|
|
|
@ -30,7 +30,7 @@ TagType Id3v1Tag::type() const
|
|||
|
||||
const char *Id3v1Tag::typeName() const
|
||||
{
|
||||
return "ID3v1 tag";
|
||||
return tagName;
|
||||
}
|
||||
|
||||
bool Id3v1Tag::canEncodingBeUsed(TagTextEncoding encoding) const
|
||||
|
|
|
@ -12,6 +12,7 @@ public:
|
|||
Id3v1Tag();
|
||||
|
||||
static constexpr TagType tagType = TagType::Id3v1Tag;
|
||||
static constexpr const char *tagName = "ID3v1 tag";
|
||||
TagType type() const;
|
||||
const char *typeName() const;
|
||||
bool canEncodingBeUsed(TagTextEncoding encoding) const;
|
||||
|
|
|
@ -147,16 +147,6 @@ TagDataType Id3v2Tag::proposedDataType(const uint32 &id) const
|
|||
}
|
||||
}
|
||||
|
||||
const TagValue &Id3v2Tag::value(const typename Id3v2Frame::identifierType &id) const
|
||||
{
|
||||
return FieldMapBasedTag<Id3v2Frame, FrameComparer>::value(id);
|
||||
}
|
||||
|
||||
bool Id3v2Tag::setValue(const typename Id3v2Frame::identifierType &id, const TagValue &value)
|
||||
{
|
||||
return FieldMapBasedTag<Id3v2Frame, FrameComparer>::setValue(id, value);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Parses tag information from the specified \a stream.
|
||||
*
|
||||
|
|
|
@ -52,23 +52,33 @@ inline uint64 Id3v2TagMaker::requiredSize() const
|
|||
return m_requiredSize;
|
||||
}
|
||||
|
||||
class TAG_PARSER_EXPORT Id3v2Tag : public FieldMapBasedTag<Id3v2Frame, FrameComparer>
|
||||
/*!
|
||||
* \brief Defines traits for the TagField implementation of the Id3v2Tag class.
|
||||
*/
|
||||
template <>
|
||||
class TAG_PARSER_EXPORT FieldMapBasedTagTraits<Id3v2Tag>
|
||||
{
|
||||
public:
|
||||
typedef Id3v2Tag implementationType;
|
||||
typedef Id3v2Frame fieldType;
|
||||
typedef FrameComparer compare;
|
||||
};
|
||||
|
||||
class TAG_PARSER_EXPORT Id3v2Tag : public FieldMapBasedTag<Id3v2Tag>
|
||||
{
|
||||
public:
|
||||
Id3v2Tag();
|
||||
|
||||
static constexpr TagType tagType = TagType::Id3v2Tag;
|
||||
TagType type() const;
|
||||
const char *typeName() const;
|
||||
static constexpr const char *tagName = "ID3v2 tag";
|
||||
static constexpr TagTextEncoding defaultTextEncoding = TagTextEncoding::Utf16LittleEndian;
|
||||
TagTextEncoding proposedTextEncoding() const;
|
||||
bool canEncodingBeUsed(TagTextEncoding encoding) const;
|
||||
uint32 fieldId(KnownField value) const;
|
||||
KnownField knownField(const uint32 &id) const;
|
||||
TagDataType proposedDataType(const uint32 &id) const;
|
||||
using FieldMapBasedTag<Id3v2Frame, FrameComparer>::value;
|
||||
const TagValue &value(const typename Id3v2Frame::identifierType &id) const;
|
||||
using FieldMapBasedTag<Id3v2Frame, FrameComparer>::setValue;
|
||||
bool setValue(const typename Id3v2Frame::identifierType &id, const TagValue &value);
|
||||
using FieldMapBasedTag<Id3v2Tag>::value;
|
||||
using FieldMapBasedTag<Id3v2Tag>::setValue;
|
||||
bool supportsDescription(KnownField field) const;
|
||||
bool supportsMimeType(KnownField field) const;
|
||||
|
||||
|
@ -109,16 +119,6 @@ inline Id3v2Tag::Id3v2Tag() :
|
|||
m_paddingSize(0)
|
||||
{}
|
||||
|
||||
inline TagType Id3v2Tag::type() const
|
||||
{
|
||||
return TagType::Id3v2Tag;
|
||||
}
|
||||
|
||||
inline const char *Id3v2Tag::typeName() const
|
||||
{
|
||||
return "ID3v2 tag";
|
||||
}
|
||||
|
||||
inline TagTextEncoding Id3v2Tag::proposedTextEncoding() const
|
||||
{
|
||||
return m_majorVersion > 3 ? TagTextEncoding::Utf8 : TagTextEncoding::Utf16LittleEndian;
|
||||
|
|
|
@ -47,16 +47,26 @@ inline uint64 MatroskaTagMaker::requiredSize() const
|
|||
return m_totalSize;
|
||||
}
|
||||
|
||||
class TAG_PARSER_EXPORT MatroskaTag : public FieldMapBasedTag<MatroskaTagField>
|
||||
/*!
|
||||
* \brief Defines traits for the TagField implementation of the MatroskaTag class.
|
||||
*/
|
||||
template <>
|
||||
class TAG_PARSER_EXPORT FieldMapBasedTagTraits<MatroskaTag>
|
||||
{
|
||||
public:
|
||||
typedef MatroskaTag implementationType;
|
||||
typedef MatroskaTagField fieldType;
|
||||
typedef std::less<typename fieldType::identifierType> compare;
|
||||
};
|
||||
|
||||
class TAG_PARSER_EXPORT MatroskaTag : public FieldMapBasedTag<MatroskaTag>
|
||||
{
|
||||
public:
|
||||
MatroskaTag();
|
||||
|
||||
static constexpr TagType tagType = TagType::MatroskaTag;
|
||||
// FIXME: implement type() and typeName() in FieldMapBasedTag
|
||||
TagType type() const;
|
||||
const char *typeName() const;
|
||||
TagTextEncoding proposedTextEncoding() const;
|
||||
static constexpr const char *tagName = "Matroska tag";
|
||||
static constexpr TagTextEncoding defaultTextEncoding = TagTextEncoding::Utf8;
|
||||
bool canEncodingBeUsed(TagTextEncoding encoding) const;
|
||||
bool supportsTarget() const;
|
||||
TagTargetLevel targetLevel() const;
|
||||
|
@ -88,21 +98,6 @@ inline TagTargetLevel MatroskaTag::targetLevel() const
|
|||
return matroskaTagTargetLevel(m_target.level());
|
||||
}
|
||||
|
||||
inline TagType MatroskaTag::type() const
|
||||
{
|
||||
return TagType::MatroskaTag;
|
||||
}
|
||||
|
||||
inline const char *MatroskaTag::typeName() const
|
||||
{
|
||||
return "Matroska tag";
|
||||
}
|
||||
|
||||
inline TagTextEncoding MatroskaTag::proposedTextEncoding() const
|
||||
{
|
||||
return TagTextEncoding::Utf8;
|
||||
}
|
||||
|
||||
inline bool MatroskaTag::canEncodingBeUsed(TagTextEncoding encoding) const
|
||||
{
|
||||
return encoding == TagTextEncoding::Utf8;
|
||||
|
|
|
@ -59,16 +59,16 @@ const TagValue &Mp4Tag::value(KnownField field) const
|
|||
{
|
||||
switch(field) {
|
||||
case KnownField::Genre: {
|
||||
const TagValue &value = FieldMapBasedTag<fieldType>::value(Mp4TagAtomIds::Genre);
|
||||
const TagValue &value = FieldMapBasedTag<Mp4Tag>::value(Mp4TagAtomIds::Genre);
|
||||
if(!value.isEmpty()) {
|
||||
return value;
|
||||
} else {
|
||||
return FieldMapBasedTag<fieldType>::value(Mp4TagAtomIds::PreDefinedGenre);
|
||||
return FieldMapBasedTag<Mp4Tag>::value(Mp4TagAtomIds::PreDefinedGenre);
|
||||
}
|
||||
} case KnownField::EncoderSettings:
|
||||
return this->value(Mp4TagExtendedMeanIds::iTunes, Mp4TagExtendedNameIds::cdec);
|
||||
case KnownField::RecordLabel: {
|
||||
const TagValue &value = FieldMapBasedTag<fieldType>::value(Mp4TagAtomIds::RecordLabel);
|
||||
const TagValue &value = FieldMapBasedTag<Mp4Tag>::value(Mp4TagAtomIds::RecordLabel);
|
||||
if(!value.isEmpty()) {
|
||||
return value;
|
||||
} else {
|
||||
|
@ -76,13 +76,13 @@ const TagValue &Mp4Tag::value(KnownField field) const
|
|||
}
|
||||
}
|
||||
default:
|
||||
return FieldMapBasedTag<fieldType>::value(field);
|
||||
return FieldMapBasedTag<Mp4Tag>::value(field);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<const TagValue *> Mp4Tag::values(KnownField field) const
|
||||
{
|
||||
auto values = FieldMapBasedTag<fieldType>::values(field);
|
||||
auto values = FieldMapBasedTag<Mp4Tag>::values(field);
|
||||
const Mp4ExtendedFieldId extendedId(field);
|
||||
if(extendedId) {
|
||||
auto range = fields().equal_range(Mp4TagAtomIds::Extended);
|
||||
|
@ -180,10 +180,10 @@ bool Mp4Tag::setValue(KnownField field, const TagValue &value)
|
|||
switch(value.type()) {
|
||||
case TagDataType::StandardGenreIndex:
|
||||
fields().erase(Mp4TagAtomIds::Genre);
|
||||
return FieldMapBasedTag<fieldType>::setValue(Mp4TagAtomIds::PreDefinedGenre, value);
|
||||
return FieldMapBasedTag<Mp4Tag>::setValue(Mp4TagAtomIds::PreDefinedGenre, value);
|
||||
default:
|
||||
fields().erase(Mp4TagAtomIds::PreDefinedGenre);
|
||||
return FieldMapBasedTag<fieldType>::setValue(Mp4TagAtomIds::Genre, value);
|
||||
return FieldMapBasedTag<Mp4Tag>::setValue(Mp4TagAtomIds::Genre, value);
|
||||
}
|
||||
case KnownField::EncoderSettings:
|
||||
return setValue(Mp4TagExtendedMeanIds::iTunes, Mp4TagExtendedNameIds::cdec, value);
|
||||
|
@ -193,7 +193,7 @@ bool Mp4Tag::setValue(KnownField field, const TagValue &value)
|
|||
}
|
||||
FALLTHROUGH;
|
||||
default:
|
||||
return FieldMapBasedTag<fieldType>::setValue(field, value);
|
||||
return FieldMapBasedTag<Mp4Tag>::setValue(field, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -225,7 +225,7 @@ bool Mp4Tag::setValues(KnownField field, const std::vector<TagValue> &values)
|
|||
range.first->second.setValue(TagValue());
|
||||
}
|
||||
}
|
||||
return FieldMapBasedTag<fieldType>::setValues(field, values);
|
||||
return FieldMapBasedTag<Mp4Tag>::setValues(field, values);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -260,10 +260,10 @@ bool Mp4Tag::hasField(KnownField field) const
|
|||
{
|
||||
switch(field) {
|
||||
case KnownField::Genre:
|
||||
return FieldMapBasedTag<fieldType>::hasField(Mp4TagAtomIds::PreDefinedGenre)
|
||||
|| FieldMapBasedTag<fieldType>::hasField(Mp4TagAtomIds::Genre);
|
||||
return FieldMapBasedTag<Mp4Tag>::hasField(Mp4TagAtomIds::PreDefinedGenre)
|
||||
|| FieldMapBasedTag<Mp4Tag>::hasField(Mp4TagAtomIds::Genre);
|
||||
default:
|
||||
return FieldMapBasedTag<fieldType>::hasField(field);
|
||||
return FieldMapBasedTag<Mp4Tag>::hasField(field);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
46
mp4/mp4tag.h
46
mp4/mp4tag.h
|
@ -87,39 +87,50 @@ inline uint64 Mp4TagMaker::requiredSize() const
|
|||
return m_metaSize;
|
||||
}
|
||||
|
||||
class TAG_PARSER_EXPORT Mp4Tag : public FieldMapBasedTag<Mp4TagField>
|
||||
/*!
|
||||
* \brief Defines traits for the TagField implementation of the Mp4Tag class.
|
||||
*/
|
||||
template <>
|
||||
class TAG_PARSER_EXPORT FieldMapBasedTagTraits<Mp4Tag>
|
||||
{
|
||||
public:
|
||||
typedef Mp4Tag implementationType;
|
||||
typedef Mp4TagField fieldType;
|
||||
typedef std::less<typename fieldType::identifierType> compare;
|
||||
};
|
||||
|
||||
class TAG_PARSER_EXPORT Mp4Tag : public FieldMapBasedTag<Mp4Tag>
|
||||
{
|
||||
public:
|
||||
Mp4Tag();
|
||||
|
||||
static constexpr TagType tagType = TagType::Mp4Tag;
|
||||
TagType type() const;
|
||||
const char *typeName() const;
|
||||
TagTextEncoding proposedTextEncoding() const;
|
||||
static constexpr const char *tagName = "MP4/iTunes tag";
|
||||
static constexpr TagTextEncoding defaultTextEncoding = TagTextEncoding::Utf8;
|
||||
bool canEncodingBeUsed(TagTextEncoding encoding) const;
|
||||
|
||||
uint32 fieldId(KnownField field) const;
|
||||
KnownField knownField(const uint32 &id) const;
|
||||
bool supportsField(KnownField field) const;
|
||||
using FieldMapBasedTag<Mp4TagField>::value;
|
||||
using FieldMapBasedTag<Mp4Tag>::value;
|
||||
const TagValue &value(KnownField value) const;
|
||||
using FieldMapBasedTag<Mp4TagField>::values;
|
||||
using FieldMapBasedTag<Mp4Tag>::values;
|
||||
std::vector<const TagValue *> values(KnownField field) const;
|
||||
#ifdef LEGACY_API
|
||||
const TagValue &value(const std::string mean, const std::string name) const;
|
||||
#endif
|
||||
const TagValue &value(const std::string &mean, const std::string &name) const;
|
||||
const TagValue &value(const char *mean, const char *name) const;
|
||||
using FieldMapBasedTag<Mp4TagField>::setValue;
|
||||
using FieldMapBasedTag<Mp4Tag>::setValue;
|
||||
bool setValue(KnownField field, const TagValue &value);
|
||||
using FieldMapBasedTag<Mp4TagField>::setValues;
|
||||
using FieldMapBasedTag<Mp4Tag>::setValues;
|
||||
bool setValues(KnownField field, const std::vector<TagValue> &values);
|
||||
#ifdef LEGACY_API
|
||||
bool setValue(const std::string mean, const std::string name, const TagValue &value);
|
||||
#endif
|
||||
bool setValue(const std::string &mean, const std::string &name, const TagValue &value);
|
||||
bool setValue(const char *mean, const char *name, const TagValue &value);
|
||||
using FieldMapBasedTag<Mp4TagField>::hasField;
|
||||
using FieldMapBasedTag<Mp4Tag>::hasField;
|
||||
bool hasField(KnownField value) const;
|
||||
|
||||
void parse(Mp4Atom &metaAtom);
|
||||
|
@ -133,28 +144,13 @@ public:
|
|||
inline Mp4Tag::Mp4Tag()
|
||||
{}
|
||||
|
||||
inline TagType Mp4Tag::type() const
|
||||
{
|
||||
return TagType::Mp4Tag;
|
||||
}
|
||||
|
||||
inline const char *Mp4Tag::typeName() const
|
||||
{
|
||||
return "MP4/iTunes tag";
|
||||
}
|
||||
|
||||
inline TagTextEncoding Mp4Tag::proposedTextEncoding() const
|
||||
{
|
||||
return TagTextEncoding::Utf8;
|
||||
}
|
||||
|
||||
inline bool Mp4Tag::supportsField(KnownField field) const
|
||||
{
|
||||
switch(field) {
|
||||
case KnownField::EncoderSettings:
|
||||
return true;
|
||||
default:
|
||||
return FieldMapBasedTag<Mp4TagField>::supportsField(field);
|
||||
return FieldMapBasedTag<Mp4Tag>::supportsField(field);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ const TagValue &VorbisComment::value(KnownField field) const
|
|||
case KnownField::Vendor:
|
||||
return vendor();
|
||||
default:
|
||||
return FieldMapBasedTag<VorbisCommentField, CaseInsensitiveStringComparer>::value(field);
|
||||
return FieldMapBasedTag<VorbisComment>::value(field);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,7 @@ bool VorbisComment::setValue(KnownField field, const TagValue &value)
|
|||
setVendor(value);
|
||||
return true;
|
||||
default:
|
||||
return FieldMapBasedTag<VorbisCommentField, CaseInsensitiveStringComparer>::setValue(field, value);
|
||||
return FieldMapBasedTag<VorbisComment>::setValue(field, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,15 +12,26 @@ namespace Media {
|
|||
class OggIterator;
|
||||
class VorbisComment;
|
||||
|
||||
class TAG_PARSER_EXPORT VorbisComment : public FieldMapBasedTag<VorbisCommentField, CaseInsensitiveStringComparer>
|
||||
/*!
|
||||
* \brief Defines traits for the TagField implementation of the VorbisComment class.
|
||||
*/
|
||||
template <>
|
||||
class TAG_PARSER_EXPORT FieldMapBasedTagTraits<VorbisComment>
|
||||
{
|
||||
public:
|
||||
typedef VorbisComment implementationType;
|
||||
typedef VorbisCommentField fieldType;
|
||||
typedef CaseInsensitiveStringComparer compare;
|
||||
};
|
||||
|
||||
class TAG_PARSER_EXPORT VorbisComment : public FieldMapBasedTag<VorbisComment>
|
||||
{
|
||||
public:
|
||||
VorbisComment();
|
||||
|
||||
static constexpr TagType tagType = TagType::VorbisComment;
|
||||
TagType type() const;
|
||||
const char *typeName() const;
|
||||
TagTextEncoding proposedTextEncoding() const;
|
||||
static constexpr const char *tagName = "Vorbis comment";
|
||||
static constexpr TagTextEncoding defaultTextEncoding = TagTextEncoding::Utf8;
|
||||
bool canEncodingBeUsed(TagTextEncoding encoding) const;
|
||||
|
||||
const TagValue &value(KnownField field) const;
|
||||
|
@ -49,21 +60,6 @@ private:
|
|||
inline VorbisComment::VorbisComment()
|
||||
{}
|
||||
|
||||
inline TagType VorbisComment::type() const
|
||||
{
|
||||
return TagType::VorbisComment;
|
||||
}
|
||||
|
||||
inline const char *VorbisComment::typeName() const
|
||||
{
|
||||
return "Vorbis comment";
|
||||
}
|
||||
|
||||
inline TagTextEncoding VorbisComment::proposedTextEncoding() const
|
||||
{
|
||||
return TagTextEncoding::Utf8;
|
||||
}
|
||||
|
||||
inline bool VorbisComment::canEncodingBeUsed(TagTextEncoding encoding) const
|
||||
{
|
||||
return encoding == TagTextEncoding::Utf8;
|
||||
|
|
Loading…
Reference in New Issue