]> git.saurik.com Git - iphone-api.git/blob - WebCore/PlatformString.h
Add support for new WinterBoard Settings features.
[iphone-api.git] / WebCore / PlatformString.h
1 /*
2 * (C) 1999 Lars Knoll (knoll@kde.org)
3 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 *
20 */
21
22 #ifndef PlatformString_h
23 #define PlatformString_h
24
25 // This file would be called String.h, but that conflicts with <string.h>
26 // on systems without case-sensitive file systems.
27
28 #include "StringImpl.h"
29
30 #include <wtf/PassRefPtr.h>
31
32 #if USE(JSC)
33 #include <runtime/Identifier.h>
34 #else
35 // runtime/Identifier.h includes HashMap.h and HashSet.h. We explicitly include
36 // them in the case of non-JSC builds to keep things consistent.
37 #include <wtf/HashMap.h>
38 #include <wtf/HashSet.h>
39 #endif
40
41 #if PLATFORM(CF) || (PLATFORM(QT) && PLATFORM(DARWIN))
42 typedef const struct __CFString * CFStringRef;
43 #endif
44
45 #if PLATFORM(QT)
46 QT_BEGIN_NAMESPACE
47 class QString;
48 QT_END_NAMESPACE
49 #endif
50
51 #if PLATFORM(WX)
52 class wxString;
53 #endif
54
55 namespace WebCore {
56
57 class CString;
58 class SharedBuffer;
59 struct StringHash;
60
61 class String {
62 public:
63 String() { } // gives null string, distinguishable from an empty string
64 String(const UChar*, unsigned length);
65 String(const UChar*); // Specifically for null terminated UTF-16
66 #if USE(JSC)
67 String(const JSC::Identifier&);
68 String(const JSC::UString&);
69 #endif
70 String(const char*);
71 String(const char*, unsigned length);
72 String(StringImpl* i) : m_impl(i) { }
73 String(PassRefPtr<StringImpl> i) : m_impl(i) { }
74 String(RefPtr<StringImpl> i) : m_impl(i) { }
75
76 void swap(String& o) { m_impl.swap(o.m_impl); }
77
78 // Hash table deleted values, which are only constructed and never copied or destroyed.
79 String(WTF::HashTableDeletedValueType) : m_impl(WTF::HashTableDeletedValue) { }
80 bool isHashTableDeletedValue() const { return m_impl.isHashTableDeletedValue(); }
81
82 static String adopt(StringBuffer& buffer) { return StringImpl::adopt(buffer); }
83 static String adopt(Vector<UChar>& vector) { return StringImpl::adopt(vector); }
84
85 #if USE(JSC)
86 operator JSC::UString() const;
87 #endif
88
89 unsigned length() const;
90 const UChar* characters() const;
91 const UChar* charactersWithNullTermination();
92
93 UChar operator[](unsigned i) const; // if i >= length(), returns 0
94 UChar32 characterStartingAt(unsigned) const; // Ditto.
95
96 bool contains(UChar c) const { return find(c) != -1; }
97 bool contains(const char* str, bool caseSensitive = true) const { return find(str, 0, caseSensitive) != -1; }
98 bool contains(const String& str, bool caseSensitive = true) const { return find(str, 0, caseSensitive) != -1; }
99
100 int find(UChar c, int start = 0) const
101 { return m_impl ? m_impl->find(c, start) : -1; }
102 int find(CharacterMatchFunctionPtr matchFunction, int start = 0) const
103 { return m_impl ? m_impl->find(matchFunction, start) : -1; }
104 int find(const char* str, int start = 0, bool caseSensitive = true) const
105 { return m_impl ? m_impl->find(str, start, caseSensitive) : -1; }
106 int find(const String& str, int start = 0, bool caseSensitive = true) const
107 { return m_impl ? m_impl->find(str.impl(), start, caseSensitive) : -1; }
108
109 int reverseFind(UChar c, int start = -1) const
110 { return m_impl ? m_impl->reverseFind(c, start) : -1; }
111 int reverseFind(const String& str, int start = -1, bool caseSensitive = true) const
112 { return m_impl ? m_impl->reverseFind(str.impl(), start, caseSensitive) : -1; }
113
114 bool startsWith(const String& s, bool caseSensitive = true) const
115 { return m_impl ? m_impl->startsWith(s.impl(), caseSensitive) : s.isEmpty(); }
116 bool endsWith(const String& s, bool caseSensitive = true) const
117 { return m_impl ? m_impl->endsWith(s.impl(), caseSensitive) : s.isEmpty(); }
118
119 void append(const String&);
120 void append(char);
121 void append(UChar);
122 void append(const UChar*, unsigned length);
123 void insert(const String&, unsigned pos);
124 void insert(const UChar*, unsigned length, unsigned pos);
125
126 String& replace(UChar a, UChar b) { if (m_impl) m_impl = m_impl->replace(a, b); return *this; }
127 String& replace(UChar a, const String& b) { if (m_impl) m_impl = m_impl->replace(a, b.impl()); return *this; }
128 String& replace(const String& a, const String& b) { if (m_impl) m_impl = m_impl->replace(a.impl(), b.impl()); return *this; }
129 String& replace(unsigned index, unsigned len, const String& b) { if (m_impl) m_impl = m_impl->replace(index, len, b.impl()); return *this; }
130
131 void truncate(unsigned len);
132 void remove(unsigned pos, int len = 1);
133
134 String substring(unsigned pos, unsigned len = UINT_MAX) const;
135 String left(unsigned len) const { return substring(0, len); }
136 String right(unsigned len) const { return substring(length() - len, len); }
137
138 // Returns a lowercase/uppercase version of the string
139 String lower() const;
140 String upper() const;
141
142 String stripWhiteSpace() const;
143 String simplifyWhiteSpace() const;
144
145 String removeCharacters(CharacterMatchFunctionPtr) const;
146
147 // Return the string with case folded for case insensitive comparison.
148 String foldCase() const;
149
150 static String number(short);
151 static String number(unsigned short);
152 static String number(int);
153 static String number(unsigned);
154 static String number(long);
155 static String number(unsigned long);
156 static String number(long long);
157 static String number(unsigned long long);
158 static String number(double);
159
160 static String format(const char *, ...) WTF_ATTRIBUTE_PRINTF(1, 2);
161
162 void split(const String& separator, Vector<String>& result) const;
163 void split(const String& separator, bool allowEmptyEntries, Vector<String>& result) const;
164 void split(UChar separator, Vector<String>& result) const;
165 void split(UChar separator, bool allowEmptyEntries, Vector<String>& result) const;
166
167 int toIntStrict(bool* ok = 0, int base = 10) const;
168 unsigned toUIntStrict(bool* ok = 0, int base = 10) const;
169 int64_t toInt64Strict(bool* ok = 0, int base = 10) const;
170 uint64_t toUInt64Strict(bool* ok = 0, int base = 10) const;
171
172 int toInt(bool* ok = 0) const;
173 unsigned toUInt(bool* ok = 0) const;
174 int64_t toInt64(bool* ok = 0) const;
175 uint64_t toUInt64(bool* ok = 0) const;
176 double toDouble(bool* ok = 0) const;
177 float toFloat(bool* ok = 0) const;
178
179 bool percentage(int& percentage) const;
180
181 // Makes a deep copy. Helpful only if you need to use a String on another thread.
182 // Since the underlying StringImpl objects are immutable, there's no other reason
183 // to ever prefer copy() over plain old assignment.
184 String copy() const;
185
186 // Makes a deep copy like copy() but only for a substring.
187 // (This ensures that you always get something suitable for a thread while subtring
188 // may not. For example, in the empty string case, StringImpl::substring returns
189 // empty() which is not safe for another thread.)
190 String substringCopy(unsigned pos, unsigned len = UINT_MAX) const;
191
192 bool isNull() const { return !m_impl; }
193 bool isEmpty() const;
194
195 StringImpl* impl() const { return m_impl.get(); }
196
197 #if PLATFORM(CF) || (PLATFORM(QT) && PLATFORM(DARWIN))
198 String(CFStringRef);
199 CFStringRef createCFString() const;
200 #endif
201
202 #ifdef __OBJC__
203 String(NSString*);
204
205 // This conversion maps NULL to "", which loses the meaning of NULL, but we
206 // need this mapping because AppKit crashes when passed nil NSStrings.
207 operator NSString*() const { if (!m_impl) return @""; return *m_impl; }
208 #endif
209
210 #if PLATFORM(QT)
211 String(const QString&);
212 String(const QStringRef&);
213 operator QString() const;
214 #endif
215
216 #if PLATFORM(WX)
217 String(const wxString&);
218 operator wxString() const;
219 #endif
220
221 #ifndef NDEBUG
222 Vector<char> ascii() const;
223 #endif
224
225 CString latin1() const;
226 CString utf8() const;
227
228 static String fromUTF8(const char*, size_t);
229 static String fromUTF8(const char*);
230
231 // Determines the writing direction using the Unicode Bidi Algorithm rules P2 and P3.
232 WTF::Unicode::Direction defaultWritingDirection() const { return m_impl ? m_impl->defaultWritingDirection() : WTF::Unicode::LeftToRight; }
233
234 private:
235 RefPtr<StringImpl> m_impl;
236 };
237
238 String operator+(const String&, const String&);
239 String operator+(const String&, const char*);
240 String operator+(const char*, const String&);
241
242 inline String& operator+=(String& a, const String& b) { a.append(b); return a; }
243
244 inline bool operator==(const String& a, const String& b) { return equal(a.impl(), b.impl()); }
245 inline bool operator==(const String& a, const char* b) { return equal(a.impl(), b); }
246 inline bool operator==(const char* a, const String& b) { return equal(a, b.impl()); }
247
248 inline bool operator!=(const String& a, const String& b) { return !equal(a.impl(), b.impl()); }
249 inline bool operator!=(const String& a, const char* b) { return !equal(a.impl(), b); }
250 inline bool operator!=(const char* a, const String& b) { return !equal(a, b.impl()); }
251
252 inline bool equalIgnoringCase(const String& a, const String& b) { return equalIgnoringCase(a.impl(), b.impl()); }
253 inline bool equalIgnoringCase(const String& a, const char* b) { return equalIgnoringCase(a.impl(), b); }
254 inline bool equalIgnoringCase(const char* a, const String& b) { return equalIgnoringCase(a, b.impl()); }
255
256 inline bool operator!(const String& str) { return str.isNull(); }
257
258 inline void swap(String& a, String& b) { a.swap(b); }
259
260 // String Operations
261
262 bool charactersAreAllASCII(const UChar*, size_t);
263
264 int charactersToIntStrict(const UChar*, size_t, bool* ok = 0, int base = 10);
265 unsigned charactersToUIntStrict(const UChar*, size_t, bool* ok = 0, int base = 10);
266 int64_t charactersToInt64Strict(const UChar*, size_t, bool* ok = 0, int base = 10);
267 uint64_t charactersToUInt64Strict(const UChar*, size_t, bool* ok = 0, int base = 10);
268
269 int charactersToInt(const UChar*, size_t, bool* ok = 0); // ignores trailing garbage
270 unsigned charactersToUInt(const UChar*, size_t, bool* ok = 0); // ignores trailing garbage
271 int64_t charactersToInt64(const UChar*, size_t, bool* ok = 0); // ignores trailing garbage
272 uint64_t charactersToUInt64(const UChar*, size_t, bool* ok = 0); // ignores trailing garbage
273
274 double charactersToDouble(const UChar*, size_t, bool* ok = 0);
275 float charactersToFloat(const UChar*, size_t, bool* ok = 0);
276
277 int find(const UChar*, size_t, UChar, int startPosition = 0);
278 int reverseFind(const UChar*, size_t, UChar, int startPosition = -1);
279
280 #ifdef __OBJC__
281 // This is for situations in WebKit where the long standing behavior has been
282 // "nil if empty", so we try to maintain longstanding behavior for the sake of
283 // entrenched clients
284 inline NSString* nsStringNilIfEmpty(const String& str) { return str.isEmpty() ? nil : (NSString*)str; }
285 #endif
286
287 inline bool charactersAreAllASCII(const UChar* characters, size_t length)
288 {
289 UChar ored = 0;
290 for (size_t i = 0; i < length; ++i)
291 ored |= characters[i];
292 return !(ored & 0xFF80);
293 }
294
295 inline int find(const UChar* characters, size_t length, UChar character, int startPosition)
296 {
297 if (startPosition >= static_cast<int>(length))
298 return -1;
299 for (size_t i = startPosition; i < length; ++i) {
300 if (characters[i] == character)
301 return static_cast<int>(i);
302 }
303 return -1;
304 }
305
306 inline int find(const UChar* characters, size_t length, CharacterMatchFunctionPtr matchFunction, int startPosition)
307 {
308 if (startPosition >= static_cast<int>(length))
309 return -1;
310 for (size_t i = startPosition; i < length; ++i) {
311 if (matchFunction(characters[i]))
312 return static_cast<int>(i);
313 }
314 return -1;
315 }
316
317 inline int reverseFind(const UChar* characters, size_t length, UChar character, int startPosition)
318 {
319 if (startPosition >= static_cast<int>(length) || !length)
320 return -1;
321 if (startPosition < 0)
322 startPosition += static_cast<int>(length);
323 while (true) {
324 if (characters[startPosition] == character)
325 return startPosition;
326 if (!startPosition)
327 return -1;
328 startPosition--;
329 }
330 ASSERT_NOT_REACHED();
331 return -1;
332 }
333
334 inline void append(Vector<UChar>& vector, const String& string)
335 {
336 vector.append(string.characters(), string.length());
337 }
338
339 inline void appendNumber(Vector<UChar>& vector, unsigned char number)
340 {
341 int numberLength = number > 99 ? 3 : (number > 9 ? 2 : 1);
342 size_t vectorSize = vector.size();
343 vector.grow(vectorSize + numberLength);
344
345 switch (numberLength) {
346 case 3:
347 vector[vectorSize + 2] = number % 10 + '0';
348 number /= 10;
349
350 case 2:
351 vector[vectorSize + 1] = number % 10 + '0';
352 number /= 10;
353
354 case 1:
355 vector[vectorSize] = number % 10 + '0';
356 }
357 }
358
359
360
361 PassRefPtr<SharedBuffer> utf8Buffer(const String&);
362
363 } // namespace WebCore
364
365 namespace WTF {
366
367 // StringHash is the default hash for String
368 template<typename T> struct DefaultHash;
369 template<> struct DefaultHash<WebCore::String> {
370 typedef WebCore::StringHash Hash;
371 };
372
373 }
374
375 #endif