summaryrefslogtreecommitdiff
path: root/cpp/src/Ice/StringConverter.cpp
diff options
context:
space:
mode:
authorBernard Normier <bernard@zeroc.com>2007-07-18 16:47:05 -0400
committerBernard Normier <bernard@zeroc.com>2007-07-18 16:47:05 -0400
commitd7677e935d836ce91e64af89e78d0c0345a49b7d (patch)
tree51a19a78005a291fd81997ee5e9114edf1b67a12 /cpp/src/Ice/StringConverter.cpp
parentMerge branch 'master' of ssh://cvs/home/git/ice (diff)
downloadice-d7677e935d836ce91e64af89e78d0c0345a49b7d.tar.bz2
ice-d7677e935d836ce91e64af89e78d0c0345a49b7d.tar.xz
ice-d7677e935d836ce91e64af89e78d0c0345a49b7d.zip
Added new WindowsStringConverter
Diffstat (limited to 'cpp/src/Ice/StringConverter.cpp')
-rwxr-xr-xcpp/src/Ice/StringConverter.cpp126
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
+
}