OLD | NEW |
1 /* | 1 /* |
2 Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. | 2 Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. |
3 | 3 |
4 This library is free software; you can redistribute it and/or | 4 This library is free software; you can redistribute it and/or |
5 modify it under the terms of the GNU Library General Public | 5 modify it under the terms of the GNU Library General Public |
6 License as published by the Free Software Foundation; either | 6 License as published by the Free Software Foundation; either |
7 version 2 of the License, or (at your option) any later version. | 7 version 2 of the License, or (at your option) any later version. |
8 | 8 |
9 This library is distributed in the hope that it will be useful, | 9 This library is distributed in the hope that it will be useful, |
10 but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 Library General Public License for more details. | 12 Library General Public License for more details. |
13 | 13 |
14 You should have received a copy of the GNU Library General Public License | 14 You should have received a copy of the GNU Library General Public License |
15 along with this library; see the file COPYING.LIB. If not, write to | 15 along with this library; see the file COPYING.LIB. If not, write to |
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
17 Boston, MA 02110-1301, USA. | 17 Boston, MA 02110-1301, USA. |
18 */ | 18 */ |
19 | 19 |
20 #include "config.h" | 20 #include "config.h" |
21 #include "platform/text/SegmentedString.h" | 21 #include "platform/text/SegmentedString.h" |
22 | 22 |
23 namespace blink { | 23 namespace blink { |
24 | 24 |
25 unsigned SegmentedString::length() const | 25 unsigned SegmentedString::length() const |
26 { | 26 { |
27 unsigned length = m_currentString.length(); | 27 unsigned length = m_currentString.length(); |
28 if (m_pushedChar1) { | |
29 ++length; | |
30 if (m_pushedChar2) | |
31 ++length; | |
32 } | |
33 if (isComposite()) { | 28 if (isComposite()) { |
34 Deque<SegmentedSubstring>::const_iterator it = m_substrings.begin(); | 29 Deque<SegmentedSubstring>::const_iterator it = m_substrings.begin(); |
35 Deque<SegmentedSubstring>::const_iterator e = m_substrings.end(); | 30 Deque<SegmentedSubstring>::const_iterator e = m_substrings.end(); |
36 for (; it != e; ++it) | 31 for (; it != e; ++it) |
37 length += it->length(); | 32 length += it->length(); |
38 } | 33 } |
39 return length; | 34 return length; |
40 } | 35 } |
41 | 36 |
42 void SegmentedString::setExcludeLineNumbers() | 37 void SegmentedString::setExcludeLineNumbers() |
43 { | 38 { |
44 m_currentString.setExcludeLineNumbers(); | 39 m_currentString.setExcludeLineNumbers(); |
45 if (isComposite()) { | 40 if (isComposite()) { |
46 Deque<SegmentedSubstring>::iterator it = m_substrings.begin(); | 41 Deque<SegmentedSubstring>::iterator it = m_substrings.begin(); |
47 Deque<SegmentedSubstring>::iterator e = m_substrings.end(); | 42 Deque<SegmentedSubstring>::iterator e = m_substrings.end(); |
48 for (; it != e; ++it) | 43 for (; it != e; ++it) |
49 it->setExcludeLineNumbers(); | 44 it->setExcludeLineNumbers(); |
50 } | 45 } |
51 } | 46 } |
52 | 47 |
53 void SegmentedString::clear() | 48 void SegmentedString::clear() |
54 { | 49 { |
55 m_pushedChar1 = 0; | |
56 m_pushedChar2 = 0; | |
57 m_currentChar = 0; | 50 m_currentChar = 0; |
58 m_currentString.clear(); | 51 m_currentString.clear(); |
59 m_numberOfCharactersConsumedPriorToCurrentString = 0; | 52 m_numberOfCharactersConsumedPriorToCurrentString = 0; |
60 m_numberOfCharactersConsumedPriorToCurrentLine = 0; | 53 m_numberOfCharactersConsumedPriorToCurrentLine = 0; |
61 m_currentLine = 0; | 54 m_currentLine = 0; |
62 m_substrings.clear(); | 55 m_substrings.clear(); |
63 m_closed = false; | 56 m_closed = false; |
64 m_empty = true; | 57 m_empty = true; |
65 m_fastPathFlags = NoFastPath; | 58 m_fastPathFlags = NoFastPath; |
66 m_advanceFunc = &SegmentedString::advanceEmpty; | 59 m_advanceFunc = &SegmentedString::advanceEmpty; |
67 m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceEmpty; | 60 m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceEmpty; |
68 } | 61 } |
69 | 62 |
70 void SegmentedString::append(const SegmentedSubstring& s) | 63 void SegmentedString::append(const SegmentedSubstring& s) |
71 { | 64 { |
72 ASSERT(!m_closed); | 65 ASSERT(!m_closed); |
73 if (!s.length()) | 66 if (!s.length()) |
74 return; | 67 return; |
75 | 68 |
76 if (!m_currentString.length()) { | 69 if (!m_currentString.length()) { |
77 m_numberOfCharactersConsumedPriorToCurrentString += m_currentString.numb
erOfCharactersConsumed(); | 70 m_numberOfCharactersConsumedPriorToCurrentString += m_currentString.numb
erOfCharactersConsumed(); |
78 m_currentString = s; | 71 m_currentString = s; |
79 updateAdvanceFunctionPointers(); | 72 updateAdvanceFunctionPointers(); |
80 } else { | 73 } else { |
81 m_substrings.append(s); | 74 m_substrings.append(s); |
82 } | 75 } |
83 m_empty = false; | 76 m_empty = false; |
84 } | 77 } |
85 | 78 |
| 79 void SegmentedString::push(UChar c) |
| 80 { |
| 81 ASSERT(c); |
| 82 m_currentString.push(c); |
| 83 m_currentChar = c; |
| 84 } |
| 85 |
86 void SegmentedString::prepend(const SegmentedSubstring& s) | 86 void SegmentedString::prepend(const SegmentedSubstring& s) |
87 { | 87 { |
88 ASSERT(!escaped()); | 88 ASSERT(!escaped()); |
89 ASSERT(!s.numberOfCharactersConsumed()); | 89 ASSERT(!s.numberOfCharactersConsumed()); |
90 if (!s.length()) | 90 if (!s.length()) |
91 return; | 91 return; |
92 | 92 |
93 // FIXME: We're assuming that the prepend were originally consumed by | 93 // FIXME: We're assuming that the prepend were originally consumed by |
94 // this SegmentedString. We're also ASSERTing that s is a fresh | 94 // this SegmentedString. We're also ASSERTing that s is a fresh |
95 // SegmentedSubstring. These assumptions are sufficient for our | 95 // SegmentedSubstring. These assumptions are sufficient for our |
(...skipping 16 matching lines...) Expand all Loading... |
112 void SegmentedString::close() | 112 void SegmentedString::close() |
113 { | 113 { |
114 // Closing a stream twice is likely a coding mistake. | 114 // Closing a stream twice is likely a coding mistake. |
115 ASSERT(!m_closed); | 115 ASSERT(!m_closed); |
116 m_closed = true; | 116 m_closed = true; |
117 } | 117 } |
118 | 118 |
119 void SegmentedString::append(const SegmentedString& s) | 119 void SegmentedString::append(const SegmentedString& s) |
120 { | 120 { |
121 ASSERT(!m_closed); | 121 ASSERT(!m_closed); |
122 if (s.m_pushedChar1) { | |
123 Vector<UChar, 2> unconsumedData; | |
124 unconsumedData.append(s.m_pushedChar1); | |
125 if (s.m_pushedChar2) | |
126 unconsumedData.append(s.m_pushedChar2); | |
127 append(SegmentedSubstring(String(unconsumedData))); | |
128 } | |
129 | 122 |
130 append(s.m_currentString); | 123 append(s.m_currentString); |
131 if (s.isComposite()) { | 124 if (s.isComposite()) { |
132 Deque<SegmentedSubstring>::const_iterator it = s.m_substrings.begin(); | 125 Deque<SegmentedSubstring>::const_iterator it = s.m_substrings.begin(); |
133 Deque<SegmentedSubstring>::const_iterator e = s.m_substrings.end(); | 126 Deque<SegmentedSubstring>::const_iterator e = s.m_substrings.end(); |
134 for (; it != e; ++it) | 127 for (; it != e; ++it) |
135 append(*it); | 128 append(*it); |
136 } | 129 } |
137 m_currentChar = m_pushedChar1 ? m_pushedChar1 : (m_currentString.length() ?
m_currentString.getCurrentChar() : 0); | 130 m_currentChar = m_currentString.length() ? m_currentString.getCurrentChar()
: 0; |
138 } | 131 } |
139 | 132 |
140 void SegmentedString::prepend(const SegmentedString& s) | 133 void SegmentedString::prepend(const SegmentedString& s) |
141 { | 134 { |
142 ASSERT(!escaped()); | 135 ASSERT(!escaped()); |
143 ASSERT(!s.escaped()); | 136 ASSERT(!s.escaped()); |
144 if (s.isComposite()) { | 137 if (s.isComposite()) { |
145 Deque<SegmentedSubstring>::const_reverse_iterator it = s.m_substrings.rb
egin(); | 138 Deque<SegmentedSubstring>::const_reverse_iterator it = s.m_substrings.rb
egin(); |
146 Deque<SegmentedSubstring>::const_reverse_iterator e = s.m_substrings.ren
d(); | 139 Deque<SegmentedSubstring>::const_reverse_iterator e = s.m_substrings.ren
d(); |
147 for (; it != e; ++it) | 140 for (; it != e; ++it) |
(...skipping 18 matching lines...) Expand all Loading... |
166 m_empty = true; | 159 m_empty = true; |
167 m_fastPathFlags = NoFastPath; | 160 m_fastPathFlags = NoFastPath; |
168 m_advanceFunc = &SegmentedString::advanceEmpty; | 161 m_advanceFunc = &SegmentedString::advanceEmpty; |
169 m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceEmpty; | 162 m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceEmpty; |
170 } | 163 } |
171 } | 164 } |
172 | 165 |
173 String SegmentedString::toString() const | 166 String SegmentedString::toString() const |
174 { | 167 { |
175 StringBuilder result; | 168 StringBuilder result; |
176 if (m_pushedChar1) { | |
177 result.append(m_pushedChar1); | |
178 if (m_pushedChar2) | |
179 result.append(m_pushedChar2); | |
180 } | |
181 m_currentString.appendTo(result); | 169 m_currentString.appendTo(result); |
182 if (isComposite()) { | 170 if (isComposite()) { |
183 Deque<SegmentedSubstring>::const_iterator it = m_substrings.begin(); | 171 Deque<SegmentedSubstring>::const_iterator it = m_substrings.begin(); |
184 Deque<SegmentedSubstring>::const_iterator e = m_substrings.end(); | 172 Deque<SegmentedSubstring>::const_iterator e = m_substrings.end(); |
185 for (; it != e; ++it) | 173 for (; it != e; ++it) |
186 it->appendTo(result); | 174 it->appendTo(result); |
187 } | 175 } |
188 return result.toString(); | 176 return result.toString(); |
189 } | 177 } |
190 | 178 |
191 void SegmentedString::advance(unsigned count, UChar* consumedCharacters) | 179 void SegmentedString::advance(unsigned count, UChar* consumedCharacters) |
192 { | 180 { |
193 ASSERT_WITH_SECURITY_IMPLICATION(count <= length()); | 181 ASSERT_WITH_SECURITY_IMPLICATION(count <= length()); |
194 for (unsigned i = 0; i < count; ++i) { | 182 for (unsigned i = 0; i < count; ++i) { |
195 consumedCharacters[i] = currentChar(); | 183 consumedCharacters[i] = currentChar(); |
196 advance(); | 184 advance(); |
197 } | 185 } |
198 } | 186 } |
199 | 187 |
200 void SegmentedString::advance8() | 188 void SegmentedString::advance8() |
201 { | 189 { |
202 ASSERT(!m_pushedChar1); | |
203 decrementAndCheckLength(); | 190 decrementAndCheckLength(); |
204 m_currentChar = m_currentString.incrementAndGetCurrentChar8(); | 191 m_currentChar = m_currentString.incrementAndGetCurrentChar8(); |
205 } | 192 } |
206 | 193 |
207 void SegmentedString::advance16() | 194 void SegmentedString::advance16() |
208 { | 195 { |
209 ASSERT(!m_pushedChar1); | |
210 decrementAndCheckLength(); | 196 decrementAndCheckLength(); |
211 m_currentChar = m_currentString.incrementAndGetCurrentChar16(); | 197 m_currentChar = m_currentString.incrementAndGetCurrentChar16(); |
212 } | 198 } |
213 | 199 |
214 void SegmentedString::advanceAndUpdateLineNumber8() | 200 void SegmentedString::advanceAndUpdateLineNumber8() |
215 { | 201 { |
216 ASSERT(!m_pushedChar1); | |
217 ASSERT(m_currentString.getCurrentChar() == m_currentChar); | 202 ASSERT(m_currentString.getCurrentChar() == m_currentChar); |
218 if (m_currentChar == '\n') { | 203 if (m_currentChar == '\n') { |
219 ++m_currentLine; | 204 ++m_currentLine; |
220 m_numberOfCharactersConsumedPriorToCurrentLine = numberOfCharactersConsu
med() + 1; | 205 m_numberOfCharactersConsumedPriorToCurrentLine = numberOfCharactersConsu
med() + 1; |
221 } | 206 } |
222 decrementAndCheckLength(); | 207 decrementAndCheckLength(); |
223 m_currentChar = m_currentString.incrementAndGetCurrentChar8(); | 208 m_currentChar = m_currentString.incrementAndGetCurrentChar8(); |
224 } | 209 } |
225 | 210 |
226 void SegmentedString::advanceAndUpdateLineNumber16() | 211 void SegmentedString::advanceAndUpdateLineNumber16() |
227 { | 212 { |
228 ASSERT(!m_pushedChar1); | |
229 ASSERT(m_currentString.getCurrentChar() == m_currentChar); | 213 ASSERT(m_currentString.getCurrentChar() == m_currentChar); |
230 if (m_currentChar == '\n') { | 214 if (m_currentChar == '\n') { |
231 ++m_currentLine; | 215 ++m_currentLine; |
232 m_numberOfCharactersConsumedPriorToCurrentLine = numberOfCharactersConsu
med() + 1; | 216 m_numberOfCharactersConsumedPriorToCurrentLine = numberOfCharactersConsu
med() + 1; |
233 } | 217 } |
234 decrementAndCheckLength(); | 218 decrementAndCheckLength(); |
235 m_currentChar = m_currentString.incrementAndGetCurrentChar16(); | 219 m_currentChar = m_currentString.incrementAndGetCurrentChar16(); |
236 } | 220 } |
237 | 221 |
238 void SegmentedString::advanceSlowCase() | 222 void SegmentedString::advanceSlowCase() |
239 { | 223 { |
240 if (m_pushedChar1) { | 224 if (m_currentString.length()) { |
241 m_pushedChar1 = m_pushedChar2; | |
242 m_pushedChar2 = 0; | |
243 | |
244 if (m_pushedChar1) { | |
245 m_currentChar = m_pushedChar1; | |
246 return; | |
247 } | |
248 | |
249 updateAdvanceFunctionPointers(); | |
250 } else if (m_currentString.length()) { | |
251 m_currentString.decrementLength(); | 225 m_currentString.decrementLength(); |
252 if (!m_currentString.length()) | 226 if (!m_currentString.length()) |
253 advanceSubstring(); | 227 advanceSubstring(); |
254 } else if (!isComposite()) { | 228 } else if (!isComposite()) { |
255 m_currentString.clear(); | 229 m_currentString.clear(); |
256 m_empty = true; | 230 m_empty = true; |
257 m_fastPathFlags = NoFastPath; | 231 m_fastPathFlags = NoFastPath; |
258 m_advanceFunc = &SegmentedString::advanceEmpty; | 232 m_advanceFunc = &SegmentedString::advanceEmpty; |
259 m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceEmpty; | 233 m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceEmpty; |
260 } | 234 } |
261 m_currentChar = m_currentString.length() ? m_currentString.getCurrentChar()
: 0; | 235 m_currentChar = m_currentString.length() ? m_currentString.getCurrentChar()
: 0; |
262 } | 236 } |
263 | 237 |
264 void SegmentedString::advanceAndUpdateLineNumberSlowCase() | 238 void SegmentedString::advanceAndUpdateLineNumberSlowCase() |
265 { | 239 { |
266 if (m_pushedChar1) { | 240 if (m_currentString.length()) { |
267 m_pushedChar1 = m_pushedChar2; | |
268 m_pushedChar2 = 0; | |
269 | |
270 if (m_pushedChar1) { | |
271 m_currentChar = m_pushedChar1; | |
272 return; | |
273 } | |
274 | |
275 updateAdvanceFunctionPointers(); | |
276 } else if (m_currentString.length()) { | |
277 if (m_currentString.getCurrentChar() == '\n' && m_currentString.doNotExc
ludeLineNumbers()) { | 241 if (m_currentString.getCurrentChar() == '\n' && m_currentString.doNotExc
ludeLineNumbers()) { |
278 ++m_currentLine; | 242 ++m_currentLine; |
279 // Plus 1 because numberOfCharactersConsumed value hasn't incremente
d yet; it does with length() decrement below. | 243 // Plus 1 because numberOfCharactersConsumed value hasn't incremente
d yet; it does with length() decrement below. |
280 m_numberOfCharactersConsumedPriorToCurrentLine = numberOfCharactersC
onsumed() + 1; | 244 m_numberOfCharactersConsumedPriorToCurrentLine = numberOfCharactersC
onsumed() + 1; |
281 } | 245 } |
282 m_currentString.decrementLength(); | 246 m_currentString.decrementLength(); |
283 if (!m_currentString.length()) | 247 if (!m_currentString.length()) |
284 advanceSubstring(); | 248 advanceSubstring(); |
285 else | 249 else |
286 m_currentString.incrementAndGetCurrentChar(); // Only need the ++ | 250 m_currentString.incrementAndGetCurrentChar(); // Only need the ++ |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
319 return OrdinalNumber::fromZeroBasedInt(zeroBasedColumn); | 283 return OrdinalNumber::fromZeroBasedInt(zeroBasedColumn); |
320 } | 284 } |
321 | 285 |
322 void SegmentedString::setCurrentPosition(OrdinalNumber line, OrdinalNumber colum
nAftreProlog, int prologLength) | 286 void SegmentedString::setCurrentPosition(OrdinalNumber line, OrdinalNumber colum
nAftreProlog, int prologLength) |
323 { | 287 { |
324 m_currentLine = line.zeroBasedInt(); | 288 m_currentLine = line.zeroBasedInt(); |
325 m_numberOfCharactersConsumedPriorToCurrentLine = numberOfCharactersConsumed(
) + prologLength - columnAftreProlog.zeroBasedInt(); | 289 m_numberOfCharactersConsumedPriorToCurrentLine = numberOfCharactersConsumed(
) + prologLength - columnAftreProlog.zeroBasedInt(); |
326 } | 290 } |
327 | 291 |
328 } | 292 } |
OLD | NEW |