5 #ifndef V8_DATEPARSER_H_ 6 #define V8_DATEPARSER_H_ 8 #include "src/allocation.h" 9 #include "src/char-predicates.h" 27 template <
typename Char>
31 YEAR, MONTH, DAY, HOUR, MINUTE, SECOND, MILLISECOND, UTC_OFFSET, OUTPUT_SIZE
36 static inline bool Between(
int x,
int lo,
int hi) {
37 return static_cast<unsigned>(x - lo) <= static_cast<unsigned>(hi - lo);
41 static const int kNone = kMaxInt;
45 static const int kMaxSignificantDigits = 9;
48 template <
typename Char>
51 explicit InputReader(
Vector<Char> s) : index_(0), buffer_(s) { Next(); }
53 int position() {
return index_; }
57 ch_ = (index_ < buffer_.length()) ? buffer_[index_] : 0;
64 int ReadUnsignedNumeral() {
67 while (IsAsciiDigit()) {
68 if (
i < kMaxSignificantDigits) n = n * 10 + ch_ -
'0';
78 int ReadWord(
uint32_t* prefix,
int prefix_size) {
80 for (len = 0; IsAsciiAlphaOrAbove(); Next(), len++) {
81 if (len < prefix_size) prefix[len] = AsciiAlphaToLower(ch_);
83 for (
int i = len;
i < prefix_size;
i++) prefix[
i] = 0;
96 inline bool SkipWhiteSpace();
97 inline bool SkipParentheses();
100 bool Is(
uint32_t c)
const {
return ch_ == c; }
101 bool IsEnd()
const {
return ch_ == 0; }
102 bool IsAsciiDigit()
const {
return IsDecimalDigit(ch_); }
103 bool IsAsciiAlphaOrAbove()
const {
return ch_ >=
'A'; }
104 bool IsAsciiSign()
const {
return ch_ ==
'+' || ch_ ==
'-'; }
107 int GetAsciiSignValue()
const {
return 44 -
static_cast<int>(ch_); }
116 INVALID, MONTH_NAME, TIME_ZONE_NAME, TIME_SEPARATOR, AM_PM
121 bool IsInvalid() {
return tag_ == kInvalidTokenTag; }
122 bool IsUnknown() {
return tag_ == kUnknownTokenTag; }
123 bool IsNumber() {
return tag_ == kNumberTag; }
124 bool IsSymbol() {
return tag_ == kSymbolTag; }
125 bool IsWhiteSpace() {
return tag_ == kWhiteSpaceTag; }
126 bool IsEndOfInput() {
return tag_ == kEndOfInputTag; }
127 bool IsKeyword() {
return tag_ >= kKeywordTagStart; }
129 int length() {
return length_; }
135 KeywordType keyword_type() {
137 return static_cast<KeywordType
>(tag_);
139 int keyword_value() {
145 return static_cast<char>(value_);
147 bool IsSymbol(
char symbol) {
148 return IsSymbol() && this->symbol() == symbol;
150 bool IsKeywordType(KeywordType tag) {
153 bool IsFixedLengthNumber(
int length) {
154 return IsNumber() && length_ == length;
157 return tag_ == kSymbolTag && (value_ ==
'-' || value_ ==
'+');
160 DCHECK(IsAsciiSign());
164 return IsKeywordType(TIME_ZONE_NAME) && length_ == 1 && value_ == 0;
166 bool IsUnknown(
int character) {
167 return IsUnknown() && value_ == character;
170 static DateToken Keyword(KeywordType tag,
int value,
int length) {
171 return DateToken(tag, length, value);
173 static DateToken
Number(
int value,
int length) {
174 return DateToken(kNumberTag, length, value);
176 static DateToken
Symbol(
char symbol) {
177 return DateToken(kSymbolTag, 1, symbol);
179 static DateToken EndOfInput() {
180 return DateToken(kEndOfInputTag, 0, -1);
182 static DateToken WhiteSpace(
int length) {
183 return DateToken(kWhiteSpaceTag, length, -1);
185 static DateToken Unknown() {
186 return DateToken(kUnknownTokenTag, 1, -1);
188 static DateToken Invalid() {
189 return DateToken(kInvalidTokenTag, 0, -1);
194 kInvalidTokenTag = -6,
195 kUnknownTokenTag = -5,
202 DateToken(
int tag,
int length,
int value)
212 template <
typename Char>
213 class DateStringTokenizer {
215 explicit DateStringTokenizer(InputReader<Char>* in)
216 : in_(in), next_(Scan()) { }
218 DateToken result = next_;
226 bool SkipSymbol(
char symbol) {
227 if (next_.IsSymbol(symbol)) {
237 InputReader<Char>* in_;
241 static int ReadMilliseconds(DateToken number);
249 static int Lookup(
const uint32_t* pre,
int len);
251 static KeywordType GetType(
int i) {
252 return static_cast<KeywordType
>(array[
i][kTypeOffset]);
255 static int GetValue(
int i) {
return array[
i][kValueOffset]; }
257 static const int kPrefixLength = 3;
258 static const int kTypeOffset = kPrefixLength;
259 static const int kValueOffset = kTypeOffset + 1;
260 static const int kEntrySize = kValueOffset + 1;
261 static const int8_t array[][kEntrySize];
264 class TimeZoneComposer {
267 void Set(
int offset_in_hours) {
268 sign_ = offset_in_hours < 0 ? -1 : 1;
269 hour_ = offset_in_hours * sign_;
272 void SetSign(
int sign) { sign_ = sign < 0 ? -1 : 1; }
273 void SetAbsoluteHour(
int hour) { hour_ = hour; }
274 void SetAbsoluteMinute(
int minute) { minute_ = minute; }
275 bool IsExpecting(
int n)
const {
276 return hour_ !=
kNone && minute_ ==
kNone && TimeComposer::IsMinute(n);
278 bool IsUTC()
const {
return hour_ == 0 && minute_ == 0; }
280 bool IsEmpty() {
return hour_ ==
kNone; }
289 TimeComposer() : index_(0), hour_offset_(
kNone) {}
290 bool IsEmpty()
const {
return index_ == 0; }
291 bool IsExpecting(
int n)
const {
292 return (index_ == 1 && IsMinute(n)) ||
293 (index_ == 2 && IsSecond(n)) ||
294 (index_ == 3 && IsMillisecond(n));
297 return index_ < kSize ? (comp_[index_++] = n,
true) :
false;
299 bool AddFinal(
int n) {
300 if (!Add(n))
return false;
301 while (index_ < kSize) comp_[index_++] = 0;
304 void SetHourOffset(
int n) { hour_offset_ = n; }
307 static bool IsMinute(
int x) {
return Between(x, 0, 59); }
308 static bool IsHour(
int x) {
return Between(x, 0, 23); }
309 static bool IsSecond(
int x) {
return Between(x, 0, 59); }
312 static bool IsHour12(
int x) {
return Between(x, 0, 12); }
313 static bool IsMillisecond(
int x) {
return Between(x, 0, 999); }
315 static const int kSize = 4;
323 DayComposer() : index_(0), named_month_(
kNone), is_iso_date_(
false) {}
324 bool IsEmpty()
const {
return index_ == 0; }
326 if (index_ < kSize) {
333 void SetNamedMonth(
int n) { named_month_ = n; }
335 void set_iso_date() { is_iso_date_ =
true; }
336 static bool IsMonth(
int x) {
return Between(x, 1, 12); }
337 static bool IsDay(
int x) {
return Between(x, 1, 31); }
340 static const int kSize = 3;
353 template <
typename Char>
354 static DateParser::DateToken ParseES5DateTime(
355 DateStringTokenizer<Char>* scanner, DayComposer* day, TimeComposer* time,
356 TimeZoneComposer* tz);
363 #endif // V8_DATEPARSER_H_