summaryrefslogtreecommitdiff
path: root/cpp/src/Ice/LoggerI.cpp
diff options
context:
space:
mode:
authorJose <jose@zeroc.com>2014-05-02 19:56:38 +0200
committerJose <jose@zeroc.com>2014-05-02 19:56:38 +0200
commit1161c5817059464ab511632c0ce5d14593ced1a3 (patch)
tree51bbcdf2a4ea43c430312157350bb4271bc3f40d /cpp/src/Ice/LoggerI.cpp
parentUpdate .gitignore files (diff)
downloadice-1161c5817059464ab511632c0ce5d14593ced1a3.tar.bz2
ice-1161c5817059464ab511632c0ce5d14593ced1a3.tar.xz
ice-1161c5817059464ab511632c0ce5d14593ced1a3.zip
ICE-4851 - Use wstrings for input and output data that contain non-ASCII characters?
Diffstat (limited to 'cpp/src/Ice/LoggerI.cpp')
-rw-r--r--cpp/src/Ice/LoggerI.cpp117
1 files changed, 110 insertions, 7 deletions
diff --git a/cpp/src/Ice/LoggerI.cpp b/cpp/src/Ice/LoggerI.cpp
index 3375a2704e5..b5e599cc638 100644
--- a/cpp/src/Ice/LoggerI.cpp
+++ b/cpp/src/Ice/LoggerI.cpp
@@ -11,7 +11,13 @@
#include <Ice/LoggerI.h>
#include <IceUtil/Mutex.h>
#include <IceUtil/MutexPtrLock.h>
-#include <Ice/StringConverter.h>
+
+#ifdef _WIN32
+# include <IceUtil/StringUtil.h>
+# include <IceUtil/ScopedArray.h>
+# include <IceUtil/StringConverter.h>
+#endif
+
#include <Ice/LocalException.h>
using namespace std;
@@ -41,9 +47,70 @@ public:
Init init;
+#ifdef _WIN32
+string
+UTF8ToCodePage(const string& in, int codePage)
+{
+ string out;
+ if(!in.empty())
+ {
+ if(CP_UTF8 == codePage)
+ {
+ out = in;
+ }
+ else
+ {
+ IceUtil::ScopedArray<wchar_t> wbuffer;
+ int size = 0;
+ int wlength = 0;
+ do
+ {
+ size == 0 ? 2 * in.size() : 2 * size;
+ wbuffer.reset(new wchar_t[size]);
+ wlength = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, in.c_str(), -1, wbuffer.get(), size);
+ }
+ while(wlength == 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER);
+
+ if(wlength == 0)
+ {
+ throw IceUtil::IllegalConversionException(__FILE__, __LINE__, IceUtilInternal::lastErrorToString());
+ }
+
+ //
+ // WC_ERR_INVALID_CHARS conversion flag is only supported with 65001 (UTF-8) and
+ // 54936 (GB18030 Simplified Chinese)
+ //
+ DWORD conversionFlags = (codePage == 65001 || codePage == 54936) ? WC_ERR_INVALID_CHARS : 0;
+
+ IceUtil::ScopedArray<char> buffer;
+
+ size = 0;
+ int length = 0;
+ do
+ {
+ size == 0 ? wlength + 2 : 2 * size;
+ buffer.reset(new char[length]);
+ length = WideCharToMultiByte(codePage, conversionFlags, wbuffer.get(), wlength, buffer.get(), size, 0, 0);
+ }
+ while(length == 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER);
+
+ if(!length)
+ {
+ throw IceUtil::IllegalConversionException(__FILE__, __LINE__, IceUtilInternal::lastErrorToString());;
+ }
+ out.assign(buffer.get(), length);
+ }
+ }
+ return out;
}
+#endif
-Ice::LoggerI::LoggerI(const string& prefix, const string& file)
+}
+
+Ice::LoggerI::LoggerI(const string& prefix, const string& file,
+ bool convert, const IceUtil::StringConverterPtr& converter) :
+ _convert(convert),
+ _converter(converter)
{
if(!prefix.empty())
{
@@ -52,10 +119,6 @@ Ice::LoggerI::LoggerI(const string& prefix, const string& file)
if(!file.empty())
{
- //
- // The given file string is execpted to be encoded as UTF8 by
- // the caller, so no need to convert it here.
- //
_file = file;
_out.open(file, fstream::out | fstream::app);
if(!_out.is_open())
@@ -108,7 +171,7 @@ Ice::LoggerI::error(const string& message)
LoggerPtr
Ice::LoggerI::cloneWithPrefix(const std::string& prefix)
{
- return new LoggerI(prefix, _file);
+ return new LoggerI(prefix, _file, _convert, _converter);
}
void
@@ -134,6 +197,46 @@ Ice::LoggerI::write(const string& message, bool indent)
}
else
{
+#ifndef _WIN32
cerr << s << endl;
+#else
+ //
+ // Convert the message from the native narrow string encoding to the console
+ // code page encoding for printing. If the _convert member is set to false
+ // we don't do any conversion.
+ //
+ if(!_convert)
+ {
+ cerr << s << endl;
+ }
+ else
+ {
+ try
+ {
+ //
+ // First we convert the message to UTF8 using nativeToUTF8
+ // then we convert the message to the console code page
+ // using UTF8ToCodePage.
+ //
+ // nativeToUTF8 doesn't do any conversion if the converter is
+ // null likewise UTF8ToCodePage doesn't do any conversion if
+ // the code page is UTF8.
+ //
+ // We cannot use cerr here as writing to console using cerr
+ // will do its own conversion and will corrupt the messages.
+ //
+ fprintf_s(stderr, "%s\n", UTF8ToCodePage(IceUtil::nativeToUTF8(_converter, s),
+ GetConsoleOutputCP()).c_str());
+ }
+ catch(const IceUtil::IllegalConversionException&)
+ {
+ //
+ // If there is a problem with the encoding conversions we just
+ // write the original message without encoding conversions.
+ //
+ fprintf_s(stderr, "%s\n", s.c_str());
+ }
+ }
+#endif
}
}