diff options
author | Bernard Normier <bernard@zeroc.com> | 2007-07-18 16:47:05 -0400 |
---|---|---|
committer | Bernard Normier <bernard@zeroc.com> | 2007-07-18 16:47:05 -0400 |
commit | d7677e935d836ce91e64af89e78d0c0345a49b7d (patch) | |
tree | 51a19a78005a291fd81997ee5e9114edf1b67a12 /cpp/src | |
parent | Merge branch 'master' of ssh://cvs/home/git/ice (diff) | |
download | ice-d7677e935d836ce91e64af89e78d0c0345a49b7d.tar.bz2 ice-d7677e935d836ce91e64af89e78d0c0345a49b7d.tar.xz ice-d7677e935d836ce91e64af89e78d0c0345a49b7d.zip |
Added new WindowsStringConverter
Diffstat (limited to 'cpp/src')
-rwxr-xr-x | cpp/src/Ice/StringConverter.cpp | 126 |
1 files changed, 125 insertions, 1 deletions
diff --git a/cpp/src/Ice/StringConverter.cpp b/cpp/src/Ice/StringConverter.cpp index 985111f9aa9..1d426877379 100755 --- a/cpp/src/Ice/StringConverter.cpp +++ b/cpp/src/Ice/StringConverter.cpp @@ -8,12 +8,49 @@ // ********************************************************************** #include <Ice/StringConverter.h> -#include <IceUtil/Unicode.h> +#include <IceUtil/IceUtil.h> #include <Ice/LocalException.h> using namespace IceUtil; using namespace std; + +#ifdef _WIN32 +namespace +{ +// +// Helper function +// + +string getMessageForLastError() +{ + LPVOID lpMsgBuf = 0; + DWORD ok = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR)&lpMsgBuf, + 0, + NULL); + + string msg; + if(ok) + { + msg = (LPCTSTR)lpMsgBuf; + LocalFree(lpMsgBuf); + } + else + { + msg = "Unknown Windows error"; + } + return msg; +} +} +#endif + + namespace Ice { @@ -64,6 +101,12 @@ void UnicodeWstringConverter::fromUTF8(const Byte* sourceStart, const Byte* sourceEnd, wstring& target) const { + if(sourceStart == sourceEnd) + { + target = L""; + return; + } + ConversionResult result = convertUTF8ToUTFWstring(sourceStart, sourceEnd, target, lenientConversion); @@ -82,4 +125,85 @@ UnicodeWstringConverter::fromUTF8(const Byte* sourceStart, const Byte* sourceEnd } } } + +#ifdef _WIN32 +WindowsStringConverter::WindowsStringConverter(unsigned int cp) : + _cp(cp) +{ +} + +Byte* +WindowsStringConverter::toUTF8(const char* sourceStart, + const char* sourceEnd, + UTF8Buffer& buffer) const +{ + // + // First convert to UTF-16 + // + int sourceSize = sourceEnd - sourceStart; + assert(sourceSize > 0); + + size_t size = 0; + int writtenWchar = 0; + IceUtil::ScopedArray<wchar_t> wbuffer; + do + { + size = size == 0 ? static_cast<size_t>(sourceSize) + 2 : 2 * size; + wbuffer.reset(new wchar_t[size]); + + writtenWchar = MultiByteToWideChar(_cp, MB_ERR_INVALID_CHARS, sourceStart, + sourceSize, wbuffer.get(), size); + } while(writtenWchar == 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER); + + if(writtenWchar == 0) + { + throw StringConversionException(__FILE__, __LINE__, getMessageForLastError()); + } + + // + // Then convert this UTF-16 wbuffer into UTF-8 + // + return _unicodeWstringConverter.toUTF8(wbuffer.get(), wbuffer.get() + writtenWchar, buffer); +} + +void +WindowsStringConverter::fromUTF8(const Byte* sourceStart, const Byte* sourceEnd, + string& target) const +{ + if(sourceStart == sourceEnd) + { + target = ""; + return; + } + + // + // First convert to wstring (UTF-16) + // + wstring wtarget; + _unicodeWstringConverter.fromUTF8(sourceStart, sourceEnd, wtarget); + + // + // And then to a multi-byte narrow string + // + size_t size = 0; + int writtenChar = 0; + IceUtil::ScopedArray<char> buffer; + do + { + size = size == 0 ? static_cast<size_t>(sourceEnd - sourceStart) + 2 : 2 * size; + buffer.reset(new char[size]); + writtenChar = WideCharToMultiByte(_cp, 0, wtarget.data(), wtarget.size(), + buffer.get(), size, 0, 0); + } while(writtenChar == 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER); + + if(writtenChar == 0) + { + throw StringConversionException(__FILE__, __LINE__, getMessageForLastError()); + } + + target.assign(buffer.get(), writtenChar); +} + +#endif + } |