2  * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) 
   3  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. 
   4  * Copyright (C) 2009 Google Inc. All rights reserved. 
   6  * This library is free software; you can redistribute it and/or 
   7  * modify it under the terms of the GNU Library General Public 
   8  * License as published by the Free Software Foundation; either 
   9  * version 2 of the License, or (at your option) any later version. 
  11  * This library is distributed in the hope that it will be useful, 
  12  * but WITHOUT ANY WARRANTY; without even the implied warranty of 
  13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
  14  * Library General Public License for more details. 
  16  * You should have received a copy of the GNU Library General Public License 
  17  * along with this library; see the file COPYING.LIB.  If not, write to 
  18  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 
  19  * Boston, MA 02110-1301, USA. 
  26 #include <wtf/text/StringImpl.h> 
  32     // Construct a null string, distinguishable from an empty string. 
  35     // Construct a string with UTF-16 data. 
  36     UString(const UChar
* characters
, unsigned length
); 
  38     // Construct a string with UTF-16 data, from a null-terminated source. 
  39     UString(const UChar
*); 
  41     // Construct a string with latin1 data. 
  42     UString(const char* characters
, unsigned length
); 
  44     // Construct a string with latin1 data, from a null-terminated source. 
  45     UString(const char* characters
); 
  47     // Construct a string referencing an existing StringImpl. 
  48     UString(StringImpl
* impl
) : m_impl(impl
) { } 
  49     UString(PassRefPtr
<StringImpl
> impl
) : m_impl(impl
) { } 
  50     UString(RefPtr
<StringImpl
> impl
) : m_impl(impl
) { } 
  52     // Inline the destructor. 
  53     ALWAYS_INLINE 
~UString() { } 
  55     void swap(UString
& o
) { m_impl
.swap(o
.m_impl
); } 
  57     template<size_t inlineCapacity
> 
  58     static UString 
adopt(Vector
<UChar
, inlineCapacity
>& vector
) { return StringImpl::adopt(vector
); } 
  60     bool isNull() const { return !m_impl
; } 
  61     bool isEmpty() const { return !m_impl 
|| !m_impl
->length(); } 
  63     StringImpl
* impl() const { return m_impl
.get(); } 
  65     unsigned length() const 
  69         return m_impl
->length(); 
  72     const UChar
* characters() const 
  76         return m_impl
->characters(); 
  79     CString 
ascii() const; 
  80     CString 
latin1() const; 
  81     CString 
utf8(bool strict 
= false) const; 
  83     UChar 
operator[](unsigned index
) const 
  85         if (!m_impl 
|| index 
>= m_impl
->length()) 
  87         return m_impl
->characters()[index
]; 
  90     static UString 
number(int); 
  91     static UString 
number(unsigned); 
  92     static UString 
number(long); 
  93     static UString 
number(long long); 
  94     static UString 
number(double); 
  96     // Find a single character or string, also with match function & latin1 forms. 
  97     size_t find(UChar c
, unsigned start 
= 0) const 
  98         { return m_impl 
? m_impl
->find(c
, start
) : notFound
; } 
  99     size_t find(const UString
& str
, unsigned start 
= 0) const 
 100         { return m_impl 
? m_impl
->find(str
.impl(), start
) : notFound
; } 
 101     size_t find(const char* str
, unsigned start 
= 0) const 
 102         { return m_impl 
? m_impl
->find(str
, start
) : notFound
; } 
 104     // Find the last instance of a single character or string. 
 105     size_t reverseFind(UChar c
, unsigned start 
= UINT_MAX
) const 
 106         { return m_impl 
? m_impl
->reverseFind(c
, start
) : notFound
; } 
 107     size_t reverseFind(const UString
& str
, unsigned start 
= UINT_MAX
) const 
 108         { return m_impl 
? m_impl
->reverseFind(str
.impl(), start
) : notFound
; } 
 110     UString 
substringSharingImpl(unsigned pos
, unsigned len 
= UINT_MAX
) const; 
 113     RefPtr
<StringImpl
> m_impl
; 
 116 ALWAYS_INLINE 
bool operator==(const UString
& s1
, const UString
& s2
) 
 118     StringImpl
* rep1 
= s1
.impl(); 
 119     StringImpl
