1/* 2 * Copyright (C) 2004, 2005, 2006, 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 21#ifndef AtomicString_h 22#define AtomicString_h 23 24#include "AtomicStringImpl.h" 25#include "PlatformString.h" 26 27// Define 'NO_IMPLICIT_ATOMICSTRING' before including this header, 28// to disallow (expensive) implicit String-->AtomicString conversions. 29#ifdef NO_IMPLICIT_ATOMICSTRING 30#define ATOMICSTRING_CONVERSION explicit 31#else 32#define ATOMICSTRING_CONVERSION 33#endif 34 35namespace WebCore { 36 37struct AtomicStringHash; 38 39class AtomicString { 40public: 41 static void init(); 42 43 AtomicString() { } 44 AtomicString(const char* s) : m_string(add(s)) { } 45 AtomicString(const UChar* s, int length) : m_string(add(s, length)) { } 46 AtomicString(const UChar* s) : m_string(add(s)) { } 47#if USE(JSC) 48 AtomicString(const JSC::UString& s) : m_string(add(s)) { } 49 AtomicString(const JSC::Identifier& s) : m_string(add(s)) { } 50#endif 51 ATOMICSTRING_CONVERSION AtomicString(StringImpl* imp) : m_string(add(imp)) { } 52 AtomicString(AtomicStringImpl* imp) : m_string(imp) { } 53 ATOMICSTRING_CONVERSION AtomicString(const String& s) : m_string(add(s.impl())) { } 54 55 // Hash table deleted values, which are only constructed and never copied or destroyed. 56 AtomicString(WTF::HashTableDeletedValueType) : m_string(WTF::HashTableDeletedValue) { } 57 bool isHashTableDeletedValue() const { return m_string.isHashTableDeletedValue(); } 58 59#if USE(JSC) 60 static AtomicStringImpl* find(const JSC::Identifier&); 61#endif 62 63 operator const String&() const { return m_string; } 64 const String& string() const { return m_string; }; 65 66#if USE(JSC) 67 operator JSC::UString() const; 68#endif 69 70 AtomicStringImpl* impl() const { return static_cast<AtomicStringImpl *>(m_string.impl()); } 71 72 const UChar* characters() const { return m_string.characters(); } 73 unsigned length() const { return m_string.length(); } 74 75 UChar operator[](unsigned int i) const { return m_string[i]; } 76 77 bool contains(UChar c) const { return m_string.contains(c); } 78 bool contains(const char* s, bool caseSensitive = true) const 79 { return m_string.contains(s, caseSensitive); } 80 bool contains(const String& s, bool caseSensitive = true) const 81 { return m_string.contains(s, caseSensitive); } 82 83 int find(UChar c, int start = 0) const { return m_string.find(c, start); } 84 int find(const char* s, int start = 0, bool caseSentitive = true) const 85 { return m_string.find(s, start, caseSentitive); } 86 int find(const String& s, int start = 0, bool caseSentitive = true) const 87 { return m_string.find(s, start, caseSentitive); } 88 89 bool startsWith(const String& s, bool caseSensitive = true) const 90 { return m_string.startsWith(s, caseSensitive); } 91 bool endsWith(const String& s, bool caseSensitive = true) const 92 { return m_string.endsWith(s, caseSensitive); } 93 94 AtomicString lower() const; 95 AtomicString upper() const { return AtomicString(impl()->upper()); } 96 97 int toInt(bool* ok = 0) const { return m_string.toInt(ok); } 98 double toDouble(bool* ok = 0) const { return m_string.toDouble(ok); } 99 float toFloat(bool* ok = 0) const { return m_string.toFloat(ok); } 100 bool percentage(int& p) const { return m_string.percentage(p); } 101 102 bool isNull() const { return m_string.isNull(); } 103 bool isEmpty() const { return m_string.isEmpty(); } 104 105 static void remove(StringImpl*); 106 107#if PLATFORM(CF) 108 AtomicString(CFStringRef s) : m_string(add(String(s).impl())) { } 109 CFStringRef createCFString() const { return m_string.createCFString(); } 110#endif 111#ifdef __OBJC__ 112 AtomicString(NSString* s) : m_string(add(String(s).impl())) { } 113 operator NSString*() const { return m_string; } 114#endif 115#if PLATFORM(QT) 116 AtomicString(const QString& s) : m_string(add(String(s).impl())) { } 117 operator QString() const { return m_string; } 118#endif 119 120private: 121 String m_string; 122 123 static PassRefPtr<StringImpl> add(const char*); 124 static PassRefPtr<StringImpl> add(const UChar*, int length); 125 static PassRefPtr<StringImpl> add(const UChar*); 126 static PassRefPtr<StringImpl> add(StringImpl*); 127#if USE(JSC) 128 static PassRefPtr<StringImpl> add(const JSC::UString&); 129 static PassRefPtr<StringImpl> add(const JSC::Identifier&); 130#endif 131}; 132 133inline bool operator==(const AtomicString& a, const AtomicString& b) { return a.impl() == b.impl(); } 134bool operator==(const AtomicString& a, const char* b); 135inline bool operator==(const AtomicString& a, const String& b) { return equal(a.impl(), b.impl()); } 136inline bool operator==(const char* a, const AtomicString& b) { return b == a; } 137inline bool operator==(const String& a, const AtomicString& b) { return equal(a.impl(), b.impl()); } 138 139inline bool operator!=(const AtomicString& a, const AtomicString& b) { return a.impl() != b.impl(); } 140inline bool operator!=(const AtomicString& a, const char *b) { return !(a == b); } 141inline bool operator!=(const AtomicString& a, const String& b) { return !equal(a.impl(), b.impl()); } 142inline bool operator!=(const char* a, const AtomicString& b) { return !(b == a); } 143inline bool operator!=(const String& a, const AtomicString& b) { return !equal(a.impl(), b.impl()); } 144 145inline bool equalIgnoringCase(const AtomicString& a, const AtomicString& b) { return equalIgnoringCase(a.impl(), b.impl()); } 146inline bool equalIgnoringCase(const AtomicString& a, const char* b) { return equalIgnoringCase(a.impl(), b); } 147inline bool equalIgnoringCase(const AtomicString& a, const String& b) { return equalIgnoringCase(a.impl(), b.impl()); } 148inline bool equalIgnoringCase(const char* a, const AtomicString& b) { return equalIgnoringCase(a, b.impl()); } 149inline bool equalIgnoringCase(const String& a, const AtomicString& b) { return equalIgnoringCase(a.impl(), b.impl()); } 150 151// Define external global variables for the commonly used atomic strings. 152// These are only usable from the main thread. 153#ifndef ATOMICSTRING_HIDE_GLOBALS 154 extern const AtomicString nullAtom; 155 extern const AtomicString emptyAtom; 156 extern const AtomicString textAtom; 157 extern const AtomicString commentAtom; 158 extern const AtomicString starAtom; 159 extern const AtomicString xmlAtom; 160 extern const AtomicString xmlnsAtom; 161#endif 162 163} // namespace WebCore 164 165 166namespace WTF { 167 168 // AtomicStringHash is the default hash for AtomicString 169 template<typename T> struct DefaultHash; 170 template<> struct DefaultHash<WebCore::AtomicString> { 171 typedef WebCore::AtomicStringHash Hash; 172 }; 173 174} // namespace WTF 175 176#endif // AtomicString_h 177