<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[166097] trunk/Source/WebCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/166097">166097</a></dd>
<dt>Author</dt> <dd>bfulgham@apple.com</dd>
<dt>Date</dt> <dd>2014-03-21 14:26:41 -0700 (Fri, 21 Mar 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Merge VTTScanner Code from Blink
https://bugs.webkit.org/show_bug.cgi?id=130616

Reviewed by Eric Carlson.

Merged from Blink (patch by fs@opera.com):
https://chromium.googlesource.com/chromium/blink/+/f1ceb058d574a1174b524c57f67350510a942071
http://crbug.com/75273002
https://chromium.googlesource.com/chromium/blink/+/3e2c67969486e86347b328c72c67cacabfe6f4a1
http://crbug.com/134173002
https://chromium.googlesource.com/chromium/blink/+/5962b7bbb001838f3fc7f24817637528b86bfd9b
http://crbug.com/134153002
https://chromium.googlesource.com/chromium/blink/+/6c81f51438013edca920a19fc6a31026fc562af2
http://crbug.com/137033002
https://chromium.googlesource.com/chromium/blink/+/fa286dca17a291da3ae8be80111e2264de6d5cfd
http://crbug.com/140503004
https://chromium.googlesource.com/chromium/blink/+/8f33b63aabcce7dd21dd15288d45c4eb37c02001
http://crbug.com/139343006
https://chromium.googlesource.com/chromium/blink/+/1872b54b908fac525f1ad9d6f15174b11e27c8af
http://crbug.com/143983002
https://chromium.googlesource.com/chromium/blink/+/e6494b3359e2077bd8772d86ab1fb709acf4c398
http://crbug.com/144893002
 
* CMakeLists.txt:
* GNUmakefile.list.am:
* WebCore.vcxproj/WebCore.vcxproj:
* WebCore.vcxproj/WebCore.vcxproj.filters:
* WebCore.xcodeproj/project.pbxproj:
* html/track/ParsingUtilities.h: Added.
(skipExactly):
(skipUntil):
(skipWhile):
* html/track/VTTCue.cpp:
(WebCore::VTTCue::markFutureAndPastNodes):
(WebCore::VTTCue::settingName):
(WebCore::scanPercentage):
(WebCore::VTTCue::setCueSettings):
* html/track/VTTCue.h:
* html/track/VTTRegion.cpp:
(WebCore::VTTRegion::setRegionSettings):
(WebCore::VTTRegion::scanSettingName):
(WebCore::parsedEntireRun):
(WebCore::VTTRegion::parseSettingValue):
* html/track/VTTRegion.h:
* html/track/VTTScanner.cpp: Added.
(WebCore::VTTScanner::VTTScanner):
(WebCore::VTTScanner::scan):
(WebCore::VTTScanner::scanRun):
(WebCore::VTTScanner::skipRun):
(WebCore::VTTScanner::extractString):
(WebCore::VTTScanner::restOfInputAsString):
(WebCore::VTTScanner::scanDigits):
(WebCore::VTTScanner::scanFloat):
* html/track/VTTScanner.h: Added.
(WebCore::VTTScanner::Run::Run):
(WebCore::VTTScanner::Run::start):
(WebCore::VTTScanner::Run::end):
(WebCore::VTTScanner::Run::isEmpty):
(WebCore::VTTScanner::isAt):
(WebCore::VTTScanner::isAtEnd):
(WebCore::VTTScanner::match):
(WebCore::VTTScanner::position):
(WebCore::VTTScanner::end):
(WebCore::VTTScanner::LCharPredicateAdapter):
(WebCore::VTTScanner::Run::length):
(WebCore::VTTScanner::scan):
(WebCore::VTTScanner::skipWhile):
(WebCore::VTTScanner::skipUntil):
(WebCore::VTTScanner::collectWhile):
(WebCore::VTTScanner::collectUntil):
(WebCore::VTTScanner::seekTo):
(WebCore::VTTScanner::currentChar):
(WebCore::VTTScanner::advance):
* html/track/WebVTTParser.cpp:
(WebCore::WebVTTParser::parseFloatPercentageValue):
(WebCore::WebVTTParser::parseFloatPercentageValuePair):
(WebCore::WebVTTParser::collectTimingsAndSettings):
(WebCore::WebVTTParser::collectTimeStamp):
(WebCore::WebVTTTreeBuilder::constructTreeFromToken):
* html/track/WebVTTParser.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreCMakeListstxt">trunk/Source/WebCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreGNUmakefilelistam">trunk/Source/WebCore/GNUmakefile.list.am</a></li>
<li><a href="#trunkSourceWebCoreWebCorevcxprojWebCorevcxproj">trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj</a></li>
<li><a href="#trunkSourceWebCoreWebCorevcxprojWebCorevcxprojfilters">trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCorehtmltrackVTTCuecpp">trunk/Source/WebCore/html/track/VTTCue.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmltrackVTTCueh">trunk/Source/WebCore/html/track/VTTCue.h</a></li>
<li><a href="#trunkSourceWebCorehtmltrackVTTRegioncpp">trunk/Source/WebCore/html/track/VTTRegion.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmltrackVTTRegionh">trunk/Source/WebCore/html/track/VTTRegion.h</a></li>
<li><a href="#trunkSourceWebCorehtmltrackWebVTTParsercpp">trunk/Source/WebCore/html/track/WebVTTParser.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmltrackWebVTTParserh">trunk/Source/WebCore/html/track/WebVTTParser.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebCorehtmltrackParsingUtilitiesh">trunk/Source/WebCore/html/track/ParsingUtilities.h</a></li>
<li><a href="#trunkSourceWebCorehtmltrackVTTScannercpp">trunk/Source/WebCore/html/track/VTTScanner.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmltrackVTTScannerh">trunk/Source/WebCore/html/track/VTTScanner.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/CMakeLists.txt (166096 => 166097)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/CMakeLists.txt        2014-03-21 21:14:46 UTC (rev 166096)
+++ trunk/Source/WebCore/CMakeLists.txt        2014-03-21 21:26:41 UTC (rev 166097)
</span><span class="lines">@@ -2742,6 +2742,7 @@
</span><span class="cx">         html/track/VideoTrack.cpp
</span><span class="cx">         html/track/VideoTrackList.cpp
</span><span class="cx">         html/track/VTTCue.cpp
</span><ins>+        html/track/VTTScanner.cpp
</ins><span class="cx">         html/track/WebVTTElement.cpp
</span><span class="cx">         html/track/WebVTTParser.cpp
</span><span class="cx">         html/track/WebVTTTokenizer.cpp
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (166096 => 166097)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-03-21 21:14:46 UTC (rev 166096)
+++ trunk/Source/WebCore/ChangeLog        2014-03-21 21:26:41 UTC (rev 166097)
</span><span class="lines">@@ -1,3 +1,86 @@
</span><ins>+2014-03-21  Brent Fulgham  &lt;bfulgham@apple.com&gt;
+
+        Merge VTTScanner Code from Blink
+        https://bugs.webkit.org/show_bug.cgi?id=130616
+
+        Reviewed by Eric Carlson.
+
+        Merged from Blink (patch by fs@opera.com):
+        https://chromium.googlesource.com/chromium/blink/+/f1ceb058d574a1174b524c57f67350510a942071
+        http://crbug.com/75273002
+        https://chromium.googlesource.com/chromium/blink/+/3e2c67969486e86347b328c72c67cacabfe6f4a1
+        http://crbug.com/134173002
+        https://chromium.googlesource.com/chromium/blink/+/5962b7bbb001838f3fc7f24817637528b86bfd9b
+        http://crbug.com/134153002
+        https://chromium.googlesource.com/chromium/blink/+/6c81f51438013edca920a19fc6a31026fc562af2
+        http://crbug.com/137033002
+        https://chromium.googlesource.com/chromium/blink/+/fa286dca17a291da3ae8be80111e2264de6d5cfd
+        http://crbug.com/140503004
+        https://chromium.googlesource.com/chromium/blink/+/8f33b63aabcce7dd21dd15288d45c4eb37c02001
+        http://crbug.com/139343006
+        https://chromium.googlesource.com/chromium/blink/+/1872b54b908fac525f1ad9d6f15174b11e27c8af
+        http://crbug.com/143983002
+        https://chromium.googlesource.com/chromium/blink/+/e6494b3359e2077bd8772d86ab1fb709acf4c398
+        http://crbug.com/144893002

+        * CMakeLists.txt:
+        * GNUmakefile.list.am:
+        * WebCore.vcxproj/WebCore.vcxproj:
+        * WebCore.vcxproj/WebCore.vcxproj.filters:
+        * WebCore.xcodeproj/project.pbxproj:
+        * html/track/ParsingUtilities.h: Added.
+        (skipExactly):
+        (skipUntil):
+        (skipWhile):
+        * html/track/VTTCue.cpp:
+        (WebCore::VTTCue::markFutureAndPastNodes):
+        (WebCore::VTTCue::settingName):
+        (WebCore::scanPercentage):
+        (WebCore::VTTCue::setCueSettings):
+        * html/track/VTTCue.h:
+        * html/track/VTTRegion.cpp:
+        (WebCore::VTTRegion::setRegionSettings):
+        (WebCore::VTTRegion::scanSettingName):
+        (WebCore::parsedEntireRun):
+        (WebCore::VTTRegion::parseSettingValue):
+        * html/track/VTTRegion.h:
+        * html/track/VTTScanner.cpp: Added.
+        (WebCore::VTTScanner::VTTScanner):
+        (WebCore::VTTScanner::scan):
+        (WebCore::VTTScanner::scanRun):
+        (WebCore::VTTScanner::skipRun):
+        (WebCore::VTTScanner::extractString):
+        (WebCore::VTTScanner::restOfInputAsString):
+        (WebCore::VTTScanner::scanDigits):
+        (WebCore::VTTScanner::scanFloat):
+        * html/track/VTTScanner.h: Added.
+        (WebCore::VTTScanner::Run::Run):
+        (WebCore::VTTScanner::Run::start):
+        (WebCore::VTTScanner::Run::end):
+        (WebCore::VTTScanner::Run::isEmpty):
+        (WebCore::VTTScanner::isAt):
+        (WebCore::VTTScanner::isAtEnd):
+        (WebCore::VTTScanner::match):
+        (WebCore::VTTScanner::position):
+        (WebCore::VTTScanner::end):
+        (WebCore::VTTScanner::LCharPredicateAdapter):
+        (WebCore::VTTScanner::Run::length):
+        (WebCore::VTTScanner::scan):
+        (WebCore::VTTScanner::skipWhile):
+        (WebCore::VTTScanner::skipUntil):
+        (WebCore::VTTScanner::collectWhile):
+        (WebCore::VTTScanner::collectUntil):
+        (WebCore::VTTScanner::seekTo):
+        (WebCore::VTTScanner::currentChar):
+        (WebCore::VTTScanner::advance):
+        * html/track/WebVTTParser.cpp:
+        (WebCore::WebVTTParser::parseFloatPercentageValue):
+        (WebCore::WebVTTParser::parseFloatPercentageValuePair):
+        (WebCore::WebVTTParser::collectTimingsAndSettings):
+        (WebCore::WebVTTParser::collectTimeStamp):
+        (WebCore::WebVTTTreeBuilder::constructTreeFromToken):
+        * html/track/WebVTTParser.h:
+
</ins><span class="cx"> 2014-03-21  Benjamin Poulain  &lt;bpoulain@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Pseudo type cleanup part 2: split pseudo elements parsing
</span></span></pre></div>
<a id="trunkSourceWebCoreGNUmakefilelistam"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/GNUmakefile.list.am (166096 => 166097)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/GNUmakefile.list.am        2014-03-21 21:14:46 UTC (rev 166096)
+++ trunk/Source/WebCore/GNUmakefile.list.am        2014-03-21 21:26:41 UTC (rev 166097)
</span><span class="lines">@@ -3695,6 +3695,7 @@
</span><span class="cx">         Source/WebCore/html/track/InbandWebVTTTextTrack.h \
</span><span class="cx">         Source/WebCore/html/track/LoadableTextTrack.cpp \
</span><span class="cx">         Source/WebCore/html/track/LoadableTextTrack.h \
</span><ins>+        Source/WebCore/html/track/ParsingUtilities.h \
</ins><span class="cx">         Source/WebCore/html/track/TextTrack.cpp \
</span><span class="cx">         Source/WebCore/html/track/TextTrack.h \
</span><span class="cx">         Source/WebCore/html/track/TextTrackCue.cpp \
</span><span class="lines">@@ -3719,6 +3720,8 @@
</span><span class="cx">         Source/WebCore/html/track/VideoTrackList.h \
</span><span class="cx">         Source/WebCore/html/track/VTTCue.cpp \
</span><span class="cx">         Source/WebCore/html/track/VTTCue.h \
</span><ins>+        Source/WebCore/html/track/VTTScanner.cpp \
+        Source/WebCore/html/track/VTTScanner.h \
</ins><span class="cx">         Source/WebCore/html/track/WebVTTElement.cpp \
</span><span class="cx">         Source/WebCore/html/track/WebVTTElement.h \
</span><span class="cx">         Source/WebCore/html/track/WebVTTParser.cpp \
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorevcxprojWebCorevcxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj (166096 => 166097)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj        2014-03-21 21:14:46 UTC (rev 166096)
+++ trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj        2014-03-21 21:26:41 UTC (rev 166097)
</span><span class="lines">@@ -15850,6 +15850,7 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\html\track\TrackBase.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\html\track\TrackEvent.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\html\track\VTTCue.cpp&quot; /&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\html\track\VTTScanner.cpp&quot; /&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\html\track\WebVTTParser.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\html\track\WebVTTTokenizer.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\bindings\generic\ActiveDOMCallback.cpp&quot; /&gt;
</span><span class="lines">@@ -20592,6 +20593,7 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\html\track\InbandTextTrack.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\html\track\InbandWebVTTTextTrack.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\html\track\LoadableTextTrack.h&quot; /&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\html\track\ParsingUtilities.h&quot; /&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\html\track\TextTrack.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\html\track\TextTrackCue.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\html\track\TextTrackCueList.h&quot; /&gt;
</span><span class="lines">@@ -20599,6 +20601,7 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\html\track\TrackBase.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\html\track\TrackEvent.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\html\track\VTTCue.h&quot; /&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\html\track\VTTScanner.h&quot; /&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\html\track\WebVTTParser.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\html\track\WebVTTToken.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\html\track\WebVTTTokenizer.h&quot; /&gt;
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorevcxprojWebCorevcxprojfilters"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters (166096 => 166097)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters        2014-03-21 21:14:46 UTC (rev 166096)
+++ trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters        2014-03-21 21:26:41 UTC (rev 166097)
</span><span class="lines">@@ -4200,6 +4200,9 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\html\track\VTTCue.cpp&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;html\track&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClCompile&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\html\track\VTTScanner.cpp&quot;&gt;
+      &lt;Filter&gt;html\track&lt;/Filter&gt;
+    &lt;/ClCompile&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\html\track\WebVTTParser.cpp&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;html\track&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClCompile&gt;
</span><span class="lines">@@ -11245,6 +11248,9 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\html\track\LoadableTextTrack.h&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;html\track&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClInclude&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\html\track\ParsingUtilities.h&quot;&gt;
+      &lt;Filter&gt;html\track&lt;/Filter&gt;
+    &lt;/ClInclude&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\html\track\TextTrack.h&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;html\track&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClInclude&gt;
</span><span class="lines">@@ -11266,6 +11272,9 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\html\track\VTTCue.h&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;html\track&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClInclude&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\html\track\VTTScanner.h&quot;&gt;
+      &lt;Filter&gt;html\track&lt;/Filter&gt;
+    &lt;/ClInclude&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\html\track\WebVTTParser.h&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;html\track&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClInclude&gt;
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (166096 => 166097)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2014-03-21 21:14:46 UTC (rev 166096)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2014-03-21 21:26:41 UTC (rev 166097)
</span><span class="lines">@@ -2297,6 +2297,9 @@
</span><span class="cx">                 7A74ECBA101839A600BF939E /* InspectorDOMStorageAgent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7A74ECB8101839A500BF939E /* InspectorDOMStorageAgent.cpp */; };
</span><span class="cx">                 7A74ECBB101839A600BF939E /* InspectorDOMStorageAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A74ECB9101839A600BF939E /* InspectorDOMStorageAgent.h */; };
</span><span class="cx">                 7A74ECBD101839DA00BF939E /* JSInspectorFrontendHostCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7A74ECBC101839DA00BF939E /* JSInspectorFrontendHostCustom.cpp */; };
</span><ins>+                7A93868418DCC14500B8263D /* ParsingUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A93868118DCC14500B8263D /* ParsingUtilities.h */; };
+                7A93868518DCC14500B8263D /* VTTScanner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7A93868218DCC14500B8263D /* VTTScanner.cpp */; };
+                7A93868618DCC14500B8263D /* VTTScanner.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A93868318DCC14500B8263D /* VTTScanner.h */; };
</ins><span class="cx">                 7AABA25914BC613300AA9A11 /* DOMEditor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7AABA25714BC613300AA9A11 /* DOMEditor.cpp */; };
</span><span class="cx">                 7AABA25A14BC613300AA9A11 /* DOMEditor.h in Headers */ = {isa = PBXBuildFile; fileRef = 7AABA25814BC613300AA9A11 /* DOMEditor.h */; };
</span><span class="cx">                 7AB0B1C01211A62200A76940 /* InspectorDatabaseAgent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7AB0B1BE1211A62200A76940 /* InspectorDatabaseAgent.cpp */; };
</span><span class="lines">@@ -9306,6 +9309,9 @@
</span><span class="cx">                 7A74ECB8101839A500BF939E /* InspectorDOMStorageAgent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorDOMStorageAgent.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 7A74ECB9101839A600BF939E /* InspectorDOMStorageAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorDOMStorageAgent.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 7A74ECBC101839DA00BF939E /* JSInspectorFrontendHostCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSInspectorFrontendHostCustom.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                7A93868118DCC14500B8263D /* ParsingUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParsingUtilities.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                7A93868218DCC14500B8263D /* VTTScanner.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VTTScanner.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                7A93868318DCC14500B8263D /* VTTScanner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VTTScanner.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 7AABA25714BC613300AA9A11 /* DOMEditor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DOMEditor.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 7AABA25814BC613300AA9A11 /* DOMEditor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMEditor.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 7AB0B1BE1211A62200A76940 /* InspectorDatabaseAgent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorDatabaseAgent.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -19259,6 +19265,7 @@
</span><span class="cx">                 B1AD4E7713A12A7200846B27 /* track */ = {
</span><span class="cx">                         isa = PBXGroup;
</span><span class="cx">                         children = (
</span><ins>+                                7A93868118DCC14500B8263D /* ParsingUtilities.h */,
</ins><span class="cx">                                 7A45032D18DB717200377B34 /* BufferedLineReader.cpp */,
</span><span class="cx">                                 7A45032E18DB717200377B34 /* BufferedLineReader.h */,
</span><span class="cx">                                 BE88E0CC1715D2A200658D98 /* AudioTrack.cpp */,
</span><span class="lines">@@ -19314,6 +19321,8 @@
</span><span class="cx">                                 BE20507618A458460080647E /* VTTCue.cpp */,
</span><span class="cx">                                 BE20507718A458460080647E /* VTTCue.h */,
</span><span class="cx">                                 BE20507818A458460080647E /* VTTCue.idl */,
</span><ins>+                                7A93868218DCC14500B8263D /* VTTScanner.cpp */,
+                                7A93868318DCC14500B8263D /* VTTScanner.h */,
</ins><span class="cx">                                 F12171F316A8BC63000053CA /* WebVTTElement.cpp */,
</span><span class="cx">                                 F12171F416A8BC63000053CA /* WebVTTElement.h */,
</span><span class="cx">                                 5D21A80013ECE5DF00BB7064 /* WebVTTParser.cpp */,
</span><span class="lines">@@ -23924,6 +23933,7 @@
</span><span class="cx">                                 A871DE2B0A152AC800B12A68 /* HTMLFrameElement.h in Headers */,
</span><span class="cx">                                 14FFE31D0AE1963300136BF5 /* HTMLFrameElementBase.h in Headers */,
</span><span class="cx">                                 93E241FF0B2B4E4000C732A1 /* HTMLFrameOwnerElement.h in Headers */,
</span><ins>+                                7A93868418DCC14500B8263D /* ParsingUtilities.h in Headers */,
</ins><span class="cx">                                 A871DE280A152AC800B12A68 /* HTMLFrameSetElement.h in Headers */,
</span><span class="cx">                                 A871DE2D0A152AC800B12A68 /* HTMLHeadElement.h in Headers */,
</span><span class="cx">                                 A8EA7CB80A192B9C00A8EF5F /* HTMLHeadingElement.h in Headers */,
</span><span class="lines">@@ -25574,6 +25584,7 @@
</span><span class="cx">                                 65653F2E0D9727D200CA9723 /* SVGAltGlyphElement.h in Headers */,
</span><span class="cx">                                 24D912B813CA9A6900D21915 /* SVGAltGlyphItemElement.h in Headers */,
</span><span class="cx">                                 B22279770D00BF220071B782 /* SVGAngle.h in Headers */,
</span><ins>+                                7A93868618DCC14500B8263D /* VTTScanner.h in Headers */,
</ins><span class="cx">                                 B222797A0D00BF220071B782 /* SVGAnimateColorElement.h in Headers */,
</span><span class="cx">                                 087B84961272CEC800A14417 /* SVGAnimatedAngle.h in Headers */,
</span><span class="cx">                                 085797091278394C00A8EC5F /* SVGAnimatedBoolean.h in Headers */,
</span><span class="lines">@@ -26576,6 +26587,7 @@
</span><span class="cx">                                 FD31608712B026F700C1A359 /* AudioResamplerKernel.cpp in Sources */,
</span><span class="cx">                                 FD8C46EB154608E700A5910C /* AudioScheduledSourceNode.cpp in Sources */,
</span><span class="cx">                                 CDA79824170A258300D45C55 /* AudioSession.cpp in Sources */,
</span><ins>+                                7A93868518DCC14500B8263D /* VTTScanner.cpp in Sources */,
</ins><span class="cx">                                 CDA79827170A279100D45C55 /* AudioSessionIOS.mm in Sources */,
</span><span class="cx">                                 CD54DE4B17469C6D005E5B36 /* AudioSessionMac.cpp in Sources */,
</span><span class="cx">                                 07C59B5317F4AC15000FBCBB /* AudioStreamTrack.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebCorehtmltrackParsingUtilitiesh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/html/track/ParsingUtilities.h (0 => 166097)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/track/ParsingUtilities.h                                (rev 0)
+++ trunk/Source/WebCore/html/track/ParsingUtilities.h        2014-03-21 21:26:41 UTC (rev 166097)
</span><span class="lines">@@ -0,0 +1,76 @@
</span><ins>+/*
+ * Copyright (C) 2013 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
+ * &quot;AS IS&quot; 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 ParsingUtilities_h
+#define ParsingUtilities_h
+
+template&lt;typename CharType&gt;
+bool skipExactly(const CharType*&amp; position, const CharType* end, CharType delimiter)
+{
+    if (position &lt; end &amp;&amp; *position == delimiter) {
+        ++position;
+        return true;
+    }
+    return false;
+}
+
+template&lt;typename CharType, bool characterPredicate(CharType)&gt;
+bool skipExactly(const CharType*&amp; position, const CharType* end)
+{
+    if (position &lt; end &amp;&amp; characterPredicate(*position)) {
+        ++position;
+        return true;
+    }
+    return false;
+}
+
+template&lt;typename CharType&gt;
+void skipUntil(const CharType*&amp; position, const CharType* end, CharType delimiter)
+{
+    while (position &lt; end &amp;&amp; *position != delimiter)
+        ++position;
+}
+
+template&lt;typename CharType, bool characterPredicate(CharType)&gt;
+void skipUntil(const CharType*&amp; position, const CharType* end)
+{
+    while (position &lt; end &amp;&amp; !characterPredicate(*position))
+        ++position;
+}
+
+template&lt;typename CharType, bool characterPredicate(CharType)&gt;
+void skipWhile(const CharType*&amp; position, const CharType* end)
+{
+    while (position &lt; end &amp;&amp; characterPredicate(*position))
+        ++position;
+}
+
+#endif
+
</ins></span></pre></div>
<a id="trunkSourceWebCorehtmltrackVTTCuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/track/VTTCue.cpp (166096 => 166097)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/track/VTTCue.cpp        2014-03-21 21:14:46 UTC (rev 166096)
+++ trunk/Source/WebCore/html/track/VTTCue.cpp        2014-03-21 21:26:41 UTC (rev 166097)
</span><span class="lines">@@ -46,6 +46,7 @@
</span><span class="cx"> #include &quot;Text.h&quot;
</span><span class="cx"> #include &quot;TextTrack.h&quot;
</span><span class="cx"> #include &quot;TextTrackCueList.h&quot;
</span><ins>+#include &quot;VTTScanner.h&quot;
</ins><span class="cx"> #include &quot;WebVTTElement.h&quot;
</span><span class="cx"> #include &quot;WebVTTParser.h&quot;
</span><span class="cx"> #include &lt;wtf/MathExtras.h&gt;
</span><span class="lines">@@ -694,10 +695,8 @@
</span><span class="cx">     
</span><span class="cx">     for (Node* child = root-&gt;firstChild(); child; child = NodeTraversal::next(child, root)) {
</span><span class="cx">         if (child-&gt;nodeName() == timestampTag) {
</span><del>-            unsigned position = 0;
-            String timestamp = child-&gt;nodeValue();
</del><span class="cx">             double currentTimestamp;
</span><del>-            bool check = WebVTTParser::collectTimeStamp(timestamp, position, currentTimestamp);
</del><ins>+            bool check = WebVTTParser::collectTimeStamp(child-&gt;nodeValue(), currentTimestamp);
</ins><span class="cx">             ASSERT_UNUSED(check, check);
</span><span class="cx">             
</span><span class="cx">             if (currentTimestamp &gt; movieTime)
</span><span class="lines">@@ -832,37 +831,32 @@
</span><span class="cx">     return coordinates;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-VTTCue::CueSetting VTTCue::settingName(const String&amp; name)
</del><ins>+VTTCue::CueSetting VTTCue::settingName(VTTScanner&amp; input)
</ins><span class="cx"> {
</span><del>-    DEPRECATED_DEFINE_STATIC_LOCAL(const String, verticalKeyword, (ASCIILiteral(&quot;vertical&quot;)));
-    DEPRECATED_DEFINE_STATIC_LOCAL(const String, lineKeyword, (ASCIILiteral(&quot;line&quot;)));
-    DEPRECATED_DEFINE_STATIC_LOCAL(const String, positionKeyword, (ASCIILiteral(&quot;position&quot;)));
-    DEPRECATED_DEFINE_STATIC_LOCAL(const String, sizeKeyword, (ASCIILiteral(&quot;size&quot;)));
-    DEPRECATED_DEFINE_STATIC_LOCAL(const String, alignKeyword, (ASCIILiteral(&quot;align&quot;)));
</del><ins>+    CueSetting parsedSetting = None;
+    if (input.scan(&quot;vertical&quot;))
+        parsedSetting = Vertical;
+    else if (input.scan(&quot;line&quot;))
+        parsedSetting = Line;
+    else if (input.scan(&quot;position&quot;))
+        parsedSetting = Position;
+    else if (input.scan(&quot;size&quot;))
+        parsedSetting = Size;
+    else if (input.scan(&quot;align&quot;))
+        parsedSetting = Align;
</ins><span class="cx"> #if ENABLE(WEBVTT_REGIONS)
</span><del>-    DEPRECATED_DEFINE_STATIC_LOCAL(const String, regionIdKeyword, (ASCIILiteral(&quot;region&quot;)));
</del><ins>+    else if (input.scan(&quot;region&quot;))
+        parsedSetting = RegionId;
</ins><span class="cx"> #endif
</span><ins>+    // Verify that a ':' follows.
+    if (parsedSetting != None &amp;&amp; input.scan(':'))
+        return parsedSetting;
</ins><span class="cx"> 
</span><del>-    if (name == verticalKeyword)
-        return Vertical;
-    if (name == lineKeyword)
-        return Line;
-    if (name == positionKeyword)
-        return Position;
-    if (name == sizeKeyword)
-        return Size;
-    if (name == alignKeyword)
-        return Align;
-#if ENABLE(WEBVTT_REGIONS)
-    if (name == regionIdKeyword)
-        return RegionId;
-#endif
-
</del><span class="cx">     return None;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // Used for 'position' and 'size'.
</span><del>-static bool scanPercentage(const String&amp; input, unsigned&amp; position, int&amp; number)
</del><ins>+static bool scanPercentage(VTTScanner&amp; input, const VTTScanner::Run&amp; valueRun, int&amp; number)
</ins><span class="cx"> {
</span><span class="cx">     // 1. If value contains any characters other than U+0025 PERCENT SIGN
</span><span class="cx">     //    characters (%) and characters in the range U+0030 DIGIT ZERO (0) to
</span><span class="lines">@@ -870,20 +864,16 @@
</span><span class="cx">     // 2. If value does not contain at least one character in the range U+0030
</span><span class="cx">     //    DIGIT ZERO (0) to U+0039 DIGIT NINE (9), then jump to the step
</span><span class="cx">     //    labeled next setting.
</span><del>-    if (!WebVTTParser::collectDigitsToInt(input, position, number))
</del><ins>+    if (!input.scanDigits(number))
</ins><span class="cx">         return false;
</span><del>-    if (position &gt;= input.length())
-        return false;
</del><span class="cx"> 
</span><span class="cx">     // 3. If any character in value other than the last character is a U+0025
</span><span class="cx">     //    PERCENT SIGN character (%), then jump to the step labeled next
</span><span class="cx">     //    setting.
</span><span class="cx">     // 4. If the last character in value is not a U+0025 PERCENT SIGN character
</span><span class="cx">     //    (%), then jump to the step labeled next setting.
</span><del>-    if (input[position++] != '%')
</del><ins>+    if (!input.scan('%') || !input.isAt(valueRun.end()))
</ins><span class="cx">         return false;
</span><del>-    if (position &lt; input.length() &amp;&amp; !WebVTTParser::isValidSettingDelimiter(input[position]))
-        return false;
</del><span class="cx"> 
</span><span class="cx">     // 5. Ignoring the trailing percent sign, interpret value as an integer,
</span><span class="cx">     //    and let number be that number.
</span><span class="lines">@@ -892,18 +882,16 @@
</span><span class="cx">     return number &gt;= 0 &amp;&amp; number &lt;= 100;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void VTTCue::setCueSettings(const String&amp; input)
</del><ins>+void VTTCue::setCueSettings(const String&amp; inputString)
</ins><span class="cx"> {
</span><del>-    m_settings = input;
-    unsigned position = 0;
</del><ins>+    VTTScanner input(inputString);
</ins><span class="cx"> 
</span><del>-    while (position &lt; input.length()) {
</del><ins>+    while (!input.isAtEnd()) {
</ins><span class="cx"> 
</span><span class="cx">         // The WebVTT cue settings part of a WebVTT cue consists of zero or more of the following components, in any order, 
</span><del>-        // separated from each other by one or more U+0020 SPACE characters or U+0009 CHARACTER TABULATION (tab) characters. 
-        while (position &lt; input.length() &amp;&amp; WebVTTParser::isValidSettingDelimiter(input[position]))
-            position++;
-        if (position &gt;= input.length())
</del><ins>+        // separated from each other by one or more U+0020 SPACE characters or U+0009 CHARACTER TABULATION (tab) characters.
+        input.skipWhile&lt;WebVTTParser::isValidSettingDelimiter&gt;();
+        if (input.isAtEnd())
</ins><span class="cx">             break;
</span><span class="cx"> 
</span><span class="cx">         // When the user agent is to parse the WebVTT settings given by a string input for a text track cue cue, 
</span><span class="lines">@@ -912,20 +900,11 @@
</span><span class="cx">         // 2. For each token setting in the list settings, run the following substeps:
</span><span class="cx">         //    1. If setting does not contain a U+003A COLON character (:), or if the first U+003A COLON character (:) 
</span><span class="cx">         //       in setting is either the first or last character of setting, then jump to the step labeled next setting.
</span><del>-        unsigned endOfSetting = position;
-        String setting = WebVTTParser::collectWord(input, &amp;endOfSetting);
-        CueSetting name;
-        size_t colonOffset = setting.find(':', 1);
-        if (colonOffset == notFound || !colonOffset || colonOffset == setting.length() - 1)
-            goto NextSetting;
</del><ins>+        //    2. Let name be the leading substring of setting up to and excluding the first U+003A COLON character (:) in that string.
+        CueSetting name = settingName(input);
</ins><span class="cx"> 
</span><del>-        // 2. Let name be the leading substring of setting up to and excluding the first U+003A COLON character (:) in that string.
-        name = settingName(setting.substring(0, colonOffset));
-
</del><span class="cx">         // 3. Let value be the trailing substring of setting starting from the character immediately after the first U+003A COLON character (:) in that string.
</span><del>-        position += colonOffset + 1;
-        if (position &gt;= input.length())
-            break;
</del><ins>+        VTTScanner::Run valueRun = input.collectUntil&lt;WebVTTParser::isValidSettingDelimiter&gt;();
</ins><span class="cx"> 
</span><span class="cx">         // 4. Run the appropriate substeps that apply for the value of name, as follows:
</span><span class="cx">         switch (name) {
</span><span class="lines">@@ -933,13 +912,12 @@
</span><span class="cx">             // If name is a case-sensitive match for &quot;vertical&quot;
</span><span class="cx">             // 1. If value is a case-sensitive match for the string &quot;rl&quot;, then let cue's text track cue writing direction 
</span><span class="cx">             //    be vertical growing left.
</span><del>-            String writingDirection = WebVTTParser::collectWord(input, &amp;position);
-            if (writingDirection == verticalGrowingLeftKeyword())
</del><ins>+            if (input.scanRun(valueRun, verticalGrowingLeftKeyword()))
</ins><span class="cx">                 m_writingDirection = VerticalGrowingLeft;
</span><span class="cx">             
</span><span class="cx">             // 2. Otherwise, if value is a case-sensitive match for the string &quot;lr&quot;, then let cue's text track cue writing 
</span><span class="cx">             //    direction be vertical growing right.
</span><del>-            else if (writingDirection == verticalGrowingRightKeyword())
</del><ins>+            else if (input.scanRun(valueRun, verticalGrowingRightKeyword()))
</ins><span class="cx">                 m_writingDirection = VerticalGrowingRight;
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="lines">@@ -948,10 +926,12 @@
</span><span class="cx">             // 1. If value contains any characters other than U+002D HYPHEN-MINUS characters (-), U+0025 PERCENT SIGN 
</span><span class="cx">             //    characters (%), and characters in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), then jump
</span><span class="cx">             //    to the step labeled next setting.
</span><del>-            StringBuilder linePositionBuilder;
-            while (position &lt; input.length() &amp;&amp; (input[position] == '-' || input[position] == '%' || isASCIIDigit(input[position])))
-                linePositionBuilder.append(input[position++]);
-            if (position &lt; input.length() &amp;&amp; !WebVTTParser::isValidSettingDelimiter(input[position]))
</del><ins>+            bool isNegative = input.scan('-');
+            int linePosition;
+            unsigned numDigits = input.scanDigits(linePosition);
+            bool isPercentage = input.scan('%');
+
+            if (!input.isAt(valueRun.end()))
</ins><span class="cx">                 break;
</span><span class="cx"> 
</span><span class="cx">             // 2. If value does not contain at least one character in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT 
</span><span class="lines">@@ -960,43 +940,38 @@
</span><span class="cx">             //    jump to the step labeled next setting.
</span><span class="cx">             // 4. If any character in value other than the last character is a U+0025 PERCENT SIGN character (%), then
</span><span class="cx">             //    jump to the step labeled next setting.
</span><del>-            String linePosition = linePositionBuilder.toString();
-            if (linePosition.find('-', 1) != notFound || linePosition.reverseFind(&quot;%&quot;, linePosition.length() - 2) != notFound)
-                break;
-
</del><span class="cx">             // 5. If the first character in value is a U+002D HYPHEN-MINUS character (-) and the last character in value is a 
</span><span class="cx">             //    U+0025 PERCENT SIGN character (%), then jump to the step labeled next setting.
</span><del>-            if (linePosition[0] == '-' &amp;&amp; linePosition[linePosition.length() - 1] == '%')
</del><ins>+            if (!numDigits || (isPercentage &amp;&amp; isNegative))
</ins><span class="cx">                 break;
</span><span class="cx"> 
</span><span class="cx">             // 6. Ignoring the trailing percent sign, if any, interpret value as a (potentially signed) integer, and 
</span><span class="cx">             //    let number be that number. 
</span><del>-            // NOTE: toInt ignores trailing non-digit characters, such as '%'.
-            bool validNumber;
-            int number = linePosition.toInt(&amp;validNumber);
-            if (!validNumber)
-                break;
-
</del><span class="cx">             // 7. If the last character in value is a U+0025 PERCENT SIGN character (%), but number is not in the range 
</span><span class="cx">             //    0 â‰¤ number â‰¤ 100, then jump to the step labeled next setting.
</span><span class="cx">             // 8. Let cue's text track cue line position be number.
</span><span class="cx">             // 9. If the last character in value is a U+0025 PERCENT SIGN character (%), then let cue's text track cue 
</span><span class="cx">             //    snap-to-lines flag be false. Otherwise, let it be true.
</span><del>-            if (linePosition[linePosition.length() - 1] == '%') {
-                if (number &lt; 0 || number &gt; 100)
</del><ins>+            if (isPercentage) {
+                if (linePosition &lt; 0 || linePosition &gt; 100)
</ins><span class="cx">                     break;
</span><span class="cx"> 
</span><span class="cx">                 // 10 - If '%' then set snap-to-lines flag to false.
</span><span class="cx">                 m_snapToLines = false;
</span><ins>+            } else {
+                if (isNegative)
+                    linePosition = -linePosition;
+
+                m_snapToLines = true;
</ins><span class="cx">             }
</span><span class="cx"> 
</span><del>-            m_linePosition = number;
</del><ins>+            m_linePosition = linePosition;
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         case Position: {
</span><span class="cx">             int number;
</span><span class="cx">             // Steps 1 - 6.
</span><del>-            if (!scanPercentage(input, position, number))            
</del><ins>+            if (!scanPercentage(input, valueRun, number))            
</ins><span class="cx">                 break;
</span><span class="cx"> 
</span><span class="cx">             // 7. Let cue's text track cue text position be number.
</span><span class="lines">@@ -1006,7 +981,7 @@
</span><span class="cx">         case Size: {
</span><span class="cx">             int number;
</span><span class="cx">             // Steps 1 - 6.
</span><del>-            if (!scanPercentage(input, position, number))            
</del><ins>+            if (!scanPercentage(input, valueRun, number))            
</ins><span class="cx">                 break;
</span><span class="cx"> 
</span><span class="cx">             // 7. Let cue's text track cue size be number.
</span><span class="lines">@@ -1014,40 +989,38 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         case Align: {
</span><del>-            String cueAlignment = WebVTTParser::collectWord(input, &amp;position);
-
</del><span class="cx">             // 1. If value is a case-sensitive match for the string &quot;start&quot;, then let cue's text track cue alignment be start alignment.
</span><del>-            if (cueAlignment == startKeyword())
</del><ins>+            if (input.scanRun(valueRun, startKeyword()))
</ins><span class="cx">                 m_cueAlignment = Start;
</span><span class="cx"> 
</span><span class="cx">             // 2. If value is a case-sensitive match for the string &quot;middle&quot;, then let cue's text track cue alignment be middle alignment.
</span><del>-            else if (cueAlignment == middleKeyword())
</del><ins>+            else if (input.scanRun(valueRun, middleKeyword()))
</ins><span class="cx">                 m_cueAlignment = Middle;
</span><span class="cx"> 
</span><span class="cx">             // 3. If value is a case-sensitive match for the string &quot;end&quot;, then let cue's text track cue alignment be end alignment.
</span><del>-            else if (cueAlignment == endKeyword())
</del><ins>+            else if (input.scanRun(valueRun, endKeyword()))
</ins><span class="cx">                 m_cueAlignment = End;
</span><span class="cx"> 
</span><span class="cx">             // 4. If value is a case-sensitive match for the string &quot;left&quot;, then let cue's text track cue alignment be left alignment.
</span><del>-            else if (cueAlignment == leftKeyword())
</del><ins>+            else if (input.scanRun(valueRun, leftKeyword()))
</ins><span class="cx">                 m_cueAlignment = Left;
</span><span class="cx"> 
</span><span class="cx">             // 5. If value is a case-sensitive match for the string &quot;right&quot;, then let cue's text track cue alignment be right alignment.
</span><del>-            else if (cueAlignment == rightKeyword())
</del><ins>+            else if (input.scanRun(valueRun, rightKeyword()))
</ins><span class="cx">                 m_cueAlignment = Right;
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx"> #if ENABLE(WEBVTT_REGIONS)
</span><span class="cx">         case RegionId:
</span><del>-            m_regionId = WebVTTParser::collectWord(input, &amp;position);
</del><ins>+            m_regionId = input.extractString(valueRun);
</ins><span class="cx">             break;
</span><span class="cx"> #endif
</span><span class="cx">         case None:
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-NextSetting:
-        position = endOfSetting;
</del><ins>+        // Make sure the entire run is consumed.
+        input.skipRun(valueRun);
</ins><span class="cx">     }
</span><span class="cx"> #if ENABLE(WEBVTT_REGIONS)
</span><span class="cx">     // If cue's line position is not auto or cue's size is not 100 or cue's
</span></span></pre></div>
<a id="trunkSourceWebCorehtmltrackVTTCueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/track/VTTCue.h (166096 => 166097)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/track/VTTCue.h        2014-03-21 21:14:46 UTC (rev 166096)
+++ trunk/Source/WebCore/html/track/VTTCue.h        2014-03-21 21:26:41 UTC (rev 166097)
</span><span class="lines">@@ -45,6 +45,7 @@
</span><span class="cx"> class HTMLSpanElement;
</span><span class="cx"> class ScriptExecutionContext;
</span><span class="cx"> class VTTCue;
</span><ins>+class VTTScanner;
</ins><span class="cx"> 
</span><span class="cx"> // ----------------------------
</span><span class="cx"> 
</span><span class="lines">@@ -189,7 +190,7 @@
</span><span class="cx">         RegionId
</span><span class="cx"> #endif
</span><span class="cx">     };
</span><del>-    CueSetting settingName(const String&amp;);
</del><ins>+    CueSetting settingName(VTTScanner&amp;);
</ins><span class="cx"> 
</span><span class="cx">     String m_content;
</span><span class="cx">     String m_settings;
</span></span></pre></div>
<a id="trunkSourceWebCorehtmltrackVTTRegioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/track/VTTRegion.cpp (166096 => 166097)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/track/VTTRegion.cpp        2014-03-21 21:14:46 UTC (rev 166096)
+++ trunk/Source/WebCore/html/track/VTTRegion.cpp        2014-03-21 21:26:41 UTC (rev 166097)
</span><span class="lines">@@ -41,6 +41,7 @@
</span><span class="cx"> #include &quot;Logging.h&quot;
</span><span class="cx"> #include &quot;RenderElement.h&quot;
</span><span class="cx"> #include &quot;VTTCue.h&quot;
</span><ins>+#include &quot;VTTScanner.h&quot;
</ins><span class="cx"> #include &quot;WebVTTParser.h&quot;
</span><span class="cx"> #include &lt;wtf/MathExtras.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -216,83 +217,100 @@
</span><span class="cx">     setScroll(region-&gt;scroll(), ASSERT_NO_EXCEPTION);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void VTTRegion::setRegionSettings(const String&amp; input)
</del><ins>+void VTTRegion::setRegionSettings(const String&amp; inputString)
</ins><span class="cx"> {
</span><del>-    m_settings = input;
-    unsigned position = 0;
</del><ins>+    m_settings = inputString;
+    VTTScanner input(inputString);
</ins><span class="cx"> 
</span><del>-    while (position &lt; input.length()) {
-        while (position &lt; input.length() &amp;&amp; WebVTTParser::isValidSettingDelimiter(input[position]))
-            position++;
-
-        if (position &gt;= input.length())
</del><ins>+    while (!input.isAtEnd()) {
+        input.skipWhile&lt;WebVTTParser::isValidSettingDelimiter&gt;();
+        if (input.isAtEnd())
</ins><span class="cx">             break;
</span><span class="cx"> 
</span><del>-        parseSetting(input, &amp;position);
</del><ins>+        // Scan the name part.
+        RegionSetting name = scanSettingName(input);
+
+        // Verify that we're looking at a '='.
+        if (name == None || !input.scan('=')) {
+            input.skipUntil&lt;WebVTTParser::isASpace&gt;();
+            continue;
+        }
+
+        // Scan the value part.
+        parseSettingValue(name, input);
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-VTTRegion::RegionSetting VTTRegion::getSettingFromString(const String&amp; setting)
</del><ins>+VTTRegion::RegionSetting VTTRegion::scanSettingName(VTTScanner&amp; input)
</ins><span class="cx"> {
</span><del>-    DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, idKeyword, (&quot;id&quot;, AtomicString::ConstructFromLiteral));
-    DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, heightKeyword, (&quot;height&quot;, AtomicString::ConstructFromLiteral));
-    DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, widthKeyword, (&quot;width&quot;, AtomicString::ConstructFromLiteral));
-    DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, regionAnchorKeyword, (&quot;regionanchor&quot;, AtomicString::ConstructFromLiteral));
-    DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, viewportAnchorKeyword, (&quot;viewportanchor&quot;, AtomicString::ConstructFromLiteral));
-    DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, scrollKeyword, (&quot;scroll&quot;, AtomicString::ConstructFromLiteral));
-
-    if (setting == idKeyword)
</del><ins>+    if (input.scan(&quot;id&quot;))
</ins><span class="cx">         return Id;
</span><del>-    if (setting == heightKeyword)
</del><ins>+    if (input.scan(&quot;height&quot;))
</ins><span class="cx">         return Height;
</span><del>-    if (setting == widthKeyword)
</del><ins>+    if (input.scan(&quot;width&quot;))
</ins><span class="cx">         return Width;
</span><del>-    if (setting == viewportAnchorKeyword)
</del><ins>+    if (input.scan(&quot;viewportanchor&quot;))
</ins><span class="cx">         return ViewportAnchor;
</span><del>-    if (setting == regionAnchorKeyword)
</del><ins>+    if (input.scan(&quot;regionanchor&quot;))
</ins><span class="cx">         return RegionAnchor;
</span><del>-    if (setting == scrollKeyword)
</del><ins>+    if (input.scan(&quot;scroll&quot;))
</ins><span class="cx">         return Scroll;
</span><span class="cx"> 
</span><span class="cx">     return None;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void VTTRegion::parseSettingValue(RegionSetting setting, const String&amp; value)
</del><ins>+static inline bool parsedEntireRun(const VTTScanner&amp; input, const VTTScanner::Run&amp; run)
</ins><span class="cx"> {
</span><ins>+    return input.isAt(run.end()); 
+}
+
+void VTTRegion::parseSettingValue(RegionSetting setting, VTTScanner&amp; input)
+{
</ins><span class="cx">     DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, scrollUpValueKeyword, (&quot;up&quot;, AtomicString::ConstructFromLiteral));
</span><span class="cx"> 
</span><ins>+    VTTScanner::Run valueRun = input.collectUntil&lt;WebVTTParser::isASpace&gt;();
+
</ins><span class="cx">     switch (setting) {
</span><del>-    case Id:
-        if (value.find(&quot;--&gt;&quot;) == notFound)
-            m_id = value;
</del><ins>+    case Id: {
+        String stringValue = input.extractString(valueRun);
+        if (stringValue.find(&quot;--&gt;&quot;) == notFound)
+            m_id = stringValue;
</ins><span class="cx">         break;
</span><ins>+    }
</ins><span class="cx">     case Width: {
</span><span class="cx">         float floatWidth;
</span><del>-        if (WebVTTParser::parseFloatPercentageValue(value, floatWidth))
</del><ins>+        if (WebVTTParser::parseFloatPercentageValue(input, floatWidth) &amp;&amp; parsedEntireRun(input, valueRun))
</ins><span class="cx">             m_width = floatWidth;
</span><span class="cx">         else
</span><span class="cx">             LOG(Media, &quot;VTTRegion::parseSettingValue, invalid Width&quot;);
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx">     case Height: {
</span><del>-        unsigned position = 0;
</del><span class="cx">         int number;
</span><del>-        if (WebVTTParser::collectDigitsToInt(value, position, number) &amp;&amp; position == value.length())
</del><ins>+        if (input.scanDigits(number) &amp;&amp; parsedEntireRun(input, valueRun))
</ins><span class="cx">             m_heightInLines = number;
</span><span class="cx">         else
</span><span class="cx">             LOG(Media, &quot;VTTRegion::parseSettingValue, invalid Height&quot;);
</span><span class="cx">         break;
</span><span class="cx">     }
</span><del>-    case RegionAnchor:
-        if (!WebVTTParser::parseFloatPercentageValuePair(value, ',', m_regionAnchor))
</del><ins>+    case RegionAnchor: {
+        FloatPoint anchor;
+        if (WebVTTParser::parseFloatPercentageValuePair(input, ',', anchor) &amp;&amp; parsedEntireRun(input, valueRun))
+            m_regionAnchor = anchor;
+        else
</ins><span class="cx">             LOG(Media, &quot;VTTRegion::parseSettingValue, invalid RegionAnchor&quot;);
</span><span class="cx">         break;
</span><del>-    case ViewportAnchor:
-        if (!WebVTTParser::parseFloatPercentageValuePair(value, ',', m_viewportAnchor))
</del><ins>+    }
+    case ViewportAnchor: {
+        FloatPoint anchor;
+        if (WebVTTParser::parseFloatPercentageValuePair(input, ',', anchor) &amp;&amp; parsedEntireRun(input, valueRun))
+            m_viewportAnchor = anchor;
+        else
</ins><span class="cx">             LOG(Media, &quot;VTTRegion::parseSettingValue, invalid ViewportAnchor&quot;);
</span><span class="cx">         break;
</span><ins>+    }
</ins><span class="cx">     case Scroll:
</span><del>-        if (value == scrollUpValueKeyword)
</del><ins>+        if (input.scanRun(valueRun, scrollUpValueKeyword))
</ins><span class="cx">             m_scroll = true;
</span><span class="cx">         else
</span><span class="cx">             LOG(Media, &quot;VTTRegion::parseSettingValue, invalid Scroll&quot;);
</span><span class="lines">@@ -300,22 +318,10 @@
</span><span class="cx">     case None:
</span><span class="cx">         break;
</span><span class="cx">     }
</span><ins>+
+    input.skipRun(valueRun);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void VTTRegion::parseSetting(const String&amp; input, unsigned* position)
-{
-    String setting = WebVTTParser::collectWord(input, position);
-
-    size_t equalOffset = setting.find('=', 1);
-    if (equalOffset == notFound || !equalOffset || equalOffset == setting.length() - 1)
-        return;
-
-    RegionSetting name = getSettingFromString(setting.substring(0, equalOffset));
-    String value = setting.substring(equalOffset + 1, setting.length() - 1);
-
-    parseSettingValue(name, value);
-}
-    
</del><span class="cx"> const AtomicString&amp; VTTRegion::textTrackCueContainerScrollingClass()
</span><span class="cx"> {
</span><span class="cx">     DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, trackRegionCueContainerScrollingClass, (&quot;scrolling&quot;, AtomicString::ConstructFromLiteral));
</span></span></pre></div>
<a id="trunkSourceWebCorehtmltrackVTTRegionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/track/VTTRegion.h (166096 => 166097)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/track/VTTRegion.h        2014-03-21 21:14:46 UTC (rev 166096)
+++ trunk/Source/WebCore/html/track/VTTRegion.h        2014-03-21 21:26:41 UTC (rev 166097)
</span><span class="lines">@@ -44,6 +44,7 @@
</span><span class="cx"> 
</span><span class="cx"> class HTMLDivElement;
</span><span class="cx"> class VTTCueBox;
</span><ins>+class VTTScanner;
</ins><span class="cx"> 
</span><span class="cx"> class VTTRegion : public RefCounted&lt;VTTRegion&gt;, public ContextDestructionObserver {
</span><span class="cx"> public:
</span><span class="lines">@@ -116,10 +117,9 @@
</span><span class="cx">         Scroll
</span><span class="cx">     };
</span><span class="cx"> 
</span><del>-    RegionSetting getSettingFromString(const String&amp;);
</del><ins>+    RegionSetting scanSettingName(VTTScanner&amp;);
</ins><span class="cx"> 
</span><del>-    void parseSettingValue(RegionSetting, const String&amp;);
-    void parseSetting(const String&amp;, unsigned*);
</del><ins>+    void parseSettingValue(RegionSetting, VTTScanner&amp;);
</ins><span class="cx"> 
</span><span class="cx">     static const AtomicString&amp; textTrackCueContainerShadowPseudoId();
</span><span class="cx">     static const AtomicString&amp; textTrackCueContainerScrollingClass();
</span></span></pre></div>
<a id="trunkSourceWebCorehtmltrackVTTScannercpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/html/track/VTTScanner.cpp (0 => 166097)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/track/VTTScanner.cpp                                (rev 0)
+++ trunk/Source/WebCore/html/track/VTTScanner.cpp        2014-03-21 21:26:41 UTC (rev 166097)
</span><span class="lines">@@ -0,0 +1,172 @@
</span><ins>+/*
+ * Copyright (c) 2013, Opera Software ASA. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of Opera Software ASA 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
+ * &quot;AS IS&quot; 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 HOLDER 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 &quot;config.h&quot;
+#include &quot;VTTScanner.h&quot;
+
+namespace WebCore {
+
+VTTScanner::VTTScanner(const String&amp; line)
+    : m_is8Bit(line.is8Bit())
+{
+    if (m_is8Bit) {
+        m_data.characters8 = line.characters8();
+        m_end.characters8 = m_data.characters8 + line.length();
+    } else {
+        m_data.characters16 = line.characters16();
+        m_end.characters16 = m_data.characters16 + line.length();
+    }
+}
+
+bool VTTScanner::scan(char c)
+{
+    if (!match(c))
+        return false;
+    advance();
+    return true;
+}
+
+bool VTTScanner::scan(const LChar* characters, size_t charactersCount)
+{
+    unsigned matchLength = m_is8Bit ? m_end.characters8 - m_data.characters8 : m_end.characters16 - m_data.characters16;
+    if (matchLength &lt; charactersCount)
+        return false;
+    bool matched;
+    if (m_is8Bit)
+        matched = WTF::equal(m_data.characters8, characters, charactersCount);
+    else
+        matched = WTF::equal(m_data.characters16, characters, charactersCount);
+    if (matched)
+        advance(charactersCount);
+    return matched;
+}
+
+bool VTTScanner::scanRun(const Run&amp; run, const String&amp; toMatch)
+{
+    ASSERT(run.start() == position());
+    ASSERT(run.start() &lt;= end());
+    ASSERT(run.end() &gt;= run.start());
+    ASSERT(run.end() &lt;= end());
+    size_t matchLength = run.length();
+    if (toMatch.length() &gt; matchLength)
+        return false;
+    bool matched;
+    if (m_is8Bit)
+        matched = WTF::equal(toMatch.impl(), m_data.characters8, matchLength);
+    else
+        matched = WTF::equal(toMatch.impl(), m_data.characters16, matchLength);
+    if (matched)
+        seekTo(run.end());
+    return matched;
+}
+
+void VTTScanner::skipRun(const Run&amp; run)
+{
+    ASSERT(run.start() &lt;= end());
+    ASSERT(run.end() &gt;= run.start());
+    ASSERT(run.end() &lt;= end());
+    seekTo(run.end());
+}
+
+String VTTScanner::extractString(const Run&amp; run)
+{
+    ASSERT(run.start() == position());
+    ASSERT(run.start() &lt;= end());
+    ASSERT(run.end() &gt;= run.start());
+    ASSERT(run.end() &lt;= end());
+    String s;
+    if (m_is8Bit)
+        s = String(m_data.characters8, run.length());
+    else
+        s = String(m_data.characters16, run.length());
+    seekTo(run.end());
+    return s;
+}
+
+String VTTScanner::restOfInputAsString()
+{
+    Run rest(position(), end(), m_is8Bit);
+    return extractString(rest);
+}
+
+unsigned VTTScanner::scanDigits(int&amp; number)
+{
+    Run runOfDigits = collectWhile&lt;isASCIIDigit&gt;();
+    if (runOfDigits.isEmpty()) {
+        number = 0;
+        return 0;
+    }
+    bool validNumber;
+    size_t numDigits = runOfDigits.length();
+    if (m_is8Bit)
+        number = charactersToIntStrict(m_data.characters8, numDigits, &amp;validNumber);
+    else
+        number = charactersToIntStrict(m_data.characters16, numDigits, &amp;validNumber);
+
+    // Since we know that scanDigits only scanned valid (ASCII) digits (and
+    // hence that's what got passed to charactersToInt()), the remaining
+    // failure mode for charactersToInt() is overflow, so if |validNumber| is
+    // not true, then set |number| to the maximum int value.
+    if (!validNumber)
+        number = std::numeric_limits&lt;int&gt;::max();
+    // Consume the digits.
+    seekTo(runOfDigits.end());
+    return numDigits;
+}
+
+bool VTTScanner::scanFloat(float&amp; number)
+{
+    Run integerRun = collectWhile&lt;isASCIIDigit&gt;();
+    seekTo(integerRun.end());
+    Run decimalRun(position(), position(), m_is8Bit);
+    if (scan('.')) {
+        decimalRun = collectWhile&lt;isASCIIDigit&gt;();
+        seekTo(decimalRun.end());
+    }
+
+    // At least one digit required.
+    if (integerRun.isEmpty() &amp;&amp; decimalRun.isEmpty()) {
+        // Restore to starting position.
+        seekTo(integerRun.start());
+        return false;
+    }
+
+    size_t lengthOfFloat = Run(integerRun.start(), position(), m_is8Bit).length();
+    bool validNumber;
+    if (m_is8Bit)
+        number = charactersToFloat(integerRun.start(), lengthOfFloat, &amp;validNumber);
+    else
+        number = charactersToFloat(reinterpret_cast&lt;const UChar*&gt;(integerRun.start()), lengthOfFloat, &amp;validNumber);
+
+    if (!validNumber)
+        number = std::numeric_limits&lt;float&gt;::max();
+    return true;
+}
+
+}
</ins></span></pre></div>
<a id="trunkSourceWebCorehtmltrackVTTScannerh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/html/track/VTTScanner.h (0 => 166097)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/track/VTTScanner.h                                (rev 0)
+++ trunk/Source/WebCore/html/track/VTTScanner.h        2014-03-21 21:26:41 UTC (rev 166097)
</span><span class="lines">@@ -0,0 +1,233 @@
</span><ins>+/*
+ * Copyright (c) 2013, Opera Software ASA. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of Opera Software ASA 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
+ * &quot;AS IS&quot; 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 HOLDER 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 VTTScanner_h
+#define VTTScanner_h
+
+#include &quot;ParsingUtilities.h&quot;
+#include &lt;wtf/text/WTFString.h&gt;
+
+namespace WebCore {
+
+// Helper class for &quot;scanning&quot; an input string and performing parsing of
+// &quot;micro-syntax&quot;-like constructs.
+//
+// There's two primary operations: match and scan.
+//
+// The 'match' operation matches an explicitly or implicitly specified sequence
+// against the characters ahead of the current input pointer, and returns true
+// if the sequence can be matched.
+//
+// The 'scan' operation performs a 'match', and if the match is successful it
+// advance the input pointer past the matched sequence.
+class VTTScanner {
+    WTF_MAKE_NONCOPYABLE(VTTScanner);
+public:
+    explicit VTTScanner(const String&amp; line);
+
+    typedef const LChar* Position;
+
+    class Run {
+    public:
+        Run(Position start, Position end, bool is8Bit)
+            : m_start(start), m_end(end), m_is8Bit(is8Bit) { }
+
+        Position start() const { return m_start; }
+        Position end() const { return m_end; }
+
+        bool isEmpty() const { return m_start == m_end; }
+        size_t length() const;
+
+    private:
+        Position m_start;
+        Position m_end;
+        bool m_is8Bit;
+    };
+
+    // Check if the input pointer points at the specified position.
+    bool isAt(Position checkPosition) const { return position() == checkPosition; }
+    // Check if the input pointer points at the end of the input.
+    bool isAtEnd() const { return position() == end(); }
+    // Match the character |c| against the character at the input pointer (~lookahead).
+    bool match(char c) const { return !isAtEnd() &amp;&amp; currentChar() == c; }
+    // Scan the character |c|.
+    bool scan(char);
+    // Scan the first |charactersCount| characters of the string |characters|.
+    bool scan(const LChar* characters, size_t charactersCount);
+
+    // Scan the literal |characters|.
+    template&lt;unsigned charactersCount&gt;
+    bool scan(const char (&amp;characters)[charactersCount]);
+
+    // Skip (advance the input pointer) as long as the specified
+    // |characterPredicate| returns true, and the input pointer is not passed
+    // the end of the input.
+    template&lt;bool characterPredicate(UChar)&gt;
+    void skipWhile();
+
+    // Like skipWhile, but using a negated predicate.
+    template&lt;bool characterPredicate(UChar)&gt;
+    void skipUntil();
+
+    // Return the run of characters for which the specified
+    // |characterPredicate| returns true. The start of the run will be the
+    // current input pointer.
+    template&lt;bool characterPredicate(UChar)&gt;
+    Run collectWhile();
+
+    // Like collectWhile, but using a negated predicate.
+    template&lt;bool characterPredicate(UChar)&gt;
+    Run collectUntil();
+
+    // Scan the string |toMatch|, using the specified |run| as the sequence to
+    // match against.
+    bool scanRun(const Run&amp;, const String&amp; toMatch);
+
+    // Skip to the end of the specified |run|.
+    void skipRun(const Run&amp;);
+
+    // Return the String made up of the characters in |run|, and advance the
+    // input pointer to the end of the run.
+    String extractString(const Run&amp;);
+
+    // Return a String constructed from the rest of the input (between input
+    // pointer and end of input), and advance the input pointer accordingly.
+    String restOfInputAsString();
+
+    // Scan a set of ASCII digits from the input. Return the number of digits
+    // scanned, and set |number| to the computed value. If the digits make up a
+    // number that does not fit the 'int' type, |number| is set to INT_MAX.
+    // Note: Does not handle sign.
+    unsigned scanDigits(int&amp; number);
+
+    // Scan a floating point value on one of the forms: \d+\.? \d+\.\d+ \.\d+
+    bool scanFloat(float&amp; number);
+
+protected:
+    Position position() const { return m_data.characters8; }
+    Position end() const { return m_end.characters8; }
+    void seekTo(Position);
+    UChar currentChar() const;
+    void advance(unsigned amount = 1);
+    // Adapt a UChar-predicate to an LChar-predicate.
+    // (For use with skipWhile/Until from ParsingUtilities.h).
+    template&lt;bool characterPredicate(UChar)&gt;
+    static inline bool LCharPredicateAdapter(LChar c) { return characterPredicate(c); }
+    union {
+        const LChar* characters8;
+        const UChar* characters16;
+    } m_data;
+    union {
+        const LChar* characters8;
+        const UChar* characters16;
+    } m_end;
+    bool m_is8Bit;
+};
+
+inline size_t VTTScanner::Run::length() const
+{
+    if (m_is8Bit)
+        return m_end - m_start;
+    return reinterpret_cast&lt;const UChar*&gt;(m_end) - reinterpret_cast&lt;const UChar*&gt;(m_start);
+}
+
+template&lt;unsigned charactersCount&gt;
+inline bool VTTScanner::scan(const char (&amp;characters)[charactersCount])
+{
+    return scan(reinterpret_cast&lt;const LChar*&gt;(characters), charactersCount - 1);
+}
+
+template&lt;bool characterPredicate(UChar)&gt;
+inline void VTTScanner::skipWhile()
+{
+    if (m_is8Bit)
+        ::skipWhile&lt;LChar, LCharPredicateAdapter&lt;characterPredicate&gt; &gt;(m_data.characters8, m_end.characters8);
+    else
+        ::skipWhile&lt;UChar, characterPredicate&gt;(m_data.characters16, m_end.characters16);
+}
+
+template&lt;bool characterPredicate(UChar)&gt;
+inline void VTTScanner::skipUntil()
+{
+    if (m_is8Bit)
+        ::skipUntil&lt;LChar, LCharPredicateAdapter&lt;characterPredicate&gt; &gt;(m_data.characters8, m_end.characters8);
+    else
+        ::skipUntil&lt;UChar, characterPredicate&gt;(m_data.characters16, m_end.characters16);
+}
+
+template&lt;bool characterPredicate(UChar)&gt;
+inline VTTScanner::Run VTTScanner::collectWhile()
+{
+    if (m_is8Bit) {
+        const LChar* current = m_data.characters8;
+        ::skipWhile&lt;LChar, LCharPredicateAdapter&lt;characterPredicate&gt; &gt;(current, m_end.characters8);
+        return Run(position(), current, m_is8Bit);
+    }
+    const UChar* current = m_data.characters16;
+    ::skipWhile&lt;UChar, characterPredicate&gt;(current, m_end.characters16);
+    return Run(position(), reinterpret_cast&lt;Position&gt;(current), m_is8Bit);
+}
+
+template&lt;bool characterPredicate(UChar)&gt;
+inline VTTScanner::Run VTTScanner::collectUntil()
+{
+    if (m_is8Bit) {
+        const LChar* current = m_data.characters8;
+        ::skipUntil&lt;LChar, LCharPredicateAdapter&lt;characterPredicate&gt; &gt;(current, m_end.characters8);
+        return Run(position(), current, m_is8Bit);
+    }
+    const UChar* current = m_data.characters16;
+    ::skipUntil&lt;UChar, characterPredicate&gt;(current, m_end.characters16);
+    return Run(position(), reinterpret_cast&lt;Position&gt;(current), m_is8Bit);
+}
+
+inline void VTTScanner::seekTo(Position position)
+{
+    ASSERT(position &lt;= end());
+    m_data.characters8 = position;
+}
+
+inline UChar VTTScanner::currentChar() const
+{
+    ASSERT(position() &lt; end());
+    return m_is8Bit ? *m_data.characters8 : *m_data.characters16;
+}
+
+inline void VTTScanner::advance(unsigned amount)
+{
+    ASSERT(position() &lt; end());
+    if (m_is8Bit)
+        m_data.characters8 += amount;
+    else
+        m_data.characters16 += amount;
+}
+
+}
+
+#endif
</ins></span></pre></div>
<a id="trunkSourceWebCorehtmltrackWebVTTParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/track/WebVTTParser.cpp (166096 => 166097)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/track/WebVTTParser.cpp        2014-03-21 21:14:46 UTC (rev 166096)
+++ trunk/Source/WebCore/html/track/WebVTTParser.cpp        2014-03-21 21:26:41 UTC (rev 166097)
</span><span class="lines">@@ -38,6 +38,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;ProcessingInstruction.h&quot;
</span><span class="cx"> #include &quot;Text.h&quot;
</span><ins>+#include &quot;VTTScanner.h&quot;
</ins><span class="cx"> #include &quot;WebVTTElement.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -48,67 +49,16 @@
</span><span class="cx"> const char* fileIdentifier = &quot;WEBVTT&quot;;
</span><span class="cx"> const unsigned fileIdentifierLength = 6;
</span><span class="cx"> 
</span><del>-static unsigned scanDigits(const String&amp; input, unsigned&amp; position)
-{
-    unsigned startPosition = position;
-    while (position &lt; input.length() &amp;&amp; isASCIIDigit(input[position]))
-        position++;
-    return position - startPosition;
-}
-    
-unsigned WebVTTParser::collectDigitsToInt(const String&amp; input, unsigned&amp; position, int&amp; number)
-{
-    unsigned startPosition = position;
-    unsigned numDigits = scanDigits(input, position);
-    if (!numDigits) {
-        number = 0;
-        return 0;
-    }
-
-    bool validNumber;
-    if (input.is8Bit())
-        number = charactersToIntStrict(input.characters8() + startPosition, numDigits, &amp;validNumber);
-    else
-        number = charactersToIntStrict(input.characters16() + startPosition, numDigits, &amp;validNumber);
-
-    // Since we know that scanDigits only scanned valid (ASCII) digits (and
-    // hence that's what got passed to charactersToInt()), the remaining
-    // failure mode for charactersToInt() is overflow, so if |validNumber| is
-    // not true, then set |number| to the maximum int value.
-    if (!validNumber)
-        number = std::numeric_limits&lt;int&gt;::max();
-    return numDigits;
-}
-
-String WebVTTParser::collectWord(const String&amp; input, unsigned* position)
-{
-    StringBuilder string;
-    while (*position &lt; input.length() &amp;&amp; !isASpace(input[*position]))
-        string.append(input[(*position)++]);
-    return string.toString();
-}
-
</del><span class="cx"> #if ENABLE(WEBVTT_REGIONS)
</span><del>-bool WebVTTParser::parseFloatPercentageValue(const String&amp; value, float&amp; percentage)
</del><ins>+bool WebVTTParser::parseFloatPercentageValue(VTTScanner&amp; valueScanner, float&amp; percentage)
</ins><span class="cx"> {
</span><ins>+    float number;
+    if (!valueScanner.scanFloat(number))
+        return false;
</ins><span class="cx">     // '%' must be present and at the end of the setting value.
</span><del>-    if (value.isEmpty() || value[value.length() - 1] != '%')
</del><ins>+    if (!valueScanner.scan('%'))
</ins><span class="cx">         return false;
</span><span class="cx"> 
</span><del>-    unsigned position = 0;
-    unsigned digitsBeforeDot = scanDigits(value, position);
-    unsigned digitsAfterDot = 0;
-    if (value[position] == '.') {
-        position++;
-
-        digitsAfterDot = scanDigits(value, position);
-    }
-
-    // At least one digit is required
-    if (!digitsBeforeDot &amp;&amp; !digitsAfterDot)
-        return false;
-
-    float number = value.toFloat();
</del><span class="cx">     if (number &lt; 0 || number &gt; 100)
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><span class="lines">@@ -116,21 +66,17 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool WebVTTParser::parseFloatPercentageValuePair(const String&amp; value, char delimiter, FloatPoint&amp; valuePair)
</del><ins>+bool WebVTTParser::parseFloatPercentageValuePair(VTTScanner&amp; valueScanner, char delimiter, FloatPoint&amp; valuePair)
</ins><span class="cx"> {
</span><del>-    // The delimiter can't be the first or second value because a pair of
-    // percentages (x%,y%) implies that at least the first two characters
-    // are the first percentage value.
-    size_t delimiterOffset = value.find(delimiter, 2);
-    if (delimiterOffset == notFound || delimiterOffset == value.length() - 1)
</del><ins>+    float firstCoord;
+    if (!parseFloatPercentageValue(valueScanner, firstCoord))
</ins><span class="cx">         return false;
</span><span class="cx"> 
</span><del>-    float firstCoord;
-    if (!parseFloatPercentageValue(value.substring(0, delimiterOffset), firstCoord))
</del><ins>+    if (!valueScanner.scan(delimiter))
</ins><span class="cx">         return false;
</span><span class="cx"> 
</span><span class="cx">     float secondCoord;
</span><del>-    if (!parseFloatPercentageValue(value.substring(delimiterOffset + 1, value.length() - 1), secondCoord))
</del><ins>+    if (!parseFloatPercentageValue(valueScanner, secondCoord))
</ins><span class="cx">         return false;
</span><span class="cx"> 
</span><span class="cx">     valuePair = FloatPoint(firstCoord, secondCoord);
</span><span class="lines">@@ -325,35 +271,32 @@
</span><span class="cx"> 
</span><span class="cx"> WebVTTParser::ParseState WebVTTParser::collectTimingsAndSettings(const String&amp; line)
</span><span class="cx"> {
</span><ins>+    VTTScanner input(line);
+
</ins><span class="cx">     // Collect WebVTT cue timings and settings. (5.3 WebVTT cue timings and settings parsing.)
</span><span class="cx">     // Steps 1 - 3 - Let input be the string being parsed and position be a pointer into input
</span><del>-    unsigned position = 0;
-    skipWhiteSpace(line, position);
</del><ins>+    input.skipWhile&lt;isASpace&gt;();
</ins><span class="cx"> 
</span><span class="cx">     // Steps 4 - 5 - Collect a WebVTT timestamp. If that fails, then abort and return failure. Otherwise, let cue's text track cue start time be the collected time.
</span><del>-    if (!collectTimeStamp(line, position, m_currentStartTime))
</del><ins>+    if (!collectTimeStamp(input, m_currentStartTime))
</ins><span class="cx">         return BadCue;
</span><del>-    if (position &gt;= line.length())
-        return BadCue;
</del><span class="cx">     
</span><del>-    skipWhiteSpace(line, position);
</del><ins>+    input.skipWhile&lt;isASpace&gt;();
</ins><span class="cx"> 
</span><span class="cx">     // Steps 6 - 9 - If the next three characters are not &quot;--&gt;&quot;, abort and return failure.
</span><del>-    if (line.find(&quot;--&gt;&quot;, position) == notFound)
</del><ins>+    if (!input.scan(&quot;--&gt;&quot;))
</ins><span class="cx">         return BadCue;
</span><del>-    position += 3;
-    if (position &gt;= line.length())
-        return BadCue;
</del><span class="cx">     
</span><del>-    skipWhiteSpace(line, position);
</del><ins>+    input.skipWhile&lt;isASpace&gt;();
</ins><span class="cx"> 
</span><span class="cx">     // Steps 10 - 11 - Collect a WebVTT timestamp. If that fails, then abort and return failure. Otherwise, let cue's text track cue end time be the collected time.
</span><del>-    if (!collectTimeStamp(line, position, m_currentEndTime))
</del><ins>+    if (!collectTimeStamp(input, m_currentEndTime))
</ins><span class="cx">         return BadCue;
</span><del>-    skipWhiteSpace(line, position);
</del><span class="cx"> 
</span><ins>+    input.skipWhile&lt;isASpace&gt;();
+
</ins><span class="cx">     // Step 12 - Parse the WebVTT settings for the cue (conducted in TextTrackCue).
</span><del>-    m_currentSettings = line.substring(position, line.length()-1);
</del><ins>+    m_currentSettings = input.restOfInputAsString();
</ins><span class="cx">     return CueText;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -489,8 +432,14 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-bool WebVTTParser::collectTimeStamp(const String&amp; line, unsigned&amp; position, double&amp; timeStamp)
</del><ins>+bool WebVTTParser::collectTimeStamp(const String&amp; line, double&amp; timeStamp)
</ins><span class="cx"> {
</span><ins>+    VTTScanner input(line);
+    return collectTimeStamp(input, timeStamp);
+}
+
+bool WebVTTParser::collectTimeStamp(VTTScanner&amp; input, double&amp; timeStamp)
+{
</ins><span class="cx">     // Collect a WebVTT timestamp (5.3 WebVTT cue timings and settings parsing.)
</span><span class="cx">     // Steps 1 - 4 - Initial checks, let most significant units be minutes.
</span><span class="cx">     enum Mode { minutes, hours };
</span><span class="lines">@@ -499,26 +448,22 @@
</span><span class="cx">     // Steps 5 - 7 - Collect a sequence of characters that are 0-9.
</span><span class="cx">     // If not 2 characters or value is greater than 59, interpret as hours.
</span><span class="cx">     int value1;
</span><del>-    unsigned value1Digits = collectDigitsToInt(line, position, value1);
</del><ins>+    unsigned value1Digits = input.scanDigits(value1);
</ins><span class="cx">     if (!value1Digits)
</span><span class="cx">         return false;
</span><span class="cx">     if (value1Digits != 2 || value1 &gt; 59)
</span><span class="cx">         mode = hours;
</span><span class="cx"> 
</span><span class="cx">     // Steps 8 - 11 - Collect the next sequence of 0-9 after ':' (must be 2 chars).
</span><del>-    if (position &gt;= line.length() || line[position++] != ':')
-        return false;
</del><span class="cx">     int value2;
</span><del>-    if (collectDigitsToInt(line, position, value2) != 2)
</del><ins>+    if (!input.scan(':') || input.scanDigits(value2) != 2)
</ins><span class="cx">         return false;
</span><span class="cx"> 
</span><span class="cx">     // Step 12 - Detect whether this timestamp includes hours.
</span><span class="cx">     int value3;
</span><del>-    if (mode == hours || (position &lt; line.length() &amp;&amp; line[position] == ':')) {
-        if (position &gt;= line.length() || line[position++] != ':')
</del><ins>+    if (mode == hours || input.match(':')) {
+        if (!input.scan(':') || input.scanDigits(value3) != 2)
</ins><span class="cx">             return false;
</span><del>-        if (collectDigitsToInt(line, position, value3) != 2)
-            return false;
</del><span class="cx">     } else {
</span><span class="cx">         value3 = value2;
</span><span class="cx">         value2 = value1;
</span><span class="lines">@@ -526,10 +471,8 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Steps 13 - 17 - Collect next sequence of 0-9 after '.' (must be 3 chars).
</span><del>-    if (position &gt;= line.length() || line[position++] != '.')
-        return false;
</del><span class="cx">     int value4;
</span><del>-    if (collectDigitsToInt(line, position, value4) != 3)
</del><ins>+    if (!input.scan('.') || input.scanDigits(value4) != 3)
</ins><span class="cx">         return false;
</span><span class="cx">     if (value2 &gt; 59 || value3 &gt; 59)
</span><span class="cx">         return false;
</span><span class="lines">@@ -631,10 +574,9 @@
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx">     case WebVTTTokenTypes::TimestampTag: {
</span><del>-        unsigned position = 0;
</del><span class="cx">         String charactersString = m_token.characters();
</span><span class="cx">         double parsedTimeStamp;
</span><del>-        if (WebVTTParser::collectTimeStamp(charactersString, position, parsedTimeStamp))
</del><ins>+        if (WebVTTParser::collectTimeStamp(charactersString, parsedTimeStamp))
</ins><span class="cx">             m_currentNode-&gt;parserAppendChild(ProcessingInstruction::create(document, &quot;timestamp&quot;, charactersString));
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="lines">@@ -643,12 +585,6 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebVTTParser::skipWhiteSpace(const String&amp; line, unsigned&amp; position)
-{
-    while (position &lt; line.length() &amp;&amp; isASpace(line[position]))
-        position++;
</del><span class="cx"> }
</span><span class="cx"> 
</span><del>-}
-
</del><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebCorehtmltrackWebVTTParserh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/track/WebVTTParser.h (166096 => 166097)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/track/WebVTTParser.h        2014-03-21 21:14:46 UTC (rev 166096)
+++ trunk/Source/WebCore/html/track/WebVTTParser.h        2014-03-21 21:26:41 UTC (rev 166097)
</span><span class="lines">@@ -49,6 +49,7 @@
</span><span class="cx"> using namespace HTMLNames;
</span><span class="cx"> 
</span><span class="cx"> class Document;
</span><ins>+class VTTScanner;
</ins><span class="cx"> 
</span><span class="cx"> class WebVTTParserClient {
</span><span class="cx"> public:
</span><span class="lines">@@ -119,25 +120,23 @@
</span><span class="cx">             || tagName == rtTag;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    static inline bool isASpace(char c)
</del><ins>+    static inline bool isASpace(UChar c)
</ins><span class="cx">     {
</span><span class="cx">         // WebVTT space characters are U+0020 SPACE, U+0009 CHARACTER TABULATION (tab), U+000A LINE FEED (LF), U+000C FORM FEED (FF), and U+000D CARRIAGE RETURN    (CR).
</span><span class="cx">         return c == ' ' || c == '\t' || c == '\n' || c == '\f' || c == '\r';
</span><span class="cx">     }
</span><del>-    static inline bool isValidSettingDelimiter(char c)
</del><ins>+    static inline bool isValidSettingDelimiter(UChar c)
</ins><span class="cx">     {
</span><span class="cx">         // ... a WebVTT cue consists of zero or more of the following components, in any order, separated from each other by one or more 
</span><span class="cx">         // U+0020 SPACE characters or U+0009 CHARACTER TABULATION (tab) characters.
</span><span class="cx">         return c == ' ' || c == '\t';
</span><span class="cx">     }
</span><del>-    static unsigned collectDigitsToInt(const String&amp;, unsigned&amp; position, int&amp; number);
-    static String collectWord(const String&amp;, unsigned*);
-    static bool collectTimeStamp(const String&amp;, unsigned&amp;, double&amp;);
</del><ins>+    static bool collectTimeStamp(const String&amp;, double&amp;);
</ins><span class="cx"> 
</span><span class="cx"> #if ENABLE(WEBVTT_REGIONS)
</span><span class="cx">     // Useful functions for parsing percentage settings.
</span><del>-    static bool parseFloatPercentageValue(const String&amp;, float&amp;);
-    static bool parseFloatPercentageValuePair(const String&amp;, char, FloatPoint&amp;);
</del><ins>+    static bool parseFloatPercentageValue(VTTScanner&amp; valueScanner, float&amp;);
+    static bool parseFloatPercentageValuePair(VTTScanner&amp; valueScanner, char, FloatPoint&amp;);
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     // Input data to the parser to parse.
</span><span class="lines">@@ -176,7 +175,7 @@
</span><span class="cx">     void createNewRegion(const String&amp; headerValue);
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-    static void skipWhiteSpace(const String&amp;, unsigned&amp;);
</del><ins>+    static bool collectTimeStamp(VTTScanner&amp; input, double&amp; timeStamp);
</ins><span class="cx"> 
</span><span class="cx">     BufferedLineReader m_lineReader;
</span><span class="cx">     RefPtr&lt;TextResourceDecoder&gt; m_decoder;
</span></span></pre>
</div>
</div>

</body>
</html>