ustring.cpp

来自「konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版」· C++ 代码 · 共 978 行 · 第 1/2 页

CPP
978
字号
// -*- c-basic-offset: 2 -*-/* *  This file is part of the KDE libraries *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org) *  Copyright (C) 2003 Apple Computer, Inc. * *  This library is free software; you can redistribute it and/or *  modify it under the terms of the GNU Library General Public *  License as published by the Free Software Foundation; either *  version 2 of the License, or (at your option) any later version. * *  This library is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *  Library General Public License for more details. * *  You should have received a copy of the GNU Library General Public License *  along with this library; see the file COPYING.LIB.  If not, write to *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *  Boston, MA 02110-1301, USA. * */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <stdlib.h>#include <stdio.h>#include <ctype.h>#ifdef HAVE_STRING_H#include <string.h>#endif#ifdef HAVE_STRINGS_H#include <strings.h>#endif#include "ustring.h"#include "operations.h"#include "identifier.h"#include <math.h>#include "dtoa.h"namespace KJS {  extern const double NaN;  extern const double Inf;}using namespace KJS;CString::CString(const char *c){  length = strlen(c);  data = new char[length+1];  memcpy(data, c, length + 1);}CString::CString(const char *c, int len){  length = len;  data = new char[len+1];  memcpy(data, c, len);  data[len] = 0;}CString::CString(const CString &b){  length = b.length;  data = new char[length+1];  memcpy(data, b.data, length + 1);}CString::~CString(){  delete [] data;}CString &CString::append(const CString &t){  char *n = new char[length + t.length + 1];  if (length)    memcpy(n, data, length);  if (t.length)    memcpy(n+length, t.data, t.length);  length += t.length;  n[length] = 0;  delete [] data;  data = n;  return *this;}CString &CString::operator=(const char *c){  delete [] data;  length = strlen(c);  data = new char[length+1];  memcpy(data, c, length + 1);  return *this;}CString &CString::operator=(const CString &str){  if (this == &str)    return *this;  delete [] data;  length = str.length;  data = new char[length + 1];  memcpy(data, str.data, length + 1);  return *this;}bool KJS::operator==(const KJS::CString& c1, const KJS::CString& c2){  int len = c1.size();  return len == c2.size() && (len == 0 || memcmp(c1.c_str(), c2.c_str(), len) == 0);}UChar UChar::null((char)0);UString::Rep UString::Rep::null = { 0, 0, 0, 1, 1 };UString::Rep UString::Rep::empty = { 0, 0, 0, 1, 1 };UString UString::null;static const int normalStatBufferSize = 4096;static char *statBuffer = 0;static int statBufferSize = 0;UChar UChar::toLower() const{  // ### properly support unicode tolower  if (uc >= 256 || islower(uc))    return *this;  return (unsigned char)tolower(uc);}UChar UChar::toUpper() const{  if (uc >= 256 || isupper(uc))    return *this;  return (unsigned char)toupper(uc);}UCharReference& UCharReference::operator=(UChar c){  str->detach();  if (offset < str->rep->len)    *(str->rep->dat + offset) = c;  /* TODO: lengthen string ? */  return *this;}UChar& UCharReference::ref() const{  if (offset < str->rep->len)    return *(str->rep->dat + offset);  else    return UChar::null;}// return an uninitialized UChar array of size sstatic inline UChar* allocateChars(int s){  // work around default UChar constructor code  return reinterpret_cast<UChar*>(new short[s]);}UString::Rep *UString::Rep::create(UChar *d, int l){  Rep *r = new Rep;  r->dat = d;  r->len = l;  r->capacity = l;  r->rc = 1;  r->_hash = 0;  return r;}void UString::Rep::destroy(){  if (capacity == capacityForIdentifier)    Identifier::remove(this);  delete [] dat;  delete this;}// Golden ratio - arbitrary start value to avoid mapping all 0's to all 0's// or anything like that.const unsigned PHI = 0x9e3779b9U;// This hash algorithm comes from:// http://burtleburtle.net/bob/hash/hashfaq.html// http://burtleburtle.net/bob/hash/doobs.htmlunsigned UString::Rep::computeHash(const UChar *s, int length){    int prefixLength = length < 8 ? length : 8;    int suffixPosition = length < 16 ? 8 : length - 8;    unsigned h = PHI;    h += length;    h += (h << 10);    h ^= (h << 6);    for (int i = 0; i < prefixLength; i++) {        h += s[i].uc;	h += (h << 10);	h ^= (h << 6);    }    for (int i = suffixPosition; i < length; i++){        h += s[i].uc;	h += (h << 10);	h ^= (h << 6);    }    h += (h << 3);    h ^= (h >> 11);    h += (h << 15);    if (h == 0)        h = 0x80000000;    return h;}// This hash algorithm comes from:// http://burtleburtle.net/bob/hash/hashfaq.html// http://burtleburtle.net/bob/hash/doobs.htmlunsigned UString::Rep::computeHash(const char *s){    int length = strlen(s);    int prefixLength = length < 8 ? length : 8;    int suffixPosition = length < 16 ? 8 : length - 8;    unsigned h = PHI;    h += length;    h += (h << 10);    h ^= (h << 6);    for (int i = 0; i < prefixLength; i++) {        h += (unsigned char)s[i];	h += (h << 10);	h ^= (h << 6);    }    for (int i = suffixPosition; i < length; i++) {        h += (unsigned char)s[i];	h += (h << 10);	h ^= (h << 6);    }    h += (h << 3);    h ^= (h >> 11);    h += (h << 15);    if (h == 0)        h = 0x80000000;    return h;}UString::UString(){  null.rep = &Rep::null;  attach(&Rep::null);}UString::UString(char c){    UChar *d = allocateChars(1);    d[0] = c;    rep = Rep::create(d, 1);}UString::UString(const char *c){  if (!c) {    attach(&Rep::null);    return;  }  int length = strlen(c);  if (length == 0) {    attach(&Rep::empty);    return;  }  UChar *d = new UChar[length];  for (int i = 0; i < length; i++)    d[i].uc = c[i];  rep = Rep::create(d, length);}UString::UString(const UChar *c, int length){  if (length == 0) {    attach(&Rep::empty);    return;  }  UChar *d = allocateChars(length);  memcpy(d, c, length * sizeof(UChar));  rep = Rep::create(d, length);}UString::UString(UChar *c, int length, bool copy){  if (length == 0) {    attach(&Rep::empty);    return;  }  UChar *d;  if (copy) {    d = allocateChars(length);    memcpy(d, c, length * sizeof(UChar));  } else    d = c;  rep = Rep::create(d, length);}UString::UString(const UString &a, const UString &b){  int aSize = a.size();  int bSize = b.size();  int length = aSize + bSize;  if (length == 0) {    attach(&Rep::empty);    return;  }  UChar *d = allocateChars(length);  memcpy(d, a.data(), aSize * sizeof(UChar));  memcpy(d + aSize, b.data(), bSize * sizeof(UChar));  rep = Rep::create(d, length);}UString UString::from(int i){  return from((long)i);}UString UString::from(unsigned int u){  UChar buf[20];  UChar *end = buf + 20;  UChar *p = end;  if (u == 0) {    *--p = '0';  } else {    while (u) {      *--p = (unsigned short)((u % 10) + '0');      u /= 10;    }  }  return UString(p, end - p);}UString UString::from(long l){  UChar buf[20];  UChar *end = buf + 20;  UChar *p = end;  if (l == 0) {    *--p = '0';  } else {    bool negative = false;    if (l < 0) {      negative = true;      l = -l;    }    while (l) {      *--p = (unsigned short)((l % 10) + '0');      l /= 10;    }    if (negative) {      *--p = '-';    }  }  return UString(p, end - p);}UString UString::from(double d){  char buf[80];  int decimalPoint;  int sign;  char *result = kjs_dtoa(d, 0, 0, &decimalPoint, &sign, NULL);  int length = strlen(result);  int i = 0;  if (sign) {    buf[i++] = '-';  }  if (decimalPoint <= 0 && decimalPoint > -6) {    buf[i++] = '0';    buf[i++] = '.';    for (int j = decimalPoint; j < 0; j++) {      buf[i++] = '0';    }    strcpy(buf + i, result);  } else if (decimalPoint <= 21 && decimalPoint > 0) {    if (length <= decimalPoint) {      strcpy(buf + i, result);      i += length;      for (int j = 0; j < decimalPoint - length; j++) {	buf[i++] = '0';      }      buf[i] = '\0';    } else {      strncpy(buf + i, result, decimalPoint);      i += decimalPoint;      buf[i++] = '.';      strcpy(buf + i, result + decimalPoint);    }  } else if (result[0] < '0' || result[0] > '9') {    strcpy(buf + i, result);  } else {    buf[i++] = result[0];    if (length > 1) {      buf[i++] = '.';      strcpy(buf + i, result + 1);      i += length - 1;    }    buf[i++] = 'e';    buf[i++] = (decimalPoint >= 0) ? '+' : '-';    // decimalPoint can't be more than 3 digits decimal given the    // nature of float representation    int exponential = decimalPoint - 1;    if (exponential < 0) {      exponential = exponential * -1;    }    if (exponential >= 100) {      buf[i++] = '0' + exponential / 100;    }    if (exponential >= 10) {      buf[i++] = '0' + (exponential % 100) / 10;    }    buf[i++] = '0' + exponential % 10;    buf[i++] = '\0';  }  kjs_freedtoa(result);  return UString(buf);}UString &UString::append(const UString &t){  int l = size();  int tLen = t.size();  int newLen = l + tLen;  if (rep->rc == 1 && newLen <= rep->capacity) {    memcpy(rep->dat+l, t.data(), tLen * sizeof(UChar));    rep->len = newLen;    rep->_hash = 0;    return *this;  }  int newCapacity = (newLen * 3 + 1) / 2;  UChar *n = allocateChars(newCapacity);  memcpy(n, data(), l * sizeof(UChar));  memcpy(n+l, t.data(), tLen * sizeof(UChar));  release();  rep = Rep::create(n, newLen);  rep->capacity = newCapacity;  return *this;}CString UString::cstring() const{  return ascii();}char *UString::ascii() const{  // Never make the buffer smaller than normalStatBufferSize.  // Thus we almost never need to reallocate.  int length = size();  int neededSize = length + 1;  if (neededSize < normalStatBufferSize) {    neededSize = normalStatBufferSize;  }  if (neededSize != statBufferSize) {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?