]>
Commit | Line | Data |
---|---|---|
a90939db JF |
1 | /* |
2 | Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. | |
3 | ||
4 | This library is free software; you can redistribute it and/or | |
5 | modify it under the terms of the GNU Library General Public | |
6 | License as published by the Free Software Foundation; either | |
7 | version 2 of the License, or (at your option) any later version. | |
8 | ||
9 | This library is distributed in the hope that it will be useful, | |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
12 | Library General Public License for more details. | |
13 | ||
14 | You should have received a copy of the GNU Library General Public License | |
15 | along with this library; see the file COPYING.LIB. If not, write to | |
16 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | |
17 | Boston, MA 02110-1301, USA. | |
18 | */ | |
19 | ||
20 | #ifndef SegmentedString_h | |
21 | #define SegmentedString_h | |
22 | ||
23 | #include "PlatformString.h" | |
24 | #include <wtf/Deque.h> | |
25 | ||
26 | namespace WebCore { | |
27 | ||
28 | class SegmentedString; | |
29 | ||
30 | class SegmentedSubstring { | |
31 | public: | |
32 | SegmentedSubstring() : m_length(0), m_current(0), m_doNotExcludeLineNumbers(true) {} | |
33 | SegmentedSubstring(const String& str) | |
34 | : m_length(str.length()) | |
35 | , m_current(str.isEmpty() ? 0 : str.characters()) | |
36 | , m_string(str) | |
37 | , m_doNotExcludeLineNumbers(true) | |
38 | { | |
39 | } | |
40 | ||
41 | SegmentedSubstring(const UChar* str, int length) : m_length(length), m_current(length == 0 ? 0 : str), m_doNotExcludeLineNumbers(true) {} | |
42 | ||
43 | void clear() { m_length = 0; m_current = 0; } | |
44 | ||
45 | bool excludeLineNumbers() const { return !m_doNotExcludeLineNumbers; } | |
46 | bool doNotExcludeLineNumbers() const { return m_doNotExcludeLineNumbers; } | |
47 | ||
48 | void setExcludeLineNumbers() { m_doNotExcludeLineNumbers = false; } | |
49 | ||
50 | void appendTo(String& str) const | |
51 | { | |
52 | if (m_string.characters() == m_current) { | |
53 | if (str.isEmpty()) | |
54 | str = m_string; | |
55 | else | |
56 | str.append(m_string); | |
57 | } else { | |
58 | str.append(String(m_current, m_length)); | |
59 | } | |
60 | } | |
61 | ||
62 | public: | |
63 | int m_length; | |
64 | const UChar* m_current; | |
65 | ||
66 | private: | |
67 | String m_string; | |
68 | bool m_doNotExcludeLineNumbers; | |
69 | }; | |
70 | ||
71 | class SegmentedString { | |
72 | public: | |
73 | SegmentedString() | |
74 | : m_pushedChar1(0), m_pushedChar2(0), m_currentChar(0), m_composite(false) {} | |
75 | SegmentedString(const UChar* str, int length) : m_pushedChar1(0), m_pushedChar2(0) | |
76 | , m_currentString(str, length), m_currentChar(m_currentString.m_current), m_composite(false) {} | |
77 | SegmentedString(const String& str) | |
78 | : m_pushedChar1(0), m_pushedChar2(0), m_currentString(str) | |
79 | , m_currentChar(m_currentString.m_current), m_composite(false) {} | |
80 | SegmentedString(const SegmentedString&); | |
81 | ||
82 | const SegmentedString& operator=(const SegmentedString&); | |
83 | ||
84 | void clear(); | |
85 | ||
86 | void append(const SegmentedString&); | |
87 | void prepend(const SegmentedString&); | |
88 | ||
89 | bool excludeLineNumbers() const { return m_currentString.excludeLineNumbers(); } | |
90 | void setExcludeLineNumbers(); | |
91 | ||
92 | void push(UChar c) | |
93 | { | |
94 | if (!m_pushedChar1) { | |
95 | m_pushedChar1 = c; | |
96 | m_currentChar = m_pushedChar1 ? &m_pushedChar1 : m_currentString.m_current; | |
97 | } else { | |
98 | ASSERT(!m_pushedChar2); | |
99 | m_pushedChar2 = c; | |
100 | } | |
101 | } | |
102 | ||
103 | bool isEmpty() const { return !current(); } | |
104 | unsigned length() const; | |
105 | ||
106 | void advance() | |
107 | { | |
108 | if (!m_pushedChar1 && m_currentString.m_length > 1) { | |
109 | --m_currentString.m_length; | |
110 | m_currentChar = ++m_currentString.m_current; | |
111 | return; | |
112 | } | |
113 | advanceSlowCase(); | |
114 | } | |
115 | ||
116 | void advancePastNewline(int& lineNumber) | |
117 | { | |
118 | ASSERT(*current() == '\n'); | |
119 | if (!m_pushedChar1 && m_currentString.m_length > 1) { | |
120 | lineNumber += m_currentString.doNotExcludeLineNumbers(); | |
121 | --m_currentString.m_length; | |
122 | m_currentChar = ++m_currentString.m_current; | |
123 | return; | |
124 | } | |
125 | advanceSlowCase(lineNumber); | |
126 | } | |
127 | ||
128 | void advancePastNonNewline() | |
129 | { | |
130 | ASSERT(*current() != '\n'); | |
131 | if (!m_pushedChar1 && m_currentString.m_length > 1) { | |
132 | --m_currentString.m_length; | |
133 | m_currentChar = ++m_currentString.m_current; | |
134 | return; | |
135 | } | |
136 | advanceSlowCase(); | |
137 | } | |
138 | ||
139 | void advance(int& lineNumber) | |
140 | { | |
141 | if (!m_pushedChar1 && m_currentString.m_length > 1) { | |
142 | lineNumber += (*m_currentString.m_current == '\n') & m_currentString.doNotExcludeLineNumbers(); | |
143 | --m_currentString.m_length; | |
144 | m_currentChar = ++m_currentString.m_current; | |
145 | return; | |
146 | } | |
147 | advanceSlowCase(lineNumber); | |
148 | } | |
149 | ||
150 | bool escaped() const { return m_pushedChar1; } | |
151 | ||
152 | String toString() const; | |
153 | ||
154 | const UChar& operator*() const { return *current(); } | |
155 | const UChar* operator->() const { return current(); } | |
156 | ||
157 | private: | |
158 | void append(const SegmentedSubstring&); | |
159 | void prepend(const SegmentedSubstring&); | |
160 | ||
161 | void advanceSlowCase(); | |
162 | void advanceSlowCase(int& lineNumber); | |
163 | void advanceSubstring(); | |
164 | const UChar* current() const { return m_currentChar; } | |
165 | ||
166 | UChar m_pushedChar1; | |
167 | UChar m_pushedChar2; | |
168 | SegmentedSubstring m_currentString; | |
169 | const UChar* m_currentChar; | |
170 | Deque<SegmentedSubstring> m_substrings; | |
171 | bool m_composite; | |
172 | }; | |
173 | ||
174 | } | |
175 | ||
176 | #endif |