Home | History | Annotate | Download | only in vtt
      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 
     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 
     46 bool VTTScanner::scan(char c)
     47 {
     48     if (!match(c))
     49         return false;
     50     advance();
     51     return true;
     52 }
     53 
     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 
     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 
     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 
     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 
    111 String VTTScanner::restOfInputAsString()
    112 {
    113     Run rest(position(), end(), m_is8Bit);
    114     return extractString(rest);
    115 }
    116 
    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 
    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