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:
Yoshi Cheng-Hao Huang 2021-10-25 18:23:11 +00:00
Родитель a946af09ec
Коммит 2a45093834
2 изменённых файлов: 23 добавлений и 28 удалений

Просмотреть файл

@ -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);