Chromium Code Reviews| Index: Source/core/html/track/vtt/VTTScanner.h |
| diff --git a/Source/core/html/track/vtt/VTTScanner.h b/Source/core/html/track/vtt/VTTScanner.h |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..8165b671546c924c1f3c6c033e5b2861747feb41 |
| --- /dev/null |
| +++ b/Source/core/html/track/vtt/VTTScanner.h |
| @@ -0,0 +1,219 @@ |
| +/* |
| + * 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. |
| + */ |
| + |
| +#ifndef VTTScanner_h |
| +#define VTTScanner_h |
| + |
| +#include "platform/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 { |
|
jochen (gone - plz use gerrit)
2014/01/03 11:02:24
can you make this class non-copiable as well?
|
| +public: |
| + VTTScanner(const String& line); |
|
jochen (gone - plz use gerrit)
2014/01/03 11:02:24
explicit
|
| + |
| + typedef const LChar* Position; |
| + |
| + struct Run { |
|
jochen (gone - plz use gerrit)
2014/01/03 11:02:24
this is really a class with all the fancy methods
|
| + Run(Position start, Position end, bool is8Bit) |
| + : start(start), end(end), is8Bit(is8Bit) { } |
| + |
| + bool isEmpty() const { return start == end; } |
| + size_t length() const; |
| + |
| + Position start; |
| + Position end; |
| + bool 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(); |
| + |
| + // 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(); |
| + |
| + // 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); |
| + |
| +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; |
|
jochen (gone - plz use gerrit)
2014/01/03 11:02:24
it would be nicer if you had accessors and made th
|
| +}; |
| + |
| +inline size_t VTTScanner::Run::length() const |
| +{ |
| + if (is8Bit) |
| + return end - start; |
| + return reinterpret_cast<const UChar*>(end) - reinterpret_cast<const UChar*>(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) |
| + ::skipWhile<LChar, LCharPredicateAdapter<characterPredicate> >(m_data.characters8, m_end.characters8); |
| + else |
| + ::skipWhile<UChar, characterPredicate>(m_data.characters16, m_end.characters16); |
| +} |
| + |
| +template<bool characterPredicate(UChar)> |
| +inline VTTScanner::Run VTTScanner::collectWhile() |
| +{ |
| + Run run(position(), position(), m_is8Bit); |
| + if (m_is8Bit) { |
| + const LChar* current = m_data.characters8; |
| + ::skipWhile<LChar, LCharPredicateAdapter<characterPredicate> >(current, m_end.characters8); |
| + run.end = current; |
| + } else { |
| + const UChar* current = m_data.characters16; |
| + ::skipWhile<UChar, characterPredicate>(current, m_end.characters16); |
| + run.end = reinterpret_cast<Position>(current); |
| + } |
| + return run; |
| +} |
| + |
| +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; |
| +} |
| + |
| +// Wrapper of VTTScanner that allows easy interaction with a parsing model |
| +// where a <String, index> tuple is used. |
| +class VTTLegacyScanner : public VTTScanner { |
| + WTF_MAKE_NONCOPYABLE(VTTLegacyScanner); |
| +public: |
| + VTTLegacyScanner(const String& line, unsigned* outPosition) |
| + : VTTScanner(line) |
| + , m_outPosition(outPosition) |
| + { |
| + ASSERT(outPosition && *outPosition <= line.length()); |
| + // Adjust state according to |*outPosition|. |
| + advance(*outPosition); |
| + // Save the start position to allow adjusting |*outPosition|. |
| + if (m_is8Bit) |
| + m_start.characters8 = m_data.characters8; |
| + else |
| + m_start.characters16 = m_data.characters16; |
| + } |
| + ~VTTLegacyScanner() |
| + { |
| + // "Export" the updated position. |
| + unsigned advancedChars = m_is8Bit ? m_data.characters8 - m_start.characters8 : m_data.characters16 - m_start.characters16; |
| + *m_outPosition += advancedChars; |
| + } |
| + |
| +private: |
| + unsigned* m_outPosition; |
| + union { |
| + const LChar* characters8; |
| + const UChar* characters16; |
| + } m_start; |
| +}; |
| + |
| +} |
| + |
| +#endif |