From b5c0ab58ba48c57d283abcc41f936e4ab27be5d0 Mon Sep 17 00:00:00 2001 From: Urs Fleisch Date: Sun, 10 May 2015 10:30:51 +0200 Subject: [PATCH 1/3] Get version information from taglib.h. This avoids duplication of the version information in both CMakeLists.txt and taglib.h while keeping the possibility to use something different from CMake. --- CMakeLists.txt | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d4469b5d..bae9e2fc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,9 +52,20 @@ if (MSVC AND ENABLE_STATIC_RUNTIME) endforeach(flag_var) endif() -set(TAGLIB_LIB_MAJOR_VERSION "1") -set(TAGLIB_LIB_MINOR_VERSION "9") -set(TAGLIB_LIB_PATCH_VERSION "1") +# Read version information from file taglib/toolkit/taglib.h into variables +# TAGLIB_LIB_MAJOR_VERSION, TAGLIB_LIB_MINOR_VERSION, TAGLIB_LIB_PATCH_VERSION. +foreach(version_part MAJOR MINOR PATCH) + set(version_var_name "TAGLIB_${version_part}_VERSION") + file(STRINGS taglib/toolkit/taglib.h version_line + REGEX "^#define +${version_var_name}") + if(NOT version_line) + message(FATAL_ERROR "${version_var_name} not found in taglib.h") + endif() + string(REGEX MATCH "${version_var_name} +([^ ]+)" result ${version_line}) + set(TAGLIB_LIB_${version_part}_VERSION ${CMAKE_MATCH_1}) +endforeach(version_part) +# Only used to force cmake rerun when taglib.h changes. +configure_file(taglib/toolkit/taglib.h ${CMAKE_CURRENT_BINARY_DIR}/taglib.h.stamp) set(TAGLIB_LIB_VERSION_STRING "${TAGLIB_LIB_MAJOR_VERSION}.${TAGLIB_LIB_MINOR_VERSION}.${TAGLIB_LIB_PATCH_VERSION}") From 84e3582332eb593497912d055f15827a57815478 Mon Sep 17 00:00:00 2001 From: Tsuda Kageyu Date: Wed, 18 Nov 2015 11:45:27 +0900 Subject: [PATCH 2/3] Add alternative methods to XiphComment::removeField(). Using XiphComment::removeField() may lead to a linkage error, however we can't fix the method itself without breaking the ABI or changing its behavior. So we added some alternative method and marked the old one deprecated. --- taglib/ogg/xiphcomment.cpp | 36 +++++++++++++++++++++++---------- taglib/ogg/xiphcomment.h | 24 ++++++++++++++++++++++ tests/test_xiphcomment.cpp | 41 +++++++++++++++++++++++++++++++------- 3 files changed, 83 insertions(+), 18 deletions(-) diff --git a/taglib/ogg/xiphcomment.cpp b/taglib/ogg/xiphcomment.cpp index e5b2fc8e..a36862df 100644 --- a/taglib/ogg/xiphcomment.cpp +++ b/taglib/ogg/xiphcomment.cpp @@ -264,22 +264,36 @@ void Ogg::XiphComment::addField(const String &key, const String &value, bool rep void Ogg::XiphComment::removeField(const String &key, const String &value) { - if(!value.isNull()) { - StringList::Iterator it = d->fieldListMap[key].begin(); - while(it != d->fieldListMap[key].end()) { - if(value == *it) - it = d->fieldListMap[key].erase(it); - else - it++; - } - } + if(!value.isNull()) + removeFields(key, value); else - d->fieldListMap.erase(key); + removeFields(key); +} + +void Ogg::XiphComment::removeFields(const String &key) +{ + d->fieldListMap.erase(key.upper()); +} + +void Ogg::XiphComment::removeFields(const String &key, const String &value) +{ + StringList &fields = d->fieldListMap[key.upper()]; + for(StringList::Iterator it = fields.begin(); it != fields.end(); ) { + if(*it == value) + it = fields.erase(it); + else + ++it; + } +} + +void Ogg::XiphComment::removeAllFields() +{ + d->fieldListMap.clear(); } bool Ogg::XiphComment::contains(const String &key) const { - return d->fieldListMap.contains(key) && !d->fieldListMap[key].isEmpty(); + return !d->fieldListMap[key.upper()].isEmpty(); } ByteVector Ogg::XiphComment::render() const diff --git a/taglib/ogg/xiphcomment.h b/taglib/ogg/xiphcomment.h index 54f3070b..8914ec07 100644 --- a/taglib/ogg/xiphcomment.h +++ b/taglib/ogg/xiphcomment.h @@ -181,9 +181,33 @@ namespace TagLib { /*! * Remove the field specified by \a key with the data \a value. If * \a value is null, all of the fields with the given key will be removed. + * + * \deprecated Using this method may lead to a linkage error. */ + // BIC: remove and merge with below void removeField(const String &key, const String &value = String::null); + /*! + * Remove all the fields specified by \a key. + * + * \see removeAllFields() + */ + void removeFields(const String &key); + + /*! + * Remove all the fields specified by \a key with the data \a value. + * + * \see removeAllFields() + */ + void removeFields(const String &key, const String &value); + + /*! + * Remove all the fields in the comment. + * + * \see removeFields() + */ + void removeAllFields(); + /*! * Returns true if the field is contained within the comment. * diff --git a/tests/test_xiphcomment.cpp b/tests/test_xiphcomment.cpp index e2358333..617bd765 100644 --- a/tests/test_xiphcomment.cpp +++ b/tests/test_xiphcomment.cpp @@ -1,7 +1,7 @@ #include #include -#include #include +#include #include #include #include @@ -19,6 +19,7 @@ class TestXiphComment : public CppUnit::TestFixture CPPUNIT_TEST(testSetTrack); CPPUNIT_TEST(testInvalidKeys); CPPUNIT_TEST(testClearComment); + CPPUNIT_TEST(testRemoveFields); CPPUNIT_TEST_SUITE_END(); public: @@ -78,20 +79,46 @@ public: void testClearComment() { - ScopedFileCopy copy("no-tags", ".flac"); + ScopedFileCopy copy("empty", ".ogg"); { - FLAC::File f(copy.fileName().c_str()); - f.xiphComment()->addField("COMMENT", "Comment1"); + Ogg::Vorbis::File f(copy.fileName().c_str()); + f.tag()->addField("COMMENT", "Comment1"); f.save(); } { - FLAC::File f(copy.fileName().c_str()); - f.xiphComment()->setComment(""); - CPPUNIT_ASSERT_EQUAL(String(""), f.xiphComment()->comment()); + Ogg::Vorbis::File f(copy.fileName().c_str()); + f.tag()->setComment(""); + CPPUNIT_ASSERT_EQUAL(String(""), f.tag()->comment()); } } + void testRemoveFields() + { + Ogg::Vorbis::File f(TEST_FILE_PATH_C("empty.ogg")); + f.tag()->addField("title", "Title1"); + f.tag()->addField("Title", "Title1", false); + f.tag()->addField("titlE", "Title2", false); + f.tag()->addField("TITLE", "Title3", false); + f.tag()->addField("artist", "Artist1"); + f.tag()->addField("ARTIST", "Artist2", false); + CPPUNIT_ASSERT_EQUAL(String("Title1 Title1 Title2 Title3"), f.tag()->title()); + CPPUNIT_ASSERT_EQUAL(String("Artist1 Artist2"), f.tag()->artist()); + + f.tag()->removeFields("title", "Title1"); + CPPUNIT_ASSERT_EQUAL(String("Title2 Title3"), f.tag()->title()); + CPPUNIT_ASSERT_EQUAL(String("Artist1 Artist2"), f.tag()->artist()); + + f.tag()->removeFields("Artist"); + CPPUNIT_ASSERT_EQUAL(String("Title2 Title3"), f.tag()->title()); + CPPUNIT_ASSERT(f.tag()->artist().isEmpty()); + + f.tag()->removeAllFields(); + CPPUNIT_ASSERT(f.tag()->title().isEmpty()); + CPPUNIT_ASSERT(f.tag()->artist().isEmpty()); + CPPUNIT_ASSERT_EQUAL(String("Xiph.Org libVorbis I 20050304"), f.tag()->vendorID()); + } + }; CPPUNIT_TEST_SUITE_REGISTRATION(TestXiphComment); From 6477132301f1e7beca1766eccfb5f40cc8f51d3a Mon Sep 17 00:00:00 2001 From: Tsuda Kageyu Date: Sun, 22 Nov 2015 16:23:53 +0900 Subject: [PATCH 3/3] Update NEWS. --- NEWS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS b/NEWS index 24d4525c..1c0d8383 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,7 @@ * New API for creating FileRef from IOStream. * Added support for ID3v2 PCST and WFED frames. * Added String::clear(). + * Added alternative functions to XiphComment::removeField(). * Better handling of duplicate ID3v2 tags in all kinds of files. * Better handling of duplicate tags in WAV files. * Fixed crash when calling File::properties() after strip(). @@ -10,6 +11,7 @@ * Fixed updating the comment field of Vorbis comments. * Marked ByteVector::null and ByteVector::isNull() deprecated. * Marked String::null and ByteVector::isNull() deprecated. + * Marked XiphComment::removeField() deprecated. * Many smaller bug fixes and performance improvements. TagLib 1.10 (Nov 11, 2015)