summaryrefslogtreecommitdiff
path: root/Source/WebCore/html/track/VTTScanner.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/html/track/VTTScanner.h')
-rw-r--r--Source/WebCore/html/track/VTTScanner.h230
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