Skip to content

Commit

Permalink
Remove UTF16LE means swap compatibility hack
Browse files Browse the repository at this point in the history
  • Loading branch information
ufleisch committed Dec 20, 2023
1 parent 1ee7493 commit 73ddb42
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 37 deletions.
26 changes: 11 additions & 15 deletions taglib/toolkit/tstring.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ 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;
Expand Down Expand Up @@ -172,35 +172,31 @@ 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<StringPrivate>())
{
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 {
debug("String::String() -- TagLib::wstring should not contain Latin1 or UTF-8.");
}
}

String::String(const wchar_t *s) :
String(s, wcharByteOrder())
{
}

String::String(const wchar_t *s, Type t) :
d(std::make_shared<StringPrivate>())
{
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 {
Expand Down
26 changes: 14 additions & 12 deletions taglib/toolkit/tstring.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 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 = UTF16BE);
String(const wchar_t *s, Type t);

/*!
* Makes a deep copy of the data in \a c.
Expand Down
5 changes: 3 additions & 2 deletions taglib/toolkit/tutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,11 +203,12 @@ namespace TagLib
/*!
* Returns the byte order of the system.
*/
inline ByteOrder systemByteOrder()
inline constexpr ByteOrder systemByteOrder()
{
union {
union IntCharUnion {
int i;
char c;
constexpr IntCharUnion() : i{} {}
} u;

u.i = 1;
Expand Down
21 changes: 13 additions & 8 deletions tests/test_string.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <cstring>

#include "tstring.h"
#include "tutils.h"
#include <cppunit/extensions/HelperMacros.h>

using namespace std;
Expand Down Expand Up @@ -96,19 +97,23 @@ class TestString : public CppUnit::TestFixture
String unicode3(L"\u65E5\u672C\u8A9E");
CPPUNIT_ASSERT(*(unicode3.toCWString() + 1) == L'\u672C');

String unicode4(L"\u65e5\u672c\u8a9e", String::UTF16BE);
CPPUNIT_ASSERT(unicode4[1] == L'\u672c');
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 unicode5(L"\u65e5\u672c\u8a9e", String::UTF16LE);
CPPUNIT_ASSERT(unicode5[1] == L'\u2c67');
String unicode4(isLe ? wcSwappedOrder : wcSystemOrder, String::UTF16BE);
CPPUNIT_ASSERT(unicode4[1] == L'\u672c');

std::wstring stduni = L"\u65e5\u672c\u8a9e";
String unicode5(isLe ? wcSystemOrder : wcSwappedOrder, String::UTF16LE);
CPPUNIT_ASSERT(unicode5[1] == L'\u672c');

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"));
Expand Down

0 comments on commit 73ddb42

Please sign in to comment.