| 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 |