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.m_length; | 27 unsigned length = m_currentString.length(); |
28 if (m_pushedChar1) { | 28 if (m_pushedChar1) { |
29 ++length; | 29 ++length; |
30 if (m_pushedChar2) | 30 if (m_pushedChar2) |
31 ++length; | 31 ++length; |
32 } | 32 } |
33 if (isComposite()) { | 33 if (isComposite()) { |
34 Deque<SegmentedSubstring>::const_iterator it = m_substrings.begin(); | 34 Deque<SegmentedSubstring>::const_iterator it = m_substrings.begin(); |
35 Deque<SegmentedSubstring>::const_iterator e = m_substrings.end(); | 35 Deque<SegmentedSubstring>::const_iterator e = m_substrings.end(); |
36 for (; it != e; ++it) | 36 for (; it != e; ++it) |
37 length += it->m_length; | 37 length += it->length(); |
38 } | 38 } |
39 return length; | 39 return length; |
40 } | 40 } |
41 | 41 |
42 void SegmentedString::setExcludeLineNumbers() | 42 void SegmentedString::setExcludeLineNumbers() |
43 { | 43 { |
44 m_currentString.setExcludeLineNumbers(); | 44 m_currentString.setExcludeLineNumbers(); |
45 if (isComposite()) { | 45 if (isComposite()) { |
46 Deque<SegmentedSubstring>::iterator it = m_substrings.begin(); | 46 Deque<SegmentedSubstring>::iterator it = m_substrings.begin(); |
47 Deque<SegmentedSubstring>::iterator e = m_substrings.end(); | 47 Deque<SegmentedSubstring>::iterator e = m_substrings.end(); |
(...skipping 15 matching lines...) Expand all Loading... |
63 m_closed = false; | 63 m_closed = false; |
64 m_empty = true; | 64 m_empty = true; |
65 m_fastPathFlags = NoFastPath; | 65 m_fastPathFlags = NoFastPath; |
66 m_advanceFunc = &SegmentedString::advanceEmpty; | 66 m_advanceFunc = &SegmentedString::advanceEmpty; |
67 m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceEmpty; | 67 m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceEmpty; |
68 } | 68 } |
69 | 69 |
70 void SegmentedString::append(const SegmentedSubstring& s) | 70 void SegmentedString::append(const SegmentedSubstring& s) |
71 { | 71 { |
72 ASSERT(!m_closed); | 72 ASSERT(!m_closed); |
73 if (!s.m_length) | 73 if (!s.length()) |
74 return; | 74 return; |
75 | 75 |
76 if (!m_currentString.m_length) { | 76 if (!m_currentString.length()) { |
77 m_numberOfCharactersConsumedPriorToCurrentString += m_currentString.numb
erOfCharactersConsumed(); | 77 m_numberOfCharactersConsumedPriorToCurrentString += m_currentString.numb
erOfCharactersConsumed(); |
78 m_currentString = s; | 78 m_currentString = s; |
79 updateAdvanceFunctionPointers(); | 79 updateAdvanceFunctionPointers(); |
80 } else { | 80 } else { |
81 m_substrings.append(s); | 81 m_substrings.append(s); |
82 } | 82 } |
83 m_empty = false; | 83 m_empty = false; |
84 } | 84 } |
85 | 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.m_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 |
96 // current use, but we might need to handle the more elaborate | 96 // current use, but we might need to handle the more elaborate |
97 // cases in the future. | 97 // cases in the future. |
98 m_numberOfCharactersConsumedPriorToCurrentString += m_currentString.numberOf
CharactersConsumed(); | 98 m_numberOfCharactersConsumedPriorToCurrentString += m_currentString.numberOf
CharactersConsumed(); |
99 m_numberOfCharactersConsumedPriorToCurrentString -= s.m_length; | 99 m_numberOfCharactersConsumedPriorToCurrentString -= s.length(); |
100 if (!m_currentString.m_length) { | 100 if (!m_currentString.length()) { |
101 m_currentString = s; | 101 m_currentString = s; |
102 updateAdvanceFunctionPointers(); | 102 updateAdvanceFunctionPointers(); |
103 } else { | 103 } else { |
104 // Shift our m_currentString into our list. | 104 // Shift our m_currentString into our list. |
105 m_substrings.prepend(m_currentString); | 105 m_substrings.prepend(m_currentString); |
106 m_currentString = s; | 106 m_currentString = s; |
107 updateAdvanceFunctionPointers(); | 107 updateAdvanceFunctionPointers(); |
108 } | 108 } |
109 m_empty = false; | 109 m_empty = false; |
110 } | 110 } |
(...skipping 16 matching lines...) Expand all Loading... |
127 append(SegmentedSubstring(String(unconsumedData))); | 127 append(SegmentedSubstring(String(unconsumedData))); |
128 } | 128 } |
129 | 129 |
130 append(s.m_currentString); | 130 append(s.m_currentString); |
131 if (s.isComposite()) { | 131 if (s.isComposite()) { |
132 Deque<SegmentedSubstring>::const_iterator it = s.m_substrings.begin(); | 132 Deque<SegmentedSubstring>::const_iterator it = s.m_substrings.begin(); |
133 Deque<SegmentedSubstring>::const_iterator e = s.m_substrings.end(); | 133 Deque<SegmentedSubstring>::const_iterator e = s.m_substrings.end(); |
134 for (; it != e; ++it) | 134 for (; it != e; ++it) |
135 append(*it); | 135 append(*it); |
136 } | 136 } |
137 m_currentChar = m_pushedChar1 ? m_pushedChar1 : (m_currentString.m_length ?
m_currentString.getCurrentChar() : 0); | 137 m_currentChar = m_pushedChar1 ? m_pushedChar1 : (m_currentString.length() ?
m_currentString.getCurrentChar() : 0); |
138 } | 138 } |
139 | 139 |
140 void SegmentedString::prepend(const SegmentedString& s) | 140 void SegmentedString::prepend(const SegmentedString& s) |
141 { | 141 { |
142 ASSERT(!escaped()); | 142 ASSERT(!escaped()); |
143 ASSERT(!s.escaped()); | 143 ASSERT(!s.escaped()); |
144 if (s.isComposite()) { | 144 if (s.isComposite()) { |
145 Deque<SegmentedSubstring>::const_reverse_iterator it = s.m_substrings.rb
egin(); | 145 Deque<SegmentedSubstring>::const_reverse_iterator it = s.m_substrings.rb
egin(); |
146 Deque<SegmentedSubstring>::const_reverse_iterator e = s.m_substrings.ren
d(); | 146 Deque<SegmentedSubstring>::const_reverse_iterator e = s.m_substrings.ren
d(); |
147 for (; it != e; ++it) | 147 for (; it != e; ++it) |
148 prepend(*it); | 148 prepend(*it); |
149 } | 149 } |
150 prepend(s.m_currentString); | 150 prepend(s.m_currentString); |
151 m_currentChar = m_currentString.m_length ? m_currentString.getCurrentChar()
: 0; | 151 m_currentChar = m_currentString.length() ? m_currentString.getCurrentChar()
: 0; |
152 } | 152 } |
153 | 153 |
154 void SegmentedString::advanceSubstring() | 154 void SegmentedString::advanceSubstring() |
155 { | 155 { |
156 if (isComposite()) { | 156 if (isComposite()) { |
157 m_numberOfCharactersConsumedPriorToCurrentString += m_currentString.numb
erOfCharactersConsumed(); | 157 m_numberOfCharactersConsumedPriorToCurrentString += m_currentString.numb
erOfCharactersConsumed(); |
158 m_currentString = m_substrings.takeFirst(); | 158 m_currentString = m_substrings.takeFirst(); |
159 // If we've previously consumed some characters of the non-current | 159 // If we've previously consumed some characters of the non-current |
160 // string, we now account for those characters as part of the current | 160 // string, we now account for those characters as part of the current |
161 // string, not as part of "prior to current string." | 161 // string, not as part of "prior to current string." |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
240 if (m_pushedChar1) { | 240 if (m_pushedChar1) { |
241 m_pushedChar1 = m_pushedChar2; | 241 m_pushedChar1 = m_pushedChar2; |
242 m_pushedChar2 = 0; | 242 m_pushedChar2 = 0; |
243 | 243 |
244 if (m_pushedChar1) { | 244 if (m_pushedChar1) { |
245 m_currentChar = m_pushedChar1; | 245 m_currentChar = m_pushedChar1; |
246 return; | 246 return; |
247 } | 247 } |
248 | 248 |
249 updateAdvanceFunctionPointers(); | 249 updateAdvanceFunctionPointers(); |
250 } else if (m_currentString.m_length) { | 250 } else if (m_currentString.length()) { |
251 if (!--m_currentString.m_length) | 251 m_currentString.decrementLength(); |
| 252 if (!m_currentString.length()) |
252 advanceSubstring(); | 253 advanceSubstring(); |
253 } else if (!isComposite()) { | 254 } else if (!isComposite()) { |
254 m_currentString.clear(); | 255 m_currentString.clear(); |
255 m_empty = true; | 256 m_empty = true; |
256 m_fastPathFlags = NoFastPath; | 257 m_fastPathFlags = NoFastPath; |
257 m_advanceFunc = &SegmentedString::advanceEmpty; | 258 m_advanceFunc = &SegmentedString::advanceEmpty; |
258 m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceEmpty; | 259 m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceEmpty; |
259 } | 260 } |
260 m_currentChar = m_currentString.m_length ? m_currentString.getCurrentChar()
: 0; | 261 m_currentChar = m_currentString.length() ? m_currentString.getCurrentChar()
: 0; |
261 } | 262 } |
262 | 263 |
263 void SegmentedString::advanceAndUpdateLineNumberSlowCase() | 264 void SegmentedString::advanceAndUpdateLineNumberSlowCase() |
264 { | 265 { |
265 if (m_pushedChar1) { | 266 if (m_pushedChar1) { |
266 m_pushedChar1 = m_pushedChar2; | 267 m_pushedChar1 = m_pushedChar2; |
267 m_pushedChar2 = 0; | 268 m_pushedChar2 = 0; |
268 | 269 |
269 if (m_pushedChar1) { | 270 if (m_pushedChar1) { |
270 m_currentChar = m_pushedChar1; | 271 m_currentChar = m_pushedChar1; |
271 return; | 272 return; |
272 } | 273 } |
273 | 274 |
274 updateAdvanceFunctionPointers(); | 275 updateAdvanceFunctionPointers(); |
275 } else if (m_currentString.m_length) { | 276 } else if (m_currentString.length()) { |
276 if (m_currentString.getCurrentChar() == '\n' && m_currentString.doNotExc
ludeLineNumbers()) { | 277 if (m_currentString.getCurrentChar() == '\n' && m_currentString.doNotExc
ludeLineNumbers()) { |
277 ++m_currentLine; | 278 ++m_currentLine; |
278 // Plus 1 because numberOfCharactersConsumed value hasn't incremente
d yet; it does with m_length decrement below. | 279 // Plus 1 because numberOfCharactersConsumed value hasn't incremente
d yet; it does with length() decrement below. |
279 m_numberOfCharactersConsumedPriorToCurrentLine = numberOfCharactersC
onsumed() + 1; | 280 m_numberOfCharactersConsumedPriorToCurrentLine = numberOfCharactersC
onsumed() + 1; |
280 } | 281 } |
281 if (!--m_currentString.m_length) | 282 m_currentString.decrementLength(); |
| 283 if (!m_currentString.length()) |
282 advanceSubstring(); | 284 advanceSubstring(); |
283 else | 285 else |
284 m_currentString.incrementAndGetCurrentChar(); // Only need the ++ | 286 m_currentString.incrementAndGetCurrentChar(); // Only need the ++ |
285 } else if (!isComposite()) { | 287 } else if (!isComposite()) { |
286 m_currentString.clear(); | 288 m_currentString.clear(); |
287 m_empty = true; | 289 m_empty = true; |
288 m_fastPathFlags = NoFastPath; | 290 m_fastPathFlags = NoFastPath; |
289 m_advanceFunc = &SegmentedString::advanceEmpty; | 291 m_advanceFunc = &SegmentedString::advanceEmpty; |
290 m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceEmpty; | 292 m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceEmpty; |
291 } | 293 } |
292 | 294 |
293 m_currentChar = m_currentString.m_length ? m_currentString.getCurrentChar()
: 0; | 295 m_currentChar = m_currentString.length() ? m_currentString.getCurrentChar()
: 0; |
294 } | 296 } |
295 | 297 |
296 void SegmentedString::advanceEmpty() | 298 void SegmentedString::advanceEmpty() |
297 { | 299 { |
298 ASSERT(!m_currentString.m_length && !isComposite()); | 300 ASSERT(!m_currentString.length() && !isComposite()); |
299 m_currentChar = 0; | 301 m_currentChar = 0; |
300 } | 302 } |
301 | 303 |
302 void SegmentedString::updateSlowCaseFunctionPointers() | 304 void SegmentedString::updateSlowCaseFunctionPointers() |
303 { | 305 { |
304 m_fastPathFlags = NoFastPath; | 306 m_fastPathFlags = NoFastPath; |
305 m_advanceFunc = &SegmentedString::advanceSlowCase; | 307 m_advanceFunc = &SegmentedString::advanceSlowCase; |
306 m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceAndUpdateLineNum
berSlowCase; | 308 m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceAndUpdateLineNum
berSlowCase; |
307 } | 309 } |
308 | 310 |
309 OrdinalNumber SegmentedString::currentLine() const | 311 OrdinalNumber SegmentedString::currentLine() const |
310 { | 312 { |
311 return OrdinalNumber::fromZeroBasedInt(m_currentLine); | 313 return OrdinalNumber::fromZeroBasedInt(m_currentLine); |
312 } | 314 } |
313 | 315 |
314 OrdinalNumber SegmentedString::currentColumn() const | 316 OrdinalNumber SegmentedString::currentColumn() const |
315 { | 317 { |
316 int zeroBasedColumn = numberOfCharactersConsumed() - m_numberOfCharactersCon
sumedPriorToCurrentLine; | 318 int zeroBasedColumn = numberOfCharactersConsumed() - m_numberOfCharactersCon
sumedPriorToCurrentLine; |
317 return OrdinalNumber::fromZeroBasedInt(zeroBasedColumn); | 319 return OrdinalNumber::fromZeroBasedInt(zeroBasedColumn); |
318 } | 320 } |
319 | 321 |
320 void SegmentedString::setCurrentPosition(OrdinalNumber line, OrdinalNumber colum
nAftreProlog, int prologLength) | 322 void SegmentedString::setCurrentPosition(OrdinalNumber line, OrdinalNumber colum
nAftreProlog, int prologLength) |
321 { | 323 { |
322 m_currentLine = line.zeroBasedInt(); | 324 m_currentLine = line.zeroBasedInt(); |
323 m_numberOfCharactersConsumedPriorToCurrentLine = numberOfCharactersConsumed(
) + prologLength - columnAftreProlog.zeroBasedInt(); | 325 m_numberOfCharactersConsumedPriorToCurrentLine = numberOfCharactersConsumed(
) + prologLength - columnAftreProlog.zeroBasedInt(); |
324 } | 326 } |
325 | 327 |
326 } | 328 } |
OLD | NEW |