diff --git a/taglib.pc.cmake b/taglib.pc.cmake index 5ee50aa5..09402998 100644 --- a/taglib.pc.cmake +++ b/taglib.pc.cmake @@ -7,5 +7,5 @@ Name: TagLib Description: Audio meta-data library Requires: Version: ${TAGLIB_LIB_VERSION_STRING} -Libs: -L${LIB_INSTALL_DIR} -ltag -Cflags: -I${INCLUDE_INSTALL_DIR}/taglib +Libs: -L${dollar}{libdir} -ltag +Cflags: -I${dollar}{includedir}/taglib diff --git a/taglib/ape/apetag.cpp b/taglib/ape/apetag.cpp index f4258630..5b99ce9f 100644 --- a/taglib/ape/apetag.cpp +++ b/taglib/ape/apetag.cpp @@ -48,7 +48,6 @@ class APE::Tag::TagPrivate { public: Footer footer; - ItemListMap itemListMap; }; diff --git a/taglib/fileref.cpp b/taglib/fileref.cpp index 67bce9fa..19e44dcf 100644 --- a/taglib/fileref.cpp +++ b/taglib/fileref.cpp @@ -160,7 +160,7 @@ namespace return new Ogg::Opus::File(arg, readAudioProperties, audioPropertiesStyle); if(ext == "TTA") return new TrueAudio::File(arg, readAudioProperties, audioPropertiesStyle); - if(ext == "M4A" || ext == "M4R" || ext == "M4B" || ext == "M4P" || ext == "MP4" || ext == "3G2") + if(ext == "M4A" || ext == "M4R" || ext == "M4B" || ext == "M4P" || ext == "MP4" || ext == "3G2" || ext == "M4V") return new MP4::File(arg, readAudioProperties, audioPropertiesStyle); if(ext == "WMA" || ext == "ASF") return new ASF::File(arg, readAudioProperties, audioPropertiesStyle); @@ -319,6 +319,7 @@ StringList FileRef::defaultFileExtensions() l.append("m4p"); l.append("3g2"); l.append("mp4"); + l.append("m4v"); l.append("wma"); l.append("asf"); l.append("aif"); diff --git a/taglib/flac/flacproperties.cpp b/taglib/flac/flacproperties.cpp index 657a3edb..bb2af9ef 100644 --- a/taglib/flac/flacproperties.cpp +++ b/taglib/flac/flacproperties.cpp @@ -152,8 +152,8 @@ void FLAC::AudioProperties::read(const ByteVector &data, long long streamLength) // The last 4 bits are the most significant 4 bits for the 36 bit // stream length in samples. (Audio files measured in days) - const ulonglong hi = flags & 0xf; - const ulonglong lo = data.toUInt32BE(pos); + const unsigned long long hi = flags & 0xf; + const unsigned long long lo = data.toUInt32BE(pos); pos += 4; d->sampleFrames = (hi << 32) | lo; diff --git a/taglib/mpeg/id3v1/id3v1tag.cpp b/taglib/mpeg/id3v1/id3v1tag.cpp index b7a8233a..d1d538ef 100644 --- a/taglib/mpeg/id3v1/id3v1tag.cpp +++ b/taglib/mpeg/id3v1/id3v1tag.cpp @@ -62,10 +62,9 @@ namespace class ID3v1::Tag::TagPrivate { public: - TagPrivate() : file(0), tagOffset(-1), track(0), genre(255) {} - - File *file; - long long tagOffset; + TagPrivate() : + track(0), + genre(255) {} String title; String artist; @@ -80,18 +79,17 @@ public: // public methods //////////////////////////////////////////////////////////////////////////////// -ID3v1::Tag::Tag() : TagLib::Tag() +ID3v1::Tag::Tag() : + TagLib::Tag(), + d(new TagPrivate()) { - d = new TagPrivate; } -ID3v1::Tag::Tag(File *file, long long tagOffset) : TagLib::Tag() +ID3v1::Tag::Tag(File *file, long long tagOffset) : + TagLib::Tag(), + d(new TagPrivate()) { - d = new TagPrivate; - d->file = file; - d->tagOffset = tagOffset; - - read(); + read(file, tagOffset); } ID3v1::Tag::~Tag() @@ -222,12 +220,12 @@ void ID3v1::Tag::setStringHandler(const TagLib::StringHandler *handler) // protected methods //////////////////////////////////////////////////////////////////////////////// -void ID3v1::Tag::read() +void ID3v1::Tag::read(File *file, long tagOffset) { - if(d->file && d->file->isValid()) { - d->file->seek(d->tagOffset); + if(file && file->isValid()) { + file->seek(tagOffset); // read the tag -- always 128 bytes - ByteVector data = d->file->readBlock(128); + const ByteVector data = file->readBlock(128); // some initial sanity checking if(data.size() == 128 && data.startsWith("TAG")) diff --git a/taglib/mpeg/id3v1/id3v1tag.h b/taglib/mpeg/id3v1/id3v1tag.h index dbc15d4d..fb24b468 100644 --- a/taglib/mpeg/id3v1/id3v1tag.h +++ b/taglib/mpeg/id3v1/id3v1tag.h @@ -140,7 +140,7 @@ namespace TagLib { /*! * Reads from the file specified in the constructor. */ - void read(); + void read(File *file, long tagOffset); /*! * Pareses the body of the tag in \a data. */ diff --git a/taglib/mpeg/id3v2/id3v2tag.cpp b/taglib/mpeg/id3v2/id3v2tag.cpp index e7e6ff7b..786d7d25 100644 --- a/taglib/mpeg/id3v2/id3v2tag.cpp +++ b/taglib/mpeg/id3v2/id3v2tag.cpp @@ -84,8 +84,7 @@ class ID3v2::Tag::TagPrivate { public: TagPrivate() : - file(0), - tagOffset(-1), + fileLength(0), extendedHeader(0), footer(0) { @@ -98,8 +97,7 @@ public: delete footer; } - File *file; - long long tagOffset; + long long fileLength; const FrameFactory *factory; Header header; @@ -125,11 +123,9 @@ ID3v2::Tag::Tag(File *file, long long tagOffset, const FrameFactory *factory) : TagLib::Tag(), d(new TagPrivate()) { - d->file = file; - d->tagOffset = tagOffset; d->factory = factory; - read(); + read(file, tagOffset); } ID3v2::Tag::~Tag() @@ -794,7 +790,8 @@ ByteVector ID3v2::Tag::render(int version) const // Compute the amount of padding, and append that to tagData. - long long paddingSize = d->header.tagSize() - (tagData.size() - Header::size()); + long long originalSize = d->header.tagSize(); + long long paddingSize = originalSize - (tagData.size() - Header::size()); if(paddingSize <= 0) { paddingSize = MinPaddingSize; @@ -802,7 +799,7 @@ ByteVector ID3v2::Tag::render(int version) const else { // Padding won't increase beyond 1% of the file size or 1MB. - long long threshold = d->file ? d->file->length() / 100 : 0; + long long threshold = d->fileLength / 100; threshold = std::max(threshold, MinPaddingSize); threshold = std::min(threshold, MaxPaddingSize); @@ -816,6 +813,9 @@ ByteVector ID3v2::Tag::render(int version) const d->header.setMajorVersion(version); d->header.setTagSize(static_cast(tagData.size() - Header::size())); + if(d->fileLength > 0) + d->fileLength += (d->header.tagSize() - originalSize); + // TODO: This should eventually include d->footer->render(). const ByteVector headerData = d->header.render(); std::copy(headerData.begin(), headerData.end(), tagData.begin()); @@ -840,22 +840,24 @@ void ID3v2::Tag::setLatin1StringHandler(const TagLib::StringHandler *handler) // protected members //////////////////////////////////////////////////////////////////////////////// -void ID3v2::Tag::read() +void ID3v2::Tag::read(TagLib::File *file, long offset) { - if(!d->file) + if(!file) return; - if(!d->file->isOpen()) + if(!file->isOpen()) return; - d->file->seek(d->tagOffset); - d->header.setData(d->file->readBlock(Header::size())); + d->fileLength = file->length(); + + file->seek(offset); + d->header.setData(file->readBlock(Header::size())); // If the tag size is 0, then this is an invalid tag (tags must contain at // least one frame) if(d->header.tagSize() != 0) - parse(d->file->readBlock(d->header.tagSize())); + parse(file->readBlock(d->header.tagSize())); // Look for duplicate ID3v2 tags and treat them as an extra blank of this one. // It leads to overwriting them with zero when saving the tag. @@ -867,9 +869,9 @@ void ID3v2::Tag::read() while(true) { - d->file->seek(d->tagOffset + d->header.completeTagSize() + extraSize); + file->seek(offset + d->header.completeTagSize() + extraSize); - const ByteVector data = d->file->readBlock(Header::size()); + const ByteVector data = file->readBlock(Header::size()); if(data.size() < Header::size() || !data.startsWith(Header::fileIdentifier())) break; diff --git a/taglib/mpeg/id3v2/id3v2tag.h b/taglib/mpeg/id3v2/id3v2tag.h index 7e2e756f..bdc0f3c9 100644 --- a/taglib/mpeg/id3v2/id3v2tag.h +++ b/taglib/mpeg/id3v2/id3v2tag.h @@ -356,7 +356,7 @@ namespace TagLib { * the Header, the body of the tag (which contains the ExtendedHeader and * frames) and Footer. */ - void read(); + void read(TagLib::File *file, long offset); /*! * This is called by read to parse the body of the tag. It determines if an diff --git a/taglib/riff/aiff/aifffile.cpp b/taglib/riff/aiff/aifffile.cpp index bd02c067..85257724 100644 --- a/taglib/riff/aiff/aifffile.cpp +++ b/taglib/riff/aiff/aifffile.cpp @@ -100,11 +100,16 @@ bool RIFF::AIFF::File::save() return false; } - removeChunk("ID3 "); - removeChunk("id3 "); + if(d->hasID3v2) { + removeChunk("ID3 "); + removeChunk("id3 "); + d->hasID3v2 = false; + } - setChunkData("ID3 ", d->tag->render()); - d->hasID3v2 = true; + if(tag() && !tag()->isEmpty()) { + setChunkData("ID3 ", d->tag->render()); + d->hasID3v2 = true; + } return true; } diff --git a/taglib/riff/rifffile.cpp b/taglib/riff/rifffile.cpp index 40b3b5d8..d6e583d3 100644 --- a/taglib/riff/rifffile.cpp +++ b/taglib/riff/rifffile.cpp @@ -23,13 +23,15 @@ * http://www.mozilla.org/MPL/ * ***************************************************************************/ +#include +#include + #include #include #include #include "rifffile.h" -#include -#include +#include "riffutils.h" using namespace TagLib; @@ -47,13 +49,11 @@ namespace class RIFF::File::FilePrivate { public: - FilePrivate() : - endianness(BigEndian), - size(0) - { - } + FilePrivate(ByteOrder endianness) : + endianness(endianness), + size(0) {} - ByteOrder endianness; + const ByteOrder endianness; ByteVector type; TagLib::uint size; ByteVector format; @@ -88,20 +88,18 @@ bool RIFF::File::isValidChunkName(const ByteVector &name) // static // protected members //////////////////////////////////////////////////////////////////////////////// -RIFF::File::File(FileName file, ByteOrder endianness) : TagLib::File(file) +RIFF::File::File(FileName file, ByteOrder endianness) : + TagLib::File(file), + d(new FilePrivate(endianness)) { - d = new FilePrivate; - d->endianness = endianness; - if(isOpen()) read(); } -RIFF::File::File(IOStream *stream, ByteOrder endianness) : TagLib::File(stream) +RIFF::File::File(IOStream *stream, ByteOrder endianness) : + TagLib::File(stream), + d(new FilePrivate(endianness)) { - d = new FilePrivate; - d->endianness = endianness; - if(isOpen()) read(); } @@ -288,7 +286,7 @@ void RIFF::File::read() break; } - if(static_cast(tell()) + chunkSize > static_cast(length())) { + if(tell() + chunkSize > length()) { debug("RIFF::File::read() -- Chunk '" + chunkName + "' has invalid size (larger than the file size)"); setValid(false); break; @@ -314,8 +312,8 @@ void RIFF::File::read() chunk.padding = 1; } } - d->chunks.push_back(chunk); + d->chunks.push_back(chunk); } } diff --git a/taglib/riff/riffutils.h b/taglib/riff/riffutils.h new file mode 100644 index 00000000..c9270dff --- /dev/null +++ b/taglib/riff/riffutils.h @@ -0,0 +1,55 @@ +/*************************************************************************** + copyright : (C) 2015 by Tsuda Kageyu + email : tsuda.kageyu@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library 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 * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * + * 02110-1301 USA * + * * + * Alternatively, this file is available under the Mozilla Public * + * License Version 1.1. You may obtain a copy of the License at * + * http://www.mozilla.org/MPL/ * + ***************************************************************************/ + +#ifndef TAGLIB_RIFFUTILS_H +#define TAGLIB_RIFFUTILS_H + +// THIS FILE IS NOT A PART OF THE TAGLIB API + +#ifndef DO_NOT_DOCUMENT // tell Doxygen not to document this header + +namespace TagLib +{ + namespace RIFF + { + static bool isValidChunkName(const ByteVector &name) + { + if(name.size() != 4) + return false; + + for(ByteVector::ConstIterator it = name.begin(); it != name.end(); ++it) { + const uchar c = static_cast(*it); + if(c < 32 || 127 < c) + return false; + } + + return true; + } + } +} + +#endif + +#endif diff --git a/taglib/riff/wav/infotag.cpp b/taglib/riff/wav/infotag.cpp index 6b2ee6d2..ab60bd6c 100644 --- a/taglib/riff/wav/infotag.cpp +++ b/taglib/riff/wav/infotag.cpp @@ -29,6 +29,7 @@ #include "rifffile.h" #include "infotag.h" +#include "riffutils.h" using namespace TagLib; using namespace RIFF::Info; @@ -66,16 +67,16 @@ public: // public members //////////////////////////////////////////////////////////////////////////////// -RIFF::Info::Tag::Tag(const ByteVector &data) - : TagLib::Tag() - , d(new TagPrivate()) +RIFF::Info::Tag::Tag(const ByteVector &data) : + TagLib::Tag(), + d(new TagPrivate()) { parse(data); } -RIFF::Info::Tag::Tag() - : TagLib::Tag() - , d(new TagPrivate()) +RIFF::Info::Tag::Tag() : + TagLib::Tag(), + d(new TagPrivate()) { } @@ -189,8 +190,8 @@ String RIFF::Info::Tag::fieldText(const ByteVector &id) const void RIFF::Info::Tag::setFieldText(const ByteVector &id, const String &s) { - // id must be four-byte long pure ASCII string. - if(!RIFF::File::isValidChunkName(id)) + // id must be four-byte long pure ascii string. + if(!isValidChunkName(id)) return; if(!s.isEmpty()) @@ -209,8 +210,7 @@ ByteVector RIFF::Info::Tag::render() const { ByteVector data("INFO"); - FieldMap::ConstIterator it = d->fieldMap.begin(); - for(; it != d->fieldMap.end(); ++it) { + for(FieldMap::ConstIterator it = d->fieldMap.begin(); it != d->fieldMap.end(); ++it) { ByteVector text = stringHandler->render(it->second); if(text.isEmpty()) continue; @@ -251,7 +251,7 @@ void RIFF::Info::Tag::parse(const ByteVector &data) break; const ByteVector id = data.mid(p, 4); - if(RIFF::File::isValidChunkName(id)) { + if(isValidChunkName(id)) { const String text = stringHandler->parse(data.mid(p + 8, size)); d->fieldMap[id] = text; } diff --git a/taglib/toolkit/tbytevector.cpp b/taglib/toolkit/tbytevector.cpp index 85b86754..69feb40c 100644 --- a/taglib/toolkit/tbytevector.cpp +++ b/taglib/toolkit/tbytevector.cpp @@ -265,15 +265,15 @@ long double toFloat80(const ByteVector &v, size_t offset) const int exponent = ((bytes[0] & 0x7F) << 8) | bytes[1]; // 64-bit fraction. Leading 1 is explicit. - const ulonglong fraction - = (static_cast(bytes[2]) << 56) - | (static_cast(bytes[3]) << 48) - | (static_cast(bytes[4]) << 40) - | (static_cast(bytes[5]) << 32) - | (static_cast(bytes[6]) << 24) - | (static_cast(bytes[7]) << 16) - | (static_cast(bytes[8]) << 8) - | (static_cast(bytes[9])); + const unsigned long long fraction + = (static_cast(bytes[2]) << 56) + | (static_cast(bytes[3]) << 48) + | (static_cast(bytes[4]) << 40) + | (static_cast(bytes[5]) << 32) + | (static_cast(bytes[6]) << 24) + | (static_cast(bytes[7]) << 16) + | (static_cast(bytes[8]) << 8) + | (static_cast(bytes[9])); long double val; if(exponent == 0 && fraction == 0) @@ -382,12 +382,12 @@ ByteVector ByteVector::fromFloat32BE(float value) ByteVector ByteVector::fromFloat64LE(double value) { - return fromFloat(value); + return fromFloat(value); } ByteVector ByteVector::fromFloat64BE(double value) { - return fromFloat(value); + return fromFloat(value); } //////////////////////////////////////////////////////////////////////////////// @@ -755,12 +755,12 @@ float ByteVector::toFloat32BE(size_t offset) const double ByteVector::toFloat64LE(size_t offset) const { - return toFloat(*this, offset); + return toFloat(*this, offset); } double ByteVector::toFloat64BE(size_t offset) const { - return toFloat(*this, offset); + return toFloat(*this, offset); } long double ByteVector::toFloat80LE(size_t offset) const diff --git a/taglib/toolkit/tstring.cpp b/taglib/toolkit/tstring.cpp index aadea5d3..77a454c5 100644 --- a/taglib/toolkit/tstring.cpp +++ b/taglib/toolkit/tstring.cpp @@ -174,7 +174,7 @@ namespace if(length > 0) { if(swap) { for(size_t i = 0; i < length; ++i) - data[i] = Utils::byteSwap(static_cast(s[i])); + data[i] = Utils::byteSwap(static_cast(s[i])); } else { ::wmemcpy(&data[0], s, length); @@ -194,7 +194,7 @@ namespace } // Uses memcpy instead of reinterpret_cast to avoid an alignment exception. - ushort bom; + TagLib::ushort bom; ::memcpy(&bom, s, 2); if(bom == 0xfeff) @@ -215,7 +215,7 @@ namespace data.resize(length / 2); for(size_t i = 0; i < length / 2; ++i) { - ushort c; + TagLib::ushort c; ::memcpy(&c, s, 2); if(swap) c = Utils::byteSwap(c); diff --git a/taglib/toolkit/tutils.h b/taglib/toolkit/tutils.h index 146743a4..b3a0e7af 100644 --- a/taglib/toolkit/tutils.h +++ b/taglib/toolkit/tutils.h @@ -134,7 +134,7 @@ namespace TagLib /*! * Reverses the order of bytes in an 64-bit integer. */ - inline ulonglong byteSwap(ulonglong x) + inline unsigned long long byteSwap(unsigned long long x) { #if defined(HAVE_BOOST_BYTESWAP) diff --git a/tests/data/blank_video.m4v b/tests/data/blank_video.m4v new file mode 100644 index 00000000..4bb15ded Binary files /dev/null and b/tests/data/blank_video.m4v differ diff --git a/tests/test_aiff.cpp b/tests/test_aiff.cpp index 470f690e..b7aa8385 100644 --- a/tests/test_aiff.cpp +++ b/tests/test_aiff.cpp @@ -64,14 +64,23 @@ public: { RIFF::AIFF::File f(newname.c_str()); CPPUNIT_ASSERT(!f.hasID3v2Tag()); + f.tag()->setTitle(L"TitleXXX"); f.save(); + CPPUNIT_ASSERT(f.hasID3v2Tag()); } - { RIFF::AIFF::File f(newname.c_str()); CPPUNIT_ASSERT(f.hasID3v2Tag()); CPPUNIT_ASSERT_EQUAL(String(L"TitleXXX"), f.tag()->title()); + + f.tag()->setTitle(""); + f.save(); + CPPUNIT_ASSERT(!f.hasID3v2Tag()); + } + { + RIFF::AIFF::File f(newname.c_str()); + CPPUNIT_ASSERT(!f.hasID3v2Tag()); } } diff --git a/tests/test_fileref.cpp b/tests/test_fileref.cpp index 29258c86..4495a628 100644 --- a/tests/test_fileref.cpp +++ b/tests/test_fileref.cpp @@ -38,6 +38,7 @@ class TestFileRef : public CppUnit::TestFixture CPPUNIT_TEST(testMP4_1); CPPUNIT_TEST(testMP4_2); CPPUNIT_TEST(testMP4_3); + CPPUNIT_TEST(testMP4_4); CPPUNIT_TEST(testTrueAudio); CPPUNIT_TEST(testAPE); CPPUNIT_TEST(testWav); @@ -155,6 +156,11 @@ public: fileRefSave("no-tags", ".3g2"); } + void testMP4_4() + { + fileRefSave("blank_video", ".m4v"); + } + void testWav() { fileRefSave("empty", ".wav"); diff --git a/tests/test_mp4.cpp b/tests/test_mp4.cpp index 7a1dbd0a..313d40ed 100644 --- a/tests/test_mp4.cpp +++ b/tests/test_mp4.cpp @@ -17,6 +17,7 @@ class TestMP4 : public CppUnit::TestFixture CPPUNIT_TEST_SUITE(TestMP4); CPPUNIT_TEST(testPropertiesAAC); CPPUNIT_TEST(testPropertiesALAC); + CPPUNIT_TEST(testPropertiesM4V); CPPUNIT_TEST(testFreeForm); CPPUNIT_TEST(testCheckValid); CPPUNIT_TEST(testHasTag); @@ -64,6 +65,21 @@ public: CPPUNIT_ASSERT_EQUAL(MP4::AudioProperties::ALAC, f.audioProperties()->codec()); } + void testPropertiesM4V() + { + MP4::File f(TEST_FILE_PATH_C("blank_video.m4v")); + CPPUNIT_ASSERT(f.audioProperties()); + CPPUNIT_ASSERT_EQUAL(0, f.audioProperties()->length()); + CPPUNIT_ASSERT_EQUAL(0, f.audioProperties()->lengthInSeconds()); + CPPUNIT_ASSERT_EQUAL(975, f.audioProperties()->lengthInMilliseconds()); + CPPUNIT_ASSERT_EQUAL(96, f.audioProperties()->bitrate()); + CPPUNIT_ASSERT_EQUAL(2, f.audioProperties()->channels()); + CPPUNIT_ASSERT_EQUAL(44100, f.audioProperties()->sampleRate()); + CPPUNIT_ASSERT_EQUAL(16, f.audioProperties()->bitsPerSample()); + CPPUNIT_ASSERT_EQUAL(false, f.audioProperties()->isEncrypted()); + CPPUNIT_ASSERT_EQUAL(MP4::AudioProperties::AAC, f.audioProperties()->codec()); + } + void testCheckValid() { MP4::File f(TEST_FILE_PATH_C("empty.aiff")); diff --git a/tests/test_wav.cpp b/tests/test_wav.cpp index 0aeb91c9..96891877 100644 --- a/tests/test_wav.cpp +++ b/tests/test_wav.cpp @@ -91,26 +91,29 @@ public: { RIFF::WAV::File f(filename.c_str()); CPPUNIT_ASSERT(f.isValid()); + CPPUNIT_ASSERT(!f.hasID3v2Tag()); f.ID3v2Tag()->setTitle(L"Title"); f.ID3v2Tag()->setArtist(L"Artist"); f.save(); + CPPUNIT_ASSERT(f.hasID3v2Tag()); } - { RIFF::WAV::File f(filename.c_str()); CPPUNIT_ASSERT(f.isValid()); + CPPUNIT_ASSERT(f.hasID3v2Tag()); CPPUNIT_ASSERT_EQUAL(String(L"Title"), f.ID3v2Tag()->title()); CPPUNIT_ASSERT_EQUAL(String(L"Artist"), f.ID3v2Tag()->artist()); f.ID3v2Tag()->setTitle(L""); f.ID3v2Tag()->setArtist(L""); f.save(); + CPPUNIT_ASSERT(!f.hasID3v2Tag()); } - { RIFF::WAV::File f(filename.c_str()); CPPUNIT_ASSERT(f.isValid()); + CPPUNIT_ASSERT(!f.hasID3v2Tag()); CPPUNIT_ASSERT_EQUAL(String(L""), f.ID3v2Tag()->title()); CPPUNIT_ASSERT_EQUAL(String(L""), f.ID3v2Tag()->artist()); } @@ -124,26 +127,30 @@ public: { RIFF::WAV::File f(filename.c_str()); CPPUNIT_ASSERT(f.isValid()); + CPPUNIT_ASSERT(!f.hasInfoTag()); f.InfoTag()->setTitle(L"Title"); f.InfoTag()->setArtist(L"Artist"); f.save(); + CPPUNIT_ASSERT(f.hasInfoTag()); } - { RIFF::WAV::File f(filename.c_str()); CPPUNIT_ASSERT(f.isValid()); + CPPUNIT_ASSERT(f.hasInfoTag()); CPPUNIT_ASSERT_EQUAL(String(L"Title"), f.InfoTag()->title()); CPPUNIT_ASSERT_EQUAL(String(L"Artist"), f.InfoTag()->artist()); f.InfoTag()->setTitle(L""); f.InfoTag()->setArtist(L""); f.save(); + CPPUNIT_ASSERT(!f.hasInfoTag()); } { RIFF::WAV::File f(filename.c_str()); CPPUNIT_ASSERT(f.isValid()); + CPPUNIT_ASSERT(!f.hasInfoTag()); CPPUNIT_ASSERT_EQUAL(String(L""), f.InfoTag()->title()); CPPUNIT_ASSERT_EQUAL(String(L""), f.InfoTag()->artist()); }