fix logic
[personal-kdelibs.git] / khtml / dom / dom_string.cpp
bloba20dad9b0bcbda3734bd58cb85a5762988cf8b98
1 /**
2 * This file is part of the DOM implementation for KDE.
4 * Copyright 1999 Lars Knoll (knoll@kde.org)
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.
22 #include "dom/dom_string.h"
23 #include "xml/dom_stringimpl.h"
25 #include <wtf/Vector.h>
27 using namespace DOM;
30 DOMString::DOMString(const QChar *str, uint len)
32 impl = new DOMStringImpl( str, len );
33 impl->ref();
36 DOMString::DOMString(const QString &str)
38 if (str.isNull()) {
39 impl = 0;
40 return;
43 impl = new DOMStringImpl( str.unicode(), str.length() );
44 impl->ref();
47 DOMString::DOMString(const char *str)
49 if (!str) {
50 impl = 0;
51 return;
54 impl = new DOMStringImpl( str );
55 impl->ref();
58 DOMString::DOMString(const char *str, uint len)
60 if (!str) {
61 impl = 0;
62 return;
64 impl = new DOMStringImpl(str, len);
65 impl->ref();
68 DOMString::DOMString(DOMStringImpl *i)
70 impl = i;
71 if(impl) impl->ref();
74 DOMString::DOMString(const DOMString &other)
76 impl = other.impl;
77 if(impl) impl->ref();
80 DOMString::~DOMString()
82 if(impl) impl->deref();
85 DOMString &DOMString::operator =(const DOMString &other)
87 if ( impl != other.impl ) {
88 if(impl) impl->deref();
89 impl = other.impl;
90 if(impl) impl->ref();
92 return *this;
95 DOMString &DOMString::operator += (const DOMString &str)
97 if(!impl)
99 // ### FIXME!!!
100 impl = str.impl;
101 if (impl)
102 impl->ref();
103 return *this;
105 if(str.impl)
107 DOMStringImpl *i = impl->copy();
108 impl->deref();
109 impl = i;
110 impl->ref();
111 impl->append(str.impl);
113 return *this;
116 DOMString DOMString::operator + (const DOMString &str)
118 if(!impl) return str.copy();
119 if(str.impl)
121 DOMString s = copy();
122 s += str;
123 return s;
126 return copy();
129 void DOMString::insert(DOMString str, uint pos)
131 if(!impl)
133 impl = str.impl->copy();
134 impl->ref();
136 else
137 impl->insert(str.impl, pos);
141 const QChar &DOMString::operator [](unsigned int i) const
143 static const QChar nullChar = 0;
145 if(!impl || i >= impl->l ) return nullChar;
147 return *(impl->s+i);
150 int DOMString::find(const QChar c, int start) const
152 unsigned int l = start;
153 if(!impl || l >= impl->l ) return -1;
154 while( l < impl->l )
156 if( *(impl->s+l) == c ) return l;
157 l++;
159 return -1;
162 int DOMString::reverseFind(const QChar c, int start) const
164 unsigned int l = start;
165 if (!impl || l < -impl->l) return -1;
166 l += impl->l;
167 while (1) {
168 if (*(impl->s + l) == c) return l;
169 l--;
170 if (l == 0)
171 return -1;
173 return -1;
176 DOMString DOMString::substring(unsigned pos, unsigned len) const
178 return (impl) ? impl->substring(pos, len) : DOMString();
181 uint DOMString::length() const
183 if(!impl) return 0;
184 return impl->l;
187 void DOMString::truncate( unsigned int len )
189 if(impl) impl->truncate(len);
192 void DOMString::remove(unsigned int pos, int len)
194 if(impl) impl->remove(pos, len);
197 DOMString DOMString::split(unsigned int pos)
199 if(!impl) return DOMString();
200 return impl->split(pos);
203 DOMString DOMString::lower() const
205 if(!impl) return DOMString();
206 return impl->lower();
209 DOMString DOMString::upper() const
211 if(!impl) return DOMString();
212 return impl->upper();
215 bool DOMString::percentage(int &_percentage) const
217 if(!impl || !impl->l) return false;
219 if ( *(impl->s+impl->l-1) != QChar('%'))
220 return false;
222 _percentage = QString::fromRawData(impl->s, impl->l-1).toInt();
223 return true;
226 QChar *DOMString::unicode() const
228 if(!impl) return 0;
229 return impl->unicode();
232 QString DOMString::string() const
234 if(!impl) return QString();
236 return impl->string();
239 int DOMString::toInt() const
241 if(!impl) return 0;
243 return impl->toInt();
246 int DOMString::toInt(bool* ok) const
248 if (!impl) {
249 *ok = false;
250 return 0;
253 return impl->toInt(ok);
256 float DOMString::toFloat(bool* ok) const
258 if (!impl) {
259 if (ok)
260 *ok = false;
261 return 0;
263 return impl->toInt(ok);
266 DOMString DOMString::number(float f)
268 return DOMString(QString::number(f));
271 DOMString DOMString::copy() const
273 if(!impl) return DOMString();
274 return impl->copy();
277 bool DOMString::endsWith(const DOMString& str) const
279 if (str.length() > length()) return false;
280 return impl->endsWith(str.implementation());
283 bool DOMString::startsWith(const DOMString& str) const
285 if (str.length() > length()) return false;
286 return impl->startsWith(str.implementation());
289 // ------------------------------------------------------------------------
291 bool DOM::strcasecmp( const DOMString &as, const DOMString &bs )
293 return strcasecmp(as.implementation(), bs.implementation());
296 bool DOM::strcasecmp( const DOMString &as, const char* bs )
298 const QChar *a = as.unicode();
299 int l = as.length();
300 if ( !bs ) return ( l != 0 );
301 while ( l-- ) {
302 if ( a->toLatin1() != *bs ) {
303 char cc = ( ( *bs >= 'A' ) && ( *bs <= 'Z' ) ) ? ( ( *bs ) + 'a' - 'A' ) : ( *bs );
304 if ( a->toLower().toLatin1() != cc ) return true;
306 a++, bs++;
308 return ( *bs != '\0' );
311 bool DOMString::isEmpty() const
313 return (!impl || impl->l == 0);
316 DOMString DOMString::format(const char *format, ...)
318 va_list args;
319 va_start(args, format);
321 Vector<char, 256> buffer;
323 // Do the format once to get the length.
324 #if COMPILER(MSVC)
325 int result = _vscprintf(format, args);
326 #else
327 char ch;
328 int result = vsnprintf(&ch, 1, format, args);
329 // We need to call va_end() and then va_start() again here, as the
330 // contents of args is undefined after the call to vsnprintf
331 // according to http://man.cx/snprintf(3)
333 // Not calling va_end/va_start here happens to work on lots of
334 // systems, but fails e.g. on 64bit Linux.
335 va_end(args);
336 va_start(args, format);
337 #endif
339 if (result == 0)
340 return DOMString("");
341 if (result < 0)
342 return DOMString();
343 unsigned len = result;
344 buffer.grow(len + 1);
346 // Now do the formatting again, guaranteed to fit.
347 vsnprintf(buffer.data(), buffer.size(), format, args);
349 va_end(args);
351 buffer[len] = 0; // we don't really need this I guess
352 return new DOMStringImpl(buffer.data()/*, len*/);
355 //-----------------------------------------------------------------------------
357 bool DOM::operator==( const DOMString &a, const DOMString &b )
359 return !strcmp(a.implementation(), b.implementation());
362 bool DOM::operator==( const DOMString &a, const QString &b )
364 int l = a.length();
366 if( l != b.length() ) return false;
368 if(!memcmp(a.unicode(), b.unicode(), l*sizeof(QChar)))
369 return true;
370 return false;
373 bool DOM::operator==( const DOMString &a, const char *b )
375 DOMStringImpl* aimpl = a.impl;
376 if ( !b ) return !aimpl;
378 if ( aimpl ) {
379 int alen = aimpl->l;
380 const QChar *aptr = aimpl->s;
381 while ( alen-- ) {
382 unsigned char c = *b++;
383 if ( !c || ( *aptr++ ).unicode() != c )
384 return false;
388 return !*b;