lib/icu/Win32: throw exception on error

This commit is contained in:
Max Kellermann
2016-04-13 11:51:01 +02:00
parent e228144159
commit b9f535cd49
6 changed files with 72 additions and 40 deletions

View File

@@ -42,6 +42,7 @@
#endif
#include <memory>
#include <stdexcept>
#include <assert.h>
#include <string.h>
@@ -108,12 +109,24 @@ IcuCollate(const char *a, const char *b)
#endif
#elif defined(WIN32)
const auto wa = MultiByteToWideChar(CP_UTF8, a);
const auto wb = MultiByteToWideChar(CP_UTF8, b);
if (wa.IsNull())
return wb.IsNull() ? 0 : -1;
else if (wb.IsNull())
AllocatedString<wchar_t> wa = nullptr, wb = nullptr;
try {
wa = MultiByteToWideChar(CP_UTF8, a);
} catch (const std::runtime_error &) {
try {
wb = MultiByteToWideChar(CP_UTF8, b);
return -1;
} catch (const std::runtime_error &) {
return 0;
}
}
try {
wb = MultiByteToWideChar(CP_UTF8, b);
} catch (const std::runtime_error &) {
return 1;
}
auto result = CompareStringEx(LOCALE_NAME_INVARIANT,
LINGUISTIC_IGNORECASE,
@@ -134,7 +147,7 @@ IcuCollate(const char *a, const char *b)
AllocatedString<>
IcuCaseFold(const char *src)
{
try {
#ifdef HAVE_ICU
assert(collator != nullptr);
#if !CLANG_CHECK_VERSION(3,6)
@@ -161,8 +174,6 @@ IcuCaseFold(const char *src)
#elif defined(WIN32)
const auto u = MultiByteToWideChar(CP_UTF8, src);
if (u.IsNull())
return AllocatedString<>::Duplicate(src);
const int size = LCMapStringEx(LOCALE_NAME_INVARIANT,
LCMAP_SORTKEY|LINGUISTIC_IGNORECASE,
@@ -178,11 +189,7 @@ IcuCaseFold(const char *src)
nullptr, nullptr, 0) <= 0)
return AllocatedString<>::Duplicate(src);
auto result = WideCharToMultiByte(CP_UTF8, buffer.get());
if (result.IsNull())
return AllocatedString<>::Duplicate(src);
return result;
return WideCharToMultiByte(CP_UTF8, buffer.get());
#else
size_t size = strlen(src) + 1;
@@ -201,5 +208,6 @@ IcuCaseFold(const char *src)
return AllocatedString<>::Donate(buffer.release());
#endif
} catch (const std::runtime_error &) {
return AllocatedString<>::Duplicate(src);
}

View File

@@ -19,6 +19,7 @@
#include "config.h"
#include "Win32.hxx"
#include "system/Error.hxx"
#include "util/AllocatedString.hxx"
#include <memory>
@@ -31,14 +32,14 @@ WideCharToMultiByte(unsigned code_page, const wchar_t *src)
int length = WideCharToMultiByte(code_page, 0, src, -1, nullptr, 0,
nullptr, nullptr);
if (length <= 0)
return nullptr;
throw MakeLastError("Failed to convert from Unicode");
std::unique_ptr<char[]> buffer(new char[length]);
length = WideCharToMultiByte(code_page, 0, src, -1,
buffer.get(), length,
nullptr, nullptr);
if (length <= 0)
return nullptr;
throw MakeLastError("Failed to convert from Unicode");
return AllocatedString<char>::Donate(buffer.release());
}
@@ -48,13 +49,13 @@ MultiByteToWideChar(unsigned code_page, const char *src)
{
int length = MultiByteToWideChar(code_page, 0, src, -1, nullptr, 0);
if (length <= 0)
return nullptr;
throw MakeLastError("Failed to convert to Unicode");
std::unique_ptr<wchar_t[]> buffer(new wchar_t[length]);
length = MultiByteToWideChar(code_page, 0, src, -1,
buffer.get(), length);
if (length <= 0)
return nullptr;
throw MakeLastError("Failed to convert to Unicode");
return AllocatedString<wchar_t>::Donate(buffer.release());
}

View File

@@ -27,10 +27,16 @@
template<typename T> class AllocatedString;
/**
* Throws std::system_error on error.
*/
gcc_pure gcc_nonnull_all
AllocatedString<char>
WideCharToMultiByte(unsigned code_page, const wchar_t *src);
/**
* Throws std::system_error on error.
*/
gcc_pure gcc_nonnull_all
AllocatedString<wchar_t>
MultiByteToWideChar(unsigned code_page, const char *src);