mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-24 08:07:30 +09:00
Issue #2046 - Create helper method to call ICU string conversion methods
Based-on: m-c 1333844
This commit is contained in:
parent
50e3c1f5e6
commit
eee13d2653
2 changed files with 78 additions and 173 deletions
|
|
@ -57,6 +57,7 @@ using mozilla::IsNaN;
|
||||||
using mozilla::IsNegativeZero;
|
using mozilla::IsNegativeZero;
|
||||||
using mozilla::PodCopy;
|
using mozilla::PodCopy;
|
||||||
|
|
||||||
|
using js::intl::CallICU;
|
||||||
using js::intl::GetAvailableLocales;
|
using js::intl::GetAvailableLocales;
|
||||||
using js::intl::IcuLocale;
|
using js::intl::IcuLocale;
|
||||||
using js::intl::INITIAL_CHAR_BUFFER_SIZE;
|
using js::intl::INITIAL_CHAR_BUFFER_SIZE;
|
||||||
|
|
@ -1050,33 +1051,9 @@ PartitionNumberPattern(JSContext* cx, UNumberFormat* nf, double* x,
|
||||||
if (IsNegativeZero(*x))
|
if (IsNegativeZero(*x))
|
||||||
*x = 0.0;
|
*x = 0.0;
|
||||||
|
|
||||||
MOZ_ASSERT(formattedChars.length() == 0,
|
return CallICU(cx, formattedChars, [nf, x, fpositer](UChar* chars, int32_t size, UErrorCode* status) {
|
||||||
"formattedChars must initially be empty");
|
return unum_formatDoubleForFields(nf, *x, chars, size, fpositer, status);
|
||||||
MOZ_ALWAYS_TRUE(formattedChars.resize(INITIAL_CHAR_BUFFER_SIZE));
|
}) >= 0;
|
||||||
UErrorCode status = U_ZERO_ERROR;
|
|
||||||
|
|
||||||
int32_t resultSize;
|
|
||||||
resultSize =
|
|
||||||
unum_formatDoubleForFields(nf, *x,
|
|
||||||
Char16ToUChar(formattedChars.begin()), INITIAL_CHAR_BUFFER_SIZE,
|
|
||||||
fpositer, &status);
|
|
||||||
if (status == U_BUFFER_OVERFLOW_ERROR) {
|
|
||||||
if (!formattedChars.resize(size_t(resultSize)))
|
|
||||||
return false;
|
|
||||||
status = U_ZERO_ERROR;
|
|
||||||
#ifdef DEBUG
|
|
||||||
int32_t size =
|
|
||||||
#endif
|
|
||||||
unum_formatDoubleForFields(nf, *x, Char16ToUChar(formattedChars.begin()), resultSize,
|
|
||||||
fpositer, &status);
|
|
||||||
MOZ_ASSERT(size == resultSize);
|
|
||||||
}
|
|
||||||
if (U_FAILURE(status)) {
|
|
||||||
intl::ReportInternalError(cx);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return formattedChars.resize(size_t(resultSize));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
|
@ -2182,30 +2159,10 @@ js::intl_canonicalizeTimeZone(JSContext* cx, unsigned argc, Value* vp)
|
||||||
|
|
||||||
mozilla::Range<const char16_t> tzchars = stableChars.twoByteRange();
|
mozilla::Range<const char16_t> tzchars = stableChars.twoByteRange();
|
||||||
|
|
||||||
Vector<char16_t, INITIAL_CHAR_BUFFER_SIZE> chars(cx);
|
JSString* str = CallICU(cx, [&tzchars](UChar* chars, uint32_t size, UErrorCode* status) {
|
||||||
if (!chars.resize(INITIAL_CHAR_BUFFER_SIZE))
|
return ucal_getCanonicalTimeZoneID(tzchars.begin().get(), tzchars.length(),
|
||||||
return false;
|
chars, size, nullptr, status);
|
||||||
|
});
|
||||||
UBool* isSystemID = nullptr;
|
|
||||||
UErrorCode status = U_ZERO_ERROR;
|
|
||||||
int32_t size = ucal_getCanonicalTimeZoneID(Char16ToUChar(tzchars.begin().get()),
|
|
||||||
tzchars.length(), Char16ToUChar(chars.begin()),
|
|
||||||
INITIAL_CHAR_BUFFER_SIZE, isSystemID, &status);
|
|
||||||
if (status == U_BUFFER_OVERFLOW_ERROR) {
|
|
||||||
MOZ_ASSERT(size >= 0);
|
|
||||||
if (!chars.resize(size_t(size)))
|
|
||||||
return false;
|
|
||||||
status = U_ZERO_ERROR;
|
|
||||||
ucal_getCanonicalTimeZoneID(Char16ToUChar(tzchars.begin().get()), tzchars.length(),
|
|
||||||
Char16ToUChar(chars.begin()), size, isSystemID, &status);
|
|
||||||
}
|
|
||||||
if (U_FAILURE(status)) {
|
|
||||||
intl::ReportInternalError(cx);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
MOZ_ASSERT(size >= 0);
|
|
||||||
JSString* str = NewStringCopyN<CanGC>(cx, chars.begin(), size_t(size));
|
|
||||||
if (!str)
|
if (!str)
|
||||||
return false;
|
return false;
|
||||||
args.rval().setString(str);
|
args.rval().setString(str);
|
||||||
|
|
@ -2223,27 +2180,7 @@ js::intl_defaultTimeZone(JSContext* cx, unsigned argc, Value* vp)
|
||||||
// needed.
|
// needed.
|
||||||
js::ResyncICUDefaultTimeZone();
|
js::ResyncICUDefaultTimeZone();
|
||||||
|
|
||||||
Vector<char16_t, INITIAL_CHAR_BUFFER_SIZE> chars(cx);
|
JSString* str = CallICU(cx, ucal_getDefaultTimeZone);
|
||||||
if (!chars.resize(INITIAL_CHAR_BUFFER_SIZE))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
UErrorCode status = U_ZERO_ERROR;
|
|
||||||
int32_t size = ucal_getDefaultTimeZone(Char16ToUChar(chars.begin()), INITIAL_CHAR_BUFFER_SIZE,
|
|
||||||
&status);
|
|
||||||
if (status == U_BUFFER_OVERFLOW_ERROR) {
|
|
||||||
MOZ_ASSERT(size >= 0);
|
|
||||||
if (!chars.resize(size_t(size)))
|
|
||||||
return false;
|
|
||||||
status = U_ZERO_ERROR;
|
|
||||||
ucal_getDefaultTimeZone(Char16ToUChar(chars.begin()), size, &status);
|
|
||||||
}
|
|
||||||
if (U_FAILURE(status)) {
|
|
||||||
intl::ReportInternalError(cx);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
MOZ_ASSERT(size >= 0);
|
|
||||||
JSString* str = NewStringCopyN<CanGC>(cx, chars.begin(), size_t(size));
|
|
||||||
if (!str)
|
if (!str)
|
||||||
return false;
|
return false;
|
||||||
args.rval().setString(str);
|
args.rval().setString(str);
|
||||||
|
|
@ -2307,25 +2244,11 @@ js::intl_patternForSkeleton(JSContext* cx, unsigned argc, Value* vp)
|
||||||
}
|
}
|
||||||
ScopedICUObject<UDateTimePatternGenerator, udatpg_close> toClose(gen);
|
ScopedICUObject<UDateTimePatternGenerator, udatpg_close> toClose(gen);
|
||||||
|
|
||||||
int32_t size = udatpg_getBestPattern(gen, Char16ToUChar(skeletonChars.begin().get()),
|
JSString* str =
|
||||||
skeletonLen, nullptr, 0, &status);
|
CallICU(cx, [gen, &skeletonChars, skeletonLen](UChar* chars, uint32_t size, UErrorCode* status) {
|
||||||
if (U_FAILURE(status) && status != U_BUFFER_OVERFLOW_ERROR) {
|
return udatpg_getBestPattern(gen, skeletonChars.begin().get(), skeletonLen,
|
||||||
intl::ReportInternalError(cx);
|
chars, size, status);
|
||||||
return false;
|
});
|
||||||
}
|
|
||||||
ScopedJSFreePtr<UChar> pattern(cx->pod_malloc<UChar>(size + 1));
|
|
||||||
if (!pattern)
|
|
||||||
return false;
|
|
||||||
pattern[size] = '\0';
|
|
||||||
status = U_ZERO_ERROR;
|
|
||||||
udatpg_getBestPattern(gen, Char16ToUChar(skeletonChars.begin().get()),
|
|
||||||
skeletonLen, pattern, size, &status);
|
|
||||||
if (U_FAILURE(status)) {
|
|
||||||
intl::ReportInternalError(cx);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
RootedString str(cx, JS_NewUCStringCopyZ(cx, reinterpret_cast<char16_t*>(pattern.get())));
|
|
||||||
if (!str)
|
if (!str)
|
||||||
return false;
|
return false;
|
||||||
args.rval().setString(str);
|
args.rval().setString(str);
|
||||||
|
|
@ -2404,29 +2327,13 @@ intl_FormatDateTime(JSContext* cx, UDateFormat* df, double x, MutableHandleValue
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<char16_t, INITIAL_CHAR_BUFFER_SIZE> chars(cx);
|
JSString* str = CallICU(cx, [df, x](UChar* chars, int32_t size, UErrorCode* status) {
|
||||||
if (!chars.resize(INITIAL_CHAR_BUFFER_SIZE))
|
return udat_format(df, x, chars, size, nullptr, status);
|
||||||
return false;
|
});
|
||||||
UErrorCode status = U_ZERO_ERROR;
|
|
||||||
int size = udat_format(df, x, Char16ToUChar(chars.begin()), INITIAL_CHAR_BUFFER_SIZE,
|
|
||||||
nullptr, &status);
|
|
||||||
if (status == U_BUFFER_OVERFLOW_ERROR) {
|
|
||||||
if (!chars.resize(size))
|
|
||||||
return false;
|
|
||||||
status = U_ZERO_ERROR;
|
|
||||||
udat_format(df, x, Char16ToUChar(chars.begin()), size, nullptr, &status);
|
|
||||||
}
|
|
||||||
if (U_FAILURE(status)) {
|
|
||||||
intl::ReportInternalError(cx);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
JSString* str = NewStringCopyN<CanGC>(cx, chars.begin(), size);
|
|
||||||
if (!str)
|
if (!str)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
result.setString(str);
|
result.setString(str);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2536,33 +2443,22 @@ intl_FormatToPartsDateTime(JSContext* cx, UDateFormat* df, double x, MutableHand
|
||||||
}
|
}
|
||||||
ScopedICUObject<UFieldPositionIterator, ufieldpositer_close> toClose(fpositer);
|
ScopedICUObject<UFieldPositionIterator, ufieldpositer_close> toClose(fpositer);
|
||||||
|
|
||||||
int resultSize =
|
RootedString overallResult(cx);
|
||||||
udat_formatForFields(df, x, Char16ToUChar(chars.begin()), INITIAL_CHAR_BUFFER_SIZE,
|
overallResult = CallICU(cx, [df, x, fpositer](UChar* chars, int32_t size, UErrorCode* status) {
|
||||||
fpositer, &status);
|
return udat_formatForFields(df, x, chars, size, fpositer, status);
|
||||||
if (status == U_BUFFER_OVERFLOW_ERROR) {
|
});
|
||||||
if (!chars.resize(resultSize))
|
if (!overallResult)
|
||||||
return false;
|
|
||||||
status = U_ZERO_ERROR;
|
|
||||||
udat_formatForFields(df, x, Char16ToUChar(chars.begin()), resultSize, fpositer, &status);
|
|
||||||
}
|
|
||||||
if (U_FAILURE(status)) {
|
|
||||||
intl::ReportInternalError(cx);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
RootedArrayObject partsArray(cx, NewDenseEmptyArray(cx));
|
RootedArrayObject partsArray(cx, NewDenseEmptyArray(cx));
|
||||||
if (!partsArray)
|
if (!partsArray)
|
||||||
return false;
|
return false;
|
||||||
if (resultSize == 0) {
|
if (overallResult->length() == 0) {
|
||||||
// An empty string contains no parts, so avoid extra work below.
|
// An empty string contains no parts, so avoid extra work below.
|
||||||
result.setObject(*partsArray);
|
result.setObject(*partsArray);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
RootedString overallResult(cx, NewStringCopyN<CanGC>(cx, chars.begin(), resultSize));
|
|
||||||
if (!overallResult)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
size_t lastEndIndex = 0;
|
size_t lastEndIndex = 0;
|
||||||
|
|
||||||
uint32_t partIndex = 0;
|
uint32_t partIndex = 0;
|
||||||
|
|
@ -2950,23 +2846,9 @@ js::intl_SelectPluralRule(JSContext* cx, unsigned argc, Value* vp)
|
||||||
|
|
||||||
ScopedICUObject<UPluralRules, uplrules_close> closePluralRules(pr);
|
ScopedICUObject<UPluralRules, uplrules_close> closePluralRules(pr);
|
||||||
|
|
||||||
Vector<char16_t, INITIAL_CHAR_BUFFER_SIZE> chars(cx);
|
JSString* str = CallICU(cx, [pr, y](UChar* chars, int32_t size, UErrorCode* status) {
|
||||||
if (!chars.resize(INITIAL_CHAR_BUFFER_SIZE))
|
return uplrules_select(pr, y, chars, size, status);
|
||||||
return false;
|
});
|
||||||
|
|
||||||
int size = uplrules_select(pr, y, Char16ToUChar(chars.begin()), INITIAL_CHAR_BUFFER_SIZE, &status);
|
|
||||||
if (status == U_BUFFER_OVERFLOW_ERROR) {
|
|
||||||
if (!chars.resize(size))
|
|
||||||
return false;
|
|
||||||
status = U_ZERO_ERROR;
|
|
||||||
uplrules_select(pr, y, Char16ToUChar(chars.begin()), size, &status);
|
|
||||||
}
|
|
||||||
if (U_FAILURE(status)) {
|
|
||||||
intl::ReportInternalError(cx);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
JSString* str = NewStringCopyN<CanGC>(cx, chars.begin(), size);
|
|
||||||
if (!str)
|
if (!str)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
@ -3333,21 +3215,17 @@ js::intl_FormatRelativeTime(JSContext* cx, unsigned argc, Value* vp)
|
||||||
intl::ReportInternalError(cx);
|
intl::ReportInternalError(cx);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t size;
|
|
||||||
|
|
||||||
if (relDateTimeNumeric == RelativeTimeNumeric::Auto) {
|
|
||||||
size = ureldatefmt_format(rtf, t, relDateTimeUnit, Char16ToUChar(chars.begin()),
|
|
||||||
INITIAL_CHAR_BUFFER_SIZE, &status);
|
|
||||||
} else {
|
|
||||||
MOZ_ASSERT(relDateTimeNumeric == RelativeTimeNumeric::Always);
|
|
||||||
size = ureldatefmt_formatNumeric(rtf, t, relDateTimeUnit, Char16ToUChar(chars.begin()),
|
|
||||||
INITIAL_CHAR_BUFFER_SIZE, &status);
|
|
||||||
}
|
|
||||||
|
|
||||||
ScopedICUObject<URelativeDateTimeFormatter, ureldatefmt_close> closeRelativeTimeFormat(rtf);
|
ScopedICUObject<URelativeDateTimeFormatter, ureldatefmt_close> closeRelativeTimeFormat(rtf);
|
||||||
|
|
||||||
JSString* str = NewStringCopyN<CanGC>(cx, chars.begin(), size);
|
JSString* str =
|
||||||
|
CallICU(cx, [rtf, t, relDateTimeUnit, relDateTimeNumeric](UChar* chars, int32_t size,
|
||||||
|
UErrorCode* status)
|
||||||
|
{
|
||||||
|
auto fmt = relDateTimeNumeric == RelativeTimeNumeric::Auto
|
||||||
|
? ureldatefmt_format
|
||||||
|
: ureldatefmt_formatNumeric;
|
||||||
|
return fmt(rtf, t, relDateTimeUnit, chars, size, status);
|
||||||
|
});
|
||||||
if (!str)
|
if (!str)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
@ -3699,22 +3577,9 @@ js::intl_ComputeDisplayNames(JSContext* cx, unsigned argc, Value* vp)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t resultSize =
|
JSString* word = CallICU(cx, [fmt, symbolType, index](UChar* chars, int32_t size, UErrorCode* status) {
|
||||||
udat_getSymbols(fmt, symbolType, index, Char16ToUChar(chars.begin()),
|
return udat_getSymbols(fmt, symbolType, index, chars, size, status);
|
||||||
INITIAL_CHAR_BUFFER_SIZE, &status);
|
});
|
||||||
if (status == U_BUFFER_OVERFLOW_ERROR) {
|
|
||||||
if (!chars.resize(resultSize))
|
|
||||||
return false;
|
|
||||||
status = U_ZERO_ERROR;
|
|
||||||
udat_getSymbols(fmt, symbolType, index, Char16ToUChar(chars.begin()),
|
|
||||||
resultSize, &status);
|
|
||||||
}
|
|
||||||
if (U_FAILURE(status)) {
|
|
||||||
intl::ReportInternalError(cx);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
JSString* word = NewStringCopyN<CanGC>(cx, chars.begin(), resultSize);
|
|
||||||
if (!word)
|
if (!word)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,46 @@ static_assert(mozilla::IsSame<UChar, char16_t>::value,
|
||||||
// buffer's entire inline capacity before growing it and heap-allocating.
|
// buffer's entire inline capacity before growing it and heap-allocating.
|
||||||
static const size_t INITIAL_CHAR_BUFFER_SIZE = 32;
|
static const size_t INITIAL_CHAR_BUFFER_SIZE = 32;
|
||||||
|
|
||||||
|
template <typename ICUStringFunction, size_t InlineCapacity>
|
||||||
|
static int32_t
|
||||||
|
CallICU(JSContext* cx, Vector<char16_t, InlineCapacity>& chars, const ICUStringFunction& strFn)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(chars.length() == 0);
|
||||||
|
MOZ_ALWAYS_TRUE(chars.resize(InlineCapacity));
|
||||||
|
|
||||||
|
UErrorCode status = U_ZERO_ERROR;
|
||||||
|
int32_t size = strFn(chars.begin(), InlineCapacity, &status);
|
||||||
|
if (status == U_BUFFER_OVERFLOW_ERROR) {
|
||||||
|
MOZ_ASSERT(size >= 0);
|
||||||
|
if (!chars.resize(size_t(size)))
|
||||||
|
return -1;
|
||||||
|
status = U_ZERO_ERROR;
|
||||||
|
strFn(chars.begin(), size, &status);
|
||||||
|
}
|
||||||
|
if (U_FAILURE(status)) {
|
||||||
|
ReportInternalError(cx);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_ASSERT(size >= 0);
|
||||||
|
if (!chars.resize(size_t(size)))
|
||||||
|
return -1;
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ICUStringFunction>
|
||||||
|
static JSString*
|
||||||
|
CallICU(JSContext* cx, const ICUStringFunction& strFn)
|
||||||
|
{
|
||||||
|
Vector<char16_t, INITIAL_CHAR_BUFFER_SIZE> chars(cx);
|
||||||
|
|
||||||
|
int32_t size = CallICU(cx, chars, strFn);
|
||||||
|
if (size < 0)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return NewStringCopyN<CanGC>(cx, chars.begin(), size_t(size));
|
||||||
|
}
|
||||||
|
|
||||||
// CountAvailable and GetAvailable describe the signatures used for ICU API
|
// CountAvailable and GetAvailable describe the signatures used for ICU API
|
||||||
// to determine available locales for various functionality.
|
// to determine available locales for various functionality.
|
||||||
using CountAvailable = int32_t (*)();
|
using CountAvailable = int32_t (*)();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue