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

Side by Side Diff: src/dateparser.cc

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 13 matching lines...) Expand all
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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 #include "v8.h" 28 #include "v8.h"
29 29
30 #include "dateparser.h" 30 #include "dateparser.h"
31 31
32 namespace v8 { namespace internal { 32 namespace v8 { namespace internal {
33 33
34
35 bool DateParser::Parse(String* str, FixedArray* out) {
36 ASSERT(out->length() == OUTPUT_SIZE);
37
38 InputReader in(str);
39 TimeZoneComposer tz;
40 TimeComposer time;
41 DayComposer day;
42
43 while (!in.IsEnd()) {
44 if (in.IsAsciiDigit()) {
45 // Parse a number (possibly with 1 or 2 trailing colons).
46 int n = in.ReadUnsignedNumber();
47 if (in.Skip(':')) {
48 if (in.Skip(':')) {
49 // n + "::"
50 if (!time.IsEmpty()) return false;
51 time.Add(n);
52 time.Add(0);
53 } else {
54 // n + ":"
55 if (!time.Add(n)) return false;
56 }
57 } else if (tz.IsExpecting(n)) {
58 tz.SetAbsoluteMinute(n);
59 } else if (time.IsExpecting(n)) {
60 time.AddFinal(n);
61 // Require end or white space immediately after finalizing time.
62 if (!in.IsEnd() && !in.SkipWhiteSpace()) return false;
63 } else {
64 if (!day.Add(n)) return false;
65 in.Skip('-'); // Ignore suffix '-' for year, month, or day.
66 }
67 } else if (in.IsAsciiAlphaOrAbove()) {
68 // Parse a "word" (sequence of chars. >= 'A').
69 uint32_t pre[KeywordTable::kPrefixLength];
70 int len = in.ReadWord(pre, KeywordTable::kPrefixLength);
71 int index = KeywordTable::Lookup(pre, len);
72 KeywordType type = KeywordTable::GetType(index);
73
74 if (type == AM_PM && !time.IsEmpty()) {
75 time.SetHourOffset(KeywordTable::GetValue(index));
76 } else if (type == MONTH_NAME) {
77 day.SetNamedMonth(KeywordTable::GetValue(index));
78 in.Skip('-'); // Ignore suffix '-' for month names
79 } else if (type == TIME_ZONE_NAME && in.HasReadNumber()) {
80 tz.Set(KeywordTable::GetValue(index));
81 } else {
82 // Garbage words are illegal if no number read yet.
83 if (in.HasReadNumber()) return false;
84 }
85 } else if (in.IsAsciiSign() && (tz.IsUTC() || !time.IsEmpty())) {
86 // Parse UTC offset (only after UTC or time).
87 tz.SetSign(in.GetAsciiSignValue());
88 in.Next();
89 int n = in.ReadUnsignedNumber();
90 if (in.Skip(':')) {
91 tz.SetAbsoluteHour(n);
92 tz.SetAbsoluteMinute(kNone);
93 } else {
94 tz.SetAbsoluteHour(n / 100);
95 tz.SetAbsoluteMinute(n % 100);
96 }
97 } else if (in.Is('(')) {
98 // Ignore anything from '(' to a matching ')' or end of string.
99 in.SkipParentheses();
100 } else if ((in.IsAsciiSign() || in.Is(')')) && in.HasReadNumber()) {
101 // Extra sign or ')' is illegal if no number read yet.
102 return false;
103 } else {
104 // Ignore other characters.
105 in.Next();
106 }
107 }
108 return day.Write(out) && time.Write(out) && tz.Write(out);
109 }
110
111
112 bool DateParser::DayComposer::Write(FixedArray* output) { 34 bool DateParser::DayComposer::Write(FixedArray* output) {
113 int year = 0; // Default year is 0 (=> 2000) for KJS compatibility. 35 int year = 0; // Default year is 0 (=> 2000) for KJS compatibility.
114 int month = kNone; 36 int month = kNone;
115 int day = kNone; 37 int day = kNone;
116 38
117 if (named_month_ == kNone) { 39 if (named_month_ == kNone) {
118 if (index_ < 2) return false; 40 if (index_ < 2) return false;
119 if (index_ == 3 && !IsDay(comp_[0])) { 41 if (index_ == 3 && !IsDay(comp_[0])) {
120 // YMD 42 // YMD
121 year = comp_[0]; 43 year = comp_[0];
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 Smi::FromInt(year), 75 Smi::FromInt(year),
154 SKIP_WRITE_BARRIER); 76 SKIP_WRITE_BARRIER);
155 output->set(MONTH, 77 output->set(MONTH,
156 Smi::FromInt(month - 1), 78 Smi::FromInt(month - 1),
157 SKIP_WRITE_BARRIER); // 0-based 79 SKIP_WRITE_BARRIER); // 0-based
158 output->set(DAY, 80 output->set(DAY,
159 Smi::FromInt(day), 81 Smi::FromInt(day),
160 SKIP_WRITE_BARRIER); 82 SKIP_WRITE_BARRIER);
161 return true; 83 return true;
162 } 84 }
163 85
Erik Corry 2009/03/17 13:09:01 There should be two blank lines between methods.
164
165 bool DateParser::TimeComposer::Write(FixedArray* output) { 86 bool DateParser::TimeComposer::Write(FixedArray* output) {
166 // All time slots default to 0 87 // All time slots default to 0
167 while (index_ < kSize) { 88 while (index_ < kSize) {
168 comp_[index_++] = 0; 89 comp_[index_++] = 0;
169 } 90 }
170 91
171 int& hour = comp_[0]; 92 int& hour = comp_[0];
172 int& minute = comp_[1]; 93 int& minute = comp_[1];
173 int& second = comp_[2]; 94 int& second = comp_[2];
174 95
(...skipping 10 matching lines...) Expand all
185 SKIP_WRITE_BARRIER); 106 SKIP_WRITE_BARRIER);
186 output->set(MINUTE, 107 output->set(MINUTE,
187 Smi::FromInt(minute), 108 Smi::FromInt(minute),
188 SKIP_WRITE_BARRIER); 109 SKIP_WRITE_BARRIER);
189 output->set(SECOND, 110 output->set(SECOND,
190 Smi::FromInt(second), 111 Smi::FromInt(second),
191 SKIP_WRITE_BARRIER); 112 SKIP_WRITE_BARRIER);
192 return true; 113 return true;
193 } 114 }
194 115
195
196 bool DateParser::TimeZoneComposer::Write(FixedArray* output) { 116 bool DateParser::TimeZoneComposer::Write(FixedArray* output) {
197 if (sign_ != kNone) { 117 if (sign_ != kNone) {
198 if (hour_ == kNone) hour_ = 0; 118 if (hour_ == kNone) hour_ = 0;
199 if (minute_ == kNone) minute_ = 0; 119 if (minute_ == kNone) minute_ = 0;
200 int total_seconds = sign_ * (hour_ * 3600 + minute_ * 60); 120 int total_seconds = sign_ * (hour_ * 3600 + minute_ * 60);
201 if (!Smi::IsValid(total_seconds)) return false; 121 if (!Smi::IsValid(total_seconds)) return false;
202 output->set(UTC_OFFSET, 122 output->set(UTC_OFFSET,
203 Smi::FromInt(total_seconds), 123 Smi::FromInt(total_seconds),
204 SKIP_WRITE_BARRIER); 124 SKIP_WRITE_BARRIER);
205 } else { 125 } else {
206 output->set(UTC_OFFSET, 126 output->set(UTC_OFFSET,
207 Heap::null_value(), 127 Heap::null_value(),
208 SKIP_WRITE_BARRIER); 128 SKIP_WRITE_BARRIER);
209 } 129 }
210 return true; 130 return true;
211 } 131 }
212 132
213 133 const int8_t DateParser::KeywordTable::
214 const int8_t 134 array[][DateParser::KeywordTable::kEntrySize] = {
215 DateParser::KeywordTable::array[][DateParser::KeywordTable::kEntrySize] = {
216 {'j', 'a', 'n', DateParser::MONTH_NAME, 1}, 135 {'j', 'a', 'n', DateParser::MONTH_NAME, 1},
217 {'f', 'e', 'b', DateParser::MONTH_NAME, 2}, 136 {'f', 'e', 'b', DateParser::MONTH_NAME, 2},
218 {'m', 'a', 'r', DateParser::MONTH_NAME, 3}, 137 {'m', 'a', 'r', DateParser::MONTH_NAME, 3},
219 {'a', 'p', 'r', DateParser::MONTH_NAME, 4}, 138 {'a', 'p', 'r', DateParser::MONTH_NAME, 4},
220 {'m', 'a', 'y', DateParser::MONTH_NAME, 5}, 139 {'m', 'a', 'y', DateParser::MONTH_NAME, 5},
221 {'j', 'u', 'n', DateParser::MONTH_NAME, 6}, 140 {'j', 'u', 'n', DateParser::MONTH_NAME, 6},
222 {'j', 'u', 'l', DateParser::MONTH_NAME, 7}, 141 {'j', 'u', 'l', DateParser::MONTH_NAME, 7},
223 {'a', 'u', 'g', DateParser::MONTH_NAME, 8}, 142 {'a', 'u', 'g', DateParser::MONTH_NAME, 8},
224 {'s', 'e', 'p', DateParser::MONTH_NAME, 9}, 143 {'s', 'e', 'p', DateParser::MONTH_NAME, 9},
225 {'o', 'c', 't', DateParser::MONTH_NAME, 10}, 144 {'o', 'c', 't', DateParser::MONTH_NAME, 10},
(...skipping 30 matching lines...) Expand all
256 if (j == kPrefixLength && 175 if (j == kPrefixLength &&
257 (len <= kPrefixLength || array[i][kTypeOffset] == MONTH_NAME)) { 176 (len <= kPrefixLength || array[i][kTypeOffset] == MONTH_NAME)) {
258 return i; 177 return i;
259 } 178 }
260 } 179 }
261 return i; 180 return i;
262 } 181 }
263 182
264 183
265 } } // namespace v8::internal 184 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698