OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2010 Google, Inc. All Rights Reserved. | 2 * Copyright (C) 2010 Google, Inc. All Rights Reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 21 matching lines...) Expand all Loading... |
32 | 32 |
33 namespace blink { | 33 namespace blink { |
34 | 34 |
35 // The InputStream is made up of a sequence of SegmentedStrings: | 35 // The InputStream is made up of a sequence of SegmentedStrings: |
36 // | 36 // |
37 // [--current--][--next--][--next--] ... [--next--] | 37 // [--current--][--next--][--next--] ... [--next--] |
38 // /\ (also called m_last) | 38 // /\ (also called m_last) |
39 // L_ current insertion point | 39 // L_ current insertion point |
40 // | 40 // |
41 // The current segmented string is stored in InputStream. Each of the | 41 // The current segmented string is stored in InputStream. Each of the |
42 // afterInsertionPoint buffers are stored in InsertionPointRecords on the | 42 // afterInsertionPoint buffers are stored in InsertionPointRecords on the stack. |
43 // stack. | |
44 // | 43 // |
45 // We remove characters from the "current" string in the InputStream. | 44 // We remove characters from the "current" string in the InputStream. |
46 // document.write() will add characters at the current insertion point, | 45 // document.write() will add characters at the current insertion point, which |
47 // which appends them to the "current" string. | 46 // appends them to the "current" string. |
48 // | 47 // |
49 // m_last is a pointer to the last of the afterInsertionPoint strings. | 48 // m_last is a pointer to the last of the afterInsertionPoint strings. The |
50 // The network adds data at the end of the InputStream, which appends | 49 // network adds data at the end of the InputStream, which appends them to the |
51 // them to the "last" string. | 50 // "last" string. |
52 class HTMLInputStream { | 51 class HTMLInputStream { |
53 DISALLOW_NEW(); | 52 DISALLOW_NEW(); |
54 WTF_MAKE_NONCOPYABLE(HTMLInputStream); | 53 WTF_MAKE_NONCOPYABLE(HTMLInputStream); |
55 | 54 |
56 public: | 55 public: |
57 HTMLInputStream() : m_last(&m_first) {} | 56 HTMLInputStream() : m_last(&m_first) {} |
58 | 57 |
59 void appendToEnd(const SegmentedString& string) { m_last->append(string); } | 58 void appendToEnd(const SegmentedString& string) { m_last->append(string); } |
60 | 59 |
61 void insertAtCurrentInsertionPoint(const SegmentedString& string) { | 60 void insertAtCurrentInsertionPoint(const SegmentedString& string) { |
(...skipping 11 matching lines...) Expand all Loading... |
73 | 72 |
74 bool haveSeenEndOfFile() const { return m_last->isClosed(); } | 73 bool haveSeenEndOfFile() const { return m_last->isClosed(); } |
75 | 74 |
76 SegmentedString& current() { return m_first; } | 75 SegmentedString& current() { return m_first; } |
77 const SegmentedString& current() const { return m_first; } | 76 const SegmentedString& current() const { return m_first; } |
78 | 77 |
79 void splitInto(SegmentedString& next) { | 78 void splitInto(SegmentedString& next) { |
80 next = m_first; | 79 next = m_first; |
81 m_first = SegmentedString(); | 80 m_first = SegmentedString(); |
82 if (m_last == &m_first) { | 81 if (m_last == &m_first) { |
83 // We used to only have one SegmentedString in the InputStream | 82 // We used to only have one SegmentedString in the InputStream but now we |
84 // but now we have two. That means m_first is no longer also | 83 // have two. That means m_first is no longer also the m_last string, |
85 // the m_last string, |next| is now the last one. | 84 // |next| is now the last one. |
86 m_last = &next; | 85 m_last = &next; |
87 } | 86 } |
88 } | 87 } |
89 | 88 |
90 void mergeFrom(SegmentedString& next) { | 89 void mergeFrom(SegmentedString& next) { |
91 m_first.append(next); | 90 m_first.append(next); |
92 if (m_last == &next) { | 91 if (m_last == &next) { |
93 // The string |next| used to be the last SegmentedString in | 92 // The string |next| used to be the last SegmentedString in |
94 // the InputStream. Now that it's been merged into m_first, | 93 // the InputStream. Now that it's been merged into m_first, |
95 // that makes m_first the last one. | 94 // that makes m_first the last one. |
96 m_last = &m_first; | 95 m_last = &m_first; |
97 } | 96 } |
98 if (next.isClosed()) { | 97 if (next.isClosed()) { |
99 // We also need to merge the "closed" state from next to | 98 // We also need to merge the "closed" state from next to m_first. |
100 // m_first. Arguably, this work could be done in append(). | 99 // Arguably, this work could be done in append(). |
101 m_first.close(); | 100 m_first.close(); |
102 } | 101 } |
103 } | 102 } |
104 | 103 |
105 private: | 104 private: |
106 SegmentedString m_first; | 105 SegmentedString m_first; |
107 SegmentedString* m_last; | 106 SegmentedString* m_last; |
108 }; | 107 }; |
109 | 108 |
110 class InsertionPointRecord { | 109 class InsertionPointRecord { |
111 STACK_ALLOCATED(); | 110 STACK_ALLOCATED(); |
112 WTF_MAKE_NONCOPYABLE(InsertionPointRecord); | 111 WTF_MAKE_NONCOPYABLE(InsertionPointRecord); |
113 | 112 |
114 public: | 113 public: |
115 explicit InsertionPointRecord(HTMLInputStream& inputStream) | 114 explicit InsertionPointRecord(HTMLInputStream& inputStream) |
116 : m_inputStream(&inputStream) { | 115 : m_inputStream(&inputStream) { |
117 m_line = m_inputStream->current().currentLine(); | 116 m_line = m_inputStream->current().currentLine(); |
118 m_column = m_inputStream->current().currentColumn(); | 117 m_column = m_inputStream->current().currentColumn(); |
119 m_inputStream->splitInto(m_next); | 118 m_inputStream->splitInto(m_next); |
120 // We 'fork' current position and use it for the generated script part. | 119 // We 'fork' current position and use it for the generated script part. This |
121 // This is a bit weird, because generated part does not have positions withi
n an HTML document. | 120 // is a bit weird, because generated part does not have positions within an |
| 121 // HTML document. |
122 m_inputStream->current().setCurrentPosition(m_line, m_column, 0); | 122 m_inputStream->current().setCurrentPosition(m_line, m_column, 0); |
123 } | 123 } |
124 | 124 |
125 ~InsertionPointRecord() { | 125 ~InsertionPointRecord() { |
126 // Some inserted text may have remained in input stream. E.g. if script has
written "&" or "<table", | 126 // Some inserted text may have remained in input stream. E.g. if script has |
127 // it stays in buffer because it cannot be properly tokenized before we see
next part. | 127 // written "&" or "<table", it stays in buffer because it cannot be |
| 128 // properly tokenized before we see next part. |
128 int unparsedRemainderLength = m_inputStream->current().length(); | 129 int unparsedRemainderLength = m_inputStream->current().length(); |
129 m_inputStream->mergeFrom(m_next); | 130 m_inputStream->mergeFrom(m_next); |
130 // We restore position for the character that goes right after unparsed rema
inder. | 131 // We restore position for the character that goes right after unparsed |
| 132 // remainder. |
131 m_inputStream->current().setCurrentPosition(m_line, m_column, | 133 m_inputStream->current().setCurrentPosition(m_line, m_column, |
132 unparsedRemainderLength); | 134 unparsedRemainderLength); |
133 } | 135 } |
134 | 136 |
135 private: | 137 private: |
136 HTMLInputStream* m_inputStream; | 138 HTMLInputStream* m_inputStream; |
137 SegmentedString m_next; | 139 SegmentedString m_next; |
138 OrdinalNumber m_line; | 140 OrdinalNumber m_line; |
139 OrdinalNumber m_column; | 141 OrdinalNumber m_column; |
140 }; | 142 }; |
141 | 143 |
142 } // namespace blink | 144 } // namespace blink |
143 | 145 |
144 #endif | 146 #endif // HTMLInputStream_h |
OLD | NEW |