[SCM] WebKit Debian packaging branch, webkit-1.2, updated. upstream/1.1.90-6072-g9a69373

tkent at chromium.org tkent at chromium.org
Wed Apr 7 23:44:43 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit bdbdef0432048812c44426c1650d6e88abfaa075
Author: tkent at chromium.org <tkent at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Tue Nov 17 05:13:08 2009 +0000

    2009-11-16  Kent Tamura  <tkent at chromium.org>
    
            Reviewed by David Levin.
    
            Introduce WebCore::ISODateTime class.
            https://bugs.webkit.org/show_bug.cgi?id=31340
    
            This class represents a value of date/time types of the HTML5 INPUT
            element, and has some parsing methods for ISO 8601.
    
            This change has no tests because the class is not used yet.
    
            * GNUmakefile.am: Add ISODateTime.cpp and ISODateTime.h.
            * WebCore.gypi: ditto.
            * WebCore.pro: ditto.
            * WebCore.vcproj/WebCore.vcproj: ditto.
            * WebCore.xcodeproj/project.pbxproj: ditto.
            * WebCoreSources.bkl: ditto.
            * html/ISODateTime.cpp: Added. Implementation of WebCore::ISODateTime class.
            (WebCore::isLeapYear):
            (WebCore::maxDayOfMonth):
            (WebCore::dayOfWeek):
            (WebCore::ISODateTime::maxWeekNumberInYear):
            (WebCore::countDigits):
            (WebCore::toInt):
            (WebCore::ISODateTime::parseYear): Private helper for parseDate() and parseWeek().
            (WebCore::ISODateTime::addDay): Private helper for parseTimeZone().
            (WebCore::ISODateTime::addMinute): ditto.
            (WebCore::ISODateTime::parseTimeZone): Private helper for parseDateTime().
            (WebCore::ISODateTime::parseMonth): Parser for <input type=month>.
            (WebCore::ISODateTime::parseDate): Parser for <input type=date>.
            (WebCore::ISODateTime::parseWeek): Parser for <input type=week>.
            (WebCore::ISODateTime::parseTime): Parser for <input type=time>.
            (WebCore::ISODateTime::parseDateTimeLocal): Parser for <input type=datetime-local>.
            (WebCore::ISODateTime::parseDateTime): Parser for <input type=datetime>.
            * html/ISODateTime.h: Added.  Declare WebCore::ISODateTime class.
            (WebCore::ISODateTime::ISODateTime):
            (WebCore::ISODateTime::millisecond):
            (WebCore::ISODateTime::second):
            (WebCore::ISODateTime::minute):
            (WebCore::ISODateTime::hour):
            (WebCore::ISODateTime::monthDay):
            (WebCore::ISODateTime::month):
            (WebCore::ISODateTime::fullYear):
            (WebCore::ISODateTime::week):
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@51063 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 02a81f1..02d0a1d 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,49 @@
+2009-11-16  Kent Tamura  <tkent at chromium.org>
+
+        Reviewed by David Levin.
+
+        Introduce WebCore::ISODateTime class.
+        https://bugs.webkit.org/show_bug.cgi?id=31340
+
+        This class represents a value of date/time types of the HTML5 INPUT
+        element, and has some parsing methods for ISO 8601.
+
+        This change has no tests because the class is not used yet.
+
+        * GNUmakefile.am: Add ISODateTime.cpp and ISODateTime.h.
+        * WebCore.gypi: ditto.
+        * WebCore.pro: ditto.
+        * WebCore.vcproj/WebCore.vcproj: ditto.
+        * WebCore.xcodeproj/project.pbxproj: ditto.
+        * WebCoreSources.bkl: ditto.
+        * html/ISODateTime.cpp: Added. Implementation of WebCore::ISODateTime class.
+        (WebCore::isLeapYear):
+        (WebCore::maxDayOfMonth):
+        (WebCore::dayOfWeek):
+        (WebCore::ISODateTime::maxWeekNumberInYear):
+        (WebCore::countDigits):
+        (WebCore::toInt):
+        (WebCore::ISODateTime::parseYear): Private helper for parseDate() and parseWeek().
+        (WebCore::ISODateTime::addDay): Private helper for parseTimeZone().
+        (WebCore::ISODateTime::addMinute): ditto.
+        (WebCore::ISODateTime::parseTimeZone): Private helper for parseDateTime().
+        (WebCore::ISODateTime::parseMonth): Parser for <input type=month>.
+        (WebCore::ISODateTime::parseDate): Parser for <input type=date>.
+        (WebCore::ISODateTime::parseWeek): Parser for <input type=week>.
+        (WebCore::ISODateTime::parseTime): Parser for <input type=time>.
+        (WebCore::ISODateTime::parseDateTimeLocal): Parser for <input type=datetime-local>.
+        (WebCore::ISODateTime::parseDateTime): Parser for <input type=datetime>.
+        * html/ISODateTime.h: Added.  Declare WebCore::ISODateTime class.
+        (WebCore::ISODateTime::ISODateTime):
+        (WebCore::ISODateTime::millisecond):
+        (WebCore::ISODateTime::second):
+        (WebCore::ISODateTime::minute):
+        (WebCore::ISODateTime::hour):
+        (WebCore::ISODateTime::monthDay):
+        (WebCore::ISODateTime::month):
+        (WebCore::ISODateTime::fullYear):
+        (WebCore::ISODateTime::week):
+
 2009-11-16  Alexey Proskuryakov  <ap at apple.com>
 
         Fix a typo in previous commit.
