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