]> git.saurik.com Git - iphone-api.git/blame - WebCore/SegmentedString.h
Add support for new WinterBoard Settings features.
[iphone-api.git] / WebCore / SegmentedString.h
CommitLineData
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
26namespace WebCore {
27
28class SegmentedString;
29
30class SegmentedSubstring {
31public:
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
62public:
63 int m_length;
64 const UChar* m_current;
65
66private:
67 String m_string;
68 bool m_doNotExcludeLineNumbers;
69};
70
71class SegmentedString {
72public:
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
157private:
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