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..6c1a69a577ee23126612e0241498beb58f2d4e22 |
--- /dev/null |
+++ b/Source/core/html/track/vtt/VTTScanner.h |
@@ -0,0 +1,221 @@ |
+/* |
+ * 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 { |
+ 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 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(); |
+ |
+ // 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; |
+}; |
+ |
+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) |
+ ::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() |
+{ |
+ if (m_is8Bit) { |
+ const LChar* current = m_data.characters8; |
+ ::skipWhile<LChar, LCharPredicateAdapter<characterPredicate> >(current, m_end.characters8); |
+ return Run(position(), current, m_is8Bit); |
+ } |
+ const UChar* current = m_data.characters16; |
+ ::skipWhile<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; |
+} |
+ |
+// 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 |