diff options
Diffstat (limited to 'cpp/src/IceUtil/Unicode.cpp')
-rw-r--r-- | cpp/src/IceUtil/Unicode.cpp | 259 |
1 files changed, 141 insertions, 118 deletions
diff --git a/cpp/src/IceUtil/Unicode.cpp b/cpp/src/IceUtil/Unicode.cpp index ca36a912b47..22ced7e61b2 100644 --- a/cpp/src/IceUtil/Unicode.cpp +++ b/cpp/src/IceUtil/Unicode.cpp @@ -7,7 +7,17 @@ // // ********************************************************************** +#include <IceUtil/Config.h> + +#ifndef ICE_HAS_CODECVT_UTF8 +// +// It's better to exclude the file from the build, but it's not always +// easy to do. +// + #include <IceUtil/Unicode.h> +#include <IceUtil/Exception.h> + #include <IceUtil/ConvertUTF.h> using namespace std; @@ -16,108 +26,131 @@ using namespace IceUtilInternal; namespace { + // + // Helper class, base never defined + // Usage: WstringHelper<sizeof(wchar_t)>::toUTF8 and fromUTF8. + // + template<size_t wcharSize> + struct WstringHelper + { + static ConversionResult toUTF8( + const wchar_t*& sourceStart, const wchar_t* sourceEnd, + Byte*& targetStart, Byte* targetEnd); + + static ConversionResult fromUTF8( + const Byte*& sourceStart, const Byte* sourceEnd, + wchar_t*& targetStart, wchar_t* targetEnd); + }; + + template<> + struct WstringHelper<2> + { + static ConversionResult toUTF8( + const wchar_t*& sourceStart, const wchar_t* sourceEnd, + Byte*& targetStart, Byte* targetEnd) + { + return ConvertUTF16toUTF8( + reinterpret_cast<const UTF16**>(&sourceStart), + reinterpret_cast<const UTF16*>(sourceEnd), + &targetStart, targetEnd, lenientConversion); + } + + static ConversionResult fromUTF8( + const Byte*& sourceStart, const Byte* sourceEnd, + wchar_t*& targetStart, wchar_t* targetEnd) + { + return ConvertUTF8toUTF16( + &sourceStart, sourceEnd, + reinterpret_cast<UTF16**>(&targetStart), + reinterpret_cast<UTF16*>(targetEnd), lenientConversion); + } + }; + + template<> + struct WstringHelper<4> + { + static ConversionResult toUTF8( + const wchar_t*& sourceStart, const wchar_t* sourceEnd, + Byte*& targetStart, Byte* targetEnd) + { + return ConvertUTF32toUTF8( + reinterpret_cast<const UTF32**>(&sourceStart), + reinterpret_cast<const UTF32*>(sourceEnd), + &targetStart, targetEnd, lenientConversion); + } + + static ConversionResult fromUTF8( + const Byte*& sourceStart, const Byte* sourceEnd, + wchar_t*& targetStart, wchar_t* targetEnd) + { + return ConvertUTF8toUTF32( + &sourceStart, sourceEnd, + reinterpret_cast<UTF32**>(&targetStart), + reinterpret_cast<UTF32*>(targetEnd), lenientConversion); + } + }; + + void + checkResult(ConversionResult result) + { + switch (result) + { + case conversionOK: + break; + case sourceExhausted: + throw IceUtil::IllegalConversionException(__FILE__, __LINE__, "source exhausted"); + case sourceIllegal: + throw IceUtil::IllegalConversionException(__FILE__, __LINE__, "source illegal"); + case targetExhausted: + throw IceUtil::IllegalConversionException(__FILE__, __LINE__, "source illegal"); + default: + { + assert(0); + throw IceUtil::IllegalConversionException(__FILE__, __LINE__); + } + } + } +} + // -// Helper class, base never defined -// Usage: WstringHelper<sizeof(wchar_t)>::toUTF8 and fromUTF8. +// convertXXX functions // -template<size_t wcharSize> -struct WstringHelper -{ - static ConversionResult toUTF8( - const wchar_t*& sourceStart, const wchar_t* sourceEnd, - Byte*& targetStart, Byte* targetEnd, ConversionFlags flags); - static ConversionResult fromUTF8( - const Byte*& sourceStart, const Byte* sourceEnd, - wchar_t*& targetStart, wchar_t* targetEnd, ConversionFlags flags); -}; - -template<> -struct WstringHelper<2> +bool +IceUtilInternal::convertUTFWstringToUTF8( + const wchar_t*& sourceStart, const wchar_t* sourceEnd, + Byte*& targetStart, Byte* targetEnd) { - static ConversionResult toUTF8( - const wchar_t*& sourceStart, const wchar_t* sourceEnd, - Byte*& targetStart, Byte* targetEnd, ConversionFlags flags) - { - return ConvertUTF16toUTF8( - reinterpret_cast<const UTF16**>(&sourceStart), - reinterpret_cast<const UTF16*>(sourceEnd), - &targetStart, targetEnd, flags); - } - - static ConversionResult fromUTF8( - const Byte*& sourceStart, const Byte* sourceEnd, - wchar_t*& targetStart, wchar_t* targetEnd, ConversionFlags flags) - { - return ConvertUTF8toUTF16( - &sourceStart, sourceEnd, - reinterpret_cast<UTF16**>(&targetStart), - reinterpret_cast<UTF16*>(targetEnd), flags); - } -}; + ConversionResult result = WstringHelper<sizeof(wchar_t)>::toUTF8( + sourceStart, sourceEnd, targetStart, targetEnd); -template<> -struct WstringHelper<4> -{ - static ConversionResult toUTF8( - const wchar_t*& sourceStart, const wchar_t* sourceEnd, - Byte*& targetStart, Byte* targetEnd, ConversionFlags flags) + if(result == targetExhausted) { - return ConvertUTF32toUTF8( - reinterpret_cast<const UTF32**>(&sourceStart), - reinterpret_cast<const UTF32*>(sourceEnd), - &targetStart, targetEnd, flags); + return false; } - - static ConversionResult fromUTF8( - const Byte*& sourceStart, const Byte* sourceEnd, - wchar_t*& targetStart, wchar_t* targetEnd, ConversionFlags flags) + else { - return ConvertUTF8toUTF32( - &sourceStart, sourceEnd, - reinterpret_cast<UTF32**>(&targetStart), - reinterpret_cast<UTF32*>(targetEnd), flags); + checkResult(result); + return true; } -}; } -// -// convertXXX functions -// -ConversionResult -IceUtilInternal::convertUTFWstringToUTF8( - const wchar_t*& sourceStart, const wchar_t* sourceEnd, - Byte*& targetStart, Byte* targetEnd, ConversionFlags flags) -{ - return WstringHelper<sizeof(wchar_t)>::toUTF8( - sourceStart, sourceEnd, targetStart, targetEnd, flags); -} - -ConversionResult -IceUtilInternal::convertUTF8ToUTFWstring( - const Byte*& sourceStart, const Byte* sourceEnd, - wchar_t*& targetStart, wchar_t* targetEnd, ConversionFlags flags) -{ - return WstringHelper<sizeof(wchar_t)>::fromUTF8( - sourceStart, sourceEnd, targetStart, targetEnd, flags); -} - -ConversionResult -IceUtilInternal::convertUTF8ToUTFWstring(const Byte*& sourceStart, const Byte* sourceEnd, - std::wstring& target, ConversionFlags flags) +void +IceUtilInternal::convertUTF8ToUTFWstring(const Byte*& sourceStart, const Byte* sourceEnd, + std::wstring& target) { // // Could be reimplemented without this temporary wchar_t buffer // size_t size = static_cast<size_t>(sourceEnd - sourceStart); wchar_t* outBuf = new wchar_t[size]; - wchar_t* targetStart = outBuf; + wchar_t* targetStart = outBuf; wchar_t* targetEnd = targetStart + size; - ConversionResult result = - convertUTF8ToUTFWstring(sourceStart, sourceEnd, targetStart, - targetEnd, flags); + ConversionResult result = + WstringHelper<sizeof(wchar_t)>::fromUTF8( + sourceStart, sourceEnd, targetStart, targetEnd); if(result == conversionOK) { @@ -125,63 +158,53 @@ IceUtilInternal::convertUTF8ToUTFWstring(const Byte*& sourceStart, const Byte* s s.swap(target); } delete[] outBuf; - return result; + checkResult(result); } -ConversionResult -IceUtilInternal::convertUTF8ToUTF16(const vector<unsigned char>& source, vector<unsigned short>& target, ConversionFlags flags) +void +IceUtilInternal::convertUTF8ToUTF16(const vector<unsigned char>& source, vector<unsigned short>& target) { target.resize(source.size()); const unsigned char* sourceStart = &source[0]; const unsigned char* sourceEnd = &source[0] + source.size(); - - unsigned short* targetStart = &target[0]; + + unsigned short* targetStart = &target[0]; unsigned short* targetEnd = &target[0] + target.size(); - ConversionResult result = ConvertUTF8toUTF16(&sourceStart, sourceEnd, &targetStart, targetEnd, flags); - - if(result == conversionOK) - { - target.resize(targetStart - &target[0]); - } - return result; + ConversionResult result = ConvertUTF8toUTF16(&sourceStart, sourceEnd, &targetStart, targetEnd, lenientConversion); + + checkResult(result); + target.resize(targetStart - &target[0]); } -ConversionResult -IceUtilInternal::convertUTF8ToUTF32(const vector<unsigned char>& source, vector<unsigned int>& target, ConversionFlags flags) +void +IceUtilInternal::convertUTF8ToUTF32(const vector<unsigned char>& source, vector<unsigned int>& target) { target.resize(source.size()); const unsigned char* sourceStart = &source[0]; const unsigned char* sourceEnd = &source[0] + source.size(); - - unsigned int* targetStart = &target[0]; + + unsigned int* targetStart = &target[0]; unsigned int* targetEnd = &target[0] + target.size(); - ConversionResult result = ConvertUTF8toUTF32(&sourceStart, sourceEnd, &targetStart, targetEnd, flags); - - if(result == conversionOK) - { - target.resize(targetStart - &target[0]); - } - return result; + ConversionResult result = ConvertUTF8toUTF32(&sourceStart, sourceEnd, &targetStart, targetEnd, lenientConversion); + + checkResult(result); + target.resize(targetStart - &target[0]); } -ConversionResult -IceUtilInternal::convertUTF32ToUTF8(const vector<unsigned int>& source, vector<unsigned char>& target, ConversionFlags flags) +void +IceUtilInternal::convertUTF32ToUTF8(const vector<unsigned int>& source, vector<unsigned char>& target) { target.resize(source.size() * 4); const unsigned int* sourceStart = &source[0]; const unsigned int* sourceEnd = &source[0] + source.size(); - - unsigned char* targetStart = &target[0]; - unsigned char* targetEnd = &target[0] + target.size(); - ConversionResult result = ConvertUTF32toUTF8(&sourceStart, sourceEnd, &targetStart, targetEnd, flags); - - if(result == conversionOK) - { - target.resize(targetStart - &target[0]); - } - return result; -} + unsigned char* targetStart = &target[0]; + unsigned char* targetEnd = &target[0] + target.size(); + ConversionResult result = ConvertUTF32toUTF8(&sourceStart, sourceEnd, &targetStart, targetEnd, lenientConversion); + checkResult(result); + target.resize(targetStart - &target[0]); +} +#endif |