diff --git a/INSTALL b/INSTALL index 9e6e8075..5e36d30c 100644 --- a/INSTALL +++ b/INSTALL @@ -5,7 +5,7 @@ TagLib uses the CMake build system. As a user, you will most likely want to build TagLib in release mode and install it into a system-wide location. This can be done using the following commands: - cmake -DCMAKE_INSTALL_PREFIX=/usr/local -DCMAKE_RELEASE_TYPE=Release . + cmake -DCMAKE_INSTALL_PREFIX=/usr/local -DCMAKE_BUILD_TYPE=Release . make sudo make install diff --git a/bindings/c/CMakeLists.txt b/bindings/c/CMakeLists.txt index 2d9dafc4..387f1bd1 100644 --- a/bindings/c/CMakeLists.txt +++ b/bindings/c/CMakeLists.txt @@ -61,7 +61,7 @@ install(TARGETS tag_c PUBLIC_HEADER DESTINATION ${INCLUDE_INSTALL_DIR}/taglib ) -if(NOT WIN32 AND NOT BUILD_FRAMEWORK) +if(NOT BUILD_FRAMEWORK) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/taglib_c.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/taglib_c.pc) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/taglib_c.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig) endif() diff --git a/taglib-config.cmd.cmake b/taglib-config.cmd.cmake index bef752ed..3e2b1cde 100644 --- a/taglib-config.cmd.cmake +++ b/taglib-config.cmd.cmake @@ -1,36 +1,36 @@ -@echo off -goto beginning - * - * It is what it is, you can do with it as you please. - * - * Just don't blame me if it teaches your computer to smoke! - * - * -Enjoy - * fh :)_~ - * -:beginning -if /i "%1#" == "--libs#" goto doit -if /i "%1#" == "--cflags#" goto doit -if /i "%1#" == "--version#" goto doit -if /i "%1#" == "--prefix#" goto doit - -echo "usage: %0 [OPTIONS]" -echo [--libs] -echo [--cflags] -echo [--version] -echo [--prefix] -goto theend - - * - * NOTE: Windows does not assume libraries are prefixed with 'lib'. - * NOTE: If '-llibtag' is the last element, it is easily appended in the users installation/makefile process - * to allow for static, shared or debug builds. - * It would be preferable if the top level CMakeLists.txt provided the library name during config. ?? -:doit -if /i "%1#" == "--libs#" echo -L${LIB_INSTALL_DIR} -llibtag -if /i "%1#" == "--cflags#" echo -I${INCLUDE_INSTALL_DIR}/taglib -if /i "%1#" == "--version#" echo ${TAGLIB_LIB_MAJOR_VERSION}.${TAGLIB_LIB_MINOR_VERSION}.${TAGLIB_LIB_PATCH_VERSION} -if /i "%1#" == "--prefix#" echo ${CMAKE_INSTALL_PREFIX} - -:theend - +@echo off +goto beginning + * + * It is what it is, you can do with it as you please. + * + * Just don't blame me if it teaches your computer to smoke! + * + * -Enjoy + * fh :)_~ + * +:beginning +if /i "%1#" == "--libs#" goto doit +if /i "%1#" == "--cflags#" goto doit +if /i "%1#" == "--version#" goto doit +if /i "%1#" == "--prefix#" goto doit + +echo "usage: %0 [OPTIONS]" +echo [--libs] +echo [--cflags] +echo [--version] +echo [--prefix] +goto theend + + * + * NOTE: Windows does not assume libraries are prefixed with 'lib'. + * NOTE: If '-llibtag' is the last element, it is easily appended in the users installation/makefile process + * to allow for static, shared or debug builds. + * It would be preferable if the top level CMakeLists.txt provided the library name during config. ?? +:doit +if /i "%1#" == "--libs#" echo -L${LIB_INSTALL_DIR} -llibtag +if /i "%1#" == "--cflags#" echo -I${INCLUDE_INSTALL_DIR}/taglib +if /i "%1#" == "--version#" echo ${TAGLIB_LIB_MAJOR_VERSION}.${TAGLIB_LIB_MINOR_VERSION}.${TAGLIB_LIB_PATCH_VERSION} +if /i "%1#" == "--prefix#" echo ${CMAKE_INSTALL_PREFIX} + +:theend + diff --git a/taglib/mpeg/id3v2/frames/textidentificationframe.h b/taglib/mpeg/id3v2/frames/textidentificationframe.h index 58ed63e6..e49aa897 100644 --- a/taglib/mpeg/id3v2/frames/textidentificationframe.h +++ b/taglib/mpeg/id3v2/frames/textidentificationframe.h @@ -234,7 +234,7 @@ namespace TagLib { * This description identifies the frame and must be unique. */ - //! An ID3v2 custom text identification frame implementationx + //! An ID3v2 custom text identification frame implementation class TAGLIB_EXPORT UserTextIdentificationFrame : public TextIdentificationFrame { diff --git a/taglib/riff/wav/infotag.cpp b/taglib/riff/wav/infotag.cpp index 9857f489..eea4403a 100644 --- a/taglib/riff/wav/infotag.cpp +++ b/taglib/riff/wav/infotag.cpp @@ -35,7 +35,7 @@ using namespace RIFF::Info; class RIFF::Info::Tag::TagPrivate { public: - TagPrivate() + TagPrivate() {} FieldListMap fieldListMap; @@ -72,14 +72,14 @@ ByteVector RIFF::Info::StringHandler::render(const String &s) const // public members //////////////////////////////////////////////////////////////////////////////// -RIFF::Info::Tag::Tag(const ByteVector &data) +RIFF::Info::Tag::Tag(const ByteVector &data) : TagLib::Tag() , d(new TagPrivate()) { parse(data); } -RIFF::Info::Tag::Tag() +RIFF::Info::Tag::Tag() : TagLib::Tag() , d(new TagPrivate()) { @@ -215,7 +215,7 @@ ByteVector RIFF::Info::Tag::render() const data.append(it->first); data.append(ByteVector::fromUInt32LE(text.size() + 1)); data.append(text); - + do { data.append('\0'); } while(data.size() & 1); diff --git a/taglib/toolkit/tstring.cpp b/taglib/toolkit/tstring.cpp index 03c350cd..daf9c0eb 100644 --- a/taglib/toolkit/tstring.cpp +++ b/taglib/toolkit/tstring.cpp @@ -141,13 +141,13 @@ namespace debug("String::copyFromUTF8() - Unicode conversion error."); } -#endif +#endif } } namespace TagLib { -class String::StringPrivate +class String::StringPrivate { public: StringPrivate() @@ -155,13 +155,13 @@ public: { } - StringPrivate(size_t n, wchar_t c) - : data(new std::wstring(n, c)) + StringPrivate(size_t n, wchar_t c) + : data(new std::wstring(n, c)) { } /*! - * Stores string in UTF-16. The byte order depends on the CPU endian. + * Stores string in UTF-16. The byte order depends on the CPU endian. */ SHARED_PTR data; @@ -178,12 +178,12 @@ const size_t String::npos = std::wstring::npos; //////////////////////////////////////////////////////////////////////////////// -String::String() +String::String() : d(new StringPrivate()) { } -String::String(const String &s) +String::String(const String &s) : d(new StringPrivate(*s.d)) { } @@ -192,9 +192,9 @@ String::String(const std::string &s, Type t) : d(new StringPrivate()) { if(t == Latin1) - copyFromLatin1(&s[0], s.length()); + copyFromLatin1(s.c_str(), s.length()); else if(t == String::UTF8) - copyFromUTF8(&s[0], s.length()); + copyFromUTF8(s.c_str(), s.length()); else { debug("String::String() -- A std::string should not contain UTF16."); } @@ -256,11 +256,11 @@ String::String(const ByteVector &v, Type t) if(v.isEmpty()) return; - if(t == Latin1) + if(t == Latin1) copyFromLatin1(v.data(), v.size()); - else if(t == UTF8) + else if(t == UTF8) copyFromUTF8(v.data(), v.size()); - else + else copyFromUTF16(v.data(), v.size(), t); // If we hit a null in the ByteVector, shrink the string again. @@ -276,25 +276,8 @@ String::~String() std::string String::to8Bit(bool unicode) const { - std::string s; - - if(!unicode) { - s.resize(d->data->size()); - - std::string::iterator targetIt = s.begin(); - for(std::wstring::const_iterator it = d->data->begin(); it != d->data->end(); it++) { - *targetIt = static_cast(*it); - ++targetIt; - } - } - else { - s.resize(d->data->size() * 4 + 1); - - UTF16toUTF8(&(*d->data)[0], d->data->size(), &s[0], s.size()); - s.resize(::strlen(s.c_str())); - } - - return s; + const ByteVector v = data(unicode ? UTF8 : Latin1); + return std::string(v.data(), v.size()); } const std::wstring &String::toWString() const @@ -418,74 +401,78 @@ bool String::isNull() const ByteVector String::data(Type t) const { - switch(t) + switch(t) { case Latin1: - { - ByteVector v(size(), 0); - char *p = v.data(); + { + ByteVector v(size(), 0); + char *p = v.data(); - for(std::wstring::const_iterator it = d->data->begin(); it != d->data->end(); it++) - *p++ = static_cast(*it); + for(std::wstring::const_iterator it = d->data->begin(); it != d->data->end(); it++) + *p++ = static_cast(*it); - return v; - } + return v; + } case UTF8: - { - ByteVector v(size() * 4 + 1, 0); + if(!d->data->empty()) + { + ByteVector v(size() * 4 + 1, 0); - UTF16toUTF8(&(*d->data)[0], d->data->size(), v.data(), v.size()); - v.resize(::strlen(v.data())); + UTF16toUTF8(d->data->c_str(), d->data->size(), v.data(), v.size()); + v.resize(::strlen(v.data())); - return v; - } + return v; + } + else { + return ByteVector::null; + } case UTF16: - { - ByteVector v(2 + size() * 2, 0); - char *p = v.data(); + { + ByteVector v(2 + size() * 2, 0); + char *p = v.data(); - // Assume that if we're doing UTF16 and not UTF16BE that we want little - // endian encoding. (Byte Order Mark) + // Assume that if we're doing UTF16 and not UTF16BE that we want little + // endian encoding. (Byte Order Mark) - *p++ = '\xff'; - *p++ = '\xfe'; + *p++ = '\xff'; + *p++ = '\xfe'; - for(std::wstring::const_iterator it = d->data->begin(); it != d->data->end(); it++) { - *p++ = static_cast(*it & 0xff); - *p++ = static_cast(*it >> 8); + for(std::wstring::const_iterator it = d->data->begin(); it != d->data->end(); it++) { + *p++ = static_cast(*it & 0xff); + *p++ = static_cast(*it >> 8); + } + + return v; } - - return v; - } case UTF16BE: - { - ByteVector v(size() * 2, 0); - char *p = v.data(); + { + ByteVector v(size() * 2, 0); + char *p = v.data(); - for(std::wstring::const_iterator it = d->data->begin(); it != d->data->end(); it++) { - *p++ = static_cast(*it >> 8); - *p++ = static_cast(*it & 0xff); + for(std::wstring::const_iterator it = d->data->begin(); it != d->data->end(); it++) { + *p++ = static_cast(*it >> 8); + *p++ = static_cast(*it & 0xff); + } + + return v; } - - return v; - } case UTF16LE: - { - ByteVector v(size() * 2, 0); - char *p = v.data(); + { + ByteVector v(size() * 2, 0); + char *p = v.data(); - for(std::wstring::const_iterator it = d->data->begin(); it != d->data->end(); it++) { - *p++ = static_cast(*it & 0xff); - *p++ = static_cast(*it >> 8); + for(std::wstring::const_iterator it = d->data->begin(); it != d->data->end(); it++) { + *p++ = static_cast(*it & 0xff); + *p++ = static_cast(*it >> 8); + } + + return v; } - - return v; - } default: - { - debug("String::data() - Invalid Type value."); - return ByteVector(); - } + { + debug("String::data() - Invalid Type value."); + return ByteVector::null; + } } } @@ -717,17 +704,19 @@ void String::copyFromUTF8(const char *s, size_t length) { d->data->resize(length); - UTF8toUTF16(s, length, &(*d->data)[0], d->data->size()); - d->data->resize(::wcslen(d->data->c_str())); + if(length > 0) { + UTF8toUTF16(s, length, &(*d->data)[0], d->data->size()); + d->data->resize(::wcslen(d->data->c_str())); + } } void String::copyFromUTF16(const wchar_t *s, size_t length, Type t) { bool swap; if(t == UTF16) { - if(length >= 1 && s[0] == 0xfeff) + if(length >= 1 && s[0] == 0xfeff) swap = false; // Same as CPU endian. No need to swap bytes. - else if(length >= 1 && s[0] == 0xfffe) + else if(length >= 1 && s[0] == 0xfffe) swap = true; // Not same as CPU endian. Need to swap bytes. else { debug("String::copyFromUTF16() - Invalid UTF16 string."); @@ -737,15 +726,18 @@ void String::copyFromUTF16(const wchar_t *s, size_t length, Type t) s++; length--; } - else + else swap = (t != WCharByteOrder); d->data->resize(length); - memcpy(&(*d->data)[0], s, length * sizeof(wchar_t)); - - if(swap) { - for(size_t i = 0; i < length; ++i) - (*d->data)[i] = Utils::byteSwap(static_cast(s[i])); + if(length > 0) { + if(swap) { + for(size_t i = 0; i < length; ++i) + (*d->data)[i] = Utils::byteSwap(static_cast(s[i])); + } + else { + ::memcpy(&(*d->data)[0], s, length * sizeof(wchar_t)); + } } } @@ -762,9 +754,9 @@ void String::copyFromUTF16(const char *s, size_t length, Type t) ushort bom; ::memcpy(&bom, s, 2); - if(bom == 0xfeff) + if(bom == 0xfeff) swap = false; // Same as CPU endian. No need to swap bytes. - else if(bom == 0xfffe) + else if(bom == 0xfffe) swap = true; // Not same as CPU endian. Need to swap bytes. else { debug("String::copyFromUTF16() - Invalid UTF16 string."); @@ -774,7 +766,7 @@ void String::copyFromUTF16(const char *s, size_t length, Type t) s += 2; length -= 2; } - else + else swap = (t != WCharByteOrder); d->data->resize(length / 2); @@ -784,7 +776,7 @@ void String::copyFromUTF16(const char *s, size_t length, Type t) } } -const String::Type String::WCharByteOrder +const String::Type String::WCharByteOrder = (Utils::SystemByteOrder == BigEndian) ? String::UTF16BE : String::UTF16LE; //////////////////////////////////////////////////////////////////////////////// diff --git a/taglib/toolkit/tstring.h b/taglib/toolkit/tstring.h index 23714d45..065323b1 100644 --- a/taglib/toolkit/tstring.h +++ b/taglib/toolkit/tstring.h @@ -94,7 +94,7 @@ namespace TagLib { */ UTF16 = 1, /*! - * UTF16 big endian. 16 bit characters. + * UTF16 big endian. 16 bit characters. */ UTF16BE = 2, /*! @@ -130,20 +130,20 @@ namespace TagLib { /*! * Makes a deep copy of the data in \a s. * - * \note This should only be used with the 16-bit codecs UTF16, UTF16BE or - * UTF16LE, when used with other codecs it will simply print a warning and - * exit. UTF16BE or UTF16LE is automatically chosen as default according - * to the CPU byte order + * \note This should only be used with the 16-bit codecs UTF16, UTF16BE or + * UTF16LE, when used with other codecs it will simply print a warning and + * exit. UTF16BE or UTF16LE is automatically chosen as default according + * to the CPU byte order */ String(const std::wstring &s, Type t = WCharByteOrder); /*! * Makes a deep copy of the data in \a s. * - * \note This should only be used with the 16-bit codecs UTF16, UTF16BE or - * UTF16LE, when used with other codecs it will simply print a warning and - * exit. UTF16BE or UTF16LE is automatically chosen as default according - * to the CPU byte order + * \note This should only be used with the 16-bit codecs UTF16, UTF16BE or + * UTF16LE, when used with other codecs it will simply print a warning and + * exit. UTF16BE or UTF16LE is automatically chosen as default according + * to the CPU byte order */ String(const wchar_t *s, Type t = WCharByteOrder); @@ -158,10 +158,10 @@ namespace TagLib { /*! * Makes a deep copy of the data in \a c. * - * \note This should only be used with the 16-bit codecs UTF16, UTF16BE or - * UTF16LE, when used with other codecs it will simply print a warning and - * exit. UTF16BE or UTF16LE is automatically chosen as default according - * to the CPU byte order + * \note This should only be used with the 16-bit codecs UTF16, UTF16BE or + * UTF16LE, when used with other codecs it will simply print a warning and + * exit. UTF16BE or UTF16LE is automatically chosen as default according + * to the CPU byte order */ String(wchar_t c, Type t = WCharByteOrder); @@ -185,7 +185,7 @@ namespace TagLib { virtual ~String(); /*! - * Returns a deep copy of this String as an std::string. The returned string + * Returns a deep copy of this String as an std::string. The returned string * is encoded in UTF8 if \a unicode is true, otherwise Latin1. * * \see toCString() @@ -193,7 +193,7 @@ namespace TagLib { std::string to8Bit(bool unicode = false) const; /*! - * Returns a deep copy of this String as a wstring. The returned string is + * Returns a deep copy of this String as a wstring. The returned string is * encoded in UTF-16 (without BOM/CPU byte order). * * \see toCWString() @@ -201,43 +201,43 @@ namespace TagLib { const std::wstring &toWString() const; /*! - * Creates and returns a standard C-style (null-terminated) version of this - * String. The returned string is encoded in UTF8 if \a unicode is true, + * Creates and returns a standard C-style (null-terminated) version of this + * String. The returned string is encoded in UTF8 if \a unicode is true, * otherwise Latin1. - * - * The returned string is still owned by this String and should not be deleted + * + * The returned string is still owned by this String and should not be deleted * by the user. * - * The returned pointer remains valid until this String instance is destroyed + * The returned pointer remains valid until this String instance is destroyed * or toCString() is called again. * * \warning This however has the side effect that the returned string will remain - * in memory in addition to other memory that is consumed by this + * in memory in addition to other memory that is consumed by this * String instance. So, this method should not be used on large strings or * where memory is critical. Consider using to8Bit() instead to avoid it. * * \see to8Bit() */ const char *toCString(bool unicode = false) const; - + /*! - * Returns a standard C-style (null-terminated) wide character version of - * this String. The returned string is encoded in UTF-16 (without BOM/CPU byte + * Returns a standard C-style (null-terminated) wide character version of + * this String. The returned string is encoded in UTF-16 (without BOM/CPU byte * order). - * - * The returned string is still owned by this String and should not be deleted + * + * The returned string is still owned by this String and should not be deleted * by the user. * - * The returned pointer remains valid until this String instance is destroyed + * 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() */ const wchar_t *toCWString() const; - + /*! * Returns an iterator pointing to the beginning of the string. */ @@ -332,6 +332,8 @@ namespace TagLib { * Returns a ByteVector containing the string's data. If \a t is Latin1 or * UTF8, this will return a vector of 8 bit characters, otherwise it will use * 16 bit characters. + * + * \note The returned data is not null terminated. */ ByteVector data(Type t) const; @@ -477,7 +479,7 @@ namespace TagLib { static const String null; /*! - * When used as the value for a \a length parameter in String's member + * When used as the value for a \a length parameter in String's member * functions, means "until the end of the string". * As a return value, it is usually used to indicate no matches. */ @@ -493,31 +495,31 @@ namespace TagLib { private: /*! - * Converts a \e Latin-1 string into \e UTF-16(without BOM/CPU byte order) + * Converts a \e Latin-1 string into \e UTF-16(without BOM/CPU byte order) * and copies it to the internal buffer. */ void copyFromLatin1(const char *s, size_t length); /*! - * Converts a \e UTF-8 string into \e UTF-16(without BOM/CPU byte order) + * Converts a \e UTF-8 string into \e UTF-16(without BOM/CPU byte order) * and copies it to the internal buffer. */ void copyFromUTF8(const char *s, size_t length); /*! - * Converts a \e UTF-16 (with BOM), UTF-16LE or UTF16-BE string into + * Converts a \e UTF-16 (with BOM), UTF-16LE or UTF16-BE string into * \e UTF-16(without BOM/CPU byte order) and copies it to the internal buffer. */ void copyFromUTF16(const wchar_t *s, size_t length, Type t); /*! - * Converts a \e UTF-16 (with BOM), UTF-16LE or UTF16-BE string into + * Converts a \e UTF-16 (with BOM), UTF-16LE or UTF16-BE string into * \e UTF-16(without BOM/CPU byte order) and copies it to the internal buffer. */ void copyFromUTF16(const char *s, size_t length, Type t); /*! - * Indicates which byte order of UTF-16 is used to store strings internally. + * Indicates which byte order of UTF-16 is used to store strings internally. * * \note \e String::UTF16BE or \e String::UTF16LE */ diff --git a/taglib/xm/xmfile.cpp b/taglib/xm/xmfile.cpp index f2493b9d..18b01bf3 100644 --- a/taglib/xm/xmfile.cpp +++ b/taglib/xm/xmfile.cpp @@ -406,97 +406,90 @@ bool XM::File::save() debug("XM::File::save() - Cannot save to a read only file."); return false; } + seek(17); writeString(d->tag.title(), 20); - seek(1, Current); + + seek(38); writeString(d->tag.trackerName(), 20); - seek(2, Current); + + seek(60); uint headerSize = 0; if(!readU32L(headerSize)) return false; - seek(2+2+2, Current); + seek(70); ushort patternCount = 0; ushort instrumentCount = 0; if(!readU16L(patternCount) || !readU16L(instrumentCount)) return false; - seek(60 + headerSize); + long pos = 60 + headerSize; // should be offset_t in taglib2. // need to read patterns again in order to seek to the instruments: for(ushort i = 0; i < patternCount; ++ i) { + seek(pos); uint patternHeaderLength = 0; if(!readU32L(patternHeaderLength) || patternHeaderLength < 4) return false; + seek(pos + 7); ushort dataSize = 0; - StructReader pattern; - pattern.skip(3).u16L(dataSize); - - uint count = pattern.read(*this, patternHeaderLength - 4U); - if(count != std::min(patternHeaderLength - 4U, pattern.size())) + if (!readU16L(dataSize)) return false; - seek(patternHeaderLength - (4 + count) + dataSize, Current); + pos += patternHeaderLength + dataSize; } - StringList lines = d->tag.comment().split("\n"); + const StringList lines = d->tag.comment().split("\n"); uint sampleNameIndex = instrumentCount; for(ushort i = 0; i < instrumentCount; ++ i) { + seek(pos); uint instrumentHeaderSize = 0; if(!readU32L(instrumentHeaderSize) || instrumentHeaderSize < 4) return false; - uint len = std::min(22U, instrumentHeaderSize - 4U); + seek(pos + 4); + const uint len = std::min(22U, instrumentHeaderSize - 4U); if(i >= lines.size()) writeString(String::null, len); else writeString(lines[i], len); - long offset = 0; + ushort sampleCount = 0; if(instrumentHeaderSize >= 29U) { - ushort sampleCount = 0; - seek(1, Current); + seek(pos + 27); if(!readU16L(sampleCount)) return false; + } - if(sampleCount > 0) { - uint sampleHeaderSize = 0; - if(instrumentHeaderSize < 33U || !readU32L(sampleHeaderSize)) + uint sampleHeaderSize = 0; + if(sampleCount > 0) { + seek(pos + 29); + if(instrumentHeaderSize < 33U || !readU32L(sampleHeaderSize)) + return false; + } + + pos += instrumentHeaderSize; + + for(ushort j = 0; j < sampleCount; ++ j) { + if(sampleHeaderSize > 4U) { + seek(pos); + uint sampleLength = 0; + if(!readU32L(sampleLength)) return false; - // skip unhandeled header proportion: - seek(instrumentHeaderSize - 33, Current); - for(ushort j = 0; j < sampleCount; ++ j) { - if(sampleHeaderSize > 4U) { - uint sampleLength = 0; - if(!readU32L(sampleLength)) - return false; - offset += sampleLength; - - seek(std::min(sampleHeaderSize, 14U), Current); - if(sampleHeaderSize > 18U) { - uint len = std::min(sampleHeaderSize - 18U, 22U); - if(sampleNameIndex >= lines.size()) - writeString(String::null, len); - else - writeString(lines[sampleNameIndex ++], len); - seek(sampleHeaderSize - (18U + len), Current); - } - } - else { - seek(sampleHeaderSize, Current); - } + if(sampleHeaderSize > 18U) { + seek(pos + 18); + const uint len = std::min(sampleHeaderSize - 18U, 22U); + if(sampleNameIndex >= lines.size()) + writeString(String::null, len); + else + writeString(lines[sampleNameIndex ++], len); } } - else { - offset = instrumentHeaderSize - 29; - } + pos += sampleHeaderSize; } - else { - offset = instrumentHeaderSize - (4 + len); - } - seek(offset, Current); } return true; diff --git a/tests/test_string.cpp b/tests/test_string.cpp index 10dbbcd0..0863d3ce 100644 --- a/tests/test_string.cpp +++ b/tests/test_string.cpp @@ -45,6 +45,7 @@ class TestString : public CppUnit::TestFixture CPPUNIT_TEST(testSubstr); CPPUNIT_TEST(testNewline); CPPUNIT_TEST(testUpper); + CPPUNIT_TEST(testEncode); CPPUNIT_TEST_SUITE_END(); public: @@ -200,10 +201,10 @@ public: String a("abc"); String b = a; String c = a; - + b += 'd'; c += L'd'; - + CPPUNIT_ASSERT_EQUAL(String("abc"), a); CPPUNIT_ASSERT_EQUAL(String("abcd"), b); CPPUNIT_ASSERT_EQUAL(String("abcd"), c); @@ -277,7 +278,7 @@ public: CPPUNIT_ASSERT_EQUAL(L'\x0d', String(crlf)[3]); CPPUNIT_ASSERT_EQUAL(L'\x0a', String(crlf)[4]); } - + void testUpper() { String s1 = "tagLIB 012 strING"; @@ -286,6 +287,43 @@ public: CPPUNIT_ASSERT_EQUAL(String("TAGLIB 012 STRING"), s2); } + void testEncode() + { + String jpn(L"\u65E5\u672C\u8A9E"); + ByteVector jpn1 = jpn.data(String::Latin1); + ByteVector jpn2 = jpn.data(String::UTF8); + ByteVector jpn3 = jpn.data(String::UTF16); + ByteVector jpn4 = jpn.data(String::UTF16LE); + ByteVector jpn5 = jpn.data(String::UTF16BE); + std::string jpn6 = jpn.to8Bit(false); + std::string jpn7 = jpn.to8Bit(true); + + CPPUNIT_ASSERT_EQUAL(ByteVector("\xE5\x2C\x9E"), jpn1); + CPPUNIT_ASSERT_EQUAL(ByteVector("\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E"), jpn2); + CPPUNIT_ASSERT_EQUAL(ByteVector("\xFF\xFE\xE5\x65\x2C\x67\x9E\x8A"), jpn3); + CPPUNIT_ASSERT_EQUAL(ByteVector("\xE5\x65\x2C\x67\x9E\x8A"), jpn4); + CPPUNIT_ASSERT_EQUAL(ByteVector("\x65\xE5\x67\x2C\x8A\x9E"), jpn5); + CPPUNIT_ASSERT_EQUAL(std::string("\xE5\x2C\x9E"), jpn6); + CPPUNIT_ASSERT_EQUAL(std::string("\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E"), jpn7); + + String empty; + ByteVector empty1 = empty.data(String::Latin1); + ByteVector empty2 = empty.data(String::UTF8); + ByteVector empty3 = empty.data(String::UTF16); + ByteVector empty4 = empty.data(String::UTF16LE); + ByteVector empty5 = empty.data(String::UTF16BE); + std::string empty6 = empty.to8Bit(false); + std::string empty7 = empty.to8Bit(true); + + CPPUNIT_ASSERT(empty1.isEmpty()); + CPPUNIT_ASSERT(empty2.isEmpty()); + CPPUNIT_ASSERT_EQUAL(ByteVector("\xFF\xFE"), empty3); + CPPUNIT_ASSERT(empty4.isEmpty()); + CPPUNIT_ASSERT(empty5.isEmpty()); + CPPUNIT_ASSERT(empty6.empty()); + CPPUNIT_ASSERT(empty7.empty()); + } + }; CPPUNIT_TEST_SUITE_REGISTRATION(TestString);