| File: | out/../deps/v8/src/temporal/temporal-parser.cc |
| Warning: | line 178, column 8 Assigned value is garbage or undefined |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | // Copyright 2021 the V8 project authors. All rights reserved. | |||
| 2 | // Use of this source code is governed by a BSD-style license that can be | |||
| 3 | // found in the LICENSE file. | |||
| 4 | ||||
| 5 | #include "src/temporal/temporal-parser.h" | |||
| 6 | ||||
| 7 | #include "src/base/bounds.h" | |||
| 8 | #include "src/objects/string-inl.h" | |||
| 9 | #include "src/strings/char-predicates-inl.h" | |||
| 10 | ||||
| 11 | namespace v8 { | |||
| 12 | namespace internal { | |||
| 13 | ||||
| 14 | namespace { | |||
| 15 | ||||
| 16 | // Temporal #prod-NonzeroDigit | |||
| 17 | inline constexpr bool IsNonZeroDecimalDigit(base::uc32 c) { | |||
| 18 | return base::IsInRange(c, '1', '9'); | |||
| 19 | } | |||
| 20 | ||||
| 21 | // Temporal #prod-TZLeadingChar | |||
| 22 | inline constexpr bool IsTZLeadingChar(base::uc32 c) { | |||
| 23 | return base::IsInRange(AsciiAlphaToLower(c), 'a', 'z') || c == '.' || | |||
| 24 | c == '_'; | |||
| 25 | } | |||
| 26 | ||||
| 27 | // Temporal #prod-TZChar | |||
| 28 | inline constexpr bool IsTZChar(base::uc32 c) { | |||
| 29 | return IsTZLeadingChar(c) || c == '-'; | |||
| 30 | } | |||
| 31 | ||||
| 32 | // Temporal #prod-DecimalSeparator | |||
| 33 | inline constexpr bool IsDecimalSeparator(base::uc32 c) { | |||
| 34 | return c == '.' || c == ','; | |||
| 35 | } | |||
| 36 | ||||
| 37 | // Temporal #prod-DateTimeSeparator | |||
| 38 | inline constexpr bool IsDateTimeSeparator(base::uc32 c) { | |||
| 39 | return c == ' ' || AsciiAlphaToLower(c) == 't'; | |||
| 40 | } | |||
| 41 | ||||
| 42 | // Temporal #prod-ASCIISign | |||
| 43 | inline constexpr bool IsAsciiSign(base::uc32 c) { return c == '-' || c == '+'; } | |||
| 44 | ||||
| 45 | // Temporal #prod-Sign | |||
| 46 | inline constexpr bool IsSign(base::uc32 c) { | |||
| 47 | return c == 0x2212 || IsAsciiSign(c); | |||
| 48 | } | |||
| 49 | ||||
| 50 | inline constexpr base::uc32 CanonicalSign(base::uc32 c) { | |||
| 51 | return c == 0x2212 ? '-' : c; | |||
| 52 | } | |||
| 53 | ||||
| 54 | inline constexpr int32_t ToInt(base::uc32 c) { return c - '0'; } | |||
| 55 | ||||
| 56 | /** | |||
| 57 | * The TemporalParser use two types of internal routine: | |||
| 58 | * - Scan routines: Follow the function signature below: | |||
| 59 | * template <typename Char> int32_t Scan$ProductionName( | |||
| 60 | * base::Vector<Char> str, int32_t s, R* out) | |||
| 61 | * | |||
| 62 | * These routine scan the next item from position s in str and store the | |||
| 63 | * parsed result into out if the expected string is successfully scanned. | |||
| 64 | * It return the length of matched text from s or 0 to indicate no | |||
| 65 | * expected item matched. | |||
| 66 | * | |||
| 67 | * - Satisfy routines: Follow the function sigature below: | |||
| 68 | * template <typename Char> | |||
| 69 | * bool Satisfy$ProductionName(base::Vector<Char> str, R* r); | |||
| 70 | * It scan from the beginning of the str by calling Scan routines to put | |||
| 71 | * parsed result into r and return true if the entire str satisfy the | |||
| 72 | * production. It internally use Scan routines. | |||
| 73 | * | |||
| 74 | * TODO(ftang) investigate refactoring to class before shipping | |||
| 75 | * Reference to RegExpParserImpl by encapsulating the cursor position and | |||
| 76 | * only manipulating the current character and position with Next(), | |||
| 77 | * Advance(), current(), etc | |||
| 78 | */ | |||
| 79 | ||||
| 80 | // For Hour Production | |||
| 81 | // Hour: | |||
| 82 | // [0 1] Digit | |||
| 83 | // 2 [0 1 2 3] | |||
| 84 | template <typename Char> | |||
| 85 | bool IsHour(base::Vector<Char> str, int32_t s) { | |||
| 86 | return (str.length() >= (s + 2)) && | |||
| 87 | ((base::IsInRange(str[s], '0', '1') && IsDecimalDigit(str[s + 1])) || | |||
| 88 | ((str[s] == '2') && base::IsInRange(str[s + 1], '0', '3'))); | |||
| 89 | } | |||
| 90 | ||||
| 91 | template <typename Char> | |||
| 92 | int32_t ScanHour(base::Vector<Char> str, int32_t s, int32_t* out) { | |||
| 93 | if (!IsHour(str, s)) return 0; | |||
| 94 | *out = ToInt(str[s]) * 10 + ToInt(str[s + 1]); | |||
| 95 | return 2; | |||
| 96 | } | |||
| 97 | ||||
| 98 | // MinuteSecond: | |||
| 99 | // [0 1 2 3 4 5] Digit | |||
| 100 | template <typename Char> | |||
| 101 | bool IsMinuteSecond(base::Vector<Char> str, int32_t s) { | |||
| 102 | return (str.length() >= (s + 2)) && | |||
| 103 | (base::IsInRange(str[s], '0', '5') && IsDecimalDigit(str[s + 1])); | |||
| 104 | } | |||
| 105 | ||||
| 106 | template <typename Char> | |||
| 107 | int32_t ScanMinuteSecond(base::Vector<Char> str, int32_t s, int32_t* out) { | |||
| 108 | if (!IsMinuteSecond(str, s)) return 0; | |||
| 109 | *out = ToInt(str[s]) * 10 + ToInt(str[s + 1]); | |||
| 110 | return 2; | |||
| 111 | } | |||
| 112 | ||||
| 113 | // For the forward production in the grammar such as | |||
| 114 | // ProductionB: | |||
| 115 | // ProductionT | |||
| 116 | #define SCAN_FORWARD(B, T, R)template <typename Char> int32_t ScanB(base::Vector< Char> str, int32_t s, R* r) { return ScanT(str, s, r); } \ | |||
| 117 | template <typename Char> \ | |||
| 118 | int32_t Scan##B(base::Vector<Char> str, int32_t s, R* r) { \ | |||
| 119 | return Scan##T(str, s, r); \ | |||
| 120 | } | |||
| 121 | ||||
| 122 | // Same as above but store the result into a particular field in R | |||
| 123 | ||||
| 124 | // For the forward production in the grammar such as | |||
| 125 | // ProductionB: | |||
| 126 | // ProductionT1 | |||
| 127 | // ProductionT2 | |||
| 128 | #define SCAN_EITHER_FORWARD(B, T1, T2, R)template <typename Char> int32_t ScanB(base::Vector< Char> str, int32_t s, R* r) { int32_t len; if ((len = ScanT1 (str, s, r)) > 0) return len; return ScanT2(str, s, r); } \ | |||
| 129 | template <typename Char> \ | |||
| 130 | int32_t Scan##B(base::Vector<Char> str, int32_t s, R* r) { \ | |||
| 131 | int32_t len; \ | |||
| 132 | if ((len = Scan##T1(str, s, r)) > 0) return len; \ | |||
| 133 | return Scan##T2(str, s, r); \ | |||
| 134 | } | |||
| 135 | ||||
| 136 | // TimeHour: Hour | |||
| 137 | SCAN_FORWARD(TimeHour, Hour, int32_t)template <typename Char> int32_t ScanTimeHour(base::Vector <Char> str, int32_t s, int32_t* r) { return ScanHour(str , s, r); } | |||
| 138 | ||||
| 139 | // TimeMinute: MinuteSecond | |||
| 140 | SCAN_FORWARD(TimeMinute, MinuteSecond, int32_t)template <typename Char> int32_t ScanTimeMinute(base::Vector <Char> str, int32_t s, int32_t* r) { return ScanMinuteSecond (str, s, r); } | |||
| 141 | ||||
| 142 | // TimeSecond: | |||
| 143 | // MinuteSecond | |||
| 144 | // 60 | |||
| 145 | template <typename Char> | |||
| 146 | int32_t ScanTimeSecond(base::Vector<Char> str, int32_t s, int32_t* out) { | |||
| 147 | int32_t len = ScanMinuteSecond(str, s, out); | |||
| 148 | // MinuteSecond | |||
| 149 | if (len > 0) return len; | |||
| 150 | if ((str.length() < (s + 2)) || (str[s] != '6') || (str[s + 1] != '0')) { | |||
| 151 | return 0; | |||
| 152 | } | |||
| 153 | // 60 | |||
| 154 | *out = 60; | |||
| 155 | return 2; | |||
| 156 | } | |||
| 157 | ||||
| 158 | constexpr int kPowerOfTen[] = {1, 10, 100, 1000, 10000, | |||
| 159 | 100000, 1000000, 10000000, 100000000}; | |||
| 160 | ||||
| 161 | // FractionalPart : Digit{1,9} | |||
| 162 | template <typename Char> | |||
| 163 | int32_t ScanFractionalPart(base::Vector<Char> str, int32_t s, int32_t* out) { | |||
| 164 | int32_t cur = s; | |||
| 165 | if ((str.length() < (cur + 1)) || !IsDecimalDigit(str[cur])) return 0; | |||
| 166 | *out = ToInt(str[cur++]); | |||
| 167 | while ((cur < str.length()) && ((cur - s) < 9) && IsDecimalDigit(str[cur])) { | |||
| 168 | *out = 10 * (*out) + ToInt(str[cur++]); | |||
| 169 | } | |||
| 170 | *out *= kPowerOfTen[9 - (cur - s)]; | |||
| 171 | return cur - s; | |||
| 172 | } | |||
| 173 | ||||
| 174 | template <typename Char> | |||
| 175 | int32_t ScanFractionalPart(base::Vector<Char> str, int32_t s, int64_t* out) { | |||
| 176 | int32_t out32; | |||
| 177 | int32_t len = ScanFractionalPart(str, s, &out32); | |||
| 178 | *out = out32; | |||
| ||||
| 179 | return len; | |||
| 180 | } | |||
| 181 | ||||
| 182 | // TimeFraction: FractionalPart | |||
| 183 | SCAN_FORWARD(TimeFractionalPart, FractionalPart, int32_t)template <typename Char> int32_t ScanTimeFractionalPart (base::Vector<Char> str, int32_t s, int32_t* r) { return ScanFractionalPart(str, s, r); } | |||
| 184 | ||||
| 185 | // Fraction: DecimalSeparator FractionalPart | |||
| 186 | // DecimalSeparator: one of , . | |||
| 187 | template <typename Char> | |||
| 188 | int32_t ScanFraction(base::Vector<Char> str, int32_t s, int32_t* out) { | |||
| 189 | if ((str.length() < (s + 2)) || (!IsDecimalSeparator(str[s]))) return 0; | |||
| 190 | int32_t len; | |||
| 191 | if ((len = ScanFractionalPart(str, s + 1, out)) == 0) return 0; | |||
| 192 | return len + 1; | |||
| 193 | } | |||
| 194 | ||||
| 195 | // TimeFraction: DecimalSeparator TimeFractionalPart | |||
| 196 | // DecimalSeparator: one of , . | |||
| 197 | template <typename Char> | |||
| 198 | int32_t ScanTimeFraction(base::Vector<Char> str, int32_t s, int32_t* out) { | |||
| 199 | if ((str.length() < (s + 2)) || (!IsDecimalSeparator(str[s]))) return 0; | |||
| 200 | int32_t len; | |||
| 201 | if ((len = ScanTimeFractionalPart(str, s + 1, out)) == 0) return 0; | |||
| 202 | return len + 1; | |||
| 203 | } | |||
| 204 | ||||
| 205 | template <typename Char> | |||
| 206 | int32_t ScanTimeFraction(base::Vector<Char> str, int32_t s, | |||
| 207 | ParsedISO8601Result* r) { | |||
| 208 | return ScanTimeFraction(str, s, &(r->time_nanosecond)); | |||
| 209 | } | |||
| 210 | ||||
| 211 | // TimeSpec: | |||
| 212 | // TimeHour | |||
| 213 | // TimeHour : TimeMinute | |||
| 214 | // TimeHour : TimeMinute : TimeSecond [TimeFraction] | |||
| 215 | // TimeHour TimeMinute | |||
| 216 | // TimeHour TimeMinute TimeSecond [TimeFraction] | |||
| 217 | template <typename Char> | |||
| 218 | int32_t ScanTimeSpec(base::Vector<Char> str, int32_t s, | |||
| 219 | ParsedISO8601Result* r) { | |||
| 220 | int32_t time_hour, time_minute, time_second; | |||
| 221 | int32_t len; | |||
| 222 | int32_t cur = s; | |||
| 223 | if ((len = ScanTimeHour(str, cur, &time_hour)) == 0) return 0; | |||
| 224 | cur += len; | |||
| 225 | if ((cur + 1) > str.length()) { | |||
| 226 | // TimeHour | |||
| 227 | r->time_hour = time_hour; | |||
| 228 | return cur - s; | |||
| 229 | } | |||
| 230 | if (str[cur] == ':') { | |||
| 231 | cur++; | |||
| 232 | if ((len = ScanTimeMinute(str, cur, &time_minute)) == 0) return 0; | |||
| 233 | cur += len; | |||
| 234 | if ((cur + 1) > str.length() || (str[cur] != ':')) { | |||
| 235 | // TimeHour : TimeMinute | |||
| 236 | r->time_hour = time_hour; | |||
| 237 | r->time_minute = time_minute; | |||
| 238 | return cur - s; | |||
| 239 | } | |||
| 240 | cur++; | |||
| 241 | if ((len = ScanTimeSecond(str, cur, &time_second)) == 0) return 0; | |||
| 242 | } else { | |||
| 243 | if ((len = ScanTimeMinute(str, cur, &time_minute)) == 0) { | |||
| 244 | // TimeHour | |||
| 245 | r->time_hour = time_hour; | |||
| 246 | return cur - s; | |||
| 247 | } | |||
| 248 | cur += len; | |||
| 249 | if ((len = ScanTimeSecond(str, cur, &time_second)) == 0) { | |||
| 250 | // TimeHour TimeMinute | |||
| 251 | r->time_hour = time_hour; | |||
| 252 | r->time_minute = time_minute; | |||
| 253 | return cur - s; | |||
| 254 | } | |||
| 255 | } | |||
| 256 | cur += len; | |||
| 257 | len = ScanTimeFraction(str, cur, r); | |||
| 258 | r->time_hour = time_hour; | |||
| 259 | r->time_minute = time_minute; | |||
| 260 | r->time_second = time_second; | |||
| 261 | return cur + len - s; | |||
| 262 | } | |||
| 263 | ||||
| 264 | // TimeSpecSeparator: DateTimeSeparator TimeSpec | |||
| 265 | // DateTimeSeparator: SPACE, 't', or 'T' | |||
| 266 | template <typename Char> | |||
| 267 | int32_t ScanTimeSpecSeparator(base::Vector<Char> str, int32_t s, | |||
| 268 | ParsedISO8601Result* r) { | |||
| 269 | if (!(((s + 1) < str.length()) && IsDateTimeSeparator(str[s]))) return 0; | |||
| 270 | int32_t len = ScanTimeSpec(str, s + 1, r); | |||
| 271 | return (len == 0) ? 0 : len + 1; | |||
| 272 | } | |||
| 273 | ||||
| 274 | // DateExtendedYear: Sign Digit Digit Digit Digit Digit Digit | |||
| 275 | template <typename Char> | |||
| 276 | int32_t ScanDateExtendedYear(base::Vector<Char> str, int32_t s, int32_t* out) { | |||
| 277 | if (str.length() < (s + 7)) return 0; | |||
| 278 | if (IsSign(str[s]) && IsDecimalDigit(str[s + 1]) && | |||
| 279 | IsDecimalDigit(str[s + 2]) && IsDecimalDigit(str[s + 3]) && | |||
| 280 | IsDecimalDigit(str[s + 4]) && IsDecimalDigit(str[s + 5]) && | |||
| 281 | IsDecimalDigit(str[s + 6])) { | |||
| 282 | int32_t sign = (CanonicalSign(str[s]) == '-') ? -1 : 1; | |||
| 283 | *out = sign * (ToInt(str[s + 1]) * 100000 + ToInt(str[s + 2]) * 10000 + | |||
| 284 | ToInt(str[s + 3]) * 1000 + ToInt(str[s + 4]) * 100 + | |||
| 285 | ToInt(str[s + 5]) * 10 + ToInt(str[s + 6])); | |||
| 286 | return 7; | |||
| 287 | } | |||
| 288 | return 0; | |||
| 289 | } | |||
| 290 | ||||
| 291 | // DateFourDigitYear: Digit Digit Digit Digit | |||
| 292 | template <typename Char> | |||
| 293 | int32_t ScanDateFourDigitYear(base::Vector<Char> str, int32_t s, int32_t* out) { | |||
| 294 | if (str.length() < (s + 4)) return 0; | |||
| 295 | if (IsDecimalDigit(str[s]) && IsDecimalDigit(str[s + 1]) && | |||
| 296 | IsDecimalDigit(str[s + 2]) && IsDecimalDigit(str[s + 3])) { | |||
| 297 | *out = ToInt(str[s]) * 1000 + ToInt(str[s + 1]) * 100 + | |||
| 298 | ToInt(str[s + 2]) * 10 + ToInt(str[s + 3]); | |||
| 299 | return 4; | |||
| 300 | } | |||
| 301 | return 0; | |||
| 302 | } | |||
| 303 | ||||
| 304 | // DateYear: | |||
| 305 | // DateFourDigitYear | |||
| 306 | // DateExtendedYear | |||
| 307 | // The lookahead is at most 1 char. | |||
| 308 | SCAN_EITHER_FORWARD(DateYear, DateFourDigitYear, DateExtendedYear, int32_t)template <typename Char> int32_t ScanDateYear(base::Vector <Char> str, int32_t s, int32_t* r) { int32_t len; if (( len = ScanDateFourDigitYear(str, s, r)) > 0) return len; return ScanDateExtendedYear(str, s, r); } | |||
| 309 | ||||
| 310 | // DateMonth: | |||
| 311 | // 0 NonzeroDigit | |||
| 312 | // 10 | |||
| 313 | // 11 | |||
| 314 | // 12 | |||
| 315 | template <typename Char> | |||
| 316 | int32_t ScanDateMonth(base::Vector<Char> str, int32_t s, int32_t* out) { | |||
| 317 | if (str.length() < (s + 2)) return 0; | |||
| 318 | if (((str[s] == '0') && IsNonZeroDecimalDigit(str[s + 1])) || | |||
| 319 | ((str[s] == '1') && base::IsInRange(str[s + 1], '0', '2'))) { | |||
| 320 | *out = ToInt(str[s]) * 10 + ToInt(str[s + 1]); | |||
| 321 | return 2; | |||
| 322 | } | |||
| 323 | return 0; | |||
| 324 | } | |||
| 325 | ||||
| 326 | // DateDay: | |||
| 327 | // 0 NonzeroDigit | |||
| 328 | // 1 Digit | |||
| 329 | // 2 Digit | |||
| 330 | // 30 | |||
| 331 | // 31 | |||
| 332 | template <typename Char> | |||
| 333 | int32_t ScanDateDay(base::Vector<Char> str, int32_t s, int32_t* out) { | |||
| 334 | if (str.length() < (s + 2)) return 0; | |||
| 335 | if (((str[s] == '0') && IsNonZeroDecimalDigit(str[s + 1])) || | |||
| 336 | (base::IsInRange(str[s], '1', '2') && IsDecimalDigit(str[s + 1])) || | |||
| 337 | ((str[s] == '3') && base::IsInRange(str[s + 1], '0', '1'))) { | |||
| 338 | *out = ToInt(str[s]) * 10 + ToInt(str[s + 1]); | |||
| 339 | return 2; | |||
| 340 | } | |||
| 341 | return 0; | |||
| 342 | } | |||
| 343 | ||||
| 344 | // Date: | |||
| 345 | // DateYear - DateMonth - DateDay | |||
| 346 | // DateYear DateMonth DateDay | |||
| 347 | template <typename Char> | |||
| 348 | int32_t ScanDate(base::Vector<Char> str, int32_t s, ParsedISO8601Result* r) { | |||
| 349 | int32_t date_year, date_month, date_day; | |||
| 350 | int32_t cur = s; | |||
| 351 | int32_t len; | |||
| 352 | if ((len = ScanDateYear(str, cur, &date_year)) == 0) return 0; | |||
| 353 | if (((cur += len) + 1) > str.length()) return 0; | |||
| 354 | if (str[cur] == '-') { | |||
| 355 | cur++; | |||
| 356 | if ((len = ScanDateMonth(str, cur, &date_month)) == 0) return 0; | |||
| 357 | cur += len; | |||
| 358 | if (((cur + 1) > str.length()) || (str[cur++] != '-')) return 0; | |||
| 359 | } else { | |||
| 360 | if ((len = ScanDateMonth(str, cur, &date_month)) == 0) return 0; | |||
| 361 | cur += len; | |||
| 362 | } | |||
| 363 | if ((len = ScanDateDay(str, cur, &date_day)) == 0) return 0; | |||
| 364 | r->date_year = date_year; | |||
| 365 | r->date_month = date_month; | |||
| 366 | r->date_day = date_day; | |||
| 367 | return cur + len - s; | |||
| 368 | } | |||
| 369 | ||||
| 370 | // TimeZoneUTCOffsetHour: Hour | |||
| 371 | SCAN_FORWARD(TimeZoneUTCOffsetHour, Hour, int32_t)template <typename Char> int32_t ScanTimeZoneUTCOffsetHour (base::Vector<Char> str, int32_t s, int32_t* r) { return ScanHour(str, s, r); } | |||
| 372 | ||||
| 373 | // TimeZoneUTCOffsetMinute | |||
| 374 | SCAN_FORWARD(TimeZoneUTCOffsetMinute, MinuteSecond, int32_t)template <typename Char> int32_t ScanTimeZoneUTCOffsetMinute (base::Vector<Char> str, int32_t s, int32_t* r) { return ScanMinuteSecond(str, s, r); } | |||
| 375 | ||||
| 376 | // TimeZoneUTCOffsetSecond | |||
| 377 | SCAN_FORWARD(TimeZoneUTCOffsetSecond, MinuteSecond, int32_t)template <typename Char> int32_t ScanTimeZoneUTCOffsetSecond (base::Vector<Char> str, int32_t s, int32_t* r) { return ScanMinuteSecond(str, s, r); } | |||
| 378 | ||||
| 379 | // TimeZoneUTCOffsetFractionalPart: FractionalPart | |||
| 380 | // See PR1796 | |||
| 381 | SCAN_FORWARD(TimeZoneUTCOffsetFractionalPart, FractionalPart, int32_t)template <typename Char> int32_t ScanTimeZoneUTCOffsetFractionalPart (base::Vector<Char> str, int32_t s, int32_t* r) { return ScanFractionalPart(str, s, r); } | |||
| 382 | ||||
| 383 | // TimeZoneUTCOffsetFraction: DecimalSeparator TimeZoneUTCOffsetFractionalPart | |||
| 384 | // See PR1796 | |||
| 385 | template <typename Char> | |||
| 386 | int32_t ScanTimeZoneUTCOffsetFraction(base::Vector<Char> str, int32_t s, | |||
| 387 | int32_t* out) { | |||
| 388 | if ((str.length() < (s + 2)) || (!IsDecimalSeparator(str[s]))) return 0; | |||
| 389 | int32_t len; | |||
| 390 | if ((len = ScanTimeZoneUTCOffsetFractionalPart(str, s + 1, out)) > 0) { | |||
| 391 | return len + 1; | |||
| 392 | } | |||
| 393 | return 0; | |||
| 394 | } | |||
| 395 | ||||
| 396 | // Note: "TimeZoneUTCOffset" is abbreviated as "TZUO" below | |||
| 397 | // TimeZoneNumericUTCOffset: | |||
| 398 | // TZUOSign TZUOHour | |||
| 399 | // TZUOSign TZUOHour : TZUOMinute | |||
| 400 | // TZUOSign TZUOHour : TZUOMinute : TZUOSecond [TZUOFraction] | |||
| 401 | // TZUOSign TZUOHour TZUOMinute | |||
| 402 | // TZUOSign TZUOHour TZUOMinute TZUOSecond [TZUOFraction] | |||
| 403 | template <typename Char> | |||
| 404 | int32_t ScanTimeZoneNumericUTCOffset(base::Vector<Char> str, int32_t s, | |||
| 405 | ParsedISO8601Result* r) { | |||
| 406 | int32_t len, hour, minute, second, nanosecond; | |||
| 407 | int32_t cur = s; | |||
| 408 | if ((str.length() < (cur + 1)) || (!IsSign(str[cur]))) return 0; | |||
| 409 | int32_t sign = (CanonicalSign(str[cur++]) == '-') ? -1 : 1; | |||
| 410 | if ((len = ScanTimeZoneUTCOffsetHour(str, cur, &hour)) == 0) return 0; | |||
| 411 | cur += len; | |||
| 412 | if ((cur + 1) > str.length()) { | |||
| 413 | // TZUOSign TZUOHour | |||
| 414 | r->tzuo_sign = sign; | |||
| 415 | r->tzuo_hour = hour; | |||
| 416 | return cur - s; | |||
| 417 | } | |||
| 418 | if (str[cur] == ':') { | |||
| 419 | cur++; | |||
| 420 | if ((len = ScanTimeZoneUTCOffsetMinute(str, cur, &minute)) == 0) return 0; | |||
| 421 | cur += len; | |||
| 422 | if ((cur + 1) > str.length() || str[cur] != ':') { | |||
| 423 | // TZUOSign TZUOHour : TZUOMinute | |||
| 424 | r->tzuo_sign = sign; | |||
| 425 | r->tzuo_hour = hour; | |||
| 426 | r->tzuo_minute = minute; | |||
| 427 | return cur - s; | |||
| 428 | } | |||
| 429 | cur++; | |||
| 430 | if ((len = ScanTimeZoneUTCOffsetSecond(str, cur, &second)) == 0) return 0; | |||
| 431 | } else { | |||
| 432 | if ((len = ScanTimeZoneUTCOffsetMinute(str, cur, &minute)) == 0) { | |||
| 433 | // TZUOSign TZUOHour | |||
| 434 | r->tzuo_sign = sign; | |||
| 435 | r->tzuo_hour = hour; | |||
| 436 | return cur - s; | |||
| 437 | } | |||
| 438 | cur += len; | |||
| 439 | if ((len = ScanTimeZoneUTCOffsetSecond(str, cur, &second)) == 0) { | |||
| 440 | // TZUOSign TZUOHour TZUOMinute | |||
| 441 | r->tzuo_sign = sign; | |||
| 442 | r->tzuo_hour = hour; | |||
| 443 | r->tzuo_minute = minute; | |||
| 444 | return cur - s; | |||
| 445 | } | |||
| 446 | } | |||
| 447 | cur += len; | |||
| 448 | len = ScanTimeZoneUTCOffsetFraction(str, cur, &nanosecond); | |||
| 449 | r->tzuo_sign = sign; | |||
| 450 | r->tzuo_hour = hour; | |||
| 451 | r->tzuo_minute = minute; | |||
| 452 | r->tzuo_second = second; | |||
| 453 | if (len > 0) r->tzuo_nanosecond = nanosecond; | |||
| 454 | return cur + len - s; | |||
| 455 | } | |||
| 456 | ||||
| 457 | // TimeZoneUTCOffset: | |||
| 458 | // TimeZoneNumericUTCOffset | |||
| 459 | // UTCDesignator | |||
| 460 | template <typename Char> | |||
| 461 | int32_t ScanTimeZoneUTCOffset(base::Vector<Char> str, int32_t s, | |||
| 462 | ParsedISO8601Result* r) { | |||
| 463 | if (str.length() < (s + 1)) return 0; | |||
| 464 | if (AsciiAlphaToLower(str[s]) == 'z') { | |||
| 465 | // UTCDesignator | |||
| 466 | r->utc_designator = true; | |||
| 467 | return 1; | |||
| 468 | } | |||
| 469 | // TimeZoneNumericUTCOffset | |||
| 470 | return ScanTimeZoneNumericUTCOffset(str, s, r); | |||
| 471 | } | |||
| 472 | ||||
| 473 | // TimeZoneIANANameComponent : | |||
| 474 | // TZLeadingChar TZChar{0,13} but not one of . or .. | |||
| 475 | template <typename Char> | |||
| 476 | int32_t ScanTimeZoneIANANameComponent(base::Vector<Char> str, int32_t s) { | |||
| 477 | int32_t cur = s; | |||
| 478 | if (str.length() < (cur + 1) || !IsTZLeadingChar(str[cur++])) return 0; | |||
| 479 | while (((cur) < str.length()) && ((cur - s) < 14) && IsTZChar(str[cur])) { | |||
| 480 | cur++; | |||
| 481 | } | |||
| 482 | if ((cur - s) == 1 && str[s] == '.') return 0; | |||
| 483 | if ((cur - s) == 2 && str[s] == '.' && str[s + 1] == '.') return 0; | |||
| 484 | return cur - s; | |||
| 485 | } | |||
| 486 | ||||
| 487 | // TimeZoneIANANameTail : | |||
| 488 | // TimeZoneIANANameComponent | |||
| 489 | // TimeZoneIANANameComponent / TimeZoneIANANameTail | |||
| 490 | // TimeZoneIANAName : | |||
| 491 | // TimeZoneIANANameTail | |||
| 492 | // The spec text use tail recusion with TimeZoneIANANameComponent and | |||
| 493 | // TimeZoneIANANameTail. In our implementation, we use an iteration loop | |||
| 494 | // instead. | |||
| 495 | template <typename Char> | |||
| 496 | int32_t ScanTimeZoneIANAName(base::Vector<Char> str, int32_t s) { | |||
| 497 | int32_t cur = s; | |||
| 498 | int32_t len; | |||
| 499 | if ((len = ScanTimeZoneIANANameComponent(str, cur)) == 0) return 0; | |||
| 500 | cur += len; | |||
| 501 | while ((str.length() > (cur + 1)) && (str[cur] == '/')) { | |||
| 502 | cur++; | |||
| 503 | if ((len = ScanTimeZoneIANANameComponent(str, cur)) == 0) { | |||
| 504 | return 0; | |||
| 505 | } | |||
| 506 | // TimeZoneIANANameComponent / TimeZoneIANAName | |||
| 507 | cur += len; | |||
| 508 | } | |||
| 509 | return cur - s; | |||
| 510 | } | |||
| 511 | ||||
| 512 | template <typename Char> | |||
| 513 | int32_t ScanTimeZoneIANAName(base::Vector<Char> str, int32_t s, | |||
| 514 | ParsedISO8601Result* r) { | |||
| 515 | int32_t len; | |||
| 516 | if ((len = ScanTimeZoneIANAName(str, s)) == 0) return 0; | |||
| 517 | r->tzi_name_start = s; | |||
| 518 | r->tzi_name_length = len; | |||
| 519 | return len; | |||
| 520 | } | |||
| 521 | ||||
| 522 | // TimeZoneUTCOffsetName | |||
| 523 | // Sign Hour | |||
| 524 | // Sign Hour : MinuteSecond | |||
| 525 | // Sign Hour MinuteSecond | |||
| 526 | // Sign Hour : MinuteSecond : MinuteSecond [Fraction] | |||
| 527 | // Sign Hour MinuteSecond MinuteSecond [Fraction] | |||
| 528 | // | |||
| 529 | template <typename Char> | |||
| 530 | int32_t ScanTimeZoneUTCOffsetName(base::Vector<Char> str, int32_t s) { | |||
| 531 | int32_t cur = s; | |||
| 532 | int32_t len; | |||
| 533 | if ((str.length() < (s + 3)) || !IsSign(str[cur++])) return 0; | |||
| 534 | int32_t hour, minute, second, fraction; | |||
| 535 | if ((len = ScanHour(str, cur, &hour)) == 0) return 0; | |||
| 536 | cur += len; | |||
| 537 | if ((cur + 1) > str.length()) { | |||
| 538 | // Sign Hour | |||
| 539 | return cur - s; | |||
| 540 | } | |||
| 541 | if (str[cur] == ':') { | |||
| 542 | // Sign Hour : | |||
| 543 | cur++; | |||
| 544 | if ((len = ScanMinuteSecond(str, cur, &minute)) == 0) return 0; | |||
| 545 | cur += len; | |||
| 546 | if ((cur + 1) > str.length() || (str[cur] != ':')) { | |||
| 547 | // Sign Hour : MinuteSecond | |||
| 548 | return cur - s; | |||
| 549 | } | |||
| 550 | cur++; | |||
| 551 | // Sign Hour : MinuteSecond : | |||
| 552 | if ((len = ScanMinuteSecond(str, cur, &second)) == 0) return 0; | |||
| 553 | cur += len; | |||
| 554 | len = ScanFraction(str, cur, &fraction); | |||
| 555 | return cur + len - s; | |||
| 556 | } else { | |||
| 557 | if ((len = ScanMinuteSecond(str, cur, &minute)) == 0) { | |||
| 558 | // Sign Hour | |||
| 559 | return cur - s; | |||
| 560 | } | |||
| 561 | cur += len; | |||
| 562 | if ((len = ScanMinuteSecond(str, cur, &second)) == 0) { | |||
| 563 | // Sign Hour MinuteSecond | |||
| 564 | return cur - s; | |||
| 565 | } | |||
| 566 | cur += len; | |||
| 567 | len = ScanFraction(str, cur, &fraction); | |||
| 568 | // Sign Hour MinuteSecond MinuteSecond [Fraction] | |||
| 569 | return cur + len - s; | |||
| 570 | } | |||
| 571 | } | |||
| 572 | ||||
| 573 | // TimeZoneBracketedName | |||
| 574 | // TimeZoneIANAName | |||
| 575 | // "Etc/GMT" ASCIISign Hour | |||
| 576 | // TimeZoneUTCOffsetName | |||
| 577 | // Since "Etc/GMT" also fit TimeZoneIANAName so we need to try | |||
| 578 | // "Etc/GMT" ASCIISign Hour first. | |||
| 579 | template <typename Char> | |||
| 580 | int32_t ScanEtcGMTAsciiSignHour(base::Vector<Char> str, int32_t s) { | |||
| 581 | if ((s + 10) > str.length()) return 0; | |||
| 582 | int32_t cur = s; | |||
| 583 | if ((str[cur++] != 'E') || (str[cur++] != 't') || (str[cur++] != 'c') || | |||
| 584 | (str[cur++] != '/') || (str[cur++] != 'G') || (str[cur++] != 'M') || | |||
| 585 | (str[cur++] != 'T')) { | |||
| 586 | return 0; | |||
| 587 | } | |||
| 588 | Char sign = str[cur++]; | |||
| 589 | if (!IsAsciiSign(sign)) return 0; | |||
| 590 | int32_t hour; | |||
| 591 | int32_t len = ScanHour(str, cur, &hour); | |||
| 592 | if (len == 0) return 0; | |||
| 593 | // "Etc/GMT" ASCIISign Hour | |||
| 594 | return 10; | |||
| 595 | } | |||
| 596 | ||||
| 597 | template <typename Char> | |||
| 598 | int32_t ScanTimeZoneBracketedName(base::Vector<Char> str, int32_t s, | |||
| 599 | ParsedISO8601Result* r) { | |||
| 600 | int32_t len; | |||
| 601 | if ((len = ScanEtcGMTAsciiSignHour(str, s)) > 0) return len; | |||
| 602 | if ((len = ScanTimeZoneIANAName(str, s)) > 0) { | |||
| 603 | r->tzi_name_start = s; | |||
| 604 | r->tzi_name_length = len; | |||
| 605 | return len; | |||
| 606 | } | |||
| 607 | return ScanTimeZoneUTCOffsetName(str, s); | |||
| 608 | } | |||
| 609 | ||||
| 610 | // TimeZoneBracketedAnnotation: '[' TimeZoneBracketedName ']' | |||
| 611 | template <typename Char> | |||
| 612 | int32_t ScanTimeZoneBracketedAnnotation(base::Vector<Char> str, int32_t s, | |||
| 613 | ParsedISO8601Result* r) { | |||
| 614 | if ((str.length() < (s + 3)) || (str[s] != '[')) return 0; | |||
| 615 | int32_t cur = s + 1; | |||
| 616 | cur += ScanTimeZoneBracketedName(str, cur, r); | |||
| 617 | if ((cur - s == 1) || str.length() < (cur + 1) || (str[cur++] != ']')) { | |||
| 618 | return 0; | |||
| 619 | } | |||
| 620 | return cur - s; | |||
| 621 | } | |||
| 622 | ||||
| 623 | // TimeZoneOffsetRequired: | |||
| 624 | // TimeZoneUTCOffset [TimeZoneBracketedAnnotation] | |||
| 625 | template <typename Char> | |||
| 626 | int32_t ScanTimeZoneOffsetRequired(base::Vector<Char> str, int32_t s, | |||
| 627 | ParsedISO8601Result* r) { | |||
| 628 | int32_t cur = s; | |||
| 629 | cur += ScanTimeZoneUTCOffset(str, cur, r); | |||
| 630 | if (cur == s) return 0; | |||
| 631 | return cur + ScanTimeZoneBracketedAnnotation(str, cur, r) - s; | |||
| 632 | } | |||
| 633 | ||||
| 634 | // TimeZoneNameRequired: | |||
| 635 | // [TimeZoneUTCOffset] TimeZoneBracketedAnnotation | |||
| 636 | template <typename Char> | |||
| 637 | int32_t ScanTimeZoneNameRequired(base::Vector<Char> str, int32_t s, | |||
| 638 | ParsedISO8601Result* r) { | |||
| 639 | int32_t cur = s; | |||
| 640 | cur += ScanTimeZoneUTCOffset(str, cur, r); | |||
| 641 | int32_t len = ScanTimeZoneBracketedAnnotation(str, cur, r); | |||
| 642 | if (len == 0) return 0; | |||
| 643 | return cur + len - s; | |||
| 644 | } | |||
| 645 | ||||
| 646 | // TimeZone: | |||
| 647 | // TimeZoneOffsetRequired | |||
| 648 | // TimeZoneNameRequired | |||
| 649 | // The lookahead is at most 1 char. | |||
| 650 | SCAN_EITHER_FORWARD(TimeZone, TimeZoneOffsetRequired, TimeZoneNameRequired,template <typename Char> int32_t ScanTimeZone(base::Vector <Char> str, int32_t s, ParsedISO8601Result* r) { int32_t len; if ((len = ScanTimeZoneOffsetRequired(str, s, r)) > 0 ) return len; return ScanTimeZoneNameRequired(str, s, r); } | |||
| 651 | ParsedISO8601Result)template <typename Char> int32_t ScanTimeZone(base::Vector <Char> str, int32_t s, ParsedISO8601Result* r) { int32_t len; if ((len = ScanTimeZoneOffsetRequired(str, s, r)) > 0 ) return len; return ScanTimeZoneNameRequired(str, s, r); } | |||
| 652 | ||||
| 653 | // CalendarNameComponent: | |||
| 654 | // CalChar {3,8} | |||
| 655 | template <typename Char> | |||
| 656 | int32_t ScanCalendarNameComponent(base::Vector<Char> str, int32_t s) { | |||
| 657 | int32_t cur = s; | |||
| 658 | while ((cur < str.length()) && IsAlphaNumeric(str[cur])) cur++; | |||
| 659 | if ((cur - s) < 3 || (cur - s) > 8) return 0; | |||
| 660 | return (cur - s); | |||
| 661 | } | |||
| 662 | ||||
| 663 | // CalendarNameTail : | |||
| 664 | // CalendarNameComponent | |||
| 665 | // CalendarNameComponent - CalendarNameTail | |||
| 666 | // CalendarName : | |||
| 667 | // CalendarNameTail | |||
| 668 | // The spec text use tail recusion with CalendarNameComponent and | |||
| 669 | // CalendarNameTail. In our implementation, we use an iteration loop instead. | |||
| 670 | template <typename Char> | |||
| 671 | int32_t ScanCalendarName(base::Vector<Char> str, int32_t s, | |||
| 672 | ParsedISO8601Result* r) { | |||
| 673 | int32_t cur = s; | |||
| 674 | int32_t len; | |||
| 675 | if ((len = ScanCalendarNameComponent(str, cur)) == 0) return 0; | |||
| 676 | cur += len; | |||
| 677 | while ((str.length() > (cur + 1)) && (str[cur++] == '-')) { | |||
| 678 | if ((len = ScanCalendarNameComponent(str, cur)) == 0) return 0; | |||
| 679 | // CalendarNameComponent - CalendarName | |||
| 680 | cur += len; | |||
| 681 | } | |||
| 682 | r->calendar_name_start = s; | |||
| 683 | r->calendar_name_length = cur - s; | |||
| 684 | return cur - s; | |||
| 685 | } | |||
| 686 | ||||
| 687 | // Calendar: '[u-ca=' CalendarName ']' | |||
| 688 | template <typename Char> | |||
| 689 | int32_t ScanCalendar(base::Vector<Char> str, int32_t s, | |||
| 690 | ParsedISO8601Result* r) { | |||
| 691 | if (str.length() < (s + 7)) return 0; | |||
| 692 | int32_t cur = s; | |||
| 693 | // "[u-ca=" | |||
| 694 | if ((str[cur++] != '[') || (str[cur++] != 'u') || (str[cur++] != '-') || | |||
| 695 | (str[cur++] != 'c') || (str[cur++] != 'a') || (str[cur++] != '=')) { | |||
| 696 | return 0; | |||
| 697 | } | |||
| 698 | int32_t len = ScanCalendarName(str, cur, r); | |||
| 699 | if (len == 0) return 0; | |||
| 700 | if ((str.length() < (cur + len + 1)) || (str[cur + len] != ']')) { | |||
| 701 | return 0; | |||
| 702 | } | |||
| 703 | return 6 + len + 1; | |||
| 704 | } | |||
| 705 | ||||
| 706 | // CalendarTime: TimeSpec [TimeZone] [Calendar] | |||
| 707 | template <typename Char> | |||
| 708 | int32_t ScanCalendarTime(base::Vector<Char> str, int32_t s, | |||
| 709 | ParsedISO8601Result* r) { | |||
| 710 | int32_t cur = s; | |||
| 711 | cur += ScanTimeSpec(str, cur, r); | |||
| 712 | if (cur - s == 0) return 0; | |||
| 713 | cur += ScanTimeZone(str, cur, r); | |||
| 714 | cur += ScanCalendar(str, cur, r); | |||
| 715 | return cur - s; | |||
| 716 | } | |||
| 717 | ||||
| 718 | // DateTime: Date [TimeSpecSeparator][TimeZone] | |||
| 719 | template <typename Char> | |||
| 720 | int32_t ScanDateTime(base::Vector<Char> str, int32_t s, | |||
| 721 | ParsedISO8601Result* r) { | |||
| 722 | int32_t cur = s; | |||
| 723 | cur += ScanDate(str, cur, r); | |||
| 724 | if (cur == s) return 0; | |||
| 725 | cur += ScanTimeSpecSeparator(str, cur, r); | |||
| 726 | return cur + ScanTimeZone(str, cur, r) - s; | |||
| 727 | } | |||
| 728 | ||||
| 729 | // DateSpecYearMonth: DateYear ['-'] DateMonth | |||
| 730 | template <typename Char> | |||
| 731 | int32_t ScanDateSpecYearMonth(base::Vector<Char> str, int32_t s, | |||
| 732 | ParsedISO8601Result* r) { | |||
| 733 | int32_t date_year, date_month; | |||
| 734 | int32_t cur = s; | |||
| 735 | cur += ScanDateYear(str, cur, &date_year); | |||
| 736 | if (cur == s) return 0; | |||
| 737 | if (str.length() < (cur + 1)) return 0; | |||
| 738 | if (str[cur] == '-') cur++; | |||
| 739 | int32_t len = ScanDateMonth(str, cur, &date_month); | |||
| 740 | if (len == 0) return 0; | |||
| 741 | r->date_year = date_year; | |||
| 742 | r->date_month = date_month; | |||
| 743 | return cur + len - s; | |||
| 744 | } | |||
| 745 | ||||
| 746 | // DateSpecMonthDay: | |||
| 747 | // TwoDashopt DateMonth -opt DateDay | |||
| 748 | template <typename Char> | |||
| 749 | int32_t ScanDateSpecMonthDay(base::Vector<Char> str, int32_t s, | |||
| 750 | ParsedISO8601Result* r) { | |||
| 751 | if (str.length() < (s + 4)) return 0; | |||
| 752 | int32_t cur = s; | |||
| 753 | if (str[cur] == '-') { | |||
| 754 | // The first two dash are optional together | |||
| 755 | if (str[++cur] != '-') return 0; | |||
| 756 | // TwoDash | |||
| 757 | cur++; | |||
| 758 | } | |||
| 759 | int32_t date_month, date_day; | |||
| 760 | int32_t len = ScanDateMonth(str, cur, &date_month); | |||
| 761 | if (len == 0) return 0; | |||
| 762 | cur += len; | |||
| 763 | if (str.length() < (cur + 1)) return 0; | |||
| 764 | // '-' | |||
| 765 | if (str[cur] == '-') cur++; | |||
| 766 | len = ScanDateDay(str, cur, &date_day); | |||
| 767 | if (len == 0) return 0; | |||
| 768 | r->date_month = date_month; | |||
| 769 | r->date_day = date_day; | |||
| 770 | return cur + len - s; | |||
| 771 | } | |||
| 772 | ||||
| 773 | // TemporalTimeZoneIdentifier: | |||
| 774 | // TimeZoneNumericUTCOffset | |||
| 775 | // TimeZoneIANAName | |||
| 776 | template <typename Char> | |||
| 777 | int32_t ScanTemporalTimeZoneIdentifier(base::Vector<Char> str, int32_t s, | |||
| 778 | ParsedISO8601Result* r) { | |||
| 779 | int32_t len; | |||
| 780 | if ((len = ScanTimeZoneNumericUTCOffset(str, s, r)) > 0) return len; | |||
| 781 | if ((len = ScanTimeZoneIANAName(str, s)) == 0) return 0; | |||
| 782 | r->tzi_name_start = s; | |||
| 783 | r->tzi_name_length = len; | |||
| 784 | return len; | |||
| 785 | } | |||
| 786 | ||||
| 787 | // CalendarDateTime: DateTime [Calendar] | |||
| 788 | template <typename Char> | |||
| 789 | int32_t ScanCalendarDateTime(base::Vector<Char> str, int32_t s, | |||
| 790 | ParsedISO8601Result* r) { | |||
| 791 | int32_t len = ScanDateTime(str, 0, r); | |||
| 792 | if (len == 0) return 0; | |||
| 793 | return len + ScanCalendar(str, len, r); | |||
| 794 | } | |||
| 795 | ||||
| 796 | // TemporalZonedDateTimeString: | |||
| 797 | // Date [TimeSpecSeparator] TimeZoneNameRequired [Calendar] | |||
| 798 | template <typename Char> | |||
| 799 | int32_t ScanTemporalZonedDateTimeString(base::Vector<Char> str, int32_t s, | |||
| 800 | ParsedISO8601Result* r) { | |||
| 801 | // Date | |||
| 802 | int32_t cur = s; | |||
| 803 | cur += ScanDate(str, cur, r); | |||
| 804 | if (cur == s) return 0; | |||
| 805 | ||||
| 806 | // TimeSpecSeparator | |||
| 807 | cur += ScanTimeSpecSeparator(str, cur, r); | |||
| 808 | ||||
| 809 | // TimeZoneNameRequired | |||
| 810 | int32_t len = ScanTimeZoneNameRequired(str, cur, r); | |||
| 811 | if (len == 0) return 0; | |||
| 812 | cur += len; | |||
| 813 | ||||
| 814 | // Calendar | |||
| 815 | return cur + ScanCalendar(str, cur, r) - s; | |||
| 816 | } | |||
| 817 | ||||
| 818 | SCAN_FORWARD(TemporalDateString, CalendarDateTime, ParsedISO8601Result)template <typename Char> int32_t ScanTemporalDateString (base::Vector<Char> str, int32_t s, ParsedISO8601Result * r) { return ScanCalendarDateTime(str, s, r); } | |||
| 819 | SCAN_FORWARD(TemporalDateTimeString, CalendarDateTime, ParsedISO8601Result)template <typename Char> int32_t ScanTemporalDateTimeString (base::Vector<Char> str, int32_t s, ParsedISO8601Result * r) { return ScanCalendarDateTime(str, s, r); } | |||
| 820 | ||||
| 821 | // TemporalTimeZoneString: | |||
| 822 | // TemporalTimeZoneIdentifier | |||
| 823 | // Date [TimeSpecSeparator] TimeZone [Calendar] | |||
| 824 | template <typename Char> | |||
| 825 | int32_t ScanDate_TimeSpecSeparator_TimeZone_Calendar(base::Vector<Char> str, | |||
| 826 | int32_t s, | |||
| 827 | ParsedISO8601Result* r) { | |||
| 828 | int32_t cur = s; | |||
| 829 | cur += ScanDate(str, cur, r); | |||
| 830 | if (cur == s) return 0; | |||
| 831 | cur += ScanTimeSpecSeparator(str, cur, r); | |||
| 832 | int32_t len = ScanTimeZone(str, cur, r); | |||
| 833 | if (len == 0) return 0; | |||
| 834 | cur += len; | |||
| 835 | return cur + ScanCalendar(str, cur, r) - s; | |||
| 836 | } | |||
| 837 | ||||
| 838 | // The lookahead is at most 8 chars. | |||
| 839 | SCAN_EITHER_FORWARD(TemporalTimeZoneString, TemporalTimeZoneIdentifier,template <typename Char> int32_t ScanTemporalTimeZoneString (base::Vector<Char> str, int32_t s, ParsedISO8601Result * r) { int32_t len; if ((len = ScanTemporalTimeZoneIdentifier (str, s, r)) > 0) return len; return ScanDate_TimeSpecSeparator_TimeZone_Calendar (str, s, r); } | |||
| 840 | Date_TimeSpecSeparator_TimeZone_Calendar,template <typename Char> int32_t ScanTemporalTimeZoneString (base::Vector<Char> str, int32_t s, ParsedISO8601Result * r) { int32_t len; if ((len = ScanTemporalTimeZoneIdentifier (str, s, r)) > 0) return len; return ScanDate_TimeSpecSeparator_TimeZone_Calendar (str, s, r); } | |||
| 841 | ParsedISO8601Result)template <typename Char> int32_t ScanTemporalTimeZoneString (base::Vector<Char> str, int32_t s, ParsedISO8601Result * r) { int32_t len; if ((len = ScanTemporalTimeZoneIdentifier (str, s, r)) > 0) return len; return ScanDate_TimeSpecSeparator_TimeZone_Calendar (str, s, r); } | |||
| 842 | ||||
| 843 | // TemporalTimeString | |||
| 844 | // CalendarTime | |||
| 845 | // CalendarDateTime | |||
| 846 | // The lookahead is at most 7 chars. | |||
| 847 | SCAN_EITHER_FORWARD(TemporalTimeString, CalendarTime, CalendarDateTime,template <typename Char> int32_t ScanTemporalTimeString (base::Vector<Char> str, int32_t s, ParsedISO8601Result * r) { int32_t len; if ((len = ScanCalendarTime(str, s, r)) > 0) return len; return ScanCalendarDateTime(str, s, r); } | |||
| 848 | ParsedISO8601Result)template <typename Char> int32_t ScanTemporalTimeString (base::Vector<Char> str, int32_t s, ParsedISO8601Result * r) { int32_t len; if ((len = ScanCalendarTime(str, s, r)) > 0) return len; return ScanCalendarDateTime(str, s, r); } | |||
| 849 | ||||
| 850 | // TemporalYearMonthString: | |||
| 851 | // DateSpecYearMonth | |||
| 852 | // CalendarDateTime | |||
| 853 | // The lookahead is at most 11 chars. | |||
| 854 | SCAN_EITHER_FORWARD(TemporalYearMonthString, DateSpecYearMonth,template <typename Char> int32_t ScanTemporalYearMonthString (base::Vector<Char> str, int32_t s, ParsedISO8601Result * r) { int32_t len; if ((len = ScanDateSpecYearMonth(str, s, r )) > 0) return len; return ScanCalendarDateTime(str, s, r) ; } | |||
| 855 | CalendarDateTime, ParsedISO8601Result)template <typename Char> int32_t ScanTemporalYearMonthString (base::Vector<Char> str, int32_t s, ParsedISO8601Result * r) { int32_t len; if ((len = ScanDateSpecYearMonth(str, s, r )) > 0) return len; return ScanCalendarDateTime(str, s, r) ; } | |||
| 856 | ||||
| 857 | // TemporalMonthDayString | |||
| 858 | // DateSpecMonthDay | |||
| 859 | // CalendarDateTime | |||
| 860 | // The lookahead is at most 5 chars. | |||
| 861 | SCAN_EITHER_FORWARD(TemporalMonthDayString, DateSpecMonthDay, CalendarDateTime,template <typename Char> int32_t ScanTemporalMonthDayString (base::Vector<Char> str, int32_t s, ParsedISO8601Result * r) { int32_t len; if ((len = ScanDateSpecMonthDay(str, s, r )) > 0) return len; return ScanCalendarDateTime(str, s, r) ; } | |||
| 862 | ParsedISO8601Result)template <typename Char> int32_t ScanTemporalMonthDayString (base::Vector<Char> str, int32_t s, ParsedISO8601Result * r) { int32_t len; if ((len = ScanDateSpecMonthDay(str, s, r )) > 0) return len; return ScanCalendarDateTime(str, s, r) ; } | |||
| 863 | ||||
| 864 | // TemporalRelativeToString: | |||
| 865 | // TemporalDateTimeString | |||
| 866 | // TemporalZonedDateTimeString | |||
| 867 | // TemporalZonedDateTimeString is subset of TemporalDateTimeString | |||
| 868 | // See https://github.com/tc39/proposal-temporal/issues/1939 | |||
| 869 | SCAN_FORWARD(TemporalRelativeToString, TemporalDateTimeString,template <typename Char> int32_t ScanTemporalRelativeToString (base::Vector<Char> str, int32_t s, ParsedISO8601Result * r) { return ScanTemporalDateTimeString(str, s, r); } | |||
| 870 | ParsedISO8601Result)template <typename Char> int32_t ScanTemporalRelativeToString (base::Vector<Char> str, int32_t s, ParsedISO8601Result * r) { return ScanTemporalDateTimeString(str, s, r); } | |||
| 871 | ||||
| 872 | // TemporalInstantString | |||
| 873 | // Date TimeZoneOffsetRequired | |||
| 874 | // Date DateTimeSeparator TimeSpec TimeZoneOffsetRequired | |||
| 875 | template <typename Char> | |||
| 876 | int32_t ScanTemporalInstantString(base::Vector<Char> str, int32_t s, | |||
| 877 | ParsedISO8601Result* r) { | |||
| 878 | // Date | |||
| 879 | int32_t cur = s; | |||
| 880 | cur += ScanDate(str, cur, r); | |||
| 881 | if (cur == s) return 0; | |||
| 882 | ||||
| 883 | // TimeZoneOffsetRequired | |||
| 884 | int32_t len = ScanTimeZoneOffsetRequired(str, cur, r); | |||
| 885 | if (len > 0) return cur + len - s; | |||
| 886 | ||||
| 887 | // DateTimeSeparator | |||
| 888 | if (!(((cur + 1) < str.length()) && IsDateTimeSeparator(str[cur++]))) { | |||
| 889 | return 0; | |||
| 890 | } | |||
| 891 | // TimeSpec | |||
| 892 | len = ScanTimeSpec(str, cur, r); | |||
| 893 | if (len == 0) return 0; | |||
| 894 | cur += len; | |||
| 895 | ||||
| 896 | // TimeZoneOffsetRequired | |||
| 897 | len = ScanTimeZoneOffsetRequired(str, cur, r); | |||
| 898 | if (len == 0) return 0; | |||
| 899 | return cur + len - s; | |||
| 900 | } | |||
| 901 | ||||
| 902 | // ============================================================================== | |||
| 903 | #define SATISIFY(T, R)template <typename Char> bool SatisfyT(base::Vector< Char> str, R* r) { R ret; int32_t len = ScanT(str, 0, & ret); if ((len > 0) && (len == str.length())) { *r = ret; return true; } return false; } \ | |||
| 904 | template <typename Char> \ | |||
| 905 | bool Satisfy##T(base::Vector<Char> str, R* r) { \ | |||
| 906 | R ret; \ | |||
| 907 | int32_t len = Scan##T(str, 0, &ret); \ | |||
| 908 | if ((len > 0) && (len == str.length())) { \ | |||
| 909 | *r = ret; \ | |||
| 910 | return true; \ | |||
| 911 | } \ | |||
| 912 | return false; \ | |||
| 913 | } | |||
| 914 | ||||
| 915 | #define IF_SATISFY_RETURN(T){ if (SatisfyT(str, r)) return true; } \ | |||
| 916 | { \ | |||
| 917 | if (Satisfy##T(str, r)) return true; \ | |||
| 918 | } | |||
| 919 | ||||
| 920 | #define SATISIFY_EITHER(T1, T2, T3, R)template <typename Char> bool SatisfyT1(base::Vector< Char> str, R* r) { { if (SatisfyT2(str, r)) return true; } { if (SatisfyT3(str, r)) return true; } return false; } \ | |||
| 921 | template <typename Char> \ | |||
| 922 | bool Satisfy##T1(base::Vector<Char> str, R* r) { \ | |||
| 923 | IF_SATISFY_RETURN(T2){ if (SatisfyT2(str, r)) return true; } \ | |||
| 924 | IF_SATISFY_RETURN(T3){ if (SatisfyT3(str, r)) return true; } \ | |||
| 925 | return false; \ | |||
| 926 | } | |||
| 927 | ||||
| 928 | SATISIFY(TemporalDateTimeString, ParsedISO8601Result)template <typename Char> bool SatisfyTemporalDateTimeString (base::Vector<Char> str, ParsedISO8601Result* r) { ParsedISO8601Result ret; int32_t len = ScanTemporalDateTimeString(str, 0, &ret ); if ((len > 0) && (len == str.length())) { *r = ret ; return true; } return false; } | |||
| 929 | SATISIFY(TemporalDateString, ParsedISO8601Result)template <typename Char> bool SatisfyTemporalDateString (base::Vector<Char> str, ParsedISO8601Result* r) { ParsedISO8601Result ret; int32_t len = ScanTemporalDateString(str, 0, &ret); if ((len > 0) && (len == str.length())) { *r = ret ; return true; } return false; } | |||
| 930 | SATISIFY(CalendarTime, ParsedISO8601Result)template <typename Char> bool SatisfyCalendarTime(base:: Vector<Char> str, ParsedISO8601Result* r) { ParsedISO8601Result ret; int32_t len = ScanCalendarTime(str, 0, &ret); if (( len > 0) && (len == str.length())) { *r = ret; return true; } return false; } | |||
| 931 | SATISIFY(DateTime, ParsedISO8601Result)template <typename Char> bool SatisfyDateTime(base::Vector <Char> str, ParsedISO8601Result* r) { ParsedISO8601Result ret; int32_t len = ScanDateTime(str, 0, &ret); if ((len > 0) && (len == str.length())) { *r = ret; return true ; } return false; } | |||
| 932 | SATISIFY(DateSpecYearMonth, ParsedISO8601Result)template <typename Char> bool SatisfyDateSpecYearMonth( base::Vector<Char> str, ParsedISO8601Result* r) { ParsedISO8601Result ret; int32_t len = ScanDateSpecYearMonth(str, 0, &ret); if ((len > 0) && (len == str.length())) { *r = ret; return true; } return false; } | |||
| 933 | SATISIFY(DateSpecMonthDay, ParsedISO8601Result)template <typename Char> bool SatisfyDateSpecMonthDay(base ::Vector<Char> str, ParsedISO8601Result* r) { ParsedISO8601Result ret; int32_t len = ScanDateSpecMonthDay(str, 0, &ret); if ((len > 0) && (len == str.length())) { *r = ret; return true; } return false; } | |||
| 934 | SATISIFY(Date_TimeSpecSeparator_TimeZone_Calendar, ParsedISO8601Result)template <typename Char> bool SatisfyDate_TimeSpecSeparator_TimeZone_Calendar (base::Vector<Char> str, ParsedISO8601Result* r) { ParsedISO8601Result ret; int32_t len = ScanDate_TimeSpecSeparator_TimeZone_Calendar (str, 0, &ret); if ((len > 0) && (len == str.length ())) { *r = ret; return true; } return false; } | |||
| 935 | SATISIFY(CalendarDateTime, ParsedISO8601Result)template <typename Char> bool SatisfyCalendarDateTime(base ::Vector<Char> str, ParsedISO8601Result* r) { ParsedISO8601Result ret; int32_t len = ScanCalendarDateTime(str, 0, &ret); if ((len > 0) && (len == str.length())) { *r = ret; return true; } return false; } | |||
| 936 | SATISIFY_EITHER(TemporalTimeString, CalendarTime, CalendarDateTime,template <typename Char> bool SatisfyTemporalTimeString (base::Vector<Char> str, ParsedISO8601Result* r) { { if (SatisfyCalendarTime(str, r)) return true; } { if (SatisfyCalendarDateTime (str, r)) return true; } return false; } | |||
| 937 | ParsedISO8601Result)template <typename Char> bool SatisfyTemporalTimeString (base::Vector<Char> str, ParsedISO8601Result* r) { { if (SatisfyCalendarTime(str, r)) return true; } { if (SatisfyCalendarDateTime (str, r)) return true; } return false; } | |||
| 938 | SATISIFY_EITHER(TemporalYearMonthString, DateSpecYearMonth, CalendarDateTime,template <typename Char> bool SatisfyTemporalYearMonthString (base::Vector<Char> str, ParsedISO8601Result* r) { { if (SatisfyDateSpecYearMonth(str, r)) return true; } { if (SatisfyCalendarDateTime (str, r)) return true; } return false; } | |||
| 939 | ParsedISO8601Result)template <typename Char> bool SatisfyTemporalYearMonthString (base::Vector<Char> str, ParsedISO8601Result* r) { { if (SatisfyDateSpecYearMonth(str, r)) return true; } { if (SatisfyCalendarDateTime (str, r)) return true; } return false; } | |||
| 940 | SATISIFY_EITHER(TemporalMonthDayString, DateSpecMonthDay, CalendarDateTime,template <typename Char> bool SatisfyTemporalMonthDayString (base::Vector<Char> str, ParsedISO8601Result* r) { { if (SatisfyDateSpecMonthDay(str, r)) return true; } { if (SatisfyCalendarDateTime (str, r)) return true; } return false; } | |||
| 941 | ParsedISO8601Result)template <typename Char> bool SatisfyTemporalMonthDayString (base::Vector<Char> str, ParsedISO8601Result* r) { { if (SatisfyDateSpecMonthDay(str, r)) return true; } { if (SatisfyCalendarDateTime (str, r)) return true; } return false; } | |||
| 942 | SATISIFY(TimeZoneNumericUTCOffset, ParsedISO8601Result)template <typename Char> bool SatisfyTimeZoneNumericUTCOffset (base::Vector<Char> str, ParsedISO8601Result* r) { ParsedISO8601Result ret; int32_t len = ScanTimeZoneNumericUTCOffset(str, 0, & ret); if ((len > 0) && (len == str.length())) { *r = ret; return true; } return false; } | |||
| 943 | SATISIFY(TimeZoneIANAName, ParsedISO8601Result)template <typename Char> bool SatisfyTimeZoneIANAName(base ::Vector<Char> str, ParsedISO8601Result* r) { ParsedISO8601Result ret; int32_t len = ScanTimeZoneIANAName(str, 0, &ret); if ((len > 0) && (len == str.length())) { *r = ret; return true; } return false; } | |||
| 944 | SATISIFY_EITHER(TemporalTimeZoneIdentifier, TimeZoneNumericUTCOffset,template <typename Char> bool SatisfyTemporalTimeZoneIdentifier (base::Vector<Char> str, ParsedISO8601Result* r) { { if (SatisfyTimeZoneNumericUTCOffset(str, r)) return true; } { if (SatisfyTimeZoneIANAName(str, r)) return true; } return false ; } | |||
| 945 | TimeZoneIANAName, ParsedISO8601Result)template <typename Char> bool SatisfyTemporalTimeZoneIdentifier (base::Vector<Char> str, ParsedISO8601Result* r) { { if (SatisfyTimeZoneNumericUTCOffset(str, r)) return true; } { if (SatisfyTimeZoneIANAName(str, r)) return true; } return false ; } | |||
| 946 | SATISIFY_EITHER(TemporalTimeZoneString, TemporalTimeZoneIdentifier,template <typename Char> bool SatisfyTemporalTimeZoneString (base::Vector<Char> str, ParsedISO8601Result* r) { { if (SatisfyTemporalTimeZoneIdentifier(str, r)) return true; } { if (SatisfyDate_TimeSpecSeparator_TimeZone_Calendar(str, r)) return true; } return false; } | |||
| 947 | Date_TimeSpecSeparator_TimeZone_Calendar, ParsedISO8601Result)template <typename Char> bool SatisfyTemporalTimeZoneString (base::Vector<Char> str, ParsedISO8601Result* r) { { if (SatisfyTemporalTimeZoneIdentifier(str, r)) return true; } { if (SatisfyDate_TimeSpecSeparator_TimeZone_Calendar(str, r)) return true; } return false; } | |||
| 948 | SATISIFY(TemporalInstantString, ParsedISO8601Result)template <typename Char> bool SatisfyTemporalInstantString (base::Vector<Char> str, ParsedISO8601Result* r) { ParsedISO8601Result ret; int32_t len = ScanTemporalInstantString(str, 0, &ret ); if ((len > 0) && (len == str.length())) { *r = ret ; return true; } return false; } | |||
| 949 | SATISIFY(TemporalZonedDateTimeString, ParsedISO8601Result)template <typename Char> bool SatisfyTemporalZonedDateTimeString (base::Vector<Char> str, ParsedISO8601Result* r) { ParsedISO8601Result ret; int32_t len = ScanTemporalZonedDateTimeString(str, 0, & ret); if ((len > 0) && (len == str.length())) { *r = ret; return true; } return false; } | |||
| 950 | ||||
| 951 | SATISIFY_EITHER(TemporalRelativeToString, TemporalDateTimeString,template <typename Char> bool SatisfyTemporalRelativeToString (base::Vector<Char> str, ParsedISO8601Result* r) { { if (SatisfyTemporalDateTimeString(str, r)) return true; } { if ( SatisfyTemporalZonedDateTimeString(str, r)) return true; } return false; } | |||
| 952 | TemporalZonedDateTimeString, ParsedISO8601Result)template <typename Char> bool SatisfyTemporalRelativeToString (base::Vector<Char> str, ParsedISO8601Result* r) { { if (SatisfyTemporalDateTimeString(str, r)) return true; } { if ( SatisfyTemporalZonedDateTimeString(str, r)) return true; } return false; } | |||
| 953 | ||||
| 954 | SATISIFY(CalendarName, ParsedISO8601Result)template <typename Char> bool SatisfyCalendarName(base:: Vector<Char> str, ParsedISO8601Result* r) { ParsedISO8601Result ret; int32_t len = ScanCalendarName(str, 0, &ret); if (( len > 0) && (len == str.length())) { *r = ret; return true; } return false; } | |||
| 955 | ||||
| 956 | template <typename Char> | |||
| 957 | bool SatisfyTemporalCalendarString(base::Vector<Char> str, | |||
| 958 | ParsedISO8601Result* r) { | |||
| 959 | IF_SATISFY_RETURN(CalendarName){ if (SatisfyCalendarName(str, r)) return true; } | |||
| 960 | IF_SATISFY_RETURN(TemporalInstantString){ if (SatisfyTemporalInstantString(str, r)) return true; } | |||
| 961 | IF_SATISFY_RETURN(CalendarDateTime){ if (SatisfyCalendarDateTime(str, r)) return true; } | |||
| 962 | IF_SATISFY_RETURN(CalendarTime){ if (SatisfyCalendarTime(str, r)) return true; } | |||
| 963 | IF_SATISFY_RETURN(DateSpecYearMonth){ if (SatisfyDateSpecYearMonth(str, r)) return true; } | |||
| 964 | IF_SATISFY_RETURN(DateSpecMonthDay){ if (SatisfyDateSpecMonthDay(str, r)) return true; } | |||
| 965 | return false; | |||
| 966 | } | |||
| 967 | ||||
| 968 | // Duration | |||
| 969 | ||||
| 970 | SCAN_FORWARD(TimeFractionalPart, FractionalPart, int64_t)template <typename Char> int32_t ScanTimeFractionalPart (base::Vector<Char> str, int32_t s, int64_t* r) { return ScanFractionalPart(str, s, r); } | |||
| 971 | ||||
| 972 | template <typename Char> | |||
| 973 | int32_t ScanFraction(base::Vector<Char> str, int32_t s, int64_t* out) { | |||
| 974 | if (str.length() < (s + 2) || !IsDecimalSeparator(str[s])) return 0; | |||
| 975 | int32_t len = ScanTimeFractionalPart(str, s + 1, out); | |||
| 976 | return (len == 0) ? 0 : len + 1; | |||
| 977 | } | |||
| 978 | ||||
| 979 | SCAN_FORWARD(TimeFraction, Fraction, int64_t)template <typename Char> int32_t ScanTimeFraction(base:: Vector<Char> str, int32_t s, int64_t* r) { return ScanFraction (str, s, r); } | |||
| 980 | ||||
| 981 | // Digits : Digit [Digits] | |||
| 982 | ||||
| 983 | template <typename Char> | |||
| 984 | int32_t ScanDigits(base::Vector<Char> str, int32_t s, int64_t* out) { | |||
| 985 | if (str.length() < (s + 1) || !IsDecimalDigit(str[s])) return 0; | |||
| 986 | *out = ToInt(str[s]); | |||
| 987 | int32_t len = 1; | |||
| 988 | while (s + len + 1 <= str.length() && IsDecimalDigit(str[s + len])) { | |||
| 989 | *out = 10 * (*out) + ToInt(str[s + len]); | |||
| 990 | len++; | |||
| 991 | } | |||
| 992 | return len; | |||
| 993 | } | |||
| 994 | ||||
| 995 | SCAN_FORWARD(DurationYears, Digits, int64_t)template <typename Char> int32_t ScanDurationYears(base ::Vector<Char> str, int32_t s, int64_t* r) { return ScanDigits (str, s, r); } | |||
| 996 | SCAN_FORWARD(DurationMonths, Digits, int64_t)template <typename Char> int32_t ScanDurationMonths(base ::Vector<Char> str, int32_t s, int64_t* r) { return ScanDigits (str, s, r); } | |||
| 997 | SCAN_FORWARD(DurationWeeks, Digits, int64_t)template <typename Char> int32_t ScanDurationWeeks(base ::Vector<Char> str, int32_t s, int64_t* r) { return ScanDigits (str, s, r); } | |||
| 998 | SCAN_FORWARD(DurationDays, Digits, int64_t)template <typename Char> int32_t ScanDurationDays(base:: Vector<Char> str, int32_t s, int64_t* r) { return ScanDigits (str, s, r); } | |||
| 999 | ||||
| 1000 | // DurationWholeHours : Digits | |||
| 1001 | SCAN_FORWARD(DurationWholeHours, Digits, int64_t)template <typename Char> int32_t ScanDurationWholeHours (base::Vector<Char> str, int32_t s, int64_t* r) { return ScanDigits(str, s, r); } | |||
| 1002 | ||||
| 1003 | // DurationWholeMinutes : Digits | |||
| 1004 | SCAN_FORWARD(DurationWholeMinutes, Digits, int64_t)template <typename Char> int32_t ScanDurationWholeMinutes (base::Vector<Char> str, int32_t s, int64_t* r) { return ScanDigits(str, s, r); } | |||
| 1005 | ||||
| 1006 | // DurationWholeSeconds : Digits | |||
| 1007 | SCAN_FORWARD(DurationWholeSeconds, Digits, int64_t)template <typename Char> int32_t ScanDurationWholeSeconds (base::Vector<Char> str, int32_t s, int64_t* r) { return ScanDigits(str, s, r); } | |||
| 1008 | ||||
| 1009 | // DurationHoursFraction : TimeFraction | |||
| 1010 | SCAN_FORWARD(DurationHoursFraction, TimeFraction, int64_t)template <typename Char> int32_t ScanDurationHoursFraction (base::Vector<Char> str, int32_t s, int64_t* r) { return ScanTimeFraction(str, s, r); } | |||
| 1011 | ||||
| 1012 | // DurationMinutesFraction : TimeFraction | |||
| 1013 | SCAN_FORWARD(DurationMinutesFraction, TimeFraction, int64_t)template <typename Char> int32_t ScanDurationMinutesFraction (base::Vector<Char> str, int32_t s, int64_t* r) { return ScanTimeFraction(str, s, r); } | |||
| 1014 | ||||
| 1015 | // DurationSecondsFraction : TimeFraction | |||
| 1016 | SCAN_FORWARD(DurationSecondsFraction, TimeFraction, int64_t)template <typename Char> int32_t ScanDurationSecondsFraction (base::Vector<Char> str, int32_t s, int64_t* r) { return ScanTimeFraction(str, s, r); } | |||
| 1017 | ||||
| 1018 | #define DURATION_WHOLE_FRACTION_DESIGNATOR(Name, name, d)template <typename Char> int32_t ScanDurationWholeNameFractionDesignator ( base::Vector<Char> str, int32_t s, ParsedISO8601Duration * r) { int32_t cur = s; int64_t whole = 0; cur += ScanDurationWholeName (str, cur, &whole); if (cur == s) return 0; int64_t fraction = 0; int32_t len = ScanDurationNameFraction(str, cur, &fraction ); cur += len; if (str.length() < (cur + 1) || AsciiAlphaToLower (str[cur++]) != (d)) return 0; r->whole_name = whole; r-> name_fraction = fraction; return cur - s; } \ | |||
| 1019 | template <typename Char> \ | |||
| 1020 | int32_t ScanDurationWhole##Name##FractionDesignator( \ | |||
| 1021 | base::Vector<Char> str, int32_t s, ParsedISO8601Duration* r) { \ | |||
| 1022 | int32_t cur = s; \ | |||
| 1023 | int64_t whole = 0; \ | |||
| 1024 | cur += ScanDurationWhole##Name(str, cur, &whole); \ | |||
| 1025 | if (cur == s) return 0; \ | |||
| 1026 | int64_t fraction = 0; \ | |||
| 1027 | int32_t len = ScanDuration##Name##Fraction(str, cur, &fraction); \ | |||
| 1028 | cur += len; \ | |||
| 1029 | if (str.length() < (cur + 1) || AsciiAlphaToLower(str[cur++]) != (d)) \ | |||
| 1030 | return 0; \ | |||
| 1031 | r->whole_##name = whole; \ | |||
| 1032 | r->name##_fraction = fraction; \ | |||
| 1033 | return cur - s; \ | |||
| 1034 | } | |||
| 1035 | ||||
| 1036 | DURATION_WHOLE_FRACTION_DESIGNATOR(Seconds, seconds, 's')template <typename Char> int32_t ScanDurationWholeSecondsFractionDesignator ( base::Vector<Char> str, int32_t s, ParsedISO8601Duration * r) { int32_t cur = s; int64_t whole = 0; cur += ScanDurationWholeSeconds (str, cur, &whole); if (cur == s) return 0; int64_t fraction = 0; int32_t len = ScanDurationSecondsFraction(str, cur, & fraction); cur += len; if (str.length() < (cur + 1) || AsciiAlphaToLower (str[cur++]) != ('s')) return 0; r->whole_seconds = whole; r->seconds_fraction = fraction; return cur - s; } | |||
| 1037 | DURATION_WHOLE_FRACTION_DESIGNATOR(Minutes, minutes, 'm')template <typename Char> int32_t ScanDurationWholeMinutesFractionDesignator ( base::Vector<Char> str, int32_t s, ParsedISO8601Duration * r) { int32_t cur = s; int64_t whole = 0; cur += ScanDurationWholeMinutes (str, cur, &whole); if (cur == s) return 0; int64_t fraction = 0; int32_t len = ScanDurationMinutesFraction(str, cur, & fraction); cur += len; if (str.length() < (cur + 1) || AsciiAlphaToLower (str[cur++]) != ('m')) return 0; r->whole_minutes = whole; r->minutes_fraction = fraction; return cur - s; } | |||
| 1038 | DURATION_WHOLE_FRACTION_DESIGNATOR(Hours, hours, 'h')template <typename Char> int32_t ScanDurationWholeHoursFractionDesignator ( base::Vector<Char> str, int32_t s, ParsedISO8601Duration * r) { int32_t cur = s; int64_t whole = 0; cur += ScanDurationWholeHours (str, cur, &whole); if (cur == s) return 0; int64_t fraction = 0; int32_t len = ScanDurationHoursFraction(str, cur, & fraction); cur += len; if (str.length() < (cur + 1) || AsciiAlphaToLower (str[cur++]) != ('h')) return 0; r->whole_hours = whole; r ->hours_fraction = fraction; return cur - s; } | |||
| ||||
| 1039 | ||||
| 1040 | // DurationSecondsPart : | |||
| 1041 | // DurationWholeSeconds DurationSecondsFractionopt SecondsDesignator | |||
| 1042 | SCAN_FORWARD(DurationSecondsPart, DurationWholeSecondsFractionDesignator,template <typename Char> int32_t ScanDurationSecondsPart (base::Vector<Char> str, int32_t s, ParsedISO8601Duration * r) { return ScanDurationWholeSecondsFractionDesignator(str, s, r); } | |||
| 1043 | ParsedISO8601Duration)template <typename Char> int32_t ScanDurationSecondsPart (base::Vector<Char> str, int32_t s, ParsedISO8601Duration * r) { return ScanDurationWholeSecondsFractionDesignator(str, s, r); } | |||
| 1044 | ||||
| 1045 | // DurationMinutesPart : | |||
| 1046 | // DurationWholeMinutes DurationMinutesFractionopt MinutesDesignator | |||
| 1047 | // [DurationSecondsPart] | |||
| 1048 | template <typename Char> | |||
| 1049 | int32_t ScanDurationMinutesPart(base::Vector<Char> str, int32_t s, | |||
| 1050 | ParsedISO8601Duration* r) { | |||
| 1051 | int32_t cur = s + ScanDurationWholeMinutesFractionDesignator(str, s, r); | |||
| 1052 | if (cur == s) return 0; | |||
| 1053 | return cur + ScanDurationSecondsPart(str, cur, r) - s; | |||
| 1054 | } | |||
| 1055 | ||||
| 1056 | // DurationHoursPart : | |||
| 1057 | // DurationWholeHours DurationHoursFractionopt HoursDesignator | |||
| 1058 | // DurationMinutesPart | |||
| 1059 | // | |||
| 1060 | // DurationWholeHours DurationHoursFractionopt HoursDesignator | |||
| 1061 | // [DurationSecondsPart] | |||
| 1062 | template <typename Char> | |||
| 1063 | int32_t ScanDurationHoursPart(base::Vector<Char> str, int32_t s, | |||
| 1064 | ParsedISO8601Duration* r) { | |||
| 1065 | int32_t cur = s + ScanDurationWholeHoursFractionDesignator(str, s, r); | |||
| 1066 | if (cur == s) return 0; | |||
| 1067 | int32_t len = ScanDurationMinutesPart(str, cur, r); | |||
| 1068 | if (len > 0) return cur + len - s; | |||
| 1069 | return cur + ScanDurationSecondsPart(str, cur, r) - s; | |||
| 1070 | } | |||
| 1071 | ||||
| 1072 | // DurationTime : | |||
| 1073 | // DurationTimeDesignator DurationHoursPart | |||
| 1074 | // DurationTimeDesignator DurationMinutesPart | |||
| 1075 | // DurationTimeDesignator DurationSecondsPart | |||
| 1076 | template <typename Char> | |||
| 1077 | int32_t ScanDurationTime(base::Vector<Char> str, int32_t s, | |||
| 1078 | ParsedISO8601Duration* r) { | |||
| 1079 | int32_t cur = s; | |||
| 1080 | if (str.length() < (s + 1)) return 0; | |||
| 1081 | if (AsciiAlphaToLower(str[cur++]) != 't') return 0; | |||
| 1082 | if ((cur += ScanDurationHoursPart(str, cur, r)) - s > 1) return cur - s; | |||
| 1083 | if ((cur += ScanDurationMinutesPart(str, cur, r)) - s > 1) return cur - s; | |||
| 1084 | if ((cur += ScanDurationSecondsPart(str, cur, r)) - s > 1) return cur - s; | |||
| 1085 | return 0; | |||
| 1086 | } | |||
| 1087 | ||||
| 1088 | #define DURATION_AND_DESIGNATOR(Name, name, d)template <typename Char> int32_t ScanDurationNameDesignator (base::Vector<Char> str, int32_t s, ParsedISO8601Duration * r) { int32_t cur = s; int64_t name; if ((cur += ScanDurationName (str, cur, &name)) == s) return 0; if (str.length() < ( cur + 1) || AsciiAlphaToLower(str[cur++]) != (d)) { return 0; } r->name = name; return cur - s; } \ | |||
| 1089 | template <typename Char> \ | |||
| 1090 | int32_t ScanDuration##Name##Designator(base::Vector<Char> str, int32_t s, \ | |||
| 1091 | ParsedISO8601Duration* r) { \ | |||
| 1092 | int32_t cur = s; \ | |||
| 1093 | int64_t name; \ | |||
| 1094 | if ((cur += ScanDuration##Name(str, cur, &name)) == s) return 0; \ | |||
| 1095 | if (str.length() < (cur + 1) || AsciiAlphaToLower(str[cur++]) != (d)) { \ | |||
| 1096 | return 0; \ | |||
| 1097 | } \ | |||
| 1098 | r->name = name; \ | |||
| 1099 | return cur - s; \ | |||
| 1100 | } | |||
| 1101 | ||||
| 1102 | DURATION_AND_DESIGNATOR(Days, days, 'd')template <typename Char> int32_t ScanDurationDaysDesignator (base::Vector<Char> str, int32_t s, ParsedISO8601Duration * r) { int32_t cur = s; int64_t days; if ((cur += ScanDurationDays (str, cur, &days)) == s) return 0; if (str.length() < ( cur + 1) || AsciiAlphaToLower(str[cur++]) != ('d')) { return 0 ; } r->days = days; return cur - s; } | |||
| 1103 | DURATION_AND_DESIGNATOR(Weeks, weeks, 'w')template <typename Char> int32_t ScanDurationWeeksDesignator (base::Vector<Char> str, int32_t s, ParsedISO8601Duration * r) { int32_t cur = s; int64_t weeks; if ((cur += ScanDurationWeeks (str, cur, &weeks)) == s) return 0; if (str.length() < (cur + 1) || AsciiAlphaToLower(str[cur++]) != ('w')) { return 0; } r->weeks = weeks; return cur - s; } | |||
| 1104 | DURATION_AND_DESIGNATOR(Months, months, 'm')template <typename Char> int32_t ScanDurationMonthsDesignator (base::Vector<Char> str, int32_t s, ParsedISO8601Duration * r) { int32_t cur = s; int64_t months; if ((cur += ScanDurationMonths (str, cur, &months)) == s) return 0; if (str.length() < (cur + 1) || AsciiAlphaToLower(str[cur++]) != ('m')) { return 0; } r->months = months; return cur - s; } | |||
| 1105 | DURATION_AND_DESIGNATOR(Years, years, 'y')template <typename Char> int32_t ScanDurationYearsDesignator (base::Vector<Char> str, int32_t s, ParsedISO8601Duration * r) { int32_t cur = s; int64_t years; if ((cur += ScanDurationYears (str, cur, &years)) == s) return 0; if (str.length() < (cur + 1) || AsciiAlphaToLower(str[cur++]) != ('y')) { return 0; } r->years = years; return cur - s; } | |||
| 1106 | ||||
| 1107 | // DurationDaysPart : DurationDays DaysDesignator | |||
| 1108 | SCAN_FORWARD(DurationDaysPart, DurationDaysDesignator, ParsedISO8601Duration)template <typename Char> int32_t ScanDurationDaysPart(base ::Vector<Char> str, int32_t s, ParsedISO8601Duration* r ) { return ScanDurationDaysDesignator(str, s, r); } | |||
| 1109 | ||||
| 1110 | // DurationWeeksPart : DurationWeeks WeeksDesignator [DurationDaysPart] | |||
| 1111 | template <typename Char> | |||
| 1112 | int32_t ScanDurationWeeksPart(base::Vector<Char> str, int32_t s, | |||
| 1113 | ParsedISO8601Duration* r) { | |||
| 1114 | int32_t cur = s; | |||
| 1115 | if ((cur += ScanDurationWeeksDesignator(str, cur, r)) == s) return 0; | |||
| 1116 | return cur + ScanDurationDaysPart(str, cur, r) - s; | |||
| 1117 | } | |||
| 1118 | ||||
| 1119 | // DurationMonthsPart : | |||
| 1120 | // DurationMonths MonthsDesignator DurationWeeksPart | |||
| 1121 | // DurationMonths MonthsDesignator [DurationDaysPart] | |||
| 1122 | template <typename Char> | |||
| 1123 | int32_t ScanDurationMonthsPart(base::Vector<Char> str, int32_t s, | |||
| 1124 | ParsedISO8601Duration* r) { | |||
| 1125 | int32_t cur = s; | |||
| 1126 | int32_t len; | |||
| 1127 | if ((cur += ScanDurationMonthsDesignator(str, cur, r)) == s) return 0; | |||
| 1128 | if ((len = ScanDurationWeeksPart(str, cur, r)) > 0) return cur + len - s; | |||
| 1129 | return cur + ScanDurationDaysPart(str, cur, r) - s; | |||
| 1130 | } | |||
| 1131 | ||||
| 1132 | // DurationYearsPart : | |||
| 1133 | // DurationYears YearsDesignator DurationMonthsPart | |||
| 1134 | // DurationYears YearsDesignator DurationWeeksPart | |||
| 1135 | // DurationYears YearsDesignator [DurationDaysPart] | |||
| 1136 | template <typename Char> | |||
| 1137 | int32_t ScanDurationYearsPart(base::Vector<Char> str, int32_t s, | |||
| 1138 | ParsedISO8601Duration* r) { | |||
| 1139 | int32_t cur = s; | |||
| 1140 | int32_t len; | |||
| 1141 | if ((cur += ScanDurationYearsDesignator(str, cur, r)) == s) return 0; | |||
| 1142 | if ((len = ScanDurationMonthsPart(str, cur, r)) > 0) return cur + len - s; | |||
| 1143 | if ((len = ScanDurationWeeksPart(str, cur, r)) > 0) return cur + len - s; | |||
| 1144 | return cur + ScanDurationDaysPart(str, cur, r) - s; | |||
| 1145 | } | |||
| 1146 | ||||
| 1147 | // DurationDate : | |||
| 1148 | // DurationYearsPart [DurationTime] | |||
| 1149 | // DurationMonthsPart [DurationTime] | |||
| 1150 | // DurationWeeksPart [DurationTime] | |||
| 1151 | // DurationDaysPart [DurationTime] | |||
| 1152 | template <typename Char> | |||
| 1153 | int32_t ScanDurationDate(base::Vector<Char> str, int32_t s, | |||
| 1154 | ParsedISO8601Duration* r) { | |||
| 1155 | int32_t cur = s; | |||
| 1156 | do { | |||
| 1157 | if ((cur += ScanDurationYearsPart(str, cur, r)) > s) break; | |||
| 1158 | if ((cur += ScanDurationMonthsPart(str, cur, r)) > s) break; | |||
| 1159 | if ((cur += ScanDurationWeeksPart(str, cur, r)) > s) break; | |||
| 1160 | if ((cur += ScanDurationDaysPart(str, cur, r)) > s) break; | |||
| 1161 | return 0; | |||
| 1162 | } while (false); | |||
| 1163 | return cur + ScanDurationTime(str, cur, r) - s; | |||
| 1164 | } | |||
| 1165 | ||||
| 1166 | // Duration : | |||
| 1167 | // Signopt DurationDesignator DurationDate | |||
| 1168 | // Signopt DurationDesignator DurationTime | |||
| 1169 | template <typename Char> | |||
| 1170 | int32_t ScanDuration(base::Vector<Char> str, int32_t s, | |||
| 1171 | ParsedISO8601Duration* r) { | |||
| 1172 | if (str.length() < (s + 2)) return 0; | |||
| 1173 | int32_t cur = s; | |||
| 1174 | int32_t sign = | |||
| 1175 | (IsSign(str[cur]) && CanonicalSign(str[cur++]) == '-') ? -1 : 1; | |||
| 1176 | if (AsciiAlphaToLower(str[cur++]) != 'p') return 0; | |||
| 1177 | int32_t len = ScanDurationDate(str, cur, r); | |||
| 1178 | if (len == 0) len = ScanDurationTime(str, cur, r); | |||
| 1179 | if (len == 0) return 0; | |||
| 1180 | r->sign = sign; | |||
| 1181 | return cur + len - s; | |||
| 1182 | } | |||
| 1183 | SCAN_FORWARD(TemporalDurationString, Duration, ParsedISO8601Duration)template <typename Char> int32_t ScanTemporalDurationString (base::Vector<Char> str, int32_t s, ParsedISO8601Duration * r) { return ScanDuration(str, s, r); } | |||
| 1184 | ||||
| 1185 | SATISIFY(TemporalDurationString, ParsedISO8601Duration)template <typename Char> bool SatisfyTemporalDurationString (base::Vector<Char> str, ParsedISO8601Duration* r) { ParsedISO8601Duration ret; int32_t len = ScanTemporalDurationString(str, 0, &ret ); if ((len > 0) && (len == str.length())) { *r = ret ; return true; } return false; } | |||
| 1186 | ||||
| 1187 | } // namespace | |||
| 1188 | ||||
| 1189 | #define IMPL_PARSE_METHOD(R, NAME)Maybe<R> TemporalParser::ParseNAME(Isolate* isolate, Handle <String> iso_string) { bool valid; R parsed; iso_string = String::Flatten(isolate, iso_string); { DisallowGarbageCollection no_gc; String::FlatContent str_content = iso_string->GetFlatContent (no_gc); if (str_content.IsOneByte()) { valid = SatisfyNAME(str_content .ToOneByteVector(), &parsed); } else { valid = SatisfyNAME (str_content.ToUC16Vector(), &parsed); } } if (valid) return Just(parsed); return Nothing<R>(); } \ | |||
| 1190 | Maybe<R> TemporalParser::Parse##NAME(Isolate* isolate, \ | |||
| 1191 | Handle<String> iso_string) { \ | |||
| 1192 | bool valid; \ | |||
| 1193 | R parsed; \ | |||
| 1194 | iso_string = String::Flatten(isolate, iso_string); \ | |||
| 1195 | { \ | |||
| 1196 | DisallowGarbageCollection no_gc; \ | |||
| 1197 | String::FlatContent str_content = iso_string->GetFlatContent(no_gc); \ | |||
| 1198 | if (str_content.IsOneByte()) { \ | |||
| 1199 | valid = Satisfy##NAME(str_content.ToOneByteVector(), &parsed); \ | |||
| 1200 | } else { \ | |||
| 1201 | valid = Satisfy##NAME(str_content.ToUC16Vector(), &parsed); \ | |||
| 1202 | } \ | |||
| 1203 | } \ | |||
| 1204 | if (valid) return Just(parsed); \ | |||
| 1205 | return Nothing<R>(); \ | |||
| 1206 | } | |||
| 1207 | ||||
| 1208 | IMPL_PARSE_METHOD(ParsedISO8601Result, TemporalDateTimeString)Maybe<ParsedISO8601Result> TemporalParser::ParseTemporalDateTimeString (Isolate* isolate, Handle<String> iso_string) { bool valid ; ParsedISO8601Result parsed; iso_string = String::Flatten(isolate , iso_string); { DisallowGarbageCollection no_gc; String::FlatContent str_content = iso_string->GetFlatContent(no_gc); if (str_content .IsOneByte()) { valid = SatisfyTemporalDateTimeString(str_content .ToOneByteVector(), &parsed); } else { valid = SatisfyTemporalDateTimeString (str_content.ToUC16Vector(), &parsed); } } if (valid) return Just(parsed); return Nothing<ParsedISO8601Result>(); } | |||
| 1209 | IMPL_PARSE_METHOD(ParsedISO8601Result, TemporalDateString)Maybe<ParsedISO8601Result> TemporalParser::ParseTemporalDateString (Isolate* isolate, Handle<String> iso_string) { bool valid ; ParsedISO8601Result parsed; iso_string = String::Flatten(isolate , iso_string); { DisallowGarbageCollection no_gc; String::FlatContent str_content = iso_string->GetFlatContent(no_gc); if (str_content .IsOneByte()) { valid = SatisfyTemporalDateString(str_content .ToOneByteVector(), &parsed); } else { valid = SatisfyTemporalDateString (str_content.ToUC16Vector(), &parsed); } } if (valid) return Just(parsed); return Nothing<ParsedISO8601Result>(); } | |||
| 1210 | IMPL_PARSE_METHOD(ParsedISO8601Result, TemporalYearMonthString)Maybe<ParsedISO8601Result> TemporalParser::ParseTemporalYearMonthString (Isolate* isolate, Handle<String> iso_string) { bool valid ; ParsedISO8601Result parsed; iso_string = String::Flatten(isolate , iso_string); { DisallowGarbageCollection no_gc; String::FlatContent str_content = iso_string->GetFlatContent(no_gc); if (str_content .IsOneByte()) { valid = SatisfyTemporalYearMonthString(str_content .ToOneByteVector(), &parsed); } else { valid = SatisfyTemporalYearMonthString (str_content.ToUC16Vector(), &parsed); } } if (valid) return Just(parsed); return Nothing<ParsedISO8601Result>(); } | |||
| 1211 | IMPL_PARSE_METHOD(ParsedISO8601Result, TemporalMonthDayString)Maybe<ParsedISO8601Result> TemporalParser::ParseTemporalMonthDayString (Isolate* isolate, Handle<String> iso_string) { bool valid ; ParsedISO8601Result parsed; iso_string = String::Flatten(isolate , iso_string); { DisallowGarbageCollection no_gc; String::FlatContent str_content = iso_string->GetFlatContent(no_gc); if (str_content .IsOneByte()) { valid = SatisfyTemporalMonthDayString(str_content .ToOneByteVector(), &parsed); } else { valid = SatisfyTemporalMonthDayString (str_content.ToUC16Vector(), &parsed); } } if (valid) return Just(parsed); return Nothing<ParsedISO8601Result>(); } | |||
| 1212 | IMPL_PARSE_METHOD(ParsedISO8601Result, TemporalTimeString)Maybe<ParsedISO8601Result> TemporalParser::ParseTemporalTimeString (Isolate* isolate, Handle<String> iso_string) { bool valid ; ParsedISO8601Result parsed; iso_string = String::Flatten(isolate , iso_string); { DisallowGarbageCollection no_gc; String::FlatContent str_content = iso_string->GetFlatContent(no_gc); if (str_content .IsOneByte()) { valid = SatisfyTemporalTimeString(str_content .ToOneByteVector(), &parsed); } else { valid = SatisfyTemporalTimeString (str_content.ToUC16Vector(), &parsed); } } if (valid) return Just(parsed); return Nothing<ParsedISO8601Result>(); } | |||
| 1213 | IMPL_PARSE_METHOD(ParsedISO8601Result, TemporalInstantString)Maybe<ParsedISO8601Result> TemporalParser::ParseTemporalInstantString (Isolate* isolate, Handle<String> iso_string) { bool valid ; ParsedISO8601Result parsed; iso_string = String::Flatten(isolate , iso_string); { DisallowGarbageCollection no_gc; String::FlatContent str_content = iso_string->GetFlatContent(no_gc); if (str_content .IsOneByte()) { valid = SatisfyTemporalInstantString(str_content .ToOneByteVector(), &parsed); } else { valid = SatisfyTemporalInstantString (str_content.ToUC16Vector(), &parsed); } } if (valid) return Just(parsed); return Nothing<ParsedISO8601Result>(); } | |||
| 1214 | IMPL_PARSE_METHOD(ParsedISO8601Result, TemporalZonedDateTimeString)Maybe<ParsedISO8601Result> TemporalParser::ParseTemporalZonedDateTimeString (Isolate* isolate, Handle<String> iso_string) { bool valid ; ParsedISO8601Result parsed; iso_string = String::Flatten(isolate , iso_string); { DisallowGarbageCollection no_gc; String::FlatContent str_content = iso_string->GetFlatContent(no_gc); if (str_content .IsOneByte()) { valid = SatisfyTemporalZonedDateTimeString(str_content .ToOneByteVector(), &parsed); } else { valid = SatisfyTemporalZonedDateTimeString (str_content.ToUC16Vector(), &parsed); } } if (valid) return Just(parsed); return Nothing<ParsedISO8601Result>(); } | |||
| 1215 | IMPL_PARSE_METHOD(ParsedISO8601Result, TemporalTimeZoneString)Maybe<ParsedISO8601Result> TemporalParser::ParseTemporalTimeZoneString (Isolate* isolate, Handle<String> iso_string) { bool valid ; ParsedISO8601Result parsed; iso_string = String::Flatten(isolate , iso_string); { DisallowGarbageCollection no_gc; String::FlatContent str_content = iso_string->GetFlatContent(no_gc); if (str_content .IsOneByte()) { valid = SatisfyTemporalTimeZoneString(str_content .ToOneByteVector(), &parsed); } else { valid = SatisfyTemporalTimeZoneString (str_content.ToUC16Vector(), &parsed); } } if (valid) return Just(parsed); return Nothing<ParsedISO8601Result>(); } | |||
| 1216 | IMPL_PARSE_METHOD(ParsedISO8601Result, TemporalRelativeToString)Maybe<ParsedISO8601Result> TemporalParser::ParseTemporalRelativeToString (Isolate* isolate, Handle<String> iso_string) { bool valid ; ParsedISO8601Result parsed; iso_string = String::Flatten(isolate , iso_string); { DisallowGarbageCollection no_gc; String::FlatContent str_content = iso_string->GetFlatContent(no_gc); if (str_content .IsOneByte()) { valid = SatisfyTemporalRelativeToString(str_content .ToOneByteVector(), &parsed); } else { valid = SatisfyTemporalRelativeToString (str_content.ToUC16Vector(), &parsed); } } if (valid) return Just(parsed); return Nothing<ParsedISO8601Result>(); } | |||
| 1217 | IMPL_PARSE_METHOD(ParsedISO8601Result, TemporalCalendarString)Maybe<ParsedISO8601Result> TemporalParser::ParseTemporalCalendarString (Isolate* isolate, Handle<String> iso_string) { bool valid ; ParsedISO8601Result parsed; iso_string = String::Flatten(isolate , iso_string); { DisallowGarbageCollection no_gc; String::FlatContent str_content = iso_string->GetFlatContent(no_gc); if (str_content .IsOneByte()) { valid = SatisfyTemporalCalendarString(str_content .ToOneByteVector(), &parsed); } else { valid = SatisfyTemporalCalendarString (str_content.ToUC16Vector(), &parsed); } } if (valid) return Just(parsed); return Nothing<ParsedISO8601Result>(); } | |||
| 1218 | IMPL_PARSE_METHOD(ParsedISO8601Result, TimeZoneNumericUTCOffset)Maybe<ParsedISO8601Result> TemporalParser::ParseTimeZoneNumericUTCOffset (Isolate* isolate, Handle<String> iso_string) { bool valid ; ParsedISO8601Result parsed; iso_string = String::Flatten(isolate , iso_string); { DisallowGarbageCollection no_gc; String::FlatContent str_content = iso_string->GetFlatContent(no_gc); if (str_content .IsOneByte()) { valid = SatisfyTimeZoneNumericUTCOffset(str_content .ToOneByteVector(), &parsed); } else { valid = SatisfyTimeZoneNumericUTCOffset (str_content.ToUC16Vector(), &parsed); } } if (valid) return Just(parsed); return Nothing<ParsedISO8601Result>(); } | |||
| 1219 | IMPL_PARSE_METHOD(ParsedISO8601Duration, TemporalDurationString)Maybe<ParsedISO8601Duration> TemporalParser::ParseTemporalDurationString (Isolate* isolate, Handle<String> iso_string) { bool valid ; ParsedISO8601Duration parsed; iso_string = String::Flatten( isolate, iso_string); { DisallowGarbageCollection no_gc; String ::FlatContent str_content = iso_string->GetFlatContent(no_gc ); if (str_content.IsOneByte()) { valid = SatisfyTemporalDurationString (str_content.ToOneByteVector(), &parsed); } else { valid = SatisfyTemporalDurationString(str_content.ToUC16Vector(), & parsed); } } if (valid) return Just(parsed); return Nothing< ParsedISO8601Duration>(); } | |||
| 1220 | ||||
| 1221 | } // namespace internal | |||
| 1222 | } // namespace v8 |