<!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 <bfulgham@apple.com>
+
+ 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 <bpoulain@apple.com>
</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"> <ClCompile Include="..\html\track\TrackBase.cpp" />
</span><span class="cx"> <ClCompile Include="..\html\track\TrackEvent.cpp" />
</span><span class="cx"> <ClCompile Include="..\html\track\VTTCue.cpp" />
</span><ins>+ <ClCompile Include="..\html\track\VTTScanner.cpp" />
</ins><span class="cx"> <ClCompile Include="..\html\track\WebVTTParser.cpp" />
</span><span class="cx"> <ClCompile Include="..\html\track\WebVTTTokenizer.cpp" />
</span><span class="cx"> <ClCompile Include="..\bindings\generic\ActiveDOMCallback.cpp" />
</span><span class="lines">@@ -20592,6 +20593,7 @@
</span><span class="cx"> <ClInclude Include="..\html\track\InbandTextTrack.h" />
</span><span class="cx"> <ClInclude Include="..\html\track\InbandWebVTTTextTrack.h" />
</span><span class="cx"> <ClInclude Include="..\html\track\LoadableTextTrack.h" />
</span><ins>+ <ClInclude Include="..\html\track\ParsingUtilities.h" />
</ins><span class="cx"> <ClInclude Include="..\html\track\TextTrack.h" />
</span><span class="cx"> <ClInclude Include="..\html\track\TextTrackCue.h" />
</span><span class="cx"> <ClInclude Include="..\html\track\TextTrackCueList.h" />
</span><span class="lines">@@ -20599,6 +20601,7 @@
</span><span class="cx"> <ClInclude Include="..\html\track\TrackBase.h" />
</span><span class="cx"> <ClInclude Include="..\html\track\TrackEvent.h" />
</span><span class="cx"> <ClInclude Include="..\html\track\VTTCue.h" />
</span><ins>+ <ClInclude Include="..\html\track\VTTScanner.h" />
</ins><span class="cx"> <ClInclude Include="..\html\track\WebVTTParser.h" />
</span><span class="cx"> <ClInclude Include="..\html\track\WebVTTToken.h" />
</span><span class="cx"> <ClInclude Include="..\html\track\WebVTTTokenizer.h" />
</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"> <ClCompile Include="..\html\track\VTTCue.cpp">
</span><span class="cx"> <Filter>html\track</Filter>
</span><span class="cx"> </ClCompile>
</span><ins>+ <ClCompile Include="..\html\track\VTTScanner.cpp">
+ <Filter>html\track</Filter>
+ </ClCompile>
</ins><span class="cx"> <ClCompile Include="..\html\track\WebVTTParser.cpp">
</span><span class="cx"> <Filter>html\track</Filter>
</span><span class="cx"> </ClCompile>
</span><span class="lines">@@ -11245,6 +11248,9 @@
</span><span class="cx"> <ClInclude Include="..\html\track\LoadableTextTrack.h">
</span><span class="cx"> <Filter>html\track</Filter>
</span><span class="cx"> </ClInclude>
</span><ins>+ <ClInclude Include="..\html\track\ParsingUtilities.h">
+ <Filter>html\track</Filter>
+ </ClInclude>
</ins><span class="cx"> <ClInclude Include="..\html\track\TextTrack.h">
</span><span class="cx"> <Filter>html\track</Filter>
</span><span class="cx"> </ClInclude>
</span><span class="lines">@@ -11266,6 +11272,9 @@
</span><span class="cx"> <ClInclude Include="..\html\track\VTTCue.h">
</span><span class="cx"> <Filter>html\track</Filter>
</span><span class="cx"> </ClInclude>
</span><ins>+ <ClInclude Include="..\html\track\VTTScanner.h">
+ <Filter>html\track</Filter>
+ </ClInclude>
</ins><span class="cx"> <ClInclude Include="..\html\track\WebVTTParser.h">
</span><span class="cx"> <Filter>html\track</Filter>
</span><span class="cx"> </ClInclude>
</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 = "<group>"; };
</span><span class="cx">                 7A74ECB9101839A600BF939E /* InspectorDOMStorageAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorDOMStorageAgent.h; sourceTree = "<group>"; };
</span><span class="cx">                 7A74ECBC101839DA00BF939E /* JSInspectorFrontendHostCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSInspectorFrontendHostCustom.cpp; sourceTree = "<group>"; };
</span><ins>+                7A93868118DCC14500B8263D /* ParsingUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParsingUtilities.h; sourceTree = "<group>"; };
+                7A93868218DCC14500B8263D /* VTTScanner.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VTTScanner.cpp; sourceTree = "<group>"; };
+                7A93868318DCC14500B8263D /* VTTScanner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VTTScanner.h; sourceTree = "<group>"; };
</ins><span class="cx">                 7AABA25714BC613300AA9A11 /* DOMEditor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DOMEditor.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 7AABA25814BC613300AA9A11 /* DOMEditor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMEditor.h; sourceTree = "<group>"; };
</span><span class="cx">                 7AB0B1BE1211A62200A76940 /* InspectorDatabaseAgent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorDatabaseAgent.cpp; sourceTree = "<group>"; };
</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
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ParsingUtilities_h
+#define ParsingUtilities_h
+
+template<typename CharType>
+bool skipExactly(const CharType*& position, const CharType* end, CharType delimiter)
+{
+ if (position < end && *position == delimiter) {
+ ++position;
+ return true;
+ }
+ return false;
+}
+
+template<typename CharType, bool characterPredicate(CharType)>
+bool skipExactly(const CharType*& position, const CharType* end)
+{
+ if (position < end && characterPredicate(*position)) {
+ ++position;
+ return true;
+ }
+ return false;
+}
+
+template<typename CharType>
+void skipUntil(const CharType*& position, const CharType* end, CharType delimiter)
+{
+ while (position < end && *position != delimiter)
+ ++position;
+}
+
+template<typename CharType, bool characterPredicate(CharType)>
+void skipUntil(const CharType*& position, const CharType* end)
+{
+ while (position < end && !characterPredicate(*position))
+ ++position;
+}
+
+template<typename CharType, bool characterPredicate(CharType)>
+void skipWhile(const CharType*& position, const CharType* end)
+{
+ while (position < end && 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 "Text.h"
</span><span class="cx"> #include "TextTrack.h"
</span><span class="cx"> #include "TextTrackCueList.h"
</span><ins>+#include "VTTScanner.h"
</ins><span class="cx"> #include "WebVTTElement.h"
</span><span class="cx"> #include "WebVTTParser.h"
</span><span class="cx"> #include <wtf/MathExtras.h>
</span><span class="lines">@@ -694,10 +695,8 @@
</span><span class="cx">
</span><span class="cx"> for (Node* child = root->firstChild(); child; child = NodeTraversal::next(child, root)) {
</span><span class="cx"> if (child->nodeName() == timestampTag) {
</span><del>- unsigned position = 0;
- String timestamp = child->nodeValue();
</del><span class="cx"> double currentTimestamp;
</span><del>- bool check = WebVTTParser::collectTimeStamp(timestamp, position, currentTimestamp);
</del><ins>+ bool check = WebVTTParser::collectTimeStamp(child->nodeValue(), currentTimestamp);
</ins><span class="cx"> ASSERT_UNUSED(check, check);
</span><span class="cx">
</span><span class="cx"> if (currentTimestamp > 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& name)
</del><ins>+VTTCue::CueSetting VTTCue::settingName(VTTScanner& input)
</ins><span class="cx"> {
</span><del>- DEPRECATED_DEFINE_STATIC_LOCAL(const String, verticalKeyword, (ASCIILiteral("vertical")));
- DEPRECATED_DEFINE_STATIC_LOCAL(const String, lineKeyword, (ASCIILiteral("line")));
- DEPRECATED_DEFINE_STATIC_LOCAL(const String, positionKeyword, (ASCIILiteral("position")));
- DEPRECATED_DEFINE_STATIC_LOCAL(const String, sizeKeyword, (ASCIILiteral("size")));
- DEPRECATED_DEFINE_STATIC_LOCAL(const String, alignKeyword, (ASCIILiteral("align")));
</del><ins>+ CueSetting parsedSetting = None;
+ if (input.scan("vertical"))
+ parsedSetting = Vertical;
+ else if (input.scan("line"))
+ parsedSetting = Line;
+ else if (input.scan("position"))
+ parsedSetting = Position;
+ else if (input.scan("size"))
+ parsedSetting = Size;
+ else if (input.scan("align"))
+ parsedSetting = Align;
</ins><span class="cx"> #if ENABLE(WEBVTT_REGIONS)
</span><del>- DEPRECATED_DEFINE_STATIC_LOCAL(const String, regionIdKeyword, (ASCIILiteral("region")));
</del><ins>+ else if (input.scan("region"))
+ parsedSetting = RegionId;
</ins><span class="cx"> #endif
</span><ins>+ // Verify that a ':' follows.
+ if (parsedSetting != None && 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& input, unsigned& position, int& number)
</del><ins>+static bool scanPercentage(VTTScanner& input, const VTTScanner::Run& valueRun, int& 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 >= 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 < input.length() && !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 >= 0 && number <= 100;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void VTTCue::setCueSettings(const String& input)
</del><ins>+void VTTCue::setCueSettings(const String& 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 < 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 < input.length() && WebVTTParser::isValidSettingDelimiter(input[position]))
- position++;
- if (position >= 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<WebVTTParser::isValidSettingDelimiter>();
+ 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, &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 >= input.length())
- break;
</del><ins>+ VTTScanner::Run valueRun = input.collectUntil<WebVTTParser::isValidSettingDelimiter>();
</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 "vertical"
</span><span class="cx"> // 1. If value is a case-sensitive match for the string "rl", then let cue's text track cue writing direction
</span><span class="cx"> // be vertical growing left.
</span><del>- String writingDirection = WebVTTParser::collectWord(input, &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 "lr", 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 < input.length() && (input[position] == '-' || input[position] == '%' || isASCIIDigit(input[position])))
- linePositionBuilder.append(input[position++]);
- if (position < input.length() && !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("%", 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] == '-' && linePosition[linePosition.length() - 1] == '%')
</del><ins>+ if (!numDigits || (isPercentage && 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(&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 < 0 || number > 100)
</del><ins>+ if (isPercentage) {
+ if (linePosition < 0 || linePosition > 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, &position);
-
</del><span class="cx"> // 1. If value is a case-sensitive match for the string "start", 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 "middle", 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 "end", 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 "left", 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 "right", 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, &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&);
</del><ins>+ CueSetting settingName(VTTScanner&);
</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 "Logging.h"
</span><span class="cx"> #include "RenderElement.h"
</span><span class="cx"> #include "VTTCue.h"
</span><ins>+#include "VTTScanner.h"
</ins><span class="cx"> #include "WebVTTParser.h"
</span><span class="cx"> #include <wtf/MathExtras.h>
</span><span class="cx">
</span><span class="lines">@@ -216,83 +217,100 @@
</span><span class="cx"> setScroll(region->scroll(), ASSERT_NO_EXCEPTION);
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void VTTRegion::setRegionSettings(const String& input)
</del><ins>+void VTTRegion::setRegionSettings(const String& 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 < input.length()) {
- while (position < input.length() && WebVTTParser::isValidSettingDelimiter(input[position]))
- position++;
-
- if (position >= input.length())
</del><ins>+ while (!input.isAtEnd()) {
+ input.skipWhile<WebVTTParser::isValidSettingDelimiter>();
+ if (input.isAtEnd())
</ins><span class="cx"> break;
</span><span class="cx">
</span><del>- parseSetting(input, &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<WebVTTParser::isASpace>();
+ 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& setting)
</del><ins>+VTTRegion::RegionSetting VTTRegion::scanSettingName(VTTScanner& input)
</ins><span class="cx"> {
</span><del>- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, idKeyword, ("id", AtomicString::ConstructFromLiteral));
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, heightKeyword, ("height", AtomicString::ConstructFromLiteral));
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, widthKeyword, ("width", AtomicString::ConstructFromLiteral));
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, regionAnchorKeyword, ("regionanchor", AtomicString::ConstructFromLiteral));
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, viewportAnchorKeyword, ("viewportanchor", AtomicString::ConstructFromLiteral));
- DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, scrollKeyword, ("scroll", AtomicString::ConstructFromLiteral));
-
- if (setting == idKeyword)
</del><ins>+ if (input.scan("id"))
</ins><span class="cx"> return Id;
</span><del>- if (setting == heightKeyword)
</del><ins>+ if (input.scan("height"))
</ins><span class="cx"> return Height;
</span><del>- if (setting == widthKeyword)
</del><ins>+ if (input.scan("width"))
</ins><span class="cx"> return Width;
</span><del>- if (setting == viewportAnchorKeyword)
</del><ins>+ if (input.scan("viewportanchor"))
</ins><span class="cx"> return ViewportAnchor;
</span><del>- if (setting == regionAnchorKeyword)
</del><ins>+ if (input.scan("regionanchor"))
</ins><span class="cx"> return RegionAnchor;
</span><del>- if (setting == scrollKeyword)
</del><ins>+ if (input.scan("scroll"))
</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& value)
</del><ins>+static inline bool parsedEntireRun(const VTTScanner& input, const VTTScanner::Run& run)
</ins><span class="cx"> {
</span><ins>+ return input.isAt(run.end());
+}
+
+void VTTRegion::parseSettingValue(RegionSetting setting, VTTScanner& input)
+{
</ins><span class="cx"> DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, scrollUpValueKeyword, ("up", AtomicString::ConstructFromLiteral));
</span><span class="cx">
</span><ins>+ VTTScanner::Run valueRun = input.collectUntil<WebVTTParser::isASpace>();
+
</ins><span class="cx"> switch (setting) {
</span><del>- case Id:
- if (value.find("-->") == notFound)
- m_id = value;
</del><ins>+ case Id: {
+ String stringValue = input.extractString(valueRun);
+ if (stringValue.find("-->") == 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) && parsedEntireRun(input, valueRun))
</ins><span class="cx"> m_width = floatWidth;
</span><span class="cx"> else
</span><span class="cx"> LOG(Media, "VTTRegion::parseSettingValue, invalid Width");
</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) && position == value.length())
</del><ins>+ if (input.scanDigits(number) && parsedEntireRun(input, valueRun))
</ins><span class="cx"> m_heightInLines = number;
</span><span class="cx"> else
</span><span class="cx"> LOG(Media, "VTTRegion::parseSettingValue, invalid Height");
</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) && parsedEntireRun(input, valueRun))
+ m_regionAnchor = anchor;
+ else
</ins><span class="cx"> LOG(Media, "VTTRegion::parseSettingValue, invalid RegionAnchor");
</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) && parsedEntireRun(input, valueRun))
+ m_viewportAnchor = anchor;
+ else
</ins><span class="cx"> LOG(Media, "VTTRegion::parseSettingValue, invalid ViewportAnchor");
</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, "VTTRegion::parseSettingValue, invalid Scroll");
</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& 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& VTTRegion::textTrackCueContainerScrollingClass()
</span><span class="cx"> {
</span><span class="cx"> DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, trackRegionCueContainerScrollingClass, ("scrolling", 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<VTTRegion>, 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&);
</del><ins>+ RegionSetting scanSettingName(VTTScanner&);
</ins><span class="cx">
</span><del>- void parseSettingValue(RegionSetting, const String&);
- void parseSetting(const String&, unsigned*);
</del><ins>+ void parseSettingValue(RegionSetting, VTTScanner&);
</ins><span class="cx">
</span><span class="cx"> static const AtomicString& textTrackCueContainerShadowPseudoId();
</span><span class="cx"> static const AtomicString& 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
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT 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 "config.h"
+#include "VTTScanner.h"
+
+namespace WebCore {
+
+VTTScanner::VTTScanner(const String& 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 < 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& run, const String& toMatch)
+{
+ ASSERT(run.start() == position());
+ ASSERT(run.start() <= end());
+ ASSERT(run.end() >= run.start());
+ ASSERT(run.end() <= end());
+ size_t matchLength = run.length();
+ if (toMatch.length() > 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& run)
+{
+ ASSERT(run.start() <= end());
+ ASSERT(run.end() >= run.start());
+ ASSERT(run.end() <= end());
+ seekTo(run.end());
+}
+
+String VTTScanner::extractString(const Run& run)
+{
+ ASSERT(run.start() == position());
+ ASSERT(run.start() <= end());
+ ASSERT(run.end() >= run.start());
+ ASSERT(run.end() <= 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& number)
+{
+ Run runOfDigits = collectWhile<isASCIIDigit>();
+ if (runOfDigits.isEmpty()) {
+ number = 0;
+ return 0;
+ }
+ bool validNumber;
+ size_t numDigits = runOfDigits.length();
+ if (m_is8Bit)
+ number = charactersToIntStrict(m_data.characters8, numDigits, &validNumber);
+ else
+ number = charactersToIntStrict(m_data.characters16, numDigits, &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<int>::max();
+ // Consume the digits.
+ seekTo(runOfDigits.end());
+ return numDigits;
+}
+
+bool VTTScanner::scanFloat(float& number)
+{
+ Run integerRun = collectWhile<isASCIIDigit>();
+ seekTo(integerRun.end());
+ Run decimalRun(position(), position(), m_is8Bit);
+ if (scan('.')) {
+ decimalRun = collectWhile<isASCIIDigit>();
+ seekTo(decimalRun.end());
+ }
+
+ // At least one digit required.
+ if (integerRun.isEmpty() && 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, &validNumber);
+ else
+ number = charactersToFloat(reinterpret_cast<const UChar*>(integerRun.start()), lengthOfFloat, &validNumber);
+
+ if (!validNumber)
+ number = std::numeric_limits<float>::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
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT 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 "ParsingUtilities.h"
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+// Helper class for "scanning" an input string and performing parsing of
+// "micro-syntax"-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& 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() && 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<unsigned charactersCount>
+ bool scan(const char (&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<bool characterPredicate(UChar)>
+ void skipWhile();
+
+ // Like skipWhile, but using a negated predicate.
+ template<bool characterPredicate(UChar)>
+ 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<bool characterPredicate(UChar)>
+ Run collectWhile();
+
+ // Like collectWhile, but using a negated predicate.
+ template<bool characterPredicate(UChar)>
+ Run collectUntil();
+
+ // Scan the string |toMatch|, using the specified |run| as the sequence to
+ // match against.
+ bool scanRun(const Run&, const String& toMatch);
+
+ // Skip to the end of the specified |run|.
+ void skipRun(const Run&);
+
+ // 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&);
+
+ // 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& number);
+
+ // Scan a floating point value on one of the forms: \d+\.? \d+\.\d+ \.\d+
+ bool scanFloat(float& 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<bool characterPredicate(UChar)>
+ 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<const UChar*>(m_end) - reinterpret_cast<const UChar*>(m_start);
+}
+
+template<unsigned charactersCount>
+inline bool VTTScanner::scan(const char (&characters)[charactersCount])
+{
+ return scan(reinterpret_cast<const LChar*>(characters), charactersCount - 1);
+}
+
+template<bool characterPredicate(UChar)>
+inline void VTTScanner::skipWhile()
+{
+ if (m_is8Bit)
+ ::skipWhile<LChar, LCharPredicateAdapter<characterPredicate> >(m_data.characters8, m_end.characters8);
+ else
+ ::skipWhile<UChar, characterPredicate>(m_data.characters16, m_end.characters16);
+}
+
+template<bool characterPredicate(UChar)>
+inline void VTTScanner::skipUntil()
+{
+ if (m_is8Bit)
+ ::skipUntil<LChar, LCharPredicateAdapter<characterPredicate> >(m_data.characters8, m_end.characters8);
+ else
+ ::skipUntil<UChar, characterPredicate>(m_data.characters16, m_end.characters16);
+}
+
+template<bool characterPredicate(UChar)>
+inline VTTScanner::Run VTTScanner::collectWhile()
+{
+ if (m_is8Bit) {
+ const LChar* current = m_data.characters8;
+ ::skipWhile<LChar, LCharPredicateAdapter<characterPredicate> >(current, m_end.characters8);
+ return Run(position(), current, m_is8Bit);
+ }
+ const UChar* current = m_data.characters16;
+ ::skipWhile<UChar, characterPredicate>(current, m_end.characters16);
+ return Run(position(), reinterpret_cast<Position>(current), m_is8Bit);
+}
+
+template<bool characterPredicate(UChar)>
+inline VTTScanner::Run VTTScanner::collectUntil()
+{
+ if (m_is8Bit) {
+ const LChar* current = m_data.characters8;
+ ::skipUntil<LChar, LCharPredicateAdapter<characterPredicate> >(current, m_end.characters8);
+ return Run(position(), current, m_is8Bit);
+ }
+ const UChar* current = m_data.characters16;
+ ::skipUntil<UChar, characterPredicate>(current, m_end.characters16);
+ return Run(position(), reinterpret_cast<Position>(current), m_is8Bit);
+}
+
+inline void VTTScanner::seekTo(Position position)
+{
+ ASSERT(position <= end());
+ m_data.characters8 = position;
+}
+
+inline UChar VTTScanner::currentChar() const
+{
+ ASSERT(position() < end());
+ return m_is8Bit ? *m_data.characters8 : *m_data.characters16;
+}
+
+inline void VTTScanner::advance(unsigned amount)
+{
+ ASSERT(position() < 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 "ProcessingInstruction.h"
</span><span class="cx"> #include "Text.h"
</span><ins>+#include "VTTScanner.h"
</ins><span class="cx"> #include "WebVTTElement.h"
</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 = "WEBVTT";
</span><span class="cx"> const unsigned fileIdentifierLength = 6;
</span><span class="cx">
</span><del>-static unsigned scanDigits(const String& input, unsigned& position)
-{
- unsigned startPosition = position;
- while (position < input.length() && isASCIIDigit(input[position]))
- position++;
- return position - startPosition;
-}
-
-unsigned WebVTTParser::collectDigitsToInt(const String& input, unsigned& position, int& 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, &validNumber);
- else
- number = charactersToIntStrict(input.characters16() + startPosition, numDigits, &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<int>::max();
- return numDigits;
-}
-
-String WebVTTParser::collectWord(const String& input, unsigned* position)
-{
- StringBuilder string;
- while (*position < input.length() && !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& value, float& percentage)
</del><ins>+bool WebVTTParser::parseFloatPercentageValue(VTTScanner& valueScanner, float& 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 && !digitsAfterDot)
- return false;
-
- float number = value.toFloat();
</del><span class="cx"> if (number < 0 || number > 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& value, char delimiter, FloatPoint& valuePair)
</del><ins>+bool WebVTTParser::parseFloatPercentageValuePair(VTTScanner& valueScanner, char delimiter, FloatPoint& 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& 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<isASpace>();
</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 >= line.length())
- return BadCue;
</del><span class="cx">
</span><del>- skipWhiteSpace(line, position);
</del><ins>+ input.skipWhile<isASpace>();
</ins><span class="cx">
</span><span class="cx"> // Steps 6 - 9 - If the next three characters are not "-->", abort and return failure.
</span><del>- if (line.find("-->", position) == notFound)
</del><ins>+ if (!input.scan("-->"))
</ins><span class="cx"> return BadCue;
</span><del>- position += 3;
- if (position >= line.length())
- return BadCue;
</del><span class="cx">
</span><del>- skipWhiteSpace(line, position);
</del><ins>+ input.skipWhile<isASpace>();
</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<isASpace>();
+
</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& line, unsigned& position, double& timeStamp)
</del><ins>+bool WebVTTParser::collectTimeStamp(const String& line, double& timeStamp)
</ins><span class="cx"> {
</span><ins>+ VTTScanner input(line);
+ return collectTimeStamp(input, timeStamp);
+}
+
+bool WebVTTParser::collectTimeStamp(VTTScanner& input, double& 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 > 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 >= 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 < line.length() && line[position] == ':')) {
- if (position >= 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 >= 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 > 59 || value3 > 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->parserAppendChild(ProcessingInstruction::create(document, "timestamp", 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& line, unsigned& position)
-{
- while (position < line.length() && 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&, unsigned& position, int& number);
- static String collectWord(const String&, unsigned*);
- static bool collectTimeStamp(const String&, unsigned&, double&);
</del><ins>+ static bool collectTimeStamp(const String&, double&);
</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&, float&);
- static bool parseFloatPercentageValuePair(const String&, char, FloatPoint&);
</del><ins>+ static bool parseFloatPercentageValue(VTTScanner& valueScanner, float&);
+ static bool parseFloatPercentageValuePair(VTTScanner& valueScanner, char, FloatPoint&);
</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& headerValue);
</span><span class="cx"> #endif
</span><span class="cx">
</span><del>- static void skipWhiteSpace(const String&, unsigned&);
</del><ins>+ static bool collectTimeStamp(VTTScanner& input, double& timeStamp);
</ins><span class="cx">
</span><span class="cx"> BufferedLineReader m_lineReader;
</span><span class="cx"> RefPtr<TextResourceDecoder> m_decoder;
</span></span></pre>
</div>
</div>
</body>
</html>