Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(86)

Side by Side Diff: src/dateparser.h

Issue 42280: Made Date parser work on flat strings instead of arbitrary ones. (Closed)
Patch Set: Created 11 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2008 the V8 project authors. All rights reserved. 1 // Copyright 2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 14 matching lines...) Expand all
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #ifndef V8_DATEPARSER_H_ 28 #ifndef V8_DATEPARSER_H_
29 #define V8_DATEPARSER_H_ 29 #define V8_DATEPARSER_H_
30 30
31 #include "scanner.h" 31 #include "scanner.h"
32 32
33 namespace v8 { namespace internal { 33 namespace v8 { namespace internal {
34 34
35
36 class DateParser : public AllStatic { 35 class DateParser : public AllStatic {
37 public: 36 public:
38 37
39 // Parse the string as a date. If parsing succeeds, return true after 38 // Parse the string as a date. If parsing succeeds, return true after
40 // filling out the output array as follows (all integers are Smis): 39 // filling out the output array as follows (all integers are Smis):
41 // [0]: year 40 // [0]: year
42 // [1]: month (0 = Jan, 1 = Feb, ...) 41 // [1]: month (0 = Jan, 1 = Feb, ...)
43 // [2]: day 42 // [2]: day
44 // [3]: hour 43 // [3]: hour
45 // [4]: minute 44 // [4]: minute
46 // [5]: second 45 // [5]: second
47 // [6]: UTC offset in seconds, or null value if no timezone specified 46 // [6]: UTC offset in seconds, or null value if no timezone specified
48 // If parsing fails, return false (content of output array is not defined). 47 // If parsing fails, return false (content of output array is not defined).
49 static bool Parse(String* str, FixedArray* output); 48 template <typename Char>
49 static bool Parse(Vector<Char> str, FixedArray* output);
50 50
51 enum {YEAR, MONTH, DAY, HOUR, MINUTE, SECOND, UTC_OFFSET, OUTPUT_SIZE}; 51 enum {YEAR, MONTH, DAY, HOUR, MINUTE, SECOND, UTC_OFFSET, OUTPUT_SIZE};
52 52
53 private: 53 private:
54 // Range testing 54 // Range testing
55 static bool Between(int x, int lo, int hi) { return x >= lo && x <= hi; } 55 static inline bool Between(int x, int lo, int hi) {
56 return static_cast<unsigned>(x - lo) <= static_cast<unsigned>(hi - lo);
57 }
56 // Indicates a missing value. 58 // Indicates a missing value.
57 static const int kNone = kMaxInt; 59 static const int kNone = kMaxInt;
58 60
59 // InputReader provides basic string parsing and character classification. 61 // InputReader provides basic string parsing and character classification.
62 template <typename Char>
60 class InputReader BASE_EMBEDDED { 63 class InputReader BASE_EMBEDDED {
61 public: 64 public:
62 explicit InputReader(String* s) : buffer_(s), has_read_number_(false) { 65 explicit InputReader(Vector<Char> s)
66 : index_(0),
67 buffer_(s),
68 has_read_number_(false) {
63 Next(); 69 Next();
64 } 70 }
65 71
66 // Advance to the next character of the string. 72 // Advance to the next character of the string.
67 void Next() { ch_ = buffer_.has_more() ? buffer_.GetNext() : 0; } 73 void Next() { ch_ = (index_ < buffer_.length()) ? buffer_[index_++] : 0; }
68 74
69 // Read a string of digits as an unsigned number (cap just below kMaxInt). 75 // Read a string of digits as an unsigned number (cap just below kMaxInt).
70 int ReadUnsignedNumber() { 76 int ReadUnsignedNumber() {
71 has_read_number_ = true; 77 has_read_number_ = true;
72 int n; 78 int n;
73 for (n = 0; IsAsciiDigit() && n < kMaxInt / 10 - 1; Next()) { 79 for (n = 0; IsAsciiDigit() && n < kMaxInt / 10 - 1; Next()) {
74 n = n * 10 + ch_ - '0'; 80 n = n * 10 + ch_ - '0';
75 } 81 }
76 return n; 82 return n;
77 } 83 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 int GetAsciiSignValue() const { return 44 - static_cast<int>(ch_); } 123 int GetAsciiSignValue() const { return 44 - static_cast<int>(ch_); }
118 124
119 // Indicates whether any (possibly empty!) numbers have been read. 125 // Indicates whether any (possibly empty!) numbers have been read.
120 bool HasReadNumber() const { return has_read_number_; } 126 bool HasReadNumber() const { return has_read_number_; }
121 127
122 private: 128 private:
123 // If current character is in 'A'-'Z' or 'a'-'z', return its lower-case. 129 // If current character is in 'A'-'Z' or 'a'-'z', return its lower-case.
124 // Else, return something outside of 'A'-'Z' and 'a'-'z'. 130 // Else, return something outside of 'A'-'Z' and 'a'-'z'.
125 uint32_t GetAsciiAlphaLower() const { return ch_ | 32; } 131 uint32_t GetAsciiAlphaLower() const { return ch_ | 32; }
126 132
127 StringInputBuffer buffer_; 133 int index_;
134 Vector<Char> buffer_;
128 bool has_read_number_; 135 bool has_read_number_;
129 uint32_t ch_; 136 uint32_t ch_;
130 }; 137 };
131 138
132 enum KeywordType { INVALID, MONTH_NAME, TIME_ZONE_NAME, AM_PM }; 139 enum KeywordType { INVALID, MONTH_NAME, TIME_ZONE_NAME, AM_PM };
133 140
134 // KeywordTable maps names of months, time zones, am/pm to numbers. 141 // KeywordTable maps names of months, time zones, am/pm to numbers.
135 class KeywordTable : public AllStatic { 142 class KeywordTable : public AllStatic {
136 public: 143 public:
137 // Look up a word in the keyword table and return an index. 144 // Look up a word in the keyword table and return an index.
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 static bool IsDay(int x) { return Between(x, 1, 31); } 225 static bool IsDay(int x) { return Between(x, 1, 31); }
219 226
220 static const int kSize = 3; 227 static const int kSize = 3;
221 int comp_[kSize]; 228 int comp_[kSize];
222 int index_; 229 int index_;
223 int named_month_; 230 int named_month_;
224 }; 231 };
225 }; 232 };
226 233
227 234
235 template <typename Char>
Erik Corry 2009/03/17 13:09:01 Since the templates force us to move this to a .h
236 bool DateParser::Parse(Vector<Char> str, FixedArray* out) {
237 ASSERT(out->length() == OUTPUT_SIZE);
238 InputReader<Char> in(str);
239 TimeZoneComposer tz;
240 TimeComposer time;
241 DayComposer day;
242
243 while (!in.IsEnd()) {
244 if (in.IsAsciiDigit()) {
245 // Parse a number (possibly with 1 or 2 trailing colons).
246 int n = in.ReadUnsignedNumber();
247 if (in.Skip(':')) {
248 if (in.Skip(':')) {
249 // n + "::"
250 if (!time.IsEmpty()) return false;
251 time.Add(n);
252 time.Add(0);
253 } else {
254 // n + ":"
255 if (!time.Add(n)) return false;
256 }
257 } else if (tz.IsExpecting(n)) {
258 tz.SetAbsoluteMinute(n);
259 } else if (time.IsExpecting(n)) {
260 time.AddFinal(n);
261 // Require end or white space immediately after finalizing time.
262 if (!in.IsEnd() && !in.SkipWhiteSpace()) return false;
263 } else {
264 if (!day.Add(n)) return false;
265 in.Skip('-'); // Ignore suffix '-' for year, month, or day.
266 }
267 } else if (in.IsAsciiAlphaOrAbove()) {
268 // Parse a "word" (sequence of chars. >= 'A').
269 uint32_t pre[KeywordTable::kPrefixLength];
270 int len = in.ReadWord(pre, KeywordTable::kPrefixLength);
271 int index = KeywordTable::Lookup(pre, len);
272 KeywordType type = KeywordTable::GetType(index);
273
274 if (type == AM_PM && !time.IsEmpty()) {
275 time.SetHourOffset(KeywordTable::GetValue(index));
276 } else if (type == MONTH_NAME) {
277 day.SetNamedMonth(KeywordTable::GetValue(index));
278 in.Skip('-'); // Ignore suffix '-' for month names
279 } else if (type == TIME_ZONE_NAME && in.HasReadNumber()) {
280 tz.Set(KeywordTable::GetValue(index));
281 } else {
282 // Garbage words are illegal if a number has been read.
283 if (in.HasReadNumber()) return false;
284 }
285 } else if (in.IsAsciiSign() && (tz.IsUTC() || !time.IsEmpty())) {
286 // Parse UTC offset (only after UTC or time).
287 tz.SetSign(in.GetAsciiSignValue());
288 in.Next();
289 int n = in.ReadUnsignedNumber();
290 if (in.Skip(':')) {
291 tz.SetAbsoluteHour(n);
292 tz.SetAbsoluteMinute(kNone);
293 } else {
294 tz.SetAbsoluteHour(n / 100);
295 tz.SetAbsoluteMinute(n % 100);
296 }
297 } else if (in.Is('(')) {
298 // Ignore anything from '(' to a matching ')' or end of string.
299 in.SkipParentheses();
300 } else if ((in.IsAsciiSign() || in.Is(')')) && in.HasReadNumber()) {
301 // Extra sign or ')' is illegal if a number has been read.
302 // TODO(lrn) Is this correct?
Erik Corry 2009/03/17 13:09:01 I should be possible to find the answer to this an
303 return false;
304 } else {
305 // Ignore other characters.
306 in.Next();
307 }
308 }
309 return day.Write(out) && time.Write(out) && tz.Write(out);
310 }
311
228 } } // namespace v8::internal 312 } } // namespace v8::internal
229 313
230 #endif // V8_DATEPARSER_H_ 314 #endif // V8_DATEPARSER_H_
OLDNEW
« no previous file with comments | « src/char-predicates-inl.h ('k') | src/dateparser.cc » ('j') | src/dateparser.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698