Bug 1746711 Part 2: Ensure the enqueued surface has a color space. r=gfx-reviewers...
[gecko.git] / intl / components / src / Calendar.cpp
blobd44dedaaae4ef49cec0a060c6c2233f224bd6420
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "mozilla/intl/Calendar.h"
7 #include "unicode/ucal.h"
8 #include "unicode/uloc.h"
9 #include "unicode/utypes.h"
11 namespace mozilla::intl {
13 /* static */
14 Result<UniquePtr<Calendar>, ICUError> Calendar::TryCreate(
15 const char* aLocale, Maybe<Span<const char16_t>> aTimeZoneOverride) {
16 UErrorCode status = U_ZERO_ERROR;
17 const UChar* zoneID = nullptr;
18 int32_t zoneIDLen = 0;
19 if (aTimeZoneOverride) {
20 zoneIDLen = static_cast<int32_t>(aTimeZoneOverride->Length());
21 zoneID = aTimeZoneOverride->Elements();
24 UCalendar* calendar =
25 ucal_open(zoneID, zoneIDLen, aLocale, UCAL_DEFAULT, &status);
27 if (U_FAILURE(status)) {
28 return Err(ToICUError(status));
31 return MakeUnique<Calendar>(calendar);
34 Result<Span<const char>, ICUError> Calendar::GetBcp47Type() {
35 UErrorCode status = U_ZERO_ERROR;
36 const char* oldType = ucal_getType(mCalendar, &status);
37 if (U_FAILURE(status)) {
38 return Err(ToICUError(status));
40 const char* bcp47Type = uloc_toUnicodeLocaleType("calendar", oldType);
42 if (!bcp47Type) {
43 return Err(ICUError::InternalError);
46 return MakeStringSpan(bcp47Type);
49 static Weekday WeekdayFromDaysOfWeek(UCalendarDaysOfWeek weekday) {
50 switch (weekday) {
51 case UCAL_MONDAY:
52 return Weekday::Monday;
53 case UCAL_TUESDAY:
54 return Weekday::Tuesday;
55 case UCAL_WEDNESDAY:
56 return Weekday::Wednesday;
57 case UCAL_THURSDAY:
58 return Weekday::Thursday;
59 case UCAL_FRIDAY:
60 return Weekday::Friday;
61 case UCAL_SATURDAY:
62 return Weekday::Saturday;
63 case UCAL_SUNDAY:
64 return Weekday::Sunday;
66 MOZ_CRASH("unexpected weekday value");
69 Result<EnumSet<Weekday>, ICUError> Calendar::GetWeekend() {
70 static_assert(static_cast<int32_t>(UCAL_SUNDAY) == 1);
71 static_assert(static_cast<int32_t>(UCAL_SATURDAY) == 7);
73 UErrorCode status = U_ZERO_ERROR;
75 EnumSet<Weekday> weekend;
76 for (int32_t i = UCAL_SUNDAY; i <= UCAL_SATURDAY; i++) {
77 auto dayOfWeek = static_cast<UCalendarDaysOfWeek>(i);
78 auto type = ucal_getDayOfWeekType(mCalendar, dayOfWeek, &status);
79 if (U_FAILURE(status)) {
80 return Err(ToICUError(status));
83 switch (type) {
84 case UCAL_WEEKEND_ONSET:
85 // Treat days which start as a weekday as weekdays.
86 [[fallthrough]];
87 case UCAL_WEEKDAY:
88 break;
90 case UCAL_WEEKEND_CEASE:
91 // Treat days which start as a weekend day as weekend days.
92 [[fallthrough]];
93 case UCAL_WEEKEND:
94 weekend += WeekdayFromDaysOfWeek(dayOfWeek);
95 break;
99 return weekend;
102 Weekday Calendar::GetFirstDayOfWeek() {
103 int32_t firstDayOfWeek = ucal_getAttribute(mCalendar, UCAL_FIRST_DAY_OF_WEEK);
104 MOZ_ASSERT(UCAL_SUNDAY <= firstDayOfWeek && firstDayOfWeek <= UCAL_SATURDAY);
106 return WeekdayFromDaysOfWeek(
107 static_cast<UCalendarDaysOfWeek>(firstDayOfWeek));
110 int32_t Calendar::GetMinimalDaysInFirstWeek() {
111 int32_t minimalDays =
112 ucal_getAttribute(mCalendar, UCAL_MINIMAL_DAYS_IN_FIRST_WEEK);
113 MOZ_ASSERT(1 <= minimalDays && minimalDays <= 7);
115 return minimalDays;
118 Result<Ok, ICUError> Calendar::SetTimeInMs(double aUnixEpoch) {
119 UErrorCode status = U_ZERO_ERROR;
120 ucal_setMillis(mCalendar, aUnixEpoch, &status);
121 if (U_FAILURE(status)) {
122 return Err(ToICUError(status));
124 return Ok{};
127 /* static */
128 Result<SpanEnumeration<char>, ICUError>
129 Calendar::GetLegacyKeywordValuesForLocale(const char* aLocale) {
130 UErrorCode status = U_ZERO_ERROR;
131 UEnumeration* enumeration = ucal_getKeywordValuesForLocale(
132 "calendar", aLocale, /* commonlyUsed */ false, &status);
134 if (U_SUCCESS(status)) {
135 return SpanEnumeration<char>(enumeration);
138 return Err(ToICUError(status));
141 /* static */
142 SpanResult<char> Calendar::LegacyIdentifierToBcp47(const char* aIdentifier,
143 int32_t aLength) {
144 if (aIdentifier == nullptr) {
145 return Err(InternalError{});
147 // aLength is not needed here, as the ICU call uses the null terminated
148 // string.
149 return MakeStringSpan(uloc_toUnicodeLocaleType("ca", aIdentifier));
152 /* static */
153 Result<Calendar::Bcp47IdentifierEnumeration, ICUError>
154 Calendar::GetBcp47KeywordValuesForLocale(const char* aLocale,
155 CommonlyUsed aCommonlyUsed) {
156 UErrorCode status = U_ZERO_ERROR;
157 UEnumeration* enumeration = ucal_getKeywordValuesForLocale(
158 "calendar", aLocale, static_cast<bool>(aCommonlyUsed), &status);
160 if (U_SUCCESS(status)) {
161 return Bcp47IdentifierEnumeration(enumeration);
164 return Err(ToICUError(status));
167 Calendar::~Calendar() {
168 MOZ_ASSERT(mCalendar);
169 ucal_close(mCalendar);
172 } // namespace mozilla::intl