dom_stringimpl.cpp [plain text]
#include "dom_stringimpl.h"
#include <kdebug.h>
#include <string.h>
using namespace DOM;
using namespace khtml;
namespace DOM {
using khtml::Fixed;
DOMStringImpl::DOMStringImpl(const char *str)
{
if(str && *str)
{
l = strlen(str);
s = QT_ALLOC_QCHAR_VEC( l );
int i = l;
QChar* ptr = s;
while( i-- )
*ptr++ = *str++;
}
else
{
s = QT_ALLOC_QCHAR_VEC( 1 ); s[0] = 0x0; l = 0;
}
}
void DOMStringImpl::append(DOMStringImpl *str)
{
if(str && str->l != 0)
{
int newlen = l+str->l;
QChar *c = QT_ALLOC_QCHAR_VEC(newlen);
memcpy(c, s, l*sizeof(QChar));
memcpy(c+l, str->s, str->l*sizeof(QChar));
if(s) QT_DELETE_QCHAR_VEC(s);
s = c;
l = newlen;
}
}
void DOMStringImpl::insert(DOMStringImpl *str, uint pos)
{
if(pos > l)
{
append(str);
return;
}
if(str && str->l != 0)
{
int newlen = l+str->l;
QChar *c = QT_ALLOC_QCHAR_VEC(newlen);
memcpy(c, s, pos*sizeof(QChar));
memcpy(c+pos, str->s, str->l*sizeof(QChar));
memcpy(c+pos+str->l, s+pos, (l-pos)*sizeof(QChar));
if(s) QT_DELETE_QCHAR_VEC(s);
s = c;
l = newlen;
}
}
void DOMStringImpl::truncate(int len)
{
if(len > (int)l) return;
int nl = len < 1 ? 1 : len;
QChar *c = QT_ALLOC_QCHAR_VEC(nl);
memcpy(c, s, nl*sizeof(QChar));
if(s) QT_DELETE_QCHAR_VEC(s);
s = c;
l = len;
}
void DOMStringImpl::remove(uint pos, int len)
{
if(len <= 0) return;
if(pos >= l ) return;
if((unsigned)len > l - pos)
len = l - pos;
uint newLen = l-len;
QChar *c = QT_ALLOC_QCHAR_VEC(newLen);
memcpy(c, s, pos*sizeof(QChar));
memcpy(c+pos, s+pos+len, (l-len-pos)*sizeof(QChar));
if(s) QT_DELETE_QCHAR_VEC(s);
s = c;
l = newLen;
}
DOMStringImpl *DOMStringImpl::split(uint pos)
{
if( pos >=l ) return new DOMStringImpl();
uint newLen = l-pos;
QChar *c = QT_ALLOC_QCHAR_VEC(newLen);
memcpy(c, s+pos, newLen*sizeof(QChar));
DOMStringImpl *str = new DOMStringImpl(s + pos, newLen);
truncate(pos);
return str;
}
bool DOMStringImpl::containsOnlyWhitespace() const
{
if (!s)
return true;
for (uint i = 0; i < l; i++) {
QChar c = s[i];
if (c.unicode() <= 0x7F) {
if (!isspace(c.unicode()))
return false;
}
else
return false;
}
return true;
}
DOMStringImpl *DOMStringImpl::substring(uint pos, uint len)
{
if( pos >=l ) return new DOMStringImpl();
if(len > l - pos)
len = l - pos;
return new DOMStringImpl(s + pos, len);
}
static Length parseLength(QChar *s, unsigned int l)
{
const QChar* last = s+l-1;
if ( *last == QChar('%')) {
int i = QConstString(s, l).string().findRev('.');
if ( i >= 0 && i < (int)l-1 )
l = i + 1;
return Length(QConstString(s, l-1).string().toInt(), Percent);
}
if ( *last == QChar('*'))
{
if(l == 1)
return Length(1, Relative);
else
return Length(QConstString(s, l-1).string().toInt(), Relative);
}
bool ok;
int v = (int) QConstString(s, l).string().toFloat(&ok);
if(ok) {
return Length(v, Fixed);
}
return Length(0, Variable);
}
Length DOMStringImpl::toLength() const
{
return parseLength(s,l);
}
khtml::Length* DOMStringImpl::toLengthArray(int& len) const
{
#if !APPLE_CHANGES
QString str(s, l);
#endif
int pos = 0;
int pos2;
#if APPLE_CHANGES
QChar spacified[l];
QChar space(' ');
for(unsigned int i=0; i < l; i++) {
QChar cc = s[i];
if ( cc > '9' || ( cc < '0' && cc != '-' && cc != '*' && cc != '%' && cc != '.') ){
spacified[i] = space;
}
else {
spacified[i] = cc;
}
}
QString str(spacified, l);
#else
QChar space(' ');
for(unsigned int i=0; i < l; i++) {
char cc = str[i].latin1();
if ( cc > '9' || ( cc < '0' && cc != '-' && cc != '*' && cc != '%' && cc != '.') )
str[i] = space;
}
#endif
str = str.simplifyWhiteSpace();
len = str.contains(' ') + 1;
khtml::Length* r = new khtml::Length[len];
int i = 0;
while((pos2 = str.find(' ', pos)) != -1)
{
r[i++] = parseLength((QChar *) str.unicode()+pos, pos2-pos);
pos = pos2+1;
}
r[i] = parseLength((QChar *) str.unicode()+pos, str.length()-pos);
return r;
}
bool DOMStringImpl::isLower() const
{
unsigned int i;
for (i = 0; i < l; i++)
if (s[i].lower() != s[i])
return false;
return true;
}
DOMStringImpl *DOMStringImpl::lower() const
{
DOMStringImpl *c = new DOMStringImpl;
if(!l) return c;
c->s = QT_ALLOC_QCHAR_VEC(l);
c->l = l;
for (unsigned int i = 0; i < l; i++)
c->s[i] = s[i].lower();
return c;
}
DOMStringImpl *DOMStringImpl::upper() const
{
DOMStringImpl *c = new DOMStringImpl;
if(!l) return c;
c->s = QT_ALLOC_QCHAR_VEC(l);
c->l = l;
for (unsigned int i = 0; i < l; i++)
c->s[i] = s[i].upper();
return c;
}
DOMStringImpl *DOMStringImpl::capitalize() const
{
DOMStringImpl *c = new DOMStringImpl;
if(!l) return c;
c->s = QT_ALLOC_QCHAR_VEC(l);
c->l = l;
if ( l ) c->s[0] = s[0].upper();
for (unsigned int i = 1; i < l; i++)
c->s[i] = s[i-1].isLetterOrNumber() ? s[i] : s[i].upper();
return c;
}
int DOMStringImpl::toInt(bool *ok) const
{
unsigned i = 0;
for (; i != l; ++i) {
if (!s[i].isSpace()) {
break;
}
}
if (i != l) {
if (s[i] == '+' || s[i] == '-') {
++i;
}
}
for (; i != l; ++i) {
if (!s[i].isDigit()) {
break;
}
}
return QConstString(s, i).string().toInt(ok);
}
DOMStringImpl *DOMStringImpl::replace(QChar oldC, QChar newC)
{
if (oldC == newC)
return this;
unsigned i;
for (i = 0; i != l; ++i)
if (s[i] == oldC)
break;
if (i == l)
return this;
DOMStringImpl *c = new DOMStringImpl;
c->s = QT_ALLOC_QCHAR_VEC(l);
c->l = l;
for (i = 0; i != l; ++i) {
QChar ch = s[i];
if (ch == oldC)
ch = newC;
c->s[i] = ch;
}
return c;
}
}