Home | History | Annotate | Download | only in src
      1 // Copyright 2011 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     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.
     27 
     28 #ifndef V8_DATEPARSER_INL_H_
     29 #define V8_DATEPARSER_INL_H_
     30 
     31 #include "dateparser.h"
     32 
     33 namespace v8 {
     34 namespace internal {
     35 
     36 template <typename Char>
     37 bool DateParser::Parse(Vector<Char> str,
     38                        FixedArray* out,
     39                        UnicodeCache* unicode_cache) {
     40   ASSERT(out->length() >= OUTPUT_SIZE);
     41   InputReader<Char> in(unicode_cache, str);
     42   TimeZoneComposer tz;
     43   TimeComposer time;
     44   DayComposer day;
     45 
     46   while (!in.IsEnd()) {
     47     if (in.IsAsciiDigit()) {
     48       // Parse a number (possibly with 1 or 2 trailing colons).
     49       int n = in.ReadUnsignedNumber();
     50       if (in.Skip(':')) {
     51         if (in.Skip(':')) {
     52           // n + "::"
     53           if (!time.IsEmpty()) return false;
     54           time.Add(n);
     55           time.Add(0);
     56         } else {
     57           // n + ":"
     58           if (!time.Add(n)) return false;
     59           in.Skip('.');
     60         }
     61       } else if (in.Skip('.') && time.IsExpecting(n)) {
     62         time.Add(n);
     63         if (!in.IsAsciiDigit()) return false;
     64         int n = in.ReadMilliseconds();
     65         time.AddFinal(n);
     66       } else if (tz.IsExpecting(n)) {
     67         tz.SetAbsoluteMinute(n);
     68       } else if (time.IsExpecting(n)) {
     69         time.AddFinal(n);
     70         // Require end, white space, "Z", "+" or "-" immediately after
     71         // finalizing time.
     72         if (!in.IsEnd() && !in.SkipWhiteSpace() && !in.Is('Z') &&
     73             !in.IsAsciiSign()) return false;
     74       } else {
     75         if (!day.Add(n)) return false;
     76         in.Skip('-');  // Ignore suffix '-' for year, month, or day.
     77         // Skip trailing 'T' for ECMAScript 5 date string format but make
     78         // sure that it is followed by a digit (for the time).
     79         if (in.Skip('T') && !in.IsAsciiDigit()) return false;
     80       }
     81     } else if (in.IsAsciiAlphaOrAbove()) {
     82       // Parse a "word" (sequence of chars. >= 'A').
     83       uint32_t pre[KeywordTable::kPrefixLength];
     84       int len = in.ReadWord(pre, KeywordTable::kPrefixLength);
     85       int index = KeywordTable::Lookup(pre, len);
     86       KeywordType type = KeywordTable::GetType(index);
     87 
     88       if (type == AM_PM && !time.IsEmpty()) {
     89         time.SetHourOffset(KeywordTable::GetValue(index));
     90       } else if (type == MONTH_NAME) {
     91         day.SetNamedMonth(KeywordTable::GetValue(index));
     92         in.Skip('-');  // Ignore suffix '-' for month names
     93       } else if (type == TIME_ZONE_NAME && in.HasReadNumber()) {
     94         tz.Set(KeywordTable::GetValue(index));
     95       } else {
     96         // Garbage words are illegal if a number has been read.
     97         if (in.HasReadNumber()) return false;
     98       }
     99     } else if (in.IsAsciiSign() && (tz.IsUTC() || !time.IsEmpty())) {
    100       // Parse UTC offset (only after UTC or time).
    101       tz.SetSign(in.GetAsciiSignValue());
    102       in.Next();
    103       int n = in.ReadUnsignedNumber();
    104       if (in.Skip(':')) {
    105         tz.SetAbsoluteHour(n);
    106         tz.SetAbsoluteMinute(kNone);
    107       } else {
    108         tz.SetAbsoluteHour(n / 100);
    109         tz.SetAbsoluteMinute(n % 100);
    110       }
    111     } else if (in.Is('(')) {
    112       // Ignore anything from '(' to a matching ')' or end of string.
    113       in.SkipParentheses();
    114     } else if ((in.IsAsciiSign() || in.Is(')')) && in.HasReadNumber()) {
    115       // Extra sign or ')' is illegal if a number has been read.
    116       return false;
    117     } else {
    118       // Ignore other characters.
    119       in.Next();
    120     }
    121   }
    122   return day.Write(out) && time.Write(out) && tz.Write(out);
    123 }
    124 
    125 } }  // namespace v8::internal
    126 
    127 #endif  // V8_DATEPARSER_INL_H_
    128