| 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; } | |
| 289 | |
| 290 int numberOfCharactersConsumed() const | 294 int numberOfCharactersConsumed() const |
| 291 { | 295 { |
| 292 int numberOfPushedCharacters = 0; | 296 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; | 297 return m_numberOfCharactersConsumedPriorToCurrentString + m_currentStrin
g.numberOfCharactersConsumed() - numberOfPushedCharacters; |
| 299 } | 298 } |
| 300 | 299 |
| 301 String toString() const; | 300 String toString() const; |
| 302 | 301 |
| 303 UChar currentChar() const { return m_currentChar; } | 302 UChar currentChar() const { return m_currentChar; } |
| 304 | 303 |
| 305 // The method is moderately slow, comparing to currentLine method. | 304 // The method is moderately slow, comparing to currentLine method. |
| 306 OrdinalNumber currentColumn() const; | 305 OrdinalNumber currentColumn() const; |
| 307 OrdinalNumber currentLine() const; | 306 OrdinalNumber currentLine() const; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 333 void decrementAndCheckLength() | 332 void decrementAndCheckLength() |
| 334 { | 333 { |
| 335 ASSERT(m_currentString.length() > 1); | 334 ASSERT(m_currentString.length() > 1); |
| 336 m_currentString.decrementLength(); | 335 m_currentString.decrementLength(); |
| 337 if (m_currentString.haveOneCharacterLeft()) | 336 if (m_currentString.haveOneCharacterLeft()) |
| 338 updateSlowCaseFunctionPointers(); | 337 updateSlowCaseFunctionPointers(); |
| 339 } | 338 } |
| 340 | 339 |
| 341 void updateAdvanceFunctionPointers() | 340 void updateAdvanceFunctionPointers() |
| 342 { | 341 { |
| 343 if ((m_currentString.length() > 1) && !m_pushedChar1) { | 342 if (m_currentString.length() > 1) { |
| 344 if (m_currentString.is8Bit()) { | 343 if (m_currentString.is8Bit()) { |
| 345 m_advanceFunc = &SegmentedString::advance8; | 344 m_advanceFunc = &SegmentedString::advance8; |
| 346 m_fastPathFlags = Use8BitAdvance; | 345 m_fastPathFlags = Use8BitAdvance; |
| 347 if (m_currentString.doNotExcludeLineNumbers()) { | 346 if (m_currentString.doNotExcludeLineNumbers()) { |
| 348 m_advanceAndUpdateLineNumberFunc = &SegmentedString::advance
AndUpdateLineNumber8; | 347 m_advanceAndUpdateLineNumberFunc = &SegmentedString::advance
AndUpdateLineNumber8; |
| 349 m_fastPathFlags |= Use8BitAdvanceAndUpdateLineNumbers; | 348 m_fastPathFlags |= Use8BitAdvanceAndUpdateLineNumbers; |
| 350 } else { | 349 } else { |
| 351 m_advanceAndUpdateLineNumberFunc = &SegmentedString::advance
8; | 350 m_advanceAndUpdateLineNumberFunc = &SegmentedString::advance
8; |
| 352 } | 351 } |
| 353 return; | 352 return; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 366 m_advanceFunc = &SegmentedString::advanceEmpty; | 365 m_advanceFunc = &SegmentedString::advanceEmpty; |
| 367 m_fastPathFlags = NoFastPath; | 366 m_fastPathFlags = NoFastPath; |
| 368 m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceEmpty; | 367 m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceEmpty; |
| 369 } | 368 } |
| 370 | 369 |
| 371 updateSlowCaseFunctionPointers(); | 370 updateSlowCaseFunctionPointers(); |
| 372 } | 371 } |
| 373 | 372 |
| 374 inline LookAheadResult lookAheadInline(const String& string, TextCaseSensiti
vity caseSensitivity) | 373 inline LookAheadResult lookAheadInline(const String& string, TextCaseSensiti
vity caseSensitivity) |
| 375 { | 374 { |
| 376 if (!m_pushedChar1 && string.length() <= static_cast<unsigned>(m_current
String.length())) { | 375 if (string.length() <= static_cast<unsigned>(m_currentString.length()))
{ |
| 377 String currentSubstring = m_currentString.currentSubString(string.le
ngth()); | 376 String currentSubstring = m_currentString.currentSubString(string.le
ngth()); |
| 378 if (currentSubstring.startsWith(string, caseSensitivity)) | 377 if (currentSubstring.startsWith(string, caseSensitivity)) |
| 379 return DidMatch; | 378 return DidMatch; |
| 380 return DidNotMatch; | 379 return DidNotMatch; |
| 381 } | 380 } |
| 382 return lookAheadSlowCase(string, caseSensitivity); | 381 return lookAheadSlowCase(string, caseSensitivity); |
| 383 } | 382 } |
| 384 | 383 |
| 385 LookAheadResult lookAheadSlowCase(const String& string, TextCaseSensitivity
caseSensitivity) | 384 LookAheadResult lookAheadSlowCase(const String& string, TextCaseSensitivity
caseSensitivity) |
| 386 { | 385 { |
| 387 unsigned count = string.length(); | 386 unsigned count = string.length(); |
| 388 if (count > length()) | 387 if (count > length()) |
| 389 return NotEnoughCharacters; | 388 return NotEnoughCharacters; |
| 390 UChar* consumedCharacters; | 389 UChar* consumedCharacters; |
| 391 String consumedString = String::createUninitialized(count, consumedChara
cters); | 390 String consumedString = String::createUninitialized(count, consumedChara
cters); |
| 392 advance(count, consumedCharacters); | 391 advance(count, consumedCharacters); |
| 393 LookAheadResult result = DidNotMatch; | 392 LookAheadResult result = DidNotMatch; |
| 394 if (consumedString.startsWith(string, caseSensitivity)) | 393 if (consumedString.startsWith(string, caseSensitivity)) |
| 395 result = DidMatch; | 394 result = DidMatch; |
| 396 prepend(SegmentedString(consumedString)); | 395 prepend(SegmentedString(consumedString)); |
| 397 return result; | 396 return result; |
| 398 } | 397 } |
| 399 | 398 |
| 400 bool isComposite() const { return !m_substrings.isEmpty(); } | 399 bool isComposite() const { return !m_substrings.isEmpty(); } |
| 401 | 400 |
| 402 UChar m_pushedChar1; | |
| 403 UChar m_pushedChar2; | |
| 404 SegmentedSubstring m_currentString; | 401 SegmentedSubstring m_currentString; |
| 405 UChar m_currentChar; | 402 UChar m_currentChar; |
| 406 int m_numberOfCharactersConsumedPriorToCurrentString; | 403 int m_numberOfCharactersConsumedPriorToCurrentString; |
| 407 int m_numberOfCharactersConsumedPriorToCurrentLine; | 404 int m_numberOfCharactersConsumedPriorToCurrentLine; |
| 408 int m_currentLine; | 405 int m_currentLine; |
| 409 Deque<SegmentedSubstring> m_substrings; | 406 Deque<SegmentedSubstring> m_substrings; |
| 410 bool m_closed; | 407 bool m_closed; |
| 411 bool m_empty; | 408 bool m_empty; |
| 412 unsigned char m_fastPathFlags; | 409 unsigned char m_fastPathFlags; |
| 413 void (SegmentedString::*m_advanceFunc)(); | 410 void (SegmentedString::*m_advanceFunc)(); |
| 414 void (SegmentedString::*m_advanceAndUpdateLineNumberFunc)(); | 411 void (SegmentedString::*m_advanceAndUpdateLineNumberFunc)(); |
| 415 }; | 412 }; |
| 416 | 413 |
| 417 } | 414 } |
| 418 | 415 |
| 419 #endif | 416 #endif |
| OLD | NEW |