tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

DurationFormat.h (5510B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
      2 * vim: set ts=8 sts=2 et sw=2 tw=80:
      3 * This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef builtin_intl_DurationFormat_h
      8 #define builtin_intl_DurationFormat_h
      9 
     10 #include <stdint.h>
     11 
     12 #include "builtin/SelfHostingDefines.h"
     13 #include "builtin/temporal/TemporalUnit.h"
     14 #include "js/Class.h"
     15 #include "vm/NativeObject.h"
     16 
     17 namespace mozilla::intl {
     18 class ListFormat;
     19 class NumberFormat;
     20 }  // namespace mozilla::intl
     21 
     22 namespace js {
     23 
     24 namespace intl {
     25 enum class DurationDisplay : uint8_t { Auto, Always };
     26 enum class DurationStyle : uint8_t { Long, Short, Narrow, Numeric, TwoDigit };
     27 
     28 struct DurationFormatOptions {
     29  // Packed representation to keep the unit options as small as possible.
     30  //
     31  // Use |uint8_t| instead of the actual enum type to avoid GCC warnings:
     32  // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61414
     33 #define DECLARE_DURATION_UNIT(name)                \
     34  /* DurationDisplay */ uint8_t name##Display : 1; \
     35  /* DurationStyle */ uint8_t name##Style : 3;
     36 
     37  DECLARE_DURATION_UNIT(years);
     38  DECLARE_DURATION_UNIT(months);
     39  DECLARE_DURATION_UNIT(weeks);
     40  DECLARE_DURATION_UNIT(days);
     41  DECLARE_DURATION_UNIT(hours);
     42  DECLARE_DURATION_UNIT(minutes);
     43  DECLARE_DURATION_UNIT(seconds);
     44  DECLARE_DURATION_UNIT(milliseconds);
     45  DECLARE_DURATION_UNIT(microseconds);
     46  DECLARE_DURATION_UNIT(nanoseconds);
     47 
     48 #undef DECLARE_DURATION_UNIT
     49 
     50  int8_t fractionalDigits;
     51 };
     52 
     53 struct DurationUnitOptions {
     54  // Use the same bit-widths for fast extraction from DurationFormatOptions.
     55  /* DurationDisplay */ uint8_t display_ : 1;
     56  /* DurationStyle */ uint8_t style_ : 3;
     57 
     58  auto display() const { return static_cast<DurationDisplay>(display_); }
     59 
     60  auto style() const { return static_cast<DurationStyle>(style_); }
     61 };
     62 
     63 }  // namespace intl
     64 
     65 class DurationFormatObject : public NativeObject {
     66 public:
     67  static const JSClass class_;
     68  static const JSClass& protoClass_;
     69 
     70  static constexpr uint32_t INTERNALS_SLOT = 0;
     71  static constexpr uint32_t LIST_FORMAT_SLOT = 1;
     72  static constexpr uint32_t NUMBER_FORMAT_YEARS_SLOT = 2;
     73  static constexpr uint32_t NUMBER_FORMAT_MONTHS_SLOT = 3;
     74  static constexpr uint32_t NUMBER_FORMAT_WEEKS_SLOT = 4;
     75  static constexpr uint32_t NUMBER_FORMAT_DAYS_SLOT = 5;
     76  static constexpr uint32_t NUMBER_FORMAT_HOURS_SLOT = 6;
     77  static constexpr uint32_t NUMBER_FORMAT_MINUTES_SLOT = 7;
     78  static constexpr uint32_t NUMBER_FORMAT_SECONDS_SLOT = 8;
     79  static constexpr uint32_t NUMBER_FORMAT_MILLISECONDS_SLOT = 9;
     80  static constexpr uint32_t NUMBER_FORMAT_MICROSECONDS_SLOT = 10;
     81  static constexpr uint32_t NUMBER_FORMAT_NANOSECONDS_SLOT = 11;
     82  static constexpr uint32_t OPTIONS_SLOT = 12;
     83  static constexpr uint32_t TIME_SEPARATOR_SLOT = 13;
     84  static constexpr uint32_t SLOT_COUNT = 14;
     85 
     86  static_assert(INTERNALS_SLOT == INTL_INTERNALS_OBJECT_SLOT,
     87                "INTERNALS_SLOT must match self-hosting define for internals "
     88                "object slot");
     89 
     90 private:
     91  static constexpr uint32_t numberFormatSlot(temporal::TemporalUnit unit) {
     92    MOZ_ASSERT(temporal::TemporalUnit::Year <= unit &&
     93               unit <= temporal::TemporalUnit::Nanosecond);
     94 
     95    static_assert(uint32_t(temporal::TemporalUnit::Year) ==
     96                  NUMBER_FORMAT_YEARS_SLOT);
     97    static_assert(uint32_t(temporal::TemporalUnit::Nanosecond) ==
     98                  NUMBER_FORMAT_NANOSECONDS_SLOT);
     99 
    100    return uint32_t(unit);
    101  }
    102 
    103 public:
    104  mozilla::intl::NumberFormat* getNumberFormat(
    105      temporal::TemporalUnit unit) const {
    106    const auto& slot = getFixedSlot(numberFormatSlot(unit));
    107    if (slot.isUndefined()) {
    108      return nullptr;
    109    }
    110    return static_cast<mozilla::intl::NumberFormat*>(slot.toPrivate());
    111  }
    112 
    113  void setNumberFormat(temporal::TemporalUnit unit,
    114                       mozilla::intl::NumberFormat* numberFormat) {
    115    setFixedSlot(numberFormatSlot(unit), PrivateValue(numberFormat));
    116  }
    117 
    118  mozilla::intl::ListFormat* getListFormat() const {
    119    const auto& slot = getFixedSlot(LIST_FORMAT_SLOT);
    120    if (slot.isUndefined()) {
    121      return nullptr;
    122    }
    123    return static_cast<mozilla::intl::ListFormat*>(slot.toPrivate());
    124  }
    125 
    126  void setListFormat(mozilla::intl::ListFormat* listFormat) {
    127    setFixedSlot(LIST_FORMAT_SLOT, PrivateValue(listFormat));
    128  }
    129 
    130  intl::DurationFormatOptions* getOptions() const {
    131    const auto& slot = getFixedSlot(OPTIONS_SLOT);
    132    if (slot.isUndefined()) {
    133      return nullptr;
    134    }
    135    return static_cast<intl::DurationFormatOptions*>(slot.toPrivate());
    136  }
    137 
    138  void setOptions(intl::DurationFormatOptions* options) {
    139    setFixedSlot(OPTIONS_SLOT, PrivateValue(options));
    140  }
    141 
    142  JSString* getTimeSeparator() const {
    143    const auto& slot = getFixedSlot(TIME_SEPARATOR_SLOT);
    144    if (slot.isUndefined()) {
    145      return nullptr;
    146    }
    147    return slot.toString();
    148  }
    149 
    150  void setTimeSeparator(JSString* timeSeparator) {
    151    setFixedSlot(TIME_SEPARATOR_SLOT, StringValue(timeSeparator));
    152  }
    153 
    154 private:
    155  static const JSClassOps classOps_;
    156  static const ClassSpec classSpec_;
    157 
    158  static void finalize(JS::GCContext* gcx, JSObject* obj);
    159 };
    160 
    161 /**
    162 * `toLocaleString` implementation for Temporal.Duration objects.
    163 */
    164 [[nodiscard]] extern bool TemporalDurationToLocaleString(
    165    JSContext* cx, const JS::CallArgs& args);
    166 
    167 }  // namespace js
    168 
    169 #endif /* builtin_intl_DurationFormat_h */