Reviewed by John
[WebKit-https.git] / WebCore / khtml / dom / dom_string.cpp
1 /**
2  * This file is part of the DOM implementation for KDE.
3  *
4  * (C) 1999 Lars Knoll (knoll@kde.org)
5  * Copyright (C) 2004 Apple Computer, Inc.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public License
18  * along with this library; see the file COPYING.LIB.  If not, write to
19  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 #include "dom/dom_string.h"
24 #include "xml/dom_stringimpl.h"
25
26
27 namespace DOM {
28
29
30 DOMString::DOMString(const QChar *str, uint len)
31 {
32     if (!str) {
33         impl = 0;
34         return;
35     }
36     
37     if (len == 0)
38         impl = DOMStringImpl::empty();
39     else
40         impl = new DOMStringImpl(str, len);
41     impl->ref();
42 }
43
44 DOMString::DOMString(const QString &str)
45 {
46     if (str.isNull()) {
47         impl = 0;
48         return;
49     }
50     
51     if (str.isEmpty())
52         impl = DOMStringImpl::empty();
53     else 
54         impl = new DOMStringImpl(str.unicode(), str.length());
55     impl->ref();
56 }
57
58 DOMString::DOMString(const char *str)
59 {
60     if (!str) {
61         impl = 0;
62         return;
63     }
64
65     int l = strlen(str);
66     if (l == 0)
67         impl = DOMStringImpl::empty();
68     else
69         impl = new DOMStringImpl(str, l);
70     impl->ref();
71 }
72
73 DOMString::DOMString(DOMStringImpl *i)
74 {
75     impl = i;
76     if(impl) impl->ref();
77 }
78
79 DOMString::DOMString(const DOMString &other)
80 {
81     impl = other.impl;
82     if(impl) impl->ref();
83 }
84
85 DOMString &DOMString::operator =(const DOMString &other)
86 {
87     if ( impl != other.impl ) {
88     if(impl) impl->deref();
89     impl = other.impl;
90     if(impl) impl->ref();
91     }
92     return *this;
93 }
94
95 DOMString &DOMString::operator += (const DOMString &str)
96 {
97     if(!impl)
98     {
99         // ### FIXME!!!
100         impl = str.impl;
101         impl->ref();
102         return *this;
103     }
104     if(str.impl)
105     {
106         DOMStringImpl *i = impl->copy();
107         impl->deref();
108         impl = i;
109         impl->ref();
110         impl->append(str.impl);
111     }
112     return *this;
113 }
114
115 DOMString operator + (const DOMString &a, const DOMString &b)
116 {
117     if (a.isEmpty())
118         return b.copy();
119     if (b.isEmpty())
120         return a.copy();
121     DOMString c = a.copy();
122     c += b;
123     return c;
124 }
125
126 void DOMString::insert(DOMString str, uint pos)
127 {
128     if(!impl)
129     {
130         impl = str.impl->copy();
131         impl->ref();
132     }
133     else
134         impl->insert(str.impl, pos);
135 }
136
137
138 const QChar &DOMString::operator [](unsigned int i) const
139 {
140     static const QChar nullChar = 0;
141
142     if(!impl || i >= impl->l ) return nullChar;
143
144     return *(impl->s+i);
145 }
146
147 int DOMString::find(const QChar c, int start) const
148 {
149     unsigned int l = start;
150     if(!impl || l >= impl->l ) return -1;
151     while( l < impl->l )
152     {
153         if( *(impl->s+l) == c ) return l;
154         l++;
155     }
156     return -1;
157 }
158
159 uint DOMString::length() const
160 {
161     if(!impl) return 0;
162     return impl->l;
163 }
164
165 void DOMString::truncate( unsigned int len )
166 {
167     if(impl) impl->truncate(len);
168 }
169
170 void DOMString::remove(unsigned int pos, int len)
171 {
172   if(impl) impl->remove(pos, len);
173 }
174
175 DOMString DOMString::substring(unsigned int pos, unsigned int len)
176 {
177     if (!impl) 
178         return DOMString();
179     return impl->substring(pos, len);
180 }
181
182 DOMString DOMString::split(unsigned int pos)
183 {
184   if(!impl) return DOMString();
185   return impl->split(pos);
186 }
187
188 DOMString DOMString::lower() const
189 {
190   if(!impl) return DOMString();
191   return impl->lower();
192 }
193
194 DOMString DOMString::upper() const
195 {
196   if(!impl) return DOMString();
197   return impl->upper();
198 }
199
200 bool DOMString::percentage(int &_percentage) const
201 {
202     if(!impl || !impl->l) return false;
203
204     if ( *(impl->s+impl->l-1) != QChar('%'))
205        return false;
206
207     _percentage = QConstString(impl->s, impl->l-1).string().toInt();
208     return true;
209 }
210
211 QChar *DOMString::unicode() const
212 {
213     if(!impl) return 0;
214     return impl->s;
215 }
216
217 QString DOMString::string() const
218 {
219     if(!impl) return QString::null;
220
221     return QString(impl->s, impl->l);
222 }
223
224 int DOMString::toInt() const
225 {
226     if(!impl) return 0;
227
228     return impl->toInt();
229 }
230
231 DOMString DOMString::copy() const
232 {
233     if(!impl) return DOMString();
234     return impl->copy();
235 }
236
237 // ------------------------------------------------------------------------
238
239 bool DOM::strcasecmp( const DOMString &as, const DOMString &bs )
240 {
241     if ( as.length() != bs.length() ) return true;
242
243     const QChar *a = as.unicode();
244     const QChar *b = bs.unicode();
245     if ( a == b )  return false;
246     if ( !( a && b ) )  return true;
247     int l = as.length();
248     while ( l-- ) {
249         if ( *a != *b && a->lower() != b->lower() ) return true;
250         a++,b++;
251     }
252     return false;
253 }
254
255 bool DOM::strcasecmp( const DOMString &as, const char* bs )
256 {
257     const QChar *a = as.unicode();
258     int l = as.length();
259     if ( !bs ) return ( l != 0 );
260     while ( l-- ) {
261         if ( a->latin1() != *bs ) {
262             char cc = ( ( *bs >= 'A' ) && ( *bs <= 'Z' ) ) ? ( ( *bs ) + 'a' - 'A' ) : ( *bs );
263             if ( a->lower().latin1() != cc ) return true;
264         }
265         a++, bs++;
266     }
267     return ( *bs != '\0' );
268 }
269
270 bool DOMString::isEmpty() const
271 {
272     return (!impl || impl->l == 0);
273 }
274
275 khtml::Length* DOMString::toLengthArray(int& len) const 
276
277     return impl ? impl->toLengthArray(len) : 0;
278 }
279
280 #ifndef NDEBUG
281 const char *DOMString::ascii() const
282 {
283     return impl ? impl->ascii() : "(null impl)";
284 }
285 #endif
286
287 //-----------------------------------------------------------------------------
288
289 bool DOM::operator==( const DOMString &a, const DOMString &b )
290 {
291     if (a.impl == b.impl)
292         return true;
293     
294     unsigned int l = a.length();
295
296     if( l != b.length() ) return false;
297
298     if(!memcmp(a.unicode(), b.unicode(), l*sizeof(QChar)))
299         return true;
300     return false;
301 }
302
303 bool DOM::operator==( const DOMString &a, const QString &b )
304 {
305     unsigned int l = a.length();
306
307     if( l != b.length() ) return false;
308
309     if(!memcmp(a.unicode(), b.unicode(), l*sizeof(QChar)))
310         return true;
311     return false;
312 }
313
314 bool DOM::operator==( const DOMString &a, const char *b )
315 {
316     DOMStringImpl *aimpl = a.impl;
317     
318     if (!b)
319         return !aimpl;
320     
321     if (aimpl) {
322         int alen = aimpl->l;
323         const QChar *aptr = aimpl->s;
324         while (alen--) {
325             unsigned char c = *b++;
326             if (!c || (*aptr++).unicode() != c)
327                 return false;
328         }
329     }
330     return *b == 0;
331 }
332
333 }