diff --git a/WebCore/GNUmakefile.am b/WebCore/GNUmakefile.am
index e759831..f523946 100644
--- a/WebCore/GNUmakefile.am
+++ b/WebCore/GNUmakefile.am
@@ -1129,6 +1129,8 @@ webcore_sources += \
 	WebCore/html/HTMLUListElement.h \
 	WebCore/html/HTMLViewSourceDocument.cpp \
 	WebCore/html/HTMLViewSourceDocument.h \
+	WebCore/html/ISODateTime.cpp \
+	WebCore/html/ISODateTime.h \
 	WebCore/html/ImageData.cpp \
 	WebCore/html/ImageData.h \
 	WebCore/html/MediaError.h \
diff --git a/WebCore/WebCore.gypi b/WebCore/WebCore.gypi
index 064bb31..cc71e64 100644
--- a/WebCore/WebCore.gypi
+++ b/WebCore/WebCore.gypi
@@ -1503,6 +1503,8 @@
             'html/HTMLVideoElement.h',
             'html/HTMLViewSourceDocument.cpp',
             'html/HTMLViewSourceDocument.h',
+            'html/ISODateTime.cpp',
+            'html/ISODateTime.h',
             'html/ImageData.cpp',
             'html/ImageData.h',
             'html/MediaError.h',
diff --git a/WebCore/WebCore.pro b/WebCore/WebCore.pro
index f889ede..37da429 100644
--- a/WebCore/WebCore.pro
+++ b/WebCore/WebCore.pro
@@ -1071,6 +1071,7 @@ SOURCES += \
     html/HTMLTokenizer.cpp \
     html/HTMLUListElement.cpp \
     html/HTMLViewSourceDocument.cpp \
+    html/ISODateTime.cpp \
     html/ImageData.cpp \
     html/PreloadScanner.cpp \
     html/ValidityState.cpp \
@@ -1751,6 +1752,7 @@ HEADERS += \
     html/HTMLUListElement.h \
     html/HTMLVideoElement.h \
     html/HTMLViewSourceDocument.h \
+    html/ISODateTime.h \
     html/ImageData.h \
     html/PreloadScanner.h \
     html/TimeRanges.h \
diff --git a/WebCore/WebCore.vcproj/WebCore.vcproj b/WebCore/WebCore.vcproj/WebCore.vcproj
index 434d25a..bc53df9 100644
--- a/WebCore/WebCore.vcproj/WebCore.vcproj
+++ b/WebCore/WebCore.vcproj/WebCore.vcproj
@@ -33795,6 +33795,14 @@
 				>
 			</File>
 			<File
+				RelativePath="..\html\ISODateParser.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\html\ISODateParser.h"
+				>
+			</File>
+			<File
 				RelativePath="..\html\ImageData.cpp"
 				>
 			</File>
