lib/icu/Error: std::system_error with UErrorCode

This commit is contained in:
Max Kellermann 2022-11-29 06:22:36 +01:00
parent 8ad0d919b1
commit cf762f2a9d
6 changed files with 74 additions and 15 deletions

View File

@ -22,8 +22,8 @@
#include "config.h"
#ifdef HAVE_ICU
#include "Error.hxx"
#include "Util.hxx"
#include "util/RuntimeError.hxx"
#include <unicode/ucol.h>
#include <unicode/ustring.h>
@ -62,8 +62,7 @@ IcuCollateInit()
UErrorCode code = U_ZERO_ERROR;
collator = ucol_open("", &code);
if (collator == nullptr)
throw FormatRuntimeError("ucol_open() failed: %s",
u_errorName(code));
throw ICU::MakeError(code, "ucol_open() failed");
}
void

View File

@ -30,6 +30,7 @@
#include <string.h>
#ifdef HAVE_ICU
#include "Error.hxx"
#include "Util.hxx"
#include "util/AllocatedArray.hxx"
#include <unicode/ucnv.h>
@ -55,8 +56,9 @@ IcuConverter::Create(const char *charset)
UErrorCode code = U_ZERO_ERROR;
UConverter *converter = ucnv_open(charset, &code);
if (converter == nullptr)
throw std::runtime_error(FmtBuffer<256>(FMT_STRING("Failed to initialize charset '{}': {}"),
charset, u_errorName(code)));
throw ICU::MakeError(code,
FmtBuffer<256>(FMT_STRING("Failed to initialize charset '{}'"),
charset));
return std::unique_ptr<IcuConverter>(new IcuConverter(converter));
#elif defined(HAVE_ICONV)
@ -120,8 +122,7 @@ IcuConverter::ToUTF8(std::string_view s) const
&source, source + s.size(),
nullptr, true, &code);
if (code != U_ZERO_ERROR)
throw std::runtime_error(FmtBuffer<256>(FMT_STRING("Failed to convert to Unicode: {}"),
u_errorName(code)));
throw ICU::MakeError(code, "Failed to convert to Unicode");
const size_t target_length = target - buffer;
return UCharToUTF8({buffer, target_length});
@ -150,8 +151,7 @@ IcuConverter::FromUTF8(std::string_view s) const
nullptr, true, &code);
if (code != U_ZERO_ERROR)
throw std::runtime_error(FmtBuffer<256>(FMT_STRING("Failed to convert from Unicode: {}"),
u_errorName(code)));
throw ICU::MakeError(code, "Failed to convert from Unicode");
return {{buffer, size_t(target - buffer)}};

57
src/lib/icu/Error.hxx Normal file
View File

@ -0,0 +1,57 @@
/*
* Copyright 2022 Max Kellermann <max.kellermann@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include <unicode/utypes.h>
#include <system_error>
namespace ICU {
class ErrorCategory final : public std::error_category {
public:
const char *name() const noexcept override {
return "icu";
}
std::string message(int condition) const override {
return u_errorName(static_cast<UErrorCode>(condition));
}
};
inline ErrorCategory error_category;
inline std::system_error
MakeError(UErrorCode code, const char *msg) noexcept
{
return std::system_error(static_cast<int>(code), error_category, msg);
}
} // namespace Curl

View File

@ -20,6 +20,7 @@
#include "Init.hxx"
#include "Collate.hxx"
#include "Canonicalize.hxx"
#include "Error.hxx"
#include "util/RuntimeError.hxx"
#include <unicode/uclean.h>
@ -30,8 +31,7 @@ IcuInit()
UErrorCode code = U_ZERO_ERROR;
u_init(&code);
if (U_FAILURE(code))
throw FormatRuntimeError("u_init() failed: %s",
u_errorName(code));
throw ICU::MakeError(code, "u_init() failed");
IcuCollateInit();
IcuCanonicalizeInit();

View File

@ -18,6 +18,7 @@
*/
#include "Transliterator.hxx"
#include "Error.hxx"
#include "util/AllocatedArray.hxx"
#include <algorithm> // for std::copy()
@ -34,7 +35,7 @@ OpenTransliterator(std::basic_string_view<UChar> id,
rules.data(), rules.size(),
nullptr, &error_code);
if (t == nullptr)
throw std::runtime_error(u_errorName(error_code));
throw ICU::MakeError(error_code, "utrans_openU() failed");
return t;
}

View File

@ -18,6 +18,7 @@
*/
#include "Util.hxx"
#include "Error.hxx"
#include "util/AllocatedString.hxx"
#include "util/AllocatedArray.hxx"
@ -25,7 +26,6 @@
#include <cassert>
#include <memory>
#include <stdexcept>
#include <string.h>
@ -41,7 +41,8 @@ UCharFromUTF8(std::string_view src)
src.data(), src.size(),
&error_code);
if (U_FAILURE(error_code))
throw std::runtime_error(u_errorName(error_code));
throw ICU::MakeError(error_code,
"Conversion from UTF-8 failed");
dest.SetSize(dest_length);
return dest;
@ -61,7 +62,8 @@ UCharToUTF8(std::basic_string_view<UChar> src)
src.data(), src.size(),
&error_code);
if (U_FAILURE(error_code))
throw std::runtime_error(u_errorName(error_code));
throw ICU::MakeError(error_code,
"Conversion to UTF-8 failed");
dest[dest_length] = 0;
return AllocatedString::Donate(dest.release());