From 7be9675ec7f3c74f721bede6c94d3d214ee31d2c Mon Sep 17 00:00:00 2001 From: Dwayne Boone Date: Thu, 30 Mar 2006 15:34:00 +0000 Subject: Added wstring support --- cppe/src/IceE/Unicode.cpp | 270 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 270 insertions(+) create mode 100644 cppe/src/IceE/Unicode.cpp (limited to 'cppe/src/IceE/Unicode.cpp') diff --git a/cppe/src/IceE/Unicode.cpp b/cppe/src/IceE/Unicode.cpp new file mode 100644 index 00000000000..a4bc29fadc6 --- /dev/null +++ b/cppe/src/IceE/Unicode.cpp @@ -0,0 +1,270 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2006 ZeroC, Inc. All rights reserved. +// +// This copy of Ice-E is licensed to you under the terms described in the +// ICEE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include +#include + +using namespace std; +using namespace IceUtil; + +namespace +{ +// +// Helper class, base never defined +// Usage: WstringHelper::toUTF8 and fromUTF8. +// +template +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> +{ + static ConversionResult toUTF8( + const wchar_t*& sourceStart, const wchar_t* sourceEnd, + Byte*& targetStart, Byte* targetEnd, ConversionFlags flags) + { + return ConvertUTF16toUTF8( + reinterpret_cast(&sourceStart), + reinterpret_cast(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(&targetStart), + reinterpret_cast(targetEnd), flags); + } +}; + +template<> +struct WstringHelper<4> +{ + static ConversionResult toUTF8( + const wchar_t*& sourceStart, const wchar_t* sourceEnd, + Byte*& targetStart, Byte* targetEnd, ConversionFlags flags) + { + return ConvertUTF32toUTF8( + reinterpret_cast(&sourceStart), + reinterpret_cast(sourceEnd), + &targetStart, targetEnd, flags); + } + + static ConversionResult fromUTF8( + const Byte*& sourceStart, const Byte* sourceEnd, + wchar_t*& targetStart, wchar_t* targetEnd, ConversionFlags flags) + { + return ConvertUTF8toUTF32( + &sourceStart, sourceEnd, + reinterpret_cast(&targetStart), + reinterpret_cast(targetEnd), flags); + } +}; +} + +// +// convertXXX functions +// + +ConversionResult +IceUtil::convertUTFWstringToUTF8( + const wchar_t*& sourceStart, const wchar_t* sourceEnd, + Byte*& targetStart, Byte* targetEnd, ConversionFlags flags) +{ + return WstringHelper::toUTF8( + sourceStart, sourceEnd, targetStart, targetEnd, flags); +} + +ConversionResult +IceUtil::convertUTF8ToUTFWstring( + const Byte*& sourceStart, const Byte* sourceEnd, + wchar_t*& targetStart, wchar_t* targetEnd, ConversionFlags flags) +{ + return WstringHelper::fromUTF8( + sourceStart, sourceEnd, targetStart, targetEnd, flags); +} + +ConversionResult +IceUtil::convertUTF8ToUTFWstring(const Byte*& sourceStart, const Byte* sourceEnd, + std::wstring& target, ConversionFlags flags) +{ + // + // Could be reimplemented without this temporary wchar_t buffer + // + size_t size = static_cast(sourceEnd - sourceStart); + wchar_t* outBuf = new wchar_t[size]; + wchar_t* targetStart = outBuf; + wchar_t* targetEnd = targetStart + size; + + ConversionResult result = + convertUTF8ToUTFWstring(sourceStart, sourceEnd, targetStart, + targetEnd, flags); + + if(result == conversionOK) + { + std::wstring s(outBuf, static_cast(targetStart - outBuf)); + s.swap(target); + } + delete[] outBuf; + return result; +} + + +// +// wstringToString and stringToWstring +// + +const char* IceUtil::UTFConversionException::_name = "IceUtil::UTFConversionException"; + +IceUtil::UTFConversionException::UTFConversionException(const char* file, int line, + ConversionResult cr): + Exception(file, line), + _conversionResult(cr) +{} + +const string +IceUtil::UTFConversionException::ice_name() const +{ + return _name; +} + +string +IceUtil::UTFConversionException::toString() const +{ + string str = Exception::toString(); + switch(_conversionResult) + { + case sourceExhausted: + str += ": source exhausted"; + break; + case targetExhausted: + str += ": target exhausted"; + break; + case sourceIllegal: + str += ": illegal source"; + break; + default: + assert(0); + break; + }; + return str; +} + +IceUtil::Exception* +IceUtil::UTFConversionException::ice_clone() const +{ + return new UTFConversionException(*this); +} + +void +IceUtil::UTFConversionException::ice_throw() const +{ + throw *this; +} + +IceUtil::ConversionResult +IceUtil::UTFConversionException::conversionResult() const +{ + return _conversionResult; +} + + +string +IceUtil::wstringToString(const wstring& wstr) +{ + string target; + + size_t size = wstr.size() * 3 * (sizeof(wchar_t) / 2); + + Byte* outBuf = new Byte[size]; + Byte* targetStart = outBuf; + Byte* targetEnd = outBuf + size; + + const wchar_t* sourceStart = wstr.data(); + + ConversionResult cr = + convertUTFWstringToUTF8( + sourceStart, sourceStart + wstr.size(), + targetStart, targetEnd, lenientConversion); + + if(cr != conversionOK) + { + delete[] outBuf; + throw UTFConversionException(__FILE__, __LINE__, cr); + } + + string s(reinterpret_cast(outBuf), + static_cast(targetStart - outBuf)); + s.swap(target); + delete[] outBuf; + return target; +} + +wstring +IceUtil::stringToWstring(const string& str) +{ + wstring result; + const Byte* sourceStart = reinterpret_cast(str.data()); + + ConversionResult cr + = convertUTF8ToUTFWstring(sourceStart, sourceStart + str.size(), + result, lenientConversion); + + if(cr != conversionOK) + { + throw UTFConversionException(__FILE__, __LINE__, cr); + } + return result; +} + + +#if defined(_MSC_VER) && (_MSC_VER >= 1300) +// +// See comments in IceUtil/Unicode.h +// + +# if _MSC_VER < 1400 +string +IceUtil::wstringToString(const basic_string<__wchar_t>& str) +{ + return wstringToString(*reinterpret_cast(&str)); +} + +basic_string<__wchar_t> +IceUtil::stringToNativeWstring(const string& str) +{ + return reinterpret_cast& >(stringToWstring(str)); +} +# else +string +IceUtil::wstringToString(const basic_string& str) +{ + return wstringToString(*reinterpret_cast(&str)); +} + +basic_string +IceUtil::stringToTypedefWstring(const string& str) +{ + return reinterpret_cast& >(stringToWstring(str)); +} + +# endif +#endif -- cgit v1.2.3