diff --git a/WebCore/WebCore.xcodeproj/project.pbxproj b/WebCore/WebCore.xcodeproj/project.pbxproj
index b63263a..aeadebe 100644
--- a/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/WebCore/WebCore.xcodeproj/project.pbxproj
@@ -4739,6 +4739,8 @@
 		F5C041E50FFCA96D00839D4A /* DOMHTMLDataListElementInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = F5C041E00FFCA96D00839D4A /* DOMHTMLDataListElementInternal.h */; };
 		F5C041E60FFCA96D00839D4A /* JSHTMLDataListElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5C041E10FFCA96D00839D4A /* JSHTMLDataListElement.cpp */; };
 		F5C041E70FFCA96D00839D4A /* JSHTMLDataListElement.h in Headers */ = {isa = PBXBuildFile; fileRef = F5C041E20FFCA96D00839D4A /* JSHTMLDataListElement.h */; };
+		F5D3A57C106B83B300545297 /* ISODateTime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5D3A57A106B83B300545297 /* ISODateTime.cpp */; };
+		F5D3A57D106B83B300545297 /* ISODateTime.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D3A57B106B83B300545297 /* ISODateTime.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		F916C48D0DB510F80076CD83 /* JSXMLHttpRequestProgressEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F916C48B0DB510F80076CD83 /* JSXMLHttpRequestProgressEvent.cpp */; };
 		F916C48E0DB510F80076CD83 /* JSXMLHttpRequestProgressEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = F916C48C0DB510F80076CD83 /* JSXMLHttpRequestProgressEvent.h */; };
 		F9F0ED7A0DB50CA200D16DB9 /* XMLHttpRequestProgressEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = F9F0ED770DB50CA200D16DB9 /* XMLHttpRequestProgressEvent.h */; };
@@ -9949,6 +9951,8 @@
 		F5C2869302846DCD018635CA /* ApplicationServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ApplicationServices.framework; path = /System/Library/Frameworks/ApplicationServices.framework; sourceTree = "<absolute>"; };
 		F5C2869402846DCD018635CA /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = "<absolute>"; };
 		F5C2869502846DCD018635CA /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
+		F5D3A57A106B83B300545297 /* ISODateTime.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ISODateTime.cpp; sourceTree = "<group>"; };
+		F5D3A57B106B83B300545297 /* ISODateTime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ISODateTime.h; sourceTree = "<group>"; };
 		F8216299029F4FB501000131 /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = JavaScriptCore.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		F916C48B0DB510F80076CD83 /* JSXMLHttpRequestProgressEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSXMLHttpRequestProgressEvent.cpp; sourceTree = "<group>"; };
 		F916C48C0DB510F80076CD83 /* JSXMLHttpRequestProgressEvent.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSXMLHttpRequestProgressEvent.h; sourceTree = "<group>"; };
@@ -12736,6 +12740,8 @@
 				E446139A0CD6331000FADA75 /* HTMLVideoElement.idl */,
 				BCCD74E40A4C8DDF005FDA6D /* HTMLViewSourceDocument.cpp */,
 				BCCD74DB0A4C8D35005FDA6D /* HTMLViewSourceDocument.h */,
+				F5D3A57A106B83B300545297 /* ISODateTime.cpp */,
+				F5D3A57B106B83B300545297 /* ISODateTime.h */,
 				A77979130D6B9D0C003851B9 /* ImageData.cpp */,
 				A77979140D6B9D0C003851B9 /* ImageData.h */,
 				A77979150D6B9D0C003851B9 /* ImageData.idl */,
@@ -16900,6 +16906,7 @@
 				BCCD74DC0A4C8D35005FDA6D /* HTMLViewSourceDocument.h in Headers */,
 				514C76710CE923A1007EF3CD /* HTTPHeaderMap.h in Headers */,
 				514C76730CE923A1007EF3CD /* HTTPParsers.h in Headers */,
+				F5D3A57D106B83B300545297 /* ISODateTime.h in Headers */,
 				B275356E0B053814002CE64F /* Icon.h in Headers */,
 				5126E6BC0A2E3B12005C29FA /* IconDatabase.h in Headers */,
 				51E1ECBE0C91C90400DC255B /* IconDatabaseClient.h in Headers */,
@@ -19045,6 +19052,7 @@
 				BCCD74E50A4C8DDF005FDA6D /* HTMLViewSourceDocument.cpp in Sources */,
 				0B8C56D40F28627F000502E1 /* HTTPHeaderMap.cpp in Sources */,
 				514C76720CE923A1007EF3CD /* HTTPParsers.cpp in Sources */,
