Chromium Code Reviews| 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 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 48 if (m_length) { | 48 if (m_length) { |
| 49 if (m_string.is8Bit()) { | 49 if (m_string.is8Bit()) { |
| 50 m_is8Bit = true; | 50 m_is8Bit = true; |
| 51 m_data.string8Ptr = m_string.characters8(); | 51 m_data.string8Ptr = m_string.characters8(); |
| 52 } else { | 52 } else { |
| 53 m_is8Bit = false; | 53 m_is8Bit = false; |
| 54 m_data.string16Ptr = m_string.characters16(); | 54 m_data.string16Ptr = m_string.characters16(); |
| 55 } | 55 } |
| 56 } else { | 56 } else { |
| 57 m_is8Bit = false; | 57 m_is8Bit = false; |
| 58 m_data.string8Ptr = nullptr; | |
| 58 } | 59 } |
| 59 } | 60 } |
| 60 | 61 |
| 61 void clear() { m_length = 0; m_data.string16Ptr = 0; m_is8Bit = false;} | 62 void clear() { m_length = 0; m_data.string16Ptr = nullptr; m_is8Bit = false; } |
| 62 | 63 |
| 63 bool is8Bit() { return m_is8Bit; } | 64 bool is8Bit() { return m_is8Bit; } |
| 64 | 65 |
| 65 bool excludeLineNumbers() const { return !m_doNotExcludeLineNumbers; } | 66 bool excludeLineNumbers() const { return !m_doNotExcludeLineNumbers; } |
| 66 bool doNotExcludeLineNumbers() const { return m_doNotExcludeLineNumbers; } | 67 bool doNotExcludeLineNumbers() const { return m_doNotExcludeLineNumbers; } |
| 67 | 68 |
| 68 void setExcludeLineNumbers() { m_doNotExcludeLineNumbers = false; } | 69 void setExcludeLineNumbers() { m_doNotExcludeLineNumbers = false; } |
| 69 | 70 |
| 70 int numberOfCharactersConsumed() const { return m_string.length() - m_length ; } | 71 int numberOfCharactersConsumed() const { return m_string.length() - m_length ; } |
| 71 | 72 |
| 72 void appendTo(StringBuilder& builder) const | 73 void appendTo(StringBuilder& builder) const |
| 73 { | 74 { |
| 74 int offset = m_string.length() - m_length; | 75 int offset = m_string.length() - m_length; |
| 75 | 76 |
| 76 if (!offset) { | 77 if (!offset) { |
| 77 if (m_length) | 78 if (m_length) |
| 78 builder.append(m_string); | 79 builder.append(m_string); |
| 79 } else { | 80 } else { |
| 80 builder.append(m_string.substring(offset, m_length)); | 81 builder.append(m_string.substring(offset, m_length)); |
| 81 } | 82 } |
| 82 } | 83 } |
| 83 | 84 |
| 85 bool pushIfPossible(UChar c) | |
| 86 { | |
| 87 if (!m_length) | |
| 88 return false; | |
| 89 | |
| 90 if (m_is8Bit) { | |
| 91 if (m_data.string8Ptr == m_string.characters8()) | |
| 92 return false; | |
| 93 | |
| 94 --m_data.string8Ptr; | |
| 95 ASSERT(*m_data.string8Ptr == c); | |
| 96 ++m_length; | |
| 97 return true; | |
| 98 } | |
| 99 | |
| 100 if (m_data.string16Ptr == m_string.characters16()) | |
| 101 return false; | |
| 102 | |
| 103 --m_data.string16Ptr; | |
| 104 ASSERT(*m_data.string16Ptr == static_cast<LChar>(c)); | |
| 105 ++m_length; | |
| 106 return true; | |
| 107 } | |
| 108 | |
| 84 UChar getCurrentChar8() | 109 UChar getCurrentChar8() |
| 85 { | 110 { |
| 86 return *m_data.string8Ptr; | 111 return *m_data.string8Ptr; |
| 87 } | 112 } |
| 88 | 113 |
| 89 UChar getCurrentChar16() | 114 UChar getCurrentChar16() |
| 90 { | 115 { |
| 91 return m_data.string16Ptr ? *m_data.string16Ptr : 0; | 116 return m_data.string16Ptr ? *m_data.string16Ptr : 0; |
| 92 } | 117 } |
| 93 | 118 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 141 } m_data; | 166 } m_data; |
| 142 int m_length; | 167 int m_length; |
| 143 bool m_doNotExcludeLineNumbers; | 168 bool m_doNotExcludeLineNumbers; |
| 144 bool m_is8Bit; | 169 bool m_is8Bit; |
| 145 String m_string; | 170 String m_string; |
| 146 }; | 171 }; |
| 147 | 172 |
| 148 class PLATFORM_EXPORT SegmentedString { | 173 class PLATFORM_EXPORT SegmentedString { |
| 149 public: | 174 public: |
| 150 SegmentedString() | 175 SegmentedString() |
| 151 : m_pushedChar1(0) | 176 : m_currentChar(0) |
| 152 , m_pushedChar2(0) | |
| 153 , m_currentChar(0) | |
| 154 , m_numberOfCharactersConsumedPriorToCurrentString(0) | 177 , m_numberOfCharactersConsumedPriorToCurrentString(0) |
| 155 , m_numberOfCharactersConsumedPriorToCurrentLine(0) | 178 , m_numberOfCharactersConsumedPriorToCurrentLine(0) |
| 156 , m_currentLine(0) | 179 , m_currentLine(0) |
| 157 , m_closed(false) | 180 , m_closed(false) |
| 158 , m_empty(true) | 181 , m_empty(true) |
| 159 , m_fastPathFlags(NoFastPath) | 182 , m_fastPathFlags(NoFastPath) |
| 160 , m_advanceFunc(&SegmentedString::advanceEmpty) | 183 , m_advanceFunc(&SegmentedString::advanceEmpty) |
| 161 , m_advanceAndUpdateLineNumberFunc(&SegmentedString::advanceEmpty) | 184 , m_advanceAndUpdateLineNumberFunc(&SegmentedString::advanceEmpty) |
| 162 { | 185 { |
| 163 } | 186 } |
| 164 | 187 |
| 165 SegmentedString(const String& str) | 188 SegmentedString(const String& str) |
| 166 : m_pushedChar1(0) | 189 : m_currentString(str) |
| 167 , m_pushedChar2(0) | |
| 168 , m_currentString(str) | |
| 169 , m_currentChar(0) | 190 , m_currentChar(0) |
| 170 , m_numberOfCharactersConsumedPriorToCurrentString(0) | 191 , m_numberOfCharactersConsumedPriorToCurrentString(0) |
| 171 , m_numberOfCharactersConsumedPriorToCurrentLine(0) | 192 , m_numberOfCharactersConsumedPriorToCurrentLine(0) |
| 172 , m_currentLine(0) | 193 , m_currentLine(0) |
| 173 , m_closed(false) | 194 , m_closed(false) |
| 174 , m_empty(!str.length()) | 195 , m_empty(!str.length()) |
| 175 , m_fastPathFlags(NoFastPath) | 196 , m_fastPathFlags(NoFastPath) |
| 176 { | 197 { |
| 177 if (m_currentString.length()) | 198 if (m_currentString.length()) |
| 178 m_currentChar = m_currentString.getCurrentChar(); | 199 m_currentChar = m_currentString.getCurrentChar(); |
| 179 updateAdvanceFunctionPointers(); | 200 updateAdvanceFunctionPointers(); |
| 180 } | 201 } |
| 181 | 202 |
| 182 void clear(); | 203 void clear(); |
| 183 void close(); | 204 void close(); |
| 184 | 205 |
| 185 void append(const SegmentedString&); | 206 void append(const SegmentedString&); |
| 186 void prepend(const SegmentedString&); | 207 void prepend(const SegmentedString&); |
| 187 | 208 |
| 188 bool excludeLineNumbers() const { return m_currentString.excludeLineNumbers( ); } | 209 bool excludeLineNumbers() const { return m_currentString.excludeLineNumbers( ); } |
| 189 void setExcludeLineNumbers(); | 210 void setExcludeLineNumbers(); |
| 190 | 211 |
| 191 void push(UChar c) | 212 void push(UChar); |
| 192 { | |
| 193 ASSERT(c); | |
| 194 | |
| 195 if (!m_pushedChar1) { | |
| 196 m_currentChar = m_pushedChar1 = c; | |
| 197 updateSlowCaseFunctionPointers(); | |
| 198 } else { | |
| 199 ASSERT(!m_pushedChar2); | |
| 200 m_pushedChar2 = m_pushedChar1; | |
| 201 m_currentChar = m_pushedChar1 = c; | |
| 202 } | |
| 203 } | |
| 204 | 213 |
| 205 bool isEmpty() const { return m_empty; } | 214 bool isEmpty() const { return m_empty; } |
| 206 unsigned length() const; | 215 unsigned length() const; |
| 207 | 216 |
| 208 bool isClosed() const { return m_closed; } | 217 bool isClosed() const { return m_closed; } |
| 209 | 218 |
| 210 enum LookAheadResult { | 219 enum LookAheadResult { |
| 211 DidNotMatch, | 220 DidNotMatch, |
| 212 DidMatch, | 221 DidMatch, |
| 213 NotEnoughCharacters, | 222 NotEnoughCharacters, |
| 214 }; | 223 }; |
| 215 | 224 |
| 216 LookAheadResult lookAhead(const String& string) { return lookAheadInline(str ing, TextCaseSensitive); } | 225 LookAheadResult lookAhead(const String& string) { return lookAheadInline(str ing, TextCaseSensitive); } |
| 217 LookAheadResult lookAheadIgnoringCase(const String& string) { return lookAhe adInline(string, TextCaseInsensitive); } | 226 LookAheadResult lookAheadIgnoringCase(const String& string) { return lookAhe adInline(string, TextCaseInsensitive); } |
| 218 | 227 |
| 219 void advance() | 228 void advance() |
| 220 { | 229 { |
| 221 if (m_fastPathFlags & Use8BitAdvance) { | 230 if (m_fastPathFlags & Use8BitAdvance) { |
| 222 ASSERT(!m_pushedChar1); | |
| 223 m_currentChar = m_currentString.incrementAndGetCurrentChar8(); | 231 m_currentChar = m_currentString.incrementAndGetCurrentChar8(); |
| 224 decrementAndCheckLength(); | 232 decrementAndCheckLength(); |
| 225 return; | 233 return; |
| 226 } | 234 } |
| 227 | 235 |
| 228 (this->*m_advanceFunc)(); | 236 (this->*m_advanceFunc)(); |
| 229 } | 237 } |
| 230 | 238 |
| 231 inline void advanceAndUpdateLineNumber() | 239 inline void advanceAndUpdateLineNumber() |
| 232 { | 240 { |
| 233 if (m_fastPathFlags & Use8BitAdvance) { | 241 if (m_fastPathFlags & Use8BitAdvance) { |
| 234 ASSERT(!m_pushedChar1); | |
| 235 | |
| 236 bool haveNewLine = (m_currentChar == '\n') & !!(m_fastPathFlags & Us e8BitAdvanceAndUpdateLineNumbers); | 242 bool haveNewLine = (m_currentChar == '\n') & !!(m_fastPathFlags & Us e8BitAdvanceAndUpdateLineNumbers); |
| 237 m_currentChar = m_currentString.incrementAndGetCurrentChar8(); | 243 m_currentChar = m_currentString.incrementAndGetCurrentChar8(); |
| 238 decrementAndCheckLength(); | 244 decrementAndCheckLength(); |
| 239 | 245 |
| 240 if (haveNewLine) { | 246 if (haveNewLine) { |
| 241 ++m_currentLine; | 247 ++m_currentLine; |
| 242 m_numberOfCharactersConsumedPriorToCurrentLine = m_numberOfChar actersConsumedPriorToCurrentString + m_currentString.numberOfCharactersConsumed( ); | 248 m_numberOfCharactersConsumedPriorToCurrentLine = m_numberOfChar actersConsumedPriorToCurrentString + m_currentString.numberOfCharactersConsumed( ); |
| 243 } | 249 } |
| 244 | 250 |
| 245 return; | 251 return; |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 262 | 268 |
| 263 void advancePastNonNewline() | 269 void advancePastNonNewline() |
| 264 { | 270 { |
| 265 ASSERT(currentChar() != '\n'); | 271 ASSERT(currentChar() != '\n'); |
| 266 advance(); | 272 advance(); |
| 267 } | 273 } |
| 268 | 274 |
| 269 void advancePastNewlineAndUpdateLineNumber() | 275 void advancePastNewlineAndUpdateLineNumber() |
| 270 { | 276 { |
| 271 ASSERT(currentChar() == '\n'); | 277 ASSERT(currentChar() == '\n'); |
| 272 if (!m_pushedChar1 && m_currentString.length() > 1) { | 278 if (m_currentString.length() > 1) { |
| 273 int newLineFlag = m_currentString.doNotExcludeLineNumbers(); | 279 int newLineFlag = m_currentString.doNotExcludeLineNumbers(); |
| 274 m_currentLine += newLineFlag; | 280 m_currentLine += newLineFlag; |
| 275 if (newLineFlag) | 281 if (newLineFlag) |
| 276 m_numberOfCharactersConsumedPriorToCurrentLine = numberOfCharact ersConsumed() + 1; | 282 m_numberOfCharactersConsumedPriorToCurrentLine = numberOfCharact ersConsumed() + 1; |
| 277 decrementAndCheckLength(); | 283 decrementAndCheckLength(); |
| 278 m_currentChar = m_currentString.incrementAndGetCurrentChar(); | 284 m_currentChar = m_currentString.incrementAndGetCurrentChar(); |
| 279 return; | 285 return; |
| 280 } | 286 } |
| 281 advanceAndUpdateLineNumberSlowCase(); | 287 advanceAndUpdateLineNumberSlowCase(); |
| 282 } | 288 } |
| 283 | 289 |
| 284 // Writes the consumed characters into consumedCharacters, which must | 290 // Writes the consumed characters into consumedCharacters, which must |
| 285 // have space for at least |count| characters. | 291 // have space for at least |count| characters. |
| 286 void advance(unsigned count, UChar* consumedCharacters); | 292 void advance(unsigned count, UChar* consumedCharacters); |
| 287 | 293 |
| 288 bool escaped() const { return m_pushedChar1; } | 294 bool escaped() const { return false; } |
|
Yoav Weiss
2015/08/31 07:57:44
I believe we can get rid of escaped() altogether.
| |
| 289 | 295 |
| 290 int numberOfCharactersConsumed() const | 296 int numberOfCharactersConsumed() const |
| 291 { | 297 { |
| 292 int numberOfPushedCharacters = 0; | 298 int numberOfPushedCharacters = 0; |
| 293 if (m_pushedChar1) { | |
| 294 ++numberOfPushedCharacters; | |
| 295 if (m_pushedChar2) | |
| 296 ++numberOfPushedCharacters; | |
| 297 } | |
| 298 return m_numberOfCharactersConsumedPriorToCurrentString + m_currentStrin g.numberOfCharactersConsumed() - numberOfPushedCharacters; | 299 return m_numberOfCharactersConsumedPriorToCurrentString + m_currentStrin g.numberOfCharactersConsumed() - numberOfPushedCharacters; |
| 299 } | 300 } |
| 300 | 301 |
| 301 String toString() const; | 302 String toString() const; |
| 302 | 303 |
| 303 UChar currentChar() const { return m_currentChar; } | 304 UChar currentChar() const { return m_currentChar; } |
| 304 | 305 |
| 305 // The method is moderately slow, comparing to currentLine method. | 306 // The method is moderately slow, comparing to currentLine method. |
| 306 OrdinalNumber currentColumn() const; | 307 OrdinalNumber currentColumn() const; |
| 307 OrdinalNumber currentLine() const; | 308 OrdinalNumber currentLine() const; |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 333 void decrementAndCheckLength() | 334 void decrementAndCheckLength() |
| 334 { | 335 { |
| 335 ASSERT(m_currentString.length() > 1); | 336 ASSERT(m_currentString.length() > 1); |
| 336 m_currentString.decrementLength(); | 337 m_currentString.decrementLength(); |
| 337 if (m_currentString.haveOneCharacterLeft()) | 338 if (m_currentString.haveOneCharacterLeft()) |
| 338 updateSlowCaseFunctionPointers(); | 339 updateSlowCaseFunctionPointers(); |
| 339 } | 340 } |
| 340 | 341 |
| 341 void updateAdvanceFunctionPointers() | 342 void updateAdvanceFunctionPointers() |
| 342 { | 343 { |
| 343 if ((m_currentString.length() > 1) && !m_pushedChar1) { | 344 if (m_currentString.length() > 1) { |
| 344 if (m_currentString.is8Bit()) { | 345 if (m_currentString.is8Bit()) { |
| 345 m_advanceFunc = &SegmentedString::advance8; | 346 m_advanceFunc = &SegmentedString::advance8; |
| 346 m_fastPathFlags = Use8BitAdvance; | 347 m_fastPathFlags = Use8BitAdvance; |
| 347 if (m_currentString.doNotExcludeLineNumbers()) { | 348 if (m_currentString.doNotExcludeLineNumbers()) { |
| 348 m_advanceAndUpdateLineNumberFunc = &SegmentedString::advance AndUpdateLineNumber8; | 349 m_advanceAndUpdateLineNumberFunc = &SegmentedString::advance AndUpdateLineNumber8; |
| 349 m_fastPathFlags |= Use8BitAdvanceAndUpdateLineNumbers; | 350 m_fastPathFlags |= Use8BitAdvanceAndUpdateLineNumbers; |
| 350 } else { | 351 } else { |
| 351 m_advanceAndUpdateLineNumberFunc = &SegmentedString::advance 8; | 352 m_advanceAndUpdateLineNumberFunc = &SegmentedString::advance 8; |
| 352 } | 353 } |
| 353 return; | 354 return; |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 366 m_advanceFunc = &SegmentedString::advanceEmpty; | 367 m_advanceFunc = &SegmentedString::advanceEmpty; |
| 367 m_fastPathFlags = NoFastPath; | 368 m_fastPathFlags = NoFastPath; |
| 368 m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceEmpty; | 369 m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceEmpty; |
| 369 } | 370 } |
| 370 | 371 |
| 371 updateSlowCaseFunctionPointers(); | 372 updateSlowCaseFunctionPointers(); |
| 372 } | 373 } |
| 373 | 374 |
| 374 inline LookAheadResult lookAheadInline(const String& string, TextCaseSensiti vity caseSensitivity) | 375 inline LookAheadResult lookAheadInline(const String& string, TextCaseSensiti vity caseSensitivity) |
| 375 { | 376 { |
| 376 if (!m_pushedChar1 && string.length() <= static_cast<unsigned>(m_current String.length())) { | 377 if (string.length() <= static_cast<unsigned>(m_currentString.length())) { |
| 377 String currentSubstring = m_currentString.currentSubString(string.le ngth()); | 378 String currentSubstring = m_currentString.currentSubString(string.le ngth()); |
| 378 if (currentSubstring.startsWith(string, caseSensitivity)) | 379 if (currentSubstring.startsWith(string, caseSensitivity)) |
| 379 return DidMatch; | 380 return DidMatch; |
| 380 return DidNotMatch; | 381 return DidNotMatch; |
| 381 } | 382 } |
| 382 return lookAheadSlowCase(string, caseSensitivity); | 383 return lookAheadSlowCase(string, caseSensitivity); |
| 383 } | 384 } |
| 384 | 385 |
| 385 LookAheadResult lookAheadSlowCase(const String& string, TextCaseSensitivity caseSensitivity) | 386 LookAheadResult lookAheadSlowCase(const String& string, TextCaseSensitivity caseSensitivity) |
| 386 { | 387 { |
| 387 unsigned count = string.length(); | 388 unsigned count = string.length(); |
| 388 if (count > length()) | 389 if (count > length()) |
| 389 return NotEnoughCharacters; | 390 return NotEnoughCharacters; |
| 390 UChar* consumedCharacters; | 391 UChar* consumedCharacters; |
| 391 String consumedString = String::createUninitialized(count, consumedChara cters); | 392 String consumedString = String::createUninitialized(count, consumedChara cters); |
| 392 advance(count, consumedCharacters); | 393 advance(count, consumedCharacters); |
| 393 LookAheadResult result = DidNotMatch; | 394 LookAheadResult result = DidNotMatch; |
| 394 if (consumedString.startsWith(string, caseSensitivity)) | 395 if (consumedString.startsWith(string, caseSensitivity)) |
| 395 result = DidMatch; | 396 result = DidMatch; |
| 396 prepend(SegmentedString(consumedString)); | 397 prepend(SegmentedString(consumedString)); |
| 397 return result; | 398 return result; |
| 398 } | 399 } |
| 399 | 400 |
| 400 bool isComposite() const { return !m_substrings.isEmpty(); } | 401 bool isComposite() const { return !m_substrings.isEmpty(); } |
| 401 | 402 |
| 402 UChar m_pushedChar1; | |
| 403 UChar m_pushedChar2; | |
| 404 SegmentedSubstring m_currentString; | 403 SegmentedSubstring m_currentString; |
| 405 UChar m_currentChar; | 404 UChar m_currentChar; |
| 406 int m_numberOfCharactersConsumedPriorToCurrentString; | 405 int m_numberOfCharactersConsumedPriorToCurrentString; |
| 407 int m_numberOfCharactersConsumedPriorToCurrentLine; | 406 int m_numberOfCharactersConsumedPriorToCurrentLine; |
| 408 int m_currentLine; | 407 int m_currentLine; |
| 409 Deque<SegmentedSubstring> m_substrings; | 408 Deque<SegmentedSubstring> m_substrings; |
| 410 bool m_closed; | 409 bool m_closed; |
| 411 bool m_empty; | 410 bool m_empty; |
| 412 unsigned char m_fastPathFlags; | 411 unsigned char m_fastPathFlags; |
| 413 void (SegmentedString::*m_advanceFunc)(); | 412 void (SegmentedString::*m_advanceFunc)(); |
| 414 void (SegmentedString::*m_advanceAndUpdateLineNumberFunc)(); | 413 void (SegmentedString::*m_advanceAndUpdateLineNumberFunc)(); |
| 415 }; | 414 }; |
| 416 | 415 |
| 417 } | 416 } |
| 418 | 417 |
| 419 #endif | 418 #endif |
| OLD | NEW |