LCOV - code coverage report
Current view: top level - src - dateparser.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 66 68 97.1 %
Date: 2017-04-26 Functions: 5 5 100.0 %

          Line data    Source code
       1             : // Copyright 2011 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/dateparser.h"
       6             : 
       7             : #include "src/char-predicates-inl.h"
       8             : #include "src/objects-inl.h"
       9             : 
      10             : namespace v8 {
      11             : namespace internal {
      12             : 
      13       96258 : bool DateParser::DayComposer::Write(FixedArray* output) {
      14       96258 :   if (index_ < 1) return false;
      15             :   // Day and month defaults to 1.
      16      188626 :   while (index_ < kSize) {
      17       92442 :     comp_[index_++] = 1;
      18             :   }
      19             : 
      20             :   int year = 0;  // Default year is 0 (=> 2000) for KJS compatibility.
      21             :   int month = kNone;
      22             :   int day = kNone;
      23             : 
      24       96184 :   if (named_month_ == kNone) {
      25        5675 :     if (is_iso_date_ || (index_ == 3 && !IsDay(comp_[0]))) {
      26             :       // YMD
      27        5031 :       year = comp_[0];
      28        5031 :       month = comp_[1];
      29        5031 :       day = comp_[2];
      30             :     } else {
      31             :       // MD(Y)
      32          86 :       month = comp_[0];
      33          86 :       day = comp_[1];
      34          86 :       if (index_ == 3) year = comp_[2];
      35             :     }
      36             :   } else {
      37             :     month = named_month_;
      38       91067 :     if (index_ == 1) {
      39             :       // MD or DM
      40           0 :       day = comp_[0];
      41      182134 :     } else if (!IsDay(comp_[0])) {
      42             :       // YMD, MYD, or YDM
      43             :       year = comp_[0];
      44           0 :       day = comp_[1];
      45             :     } else {
      46             :       // DMY, MDY, or DYM
      47             :       day = comp_[0];
      48       91067 :       year = comp_[1];
      49             :     }
      50             :   }
      51             : 
      52       96184 :   if (!is_iso_date_) {
      53       91625 :     if (Between(year, 0, 49)) year += 2000;
      54       90999 :     else if (Between(year, 50, 99)) year += 1900;
      55             :   }
      56             : 
      57      192326 :   if (!Smi::IsValid(year) || !IsMonth(month) || !IsDay(day)) return false;
      58             : 
      59             :   output->set(YEAR, Smi::FromInt(year));
      60       96142 :   output->set(MONTH, Smi::FromInt(month - 1));  // 0-based
      61             :   output->set(DAY, Smi::FromInt(day));
      62       96142 :   return true;
      63             : }
      64             : 
      65             : 
      66       96142 : bool DateParser::TimeComposer::Write(FixedArray* output) {
      67             :   // All time slots default to 0
      68      196721 :   while (index_ < kSize) {
      69        4437 :     comp_[index_++] = 0;
      70             :   }
      71             : 
      72             :   int& hour = comp_[0];
      73             :   int& minute = comp_[1];
      74             :   int& second = comp_[2];
      75             :   int& millisecond = comp_[3];
      76             : 
      77       96142 :   if (hour_offset_ != kNone) {
      78        1536 :     if (!IsHour12(hour)) return false;
      79         768 :     hour %= 12;
      80         768 :     hour += hour_offset_;
      81             :   }
      82             : 
      83      480485 :   if (!IsHour(hour) || !IsMinute(minute) ||
      84      384343 :       !IsSecond(second) || !IsMillisecond(millisecond)) {
      85             :     // A 24th hour is allowed if minutes, seconds, and milliseconds are 0
      86          75 :     if (hour != 24 || minute != 0 || second != 0 || millisecond != 0) {
      87             :       return false;
      88             :     }
      89             :   }
      90             : 
      91             :   output->set(HOUR, Smi::FromInt(hour));
      92       96127 :   output->set(MINUTE, Smi::FromInt(minute));
      93       96127 :   output->set(SECOND, Smi::FromInt(second));
      94       96127 :   output->set(MILLISECOND, Smi::FromInt(millisecond));
      95       96127 :   return true;
      96             : }
      97             : 
      98             : 
      99       96127 : bool DateParser::TimeZoneComposer::Write(FixedArray* output) {
     100       96127 :   if (sign_ != kNone) {
     101       95306 :     if (hour_ == kNone) hour_ = 0;
     102       95306 :     if (minute_ == kNone) minute_ = 0;
     103             :     // Avoid signed integer overflow (undefined behavior) by doing unsigned
     104             :     // arithmetic.
     105       95306 :     unsigned total_seconds_unsigned = hour_ * 3600U + minute_ * 60U;
     106       95306 :     if (total_seconds_unsigned > Smi::kMaxValue) return false;
     107             :     int total_seconds = static_cast<int>(total_seconds_unsigned);
     108       95306 :     if (sign_ < 0) {
     109       90086 :       total_seconds = -total_seconds;
     110             :     }
     111             :     DCHECK(Smi::IsValid(total_seconds));
     112             :     output->set(UTC_OFFSET, Smi::FromInt(total_seconds));
     113             :   } else {
     114         821 :     output->set_null(UTC_OFFSET);
     115             :   }
     116             :   return true;
     117             : }
     118             : 
     119             : const int8_t DateParser::KeywordTable::
     120             :     array[][DateParser::KeywordTable::kEntrySize] = {
     121             :   {'j', 'a', 'n', DateParser::MONTH_NAME, 1},
     122             :   {'f', 'e', 'b', DateParser::MONTH_NAME, 2},
     123             :   {'m', 'a', 'r', DateParser::MONTH_NAME, 3},
     124             :   {'a', 'p', 'r', DateParser::MONTH_NAME, 4},
     125             :   {'m', 'a', 'y', DateParser::MONTH_NAME, 5},
     126             :   {'j', 'u', 'n', DateParser::MONTH_NAME, 6},
     127             :   {'j', 'u', 'l', DateParser::MONTH_NAME, 7},
     128             :   {'a', 'u', 'g', DateParser::MONTH_NAME, 8},
     129             :   {'s', 'e', 'p', DateParser::MONTH_NAME, 9},
     130             :   {'o', 'c', 't', DateParser::MONTH_NAME, 10},
     131             :   {'n', 'o', 'v', DateParser::MONTH_NAME, 11},
     132             :   {'d', 'e', 'c', DateParser::MONTH_NAME, 12},
     133             :   {'a', 'm', '\0', DateParser::AM_PM, 0},
     134             :   {'p', 'm', '\0', DateParser::AM_PM, 12},
     135             :   {'u', 't', '\0', DateParser::TIME_ZONE_NAME, 0},
     136             :   {'u', 't', 'c', DateParser::TIME_ZONE_NAME, 0},
     137             :   {'z', '\0', '\0', DateParser::TIME_ZONE_NAME, 0},
     138             :   {'g', 'm', 't', DateParser::TIME_ZONE_NAME, 0},
     139             :   {'c', 'd', 't', DateParser::TIME_ZONE_NAME, -5},
     140             :   {'c', 's', 't', DateParser::TIME_ZONE_NAME, -6},
     141             :   {'e', 'd', 't', DateParser::TIME_ZONE_NAME, -4},
     142             :   {'e', 's', 't', DateParser::TIME_ZONE_NAME, -5},
     143             :   {'m', 'd', 't', DateParser::TIME_ZONE_NAME, -6},
     144             :   {'m', 's', 't', DateParser::TIME_ZONE_NAME, -7},
     145             :   {'p', 'd', 't', DateParser::TIME_ZONE_NAME, -7},
     146             :   {'p', 's', 't', DateParser::TIME_ZONE_NAME, -8},
     147             :   {'t', '\0', '\0', DateParser::TIME_SEPARATOR, 0},
     148             :   {'\0', '\0', '\0', DateParser::INVALID, 0},
     149             : };
     150             : 
     151             : 
     152             : // We could use perfect hashing here, but this is not a bottleneck.
     153      278762 : int DateParser::KeywordTable::Lookup(const uint32_t* pre, int len) {
     154             :   int i;
     155     4906650 :   for (i = 0; array[i][kTypeOffset] != INVALID; i++) {
     156             :     int j = 0;
     157    10913886 :     while (j < kPrefixLength &&
     158     5362650 :            pre[j] == static_cast<uint32_t>(array[i][j])) {
     159      734762 :       j++;
     160             :     }
     161             :     // Check if we have a match and the length is legal.
     162             :     // Word longer than keyword is only allowed for month names.
     163     4816474 :     if (j == kPrefixLength &&
     164         189 :         (len <= kPrefixLength || array[i][kTypeOffset] == MONTH_NAME)) {
     165             :       return i;
     166             :     }
     167             :   }
     168             :   return i;
     169             : }
     170             : 
     171             : 
     172        3876 : int DateParser::ReadMilliseconds(DateToken token) {
     173             :   // Read first three significant digits of the original numeral,
     174             :   // as inferred from the value and the number of digits.
     175             :   // I.e., use the number of digits to see if there were
     176             :   // leading zeros.
     177        3876 :   int number = token.number();
     178        3876 :   int length = token.length();
     179        3876 :   if (length < 3) {
     180             :     // Less than three digits. Multiply to put most significant digit
     181             :     // in hundreds position.
     182          75 :     if (length == 1) {
     183          60 :       number *= 100;
     184          15 :     } else if (length == 2) {
     185          15 :       number *= 10;
     186             :     }
     187        3801 :   } else if (length > 3) {
     188          30 :     if (length > kMaxSignificantDigits) length = kMaxSignificantDigits;
     189             :     // More than three digits. Divide by 10^(length - 3) to get three
     190             :     // most significant digits.
     191             :     int factor = 1;
     192         105 :     do {
     193             :       DCHECK(factor <= 100000000);  // factor won't overflow.
     194         105 :       factor *= 10;
     195         105 :       length--;
     196             :     } while (length > 3);
     197          30 :     number /= factor;
     198             :   }
     199        3876 :   return number;
     200             : }
     201             : 
     202             : 
     203             : }  // namespace internal
     204             : }  // namespace v8

Generated by: LCOV version 1.10