Cleanups for VTTTokenizer

Get rid of VTTTokenizer::m_token, and hence remove the need to play
games with pointers to the resulting token, since the token is now
produced at the end of VTTTokenizer::nextToken. This renders the reset()
method empty (and it wasn't previously used outside of VTTTokenizer), so
remove it.

Make a local, tailored, version of the ADVANCE_TO macro to get rid of the
redundant check of advance(). This in turn allows removing the (now
useless) part of the scaffolding which is haveBufferedCharacterToken(),
as well as turning VTTTokenizer::m_state into the local 'state' and
moving the definition of the state enumeration into the cpp-file.
This also means the state defintions can be moved from the header-file,
so do that as well.

BUG=319391

Review URL: https://codereview.chromium.org/98763004

git-svn-id: svn://svn.chromium.org/blink/trunk@162994 bbb929c8-8fbe-4397-9dbb-9b2b20218538
diff --git a/Source/core/html/track/vtt/VTTTokenizer.cpp b/Source/core/html/track/vtt/VTTTokenizer.cpp
index 9dd82a4..0d84269 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 @@
     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 @@
     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 @@
                 } 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 @@
                 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 @@
                 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 @@
             } 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 @@
             } 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 @@
 
         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 @@
 
         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 @@
 
         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);
         }
diff --git a/Source/core/html/track/vtt/VTTTokenizer.h b/Source/core/html/track/vtt/VTTTokenizer.h
index a5862b5..abc05e2 100644
--- a/Source/core/html/track/vtt/VTTTokenizer.h
+++ b/Source/core/html/track/vtt/VTTTokenizer.h
@@ -33,60 +33,19 @@
 
 #include "core/html/parser/InputStreamPreprocessor.h"
 #include "core/html/track/vtt/VTTToken.h"
-#include "wtf/PassOwnPtr.h"
 
 namespace WebCore {
 
-class VTTTokenizerState {
-public:
-    enum State {
-        DataState,
-        EscapeState,
-        TagState,
-        StartTagState,
-        StartTagClassState,
-        StartTagAnnotationState,
-        EndTagState,
-        TimestampTagState,
-    };
-};
-
 class VTTTokenizer {
     WTF_MAKE_NONCOPYABLE(VTTTokenizer);
 public:
     explicit VTTTokenizer(const String& input);
 
-    typedef VTTTokenizerState State;
-
-    void reset();
-
     bool nextToken(VTTToken&);
 
-    inline bool haveBufferedCharacterToken() { return false; }
-
-    inline bool advanceAndEmitToken(SegmentedString& source, const VTTToken& token)
-    {
-        source.advanceAndUpdateLineNumber();
-        return emitToken(token);
-    }
-
-    inline bool emitToken(const VTTToken& token)
-    {
-        *m_token = token;
-        return true;
-    }
-
-    bool shouldSkipNullCharacters() const { return true; }
+    inline bool shouldSkipNullCharacters() const { return true; }
 
 private:
-    // m_token is owned by the caller. If nextToken is not on the stack,
-    // this member might be pointing to unallocated memory.
-    VTTToken* m_token;
-
-    // This member does not really need to be an instance member - it's only used in nextToken.
-    // The reason it's stored here is because of the use of the ADVANCE_TO state helpers.
-    VTTTokenizerState::State m_state;
-
     SegmentedString m_input;
 
     // ://www.whatwg.org/specs/web-apps/current-work/#preprocessing-the-input-stream