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 | |
33 | namespace WebCore { |
34 | |
35 | VTTScanner::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 | |
47 | bool VTTScanner::scan(char c) |
48 | { |
49 | if (!match(c)) |
50 | return false; |
51 | advance(); |
52 | return true; |
53 | } |
54 | |
55 | bool 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 | |
70 | bool 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 | |
89 | void 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 | |
97 | String VTTScanner::(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 | |
112 | String VTTScanner::restOfInputAsString() |
113 | { |
114 | Run rest(position(), end(), m_is8Bit); |
115 | return extractString(rest); |
116 | } |
117 | |
118 | unsigned 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 | |
143 | bool 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 | |