2
* Copyright (C) 2010 Google, Inc. All Rights Reserved.
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions
7
* 1. Redistributions of source code must retain the above copyright
8
* notice, this list of conditions and the following disclaimer.
9
* 2. Redistributions in binary form must reproduce the above copyright
10
* notice, this list of conditions and the following disclaimer in the
11
* documentation and/or other materials provided with the distribution.
13
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
#ifndef HTMLInputStream_h
27
#define HTMLInputStream_h
29
#include "SegmentedString.h"
33
// The InputStream is made up of a sequence of SegmentedStrings:
35
// [--current--][--next--][--next--] ... [--next--]
36
// /\ (also called m_last)
37
// L_ current insertion point
39
// The current segmented string is stored in InputStream. Each of the
40
// afterInsertionPoint buffers are stored in InsertionPointRecords on the
43
// We remove characters from the "current" string in the InputStream.
44
// document.write() will add characters at the current insertion point,
45
// which appends them to the "current" string.
47
// m_last is a pointer to the last of the afterInsertionPoint strings.
48
// The network adds data at the end of the InputStream, which appends
49
// them to the "last" string.
50
class HTMLInputStream {
51
WTF_MAKE_NONCOPYABLE(HTMLInputStream);
58
void appendToEnd(const SegmentedString& string)
60
m_last->append(string);
63
void insertAtCurrentInsertionPoint(const SegmentedString& string)
65
m_first.append(string);
68
bool hasInsertionPoint() const
70
return &m_first != m_last;
75
// FIXME: This should use InputStreamPreprocessor::endOfFileMarker
76
// once InputStreamPreprocessor is split off into its own header.
77
static const LChar endOfFileMarker = 0;
78
m_last->append(SegmentedString(String(&endOfFileMarker, 1)));
82
bool haveSeenEndOfFile() const
84
return m_last->isClosed();
87
SegmentedString& current() { return m_first; }
88
const SegmentedString& current() const { return m_first; }
90
void splitInto(SegmentedString& next)
93
m_first = SegmentedString();
94
if (m_last == &m_first) {
95
// We used to only have one SegmentedString in the InputStream
96
// but now we have two. That means m_first is no longer also
97
// the m_last string, |next| is now the last one.
102
void mergeFrom(SegmentedString& next)
104
m_first.append(next);
105
if (m_last == &next) {
106
// The string |next| used to be the last SegmentedString in
107
// the InputStream. Now that it's been merged into m_first,
108
// that makes m_first the last one.
111
if (next.isClosed()) {
112
// We also need to merge the "closed" state from next to
113
// m_first. Arguably, this work could be done in append().
119
SegmentedString m_first;
120
SegmentedString* m_last;
123
class InsertionPointRecord {
124
WTF_MAKE_NONCOPYABLE(InsertionPointRecord);
126
explicit InsertionPointRecord(HTMLInputStream& inputStream)
127
: m_inputStream(&inputStream)
129
m_line = m_inputStream->current().currentLine();
130
m_column = m_inputStream->current().currentColumn();
131
m_inputStream->splitInto(m_next);
132
// We 'fork' current position and use it for the generated script part.
133
// This is a bit weird, because generated part does not have positions within an HTML document.
134
m_inputStream->current().setCurrentPosition(m_line, m_column, 0);
137
~InsertionPointRecord()
139
// Some inserted text may have remained in input stream. E.g. if script has written "&" or "<table",
140
// it stays in buffer because it cannot be properly tokenized before we see next part.
141
int unparsedRemainderLength = m_inputStream->current().length();
142
m_inputStream->mergeFrom(m_next);
143
// We restore position for the character that goes right after unparsed remainder.
144
m_inputStream->current().setCurrentPosition(m_line, m_column, unparsedRemainderLength);
148
HTMLInputStream* m_inputStream;
149
SegmentedString m_next;
150
OrdinalNumber m_line;
151
OrdinalNumber m_column;