Index: Source/core/html/track/vtt/VTTTokenizer.cpp |
diff --git a/Source/core/html/track/vtt/VTTTokenizer.cpp b/Source/core/html/track/vtt/VTTTokenizer.cpp |
index 9dd82a4657527a2ff9832e402c549a55a552daf7..0d84269f9a0dcba757cd064e0eab6ec0a8f81b9d 100644 |
--- a/Source/core/html/track/vtt/VTTTokenizer.cpp |
+++ b/Source/core/html/track/vtt/VTTTokenizer.cpp |
@@ -38,8 +38,15 @@ |
namespace WebCore { |
-#define WEBVTT_BEGIN_STATE(stateName) BEGIN_STATE(VTTTokenizerState, stateName) |
-#define WEBVTT_ADVANCE_TO(stateName) ADVANCE_TO(VTTTokenizerState, stateName) |
+#define WEBVTT_BEGIN_STATE(stateName) case stateName: stateName: |
+#define WEBVTT_ADVANCE_TO(stateName) \ |
+ do { \ |
+ state = stateName; \ |
+ ASSERT(!m_input.isEmpty()); \ |
+ m_inputStreamPreprocessor.advance(m_input); \ |
+ cc = m_inputStreamPreprocessor.nextInputCharacter(); \ |
+ goto stateName; \ |
+ } while (false) |
template<unsigned charactersCount> |
ALWAYS_INLINE bool equalLiteral(const StringBuilder& s, const char (&characters)[charactersCount]) |
@@ -54,32 +61,32 @@ static void addNewClass(StringBuilder& classes, const StringBuilder& newClass) |
classes.append(newClass); |
} |
+inline bool emitToken(VTTToken& resultToken, const VTTToken& token) |
+{ |
+ resultToken = token; |
+ return true; |
+} |
+ |
+inline bool advanceAndEmitToken(SegmentedString& source, VTTToken& resultToken, const VTTToken& token) |
+{ |
+ source.advanceAndUpdateLineNumber(); |
+ return emitToken(resultToken, token); |
+} |
+ |
VTTTokenizer::VTTTokenizer(const String& input) |
: m_input(input) |
, m_inputStreamPreprocessor(this) |
{ |
- reset(); |
- |
// Append a EOF marker and close the input "stream". |
ASSERT(!m_input.isClosed()); |
m_input.append(SegmentedString(String(&kEndOfFileMarker, 1))); |
m_input.close(); |
} |
-void VTTTokenizer::reset() |
-{ |
- m_token = 0; |
-} |
- |
bool VTTTokenizer::nextToken(VTTToken& token) |
{ |
- // If we have a token in progress, then we're supposed to be called back |
- // with the same token so we can finish it. |
- ASSERT(!m_token || m_token == &token); |
- m_token = &token; |
- |
if (m_input.isEmpty() || !m_inputStreamPreprocessor.peek(m_input)) |
- return haveBufferedCharacterToken(); |
+ return false; |
UChar cc = m_inputStreamPreprocessor.nextInputCharacter(); |
if (cc == kEndOfFileMarker) { |
@@ -90,13 +97,19 @@ bool VTTTokenizer::nextToken(VTTToken& token) |
StringBuilder buffer; |
StringBuilder result; |
StringBuilder classes; |
- m_state = VTTTokenizerState::DataState; |
- |
- // The ADVANCE_TO helper macros expect this name ('source') on the input variable. |
- SegmentedString& source = m_input; |
+ enum { |
+ DataState, |
+ EscapeState, |
+ TagState, |
+ StartTagState, |
+ StartTagClassState, |
+ StartTagAnnotationState, |
+ EndTagState, |
+ TimestampTagState, |
+ } state = DataState; |
// 4.8.10.13.4 WebVTT cue text tokenizer |
- switch (m_state) { |
+ switch (state) { |
WEBVTT_BEGIN_STATE(DataState) { |
if (cc == '&') { |
buffer.append(static_cast<LChar>(cc)); |
@@ -107,10 +120,10 @@ bool VTTTokenizer::nextToken(VTTToken& token) |
} else { |
// We don't want to advance input or perform a state transition - just return a (new) token. |
// (On the next call to nextToken we will see '<' again, but take the other branch in this if instead.) |
- return emitToken(VTTToken::StringToken(result.toString())); |
+ return emitToken(token, VTTToken::StringToken(result.toString())); |
} |
} else if (cc == kEndOfFileMarker) { |
- return advanceAndEmitToken(source, VTTToken::StringToken(result.toString())); |
+ return advanceAndEmitToken(m_input, token, VTTToken::StringToken(result.toString())); |
} else { |
result.append(cc); |
WEBVTT_ADVANCE_TO(DataState); |
@@ -143,10 +156,10 @@ bool VTTTokenizer::nextToken(VTTToken& token) |
WEBVTT_ADVANCE_TO(EscapeState); |
} else if (cc == '<') { |
result.append(buffer); |
- return emitToken(VTTToken::StringToken(result.toString())); |
+ return emitToken(token, VTTToken::StringToken(result.toString())); |
} else if (cc == kEndOfFileMarker) { |
result.append(buffer); |
- return advanceAndEmitToken(source, VTTToken::StringToken(result.toString())); |
+ return advanceAndEmitToken(m_input, token, VTTToken::StringToken(result.toString())); |
} else { |
result.append(buffer); |
buffer.clear(); |
@@ -175,7 +188,7 @@ bool VTTTokenizer::nextToken(VTTToken& token) |
WEBVTT_ADVANCE_TO(TimestampTagState); |
} else if (cc == '>' || cc == kEndOfFileMarker) { |
ASSERT(result.isEmpty()); |
- return advanceAndEmitToken(source, VTTToken::StartTag(result.toString())); |
+ return advanceAndEmitToken(m_input, token, VTTToken::StartTag(result.toString())); |
} else { |
result.append(cc); |
WEBVTT_ADVANCE_TO(StartTagState); |
@@ -189,7 +202,7 @@ bool VTTTokenizer::nextToken(VTTToken& token) |
} else if (cc == '.') { |
WEBVTT_ADVANCE_TO(StartTagClassState); |
} else if (cc == '>' || cc == kEndOfFileMarker) { |
- return advanceAndEmitToken(source, VTTToken::StartTag(result.toString())); |
+ return advanceAndEmitToken(m_input, token, VTTToken::StartTag(result.toString())); |
} else { |
result.append(cc); |
WEBVTT_ADVANCE_TO(StartTagState); |
@@ -209,7 +222,7 @@ bool VTTTokenizer::nextToken(VTTToken& token) |
} else if (cc == '>' || cc == kEndOfFileMarker) { |
addNewClass(classes, buffer); |
buffer.clear(); |
- return advanceAndEmitToken(source, VTTToken::StartTag(result.toString(), classes.toAtomicString())); |
+ return advanceAndEmitToken(m_input, token, VTTToken::StartTag(result.toString(), classes.toAtomicString())); |
} else { |
buffer.append(cc); |
WEBVTT_ADVANCE_TO(StartTagClassState); |
@@ -219,7 +232,7 @@ bool VTTTokenizer::nextToken(VTTToken& token) |
WEBVTT_BEGIN_STATE(StartTagAnnotationState) { |
if (cc == '>' || cc == kEndOfFileMarker) { |
- return advanceAndEmitToken(source, VTTToken::StartTag(result.toString(), classes.toAtomicString(), buffer.toAtomicString())); |
+ return advanceAndEmitToken(m_input, token, VTTToken::StartTag(result.toString(), classes.toAtomicString(), buffer.toAtomicString())); |
} |
buffer.append(cc); |
WEBVTT_ADVANCE_TO(StartTagAnnotationState); |
@@ -228,7 +241,7 @@ bool VTTTokenizer::nextToken(VTTToken& token) |
WEBVTT_BEGIN_STATE(EndTagState) { |
if (cc == '>' || cc == kEndOfFileMarker) |
- return advanceAndEmitToken(source, VTTToken::EndTag(result.toString())); |
+ return advanceAndEmitToken(m_input, token, VTTToken::EndTag(result.toString())); |
result.append(cc); |
WEBVTT_ADVANCE_TO(EndTagState); |
} |
@@ -236,7 +249,7 @@ bool VTTTokenizer::nextToken(VTTToken& token) |
WEBVTT_BEGIN_STATE(TimestampTagState) { |
if (cc == '>' || cc == kEndOfFileMarker) |
- return advanceAndEmitToken(source, VTTToken::TimestampTag(result.toString())); |
+ return advanceAndEmitToken(m_input, token, VTTToken::TimestampTag(result.toString())); |
result.append(cc); |
WEBVTT_ADVANCE_TO(TimestampTagState); |
} |