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 |