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 + -
显示快捷键?