summaryrefslogtreecommitdiff
path: root/cpp/src/IceUtil/Unicode.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/IceUtil/Unicode.cpp')
-rw-r--r--cpp/src/IceUtil/Unicode.cpp192
1 files changed, 97 insertions, 95 deletions
diff --git a/cpp/src/IceUtil/Unicode.cpp b/cpp/src/IceUtil/Unicode.cpp
index 78e50b26e21..a82fc3b772c 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;
@@ -20,39 +30,30 @@ 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, ConversionFlags flags);
+template<size_t wcharSize> struct WstringHelper;
- 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)
+ 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, flags);
+ &targetStart, targetEnd, lenientConversion);
}
-
+
static ConversionResult fromUTF8(
- const Byte*& sourceStart, const Byte* sourceEnd,
- wchar_t*& targetStart, wchar_t* targetEnd, ConversionFlags flags)
+ const Byte*& sourceStart, const Byte* sourceEnd,
+ wchar_t*& targetStart, wchar_t* targetEnd)
{
return ConvertUTF8toUTF16(
&sourceStart, sourceEnd,
reinterpret_cast<UTF16**>(&targetStart),
- reinterpret_cast<UTF16*>(targetEnd), flags);
+ reinterpret_cast<UTF16*>(targetEnd), lenientConversion);
}
};
@@ -60,128 +61,129 @@ template<>
struct WstringHelper<4>
{
static ConversionResult toUTF8(
- const wchar_t*& sourceStart, const wchar_t* sourceEnd,
- Byte*& targetStart, Byte* targetEnd, ConversionFlags flags)
+ 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, flags);
+ &targetStart, targetEnd, lenientConversion);
}
-
+
static ConversionResult fromUTF8(
- const Byte*& sourceStart, const Byte* sourceEnd,
- wchar_t*& targetStart, wchar_t* targetEnd, ConversionFlags flags)
+ const Byte*& sourceStart, const Byte* sourceEnd,
+ wchar_t*& targetStart, wchar_t* targetEnd)
{
return ConvertUTF8toUTF32(
&sourceStart, sourceEnd,
reinterpret_cast<UTF32**>(&targetStart),
- reinterpret_cast<UTF32*>(targetEnd), flags);
+ 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__);
+ }
+ }
+}
}
//
// convertXXX functions
//
-ConversionResult
-IceUtilInternal::convertUTFWstringToUTF8(
- const wchar_t*& sourceStart, const wchar_t* sourceEnd,
- Byte*& targetStart, Byte* targetEnd, ConversionFlags flags)
+bool
+IceUtilInternal::convertUTFWstringToUTF8(const wchar_t*& sourceStart, const wchar_t* sourceEnd,
+ Byte*& targetStart, Byte* targetEnd)
{
- return WstringHelper<sizeof(wchar_t)>::toUTF8(
- sourceStart, sourceEnd, targetStart, targetEnd, flags);
-}
+ ConversionResult result = WstringHelper<sizeof(wchar_t)>::toUTF8(
+ sourceStart, sourceEnd, targetStart, targetEnd);
-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);
+ if(result == targetExhausted)
+ {
+ return false;
+ }
+ else
+ {
+ checkResult(result);
+ return true;
+ }
}
-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* targetEnd = targetStart + size;
-
- ConversionResult result =
- convertUTF8ToUTFWstring(sourceStart, sourceEnd, targetStart,
- targetEnd, flags);
-
- if(result == conversionOK)
- {
- std::wstring s(outBuf, static_cast<size_t>(targetStart - outBuf));
- s.swap(target);
- }
- delete[] outBuf;
- return result;
+ size_t sourceSize = static_cast<size_t>(sourceEnd - sourceStart);
+
+ target.resize(sourceSize);
+ wchar_t* targetStart = const_cast<wchar_t*>(target.data());
+ wchar_t* targetEnd = targetStart + sourceSize;
+
+ ConversionResult result = WstringHelper<sizeof(wchar_t)>::fromUTF8(sourceStart, sourceEnd,
+ targetStart, targetEnd);
+
+ checkResult(result);
+ target.resize(targetStart - target.data());
}
-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