khtml Library API Documentation

dom_stringimpl.cpp

00001 
00026 #include "dom_stringimpl.h"
00027 
00028 #include <kdebug.h>
00029 
00030 #include <string.h>
00031 
00032 using namespace DOM;
00033 using namespace khtml;
00034 
00035 
00036 DOMStringImpl::DOMStringImpl(const char *str)
00037 {
00038     if(str && *str)
00039     {
00040         l = strlen(str);
00041         s = QT_ALLOC_QCHAR_VEC( l );
00042         int i = l;
00043         QChar* ptr = s;
00044         while( i-- )
00045             *ptr++ = *str++;
00046     }
00047     else
00048     {
00049         s = QT_ALLOC_QCHAR_VEC( 1 );  // crash protection
00050         s[0] = 0x0; // == QChar::null;
00051         l = 0;
00052     }
00053 }
00054 
00055 void DOMStringImpl::append(DOMStringImpl *str)
00056 {
00057     if(str && str->l != 0)
00058     {
00059         int newlen = l+str->l;
00060         QChar *c = QT_ALLOC_QCHAR_VEC(newlen);
00061         memcpy(c, s, l*sizeof(QChar));
00062         memcpy(c+l, str->s, str->l*sizeof(QChar));
00063         if(s) QT_DELETE_QCHAR_VEC(s);
00064         s = c;
00065         l = newlen;
00066     }
00067 }
00068 
00069 void DOMStringImpl::insert(DOMStringImpl *str, uint pos)
00070 {
00071     if(pos > l)
00072     {
00073         append(str);
00074         return;
00075     }
00076     if(str && str->l != 0)
00077     {
00078         int newlen = l+str->l;
00079         QChar *c = QT_ALLOC_QCHAR_VEC(newlen);
00080         memcpy(c, s, pos*sizeof(QChar));
00081         memcpy(c+pos, str->s, str->l*sizeof(QChar));
00082         memcpy(c+pos+str->l, s+pos, (l-pos)*sizeof(QChar));
00083         if(s) QT_DELETE_QCHAR_VEC(s);
00084         s = c;
00085         l = newlen;
00086     }
00087 }
00088 
00089 void DOMStringImpl::truncate(int len)
00090 {
00091     if(len > (int)l) return;
00092 
00093     int nl = len < 1 ? 1 : len;
00094     QChar *c = QT_ALLOC_QCHAR_VEC(nl);
00095     memcpy(c, s, nl*sizeof(QChar));
00096     if(s) QT_DELETE_QCHAR_VEC(s);
00097     s = c;
00098     l = len;
00099 }
00100 
00101 void DOMStringImpl::remove(uint pos, int len)
00102 {
00103   if(pos >= l ) return;
00104   if(pos+len > l)
00105     len = l - pos;
00106 
00107   uint newLen = l-len;
00108   QChar *c = QT_ALLOC_QCHAR_VEC(newLen);
00109   memcpy(c, s, pos*sizeof(QChar));
00110   memcpy(c+pos, s+pos+len, (l-len-pos)*sizeof(QChar));
00111   if(s) QT_DELETE_QCHAR_VEC(s);
00112   s = c;
00113   l = newLen;
00114 }
00115 
00116 DOMStringImpl *DOMStringImpl::split(uint pos)
00117 {
00118   if( pos >=l ) return new DOMStringImpl();
00119 
00120   uint newLen = l-pos;
00121   QChar *c = QT_ALLOC_QCHAR_VEC(newLen);
00122   memcpy(c, s+pos, newLen*sizeof(QChar));
00123 
00124   DOMStringImpl *str = new DOMStringImpl(s + pos, newLen);
00125   truncate(pos);
00126   return str;
00127 }
00128 
00129 DOMStringImpl *DOMStringImpl::substring(uint pos, uint len)
00130 {
00131   if( pos >=l ) return new DOMStringImpl();
00132   if(pos+len > l)
00133     len = l - pos;
00134 
00135   return new DOMStringImpl(s + pos, len);
00136 }
00137 
00138 static Length parseLength(QChar *s, unsigned int l)
00139 {
00140     const QChar* last = s+l-1;
00141 
00142     if (l && *last == QChar('%')) {
00143         // CSS allows one decimal after the point, like
00144         //  42.2%, but not 42.22%
00145         // we ignore the non-integer part for speed/space reasons
00146         int i = QConstString(s, l).string().findRev('.');
00147         if ( i >= 0 && i < (int)l-1 )
00148             l = i + 1;
00149 
00150         bool ok;
00151         i = QConstString(s, l-1).string().toInt(&ok);
00152 
00153         if (ok)
00154             return Length(i, Percent);
00155 
00156         // in case of weird constructs like 5*%
00157         last--;
00158         l--;
00159     }
00160 
00161     if ( *last == '*') {
00162         if(last == s)
00163             return Length(1, Relative);
00164         else
00165             return Length(QConstString(s, l-1).string().toInt(), Relative);
00166     }
00167 
00168     // should we strip of the non-integer part here also?
00169     // CSS says no, all important browsers do so, including Mozilla. sigh.
00170     bool ok;
00171     // this ugly construct helps in case someone specifies a length as "100."
00172     int v = (int) QConstString(s, l).string().toFloat(&ok);
00173 
00174     if(ok)
00175         return Length(v, Fixed);
00176 
00177     return Length(0, Variable);
00178 }
00179 
00180 Length DOMStringImpl::toLength() const
00181 {
00182     return parseLength(s,l);
00183 }
00184 
00185 khtml::Length* DOMStringImpl::toLengthArray(int& len) const
00186 {
00187     QString str(s, l);
00188     int pos = 0;
00189     int pos2;
00190 
00191     // web authors are so stupid. This is a workaround
00192     // to fix lists like "1,2px 3 ,4"
00193     // make sure not to break percentage or relative widths
00194     // ### what about "auto" ?
00195     QChar space(' ');
00196     for(unsigned int i=0; i < l; i++) {
00197         char cc = str[i].latin1();
00198         if ( cc > '9' || ( cc < '0' && cc != '-' && cc != '*' && cc != '%' && cc != '.') )
00199             str[i] = space;
00200     }
00201     str = str.simplifyWhiteSpace();
00202 
00203     len = str.contains(' ') + 1;
00204     khtml::Length* r = new khtml::Length[len];
00205     int i = 0;
00206     while((pos2 = str.find(' ', pos)) != -1)
00207     {
00208         r[i++] = parseLength((QChar *) str.unicode()+pos, pos2-pos);
00209         pos = pos2+1;
00210     }
00211     r[i] = parseLength((QChar *) str.unicode()+pos, str.length()-pos);
00212 
00213     return r;
00214 }
00215 
00216 bool DOMStringImpl::isLower() const
00217 {
00218     unsigned int i;
00219     for (i = 0; i < l; i++)
00220         if (s[i].lower() != s[i])
00221             return false;
00222     return true;
00223 }
00224 
00225 DOMStringImpl *DOMStringImpl::lower() const
00226 {
00227     DOMStringImpl *c = new DOMStringImpl;
00228     if(!l) return c;
00229 
00230     c->s = QT_ALLOC_QCHAR_VEC(l);
00231     c->l = l;
00232 
00233     for (unsigned int i = 0; i < l; i++)
00234         c->s[i] = s[i].lower();
00235 
00236     return c;
00237 }
00238 
00239 DOMStringImpl *DOMStringImpl::upper() const
00240 {
00241     DOMStringImpl *c = new DOMStringImpl;
00242     if(!l) return c;
00243 
00244     c->s = QT_ALLOC_QCHAR_VEC(l);
00245     c->l = l;
00246 
00247     for (unsigned int i = 0; i < l; i++)
00248         c->s[i] = s[i].upper();
00249 
00250     return c;
00251 }
00252 
00253 DOMStringImpl *DOMStringImpl::capitalize()
00254 {
00255     DOMStringImpl *c = new DOMStringImpl;
00256     if(!l) return c;
00257 
00258     c->s = QT_ALLOC_QCHAR_VEC(l);
00259     c->l = l;
00260 
00261     if ( l ) c->s[0] = s[0].upper();
00262     for (unsigned int i = 1; i < l; i++)
00263         c->s[i] = s[i-1].isLetterOrNumber() ? s[i] : s[i].upper();
00264 
00265     return c;
00266 }
00267 
00268 int DOMStringImpl::toInt(bool* ok) const
00269 {
00270     // match \s*[+-]?\d*
00271     unsigned i = 0;
00272     while (i < l && s[i].isSpace())
00273         ++i;
00274     if (i < l && (s[i] == '+' || s[i] == '-'))
00275         ++i;
00276     while (i < l && s[i].isDigit())
00277         ++i;
00278 
00279     return QConstString(s, i).string().toInt(ok);
00280 }
00281 
00282 
00283 
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Jan 28 13:33:48 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001