Treat 255 as empty ID3v1 genre index

This commit is contained in:
Martchus 2019-02-13 18:06:02 +01:00
parent 97c1a2100d
commit 5140b76f08
5 changed files with 45 additions and 9 deletions

View File

@ -170,7 +170,7 @@ set(META_APP_AUTHOR "Martchus")
set(META_APP_URL "https://github.com/${META_APP_AUTHOR}/${META_PROJECT_NAME}") set(META_APP_URL "https://github.com/${META_APP_AUTHOR}/${META_PROJECT_NAME}")
set(META_APP_DESCRIPTION "C++ library for reading and writing MP4 (iTunes), ID3, Vorbis, Opus, FLAC and Matroska tags") set(META_APP_DESCRIPTION "C++ library for reading and writing MP4 (iTunes), ID3, Vorbis, Opus, FLAC and Matroska tags")
set(META_VERSION_MAJOR 8) set(META_VERSION_MAJOR 8)
set(META_VERSION_MINOR 1) set(META_VERSION_MINOR 2)
set(META_VERSION_PATCH 0) set(META_VERSION_PATCH 0)
set(META_PUBLIC_SHARED_LIB_DEPENDS c++utilities) set(META_PUBLIC_SHARED_LIB_DEPENDS c++utilities)
set(META_PUBLIC_STATIC_LIB_DEPENDS c++utilities_static) set(META_PUBLIC_STATIC_LIB_DEPENDS c++utilities_static)

View File

@ -11,6 +11,7 @@ namespace TagParser {
/*! /*!
* \brief Returns all known genre names. * \brief Returns all known genre names.
* \todo Fix const-correctness in v9.
*/ */
const char **Id3Genres::genreNames() const char **Id3Genres::genreNames()
{ {
@ -37,9 +38,13 @@ const char **Id3Genres::genreNames()
/*! /*!
* \brief Returns the numerical denotation of the specified \a genre or -1 if \a genre is unknown. * \brief Returns the numerical denotation of the specified \a genre or -1 if \a genre is unknown.
* \remarks If \a string is empty, the non-standard Id3Genres::emptyGenreIndex() is returned.
*/ */
int Id3Genres::indexFromString(const string &genre) int Id3Genres::indexFromString(const string &genre)
{ {
if (genre.empty()) {
return emptyGenreIndex();
}
const char *const *ptr = genreNames(); const char *const *ptr = genreNames();
for (int index = 0; index < genreCount(); ++ptr, ++index) { for (int index = 0; index < genreCount(); ++ptr, ++index) {
if (genre == *ptr) { if (genre == *ptr) {

View File

@ -14,6 +14,8 @@ public:
static inline const char *stringFromIndex(int index); static inline const char *stringFromIndex(int index);
static int indexFromString(const std::string &genre); static int indexFromString(const std::string &genre);
static constexpr int genreCount(); static constexpr int genreCount();
static constexpr int emptyGenreIndex();
static constexpr bool isEmptyGenre(int index);
static constexpr bool isIndexSupported(int index); static constexpr bool isIndexSupported(int index);
private: private:
@ -36,6 +38,24 @@ constexpr int Id3Genres::genreCount()
return 192; return 192;
} }
/*!
* \brief Returns the preferred genre index to indicate that no genre is set at all.
* \remarks Apparently some files use 255 to indicate the genre information is missing although this
* is not explicitely specified on [ID3.org](http://id3.org/ID3v1).
*/
constexpr int Id3Genres::emptyGenreIndex()
{
return 255;
}
/*!
* \brief Returns whether the genre \a index indicates the genre field is not set at all.
*/
constexpr bool Id3Genres::isEmptyGenre(int index)
{
return index == emptyGenreIndex();
}
/*! /*!
* \brief Returns an indication whether the specified numerical denotation is * \brief Returns an indication whether the specified numerical denotation is
* supported by this class. * supported by this class.

View File

@ -212,7 +212,7 @@ int32 TagValue::toInteger() const
int TagValue::toStandardGenreIndex() const int TagValue::toStandardGenreIndex() const
{ {
if (isEmpty()) { if (isEmpty()) {
return 0; return Id3Genres::emptyGenreIndex();
} }
int index = 0; int index = 0;
switch (m_type) { switch (m_type) {
@ -470,13 +470,17 @@ void TagValue::toString(string &result, TagTextEncoding encoding) const
case TagDataType::PositionInSet: case TagDataType::PositionInSet:
result = toPositionInSet().toString(); result = toPositionInSet().toString();
break; break;
case TagDataType::StandardGenreIndex: case TagDataType::StandardGenreIndex: {
if (const char *genreName = Id3Genres::stringFromIndex(toInteger())) { const auto genreIndex = toInteger();
if (Id3Genres::isEmptyGenre(genreIndex)) {
result.clear();
} else if (const char *genreName = Id3Genres::stringFromIndex(genreIndex)) {
result.assign(genreName); result.assign(genreName);
break;
} else { } else {
throw ConversionException("No string representation for the assigned standard genre index available."); throw ConversionException("No string representation for the assigned standard genre index available.");
} }
break;
}
case TagDataType::TimeSpan: case TagDataType::TimeSpan:
result = toTimeSpan().toString(); result = toTimeSpan().toString();
break; break;
@ -547,12 +551,17 @@ void TagValue::toWString(std::u16string &result, TagTextEncoding encoding) const
case TagDataType::PositionInSet: case TagDataType::PositionInSet:
regularStrRes = toPositionInSet().toString(); regularStrRes = toPositionInSet().toString();
break; break;
case TagDataType::StandardGenreIndex: case TagDataType::StandardGenreIndex: {
if (const char *const genreName = Id3Genres::stringFromIndex(toInteger())) { const auto genreIndex = toInteger();
if (Id3Genres::isEmptyGenre(genreIndex)) {
regularStrRes.clear();
} else if (const char *genreName = Id3Genres::stringFromIndex(genreIndex)) {
regularStrRes.assign(genreName); regularStrRes.assign(genreName);
break; } else {
throw ConversionException("No string representation for the assigned standard genre index available.");
} }
throw ConversionException("No string representation for the assigned standard genre index available."); break;
}
case TagDataType::TimeSpan: case TagDataType::TimeSpan:
regularStrRes = toTimeSpan().toString(); regularStrRes = toTimeSpan().toString();
break; break;

View File

@ -84,6 +84,8 @@ void TagValueTests::testInteger()
CPPUNIT_ASSERT_EQUAL("42"s, integer.toString()); CPPUNIT_ASSERT_EQUAL("42"s, integer.toString());
integer.assignInteger(2); integer.assignInteger(2);
CPPUNIT_ASSERT_EQUAL("Country"s, string(Id3Genres::stringFromIndex(integer.toStandardGenreIndex()))); CPPUNIT_ASSERT_EQUAL("Country"s, string(Id3Genres::stringFromIndex(integer.toStandardGenreIndex())));
integer.assignInteger(255);
CPPUNIT_ASSERT_EQUAL(string(), string(Id3Genres::stringFromIndex(integer.toStandardGenreIndex())));
// negative number // negative number
integer.assignInteger(-25); integer.assignInteger(-25);