зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1719542 - Part 1: Collator::GetSortKey calls FillBufferWithICUCall. r=platform-i18n-reviewers,anba,gregtatum
Make GetSortKey call FillBufferWithICUCall so we have the same behavior when resizeing the buffer. Differential Revision: https://phabricator.services.mozilla.com/D128998
This commit is contained in:
Родитель
a946af09ec
Коммит
2a45093834
|
@ -40,33 +40,27 @@ class Collator final {
|
|||
|
||||
template <typename B>
|
||||
ICUResult GetSortKey(Span<const char16_t> aString, B& aBuffer) const {
|
||||
static_assert(std::is_same_v<typename B::CharType, uint8_t>,
|
||||
"Expected a uint8_t* buffer.");
|
||||
// Do not use FillBufferWithICUCall, as this API does not report the
|
||||
// U_BUFFER_OVERFLOW_ERROR. The return value is always the number of bytes
|
||||
// needed, regardless of whether the result buffer was big enough.
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
int32_t length =
|
||||
ucol_getSortKey(mCollator.GetConst(), aString.data(),
|
||||
static_cast<int32_t>(aString.size()), nullptr, 0);
|
||||
if (U_FAILURE(status) || length == 0) {
|
||||
// If the length is 0, and internal error occurred according to the docs.
|
||||
return Err(ICUError::InternalError);
|
||||
}
|
||||
|
||||
if (!aBuffer.reserve(length)) {
|
||||
return Err(ICUError::OutOfMemory);
|
||||
}
|
||||
|
||||
length = ucol_getSortKey(mCollator.GetConst(), aString.data(),
|
||||
aString.size(), aBuffer.data(), length);
|
||||
|
||||
if (U_FAILURE(status) || length == 0) {
|
||||
return Err(ICUError::InternalError);
|
||||
}
|
||||
|
||||
aBuffer.written(length);
|
||||
return Ok();
|
||||
return FillBufferWithICUCall(
|
||||
aBuffer,
|
||||
[this, aString](uint8_t* target, int32_t length, UErrorCode* status) {
|
||||
// ucol_getSortKey doesn't use the error code to report
|
||||
// U_BUFFER_OVERFLOW_ERROR, instead it uses the return value to
|
||||
// indicate the desired length to store the key. So we update the
|
||||
// UErrorCode accordingly to let FillBufferWithICUCall resize the
|
||||
// buffer.
|
||||
int32_t len = ucol_getSortKey(mCollator.GetConst(), aString.data(),
|
||||
static_cast<int32_t>(aString.size()),
|
||||
target, length);
|
||||
if (len == 0) {
|
||||
// Returns 0 means there's an internal error.
|
||||
*status = U_INTERNAL_PROGRAM_ERROR;
|
||||
} else if (len > length) {
|
||||
*status = U_BUFFER_OVERFLOW_ERROR;
|
||||
} else {
|
||||
*status = U_ZERO_ERROR;
|
||||
}
|
||||
return len;
|
||||
});
|
||||
}
|
||||
|
||||
int32_t CompareStrings(Span<const char16_t> aSource,
|
||||
|
|
|
@ -130,7 +130,8 @@ template <typename ICUStringFunction, typename Buffer>
|
|||
static ICUResult FillBufferWithICUCall(Buffer& buffer,
|
||||
const ICUStringFunction& strFn) {
|
||||
static_assert(std::is_same_v<typename Buffer::CharType, char16_t> ||
|
||||
std::is_same_v<typename Buffer::CharType, char>);
|
||||
std::is_same_v<typename Buffer::CharType, char> ||
|
||||
std::is_same_v<typename Buffer::CharType, uint8_t>);
|
||||
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
int32_t length = strFn(buffer.data(), buffer.capacity(), &status);
|
||||
|
|
Загрузка…
Ссылка в новой задаче