* rep2 
= s2
.impl(); 
 123     if (rep1 
== rep2
) // If they're the same rep, they're equal. 
 127         size1 
= rep1
->length(); 
 130         size2 
= rep2
->length(); 
 132     if (size1 
!= size2
) // If the lengths are not the same, we're done. 
 138     // At this point we know  
 139     //   (a) that the strings are the same length and 
 140     //   (b) that they are greater than zero length. 
 141     const UChar
* d1 
= rep1
->characters(); 
 142     const UChar
* d2 
= rep2
->characters(); 
 144     if (d1 
== d2
) // Check to see if the data pointers are the same. 
 147     // Do quick checks for sizes 1 and 2. 
 150         return d1
[0] == d2
[0]; 
 152         return (d1
[0] == d2
[0]) & (d1
[1] == d2
[1]); 
 154         return memcmp(d1
, d2
, size1 
* sizeof(UChar
)) == 0; 
 159 inline bool operator!=(const UString
& s1
, const UString
& s2
) 
 161     return !JSC::operator==(s1
, s2
); 
 164 bool operator<(const UString
& s1
, const UString
& s2
); 
 165 bool operator>(const UString
& s1
, const UString
& s2
); 
 167 bool operator==(const UString
& s1
, const char* s2
); 
 169 inline bool operator!=(const UString
& s1
, const char* s2
) 
 171     return !JSC::operator==(s1
, s2
); 
 174 inline bool operator==(const char *s1
, const UString
& s2
) 
 176     return operator==(s2
, s1
); 
 179 inline bool operator!=(const char *s1
, const UString
& s2
) 
 181     return !JSC::operator==(s1
, s2
); 
 184 inline int codePointCompare(const UString
& s1
, const UString
& s2
) 
 186     return codePointCompare(s1
.impl(), s2
.impl()); 
 190     static unsigned hash(StringImpl
* key
) { return key
->hash(); } 
 191     static bool equal(const StringImpl
* a
, const StringImpl
* b
) 
 198         unsigned aLength 
= a
->length(); 
 199         unsigned bLength 
= b
->length(); 
 200         if (aLength 
!= bLength
) 
 203         // FIXME: perhaps we should have a more abstract macro that indicates when 
 204         // going 4 bytes at a time is unsafe 
 205 #if CPU(ARM) || CPU(SH4) || CPU(MIPS) 
 206         const UChar
* aChars 
= a
->characters(); 
 207         const UChar
* bChars 
= b
->characters(); 
 208         for (unsigned i 
= 0; i 
!= aLength
; ++i
) { 
 209             if (*aChars
++ != *bChars
++) 
 214         /* Do it 4-bytes-at-a-time on architectures where it's safe */ 
 215         const uint32_t* aChars 
= reinterpret_cast<const uint32_t*>(a
->characters()); 
 216         const uint32_t* bChars 
= reinterpret_cast<const uint32_t*>(b
->characters()); 
 218         unsigned halfLength 
= aLength 
>> 1; 
 219         for (unsigned i 
= 0; i 
!= halfLength
; ++i
) 
 220             if (*aChars
++ != *bChars
++) 
 223         if (aLength 
& 1 && *reinterpret_cast<const uint16_t*>(aChars
) != *reinterpret_cast<const uint16_t*>(bChars
)) 
 230     static unsigned hash(const RefPtr
<StringImpl
>& key
) { return key
->hash(); } 
 231     static bool equal(const RefPtr
<StringImpl
>& a
, const RefPtr
<StringImpl
>& b
) 
 233         return equal(a
.get(), b
.get()); 
 236     static unsigned hash(const UString
& key
) { return key
.impl()->hash(); } 
 237     static bool equal(const UString
& a
, const UString
& b
) 
 239         return equal(a
.impl(), b
.impl()); 
 242     static const bool safeToCompareToEmptyOrDeleted 
= false; 
 249 // UStringHash is the default hash for UString 
 250 template<typename T
> struct DefaultHash
; 
 251 template<> struct DefaultHash
<JSC::UString
> { 
 252     typedef JSC::UStringHash Hash
; 
 255 template <> struct VectorTraits
<JSC::UString
> : SimpleClassVectorTraits 
{ };