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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: src/dateparser.h
diff --git a/src/dateparser.h b/src/dateparser.h
index bf968525f5f657e494040da7901da0aee4677c8d..f03ff681980db18f452a4a50d8b8c203691faa66 100644
--- a/src/dateparser.h
+++ b/src/dateparser.h
@@ -32,7 +32,6 @@
namespace v8 { namespace internal {
-
class DateParser : public AllStatic {
public:
@@ -46,25 +45,32 @@ class DateParser : public AllStatic {
// [5]: second
// [6]: UTC offset in seconds, or null value if no timezone specified
// If parsing fails, return false (content of output array is not defined).
- static bool Parse(String* str, FixedArray* output);
+ template <typename Char>
+ static bool Parse(Vector<Char> str, FixedArray* output);
enum {YEAR, MONTH, DAY, HOUR, MINUTE, SECOND, UTC_OFFSET, OUTPUT_SIZE};
private:
// Range testing
- static bool Between(int x, int lo, int hi) { return x >= lo && x <= hi; }
+ static inline bool Between(int x, int lo, int hi) {
+ return static_cast<unsigned>(x - lo) <= static_cast<unsigned>(hi - lo);
+ }
// Indicates a missing value.
static const int kNone = kMaxInt;
// InputReader provides basic string parsing and character classification.
+ template <typename Char>
class InputReader BASE_EMBEDDED {
public:
- explicit InputReader(String* s) : buffer_(s), has_read_number_(false) {
+ explicit InputReader(Vector<Char> s)
+ : index_(0),
+ buffer_(s),
+ has_read_number_(false) {
Next();
}
// Advance to the next character of the string.
- void Next() { ch_ = buffer_.has_more() ? buffer_.GetNext() : 0; }
+ void Next() { ch_ = (index_ < buffer_.length()) ? buffer_[index_++] : 0; }
// Read a string of digits as an unsigned number (cap just below kMaxInt).
int ReadUnsignedNumber() {
@@ -124,7 +130,8 @@ class DateParser : public AllStatic {
// Else, return something outside of 'A'-'Z' and 'a'-'z'.
uint32_t GetAsciiAlphaLower() const { return ch_ | 32; }
- StringInputBuffer buffer_;
+ int index_;
+ Vector<Char> buffer_;
bool has_read_number_;
uint32_t ch_;
};
@@ -225,6 +232,83 @@ class DateParser : public AllStatic {
};
+template <typename Char>
Erik Corry 2009/03/17 13:09:01 Since the templates force us to move this to a .h
+bool DateParser::Parse(Vector<Char> str, FixedArray* out) {
+ ASSERT(out->length() == OUTPUT_SIZE);
+ InputReader<Char> in(str);
+ TimeZoneComposer tz;
+ TimeComposer time;
+ DayComposer day;
+
+ while (!in.IsEnd()) {
+ if (in.IsAsciiDigit()) {
+ // Parse a number (possibly with 1 or 2 trailing colons).
+ int n = in.ReadUnsignedNumber();
+ if (in.Skip(':')) {
+ if (in.Skip(':')) {
+ // n + "::"
+ if (!time.IsEmpty()) return false;
+ time.Add(n);
+ time.Add(0);
+ } else {
+ // n + ":"
+ if (!time.Add(n)) return false;
+ }
+ } else if (tz.IsExpecting(n)) {
+ tz.SetAbsoluteMinute(n);
+ } else if (time.IsExpecting(n)) {
+ time.AddFinal(n);
+ // Require end or white space immediately after finalizing time.
+ if (!in.IsEnd() && !in.SkipWhiteSpace()) return false;
+ } else {
+ if (!day.Add(n)) return false;
+ in.Skip('-'); // Ignore suffix '-' for year, month, or day.
+ }
+ } else if (in.IsAsciiAlphaOrAbove()) {
+ // Parse a "word" (sequence of chars. >= 'A').
+ uint32_t pre[KeywordTable::kPrefixLength];
+ int len = in.ReadWord(pre, KeywordTable::kPrefixLength);
+ int index = KeywordTable::Lookup(pre, len);
+ KeywordType type = KeywordTable::GetType(index);
+
+ if (type == AM_PM && !time.IsEmpty()) {
+ time.SetHourOffset(KeywordTable::GetValue(index));
+ } else if (type == MONTH_NAME) {
+ day.SetNamedMonth(KeywordTable::GetValue(index));
+ in.Skip('-'); // Ignore suffix '-' for month names
+ } else if (type == TIME_ZONE_NAME && in.HasReadNumber()) {
+ tz.Set(KeywordTable::GetValue(index));
+ } else {
+ // Garbage words are illegal if a number has been read.
+ if (in.HasReadNumber()) return false;
+ }
+ } else if (in.IsAsciiSign() && (tz.IsUTC() || !time.IsEmpty())) {
+ // Parse UTC offset (only after UTC or time).
+ tz.SetSign(in.GetAsciiSignValue());
+ in.Next();
+ int n = in.ReadUnsignedNumber();
+ if (in.Skip(':')) {
+ tz.SetAbsoluteHour(n);
+ tz.SetAbsoluteMinute(kNone);
+ } else {
+ tz.SetAbsoluteHour(n / 100);
+ tz.SetAbsoluteMinute(n % 100);
+ }
+ } else if (in.Is('(')) {
+ // Ignore anything from '(' to a matching ')' or end of string.
+ in.SkipParentheses();
+ } else if ((in.IsAsciiSign() || in.Is(')')) && in.HasReadNumber()) {
+ // Extra sign or ')' is illegal if a number has been read.
+ // TODO(lrn) Is this correct?
Erik Corry 2009/03/17 13:09:01 I should be possible to find the answer to this an
+ return false;
+ } else {
+ // Ignore other characters.
+ in.Next();
+ }
+ }
+ return day.Write(out) && time.Write(out) && tz.Write(out);
+}
+
} } // namespace v8::internal
#endif // V8_DATEPARSER_H_
« 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