tor-browser

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

Calendar.h (12949B)


      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_temporal_Calendar_h
      8 #define builtin_temporal_Calendar_h
      9 
     10 #include "mozilla/Assertions.h"
     11 #include "mozilla/Attributes.h"
     12 
     13 #include <stdint.h>
     14 #include <string_view>
     15 
     16 #include "js/RootingAPI.h"
     17 #include "js/TypeDecls.h"
     18 #include "js/Value.h"
     19 #include "vm/NativeObject.h"
     20 
     21 class JS_PUBLIC_API JSTracer;
     22 
     23 namespace js {
     24 struct ClassSpec;
     25 }  // namespace js
     26 
     27 namespace js::temporal {
     28 
     29 enum class CalendarId : int32_t {
     30  ISO8601,
     31 
     32  // Thai Buddhist solar calendar.
     33  Buddhist,
     34 
     35  // Chinese lunisolar calendar.
     36  Chinese,
     37 
     38  // Coptic calendar.
     39  Coptic,
     40 
     41  // Korean lunisolar calendar.
     42  Dangi,
     43 
     44  // Ethiopian Amete Mihret calendar.
     45  Ethiopian,
     46 
     47  // Ethiopian Amete Alem calendar.
     48  EthiopianAmeteAlem,
     49 
     50  // Gregorian calendar.
     51  Gregorian,
     52 
     53  // Hebrew lunisolar calendar.
     54  Hebrew,
     55 
     56  // Indian national calendar.
     57  Indian,
     58 
     59  // Islamic lunar calendars.
     60  IslamicCivil,
     61  IslamicTabular,
     62  IslamicUmmAlQura,
     63 
     64  // Japanese calendar.
     65  Japanese,
     66 
     67  // Persian solar Hijri calendar.
     68  Persian,
     69 
     70  // Republic of China (ROC) calendar.
     71  ROC,
     72 };
     73 
     74 inline constexpr auto availableCalendars = {
     75    CalendarId::ISO8601,
     76    CalendarId::Buddhist,
     77    CalendarId::Chinese,
     78    CalendarId::Coptic,
     79    CalendarId::Dangi,
     80    CalendarId::Ethiopian,
     81    CalendarId::EthiopianAmeteAlem,
     82    CalendarId::Gregorian,
     83    CalendarId::Hebrew,
     84    CalendarId::Indian,
     85    CalendarId::IslamicCivil,
     86    CalendarId::IslamicTabular,
     87 // See Bug 1950425, this calendar is only available on Nightly due to
     88 // inconsistencies between ICU4X and ICU4C.
     89 #ifdef NIGHTLY_BUILD
     90    CalendarId::IslamicUmmAlQura,
     91 #endif
     92    CalendarId::Japanese,
     93    CalendarId::Persian,
     94    CalendarId::ROC,
     95 };
     96 
     97 /**
     98 * AvailableCalendars ( )
     99 */
    100 constexpr auto& AvailableCalendars() { return availableCalendars; }
    101 
    102 class CalendarObject : public NativeObject {
    103 public:
    104  static const JSClass class_;
    105  static const JSClass& protoClass_;
    106 
    107  static constexpr uint32_t IDENTIFIER_SLOT = 0;
    108  static constexpr uint32_t SLOT_COUNT = 1;
    109 
    110  CalendarId identifier() const {
    111    return static_cast<CalendarId>(getFixedSlot(IDENTIFIER_SLOT).toInt32());
    112  }
    113 
    114 private:
    115  static const ClassSpec classSpec_;
    116 };
    117 
    118 /**
    119 * Calendar value, which is a string containing a canonical calendar identifier.
    120 */
    121 class MOZ_STACK_CLASS CalendarValue final {
    122  JS::Value value_{};
    123 
    124 public:
    125  /**
    126   * Default initialize this CalendarValue.
    127   */
    128  CalendarValue() = default;
    129 
    130  /**
    131   * Default initialize this CalendarValue.
    132   */
    133  explicit CalendarValue(const JS::Value& value) : value_(value) {
    134    MOZ_ASSERT(value.isInt32());
    135  }
    136 
    137  /**
    138   * Initialize this CalendarValue with a canonical calendar identifier.
    139   */
    140  explicit CalendarValue(CalendarId calendarId)
    141      : value_(JS::Int32Value(static_cast<int32_t>(calendarId))) {}
    142 
    143  /**
    144   * Return true iff this CalendarValue is initialized with either a canonical
    145   * calendar identifier or a calendar object.
    146   */
    147  explicit operator bool() const { return !value_.isUndefined(); }
    148 
    149  /**
    150   * Return the slot Value representation of this CalendarValue.
    151   */
    152  JS::Value toSlotValue() const { return value_; }
    153 
    154  /**
    155   * Return the calendar identifier.
    156   */
    157  CalendarId identifier() const {
    158    return static_cast<CalendarId>(value_.toInt32());
    159  }
    160 
    161  void trace(JSTracer* trc);
    162 
    163  JS::Value* valueDoNotUse() { return &value_; }
    164  JS::Value const* valueDoNotUse() const { return &value_; }
    165 };
    166 
    167 struct DateDuration;
    168 struct ISODate;
    169 struct ISODateTime;
    170 class PlainDate;
    171 class PlainMonthDayObject;
    172 class PlainMonthDay;
    173 class PlainYearMonthObject;
    174 class PlainYearMonth;
    175 class CalendarFields;
    176 enum class TemporalOverflow;
    177 enum class TemporalUnit;
    178 
    179 /**
    180 * ISODaysInMonth ( year, month )
    181 */
    182 int32_t ISODaysInMonth(int32_t year, int32_t month);
    183 
    184 /**
    185 * 21.4.1.12 MakeDay ( year, month, date )
    186 */
    187 int32_t MakeDay(const ISODate& date);
    188 
    189 /**
    190 * 21.4.1.13 MakeDate ( day, time )
    191 */
    192 int64_t MakeDate(const ISODateTime& dateTime);
    193 
    194 /**
    195 * Return the BCP 47 identifier of the calendar.
    196 */
    197 std::string_view CalendarIdentifier(CalendarId calendarId);
    198 
    199 /**
    200 * Return the BCP 47 identifier of the calendar.
    201 */
    202 inline std::string_view CalendarIdentifier(const CalendarValue& calendar) {
    203  return CalendarIdentifier(calendar.identifier());
    204 }
    205 
    206 /**
    207 * CanonicalizeCalendar ( id )
    208 *
    209 * Return the case-normalized calendar identifier if |id| is a built-in calendar
    210 * identifier. Otherwise throws a RangeError.
    211 */
    212 bool CanonicalizeCalendar(JSContext* cx, JS::Handle<JSString*> id,
    213                          JS::MutableHandle<CalendarValue> result);
    214 
    215 /**
    216 * ToTemporalCalendarSlotValue ( temporalCalendarLike )
    217 */
    218 bool ToTemporalCalendar(JSContext* cx,
    219                        JS::Handle<JS::Value> temporalCalendarLike,
    220                        JS::MutableHandle<CalendarValue> result);
    221 
    222 /**
    223 * GetTemporalCalendarWithISODefault ( item )
    224 */
    225 bool GetTemporalCalendarWithISODefault(JSContext* cx,
    226                                       JS::Handle<JSObject*> item,
    227                                       JS::MutableHandle<CalendarValue> result);
    228 
    229 /**
    230 * CalendarDateAdd ( calendar, isoDate, duration, overflow )
    231 */
    232 bool CalendarDateAdd(JSContext* cx, JS::Handle<CalendarValue> calendar,
    233                     const ISODate& isoDate, const DateDuration& duration,
    234                     TemporalOverflow overflow, ISODate* result);
    235 
    236 /**
    237 * CalendarDateUntil ( calendar, one, two, largestUnit )
    238 */
    239 bool CalendarDateUntil(JSContext* cx, JS::Handle<CalendarValue> calendar,
    240                       const ISODate& one, const ISODate& two,
    241                       TemporalUnit largestUnit, DateDuration* result);
    242 
    243 /**
    244 * CalendarISOToDate ( calendar, isoDate )
    245 *
    246 * When accessing the [[Era]] of the returned Calendar Date Record.
    247 */
    248 bool CalendarEra(JSContext* cx, JS::Handle<CalendarValue> calendar,
    249                 const ISODate& date, JS::MutableHandle<JS::Value> result);
    250 
    251 /**
    252 * CalendarISOToDate ( calendar, isoDate )
    253 *
    254 * When accessing the [[EraYear]] of the returned Calendar Date Record.
    255 */
    256 bool CalendarEraYear(JSContext* cx, JS::Handle<CalendarValue> calendar,
    257                     const ISODate& date, JS::MutableHandle<JS::Value> result);
    258 /**
    259 * CalendarISOToDate ( calendar, isoDate )
    260 *
    261 * When accessing the [[Year]] of the returned Calendar Date Record.
    262 */
    263 bool CalendarYear(JSContext* cx, JS::Handle<CalendarValue> calendar,
    264                  const ISODate& date, JS::MutableHandle<JS::Value> result);
    265 
    266 /**
    267 * CalendarISOToDate ( calendar, isoDate )
    268 *
    269 * When accessing the [[Month]] of the returned Calendar Date Record.
    270 */
    271 bool CalendarMonth(JSContext* cx, JS::Handle<CalendarValue> calendar,
    272                   const ISODate& date, JS::MutableHandle<JS::Value> result);
    273 
    274 /**
    275 * CalendarISOToDate ( calendar, isoDate )
    276 *
    277 * When accessing the [[MonthCode]] of the returned Calendar Date Record.
    278 */
    279 bool CalendarMonthCode(JSContext* cx, JS::Handle<CalendarValue> calendar,
    280                       const ISODate& date,
    281                       JS::MutableHandle<JS::Value> result);
    282 
    283 /**
    284 * CalendarISOToDate ( calendar, isoDate )
    285 *
    286 * When accessing the [[Day]] of the returned Calendar Date Record.
    287 */
    288 bool CalendarDay(JSContext* cx, JS::Handle<CalendarValue> calendar,
    289                 const ISODate& date, JS::MutableHandle<JS::Value> result);
    290 
    291 /**
    292 * CalendarISOToDate ( calendar, isoDate )
    293 *
    294 * When accessing the [[DayOfWeek]] of the returned Calendar Date Record.
    295 */
    296 bool CalendarDayOfWeek(JSContext* cx, JS::Handle<CalendarValue> calendar,
    297                       const ISODate& date,
    298                       JS::MutableHandle<JS::Value> result);
    299 
    300 /**
    301 * CalendarISOToDate ( calendar, isoDate )
    302 *
    303 * When accessing the [[DayOfYear]] of the returned Calendar Date Record.
    304 */
    305 bool CalendarDayOfYear(JSContext* cx, JS::Handle<CalendarValue> calendar,
    306                       const ISODate& date,
    307                       JS::MutableHandle<JS::Value> result);
    308 
    309 /**
    310 * CalendarISOToDate ( calendar, isoDate )
    311 *
    312 * When accessing the [[Week]] field of the [[WeekOfYear]] of the returned
    313 * Calendar Date Record.
    314 */
    315 bool CalendarWeekOfYear(JSContext* cx, JS::Handle<CalendarValue> calendar,
    316                        const ISODate& date,
    317                        JS::MutableHandle<JS::Value> result);
    318 
    319 /**
    320 * CalendarISOToDate ( calendar, isoDate )
    321 *
    322 * When accessing the [[Year]] field of the [[WeekOfYear]] of the returned
    323 * Calendar Date Record.
    324 */
    325 bool CalendarYearOfWeek(JSContext* cx, JS::Handle<CalendarValue> calendar,
    326                        const ISODate& date,
    327                        JS::MutableHandle<JS::Value> result);
    328 
    329 /**
    330 * * CalendarISOToDate ( calendar, isoDate )
    331 *
    332 * When accessing the [[DaysInWeek]] of the returned Calendar Date Record.
    333 */
    334 bool CalendarDaysInWeek(JSContext* cx, JS::Handle<CalendarValue> calendar,
    335                        const ISODate& date,
    336                        JS::MutableHandle<JS::Value> result);
    337 
    338 /**
    339 * * CalendarISOToDate ( calendar, isoDate )
    340 *
    341 * When accessing the [[DaysInMonth]] of the returned Calendar Date Record.
    342 */
    343 bool CalendarDaysInMonth(JSContext* cx, JS::Handle<CalendarValue> calendar,
    344                         const ISODate& date,
    345                         JS::MutableHandle<JS::Value> result);
    346 
    347 /**
    348 * CalendarISOToDate ( calendar, isoDate )
    349 *
    350 * When accessing the [[DaysInYear]] of the returned Calendar Date Record.
    351 */
    352 bool CalendarDaysInYear(JSContext* cx, JS::Handle<CalendarValue> calendar,
    353                        const ISODate& date,
    354                        JS::MutableHandle<JS::Value> result);
    355 
    356 /**
    357 * * CalendarISOToDate ( calendar, isoDate )
    358 *
    359 * When accessing the [[MonthsInYear]] of the returned Calendar Date Record.
    360 */
    361 bool CalendarMonthsInYear(JSContext* cx, JS::Handle<CalendarValue> calendar,
    362                          const ISODate& date,
    363                          JS::MutableHandle<JS::Value> result);
    364 
    365 /**
    366 * CalendarISOToDate ( calendar, isoDate )
    367 *
    368 * When accessing the [[InLeapYear]] of the returned Calendar Date Record.
    369 */
    370 bool CalendarInLeapYear(JSContext* cx, JS::Handle<CalendarValue> calendar,
    371                        const ISODate& date,
    372                        JS::MutableHandle<JS::Value> result);
    373 
    374 /**
    375 * CalendarDateFromFields ( calendar, fields, overflow )
    376 */
    377 bool CalendarDateFromFields(JSContext* cx, JS::Handle<CalendarValue> calendar,
    378                            JS::Handle<CalendarFields> fields,
    379                            TemporalOverflow overflow,
    380                            MutableHandle<PlainDate> result);
    381 
    382 /**
    383 * CalendarYearMonthFromFields ( calendar, fields, overflow )
    384 */
    385 bool CalendarYearMonthFromFields(JSContext* cx,
    386                                 JS::Handle<CalendarValue> calendar,
    387                                 JS::Handle<CalendarFields> fields,
    388                                 TemporalOverflow overflow,
    389                                 JS::MutableHandle<PlainYearMonth> result);
    390 
    391 /**
    392 * CalendarMonthDayFromFields ( calendar, fields, overflow )
    393 */
    394 bool CalendarMonthDayFromFields(JSContext* cx,
    395                                JS::Handle<CalendarValue> calendar,
    396                                JS::Handle<CalendarFields> fields,
    397                                TemporalOverflow overflow,
    398                                JS::MutableHandle<PlainMonthDay> result);
    399 
    400 /**
    401 * CalendarEquals ( one, two )
    402 */
    403 inline bool CalendarEquals(const CalendarValue& one, const CalendarValue& two) {
    404  // Steps 1-2.
    405  return one.identifier() == two.identifier();
    406 }
    407 
    408 // Helper for MutableWrappedPtrOperations.
    409 bool WrapCalendarValue(JSContext* cx, JS::MutableHandle<JS::Value> calendar);
    410 
    411 } /* namespace js::temporal */
    412 
    413 namespace js {
    414 
    415 template <typename Wrapper>
    416 class WrappedPtrOperations<temporal::CalendarValue, Wrapper> {
    417  const auto& container() const {
    418    return static_cast<const Wrapper*>(this)->get();
    419  }
    420 
    421 public:
    422  explicit operator bool() const { return bool(container()); }
    423 
    424  JS::Handle<JS::Value> toSlotValue() const {
    425    return JS::Handle<JS::Value>::fromMarkedLocation(
    426        container().valueDoNotUse());
    427  }
    428 
    429  temporal::CalendarId identifier() const { return container().identifier(); }
    430 };
    431 
    432 template <typename Wrapper>
    433 class MutableWrappedPtrOperations<temporal::CalendarValue, Wrapper>
    434    : public WrappedPtrOperations<temporal::CalendarValue, Wrapper> {
    435  auto& container() { return static_cast<Wrapper*>(this)->get(); }
    436 
    437  JS::MutableHandle<JS::Value> toMutableValue() {
    438    return JS::MutableHandle<JS::Value>::fromMarkedLocation(
    439        container().valueDoNotUse());
    440  }
    441 
    442 public:
    443  bool wrap(JSContext* cx) {
    444    return temporal::WrapCalendarValue(cx, toMutableValue());
    445  }
    446 };
    447 
    448 } /* namespace js */
    449 
    450 #endif /* builtin_temporal_Calendar_h */