a1e132ce6fba80aae053724557d1bb90cbf4cff4
[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::split(unsigned int pos)
176 {
177   if(!impl) return DOMString();
178   return impl->split(pos);
179 }
180
181 DOMString DOMString::lower() const
182 {
183   if(!impl) return DOMString();
184   return impl->lower();
185 }
186
187 DOMString DOMString::upper() const
188 {
189   if(!impl) return DOMString();
190   return impl->upper();
191 }
192
193 bool DOMString::percentage(int &_percentage) const
194 {
195     if(!impl || !impl->l) return false;
196
197     if ( *(impl->s+impl->l-1) != QChar('%'))
198        return false;
199
200     _percentage = QConstString(impl->s, impl->l-1).string().toInt();
201     return true;
202 }
203
204 QChar *DOMString::unicode() const
205 {
206     if(!impl) return 0;
207     return impl->s;
208 }
209
210 QString DOMString::string() const
211 {
212     if(!impl) return QString::null;
213
214     return QString(impl->s, impl->l);
215 }
216
217 int DOMString::toInt() const
218 {
219     if(!impl) return 0;
220
221     return impl->toInt();
222 }
223
224 DOMString DOMString::copy() const
225 {
226     if(!impl) return DOMString();
227     return impl->copy();
228 }
229
230 // ------------------------------------------------------------------------
231
232 bool DOM::strcasecmp( const DOMString &as, const DOMString &bs )
233 {
234     if ( as.length() != bs.length() ) return true;
235
236     const QChar *a = as.unicode();
237     const QChar *b = bs.unicode();
238     if ( a == b )  return false;
239     if ( !( a && b ) )  return true;
240     int l = as.length();
241     while ( l-- ) {
242         if ( *a != *b && a->lower() != b->lower() ) return true;
243         a++,b++;
244     }
245     return false;
246 }
247
248 bool DOM::strcasecmp( const DOMString &as, const char* bs )
249 {
250     const QChar *a = as.unicode();
251     int l = as.length();
252     if ( !bs ) return ( l != 0 );
253     while ( l-- ) {
254         if ( a->latin1() != *bs ) {
255             char cc = ( ( *bs >= 'A' ) && ( *bs <= 'Z' ) ) ? ( ( *bs ) + 'a' - 'A' ) : ( *bs );
256             if ( a->lower().latin1() != cc ) return true;
257         }
258         a++, bs++;
259     }
260     return ( *bs != '\0' );
261 }
262
263 bool DOMString::isEmpty() const
264 {
265     return (!impl || impl->l == 0);
266 }
267
268 khtml::Length* DOMString::toLengthArray(int& len) const 
269
270     return impl ? impl->toLengthArray(len) : 0;
271 }
272
273 #ifndef NDEBUG
274 const char *DOMString::ascii() const
275 {
276     return impl ? impl->ascii() : "(null impl)";
277 }
278 #endif
279
280 //-----------------------------------------------------------------------------
281
282 bool DOM::operator==( const DOMString &a, const DOMString &b )
283 {
284     if (a.impl == b.impl)
285         return true;
286     
287     unsigned int l = a.length();
288
289     if( l != b.length() ) return false;
290
291     if(!memcmp(a.unicode(), b.unicode(), l*sizeof(QChar)))
292         return true;
293     return false;
294 }
295
296 bool DOM::operator==( const DOMString &a, const QString &b )
297 {
298     unsigned int l = a.length();
299
300     if( l != b.length() ) return false;
301
302     if(!memcmp(a.unicode(), b.unicode(), l*sizeof(QChar)))
303         return true;
304     return false;
305 }
306
307 bool DOM::operator==( const DOMString &a, const char *b )
308 {
309     DOMStringImpl *aimpl = a.impl;
310     
311     if (!b)
312         return !aimpl;
313     
314     if (aimpl) {
315         int alen = aimpl->l;
316         const QChar *aptr = aimpl->s;
317         while (alen--) {
318             unsigned char c = *b++;
319             if (!c || (*aptr++).unicode() != c)
320                 return false;
321         }
322     }
323     return *b == 0;
324 }
325
326 }