diff --git a/taglib/toolkit/tstring.cpp b/taglib/toolkit/tstring.cpp index c4a628a6..cca15e10 100644 --- a/taglib/toolkit/tstring.cpp +++ b/taglib/toolkit/tstring.cpp @@ -38,11 +38,10 @@ namespace using namespace TagLib; // Returns the native format of std::wstring. - String::Type wcharByteOrder() + constexpr String::Type wcharByteOrder() { - if(Utils::systemByteOrder() == Utils::LittleEndian) - return String::UTF16LE; - return String::UTF16BE; + return Utils::systemByteOrder() == Utils::LittleEndian ? String::UTF16LE + : String::UTF16BE; } // Converts a Latin-1 string into UTF-16(without BOM/CPU byte order) @@ -172,17 +171,15 @@ String::String(const std::string &s, Type t) : } } +String::String(const wstring &s) : + String(s, wcharByteOrder()) +{ +} + String::String(const wstring &s, Type t) : d(std::make_shared()) { if(t == UTF16 || t == UTF16BE || t == UTF16LE) { - // This looks ugly but needed for the compatibility with TagLib1.8. - // Should be removed in TabLib2.0. - if (t == UTF16BE) - t = wcharByteOrder(); - else if (t == UTF16LE) - t = (wcharByteOrder() == UTF16LE ? UTF16BE : UTF16LE); - copyFromUTF16(d->data, s.c_str(), s.length(), t); } else { @@ -190,17 +187,15 @@ String::String(const wstring &s, Type t) : } } +String::String(const wchar_t *s) : + String(s, wcharByteOrder()) +{ +} + String::String(const wchar_t *s, Type t) : d(std::make_shared()) { if(t == UTF16 || t == UTF16BE || t == UTF16LE) { - // This looks ugly but needed for the compatibility with TagLib1.8. - // Should be removed in TabLib2.0. - if (t == UTF16BE) - t = wcharByteOrder(); - else if (t == UTF16LE) - t = (wcharByteOrder() == UTF16LE ? UTF16BE : UTF16LE); - copyFromUTF16(d->data, s, ::wcslen(s), t); } else { diff --git a/taglib/toolkit/tstring.h b/taglib/toolkit/tstring.h index 4d055428..78abe3ec 100644 --- a/taglib/toolkit/tstring.h +++ b/taglib/toolkit/tstring.h @@ -139,22 +139,24 @@ namespace TagLib { String(const std::string &s, Type t = Latin1); /*! - * Makes a deep copy of the data in \a s. - * - * /note If \a t is UTF16LE, the byte order of \a s will be swapped regardless - * of the CPU byte order. If UTF16BE, it will not be swapped. This behavior - * will be changed in TagLib2.0. + * Makes a deep copy of the data in \a s, which are in CPU byte order. */ - String(const wstring &s, Type t = UTF16BE); + String(const wstring &s); /*! - * Makes a deep copy of the data in \a s. - * - * /note If \a t is UTF16LE, the byte order of \a s will be swapped regardless - * of the CPU byte order. If UTF16BE, it will not be swapped. This behavior - * will be changed in TagLib2.0. + * Makes a deep copy of the data in \a s, which are in byte order \a t. */ - String(const wchar_t *s, Type t = UTF16BE); + String(const wstring &s, Type t); + + /*! + * Makes a deep copy of the data in \a s, which are in CPU byte order. + */ + String(const wchar_t *s); + + /*! + * Makes a deep copy of the data in \a s, which are in byte order \a t. + */ + String(const wchar_t *s, Type t); /*! * Makes a deep copy of the data in \a c. diff --git a/taglib/toolkit/tutils.h b/taglib/toolkit/tutils.h index 121c24f6..ee60d386 100644 --- a/taglib/toolkit/tutils.h +++ b/taglib/toolkit/tutils.h @@ -203,14 +203,14 @@ namespace TagLib /*! * Returns the byte order of the system. */ - inline ByteOrder systemByteOrder() + constexpr ByteOrder systemByteOrder() { - union { + constexpr union IntCharUnion { int i; char c; - } u; + constexpr IntCharUnion(int j) : i(j) {} + } u{1}; - u.i = 1; if(u.c == 1) return LittleEndian; return BigEndian; diff --git a/tests/test_string.cpp b/tests/test_string.cpp index 8689c819..a03772f1 100644 --- a/tests/test_string.cpp +++ b/tests/test_string.cpp @@ -26,6 +26,7 @@ #include #include "tstring.h" +#include "tutils.h" #include using namespace std; @@ -96,19 +97,23 @@ public: String unicode3(L"\u65E5\u672C\u8A9E"); CPPUNIT_ASSERT(*(unicode3.toCWString() + 1) == L'\u672C'); - String unicode4(L"\u65e5\u672c\u8a9e", String::UTF16BE); + const wchar_t wcSystemOrder[] = {L'\u65E5', L'\u672C', L'\u8A9E', 0}; + const wchar_t wcSwappedOrder[] = {L'\uE565', L'\u2C67', L'\u9E8A', 0}; + const std::wstring wsSystemOrder = L"\u65e5\u672c\u8a9e"; + const std::wstring wsSwappedOrder = L"\ue565\u2c67\u9e8a"; + const bool isLe = Utils::systemByteOrder() == Utils::LittleEndian; + + String unicode4(isLe ? wcSwappedOrder : wcSystemOrder, String::UTF16BE); CPPUNIT_ASSERT(unicode4[1] == L'\u672c'); - String unicode5(L"\u65e5\u672c\u8a9e", String::UTF16LE); - CPPUNIT_ASSERT(unicode5[1] == L'\u2c67'); + String unicode5(isLe ? wcSystemOrder : wcSwappedOrder, String::UTF16LE); + CPPUNIT_ASSERT(unicode5[1] == L'\u672c'); - std::wstring stduni = L"\u65e5\u672c\u8a9e"; - - String unicode6(stduni, String::UTF16BE); + String unicode6(isLe ? wsSwappedOrder : wsSystemOrder, String::UTF16BE); CPPUNIT_ASSERT(unicode6[1] == L'\u672c'); - String unicode7(stduni, String::UTF16LE); - CPPUNIT_ASSERT(unicode7[1] == L'\u2c67'); + String unicode7(isLe ? wsSystemOrder : wsSwappedOrder, String::UTF16LE); + CPPUNIT_ASSERT(unicode7[1] == L'\u672c'); CPPUNIT_ASSERT(String(" foo ").stripWhiteSpace() == String("foo")); CPPUNIT_ASSERT(String("foo ").stripWhiteSpace() == String("foo"));