• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2013, Opera Software ASA. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  * 3. Neither the name of Opera Software ASA nor the names of its
13  *    contributors may be used to endorse or promote products derived
14  *    from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
19  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
20  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
21  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
25  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
27  * OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #include "config.h"
31 #include "core/html/track/vtt/VTTScanner.h"
32 
33 namespace blink {
34 
VTTScanner(const String & line)35 VTTScanner::VTTScanner(const String& line) : m_is8Bit(line.is8Bit())
36 {
37     if (m_is8Bit) {
38         m_data.characters8 = line.characters8();
39         m_end.characters8 = m_data.characters8 + line.length();
40     } else {
41         m_data.characters16 = line.characters16();
42         m_end.characters16 = m_data.characters16 + line.length();
43     }
44 }
45 
scan(char c)46 bool VTTScanner::scan(char c)
47 {
48     if (!match(c))
49         return false;
50     advance();
51     return true;
52 }
53 
scan(const LChar * characters,size_t charactersCount)54 bool VTTScanner::scan(const LChar* characters, size_t charactersCount)
55 {
56     unsigned matchLength = m_is8Bit ? m_end.characters8 - m_data.characters8 : m_end.characters16 - m_data.characters16;
57     if (matchLength < charactersCount)
58         return false;
59     bool matched;
60     if (m_is8Bit)
61         matched = WTF::equal(m_data.characters8, characters, charactersCount);
62     else
63         matched = WTF::equal(m_data.characters16, characters, charactersCount);
64     if (matched)
65         advance(charactersCount);
66     return matched;
67 }
68 
scanRun(const Run & run,const String & toMatch)69 bool VTTScanner::scanRun(const Run& run, const String& toMatch)
70 {
71     ASSERT(run.start() == position());
72     ASSERT(run.start() <= end());
73     ASSERT(run.end() >= run.start());
74     ASSERT(run.end() <= end());
75     size_t matchLength = run.length();
76     if (toMatch.length() > matchLength)
77         return false;
78     bool matched;
79     if (m_is8Bit)
80         matched = WTF::equal(toMatch.impl(), m_data.characters8, matchLength);
81     else
82         matched = WTF::equal(toMatch.impl(), m_data.characters16, matchLength);
83     if (matched)
84         seekTo(run.end());
85     return matched;
86 }
87 
skipRun(const Run & run)88 void VTTScanner::skipRun(const Run& run)
89 {
90     ASSERT(run.start() <= end());
91     ASSERT(run.end() >= run.start());
92     ASSERT(run.end() <= end());
93     seekTo(run.end());
94 }
95 
extractString(const Run & run)96 String VTTScanner::extractString(const Run& run)
97 {
98     ASSERT(run.start() == position());
99     ASSERT(run.start() <= end());
100     ASSERT(run.end() >= run.start());
101     ASSERT(run.end() <= end());
102     String s;
103     if (m_is8Bit)
104         s = String(m_data.characters8, run.length());
105     else
106         s = String(m_data.characters16, run.length());
107     seekTo(run.end());
108     return s;
109 }
110 
restOfInputAsString()111 String VTTScanner::restOfInputAsString()
112 {
113     Run rest(position(), end(), m_is8Bit);
114     return extractString(rest);
115 }
116 
scanDigits(int & number)117 unsigned VTTScanner::scanDigits(int& number)
118 {
119     Run runOfDigits = collectWhile<isASCIIDigit>();
120     if (runOfDigits.isEmpty()) {
121         number = 0;
122         return 0;
123     }
124     bool validNumber;
125     size_t numDigits = runOfDigits.length();
126     if (m_is8Bit)
127         number = charactersToInt(m_data.characters8, numDigits, &validNumber);
128     else
129         number = charactersToInt(m_data.characters16, numDigits, &validNumber);
130 
131     // Since we know that scanDigits only scanned valid (ASCII) digits (and
132     // hence that's what got passed to charactersToInt()), the remaining
133     // failure mode for charactersToInt() is overflow, so if |validNumber| is
134     // not true, then set |number| to the maximum int value.
135     if (!validNumber)
136         number = std::numeric_limits<int>::max();
137     // Consume the digits.
138     seekTo(runOfDigits.end());
139     return numDigits;
140 }
141 
scanFloat(float & number)142 bool VTTScanner::scanFloat(float& number)
143 {
144     Run integerRun = collectWhile<isASCIIDigit>();
145     seekTo(integerRun.end());
146     Run decimalRun(position(), position(), m_is8Bit);
147     if (scan('.')) {
148         decimalRun = collectWhile<isASCIIDigit>();
149         seekTo(decimalRun.end());
150     }
151 
152     // At least one digit required.
153     if (integerRun.isEmpty() && decimalRun.isEmpty()) {
154         // Restore to starting position.
155         seekTo(integerRun.start());
156         return false;
157     }
158 
159     size_t lengthOfFloat = Run(integerRun.start(), position(), m_is8Bit).length();
160     bool validNumber;
161     if (m_is8Bit)
162         number = charactersToFloat(integerRun.start(), lengthOfFloat, &validNumber);
163     else
164         number = charactersToFloat(reinterpret_cast<const UChar*>(integerRun.start()), lengthOfFloat, &validNumber);
165 
166     if (!validNumber)
167         number = std::numeric_limits<float>::max();
168     return true;
169 }
170 
171 }
172