summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
authorBernard Normier <bernard@zeroc.com>2016-06-03 14:11:48 -0400
committerBernard Normier <bernard@zeroc.com>2016-06-03 14:11:48 -0400
commit48b141f8f6a8603f6b13a85bde002f6b480832f7 (patch)
tree41cf4ae281ad96e13216ea208a6579aa442844d3 /cpp/src
parentFixed 3.7a2 version in msbuild props files (diff)
downloadice-48b141f8f6a8603f6b13a85bde002f6b480832f7.tar.bz2
ice-48b141f8f6a8603f6b13a85bde002f6b480832f7.tar.xz
ice-48b141f8f6a8603f6b13a85bde002f6b480832f7.zip
Refactored string converters and use codecvt_utf8[_utf16] when
available instead of ConvertUTF
Diffstat (limited to 'cpp/src')
-rw-r--r--cpp/src/Ice/Instance.cpp15
-rw-r--r--cpp/src/Ice/LoggerI.cpp2
-rw-r--r--cpp/src/Ice/Makefile.mk6
-rw-r--r--cpp/src/IceGrid/Parser.cpp2
-rw-r--r--cpp/src/IceUtil/ConvertUTF.cpp16
-rw-r--r--cpp/src/IceUtil/ConvertUTF.h37
-rw-r--r--cpp/src/IceUtil/Makefile.mk4
-rw-r--r--cpp/src/IceUtil/StringConverter.cpp586
-rw-r--r--cpp/src/IceUtil/Unicode.cpp259
-rw-r--r--cpp/src/IceUtil/Unicode.h49
-rw-r--r--cpp/src/IceUtil/UtilException.cpp7
-rw-r--r--cpp/src/IceUtil/msbuild/iceutil/iceutil.vcxproj8
-rw-r--r--cpp/src/IceUtil/msbuild/iceutil/iceutil.vcxproj.filters16
-rw-r--r--cpp/src/Slice/PythonUtil.cpp19
-rw-r--r--cpp/src/Slice/RubyUtil.cpp19
-rw-r--r--cpp/src/slice2cpp/Gen.cpp37
-rw-r--r--cpp/src/slice2cs/Gen.cpp21
-rw-r--r--cpp/src/slice2java/Gen.cpp21
-rw-r--r--cpp/src/slice2js/Gen.cpp21
-rw-r--r--cpp/src/slice2objc/Gen.cpp20
-rw-r--r--cpp/src/slice2php/Main.cpp28
21 files changed, 672 insertions, 521 deletions
diff --git a/cpp/src/Ice/Instance.cpp b/cpp/src/Ice/Instance.cpp
index 4baed1e3421..743ca63f0cf 100644
--- a/cpp/src/Ice/Instance.cpp
+++ b/cpp/src/Ice/Instance.cpp
@@ -1003,12 +1003,15 @@ IceInternal::Instance::Instance(const CommunicatorPtr& communicator, const Initi
#ifdef NDEBUG
if(_initData.properties->getPropertyAsIntWithDefault("Ice.PrintStackTraces", 0) > 0)
-#else
- if(_initData.properties->getPropertyAsIntWithDefault("Ice.PrintStackTraces", 1) > 0)
-#endif
{
IceUtilInternal::printStackTraces = true;
}
+#else
+ if(_initData.properties->getPropertyAsIntWithDefault("Ice.PrintStackTraces", 1) == 0)
+ {
+ IceUtilInternal::printStackTraces = false;
+ }
+#endif
#ifndef _WIN32
string newUser = _initData.properties->getProperty("Ice.ChangeUser");
@@ -1250,7 +1253,7 @@ IceInternal::Instance::Instance(const CommunicatorPtr& communicator, const Initi
//
if(!_wstringConverter)
{
- _wstringConverter = new IceUtil::UnicodeWstringConverter;
+ _wstringConverter = IceUtil::createUnicodeWstringConverter();
}
__setNoDelete(false);
@@ -1346,9 +1349,9 @@ IceInternal::Instance::finishSetup(int& argc, char* argv[], const Ice::Communica
{
_wstringConverter = newWstringConverter;
}
- else if(!dynamic_cast<IceUtil::UnicodeWstringConverter*>(_wstringConverter.get()))
+ else
{
- _wstringConverter = new IceUtil::UnicodeWstringConverter;
+ _wstringConverter = IceUtil::createUnicodeWstringConverter();
}
//
diff --git a/cpp/src/Ice/LoggerI.cpp b/cpp/src/Ice/LoggerI.cpp
index 9aa0d10b7ce..8e4ea650dba 100644
--- a/cpp/src/Ice/LoggerI.cpp
+++ b/cpp/src/Ice/LoggerI.cpp
@@ -61,7 +61,7 @@ Ice::LoggerI::LoggerI(const string& prefix, const string& file,
_convert(convert),
_converter(converter),
#if defined(_WIN32) && !defined(ICE_OS_WINRT)
- _consoleConverter(new IceUtil::WindowsStringConverter(GetConsoleOutputCP())),
+ _consoleConverter(IceUtil::createWindowsStringConverter(GetConsoleOutputCP())),
#endif
_sizeMax(sizeMax)
{
diff --git a/cpp/src/Ice/Makefile.mk b/cpp/src/Ice/Makefile.mk
index d9424f1d6d4..fe90b914e73 100644
--- a/cpp/src/Ice/Makefile.mk
+++ b/cpp/src/Ice/Makefile.mk
@@ -19,7 +19,11 @@ endif
Ice_sliceflags := --include-dir Ice --dll-export ICE_API
Ice_libs := bz2
Ice_extra_sources := $(wildcard src/IceUtil/*.cpp)
-Ice_excludes := $(currentdir)/DLLMain.cpp
+Ice_excludes = src/Ice/DLLMain.cpp
+
+ifeq ($(os),Darwin)
+Ice_excludes += src/IceUtil/ConvertUTF.cpp src/IceUtil/Unicode.cpp
+endif
Ice[iphoneos]_extra_sources := $(wildcard $(addprefix $(currentdir)/ios/,*.cpp *.mm))
Ice[iphoneos]_excludes := $(currentdir)/RegisterPluginsInit.cpp
diff --git a/cpp/src/IceGrid/Parser.cpp b/cpp/src/IceGrid/Parser.cpp
index cd5aeb55fcf..01c80978f1c 100644
--- a/cpp/src/IceGrid/Parser.cpp
+++ b/cpp/src/IceGrid/Parser.cpp
@@ -2923,7 +2923,7 @@ Parser::Parser(const CommunicatorPtr& communicator,
#ifdef _WIN32
if(!windowsConsoleConverter)
{
- windowsConsoleConverter = new IceUtil::WindowsStringConverter(GetConsoleOutputCP());
+ windowsConsoleConverter = IceUtil::createWindowsStringConverter(GetConsoleOutputCP());
}
#endif
}
diff --git a/cpp/src/IceUtil/ConvertUTF.cpp b/cpp/src/IceUtil/ConvertUTF.cpp
index 2a28c78e5e1..5e0b110542c 100644
--- a/cpp/src/IceUtil/ConvertUTF.cpp
+++ b/cpp/src/IceUtil/ConvertUTF.cpp
@@ -47,9 +47,15 @@
------------------------------------------------------------------------ */
+#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/ConvertUTF.h>
-#include <IceUtil/StringConverter.h>
#ifdef CVTUTF_DEBUG
#include <stdio.h>
@@ -439,12 +445,7 @@ ConversionResult ConvertUTF8toUTF32 (
similarly unrolled loops.
--------------------------------------------------------------------- */
-}
-namespace IceUtil
-{
-
-using namespace IceUtilInternal;
/* --------------------------------------------------------------------- */
@@ -473,5 +474,6 @@ Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd) {
}
}
}
-
}
+
+#endif
diff --git a/cpp/src/IceUtil/ConvertUTF.h b/cpp/src/IceUtil/ConvertUTF.h
index a761ef455b8..b7285b4e0f4 100644
--- a/cpp/src/IceUtil/ConvertUTF.h
+++ b/cpp/src/IceUtil/ConvertUTF.h
@@ -32,9 +32,6 @@
#ifndef ICE_UTIL_CONVERT_UTF_H
#define ICE_UTIL_CONVERT_UTF_H
-#include <IceUtil/Unicode.h>
-
-
/* ---------------------------------------------------------------------
Conversions between UTF32, UTF-16, and UTF-8. Header file.
@@ -94,6 +91,25 @@
------------------------------------------------------------------------ */
+
+namespace IceUtilInternal
+{
+
+enum ConversionFlags
+{
+ strictConversion = 0,
+ lenientConversion
+};
+
+enum ConversionResult
+{
+ conversionOK, /* conversion successful */
+ sourceExhausted, /* partial character in source, but hit end */
+ targetExhausted, /* insuff. room in target for conversion */
+ sourceIllegal /* source sequence is illegal/malformed */
+};
+
+
/* ---------------------------------------------------------------------
The following 4 definitions are compiler-specific.
The C standard does not guarantee that wchar_t has at least
@@ -102,9 +118,6 @@
bit mask & shift operations.
------------------------------------------------------------------------ */
-namespace IceUtilInternal
-{
-
typedef unsigned int UTF32; /* at least 32 bits */
typedef unsigned short UTF16; /* at least 16 bits */
typedef unsigned char UTF8; /* typically 8 bits */
@@ -120,23 +133,21 @@ typedef bool Boolean; /* 0 or 1 */
ConversionResult ConvertUTF8toUTF16(
const UTF8** sourceStart, const UTF8* sourceEnd,
- UTF16** targetStart, UTF16* targetEnd, IceUtil::ConversionFlags flags);
+ UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
ConversionResult ConvertUTF16toUTF8 (
const UTF16** sourceStart, const UTF16* sourceEnd,
- UTF8** targetStart, UTF8* targetEnd, IceUtil::ConversionFlags flags);
+ UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
ConversionResult ConvertUTF8toUTF32(
const UTF8** sourceStart, const UTF8* sourceEnd,
- UTF32** targetStart, UTF32* targetEnd, IceUtil::ConversionFlags flags);
+ UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
ConversionResult ConvertUTF32toUTF8(
const UTF32** sourceStart, const UTF32* sourceEnd,
- UTF8** targetStart, UTF8* targetEnd, IceUtil::ConversionFlags flags);
+ UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
-//
-// isLegalUTFSequence is declared in IceUtil/StringConverter.h
-//
+bool isLegalUTF8Sequence(const UTF8* source, const UTF8* end);
/* --------------------------------------------------------------------- */
diff --git a/cpp/src/IceUtil/Makefile.mk b/cpp/src/IceUtil/Makefile.mk
index 228be247ff7..b866395c84f 100644
--- a/cpp/src/IceUtil/Makefile.mk
+++ b/cpp/src/IceUtil/Makefile.mk
@@ -12,6 +12,10 @@ $(project)_libraries = IceUtil
IceUtil_targetdir := $(libdir)
IceUtil_cppflags := $(if $(filter yes,$(libbacktrace)),-DICE_LIBBACKTRACE)
+ifeq ($(os),Darwin)
+IceUtil_excludes = src/IceUtil/ConvertUTF.cpp src/IceUtil/Unicode.cpp
+endif
+
# Always enable the static configuration for the IceUtil library
IceUtil_always_enable_configs := static
diff --git a/cpp/src/IceUtil/StringConverter.cpp b/cpp/src/IceUtil/StringConverter.cpp
index 46c590c42f3..8b60c48d53f 100644
--- a/cpp/src/IceUtil/StringConverter.cpp
+++ b/cpp/src/IceUtil/StringConverter.cpp
@@ -12,7 +12,13 @@
#include <IceUtil/Mutex.h>
#include <IceUtil/ScopedArray.h>
#include <IceUtil/StringUtil.h>
+
+#ifdef ICE_HAS_CODECVT_UTF8
+#include <codecvt>
+#include <locale>
+#else
#include <IceUtil/Unicode.h>
+#endif
using namespace IceUtil;
using namespace IceUtilInternal;
@@ -25,6 +31,234 @@ IceUtil::Mutex* processStringConverterMutex = 0;
IceUtil::StringConverterPtr processStringConverter;
IceUtil::WstringConverterPtr processWstringConverter;
+#ifndef ICE_HAS_THREAD_SAFE_LOCAL_STATIC
+IceUtil::WstringConverterPtr unicodeWstringConverter;
+#endif
+
+#ifdef ICE_HAS_CODECVT_UTF8
+
+template<size_t wcharSize>
+struct SelectCodeCvt;
+
+template<>
+struct SelectCodeCvt<2>
+{
+#ifdef ICE_LITTLE_ENDIAN
+ typedef std::codecvt_utf8_utf16<wchar_t, 0x10ffff, little_endian> Type;
+#else
+ typedef std::codecvt_utf8_utf16<wchar_t> Type;
+#endif
+};
+
+template<>
+struct SelectCodeCvt<4>
+{
+ typedef std::codecvt_utf8<wchar_t> Type;
+};
+
+class UnicodeWstringConverter : public WstringConverter
+{
+public:
+
+#if defined(_MSC_VER) && (_MSC_VER <= 1800)
+ //
+ // VS 2013 needs a default ctor
+ //
+ UnicodeWstringConverter()
+ {
+ }
+#endif
+
+ virtual Byte* toUTF8(const wchar_t* sourceStart, const wchar_t* sourceEnd, UTF8Buffer& buffer) const
+ {
+ //
+ // Max bytes for a character encoding in UTF-8 is 4,
+ // however MSVC returns 6
+ //
+#ifdef _MSC_VER
+ assert(_codecvt.max_length() == 4 || _codecvt.max_length() == 6);
+#else
+ assert(_codecvt.max_length() == 4);
+#endif
+ if(sourceStart == sourceEnd)
+ {
+ return buffer.getMoreBytes(1, 0);
+ }
+
+ char* targetStart = 0;
+ char* targetEnd = 0;
+ char* targetNext = 0;
+
+ mbstate_t state = mbstate_t(); // must be initialized!
+ const wchar_t* sourceNext = sourceStart;
+
+ bool more = false;
+
+ //
+ // The number of bytes we request from buffer for each remaining source character
+ //
+ size_t factor = 2;
+
+ do
+ {
+ assert(factor <= 4);
+ const size_t chunkSize = std::max<size_t>((sourceEnd - sourceStart) * factor, 4);
+ ++factor; // at the next round, we'll allocate more bytes per remaining source character
+
+ targetStart = reinterpret_cast<char*>(buffer.getMoreBytes(chunkSize, reinterpret_cast<Byte*>(targetNext)));
+ targetEnd = targetStart + chunkSize;
+ targetNext = targetStart;
+
+ codecvt_base::result result =
+ _codecvt.out(state, sourceStart, sourceEnd, sourceNext, targetStart, targetEnd, targetNext);
+
+ switch(result)
+ {
+ case codecvt_base::ok:
+ //
+ // MSVC returns ok when target is exhausted
+ //
+ more = sourceNext < sourceEnd;
+ break;
+
+ case codecvt_base::partial:
+ //
+ // clang/libc++ and g++5 return partial when target is exhausted
+ //
+ more = true;
+ assert(sourceNext < sourceEnd);
+ break;
+
+ case codecvt_base::noconv:
+ //
+ // Unexpected
+ //
+ assert(0);
+ throw IllegalConversionException(__FILE__, __LINE__, "codecvt.out noconv");
+
+ default:
+ throw IllegalConversionException(__FILE__, __LINE__, "codecvt.out error");
+ }
+
+ if(targetStart == targetNext)
+ {
+ // We didn't convert a single character
+ throw IllegalConversionException(__FILE__, __LINE__,
+ "no character converted by codecvt.out");
+ }
+
+ sourceStart = sourceNext;
+ } while (more);
+
+ return reinterpret_cast<Byte*>(targetNext);
+ }
+
+ virtual void fromUTF8(const Byte* sourceStart, const Byte* sourceEnd, wstring& target) const
+ {
+ if(sourceStart == sourceEnd)
+ {
+ target = L"";
+ }
+ else
+ {
+ //
+ // TODO: consider reimplementing without the wstring_convert helper
+ // to improve performance
+ // Note that wstring_convert is "stateful" and cannot be a shared data member
+ //
+ wstring_convert<CodeCvt> convert;
+
+ try
+ {
+ target = convert.from_bytes(reinterpret_cast<const char*>(sourceStart),
+ reinterpret_cast<const char*>(sourceEnd));
+ }
+ catch(const std::range_error& ex)
+ {
+ throw IllegalConversionException(__FILE__, __LINE__, ex.what());
+ }
+ }
+ }
+
+private:
+
+ typedef SelectCodeCvt<sizeof(wchar_t)>::Type CodeCvt;
+ const CodeCvt _codecvt;
+};
+
+#else
+
+class UnicodeWstringConverter : public WstringConverter
+{
+public:
+
+ virtual Byte* toUTF8(const wchar_t* sourceStart, const wchar_t* sourceEnd, UTF8Buffer& buffer) const
+ {
+ if(sourceStart == sourceEnd)
+ {
+ return buffer.getMoreBytes(1, 0);
+ }
+
+ Byte* targetStart = 0;
+ Byte* targetEnd = 0;
+
+ //
+ // The number of bytes we request from buffer for each remaining source character
+ //
+ size_t factor = 2;
+
+ do
+ {
+ assert(factor <= 4);
+ const size_t chunkSize = std::max<size_t>((sourceEnd - sourceStart) * factor, 4);
+ ++factor; // at the next round, we'll allocate more bytes per remaining source character
+
+ targetStart = buffer.getMoreBytes(chunkSize, targetStart);
+ targetEnd = targetStart + chunkSize;
+
+ }
+ while(convertUTFWstringToUTF8(sourceStart, sourceEnd, targetStart, targetEnd) == false);
+
+ return targetStart;
+ }
+
+
+ virtual void fromUTF8(const Byte* sourceStart, const Byte* sourceEnd, wstring& target) const
+ {
+ if(sourceStart == sourceEnd)
+ {
+ target = L"";
+ }
+ else
+ {
+ convertUTF8ToUTFWstring(sourceStart, sourceEnd, target);
+ }
+ }
+};
+
+#endif
+
+#ifdef _WIN32
+
+//
+// Converts to/from UTF-8 using MultiByteToWideChar and WideCharToMultiByte
+//
+class WindowsStringConverter : public StringConverter
+{
+public:
+
+ explicit WindowsStringConverter(unsigned int);
+
+ virtual Byte* toUTF8(const char*, const char*, UTF8Buffer&) const;
+
+ virtual void fromUTF8(const Byte*, const Byte*, string& target) const;
+
+private:
+ unsigned int _cp;
+};
+#endif
+
+
class Init
{
public:
@@ -32,6 +266,9 @@ public:
Init()
{
processStringConverterMutex = new IceUtil::Mutex;
+#ifndef ICE_HAS_THREAD_SAFE_LOCAL_STATIC
+ unicodeWstringConverter = ICE_MAKE_SHARED(UnicodeWstringConverter);
+#endif
}
~Init()
@@ -43,10 +280,16 @@ public:
Init init;
-}
-namespace
+const WstringConverterPtr&
+getUnicodeWstringConverter()
{
+#ifdef ICE_HAS_THREAD_SAFE_LOCAL_STATIC
+ static const WstringConverterPtr unicodeWstringConverter = ICE_MAKE_SHARED(UnicodeWstringConverter);
+#endif
+ return unicodeWstringConverter;
+}
+
class UTF8BufferI : public UTF8Buffer
{
@@ -68,18 +311,27 @@ public:
if(_buffer == 0)
{
_buffer = static_cast<Byte*>(malloc(howMany));
+ if(!_buffer)
+ {
+ throw std::bad_alloc();
+ }
}
else
{
assert(firstUnused != 0);
_offset = firstUnused - _buffer;
- _buffer = static_cast<Byte*>(realloc(_buffer, _offset + howMany));
- }
-
- if(!_buffer)
- {
- throw std::bad_alloc();
+ Byte* newBuffer = static_cast<Byte*>(realloc(_buffer, _offset + howMany));
+ if(!newBuffer)
+ {
+ reset();
+ throw std::bad_alloc();
+ }
+ else
+ {
+ _buffer = newBuffer;
+ }
}
+
return _buffer + _offset;
}
@@ -94,94 +346,13 @@ public:
_buffer = 0;
_offset = 0;
}
-
+
private:
- IceUtil::Byte* _buffer;
+ Byte* _buffer;
size_t _offset;
};
-}
-
-
-
-UnicodeWstringConverter::UnicodeWstringConverter(ConversionFlags flags) :
- _conversionFlags(flags)
-{
-}
-
-Byte*
-UnicodeWstringConverter::toUTF8(const wchar_t* sourceStart,
- const wchar_t* sourceEnd,
- UTF8Buffer& buffer) const
-{
- //
- // The "chunk size" is the maximum of the number of characters in the
- // source and 6 (== max bytes necessary to encode one Unicode character).
- //
- size_t chunkSize = std::max<size_t>(static_cast<size_t>(sourceEnd - sourceStart), 6);
-
- Byte* targetStart = buffer.getMoreBytes(chunkSize, 0);
- Byte* targetEnd = targetStart + chunkSize;
-
- ConversionResult result;
-
- while((result =
- convertUTFWstringToUTF8(sourceStart, sourceEnd,
- targetStart, targetEnd, _conversionFlags))
- == targetExhausted)
- {
- targetStart = buffer.getMoreBytes(chunkSize, targetStart);
- targetEnd = targetStart + chunkSize;
- }
-
- switch(result)
- {
- case conversionOK:
- break;
- case sourceExhausted:
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__, "wide string source exhausted");
- case sourceIllegal:
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__, "wide string source illegal");
- default:
- {
- assert(0);
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__);
- }
- }
- return targetStart;
-}
-
-
-void
-UnicodeWstringConverter::fromUTF8(const Byte* sourceStart, const Byte* sourceEnd,
- wstring& target) const
-{
- if(sourceStart == sourceEnd)
- {
- target = L"";
- return;
- }
-
- ConversionResult result =
- convertUTF8ToUTFWstring(sourceStart, sourceEnd, target, _conversionFlags);
-
- switch(result)
- {
- case conversionOK:
- break;
- case sourceExhausted:
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__, "UTF-8 string source exhausted");
- case sourceIllegal:
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__, "UTF-8 string source illegal");
- default:
- {
- assert(0);
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__);
- }
- }
-}
-
#ifdef _WIN32
WindowsStringConverter::WindowsStringConverter(unsigned int cp) :
_cp(cp)
@@ -205,16 +376,16 @@ WindowsStringConverter::toUTF8(const char* sourceStart,
int size = 0;
int writtenWchar = 0;
ScopedArray<wchar_t> wbuffer;
-
+
//
// The following code pages doesn't support MB_ERR_INVALID_CHARS flag
// see http://msdn.microsoft.com/en-us/library/windows/desktop/dd319072(v=vs.85).aspx
//
DWORD flags =
(_cp == 50220 || _cp == 50221 || _cp == 50222 ||
- _cp == 50225 || _cp == 50227 || _cp == 50229 ||
+ _cp == 50225 || _cp == 50227 || _cp == 50229 ||
_cp == 65000 || _cp == 42 || (_cp >= 57002 && _cp <= 57011)) ? 0 : MB_ERR_INVALID_CHARS;
-
+
do
{
size = size == 0 ? sourceSize + 2 : 2 * size;
@@ -232,7 +403,7 @@ WindowsStringConverter::toUTF8(const char* sourceStart,
//
// Then convert this UTF-16 wbuffer into UTF-8
//
- return _unicodeWstringConverter.toUTF8(wbuffer.get(), wbuffer.get() + writtenWchar, buffer);
+ return getUnicodeWstringConverter()->toUTF8(wbuffer.get(), wbuffer.get() + writtenWchar, buffer);
}
void
@@ -256,7 +427,7 @@ WindowsStringConverter::fromUTF8(const Byte* sourceStart, const Byte* sourceEnd,
// First convert to wstring (UTF-16)
//
wstring wtarget;
- _unicodeWstringConverter.fromUTF8(sourceStart, sourceEnd, wtarget);
+ getUnicodeWstringConverter()->fromUTF8(sourceStart, sourceEnd, wtarget);
//
// WC_ERR_INVALID_CHARS conversion flag is only supported with 65001 (UTF-8) and
@@ -284,7 +455,23 @@ WindowsStringConverter::fromUTF8(const Byte* sourceStart, const Byte* sourceEnd,
target.assign(buffer.get(), writtenChar);
}
+#endif
+
+}
+
+
+WstringConverterPtr
+IceUtil::createUnicodeWstringConverter()
+{
+ return getUnicodeWstringConverter();
+}
+#ifdef _WIN32
+StringConverterPtr
+IceUtil::createWindowsStringConverter(unsigned int cp)
+{
+ return ICE_MAKE_SHARED(WindowsStringConverter, cp);
+}
#endif
@@ -298,8 +485,8 @@ IceUtil::getProcessStringConverter()
void
IceUtil::setProcessStringConverter(const StringConverterPtr& converter)
{
- IceUtilInternal::MutexPtrLock<IceUtil::Mutex> lock(processStringConverterMutex);
- processStringConverter = converter;
+ IceUtilInternal::MutexPtrLock<IceUtil::Mutex> lock(processStringConverterMutex);
+ processStringConverter = converter;
}
WstringConverterPtr
@@ -312,61 +499,33 @@ IceUtil::getProcessWstringConverter()
void
IceUtil::setProcessWstringConverter(const WstringConverterPtr& converter)
{
- IceUtilInternal::MutexPtrLock<IceUtil::Mutex> lock(processStringConverterMutex);
- processWstringConverter = converter;
+ IceUtilInternal::MutexPtrLock<IceUtil::Mutex> lock(processStringConverterMutex);
+ processWstringConverter = converter;
}
string
-IceUtil::wstringToString(const wstring& v, const StringConverterPtr& converter, const WstringConverterPtr& wConverter,
- IceUtil::ConversionFlags flags)
+IceUtil::wstringToString(const wstring& v, const StringConverterPtr& converter, const WstringConverterPtr& wConverter)
{
string target;
if(!v.empty())
{
+ const WstringConverterPtr& wConverterWithDefault = wConverter ? wConverter : getUnicodeWstringConverter();
+
//
- // First convert to UTF8 narrow string.
+ // First convert to UTF-8 narrow string.
//
- if(wConverter)
- {
- UTF8BufferI buffer;
- Byte* last = wConverter->toUTF8(v.data(), v.data() + v.size(), buffer);
- target = string(reinterpret_cast<const char*>(buffer.getBuffer()), last - buffer.getBuffer());
- }
- else
- {
- size_t size = v.size() * 4 * sizeof(char);
-
- Byte* outBuf = new Byte[size];
- Byte* targetStart = outBuf;
- Byte* targetEnd = outBuf + size;
-
- const wchar_t* sourceStart = v.data();
-
- ConversionResult cr =
- convertUTFWstringToUTF8(
- sourceStart, sourceStart + v.size(),
- targetStart, targetEnd, flags);
-
- if(cr != conversionOK)
- {
- delete[] outBuf;
- assert(cr == sourceExhausted || cr == sourceIllegal);
- throw IllegalConversionException(__FILE__, __LINE__,
- cr == sourceExhausted ? "partial character" : "bad encoding");
- }
-
- target = string(reinterpret_cast<char*>(outBuf), static_cast<size_t>(targetStart - outBuf));
- delete[] outBuf;
- }
+ UTF8BufferI buffer;
+ Byte* last = wConverterWithDefault->toUTF8(v.data(), v.data() + v.size(), buffer);
+ target = string(reinterpret_cast<const char*>(buffer.getBuffer()), last - buffer.getBuffer());
//
- // If narrow string converter is present convert to the native narrow string encoding, otherwise
+ // If narrow string converter is present convert to the native narrow string encoding, otherwise
// native narrow string encoding is UTF8 and we are done.
//
if(converter)
{
string tmp;
- converter->fromUTF8(reinterpret_cast<const Byte*>(target.data()),
+ converter->fromUTF8(reinterpret_cast<const Byte*>(target.data()),
reinterpret_cast<const Byte*>(target.data() + target.size()), tmp);
tmp.swap(target);
}
@@ -375,8 +534,8 @@ IceUtil::wstringToString(const wstring& v, const StringConverterPtr& converter,
}
wstring
-IceUtil::stringToWstring(const string& v, const StringConverterPtr& converter,
- const WstringConverterPtr& wConverter, IceUtil::ConversionFlags flags)
+IceUtil::stringToWstring(const string& v, const StringConverterPtr& converter,
+ const WstringConverterPtr& wConverter)
{
wstring target;
if(!v.empty())
@@ -397,29 +556,14 @@ IceUtil::stringToWstring(const string& v, const StringConverterPtr& converter,
tmp = v;
}
+ const WstringConverterPtr& wConverterWithDefault = wConverter ? wConverter : getUnicodeWstringConverter();
+
//
- // If there is a wide string converter use fromUTF8 to convert to the wide string native encoding.
+ // Convert from UTF-8 to the wide string encoding
//
- if(wConverter)
- {
- wConverter->fromUTF8(reinterpret_cast<const Byte*>(tmp.data()),
- reinterpret_cast<const Byte*>(tmp.data() + tmp.size()), target);
- }
- else
- {
- const Byte* sourceStart = reinterpret_cast<const Byte*>(tmp.data());
-
- ConversionResult cr =
- convertUTF8ToUTFWstring(sourceStart, sourceStart + tmp.size(), target, flags);
+ wConverterWithDefault->fromUTF8(reinterpret_cast<const Byte*>(tmp.data()),
+ reinterpret_cast<const Byte*>(tmp.data() + tmp.size()), target);
- if(cr != conversionOK)
- {
- assert(cr == sourceExhausted || cr == sourceIllegal);
-
- throw IllegalConversionException(__FILE__, __LINE__,
- cr == sourceExhausted ? "partial character" : "bad encoding");
- }
- }
}
return target;
}
@@ -430,7 +574,7 @@ IceUtil::nativeToUTF8(const string& str, const IceUtil::StringConverterPtr& conv
if(!converter || str.empty())
{
return str;
- }
+ }
UTF8BufferI buffer;
Byte* last = converter->toUTF8(str.data(), str.data() + str.size(), buffer);
return string(reinterpret_cast<const char*>(buffer.getBuffer()), last - buffer.getBuffer());
@@ -448,3 +592,125 @@ IceUtil::UTF8ToNative(const string& str, const IceUtil::StringConverterPtr& conv
reinterpret_cast<const Byte*>(str.data() + str.size()), tmp);
return tmp;
}
+
+#ifdef ICE_HAS_CODECVT_UTF8
+
+#if defined(_MSC_VER) && (_MSC_VER == 1900)
+//
+// Workaround for compiler bug - see http://stackoverflow.com/questions/32055357
+//
+typedef unsigned short Char16T;
+typedef unsigned int Char32T;
+
+#else
+typedef char16_t Char16T;
+typedef char32_t Char32T;
+#endif
+
+#endif
+
+
+vector<unsigned short>
+IceUtilInternal::toUTF16(const vector<Byte>& source)
+{
+ vector<unsigned short> result;
+ if(!source.empty())
+ {
+
+#ifdef ICE_HAS_CODECVT_UTF8
+ assert(sizeof(Char16T) == sizeof(unsigned short));
+
+#ifdef ICE_LITTLE_ENDIAN
+ typedef wstring_convert<codecvt_utf8_utf16<Char16T, 0x10ffff, little_endian>, Char16T> Convert;
+#else
+ typedef wstring_convert<codecvt_utf8_utf16<Char16T>, Char16T> Convert;
+#endif
+
+ Convert convert;
+
+ try
+ {
+ Convert::wide_string ws = convert.from_bytes(reinterpret_cast<const char*>(&source.front()),
+ reinterpret_cast<const char*>(&source.front() + source.size()));
+
+ result = vector<unsigned short>(reinterpret_cast<const unsigned short*>(ws.data()),
+ reinterpret_cast<const unsigned short*>(ws.data()) + ws.length());
+ }
+ catch(const std::range_error& ex)
+ {
+ throw IllegalConversionException(__FILE__, __LINE__, ex.what());
+ }
+
+#else
+ convertUTF8ToUTF16(source, result);
+#endif
+ }
+ return result;
+}
+
+vector<unsigned int>
+IceUtilInternal::toUTF32(const vector<Byte>& source)
+{
+ vector<unsigned int> result;
+ if(!source.empty())
+ {
+
+#ifdef ICE_HAS_CODECVT_UTF8
+ assert(sizeof(Char32T) == sizeof(unsigned int));
+
+ typedef wstring_convert<codecvt_utf8<Char32T>, Char32T> Convert;
+ Convert convert;
+
+ try
+ {
+ Convert::wide_string ws = convert.from_bytes(reinterpret_cast<const char*>(&source.front()),
+ reinterpret_cast<const char*>(&source.front() + source.size()));
+
+ result = vector<unsigned int>(reinterpret_cast<const unsigned int*>(ws.data()),
+ reinterpret_cast<const unsigned int*>(ws.data()) + ws.length());
+ }
+ catch(const std::range_error& ex)
+ {
+ throw IllegalConversionException(__FILE__, __LINE__, ex.what());
+ }
+
+#else
+ convertUTF8ToUTF32(source, result);
+#endif
+ }
+ return result;
+}
+
+
+vector<Byte>
+IceUtilInternal::fromUTF32(const vector<unsigned int>& source)
+{
+ vector<Byte> result;
+ if(!source.empty())
+ {
+
+#ifdef ICE_HAS_CODECVT_UTF8
+ assert(sizeof(Char32T) == sizeof(unsigned int));
+
+ typedef wstring_convert<codecvt_utf8<Char32T>, Char32T> Convert;
+ Convert convert;
+
+ try
+ {
+ Convert::byte_string bs = convert.to_bytes(reinterpret_cast<const Char32T*>(&source.front()),
+ reinterpret_cast<const Char32T*>(&source.front() + source.size()));
+
+ result = vector<Byte>(reinterpret_cast<const Byte*>(bs.data()),
+ reinterpret_cast<const Byte*>(bs.data()) + bs.length());
+ }
+ catch(const std::range_error& ex)
+ {
+ throw IllegalConversionException(__FILE__, __LINE__, ex.what());
+ }
+
+#else
+ convertUTF32ToUTF8(source, result);
+#endif
+ }
+ return result;
+}
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
diff --git a/cpp/src/IceUtil/Unicode.h b/cpp/src/IceUtil/Unicode.h
index c061ec51da0..24f97424a52 100644
--- a/cpp/src/IceUtil/Unicode.h
+++ b/cpp/src/IceUtil/Unicode.h
@@ -11,51 +11,38 @@
#define ICE_UTIL_UNICODE_H
#include <IceUtil/Config.h>
-#include <IceUtil/StringConverter.h>
+#include <vector>
namespace IceUtilInternal
{
//
-// Converts UTF-8 byte-sequences to and from UTF-16 or UTF-32 (with native
-// endianness) depending on sizeof(wchar_t).
+// Convert UTF-8 byte-sequences to and from UTF-16 or UTF-32 (with native endianness)
//
-// These are thin wrappers over the UTF8/16/32 converters provided by
-// unicode.org
-//
-
-enum ConversionResult
-{
- conversionOK, /* conversion successful */
- sourceExhausted, /* partial character in source, but hit end */
- targetExhausted, /* insuff. room in target for conversion */
- sourceIllegal /* source sequence is illegal/malformed */
-};
+// These are wrappers for Unicode's ConvertUTF.h/cpp.
-ConversionResult
+//
+// Convert wstring encoded with UTF-16 or UTF-32 to UTF-8.
+// Returns false if needs for space and true upon success.
+// Throws IllegalConversionException to report error
+//
+bool
convertUTFWstringToUTF8(const wchar_t*& sourceStart, const wchar_t* sourceEnd,
- IceUtil::Byte*& targetStart, IceUtil::Byte* targetEnd, IceUtil::ConversionFlags flags);
+ IceUtil::Byte*& targetStart, IceUtil::Byte* targetEnd);
-ConversionResult
-convertUTF8ToUTFWstring(const IceUtil::Byte*& sourceStart, const IceUtil::Byte* sourceEnd,
- wchar_t*& targetStart, wchar_t* targetEnd, IceUtil::ConversionFlags flags);
-ConversionResult
+void
convertUTF8ToUTFWstring(const IceUtil::Byte*& sourceStart, const IceUtil::Byte* sourceEnd,
- std::wstring& target, IceUtil::ConversionFlags flags);
-
+ std::wstring& target);
-ICE_API ConversionResult
-convertUTF8ToUTF16(const std::vector<unsigned char>&, std::vector<unsigned short>&,
- IceUtil::ConversionFlags);
+void
+convertUTF8ToUTF16(const std::vector<unsigned char>&, std::vector<unsigned short>&);
-ICE_API ConversionResult
-convertUTF8ToUTF32(const std::vector<unsigned char>&, std::vector<unsigned int>&,
- IceUtil::ConversionFlags);
+void
+convertUTF8ToUTF32(const std::vector<unsigned char>&, std::vector<unsigned int>&);
-ICE_API ConversionResult
-convertUTF32ToUTF8(const std::vector<unsigned int>&, std::vector<unsigned char>&,
- IceUtil::ConversionFlags);
+void
+convertUTF32ToUTF8(const std::vector<unsigned int>&, std::vector<unsigned char>&);
}
diff --git a/cpp/src/IceUtil/UtilException.cpp b/cpp/src/IceUtil/UtilException.cpp
index 450174ec274..96bcc813958 100644
--- a/cpp/src/IceUtil/UtilException.cpp
+++ b/cpp/src/IceUtil/UtilException.cpp
@@ -74,7 +74,12 @@ using namespace std;
namespace IceUtilInternal
{
+#ifdef NDEBUG
bool ICE_API printStackTraces = false;
+#else
+bool ICE_API printStackTraces = true;
+#endif
+
bool ICE_API nullHandleAbort = false;
StackTraceImpl
@@ -477,7 +482,7 @@ getStackTrace(const vector<void*>& stackFrames)
{
s << " at "
#ifdef DBGHELP_TRANSLATE_TCHAR
- << IceUtil::wstringToString(line.FileName, converter)
+ << IceUtil::wstringToString(line.FileName, converter)
#else
<< line.FileName
#endif
diff --git a/cpp/src/IceUtil/msbuild/iceutil/iceutil.vcxproj b/cpp/src/IceUtil/msbuild/iceutil/iceutil.vcxproj
index 397b85c6b3c..320b34b7f10 100644
--- a/cpp/src/IceUtil/msbuild/iceutil/iceutil.vcxproj
+++ b/cpp/src/IceUtil/msbuild/iceutil/iceutil.vcxproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
@@ -83,7 +83,6 @@
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
- <ClCompile Include="..\..\ConvertUTF.cpp" />
<ClCompile Include="..\..\CtrlCHandler.cpp" />
<ClCompile Include="..\..\OutputUtil.cpp" />
<ClCompile Include="..\..\RecMutex.cpp" />
@@ -97,7 +96,6 @@
<ClCompile Include="..\..\Random.cpp" />
<ClCompile Include="..\..\Shared.cpp" />
<ClCompile Include="..\..\StringUtil.cpp" />
- <ClCompile Include="..\..\Unicode.cpp" />
<ClCompile Include="..\..\UUID.cpp" />
</ItemGroup>
<ItemGroup>
@@ -142,11 +140,9 @@
<ClInclude Include="..\..\..\..\include\IceUtil\UniquePtr.h" />
<ClInclude Include="..\..\..\..\include\IceUtil\UUID.h" />
<ClInclude Include="..\..\ArgVector.h" />
- <ClInclude Include="..\..\ConvertUTF.h" />
<ClInclude Include="..\..\StopWatch.h" />
- <ClInclude Include="..\..\Unicode.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
-</Project> \ No newline at end of file
+</Project>
diff --git a/cpp/src/IceUtil/msbuild/iceutil/iceutil.vcxproj.filters b/cpp/src/IceUtil/msbuild/iceutil/iceutil.vcxproj.filters
index 0370d470a60..553d622f4d9 100644
--- a/cpp/src/IceUtil/msbuild/iceutil/iceutil.vcxproj.filters
+++ b/cpp/src/IceUtil/msbuild/iceutil/iceutil.vcxproj.filters
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
@@ -15,9 +15,6 @@
</Filter>
</ItemGroup>
<ItemGroup>
- <ClCompile Include="..\..\ConvertUTF.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
<ClCompile Include="..\..\CtrlCHandler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@@ -42,9 +39,6 @@
<ClCompile Include="..\..\StringUtil.cpp">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="..\..\Unicode.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
<ClCompile Include="..\..\UUID.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@@ -188,14 +182,8 @@
<ClInclude Include="..\..\ArgVector.h">
<Filter>Header Files</Filter>
</ClInclude>
- <ClInclude Include="..\..\ConvertUTF.h">
- <Filter>Header Files</Filter>
- </ClInclude>
<ClInclude Include="..\..\StopWatch.h">
<Filter>Header Files</Filter>
</ClInclude>
- <ClInclude Include="..\..\Unicode.h">
- <Filter>Header Files</Filter>
- </ClInclude>
</ItemGroup>
-</Project> \ No newline at end of file
+</Project>
diff --git a/cpp/src/Slice/PythonUtil.cpp b/cpp/src/Slice/PythonUtil.cpp
index eb637229825..f04ccfcb4c7 100644
--- a/cpp/src/Slice/PythonUtil.cpp
+++ b/cpp/src/Slice/PythonUtil.cpp
@@ -13,7 +13,7 @@
#include <IceUtil/IceUtil.h>
#include <IceUtil/StringUtil.h>
#include <IceUtil/InputUtil.h>
-#include <IceUtil/Unicode.h>
+#include <IceUtil/StringConverter.h>
#include <climits>
#include <iterator>
@@ -1897,22 +1897,7 @@ Slice::Python::CodeVisitor::writeConstantValue(const TypePtr& type, const Syntax
vector<unsigned int> u32buffer;
u32buffer.push_back(static_cast<unsigned int>(v));
- vector<unsigned char> u8buffer;
- IceUtilInternal::ConversionResult result = convertUTF32ToUTF8(u32buffer, u8buffer, IceUtil::lenientConversion);
- switch(result)
- {
- case conversionOK:
- break;
- case sourceExhausted:
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__, "string source exhausted");
- case sourceIllegal:
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__, "string source illegal");
- default:
- {
- assert(0);
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__);
- }
- }
+ vector<unsigned char> u8buffer = fromUTF32(u32buffer);
ostringstream s;
for(vector<unsigned char>::const_iterator q = u8buffer.begin(); q != u8buffer.end(); ++q)
diff --git a/cpp/src/Slice/RubyUtil.cpp b/cpp/src/Slice/RubyUtil.cpp
index d262e416f05..8d2efd8a0e1 100644
--- a/cpp/src/Slice/RubyUtil.cpp
+++ b/cpp/src/Slice/RubyUtil.cpp
@@ -12,7 +12,7 @@
#include <Slice/Util.h>
#include <IceUtil/Functional.h>
#include <IceUtil/InputUtil.h>
-#include <IceUtil/Unicode.h>
+#include <IceUtil/StringConverter.h>
#include <iterator>
using namespace std;
@@ -1508,22 +1508,7 @@ Slice::Ruby::CodeVisitor::writeConstantValue(const TypePtr& type, const SyntaxTr
vector<unsigned int> u32buffer;
u32buffer.push_back(static_cast<unsigned int>(v));
- vector<unsigned char> u8buffer;
- IceUtilInternal::ConversionResult result = convertUTF32ToUTF8(u32buffer, u8buffer, IceUtil::lenientConversion);
- switch(result)
- {
- case conversionOK:
- break;
- case sourceExhausted:
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__, "string source exhausted");
- case sourceIllegal:
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__, "string source illegal");
- default:
- {
- assert(0);
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__);
- }
- }
+ vector<unsigned char> u8buffer = fromUTF32(u32buffer);
ostringstream s;
for(vector<unsigned char>::const_iterator q = u8buffer.begin(); q != u8buffer.end(); ++q)
diff --git a/cpp/src/slice2cpp/Gen.cpp b/cpp/src/slice2cpp/Gen.cpp
index b3998b54051..0f603adfe61 100644
--- a/cpp/src/slice2cpp/Gen.cpp
+++ b/cpp/src/slice2cpp/Gen.cpp
@@ -14,7 +14,7 @@
#include <IceUtil/Functional.h>
#include <IceUtil/Iterator.h>
#include <IceUtil/InputUtil.h>
-#include <IceUtil/Unicode.h>
+#include <IceUtil/StringConverter.h>
#include <Slice/Checksum.h>
#include <Slice/FileTracker.h>
@@ -132,22 +132,7 @@ u32CodePoint(unsigned int value, bool cpp11)
void
writeU8Buffer(const vector<unsigned char>& u8buffer, ::IceUtilInternal::Output& out, bool cpp11)
{
- vector<unsigned int> u32buffer;
- IceUtilInternal::ConversionResult result = convertUTF8ToUTF32(u8buffer, u32buffer, IceUtil::lenientConversion);
- switch(result)
- {
- case conversionOK:
- break;
- case sourceExhausted:
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__, "string source exhausted");
- case sourceIllegal:
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__, "string source illegal");
- default:
- {
- assert(0);
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__);
- }
- }
+ vector<unsigned int> u32buffer = toUTF32(u8buffer);
for(vector<unsigned int>::const_iterator c = u32buffer.begin(); c != u32buffer.end(); ++c)
{
@@ -353,23 +338,7 @@ writeConstantValue(IceUtilInternal::Output& out, const TypePtr& type, const Synt
vector<unsigned int> u32buffer;
u32buffer.push_back(static_cast<unsigned int>(v));
- vector<unsigned char> u8buffer;
-
- IceUtilInternal::ConversionResult result = convertUTF32ToUTF8(u32buffer, u8buffer, IceUtil::lenientConversion);
- switch(result)
- {
- case conversionOK:
- break;
- case sourceExhausted:
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__, "string source exhausted");
- case sourceIllegal:
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__, "string source illegal");
- default:
- {
- assert(0);
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__);
- }
- }
+ vector<unsigned char> u8buffer = fromUTF32(u32buffer);
ostringstream s;
for(vector<unsigned char>::const_iterator q = u8buffer.begin(); q != u8buffer.end(); ++q)
diff --git a/cpp/src/slice2cs/Gen.cpp b/cpp/src/slice2cs/Gen.cpp
index 7643c33081e..0e87c4c6050 100644
--- a/cpp/src/slice2cs/Gen.cpp
+++ b/cpp/src/slice2cs/Gen.cpp
@@ -24,7 +24,7 @@
#include <IceUtil/Iterator.h>
#include <IceUtil/UUID.h>
-#include <IceUtil/Unicode.h>
+#include <IceUtil/StringConverter.h>
#include <Slice/Checksum.h>
#include <Slice/FileTracker.h>
#include <Slice/Util.h>
@@ -55,22 +55,7 @@ u16CodePoint(unsigned short value)
void
writeU8Buffer(const vector<unsigned char>& u8buffer, ::IceUtilInternal::Output& out)
{
- vector<unsigned short> u16buffer;
- IceUtilInternal::ConversionResult result = convertUTF8ToUTF16(u8buffer, u16buffer, IceUtil::lenientConversion);
- switch(result)
- {
- case conversionOK:
- break;
- case sourceExhausted:
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__, "string source exhausted");
- case sourceIllegal:
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__, "string source illegal");
- default:
- {
- assert(0);
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__);
- }
- }
+ vector<unsigned short> u16buffer = toUTF16(u8buffer);
for(vector<unsigned short>::const_iterator c = u16buffer.begin(); c != u16buffer.end(); ++c)
{
@@ -3300,7 +3285,7 @@ Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p)
_out << sp << nl << "#endregion"; // Constructors
- _out << sp;
+ _out << sp;
emitGeneratedCodeAttribute();
_out << nl << "public override string ice_id()";
_out << sb;
diff --git a/cpp/src/slice2java/Gen.cpp b/cpp/src/slice2java/Gen.cpp
index 97f46017c45..14d6acad2a0 100644
--- a/cpp/src/slice2java/Gen.cpp
+++ b/cpp/src/slice2java/Gen.cpp
@@ -14,7 +14,7 @@
#include <IceUtil/Iterator.h>
#include <IceUtil/StringUtil.h>
#include <IceUtil/InputUtil.h>
-#include <IceUtil/Unicode.h>
+#include <IceUtil/StringConverter.h>
#include <cstring>
#include <limits>
@@ -39,23 +39,8 @@ u16CodePoint(unsigned short value)
void
writeU8Buffer(const vector<unsigned char>& u8buffer, ::IceUtilInternal::Output& out)
{
- vector<unsigned short> u16buffer;
- IceUtilInternal::ConversionResult result = convertUTF8ToUTF16(u8buffer, u16buffer, IceUtil::lenientConversion);
- switch(result)
- {
- case conversionOK:
- break;
- case sourceExhausted:
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__, "string source exhausted");
- case sourceIllegal:
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__, "string source illegal");
- default:
- {
- assert(0);
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__);
- }
- }
-
+ vector<unsigned short> u16buffer = toUTF16(u8buffer);
+
for(vector<unsigned short>::const_iterator c = u16buffer.begin(); c != u16buffer.end(); ++c)
{
out << u16CodePoint(*c);
diff --git a/cpp/src/slice2js/Gen.cpp b/cpp/src/slice2js/Gen.cpp
index 9e55b8b65f2..c2d0cb9209c 100644
--- a/cpp/src/slice2js/Gen.cpp
+++ b/cpp/src/slice2js/Gen.cpp
@@ -20,7 +20,7 @@
#include <direct.h>
#endif
#include <IceUtil/Iterator.h>
-#include <IceUtil/Unicode.h>
+#include <IceUtil/StringConverter.h>
#include <IceUtil/UUID.h>
#include <Slice/Checksum.h>
#include <Slice/FileTracker.h>
@@ -50,23 +50,8 @@ u16CodePoint(unsigned short value)
void
writeU8Buffer(const vector<unsigned char>& u8buffer, ::IceUtilInternal::Output& out)
{
- vector<unsigned short> u16buffer;
- IceUtilInternal::ConversionResult result = convertUTF8ToUTF16(u8buffer, u16buffer, IceUtil::lenientConversion);
- switch(result)
- {
- case conversionOK:
- break;
- case sourceExhausted:
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__, "string source exhausted");
- case sourceIllegal:
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__, "string source illegal");
- default:
- {
- assert(0);
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__);
- }
- }
-
+ vector<unsigned short> u16buffer = toUTF16(u8buffer);
+
for(vector<unsigned short>::const_iterator c = u16buffer.begin(); c != u16buffer.end(); ++c)
{
out << u16CodePoint(*c);
diff --git a/cpp/src/slice2objc/Gen.cpp b/cpp/src/slice2objc/Gen.cpp
index 6659b98ebbf..28c0b04cbe8 100644
--- a/cpp/src/slice2objc/Gen.cpp
+++ b/cpp/src/slice2objc/Gen.cpp
@@ -17,7 +17,7 @@
#include <direct.h>
#endif
#include <IceUtil/Iterator.h>
-#include <IceUtil/Unicode.h>
+#include <IceUtil/StringConverter.h>
#include <IceUtil/InputUtil.h>
#include <IceUtil/UUID.h>
#include <Slice/Checksum.h>
@@ -1589,23 +1589,7 @@ Slice::Gen::TypesVisitor::writeConstantValue(IceUtilInternal::Output& out, const
vector<unsigned int> u32buffer;
u32buffer.push_back(static_cast<unsigned int>(v));
- vector<unsigned char> u8buffer;
-
- IceUtilInternal::ConversionResult result = convertUTF32ToUTF8(u32buffer, u8buffer, IceUtil::lenientConversion);
- switch(result)
- {
- case conversionOK:
- break;
- case sourceExhausted:
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__, "string source exhausted");
- case sourceIllegal:
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__, "string source illegal");
- default:
- {
- assert(0);
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__);
- }
- }
+ vector<unsigned char> u8buffer = fromUTF32(u32buffer);
ostringstream s;
for(vector<unsigned char>::const_iterator q = u8buffer.begin(); q != u8buffer.end(); ++q)
diff --git a/cpp/src/slice2php/Main.cpp b/cpp/src/slice2php/Main.cpp
index 35117e68f36..a1689dc5c25 100644
--- a/cpp/src/slice2php/Main.cpp
+++ b/cpp/src/slice2php/Main.cpp
@@ -16,7 +16,7 @@
#include <IceUtil/StringUtil.h>
#include <IceUtil/Mutex.h>
#include <IceUtil/MutexPtrLock.h>
-#include <IceUtil/Unicode.h>
+#include <IceUtil/StringConverter.h>
#include <Slice/Checksum.h>
#include <Slice/Preprocessor.h>
#include <Slice/FileTracker.h>
@@ -393,10 +393,10 @@ CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
_out << nl << "return $proxy->ice_uncheckedCast('" << scoped << "', $facet);";
_out << eb;
- _out << sp << nl << "public static function ice_staticId()";
- _out << sb;
- _out << nl << "return '" << scoped << "';";
- _out << eb;
+ _out << sp << nl << "public static function ice_staticId()";
+ _out << sb;
+ _out << nl << "return '" << scoped << "';";
+ _out << eb;
_out << eb;
}
@@ -1327,23 +1327,7 @@ CodeVisitor::writeConstantValue(const TypePtr& type, const SyntaxTreeBasePtr& va
vector<unsigned int> u32buffer;
u32buffer.push_back(static_cast<unsigned int>(v));
- vector<unsigned char> u8buffer;
-
- IceUtilInternal::ConversionResult result = convertUTF32ToUTF8(u32buffer, u8buffer, IceUtil::lenientConversion);
- switch(result)
- {
- case conversionOK:
- break;
- case sourceExhausted:
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__, "string source exhausted");
- case sourceIllegal:
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__, "string source illegal");
- default:
- {
- assert(0);
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__);
- }
- }
+ vector<unsigned char> u8buffer = fromUTF32(u32buffer);
ostringstream s;
for(vector<unsigned char>::const_iterator q = u8buffer.begin(); q != u8buffer.end(); ++q)