+				F5D3A57C106B83B300545297 /* ISODateTime.cpp in Sources */,
 				5126E6BB0A2E3B12005C29FA /* IconDatabase.cpp in Sources */,
 				445C8DB710015FC90031531A /* IconDatabaseNone.cpp in Sources */,
 				1A2D753E0DE47FAB00F0A648 /* IconFetcher.cpp in Sources */,
diff --git a/WebCore/WebCoreSources.bkl b/WebCore/WebCoreSources.bkl
index 72c208a..236e2e2 100644
--- a/WebCore/WebCoreSources.bkl
+++ b/WebCore/WebCoreSources.bkl
@@ -674,6 +674,7 @@ This file contains the list of files needed to build WebCore.
         html/HTMLTokenizer.cpp
         html/HTMLUListElement.cpp
         html/HTMLViewSourceDocument.cpp
+        html/ISODateTime.cpp
         html/ImageData.cpp
         html/PreloadScanner.cpp
         html/ValidityState.cpp
diff --git a/WebCore/html/ISODateTime.cpp b/WebCore/html/ISODateTime.cpp
new file mode 100644
index 0000000..3980935
--- /dev/null
+++ b/WebCore/html/ISODateTime.cpp
@@ -0,0 +1,434 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ISODateTime.h"
+
+#include <wtf/ASCIICType.h>
+
+namespace WebCore {
+
+// The oldest day of Gregorian Calendar is 1582-10-15. We don't support dates older than it.
+static const int gregorianStartYear = 1582;
+static const int gregorianStartMonth = 9; // This is October, since months are 0 based.
+static const int gregorianStartDay = 15;
+
+static const int daysInMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+
+static bool isLeapYear(int year)
+{
+    if (year % 4)
+        return false;
+    if (!(year % 400))
+        return true;
+    if (!(year % 100))
+        return false;
+    return true;
+}
+
+// `month' is 0-based.
+static int maxDayOfMonth(int year, int month)
+{
+    if (month != 1) // February?
+        return daysInMonth[month];
+    return isLeapYear(year) ? 29 : 28;
+}
+
+// `month' is 0-based.
+static int dayOfWeek(int year, int month, int day)
+{
+    int shiftedMonth = month + 2;
+    // 2:January, 3:Feburuary, 4:March, ...
+
+    // Zeller's congruence
+    if (shiftedMonth <= 3) {
+        shiftedMonth += 12;
+        year--;
+    }
+    // 4:March, ..., 14:January, 15:February
+
+    int highYear = year / 100;
+    int lowYear = year % 100;
+    // We add 6 to make the result Sunday-origin.
+    int result = (day + 13 * shiftedMonth / 5 + lowYear + lowYear / 4 + highYear / 4 + 5 * highYear + 6) % 7;
+    return result;
+}
+
+int ISODateTime::maxWeekNumberInYear() const
+{
+    int day = dayOfWeek(m_year, 0, 1); // January 1.
+    return day == Thursday || (day == Wednesday && isLeapYear(m_year)) ? 53 : 52;
+}
+
+static unsigned countDigits(const UChar* src, unsigned length, unsigned start)
+{
+    unsigned index = start;
+    for (; index < length; ++index) {
+        if (!isASCIIDigit(src[index]))
+            break;
+    }
+    return index - start;
+}
+
+// Very strict integer parser. Do not allow leading or trailing whitespace unlike charactersToIntStrict().
+static bool toInt(const UChar* src, unsigned length, unsigned parseStart, unsigned parseLength, int& out)
+{
+    if (parseStart + parseLength > length || parseLength <= 0)
+        return false;
+    int value = 0;
+    const UChar* current = src + parseStart;
+    const UChar* end = current + parseLength;
+
+    // We don't need to handle negative numbers for ISO 8601.
+    for (; current < end; ++current) {
+        if (!isASCIIDigit(*current))
+            return false;
+        int digit = *current - '0';
+        if (value > (INT_MAX - digit) / 10) // Check for overflow.
+            return false;
+        value = value * 10 + digit;
+    }
+    out = value;
+    return true;
+}
+
+bool ISODateTime::parseYear(const UChar* src, unsigned length, unsigned start, unsigned& end)
+{
+    unsigned digitsLength = countDigits(src, length, start);
+    // Needs at least 4 digits according to the standard.
+    if (digitsLength < 4)
+        return false;
+    int year;
+    if (!toInt(src, length, start, digitsLength, year))
+        return false;
+    // No support for years before Gregorian calendar.
+    if (year < gregorianStartYear)
+        return false;
+    m_year = year;
+    end = start + digitsLength;
+    return true;
+}
+
+bool ISODateTime::addDay(int dayDiff)
+{
+    ASSERT(m_monthDay);
+
+    int day = m_monthDay + dayDiff;
+    if (day > maxDayOfMonth(m_year, m_month)) {
+        day = m_monthDay;
+        int year = m_year;
+        int month = m_month;
+        int maxDay = maxDayOfMonth(year, month);
+        for (; dayDiff > 0; --dayDiff) {
+            ++day;
+            if (day > maxDay) {
+                day = 1;
+                ++month;
+                if (month >= 12) { // month is 0-origin.
+                    month = 0;
+                    ++year;
+                    if (year < 0) // Check for overflow.
+                        return false;
+                }
+                maxDay = maxDayOfMonth(year, month);
+            }
+        }
+        m_year = year;
+        m_month = month;
+    } else if (day < 1) {
+        int month = m_month;
+        int year = m_year;
+        day = m_monthDay;
+        for (; dayDiff < 0; ++dayDiff) {
+            --day;
+            if (day < 1) {
+                --month;
+                if (month < 0) {
+                    month = 11;
+                    --year;
+                }
+                day = maxDayOfMonth(year, month);
+            }
+            if (year < gregorianStartYear
+                    || year == gregorianStartYear && month < gregorianStartMonth
+                    || year == gregorianStartYear && month == gregorianStartMonth && day < gregorianStartDay)
+                return false;
+        }
+        m_year = year;
+        m_month = month;
+    }
+    m_monthDay = day;
+    return true;
+}
+
+bool ISODateTime::addMinute(int minute)
+{
+    int carry;
+    // min can be negative or greater than 59.
+    minute += m_minute;
+    if (minute > 59) {
+        carry = minute / 60;
+        minute = minute % 60;
+    } else if (m_minute < 0) {
+        carry = (59 - m_minute) / 60;
+        minute += carry * 60;
+        carry = -carry;
+        ASSERT(minute >= 0 && minute <= 59);
+    } else {
+        m_minute = minute;
+        return true;
+    }
+
+    int hour = m_hour + carry;
+    if (hour > 23) {
+        carry = hour / 24;
+        hour = hour % 24;
+    } else if (hour < 0) {
+        carry = (23 - hour) / 24;
+        hour += carry * 24;
+        carry = -carry;
+        ASSERT(hour >= 0 && hour <= 23);
+    } else {
+        m_minute = minute;
+        m_hour = hour;
+        return true;
+    }
+    if (!addDay(carry))
+        return false;
+    m_minute = minute;
+    m_hour = hour;
+    return true;
+}
+
+// Parses a timezone part, and adjust year, month, monthDay, hour, minute, second, millisecond.
+bool ISODateTime::parseTimeZone(const UChar* src, unsigned length, unsigned start, unsigned& end)
+{
+    if (start >= length)
+        return false;
+    unsigned index = start;
+    if (src[index] == 'Z') {
+        end = index + 1;
+        return true;
+    }
+
+    bool minus;
+    if (src[index] == '+')
+        minus = false;
+    else if (src[index] == '-')
+        minus = true;
+    else
+        return false;
+    ++index;
+
+    int hour;
+    int minute;
+    if (!toInt(src, length, index, 2, hour) || hour < 0 || hour > 23)
+        return false;
+    index += 2;
+
+    if (index >= length || src[index] != ':')
+        return false;
+    ++index;
+
+    if (!toInt(src, length, index, 2, minute) || minute < 0 || minute > 59)
+        return false;
+    index += 2;
+
+    if (minus) {
+        hour = -hour;
+        minute = -minute;
+    }
+
+    // Subtract the timezone offset.
+    if (!addMinute(-(hour * 60 + minute)))
+        return false;
+    end = index;
+    return true;
+}
+
+bool ISODateTime::parseMonth(const UChar* src, unsigned length, unsigned start, unsigned& end)
+{
+    ASSERT(src);
+    unsigned index;
+    if (!parseYear(src, length, start, index))
+        return false;
+    if (index >= length || src[index] != '-')
+        return false;
+    ++index;
+
+    int month;
+    if (!toInt(src, length, index, 2, month) || month < 1 || month > 12)
+        return false;
+    --month;
+    // No support for months before Gregorian calendar.
+    if (m_year == gregorianStartYear && month < gregorianStartMonth)
+        return false;
+    m_month = month;
+    end = index + 2;
+    return true;
+}
+
+bool ISODateTime::parseDate(const UChar* src, unsigned length, unsigned start, unsigned& end)
+{
+    ASSERT(src);
+    unsigned index;
+    if (!parseMonth(src, length, start, index))
+        return false;
+    // '-' and 2-digits are needed.
+    if (index + 2 >= length)
+        return false;
+    if (src[index] != '-')
+        return false;
+    ++index;
+
+    int day;
+    if (!toInt(src, length, index, 2, day) || day < 1 || day > maxDayOfMonth(m_year, m_month))
+        return false;
+    // No support for dates before Gregorian calendar.
+    if (m_year == gregorianStartYear && m_month == gregorianStartMonth && day < gregorianStartDay)
+        return false;
+    m_monthDay = day;
+    end = index + 2;
+    return true;
+}
+
+bool ISODateTime::parseWeek(const UChar* src, unsigned length, unsigned start, unsigned& end)
+{
+    ASSERT(src);
+    unsigned index;
+    if (!parseYear(src, length, start, index))
+        return false;
+
+    // 4 characters ('-' 'W' digit digit) are needed.
+    if (index + 3 >= length)
+        return false;
+    if (src[index] != '-')
+        return false;
+    ++index;
+    if (src[index] != 'W')
+        return false;
+    ++index;
+
+    int week;
+    if (!toInt(src, length, index, 2, week) || week < 1 || week > maxWeekNumberInYear())
+        return false;
+    // No support for years older than or equals to Gregorian calendar start year.
+    if (m_year <= gregorianStartYear)
+        return false;
+    m_week = week;
+    end = index + 2;
+    return true;
+}
+
+bool ISODateTime::parseTime(const UChar* src, unsigned length, unsigned start, unsigned& end)
+{
+    ASSERT(src);
+    int hour;
+    if (!toInt(src, length, start, 2, hour) || hour < 0 || hour > 23)
+        return false;
+    unsigned index = start + 2;
+    if (index >= length)
+        return false;
+    if (src[index] != ':')
+        return false;
+    ++index;
+
+    int minute;
+    if (!toInt(src, length, index, 2, minute) || minute < 0 || minute > 59)
+        return false;
+    index += 2;
+
+    int second = 0;
+    int millisecond = 0;
+    // Optional second part.
+    // Do not return with false because the part is optional.
+    if (index + 2 < length && src[index] == ':') {
+        if (toInt(src, length, index + 1, 2, second) && second >= 0 && second <= 59) {
+            index += 3;
+
+            // Optional fractional second part.
+            if (index < length && src[index] == '.') {
+                unsigned digitsLength = countDigits(src, length, index + 1);
+                if (digitsLength >  0) {
+                    ++index;
+                    bool ok;
+                    if (digitsLength == 1) {
+                        ok = toInt(src, length, index, 1, millisecond);
+                        millisecond *= 100;
+                    } else if (digitsLength == 2) {
+                        ok = toInt(src, length, index, 2, millisecond);
+                        millisecond *= 10;
+                    } else // digitsLength >= 3
+                        ok = toInt(src, length, index, 3, millisecond);
+                    ASSERT(ok);
+                    index += digitsLength;
+                }
+            }
+        }
+    }
+    m_hour = hour;
+    m_minute = minute;
+    m_second = second;
+    m_millisecond = millisecond;
+    end = index;
+    return true;
+}
+
+bool ISODateTime::parseDateTimeLocal(const UChar* src, unsigned length, unsigned start, unsigned& end)
+{
+    ASSERT(src);
+    unsigned index;
+    if (!parseDate(src, length, start, index))
+        return false;
+    if (index >= length)
+        return false;
+    if (src[index] != 'T')
+        return false;
+    ++index;
+    return parseTime(src, length, index, end);
+}
+
+bool ISODateTime::parseDateTime(const UChar* src, unsigned length, unsigned start, unsigned& end)
+{
+    ASSERT(src);
+    unsigned index;
+    if (!parseDate(src, length, start, index))
+        return false;
+    if (index >= length)
+        return false;
+    if (src[index] != 'T')
+        return false;
+    ++index;
+    if (!parseTime(src, length, index, index))
+        return false;
+    return parseTimeZone(src, length, index, end);
+}
+
+} // namespace WebCore
diff --git a/WebCore/html/ISODateTime.h b/WebCore/html/ISODateTime.h
new file mode 100644
index 0000000..ee4cfb9
--- /dev/null
+++ b/WebCore/html/ISODateTime.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ISODateTime_h
+#define ISODateTime_h
+
+#include <wtf/unicode/Unicode.h>
+
+namespace WebCore {
+
+// An ISODateTime instance represents one of the following date and time combinations:
+// * year-month
+// * year-month-day
+// * year-week
+// * hour-minute-second-millisecond
+// * year-month-day hour-minute-second-millisecond
+class ISODateTime {
+public:
+    ISODateTime()
+        : m_millisecond(0)
+        , m_second(0)
+        , m_minute(0)
+        , m_hour(0)
+        , m_monthDay(0)
+        , m_month(0)
+        , m_year(0)
+        , m_week(0)
+    {
+    }
+
+    int millisecond() const { return m_millisecond; }
+    int second() const { return m_second; }
+    int minute() const { return m_minute; }
+    int hour() const { return m_hour; }
+    int monthDay() const { return m_monthDay; }
+    int month() const { return m_month; }
+    int fullYear() const { return m_year; }
+    int week() const { return m_week; }
+
+    // The following six functions parse the input `src' whose length is
+    // `length', and updates some fields of this instance. The parsing starts at
+    // src[start] and examines characters before src[length].
+    // `src' `date' must be non-null. The `src' string doesn't need to be
+    // null-terminated.
+    // The functions return true if the parsing succeeds, and set `end' to the
+    // next index after the last consumed. Extra leading characters cause parse
+    // failures, and the trailing extra characters don't cause parse failures.
+
+    // Sets year and month.
+    bool parseMonth(const UChar* src, unsigned length, unsigned start, unsigned& end);
+    // Sets year, month and monthDay.
+    bool parseDate(const UChar* src, unsigned length, unsigned start, unsigned& end);
+    // Sets year and week.
+    bool parseWeek(const UChar* src, unsigned length, unsigned start, unsigned& end);
+    // Sets hour, minute, second and millisecond.
+    bool parseTime(const UChar* src, unsigned length, unsigned start, unsigned& end);
+    // Sets year, month, monthDay, hour, minute, second and millisecond.
+    bool parseDateTimeLocal(const UChar* src, unsigned length, unsigned start, unsigned& end);
+    // Sets year, month, monthDay, hour, minute, second and millisecond, and adjusts timezone.
+    bool parseDateTime(const UChar* src, unsigned length, unsigned start, unsigned& end);
+
+private:
+    // Returns the maximum week number in this ISODateTime's year.
+    // The result is either of 52 and 53.
+    int maxWeekNumberInYear() const;
+    bool parseYear(const UChar* src, unsigned length, unsigned start, unsigned& end);
+    bool addDay(int);
+    bool addMinute(int);
+    bool parseTimeZone(const UChar* src, unsigned length, unsigned start, unsigned& end);
+
+    // m_weekDay values
+    enum {
+        Sunday = 0,
+        Monday,
+        Tuesday,
+        Wednesday,
+        Thursday,
+        Friday,
+        Saturday,
+    };
+
+    int m_millisecond;  // 0 - 999
+    int m_second;
+    int m_minute;
+    int m_hour;
+    int m_monthDay;  // 1 - 31
+    int m_month;  // 0:January - 11:December
+    int m_year;  //  1582 -
+    int m_week;  // 1 - 53
+};
+
+
+} // namespace WebCore
+
+#endif // ISODateTime_h

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list