diff --git a/CMakeLists.txt b/CMakeLists.txt old mode 100755 new mode 100644 index 92cfccd4..91f3fdd7 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,8 +47,8 @@ if (MSVC AND ENABLE_STATIC_RUNTIME) endif() set(TAGLIB_LIB_MAJOR_VERSION "1") -set(TAGLIB_LIB_MINOR_VERSION "8") -set(TAGLIB_LIB_PATCH_VERSION "0") +set(TAGLIB_LIB_MINOR_VERSION "9") +set(TAGLIB_LIB_PATCH_VERSION "1") set(TAGLIB_LIB_VERSION_STRING "${TAGLIB_LIB_MAJOR_VERSION}.${TAGLIB_LIB_MINOR_VERSION}.${TAGLIB_LIB_PATCH_VERSION}") @@ -56,9 +56,9 @@ set(TAGLIB_LIB_VERSION_STRING "${TAGLIB_LIB_MAJOR_VERSION}.${TAGLIB_LIB_MINOR_VE # 2. If any interfaces have been added, removed, or changed since the last update, increment current, and set revision to 0. # 3. If any interfaces have been added since the last public release, then increment age. # 4. If any interfaces have been removed since the last public release, then set age to 0. -set(TAGLIB_SOVERSION_CURRENT 13) +set(TAGLIB_SOVERSION_CURRENT 15) set(TAGLIB_SOVERSION_REVISION 0) -set(TAGLIB_SOVERSION_AGE 12) +set(TAGLIB_SOVERSION_AGE 14) math(EXPR TAGLIB_SOVERSION_MAJOR "${TAGLIB_SOVERSION_CURRENT} - ${TAGLIB_SOVERSION_AGE}") math(EXPR TAGLIB_SOVERSION_MINOR "${TAGLIB_SOVERSION_AGE}") diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake old mode 100755 new mode 100644 diff --git a/INSTALL b/INSTALL index 3be4d131..9e6e8075 100644 --- a/INSTALL +++ b/INSTALL @@ -46,15 +46,102 @@ the include folder to the project's User Header Search Paths. Windows ------- -For building a static library on Windows with Visual Studio 2010, cd to -the TagLib folder then: +It's Windows ... Systems vary! +This means you need to adjust things to suit your system, especially paths. - cmake -DENABLE_STATIC=ON -DENABLE_STATIC_RUNTIME=ON -G "Visual Studio 10" ... +Tested with: + Microsoft Visual Studio 2010 + Gcc by mingw-w64.sf.net v4.6.3 (Strawberry Perl 32b) + MinGW32-4.8.0 + +Requirements: + 1. Tool chain, Build Environment, Whatever ya want to call it ... + Installed and working. + 2. CMake program. (Available at: www.cmake.org) + Installed and working. + +Optional: + 1. Zlib library. + Available in some Tool Chains, Not all. + Search the web, Take your choice. + +Useful configuration options used with CMake (GUI and/or Command line): + Any of the ZLIB_ variables may be used at the command line, ZLIB_ROOT is only + available on the Command line. + ZLIB_ROOT= Where to find ZLib's root directory. + Assumes parent of: \include and \lib. + ZLIB_INCLUDE_DIR= Where to find ZLib's Include directory. + ZLIB_LIBRARY= Where to find ZLib's Library. + CMAKE_INSTALL_PREFIX= Where to install Taglib. + CMAKE_BUILD_TYPE= Release, Debug, etc ... (Not available in MSVC) + +The easiest way is at the Command Prompt. + MSVS Command Prompt for MSVS Users. + (Batch file and/or Shortcuts are your friends) + + 1. Build the Makefiles: + Replace "GENERATOR" with your needs. + For MSVS : "Visual Studio X" where X is the single or two digit version. + For MinGW: "MinGW Makefiles" + + C:\GitRoot\taglib> cmake -G "GENERATOR" -DCMAKE_INSTALL_PREFIX=C:\Libraries\taglib + + Or use the CMake GUI: + 1. Open CMake GUI. + 2. Set Paths. + "Where is the source code" and "Where to build the binaries" + Example, Both would be: C:\GitRoot\taglib + 3. Tick: Advanced + 4. Select: Configure + 5. Select: Generator + 6. Tick: Use default native compilers + 7. Select: Finish + Wait until done. + 5. If using ZLib, Scroll down. + (to the bottom of the list of options ... should go over them all) + 1. Edit: ZLIB_INCLUDE_DIR + 2. Edit: ZLIB_LIBRARY + 6. Select: Generate + + 2. Build the project: + MSVS: + C:\GitRoot\taglib> msbuild all_build.vcxproj /p:Configuration=Release + OR (Depending on MSVS version or personal choice) + C:\GitRoot\taglib> devenv all_build.vcxproj /build Release + MinGW: + C:\GitRoot\taglib> gmake + OR (Depending on MinGW install) + C:\GitRoot\taglib> mingw32-make + + Or in the MSVS GUI: + 1. Open MSVS. + 2. Open taglib solution. + 3. Set build type to: Release (look in the tool bars) + 2. Hit F7 to build the solution. (project) + + 3. Install the project: + (Change 'install' to 'uninstall' to uninstall the project) + MSVS: + C:\GitRoot\taglib> msbuild install.vcxproj + OR (Depending on MSVC version or personal choice) + C:\GitRoot\taglib> devenv install.vcxproj + MinGW: + C:\GitRoot\taglib> gmake install + OR (Depending on MinGW install) + C:\GitRoot\taglib> mingw32-make install + + Or in the MSVS GUI: + 1. Open project. + 2. Open Solution Explorer. + 3. Right Click: INSTALL + 4. Select: Project Only + 5. Select: Build Only INSTALL + +To build a static library enable the following two options with CMake. + -DENABLE_STATIC=ON -DENABLE_STATIC_RUNTIME=ON Including ENABLE_STATIC_RUNTIME=ON indicates you want TagLib built using the static runtime library, rather than the DLL form of the runtime. -CMake will create a Visual Studio solution, taglib.sln that you can open and -build as normal. Unit Tests ---------- diff --git a/NEWS b/NEWS index 24d396cd..72d41fba 100644 --- a/NEWS +++ b/NEWS @@ -1,16 +1,33 @@ -TagLib 1.9 (In Development) +TagLib 1.9.1 (Oct 8, 2013) ========================== + * Fixed binary incompatible change in TagLib::Map and TagLib::List. + * Fixed constructing String from ByteVector. + * Fixed compilation on MSVC with the /Zc:wchar_t- option. + * Fixed detecting of RIFF files with invalid chunk sizes. + * Added TagLib::MP4::PropertyMap::codec(). + +TagLib 1.9 (Oct 6, 2013) +======================== + * Added support for the Ogg Opus file format. * Added support for INFO tags in WAV files. * Changed FileStream to use Windows file API. * Included taglib-config.cmd script for Windows. * New ID3v1::Tag methods for working directly with genre numbers. * New MPEG::File methods for checking which tags are saved in the file. + * Added support for the PropertyMap API to ASF and MP4 files. + * Added MusicBrainz identifiers to the PropertyMap API. + * Allowed reading of MP4 cover art without an explicitly specified format. * Better parsing of corrupted FLAC files. * Fixed saving of PropertyMap comments without description into ID3v2 tags. * Fixed crash when parsing certain XM files. * Fixed compilation of unit test with clang. + * Better handling of files that can't be open or have read-only permissions. + * Improved atomic reference counting. + * New hookable API for debug messages. + * More complete Windows install instructions. + * Many smaller bug fixes and performance improvements. TagLib 1.8 (Sep 6, 2012) ======================== diff --git a/taglib-config.cmd.cmake b/taglib-config.cmd.cmake old mode 100755 new mode 100644 diff --git a/taglib/CMakeLists.txt b/taglib/CMakeLists.txt old mode 100755 new mode 100644 diff --git a/taglib/fileref.h b/taglib/fileref.h old mode 100755 new mode 100644 diff --git a/taglib/mp4/mp4properties.cpp b/taglib/mp4/mp4properties.cpp index 5ab189d8..2eef4ec2 100644 --- a/taglib/mp4/mp4properties.cpp +++ b/taglib/mp4/mp4properties.cpp @@ -41,13 +41,7 @@ public: channels(0), bitsPerSample(0), encrypted(false), - format(Unknown) {} - - enum Format { - Unknown = 0, - AAC = 1, - ALAC = 2, - }; + codec(Unknown) {} int length; int bitrate; @@ -55,9 +49,13 @@ public: int channels; int bitsPerSample; bool encrypted; - Format format; + Codec codec; }; +//////////////////////////////////////////////////////////////////////////////// +// public members +//////////////////////////////////////////////////////////////////////////////// + MP4::AudioProperties::AudioProperties(File *file, MP4::Atoms *atoms, ReadStyle style) : d(new PropertiesPrivate()) { @@ -105,14 +103,20 @@ MP4::AudioProperties::isEncrypted() const return d->encrypted; } +MP4::AudioProperties::Codec +MP4::AudioProperties::codec() const +{ + return d->codec; +} + String MP4::AudioProperties::toString() const { String format; - if(d->format == PropertiesPrivate::AAC) { + if(d->codec == AAC) { format = "AAC"; } - else if(d->format == PropertiesPrivate::ALAC) { + else if(d->codec == ALAC) { format = "ALAC"; } else { @@ -125,6 +129,10 @@ MP4::AudioProperties::toString() const return desc.toString(", "); } +//////////////////////////////////////////////////////////////////////////////// +// private members +//////////////////////////////////////////////////////////////////////////////// + void MP4::AudioProperties::read(File *file, Atoms *atoms) { @@ -193,7 +201,7 @@ MP4::AudioProperties::read(File *file, Atoms *atoms) file->seek(atom->offset); data = file->readBlock(atom->length); if(data.mid(20, 4) == "mp4a") { - d->format = PropertiesPrivate::AAC; + d->codec = AAC; d->channels = data.toInt16BE(40); d->bitsPerSample = data.toInt16BE(42); d->sampleRate = data.toUInt32BE(46); @@ -214,7 +222,7 @@ MP4::AudioProperties::read(File *file, Atoms *atoms) } } else if (data.mid(20, 4) == "alac") { - d->format = PropertiesPrivate::ALAC; + d->codec = ALAC; if (atom->length == 88 && data.mid(56, 4) == "alac") { d->bitsPerSample = data.at(69); d->channels = data.at(73); diff --git a/taglib/mp4/mp4properties.h b/taglib/mp4/mp4properties.h index 99de9dd0..53f6c01f 100644 --- a/taglib/mp4/mp4properties.h +++ b/taglib/mp4/mp4properties.h @@ -40,6 +40,12 @@ namespace TagLib { class TAGLIB_EXPORT AudioProperties : public TagLib::AudioProperties { public: + enum Codec { + Unknown = 0, + AAC, + ALAC + }; + AudioProperties(File *file, Atoms *atoms, ReadStyle style = Average); virtual ~AudioProperties(); @@ -50,6 +56,9 @@ namespace TagLib { virtual int bitsPerSample() const; bool isEncrypted() const; + //! Audio codec used in the MP4 file + Codec codec() const; + String toString() const; private: diff --git a/taglib/mpeg/id3v1/id3v1tag.h b/taglib/mpeg/id3v1/id3v1tag.h index 46813b3f..05e00521 100644 --- a/taglib/mpeg/id3v1/id3v1tag.h +++ b/taglib/mpeg/id3v1/id3v1tag.h @@ -153,14 +153,14 @@ namespace TagLib { /*! * Returns the genre in number. * - * /note Normally 255 indicates that this tag contains no genre. + * \note Normally 255 indicates that this tag contains no genre. */ TagLib::uint genreNumber() const; /*! * Sets the genre in number to \a i. * - * /note Valid value is from 0 up to 255. Normally 255 indicates that + * \note Valid value is from 0 up to 255. Normally 255 indicates that * this tag contains no genre. */ void setGenreNumber(TagLib::uint i); diff --git a/taglib/mpeg/id3v2/id3v2frame.cpp b/taglib/mpeg/id3v2/id3v2frame.cpp index 60c6d18b..2f1d73e6 100644 --- a/taglib/mpeg/id3v2/id3v2frame.cpp +++ b/taglib/mpeg/id3v2/id3v2frame.cpp @@ -325,7 +325,7 @@ namespace static const TagLib::uint frameTranslationSize = 51; static const char *frameTranslation[][2] = { // Text information frames - { "TALB", "ALBUM"}, + { "TALB", "ALBUM" }, { "TBPM", "BPM" }, { "TCOM", "COMPOSER" }, { "TCON", "GENRE" }, @@ -388,7 +388,7 @@ namespace //{ "USLT", "LYRICS" }, handled specially }; - static const TagLib::uint txxxFrameTranslationSize = 7; + static const TagLib::uint txxxFrameTranslationSize = 8; static const char *txxxFrameTranslation[][2] = { { "MusicBrainz Album Id", "MUSICBRAINZ_ALBUMID" }, { "MusicBrainz Artist Id", "MUSICBRAINZ_ARTISTID" }, diff --git a/taglib/riff/rifffile.cpp b/taglib/riff/rifffile.cpp index 87b3a0fa..34dde282 100644 --- a/taglib/riff/rifffile.cpp +++ b/taglib/riff/rifffile.cpp @@ -28,6 +28,7 @@ #include #include "rifffile.h" +#include #include using namespace TagLib; @@ -293,7 +294,7 @@ void RIFF::File::read() break; } - if(tell() + chunkSize > uint(length())) { + if(static_cast(tell()) + chunkSize > static_cast(length())) { debug("RIFF::File::read() -- Chunk '" + chunkName + "' has invalid size (larger than the file size)"); setValid(false); break; diff --git a/taglib/riff/wav/infotag.cpp b/taglib/riff/wav/infotag.cpp index 2530e78f..9857f489 100644 --- a/taglib/riff/wav/infotag.cpp +++ b/taglib/riff/wav/infotag.cpp @@ -171,6 +171,11 @@ bool RIFF::Info::Tag::isEmpty() const return d->fieldListMap.isEmpty(); } +FieldListMap RIFF::Info::Tag::fieldListMap() const +{ + return d->fieldListMap; +} + String RIFF::Info::Tag::fieldText(const ByteVector &id) const { if(d->fieldListMap.contains(id)) diff --git a/taglib/riff/wav/infotag.h b/taglib/riff/wav/infotag.h index a812e87e..8fba7040 100644 --- a/taglib/riff/wav/infotag.h +++ b/taglib/riff/wav/infotag.h @@ -120,6 +120,18 @@ namespace TagLib { virtual bool isEmpty() const; + /*! + * Returns a copy of the internal fields of the tag. The returned map directly + * reflects the contents of the "INFO" chunk. + * + * \note Modifying this map does not affect the tag's internal data. + * Use setFieldText() and removeField() instead. + * + * \see setFieldText() + * \see removeField() + */ + FieldListMap fieldListMap() const; + /* * Gets the value of the field with the ID \a id. */ diff --git a/taglib/toolkit/taglib.h b/taglib/toolkit/taglib.h index 723de570..dbbdc81c 100644 --- a/taglib/toolkit/taglib.h +++ b/taglib/toolkit/taglib.h @@ -27,8 +27,8 @@ #define TAGLIB_H #define TAGLIB_MAJOR_VERSION 1 -#define TAGLIB_MINOR_VERSION 8 -#define TAGLIB_PATCH_VERSION 0 +#define TAGLIB_MINOR_VERSION 9 +#define TAGLIB_PATCH_VERSION 1 #if (defined(_MSC_VER) && _MSC_VER >= 1600) #define TAGLIB_CONSTRUCT_BITSET(x) static_cast(x) diff --git a/taglib/toolkit/tbytevector.cpp b/taglib/toolkit/tbytevector.cpp index 796cf6da..4a02dbc7 100644 --- a/taglib/toolkit/tbytevector.cpp +++ b/taglib/toolkit/tbytevector.cpp @@ -27,11 +27,13 @@ #include #endif +#include #include #include #include #include #include +#include #include "tstring.h" #include "tdebug.h" @@ -464,60 +466,41 @@ ByteVector &ByteVector::replace(const ByteVector &pattern, const ByteVector &wit if(pattern.size() == 0 || pattern.size() > size()) return *this; - const size_t withSize = with.size(); + const size_t withSize = with.size(); const size_t patternSize = pattern.size(); + const ptrdiff_t diff = withSize - patternSize; + size_t offset = 0; + while (true) + { + offset = find(pattern, offset); + if(offset == npos) + break; - if(withSize == patternSize) { - // I think this case might be common enough to optimize it detach(); - offset = find(pattern); - while(offset != npos) { - ::memcpy(DATA(d) + offset, DATA(with.d), withSize); - offset = find(pattern, offset + withSize); - } - return *this; - } - // calculate new size: - size_t newSize = 0; - for(;;) { - const size_t next = find(pattern, offset); - if(next == npos) { - if(offset == 0) - // pattern not found, do nothing: - return *this; - newSize += size() - offset; + if(diff < 0) { + ::memmove( + data() + offset + withSize, + data() + offset + patternSize, + size() - offset - patternSize); + resize(size() + diff); + } + else if(diff > 0) { + resize(size() + diff); + ::memmove( + data() + offset + withSize, + data() + offset + patternSize, + size() - diff - offset - patternSize); + } + + ::memcpy(data() + offset, with.data(), with.size()); + + offset += withSize; + if(offset > size() - patternSize) break; - } - newSize += (next - offset) + withSize; - offset = next + patternSize; } - // new private data of appropriate size: - ByteVectorPrivate newData(newSize, '\0'); - char *target = &(*newData.data)[0]; - const char *source = DATA(d); - - // copy modified data into new private data: - offset = 0; - for(;;) { - const size_t next = find(pattern, offset); - if(next == npos) { - ::memcpy(target, source + offset, size() - offset); - break; - } - const size_t chunkSize = next - offset; - ::memcpy(target, source + offset, chunkSize); - target += chunkSize; - ::memcpy(target, DATA(with.d), withSize); - target += withSize; - offset += chunkSize + patternSize; - } - - // replace private data: - *d = newData; - return *this; } diff --git a/taglib/toolkit/tiostream.cpp b/taglib/toolkit/tiostream.cpp index 69f01227..d847ad60 100644 --- a/taglib/toolkit/tiostream.cpp +++ b/taglib/toolkit/tiostream.cpp @@ -41,8 +41,12 @@ namespace bool supportsUnicode() { +#ifdef UNICODE + return true; +#else const FARPROC p = GetProcAddress(GetModuleHandleA("kernel32"), "CreateFileW"); return (p != NULL); +#endif } // Indicates whether the system supports Unicode file names. diff --git a/taglib/toolkit/trefcounter.h b/taglib/toolkit/trefcounter.h index 9c927e81..424f6d49 100644 --- a/taglib/toolkit/trefcounter.h +++ b/taglib/toolkit/trefcounter.h @@ -35,6 +35,7 @@ */ namespace TagLib { + class TAGLIB_EXPORT RefCounter { public: @@ -49,7 +50,9 @@ namespace TagLib class RefCounterPrivate; RefCounterPrivate *d; }; + } #endif // DO_NOT_DOCUMENT #endif + diff --git a/taglib/toolkit/tstring.cpp b/taglib/toolkit/tstring.cpp index a8579664..26a16643 100644 --- a/taglib/toolkit/tstring.cpp +++ b/taglib/toolkit/tstring.cpp @@ -267,6 +267,9 @@ String::String(const ByteVector &v, Type t) copyFromUTF8(v.data(), v.size()); else copyFromUTF16(v.data(), v.size(), t); + + // If we hit a null in the ByteVector, shrink the string again. + d->data->resize(::wcslen(d->data->c_str())); } //////////////////////////////////////////////////////////////////////////////// diff --git a/taglib/toolkit/tstring.h b/taglib/toolkit/tstring.h index 353d6363..23714d45 100644 --- a/taglib/toolkit/tstring.h +++ b/taglib/toolkit/tstring.h @@ -231,7 +231,7 @@ namespace TagLib { * The returned pointer remains valid until this String instance is destroyed * or any other method of this String is called. * - * /note This returns a pointer to the String's internal data without any + * \note This returns a pointer to the String's internal data without any * conversions. * * \see toWString() diff --git a/taglib/toolkit/unicode.h b/taglib/toolkit/unicode.h index b9de0ea2..ebf1915d 100644 --- a/taglib/toolkit/unicode.h +++ b/taglib/toolkit/unicode.h @@ -106,6 +106,11 @@ bit mask & shift operations. ------------------------------------------------------------------------ */ +// Workaround for when MSVC doesn't have wchar_t as a built-in type. +#if defined(_MSC_VER) && !defined(_WCHAR_T_DEFINED) +# include +#endif + /* Some fundamental constants */ #define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD #define UNI_MAX_BMP (UTF32)0x0000FFFF @@ -114,10 +119,10 @@ namespace Unicode { -typedef unsigned long UTF32; /* at least 32 bits */ -typedef wchar_t UTF16; /* TagLib assumes that wchar_t is sufficient for UTF-16. */ +typedef unsigned long UTF32; /* at least 32 bits */ +typedef wchar_t UTF16; /* TagLib assumes that wchar_t is sufficient for UTF-16. */ typedef unsigned char UTF8; /* typically 8 bits */ -typedef unsigned char Boolean; /* 0 or 1 */ +typedef unsigned char Boolean; /* 0 or 1 */ typedef enum { conversionOK = 0, /* conversion successful */ diff --git a/taglib/wavpack/wavpackproperties.cpp b/taglib/wavpack/wavpackproperties.cpp index 9dc023cc..941d7281 100644 --- a/taglib/wavpack/wavpackproperties.cpp +++ b/taglib/wavpack/wavpackproperties.cpp @@ -112,8 +112,9 @@ TagLib::uint WavPack::AudioProperties::sampleFrames() const namespace { - const unsigned int sample_rates[] = { 6000, 8000, 9600, 11025, 12000, - 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000, 192000 }; + static const unsigned int sample_rates[] = { + 6000, 8000, 9600, 11025, 12000, 16000, 22050, 24000, + 32000, 44100, 48000, 64000, 88200, 96000, 192000, 0 }; } #define BYTES_STORED 3 diff --git a/taglib/wavpack/wavpackproperties.h b/taglib/wavpack/wavpackproperties.h index 06553a05..a02720e0 100644 --- a/taglib/wavpack/wavpackproperties.h +++ b/taglib/wavpack/wavpackproperties.h @@ -65,7 +65,12 @@ namespace TagLib { virtual int length() const; virtual int bitrate() const; + + /*! + * Returns the sample rate in Hz. 0 means unknown or custom. + */ virtual int sampleRate() const; + virtual int channels() const; /*! diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 7a5bbbf9..cea728a0 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -55,6 +55,7 @@ SET(test_runner_SRCS test_ape.cpp test_apetag.cpp test_wav.cpp + test_info.cpp test_wavpack.cpp test_mp4.cpp test_mp4item.cpp diff --git a/tests/test_bytevector.cpp b/tests/test_bytevector.cpp index 7965f531..eb844fcf 100644 --- a/tests/test_bytevector.cpp +++ b/tests/test_bytevector.cpp @@ -232,6 +232,11 @@ public: a.replace(ByteVector("ab"), ByteVector()); CPPUNIT_ASSERT_EQUAL(ByteVector("cdf"), a); } + { + ByteVector a("abcdabf"); + a.replace(ByteVector("bf"), ByteVector("x")); + CPPUNIT_ASSERT_EQUAL(ByteVector("abcdax"), a); + } } }; diff --git a/tests/test_id3v1.cpp b/tests/test_id3v1.cpp index 1d0a4974..7db2dbbf 100644 --- a/tests/test_id3v1.cpp +++ b/tests/test_id3v1.cpp @@ -1,7 +1,10 @@ #include #include +#include +#include #include #include +#include "utils.h" using namespace std; using namespace TagLib; @@ -16,8 +19,20 @@ public: void testStripWhiteSpace() { - ID3v1::StringHandler h; - CPPUNIT_ASSERT_EQUAL(String("Foo"), h.parse(ByteVector("Foo "))); + ScopedFileCopy copy("xing", ".mp3"); + string newname = copy.fileName(); + + { + MPEG::File f(newname.c_str()); + f.ID3v1Tag(true)->setArtist("Artist "); + f.save(); + } + + { + MPEG::File f(newname.c_str()); + CPPUNIT_ASSERT(f.ID3v1Tag(false)); + CPPUNIT_ASSERT_EQUAL(String("Artist"), f.ID3v1Tag(false)->artist()); + } } }; diff --git a/tests/test_info.cpp b/tests/test_info.cpp index f76fd67a..8e0d7154 100644 --- a/tests/test_info.cpp +++ b/tests/test_info.cpp @@ -1,9 +1,7 @@ -#include #include #include #include -#include -#include +#include #include "utils.h" using namespace std; @@ -23,7 +21,13 @@ public: CPPUNIT_ASSERT_EQUAL(String(""), tag.title()); tag.setTitle("Test title 1"); + tag.setFieldText("TEST", "Dummy Text"); + CPPUNIT_ASSERT_EQUAL(String("Test title 1"), tag.title()); + + RIFF::Info::FieldListMap map = tag.fieldListMap(); + CPPUNIT_ASSERT_EQUAL(String("Test title 1"), map["INAM"]); + CPPUNIT_ASSERT_EQUAL(String("Dummy Text"), map["TEST"]); } void testNumericFields() diff --git a/tests/test_mp4.cpp b/tests/test_mp4.cpp index d7ea4a32..e38c4a6b 100644 --- a/tests/test_mp4.cpp +++ b/tests/test_mp4.cpp @@ -39,6 +39,7 @@ public: CPPUNIT_ASSERT_EQUAL(2, f.audioProperties()->channels()); CPPUNIT_ASSERT_EQUAL(44100, f.audioProperties()->sampleRate()); CPPUNIT_ASSERT_EQUAL(16, ((MP4::AudioProperties *)f.audioProperties())->bitsPerSample()); + CPPUNIT_ASSERT_EQUAL(MP4::AudioProperties::AAC, ((MP4::AudioProperties *)f.audioProperties())->codec()); } void testPropertiesALAC() @@ -49,6 +50,7 @@ public: CPPUNIT_ASSERT_EQUAL(2, f.audioProperties()->channels()); CPPUNIT_ASSERT_EQUAL(44100, f.audioProperties()->sampleRate()); CPPUNIT_ASSERT_EQUAL(16, ((MP4::AudioProperties *)f.audioProperties())->bitsPerSample()); + CPPUNIT_ASSERT_EQUAL(MP4::AudioProperties::ALAC, ((MP4::AudioProperties *)f.audioProperties())->codec()); } void testCheckValid() diff --git a/tests/test_string.cpp b/tests/test_string.cpp index a9458055..10dbbcd0 100644 --- a/tests/test_string.cpp +++ b/tests/test_string.cpp @@ -51,6 +51,18 @@ public: void testString() { + // Needs to know the system byte order for some Unicode tests. + bool littleEndian; + { + union { + int i; + char c; + } u; + + u.i = 1; + littleEndian = (u.c == 1) ? true : false; + } + String s = "taglib string"; ByteVector v = "taglib string"; CPPUNIT_ASSERT(v == s.data(String::Latin1)); @@ -74,8 +86,28 @@ public: String unicode2(unicode.to8Bit(true), String::UTF8); CPPUNIT_ASSERT(unicode == unicode2); - String unicode3(L"\u65E5\u672C\u8A9E"); - CPPUNIT_ASSERT(*(unicode3.toCWString() + 1) == L'\u672C'); + String unicode3(L"\u65E5\u672C\u8A9E"); + CPPUNIT_ASSERT(*(unicode3.toCWString() + 1) == L'\u672C'); + + String unicode4(L"\u65e5\u672c\u8a9e"); + CPPUNIT_ASSERT(unicode4[1] == L'\u672c'); + + String unicode5(L"\u65e5\u672c\u8a9e", String::UTF16BE); + CPPUNIT_ASSERT(unicode5[1] == (littleEndian ? L'\u2c67' : L'\u672c')); + + String unicode6(L"\u65e5\u672c\u8a9e", String::UTF16LE); + CPPUNIT_ASSERT(unicode6[1] == (littleEndian ? L'\u672c' : L'\u2c67')); + + wstring stduni = L"\u65e5\u672c\u8a9e"; + + String unicode7(stduni); + CPPUNIT_ASSERT(unicode7[1] == L'\u672c'); + + String unicode8(stduni, String::UTF16BE); + CPPUNIT_ASSERT(unicode8[1] == (littleEndian ? L'\u2c67' : L'\u672c')); + + String unicode9(stduni, String::UTF16LE); + CPPUNIT_ASSERT(unicode9[1] == (littleEndian ? L'\u672c' : L'\u2c67')); CPPUNIT_ASSERT(strcmp(String::number(0).toCString(), "0") == 0); CPPUNIT_ASSERT(strcmp(String::number(12345678).toCString(), "12345678") == 0);