| 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 if (m_currentString.pushIfPossible(c)) { |
| 83 m_currentChar = c; |
| 84 return; |
| 85 } |
| 86 |
| 87 prepend(SegmentedString(String(&c, 1))); |
| 88 } |
| 89 |
| 86 void SegmentedString::prepend(const SegmentedSubstring& s) | 90 void SegmentedString::prepend(const SegmentedSubstring& s) |
| 87 { | 91 { |
| 88 ASSERT(!escaped()); | 92 ASSERT(!escaped()); |
| 89 ASSERT(!s.numberOfCharactersConsumed()); | 93 ASSERT(!s.numberOfCharactersConsumed()); |
| 90 if (!s.length()) | 94 if (!s.length()) |
| 91 return; | 95 return; |
| 92 | 96 |
| 93 // FIXME: We're assuming that the prepend were originally consumed by | 97 // FIXME: We're assuming that the prepend were originally consumed by |
| 94 // this SegmentedString. We're also ASSERTing that s is a fresh | 98 // this SegmentedString. We're also ASSERTing that s is a fresh |
| 95 // SegmentedSubstring. These assumptions are sufficient for our | 99 // SegmentedSubstring. These assumptions are sufficient for our |
| (...skipping 16 matching lines...) Expand all Loading... |
| 112 void SegmentedString::close() | 116 void SegmentedString::close() |
| 113 { | 117 { |
| 114 // Closing a stream twice is likely a coding mistake. | 118 // Closing a stream twice is likely a coding mistake. |
| 115 ASSERT(!m_closed); | 119 ASSERT(!m_closed); |
| 116 m_closed = true; | 120 m_closed = true; |
| 117 } | 121 } |
| 118 | 122 |
| 119 void SegmentedString::append(const SegmentedString& s) | 123 void SegmentedString::append(const SegmentedString& s) |
| 120 { | 124 { |
| 121 ASSERT(!m_closed); | 125 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 | 126 |
| 130 append(s.m_currentString); | 127 append(s.m_currentString); |
| 131 if (s.isComposite()) { | 128 if (s.isComposite()) { |
| 132 Deque<SegmentedSubstring>::const_iterator it = s.m_substrings.begin(); | 129 Deque<SegmentedSubstring>::const_iterator it = s.m_substrings.begin(); |
| 133 Deque<SegmentedSubstring>::const_iterator e = s.m_substrings.end(); | 130 Deque<SegmentedSubstring>::const_iterator e = s.m_substrings.end(); |
| 134 for (; it != e; ++it) | 131 for (; it != e; ++it) |
| 135 append(*it); | 132 append(*it); |
| 136 } | 133 } |
| 137 m_currentChar = m_pushedChar1 ? m_pushedChar1 : (m_currentString.length() ?
m_currentString.getCurrentChar() : 0); | 134 m_currentChar = m_currentString.length() ? m_currentString.getCurrentChar()
: 0; |
| 138 } | 135 } |
| 139 | 136 |
| 140 void SegmentedString::prepend(const SegmentedString& s) | 137 void SegmentedString::prepend(const SegmentedString& s) |
| 141 { | 138 { |
| 142 ASSERT(!escaped()); | 139 ASSERT(!escaped()); |
| 143 ASSERT(!s.escaped()); | 140 ASSERT(!s.escaped()); |
| 144 if (s.isComposite()) { | 141 if (s.isComposite()) { |
| 145 Deque<SegmentedSubstring>::const_reverse_iterator it = s.m_substrings.rb
egin(); | 142 Deque<SegmentedSubstring>::const_reverse_iterator it = s.m_substrings.rb
egin(); |
| 146 Deque<SegmentedSubstring>::const_reverse_iterator e = s.m_substrings.ren
d(); | 143 Deque<SegmentedSubstring>::const_reverse_iterator e = s.m_substrings.ren
d(); |
| 147 for (; it != e; ++it) | 144 for (; it != e; ++it) |
| (...skipping 18 matching lines...) Expand all Loading... |
| 166 m_empty = true; | 163 m_empty = true; |
| 167 m_fastPathFlags = NoFastPath; | 164 m_fastPathFlags = NoFastPath; |
| 168 m_advanceFunc = &SegmentedString::advanceEmpty; | 165 m_advanceFunc = &SegmentedString::advanceEmpty; |
| 169 m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceEmpty; | 166 m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceEmpty; |
| 170 } | 167 } |
| 171 } | 168 } |
| 172 | 169 |
| 173 String SegmentedString::toString() const | 170 String SegmentedString::toString() const |
| 174 { | 171 { |
| 175 StringBuilder result; | 172 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); | 173 m_currentString.appendTo(result); |
| 182 if (isComposite()) { | 174 if (isComposite()) { |
| 183 Deque<SegmentedSubstring>::const_iterator it = m_substrings.begin(); | 175 Deque<SegmentedSubstring>::const_iterator it = m_substrings.begin(); |
| 184 Deque<SegmentedSubstring>::const_iterator e = m_substrings.end(); | 176 Deque<SegmentedSubstring>::const_iterator e = m_substrings.end(); |
| 185 for (; it != e; ++it) | 177 for (; it != e; ++it) |
| 186 it->appendTo(result); | 178 it->appendTo(result); |
| 187 } | 179 } |
| 188 return result.toString(); | 180 return result.toString(); |
| 189 } | 181 } |
| 190 | 182 |
| 191 void SegmentedString::advance(unsigned count, UChar* consumedCharacters) | 183 void SegmentedString::advance(unsigned count, UChar* consumedCharacters) |
| 192 { | 184 { |
| 193 ASSERT_WITH_SECURITY_IMPLICATION(count <= length()); | 185 ASSERT_WITH_SECURITY_IMPLICATION(count <= length()); |
| 194 for (unsigned i = 0; i < count; ++i) { | 186 for (unsigned i = 0; i < count; ++i) { |
| 195 consumedCharacters[i] = currentChar(); | 187 consumedCharacters[i] = currentChar(); |
| 196 advance(); | 188 advance(); |
| 197 } | 189 } |
| 198 } | 190 } |
| 199 | 191 |
| 200 void SegmentedString::advance8() | 192 void SegmentedString::advance8() |
| 201 { | 193 { |
| 202 ASSERT(!m_pushedChar1); | |
| 203 decrementAndCheckLength(); | 194 decrementAndCheckLength(); |
| 204 m_currentChar = m_currentString.incrementAndGetCurrentChar8(); | 195 m_currentChar = m_currentString.incrementAndGetCurrentChar8(); |
| 205 } | 196 } |
| 206 | 197 |
| 207 void SegmentedString::advance16() | 198 void SegmentedString::advance16() |
| 208 { | 199 { |
| 209 ASSERT(!m_pushedChar1); | |
| 210 decrementAndCheckLength(); | 200 decrementAndCheckLength(); |
| 211 m_currentChar = m_currentString.incrementAndGetCurrentChar16(); | 201 m_currentChar = m_currentString.incrementAndGetCurrentChar16(); |
| 212 } | 202 } |
| 213 | 203 |
| 214 void SegmentedString::advanceAndUpdateLineNumber8() | 204 void SegmentedString::advanceAndUpdateLineNumber8() |
| 215 { | 205 { |
| 216 ASSERT(!m_pushedChar1); | |
| 217 ASSERT(m_currentString.getCurrentChar() == m_currentChar); | 206 ASSERT(m_currentString.getCurrentChar() == m_currentChar); |
| 218 if (m_currentChar == '\n') { | 207 if (m_currentChar == '\n') { |
| 219 ++m_currentLine; | 208 ++m_currentLine; |
| 220 m_numberOfCharactersConsumedPriorToCurrentLine = numberOfCharactersConsu
med() + 1; | 209 m_numberOfCharactersConsumedPriorToCurrentLine = numberOfCharactersConsu
med() + 1; |
| 221 } | 210 } |
| 222 decrementAndCheckLength(); | 211 decrementAndCheckLength(); |
| 223 m_currentChar = m_currentString.incrementAndGetCurrentChar8(); | 212 m_currentChar = m_currentString.incrementAndGetCurrentChar8(); |
| 224 } | 213 } |
| 225 | 214 |
| 226 void SegmentedString::advanceAndUpdateLineNumber16() | 215 void SegmentedString::advanceAndUpdateLineNumber16() |
| 227 { | 216 { |
| 228 ASSERT(!m_pushedChar1); | |
| 229 ASSERT(m_currentString.getCurrentChar() == m_currentChar); | 217 ASSERT(m_currentString.getCurrentChar() == m_currentChar); |
| 230 if (m_currentChar == '\n') { | 218 if (m_currentChar == '\n') { |
| 231 ++m_currentLine; | 219 ++m_currentLine; |
| 232 m_numberOfCharactersConsumedPriorToCurrentLine = numberOfCharactersConsu
med() + 1; | 220 m_numberOfCharactersConsumedPriorToCurrentLine = numberOfCharactersConsu
med() + 1; |
| 233 } | 221 } |
| 234 decrementAndCheckLength(); | 222 decrementAndCheckLength(); |
| 235 m_currentChar = m_currentString.incrementAndGetCurrentChar16(); | 223 m_currentChar = m_currentString.incrementAndGetCurrentChar16(); |
| 236 } | 224 } |
| 237 | 225 |
| 238 void SegmentedString::advanceSlowCase() | 226 void SegmentedString::advanceSlowCase() |
| 239 { | 227 { |
| 240 if (m_pushedChar1) { | 228 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(); | 229 m_currentString.decrementLength(); |
| 252 if (!m_currentString.length()) | 230 if (!m_currentString.length()) |
| 253 advanceSubstring(); | 231 advanceSubstring(); |
| 254 } else if (!isComposite()) { | 232 } else if (!isComposite()) { |
| 255 m_currentString.clear(); | 233 m_currentString.clear(); |
| 256 m_empty = true; | 234 m_empty = true; |
| 257 m_fastPathFlags = NoFastPath; | 235 m_fastPathFlags = NoFastPath; |
| 258 m_advanceFunc = &SegmentedString::advanceEmpty; | 236 m_advanceFunc = &SegmentedString::advanceEmpty; |
| 259 m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceEmpty; | 237 m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceEmpty; |
| 260 } | 238 } |
| 261 m_currentChar = m_currentString.length() ? m_currentString.getCurrentChar()
: 0; | 239 m_currentChar = m_currentString.length() ? m_currentString.getCurrentChar()
: 0; |
| 262 } | 240 } |
| 263 | 241 |
| 264 void SegmentedString::advanceAndUpdateLineNumberSlowCase() | 242 void SegmentedString::advanceAndUpdateLineNumberSlowCase() |
| 265 { | 243 { |
| 266 if (m_pushedChar1) { | 244 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()) { | 245 if (m_currentString.getCurrentChar() == '\n' && m_currentString.doNotExc
ludeLineNumbers()) { |
| 278 ++m_currentLine; | 246 ++m_currentLine; |
| 279 // Plus 1 because numberOfCharactersConsumed value hasn't incremente
d yet; it does with length() decrement below. | 247 // Plus 1 because numberOfCharactersConsumed value hasn't incremente
d yet; it does with length() decrement below. |
| 280 m_numberOfCharactersConsumedPriorToCurrentLine = numberOfCharactersC
onsumed() + 1; | 248 m_numberOfCharactersConsumedPriorToCurrentLine = numberOfCharactersC
onsumed() + 1; |
| 281 } | 249 } |
| 282 m_currentString.decrementLength(); | 250 m_currentString.decrementLength(); |
| 283 if (!m_currentString.length()) | 251 if (!m_currentString.length()) |
| 284 advanceSubstring(); | 252 advanceSubstring(); |
| 285 else | 253 else |
| 286 m_currentString.incrementAndGetCurrentChar(); // Only need the ++ | 254 m_currentString.incrementAndGetCurrentChar(); // Only need the ++ |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 319 return OrdinalNumber::fromZeroBasedInt(zeroBasedColumn); | 287 return OrdinalNumber::fromZeroBasedInt(zeroBasedColumn); |
| 320 } | 288 } |
| 321 | 289 |
| 322 void SegmentedString::setCurrentPosition(OrdinalNumber line, OrdinalNumber colum
nAftreProlog, int prologLength) | 290 void SegmentedString::setCurrentPosition(OrdinalNumber line, OrdinalNumber colum
nAftreProlog, int prologLength) |
| 323 { | 291 { |
| 324 m_currentLine = line.zeroBasedInt(); | 292 m_currentLine = line.zeroBasedInt(); |
| 325 m_numberOfCharactersConsumedPriorToCurrentLine = numberOfCharactersConsumed(
) + prologLength - columnAftreProlog.zeroBasedInt(); | 293 m_numberOfCharactersConsumedPriorToCurrentLine = numberOfCharactersConsumed(
) + prologLength - columnAftreProlog.zeroBasedInt(); |
| 326 } | 294 } |
| 327 | 295 |
| 328 } | 296 } |
| OLD | NEW |