diff options
Diffstat (limited to 'Source/WebCore/html/track/VTTScanner.h')
-rw-r--r-- | Source/WebCore/html/track/VTTScanner.h | 230 |
1 files changed, 230 insertions, 0 deletions
diff --git a/Source/WebCore/html/track/VTTScanner.h b/Source/WebCore/html/track/VTTScanner.h new file mode 100644 index 000000000..c4ae32a01 --- /dev/null +++ b/Source/WebCore/html/track/VTTScanner.h @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2013, Opera Software ASA. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Opera Software ASA nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "ParsingUtilities.h" +#include <wtf/text/WTFString.h> + +namespace WebCore { + +// Helper class for "scanning" an input string and performing parsing of +// "micro-syntax"-like constructs. +// +// There's two primary operations: match and scan. +// +// The 'match' operation matches an explicitly or implicitly specified sequence +// against the characters ahead of the current input pointer, and returns true +// if the sequence can be matched. +// +// The 'scan' operation performs a 'match', and if the match is successful it +// advance the input pointer past the matched sequence. +class VTTScanner { + WTF_MAKE_NONCOPYABLE(VTTScanner); +public: + explicit VTTScanner(const String& line); + + typedef const LChar* Position; + + class Run { + public: + Run(Position start, Position end, bool is8Bit) + : m_start(start), m_end(end), m_is8Bit(is8Bit) { } + + Position start() const { return m_start; } + Position end() const { return m_end; } + + bool isEmpty() const { return m_start == m_end; } + size_t length() const; + + private: + Position m_start; + Position m_end; + bool m_is8Bit; + }; + + // Check if the input pointer points at the specified position. + bool isAt(Position checkPosition) const { return position() == checkPosition; } + // Check if the input pointer points at the end of the input. + bool isAtEnd() const { return position() == end(); } + // Match the character |c| against the character at the input pointer (~lookahead). + bool match(char c) const { return !isAtEnd() && currentChar() == c; } + // Scan the character |c|. + bool scan(char); + // Scan the first |charactersCount| characters of the string |characters|. + bool scan(const LChar* characters, size_t charactersCount); + + // Scan the literal |characters|. + template<unsigned charactersCount> + bool scan(const char (&characters)[charactersCount]); + + // Skip (advance the input pointer) as long as the specified + // |characterPredicate| returns true, and the input pointer is not passed + // the end of the input. + template<bool characterPredicate(UChar)> + void skipWhile(); + + // Like skipWhile, but using a negated predicate. + template<bool characterPredicate(UChar)> + void skipUntil(); + + // Return the run of characters for which the specified + // |characterPredicate| returns true. The start of the run will be the + // current input pointer. + template<bool characterPredicate(UChar)> + Run collectWhile(); + + // Like collectWhile, but using a negated predicate. + template<bool characterPredicate(UChar)> + Run collectUntil(); + + // Scan the string |toMatch|, using the specified |run| as the sequence to + // match against. + bool scanRun(const Run&, const String& toMatch); + + // Skip to the end of the specified |run|. + void skipRun(const Run&); + + // Return the String made up of the characters in |run|, and advance the + // input pointer to the end of the run. + String extractString(const Run&); + + // Return a String constructed from the rest of the input (between input + // pointer and end of input), and advance the input pointer accordingly. + String restOfInputAsString(); + + // Scan a set of ASCII digits from the input. Return the number of digits + // scanned, and set |number| to the computed value. If the digits make up a + // number that does not fit the 'int' type, |number| is set to INT_MAX. + // Note: Does not handle sign. + unsigned scanDigits(int& number); + + // Scan a floating point value on one of the forms: \d+\.? \d+\.\d+ \.\d+ + bool scanFloat(float& number, bool* isNegative = nullptr); + +protected: + Position position() const { return m_data.characters8; } + Position end() const { return m_end.characters8; } + void seekTo(Position); + UChar currentChar() const; + void advance(unsigned amount = 1); + // Adapt a UChar-predicate to an LChar-predicate. + // (For use with skipWhile/Until from ParsingUtilities.h). + template<bool characterPredicate(UChar)> + static inline bool LCharPredicateAdapter(LChar c) { return characterPredicate(c); } + union { + const LChar* characters8; + const UChar* characters16; + } m_data; + union { + const LChar* characters8; + const UChar* characters16; + } m_end; + bool m_is8Bit; +}; + +inline size_t VTTScanner::Run::length() const +{ + if (m_is8Bit) + return m_end - m_start; + return reinterpret_cast<const UChar*>(m_end) - reinterpret_cast<const UChar*>(m_start); +} + +template<unsigned charactersCount> +inline bool VTTScanner::scan(const char (&characters)[charactersCount]) +{ + return scan(reinterpret_cast<const LChar*>(characters), charactersCount - 1); +} + +template<bool characterPredicate(UChar)> +inline void VTTScanner::skipWhile() +{ + if (m_is8Bit) + WebCore::skipWhile<LChar, LCharPredicateAdapter<characterPredicate> >(m_data.characters8, m_end.characters8); + else + WebCore::skipWhile<UChar, characterPredicate>(m_data.characters16, m_end.characters16); +} + +template<bool characterPredicate(UChar)> +inline void VTTScanner::skipUntil() +{ + if (m_is8Bit) + WebCore::skipUntil<LChar, LCharPredicateAdapter<characterPredicate> >(m_data.characters8, m_end.characters8); + else + WebCore::skipUntil<UChar, characterPredicate>(m_data.characters16, m_end.characters16); +} + +template<bool characterPredicate(UChar)> +inline VTTScanner::Run VTTScanner::collectWhile() +{ + if (m_is8Bit) { + const LChar* current = m_data.characters8; + WebCore::skipWhile<LChar, LCharPredicateAdapter<characterPredicate> >(current, m_end.characters8); + return Run(position(), current, m_is8Bit); + } + const UChar* current = m_data.characters16; + WebCore::skipWhile<UChar, characterPredicate>(current, m_end.characters16); + return Run(position(), reinterpret_cast<Position>(current), m_is8Bit); +} + +template<bool characterPredicate(UChar)> +inline VTTScanner::Run VTTScanner::collectUntil() +{ + if (m_is8Bit) { + const LChar* current = m_data.characters8; + WebCore::skipUntil<LChar, LCharPredicateAdapter<characterPredicate> >(current, m_end.characters8); + return Run(position(), current, m_is8Bit); + } + const UChar* current = m_data.characters16; + WebCore::skipUntil<UChar, characterPredicate>(current, m_end.characters16); + return Run(position(), reinterpret_cast<Position>(current), m_is8Bit); +} + +inline void VTTScanner::seekTo(Position position) +{ + ASSERT(position <= end()); + m_data.characters8 = position; +} + +inline UChar VTTScanner::currentChar() const +{ + ASSERT(position() < end()); + return m_is8Bit ? *m_data.characters8 : *m_data.characters16; +} + +inline void VTTScanner::advance(unsigned amount) +{ + ASSERT(position() < end()); + if (m_is8Bit) + m_data.characters8 += amount; + else + m_data.characters16 += amount; +} + +} // namespace WebCore |