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 "VTTScanner.h"
32
33namespace WebCore {
34
35VTTScanner::VTTScanner(const String& line)
36 : m_is8Bit(line.is8Bit())
37{
38 if (m_is8Bit) {
39 m_data.characters8 = line.characters8();
40 m_end.characters8 = m_data.characters8 + line.length();
41 } else {
42 m_data.characters16 = line.characters16();
43 m_end.characters16 = m_data.characters16 + line.length();
44 }
45}
46
47bool VTTScanner::scan(char c)
48{
49 if (!match(c))
50 return false;
51 advance();
52 return true;
53}
54
55bool VTTScanner::scan(const LChar* characters, size_t charactersCount)
56{
57 unsigned matchLength = m_is8Bit ? m_end.characters8 - m_data.characters8 : m_end.characters16 - m_data.characters16;
58 if (matchLength < charactersCount)
59 return false;
60 bool matched;
61 if (m_is8Bit)
62 matched = WTF::equal(m_data.characters8, characters, charactersCount);
63 else
64 matched = WTF::equal(m_data.characters16, characters, charactersCount);
65 if (matched)
66 advance(charactersCount);
67 return matched;
68}
69
70bool VTTScanner::scanRun(const Run& run, const String& toMatch)
71{
72 ASSERT(run.start() == position());
73 ASSERT(run.start() <= end());
74 ASSERT(run.end() >= run.start());
75 ASSERT(run.end() <= end());
76 size_t matchLength = run.length();
77 if (toMatch.length() > matchLength)
78 return false;
79 bool matched;
80 if (m_is8Bit)
81 matched = WTF::equal(toMatch.impl(), m_data.characters8, matchLength);
82 else
83 matched = WTF::equal(toMatch.impl(), m_data.characters16, matchLength);
84 if (matched)
85 seekTo(run.end());
86 return matched;
87}
88
89void VTTScanner::skipRun(const Run& run)
90{
91 ASSERT(run.start() <= end());
92 ASSERT(run.end() >= run.start());
93 ASSERT(run.end() <= end());
94 seekTo(run.end());
95}
96
97String VTTScanner::extractString(const Run& run)
98{
99 ASSERT(run.start() == position());
100 ASSERT(run.start() <= end());
101 ASSERT(run.end() >= run.start());
102 ASSERT(run.end() <= end());
103 String s;
104 if (m_is8Bit)
105 s = String(m_data.characters8, run.length());
106 else
107 s = String(m_data.characters16, run.length());
108 seekTo(run.end());
109 return s;
110}
111
112String VTTScanner::restOfInputAsString()
113{
114 Run rest(position(), end(), m_is8Bit);
115 return extractString(rest);
116}
117
118unsigned VTTScanner::scanDigits(int& number)
119{
120 Run runOfDigits = collectWhile<isASCIIDigit>();
121 if (runOfDigits.isEmpty()) {
122 number = 0;
123 return 0;
124 }
125 bool validNumber;
126 size_t numDigits = runOfDigits.length();
127 if (m_is8Bit)
128 number = charactersToIntStrict(m_data.characters8, numDigits, &validNumber);
129 else
130 number = charactersToIntStrict(m_data.characters16, numDigits, &validNumber);
131
132 // Since we know that scanDigits only scanned valid (ASCII) digits (and
133 // hence that's what got passed to charactersToInt()), the remaining
134 // failure mode for charactersToInt() is overflow, so if |validNumber| is
135 // not true, then set |number| to the maximum int value.
136 if (!validNumber)
137 number = std::numeric_limits<int>::max();
138 // Consume the digits.
139 seekTo(runOfDigits.end());
140 return numDigits;
141}
142
143bool VTTScanner::scanFloat(float& number, bool* isNegative)
144{
145 bool negative = scan('-');
146 Run integerRun = collectWhile<isASCIIDigit>();
147
148 seekTo(integerRun.end());
149 Run decimalRun(position(), position(), m_is8Bit);
150 if (scan('.')) {
151 decimalRun = collectWhile<isASCIIDigit>();
152 seekTo(decimalRun.end());
153 }
154
155 // At least one digit required.
156 if (integerRun.isEmpty() && decimalRun.isEmpty()) {
157 // Restore to starting position.
158 seekTo(integerRun.start());
159 return false;
160 }
161
162 size_t lengthOfFloat = Run(integerRun.start(), position(), m_is8Bit).length();
163 bool validNumber;
164 if (m_is8Bit)
165 number = charactersToFloat(integerRun.start(), lengthOfFloat, &validNumber);
166 else
167 number = charactersToFloat(reinterpret_cast<const UChar*>(integerRun.start()), lengthOfFloat, &validNumber);
168
169 if (!validNumber)
170 number = std::numeric_limits<float>::max();
171 else if (negative)
172 number = -number;
173
174 if (isNegative)
175 *isNegative = negative;
176
177 return true;
178}
179
180}
181