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 |