Home | History | Annotate | Download | only in src
      1 // Copyright 2008 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, FixedArray* out) {
     38   ASSERT(out->length() >= OUTPUT_SIZE);
     39   InputReader<Char> in(str);
     40   TimeZoneComposer tz;
     41   TimeComposer time;
     42   DayComposer day;
     43 
     44   while (!in.IsEnd()) {
     45     if (in.IsAsciiDigit()) {
     46       // Parse a number (possibly with 1 or 2 trailing colons).
     47       int n = in.ReadUnsignedNumber();
     48       if (in.Skip(':')) {
     49         if (in.Skip(':')) {
     50           // n + "::"
     51           if (!time.IsEmpty()) return false;
     52           time.Add(n);
     53           time.Add(0);
     54         } else {
     55           // n + ":"
     56           if (!time.Add(n)) return false;
     57         }
     58       } else if (tz.IsExpecting(n)) {
     59         tz.SetAbsoluteMinute(n);
     60       } else if (time.IsExpecting(n)) {
     61         time.AddFinal(n);
     62         // Require end or white space immediately after finalizing time.
     63         if (!in.IsEnd() && !in.SkipWhiteSpace()) return false;
     64       } else {
     65         if (!day.Add(n)) return false;
     66         in.Skip('-');  // Ignore suffix '-' for year, month, or day.
     67       }
     68     } else if (in.IsAsciiAlphaOrAbove()) {
     69       // Parse a "word" (sequence of chars. >= 'A').
     70       uint32_t pre[KeywordTable::kPrefixLength];
     71       int len = in.ReadWord(pre, KeywordTable::kPrefixLength);
     72       int index = KeywordTable::Lookup(pre, len);
     73       KeywordType type = KeywordTable::GetType(index);
     74 
     75       if (type == AM_PM && !time.IsEmpty()) {
     76         time.SetHourOffset(KeywordTable::GetValue(index));
     77       } else if (type == MONTH_NAME) {
     78         day.SetNamedMonth(KeywordTable::GetValue(index));
     79         in.Skip('-');  // Ignore suffix '-' for month names
     80       } else if (type == TIME_ZONE_NAME && in.HasReadNumber()) {
     81         tz.Set(KeywordTable::GetValue(index));
     82       } else {
     83         // Garbage words are illegal if a number has been read.
     84         if (in.HasReadNumber()) return false;
     85       }
     86     } else if (in.IsAsciiSign() && (tz.IsUTC() || !time.IsEmpty())) {
     87       // Parse UTC offset (only after UTC or time).
     88       tz.SetSign(in.GetAsciiSignValue());
     89       in.Next();
     90       int n = in.ReadUnsignedNumber();
     91       if (in.Skip(':')) {
     92         tz.SetAbsoluteHour(n);
     93         tz.SetAbsoluteMinute(kNone);
     94       } else {
     95         tz.SetAbsoluteHour(n / 100);
     96         tz.SetAbsoluteMinute(n % 100);
     97       }
     98     } else if (in.Is('(')) {
     99       // Ignore anything from '(' to a matching ')' or end of string.
    100       in.SkipParentheses();
    101     } else if ((in.IsAsciiSign() || in.Is(')')) && in.HasReadNumber()) {
    102       // Extra sign or ')' is illegal if a number has been read.
    103       return false;
    104     } else {
    105       // Ignore other characters.
    106       in.Next();
    107     }
    108   }
    109   return day.Write(out) && time.Write(out) && tz.Write(out);
    110 }
    111 
    112 } }  // namespace v8::internal
    113 
    114 #endif  // V8_DATEPARSER_INL_H_
    115