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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
44 : m_length(str.length()) | 44 : m_length(str.length()) |
45 , m_doNotExcludeLineNumbers(true) | 45 , m_doNotExcludeLineNumbers(true) |
46 , m_string(str) | 46 , m_string(str) |
47 { | 47 { |
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(); |
Yoav Weiss
2015/08/27 13:08:12
Unrelated to current CL, but when str.length() is
kouhei (in TOK)
2015/08/28 05:38:47
Done.
| |
55 } | 55 } |
56 } else { | 56 } else { |
57 m_is8Bit = false; | 57 m_is8Bit = false; |
58 } | 58 } |
59 } | 59 } |
60 | 60 |
61 void clear() { m_length = 0; m_data.string16Ptr = 0; m_is8Bit = false;} | 61 void clear() { m_length = 0; m_data.string16Ptr = 0; m_is8Bit = false;} |
62 | 62 |
63 bool is8Bit() { return m_is8Bit; } | 63 bool is8Bit() { return m_is8Bit; } |
64 | 64 |
65 bool excludeLineNumbers() const { return !m_doNotExcludeLineNumbers; } | 65 bool excludeLineNumbers() const { return !m_doNotExcludeLineNumbers; } |
66 bool doNotExcludeLineNumbers() const { return m_doNotExcludeLineNumbers; } | 66 bool doNotExcludeLineNumbers() const { return m_doNotExcludeLineNumbers; } |
67 | 67 |
68 void setExcludeLineNumbers() { m_doNotExcludeLineNumbers = false; } | 68 void setExcludeLineNumbers() { m_doNotExcludeLineNumbers = false; } |
69 | 69 |
70 int numberOfCharactersConsumed() const { return m_string.length() - m_length ; } | 70 int numberOfCharactersConsumed() const { return m_string.length() - m_length ; } |
71 | 71 |
72 void appendTo(StringBuilder& builder) const | 72 void appendTo(StringBuilder& builder) const |
73 { | 73 { |
74 int offset = m_string.length() - m_length; | 74 int offset = m_string.length() - m_length; |
75 | 75 |
76 if (!offset) { | 76 if (!offset) { |
77 if (m_length) | 77 if (m_length) |
78 builder.append(m_string); | 78 builder.append(m_string); |
79 } else { | 79 } else { |
80 builder.append(m_string.substring(offset, m_length)); | 80 builder.append(m_string.substring(offset, m_length)); |
81 } | 81 } |
82 } | 82 } |
83 | 83 |
84 void push(UChar c) | |
85 { | |
86 if (m_is8Bit) { | |
87 if (m_data.string8Ptr == m_string.characters8()) { | |
88 m_string.insert(&c, 1, 0); | |
Yoav Weiss
2015/08/27 13:19:03
AFAICT this goes back to String::append which look
kouhei (in TOK)
2015/08/28 05:38:47
I replaced this codepath with prepend() call in Se
| |
89 m_data.string8Ptr = m_string.characters8(); | |
90 m_length = m_string.length(); | |
91 } else { | |
92 --m_data.string8Ptr; | |
93 ASSERT(*m_data.string8Ptr == c); | |
94 } | |
95 } else { | |
96 if (m_data.string16Ptr == m_string.characters16()) { | |
97 m_string.insert(&c, 1, 0); | |
98 m_data.string16Ptr = m_string.characters16(); | |
99 m_length = m_string.length(); | |
100 } else { | |
101 --m_data.string16Ptr; | |
102 ASSERT(*m_data.string16Ptr == static_cast<LChar>(c)); | |
103 } | |
104 } | |
105 } | |
106 | |
84 UChar getCurrentChar8() | 107 UChar getCurrentChar8() |
85 { | 108 { |
86 return *m_data.string8Ptr; | 109 return *m_data.string8Ptr; |
87 } | 110 } |
88 | 111 |
89 UChar getCurrentChar16() | 112 UChar getCurrentChar16() |
90 { | 113 { |
91 return m_data.string16Ptr ? *m_data.string16Ptr : 0; | 114 return m_data.string16Ptr ? *m_data.string16Ptr : 0; |
92 } | 115 } |
93 | 116 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
141 } m_data; | 164 } m_data; |
142 int m_length; | 165 int m_length; |
143 bool m_doNotExcludeLineNumbers; | 166 bool m_doNotExcludeLineNumbers; |
144 bool m_is8Bit; | 167 bool m_is8Bit; |
145 String m_string; | 168 String m_string; |
146 }; | 169 }; |
147 | 170 |
148 class PLATFORM_EXPORT SegmentedString { | 171 class PLATFORM_EXPORT SegmentedString { |
149 public: | 172 public: |
150 SegmentedString() | 173 SegmentedString() |
151 : m_pushedChar1(0) | 174 : m_currentChar(0) |
152 , m_pushedChar2(0) | |
153 , m_currentChar(0) | |
154 , m_numberOfCharactersConsumedPriorToCurrentString(0) | 175 , m_numberOfCharactersConsumedPriorToCurrentString(0) |
155 , m_numberOfCharactersConsumedPriorToCurrentLine(0) | 176 , m_numberOfCharactersConsumedPriorToCurrentLine(0) |
156 , m_currentLine(0) | 177 , m_currentLine(0) |
157 , m_closed(false) | 178 , m_closed(false) |
158 , m_empty(true) | 179 , m_empty(true) |
159 , m_fastPathFlags(NoFastPath) | 180 , m_fastPathFlags(NoFastPath) |
160 , m_advanceFunc(&SegmentedString::advanceEmpty) | 181 , m_advanceFunc(&SegmentedString::advanceEmpty) |
161 , m_advanceAndUpdateLineNumberFunc(&SegmentedString::advanceEmpty) | 182 , m_advanceAndUpdateLineNumberFunc(&SegmentedString::advanceEmpty) |
162 { | 183 { |
163 } | 184 } |
164 | 185 |
165 SegmentedString(const String& str) | 186 SegmentedString(const String& str) |
166 : m_pushedChar1(0) | 187 : m_currentString(str) |
167 , m_pushedChar2(0) | |
168 , m_currentString(str) | |
169 , m_currentChar(0) | 188 , m_currentChar(0) |
170 , m_numberOfCharactersConsumedPriorToCurrentString(0) | 189 , m_numberOfCharactersConsumedPriorToCurrentString(0) |
171 , m_numberOfCharactersConsumedPriorToCurrentLine(0) | 190 , m_numberOfCharactersConsumedPriorToCurrentLine(0) |
172 , m_currentLine(0) | 191 , m_currentLine(0) |
173 , m_closed(false) | 192 , m_closed(false) |
174 , m_empty(!str.length()) | 193 , m_empty(!str.length()) |
175 , m_fastPathFlags(NoFastPath) | 194 , m_fastPathFlags(NoFastPath) |
176 { | 195 { |
177 if (m_currentString.length()) | 196 if (m_currentString.length()) |
178 m_currentChar = m_currentString.getCurrentChar(); | 197 m_currentChar = m_currentString.getCurrentChar(); |
179 updateAdvanceFunctionPointers(); | 198 updateAdvanceFunctionPointers(); |
180 } | 199 } |
181 | 200 |
182 void clear(); | 201 void clear(); |
183 void close(); | 202 void close(); |
184 | 203 |
185 void append(const SegmentedString&); | 204 void append(const SegmentedString&); |
186 void prepend(const SegmentedString&); | 205 void prepend(const SegmentedString&); |
187 | 206 |
188 bool excludeLineNumbers() const { return m_currentString.excludeLineNumbers( ); } | 207 bool excludeLineNumbers() const { return m_currentString.excludeLineNumbers( ); } |
189 void setExcludeLineNumbers(); | 208 void setExcludeLineNumbers(); |
190 | 209 |
191 void push(UChar c) | 210 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 | 211 |
205 bool isEmpty() const { return m_empty; } | 212 bool isEmpty() const { return m_empty; } |
206 unsigned length() const; | 213 unsigned length() const; |
207 | 214 |
208 bool isClosed() const { return m_closed; } | 215 bool isClosed() const { return m_closed; } |
209 | 216 |
210 enum LookAheadResult { | 217 enum LookAheadResult { |
211 DidNotMatch, | 218 DidNotMatch, |
212 DidMatch, | 219 DidMatch, |
213 NotEnoughCharacters, | 220 NotEnoughCharacters, |
214 }; | 221 }; |
215 | 222 |
216 LookAheadResult lookAhead(const String& string) { return lookAheadInline(str ing, TextCaseSensitive); } | 223 LookAheadResult lookAhead(const String& string) { return lookAheadInline(str ing, TextCaseSensitive); } |
217 LookAheadResult lookAheadIgnoringCase(const String& string) { return lookAhe adInline(string, TextCaseInsensitive); } | 224 LookAheadResult lookAheadIgnoringCase(const String& string) { return lookAhe adInline(string, TextCaseInsensitive); } |
218 | 225 |
219 void advance() | 226 void advance() |
220 { | 227 { |
221 if (m_fastPathFlags & Use8BitAdvance) { | 228 if (m_fastPathFlags & Use8BitAdvance) { |
222 ASSERT(!m_pushedChar1); | |
223 m_currentChar = m_currentString.incrementAndGetCurrentChar8(); | 229 m_currentChar = m_currentString.incrementAndGetCurrentChar8(); |
224 decrementAndCheckLength(); | 230 decrementAndCheckLength(); |
225 return; | 231 return; |
226 } | 232 } |
227 | 233 |
228 (this->*m_advanceFunc)(); | 234 (this->*m_advanceFunc)(); |
229 } | 235 } |
230 | 236 |
231 inline void advanceAndUpdateLineNumber() | 237 inline void advanceAndUpdateLineNumber() |
232 { | 238 { |
233 if (m_fastPathFlags & Use8BitAdvance) { | 239 if (m_fastPathFlags & Use8BitAdvance) { |
234 ASSERT(!m_pushedChar1); | |
235 | |
236 bool haveNewLine = (m_currentChar == '\n') & !!(m_fastPathFlags & Us e8BitAdvanceAndUpdateLineNumbers); | 240 bool haveNewLine = (m_currentChar == '\n') & !!(m_fastPathFlags & Us e8BitAdvanceAndUpdateLineNumbers); |
237 m_currentChar = m_currentString.incrementAndGetCurrentChar8(); | 241 m_currentChar = m_currentString.incrementAndGetCurrentChar8(); |
238 decrementAndCheckLength(); | 242 decrementAndCheckLength(); |
239 | 243 |
240 if (haveNewLine) { | 244 if (haveNewLine) { |
241 ++m_currentLine; | 245 ++m_currentLine; |
242 m_numberOfCharactersConsumedPriorToCurrentLine = m_numberOfChar actersConsumedPriorToCurrentString + m_currentString.numberOfCharactersConsumed( ); | 246 m_numberOfCharactersConsumedPriorToCurrentLine = m_numberOfChar actersConsumedPriorToCurrentString + m_currentString.numberOfCharactersConsumed( ); |
243 } | 247 } |
244 | 248 |
245 return; | 249 return; |
(...skipping 16 matching lines...) Expand all Loading... | |
262 | 266 |
263 void advancePastNonNewline() | 267 void advancePastNonNewline() |
264 { | 268 { |
265 ASSERT(currentChar() != '\n'); | 269 ASSERT(currentChar() != '\n'); |
266 advance(); | 270 advance(); |
267 } | 271 } |
268 | 272 |
269 void advancePastNewlineAndUpdateLineNumber() | 273 void advancePastNewlineAndUpdateLineNumber() |
270 { | 274 { |
271 ASSERT(currentChar() == '\n'); | 275 ASSERT(currentChar() == '\n'); |
272 if (!m_pushedChar1 && m_currentString.length() > 1) { | 276 if (m_currentString.length() > 1) { |
273 int newLineFlag = m_currentString.doNotExcludeLineNumbers(); | 277 int newLineFlag = m_currentString.doNotExcludeLineNumbers(); |
274 m_currentLine += newLineFlag; | 278 m_currentLine += newLineFlag; |
275 if (newLineFlag) | 279 if (newLineFlag) |
276 m_numberOfCharactersConsumedPriorToCurrentLine = numberOfCharact ersConsumed() + 1; | 280 m_numberOfCharactersConsumedPriorToCurrentLine = numberOfCharact ersConsumed() + 1; |
277 decrementAndCheckLength(); | 281 decrementAndCheckLength(); |
278 m_currentChar = m_currentString.incrementAndGetCurrentChar(); | 282 m_currentChar = m_currentString.incrementAndGetCurrentChar(); |
279 return; | 283 return; |
280 } | 284 } |
281 advanceAndUpdateLineNumberSlowCase(); | 285 advanceAndUpdateLineNumberSlowCase(); |
282 } | 286 } |
283 | 287 |
284 // Writes the consumed characters into consumedCharacters, which must | 288 // Writes the consumed characters into consumedCharacters, which must |
285 // have space for at least |count| characters. | 289 // have space for at least |count| characters. |
286 void advance(unsigned count, UChar* consumedCharacters); | 290 void advance(unsigned count, UChar* consumedCharacters); |
287 | 291 |
288 bool escaped() const { return m_pushedChar1; } | 292 bool escaped() const { return false; } |
289 | 293 |
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 |