/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- * vim: set ts=8 sts=2 et sw=2 tw=80: * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef builtin_intl_NumberFormat_h #define builtin_intl_NumberFormat_h #include "mozilla/Attributes.h" #include #include "builtin/SelfHostingDefines.h" #include "js/Class.h" #include "vm/NativeObject.h" struct UFormattedNumber; struct UNumberFormatter; namespace js { class NumberFormatObject : public NativeObject { public: static const JSClass class_; static const JSClass& protoClass_; static constexpr uint32_t INTERNALS_SLOT = 0; static constexpr uint32_t UNUMBER_FORMATTER_SLOT = 1; static constexpr uint32_t UFORMATTED_NUMBER_SLOT = 2; static constexpr uint32_t SLOT_COUNT = 3; static_assert(INTERNALS_SLOT == INTL_INTERNALS_OBJECT_SLOT, "INTERNALS_SLOT must match self-hosting define for internals " "object slot"); // Estimated memory use for UNumberFormatter and UFormattedNumber // (see IcuMemoryUsage). static constexpr size_t EstimatedMemoryUse = 750; UNumberFormatter* getNumberFormatter() const { const auto& slot = getFixedSlot(UNUMBER_FORMATTER_SLOT); if (slot.isUndefined()) { return nullptr; } return static_cast(slot.toPrivate()); } void setNumberFormatter(UNumberFormatter* formatter) { setFixedSlot(UNUMBER_FORMATTER_SLOT, PrivateValue(formatter)); } UFormattedNumber* getFormattedNumber() const { const auto& slot = getFixedSlot(UFORMATTED_NUMBER_SLOT); if (slot.isUndefined()) { return nullptr; } return static_cast(slot.toPrivate()); } void setFormattedNumber(UFormattedNumber* formatted) { setFixedSlot(UFORMATTED_NUMBER_SLOT, PrivateValue(formatted)); } private: static const JSClassOps classOps_; static const ClassSpec classSpec_; static void finalize(JSFreeOp* fop, JSObject* obj); }; /** * Returns a new instance of the standard built-in NumberFormat constructor. * Self-hosted code cannot cache this constructor (as it does for others in * Utilities.js) because it is initialized after self-hosted code is compiled. * * Usage: numberFormat = intl_NumberFormat(locales, options) */ extern MOZ_MUST_USE bool intl_NumberFormat(JSContext* cx, unsigned argc, Value* vp); /** * Returns the numbering system type identifier per Unicode * Technical Standard 35, Unicode Locale Data Markup Language, for the * default numbering system for the given locale. * * Usage: defaultNumberingSystem = intl_numberingSystem(locale) */ extern MOZ_MUST_USE bool intl_numberingSystem(JSContext* cx, unsigned argc, Value* vp); /** * Returns a string representing the number x according to the effective * locale and the formatting options of the given NumberFormat. * * Spec: ECMAScript Internationalization API Specification, 11.3.2. * * Usage: formatted = intl_FormatNumber(numberFormat, x, formatToParts, * unitStyle) */ extern MOZ_MUST_USE bool intl_FormatNumber(JSContext* cx, unsigned argc, Value* vp); #if DEBUG || MOZ_SYSTEM_ICU /** * Returns an object with all available measurement units. * * Usage: units = intl_availableMeasurementUnits() */ extern MOZ_MUST_USE bool intl_availableMeasurementUnits(JSContext* cx, unsigned argc, Value* vp); #endif namespace intl { /** * Class to create a number formatter skeleton. * * The skeleton syntax is documented at: * https://github.com/unicode-org/icu/blob/master/docs/userguide/format_parse/numbers/skeletons.md */ class MOZ_STACK_CLASS NumberFormatterSkeleton final { static constexpr size_t DefaultVectorSize = 128; using SkeletonVector = Vector; SkeletonVector vector_; bool append(char16_t c) { return vector_.append(c); } bool appendN(char16_t c, size_t times) { return vector_.appendN(c, times); } template bool append(const char16_t (&chars)[N]) { static_assert(N > 0, "should only be used with string literals or properly " "null-terminated arrays"); MOZ_ASSERT(chars[N - 1] == '\0', "should only be used with string literals or properly " "null-terminated arrays"); return vector_.append(chars, N - 1); // Without trailing \0. } template bool appendToken(const char16_t (&token)[N]) { return append(token) && append(' '); } bool append(const char* chars, size_t length) { return vector_.append(chars, length); } public: explicit NumberFormatterSkeleton(JSContext* cx) : vector_(cx) {} /** * Return a new UNumberFormatter based on this skeleton. */ UNumberFormatter* toFormatter(JSContext* cx, const char* locale); /** * Set this skeleton to display a currency amount. |currency| must be a * three-letter currency code. * * https://github.com/unicode-org/icu/blob/master/docs/userguide/format_parse/numbers/skeletons.md#unit */ MOZ_MUST_USE bool currency(JSLinearString* currency); enum class CurrencyDisplay { Code, Name, Symbol, NarrowSymbol }; /** * Set the currency display style for this skeleton. * * https://github.com/unicode-org/icu/blob/master/docs/userguide/format_parse/numbers/skeletons.md#unit-width */ MOZ_MUST_USE bool currencyDisplay(CurrencyDisplay display); /** * Set this skeleton to display a unit amount. |unit| must be a well-formed * unit identifier. * * https://github.com/unicode-org/icu/blob/master/docs/userguide/format_parse/numbers/skeletons.md#unit * https://github.com/unicode-org/icu/blob/master/docs/userguide/format_parse/numbers/skeletons.md#per-unit */ MOZ_MUST_USE bool unit(JSLinearString* unit); enum class UnitDisplay { Short, Narrow, Long }; /** * Set the unit display style for this skeleton. * * https://github.com/unicode-org/icu/blob/master/docs/userguide/format_parse/numbers/skeletons.md#unit-width */ MOZ_MUST_USE bool unitDisplay(UnitDisplay display); /** * Set this skeleton to display a percent number. * * https://github.com/unicode-org/icu/blob/master/docs/userguide/format_parse/numbers/skeletons.md#unit * https://github.com/unicode-org/icu/blob/master/docs/userguide/format_parse/numbers/skeletons.md#scale */ MOZ_MUST_USE bool percent(); /** * Set the fraction digits settings for this skeleton. |min| can be zero, * |max| must be larger-or-equal to |min|. * * https://github.com/unicode-org/icu/blob/master/docs/userguide/format_parse/numbers/skeletons.md#fraction-precision */ MOZ_MUST_USE bool fractionDigits(uint32_t min, uint32_t max); /** * Set the integer-width settings for this skeleton. |min| must be a non-zero * number. * * https://github.com/unicode-org/icu/blob/master/docs/userguide/format_parse/numbers/skeletons.md#integer-width */ MOZ_MUST_USE bool integerWidth(uint32_t min); /** * Set the significant digits settings for this skeleton. |min| must be a * non-zero number, |max| must be larger-or-equal to |min|. * * https://github.com/unicode-org/icu/blob/master/docs/userguide/format_parse/numbers/skeletons.md#significant-digits-precision */ MOZ_MUST_USE bool significantDigits(uint32_t min, uint32_t max); /** * Enable or disable grouping for this skeleton. * * https://github.com/unicode-org/icu/blob/master/docs/userguide/format_parse/numbers/skeletons.md#grouping */ MOZ_MUST_USE bool useGrouping(bool on); enum class Notation { Standard, Scientific, Engineering, CompactShort, CompactLong }; /** * Set the notation style for this skeleton. * * https://github.com/unicode-org/icu/blob/master/docs/userguide/format_parse/numbers/skeletons.md#notation */ MOZ_MUST_USE bool notation(Notation style); enum class SignDisplay { Auto, Never, Always, ExceptZero, Accounting, AccountingAlways, AccountingExceptZero }; /** * Set the sign-display for this skeleton. * * https://github.com/unicode-org/icu/blob/master/docs/userguide/format_parse/numbers/skeletons.md#sign-display */ MOZ_MUST_USE bool signDisplay(SignDisplay display); /** * Set the rounding mode to 'half-up' for this skeleton. * * https://github.com/unicode-org/icu/blob/master/docs/userguide/format_parse/numbers/skeletons.md#rounding-mode */ MOZ_MUST_USE bool roundingModeHalfUp(); }; } // namespace intl } // namespace js #endif /* builtin_intl_NumberFormat_h */