From 62efb9ff17ca889b26058062833290c89882ed9b Mon Sep 17 00:00:00 2001 From: Tsuda Kageyu Date: Thu, 21 Mar 2013 14:43:03 +0900 Subject: [PATCH] Detect sizeof(wchar_t) at compile time --- taglib/toolkit/tstring.cpp | 78 ++++++++++++++++++++++---------------- taglib/toolkit/tstring.h | 4 ++ 2 files changed, 49 insertions(+), 33 deletions(-) diff --git a/taglib/toolkit/tstring.cpp b/taglib/toolkit/tstring.cpp index ec3dd828..d6256a7b 100644 --- a/taglib/toolkit/tstring.cpp +++ b/taglib/toolkit/tstring.cpp @@ -46,8 +46,6 @@ # include #endif -using namespace TagLib; - namespace { inline unsigned short byteSwap(unsigned short x) @@ -91,6 +89,8 @@ namespace { #endif } +namespace TagLib { + class String::StringPrivate : public RefCounter { public: @@ -980,35 +980,46 @@ void String::copyFromUTF16(const wchar_t *s, size_t length, Type t) } } +template +void String::internalCopyFromUTF16(const char *s, size_t length, Type t) +{ + // Non specialized version. Used where sizeof(wchar_t) != 2. + + bool swap; + if(t == UTF16) { + if(length >= 2 && *reinterpret_cast(s) == 0xfeff) + swap = false; // Same as CPU endian. No need to swap bytes. + else if(length >= 2 && *reinterpret_cast(s) == 0xfffe) + swap = true; // Not same as CPU endian. Need to swap bytes. + else { + debug("String::copyFromUTF16() - Invalid UTF16 string."); + return; + } + + s += 2; + length -= 2; + } + else + swap = (t != WCharByteOrder); + + d->data.resize(length / 2); + for(size_t i = 0; i < length / 2; ++i) { + d->data[i] = swap ? combine(*s, *(s + 1)) : combine(*(s + 1), *s); + s += 2; + } +} + +template <> +void String::internalCopyFromUTF16<2>(const char *s, size_t length, Type t) +{ + // Specialized version for where sizeof(wchar_t) == 2. + + copyFromUTF16(reinterpret_cast(s), length / 2, t); +} + void String::copyFromUTF16(const char *s, size_t length, Type t) { - if(sizeof(wchar_t) == 2) - copyFromUTF16(reinterpret_cast(s), length / 2, t); - else - { - bool swap; - if(t == UTF16) { - if(length >= 2 && *reinterpret_cast(s) == 0xfeff) - swap = false; // Same as CPU endian. No need to swap bytes. - else if(length >= 2 && *reinterpret_cast(s) == 0xfffe) - swap = true; // Not same as CPU endian. Need to swap bytes. - else { - debug("String::copyFromUTF16() - Invalid UTF16 string."); - return; - } - - s += 2; - length -= 2; - } - else - swap = (t != WCharByteOrder); - - d->data.resize(length / 2); - for(size_t i = 0; i < length / 2; ++i) { - d->data[i] = swap ? combine(*s, *(s + 1)) : combine(*(s + 1), *s); - s += 2; - } - } + internalCopyFromUTF16(s, length, t); } #if defined(TAGLIB_LITTLE_ENDIAN) @@ -1029,29 +1040,30 @@ const String::Type String::WCharByteOrder = wcharByteOrder(); // related functions //////////////////////////////////////////////////////////////////////////////// -const TagLib::String TagLib::operator+(const TagLib::String &s1, const TagLib::String &s2) +const String operator+(const String &s1, const String &s2) { String s(s1); s.append(s2); return s; } -const TagLib::String TagLib::operator+(const char *s1, const TagLib::String &s2) +const String operator+(const char *s1, const String &s2) { String s(s1); s.append(s2); return s; } -const TagLib::String TagLib::operator+(const TagLib::String &s1, const char *s2) +const String operator+(const String &s1, const char *s2) { String s(s1); s.append(s2); return s; } -std::ostream &TagLib::operator<<(std::ostream &s, const String &str) +std::ostream &operator<<(std::ostream &s, const String &str) { s << str.to8Bit(); return s; } +} diff --git a/taglib/toolkit/tstring.h b/taglib/toolkit/tstring.h index 32ce6e49..13234f7f 100644 --- a/taglib/toolkit/tstring.h +++ b/taglib/toolkit/tstring.h @@ -509,6 +509,9 @@ namespace TagLib { */ void copyFromUTF16(const char *s, size_t length, Type t); + template + void internalCopyFromUTF16(const char *s, size_t length, Type t); + /*! * Indicates which byte order of UTF-16 is used to store strings internally. * @@ -557,3 +560,4 @@ namespace TagLib { } #endif +