summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/DeprecatedString.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/platform/DeprecatedString.cpp')
-rw-r--r--WebCore/platform/DeprecatedString.cpp2679
1 files changed, 0 insertions, 2679 deletions
diff --git a/WebCore/platform/DeprecatedString.cpp b/WebCore/platform/DeprecatedString.cpp
deleted file mode 100644
index 3656224..0000000
--- a/WebCore/platform/DeprecatedString.cpp
+++ /dev/null
@@ -1,2679 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "DeprecatedString.h"
-
-#include "CString.h"
-#include "FloatConversion.h"
-#include "Logging.h"
-#include "PlatformString.h"
-#include "RegularExpression.h"
-#include "TextEncoding.h"
-#include <kjs/dtoa.h>
-#include <kjs/identifier.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <wtf/Platform.h>
-#include <wtf/StringExtras.h>
-
-#if PLATFORM(WIN_OS)
-#include <windows.h>
-#endif
-
-#if PLATFORM(QT)
-#include <QString>
-#endif
-
-using namespace std;
-using namespace KJS;
-using namespace WTF;
-
-namespace WebCore {
-
-COMPILE_ASSERT(sizeof(DeprecatedChar) == 2, deprecated_char_is_2_bytes)
-
-#define CHECK_FOR_HANDLE_LEAKS 0
-
-#if PLATFORM(SYMBIAN)
-#undef CHECK_FOR_HANDLE_LEAKS
-// symbian:fixme need page aligned allocations as Symbian platform does not have support for valloc
-#define CHECK_FOR_HANDLE_LEAKS 1
-#endif
-
-#define ALLOC_QCHAR_GOOD_SIZE(X) (X)
-#define ALLOC_CHAR_GOOD_SIZE(X) (X)
-
-#define ALLOC_CHAR(N) (char*)fastMalloc(N)
-#define REALLOC_CHAR(P, N) (char *)fastRealloc(P, N)
-#define DELETE_CHAR(P) fastFree(P)
-
-#define WEBCORE_ALLOCATE_CHARACTERS(N) (DeprecatedChar*)fastMalloc(sizeof(DeprecatedChar)*(N))
-#define WEBCORE_REALLOCATE_CHARACTERS(P, N) (DeprecatedChar *)fastRealloc(P, sizeof(DeprecatedChar)*(N))
-#define DELETE_QCHAR(P) fastFree(P)
-
-#ifndef CHECK_FOR_HANDLE_LEAKS
-struct HandleNode;
-struct HandlePageNode;
-
-static HandleNode *allocateNode(HandlePageNode *pageNode);
-static HandlePageNode *allocatePageNode();
-
-static HandlePageNode *usedNodeAllocationPages = 0;
-static HandlePageNode *freeNodeAllocationPages = 0;
-
-static inline void initializeHandleNodes()
-{
- if (freeNodeAllocationPages == 0)
- freeNodeAllocationPages = allocatePageNode();
-}
-#endif
-
-static inline DeprecatedStringData **allocateHandle()
-{
-#ifdef CHECK_FOR_HANDLE_LEAKS
- return static_cast<DeprecatedStringData **>(fastMalloc(sizeof(DeprecatedStringData *)));
-#else
-
- initializeHandleNodes();
-
- return reinterpret_cast<DeprecatedStringData **>(allocateNode(freeNodeAllocationPages));
-#endif
-}
-
-static void freeHandle(DeprecatedStringData **);
-
-#define IS_ASCII_QCHAR(c) ((c).unicode() > 0 && (c).unicode() <= 0xff)
-
-static const int caseDelta = ('a' - 'A');
-
-const char * const DeprecatedString::null = 0;
-
-DeprecatedStringData *DeprecatedString::shared_null = 0;
-DeprecatedStringData **DeprecatedString::shared_null_handle = 0;
-
-// -------------------------------------------------------------------------
-// Utility functions
-// -------------------------------------------------------------------------
-
-static inline int ucstrcmp( const DeprecatedString &as, const DeprecatedString &bs )
-{
- const DeprecatedChar *a = as.unicode();
- const DeprecatedChar *b = bs.unicode();
- if ( a == b )
- return 0;
- if ( a == 0 )
- return 1;
- if ( b == 0 )
- return -1;
- int l = min(as.length(), bs.length());
- while ( l-- && *a == *b )
- a++,b++;
- if ( l == -1 )
- return ( as.length() - bs.length() );
- return a->unicode() - b->unicode();
-}
-
-static bool equal(const DeprecatedChar *a, const char *b, int l)
-{
- ASSERT(l >= 0);
- while (l--) {
- if (*a != *b)
- return false;
- a++; b++;
- }
- return true;
-}
-
-// Not a "true" case insensitive compare; only insensitive for plain ASCII.
-
-static bool equalCaseInsensitive(const char *a, const char *b, int l)
-{
- ASSERT(l >= 0);
- while (l--) {
- if (toASCIILower(*a) != toASCIILower(*b))
- return false;
- a++; b++;
- }
- return true;
-}
-
-static bool equalCaseInsensitive(const DeprecatedChar *a, const char *b, int l)
-{
- ASSERT(l >= 0);
- while (l--) {
- if (toASCIILower(a->unicode()) != static_cast<unsigned char>(toASCIILower(*b)))
- return false;
- a++; b++;
- }
- return true;
-}
-
-static bool equalCaseInsensitive(const DeprecatedChar *a, const DeprecatedChar *b, int l)
-{
- ASSERT(l >= 0);
- while (l--) {
- if (toASCIILower(a->unicode()) != toASCIILower(b->unicode()))
- return false;
- a++; b++;
- }
- return true;
-}
-
-static inline bool equalCaseInsensitive(char c1, char c2)
-{
- return toASCIILower(c1) == toASCIILower(c2);
-}
-
-static inline bool equalCaseInsensitive(DeprecatedChar c1, char c2)
-{
- return toASCIILower(c1.unicode()) == static_cast<unsigned char>(toASCIILower(c2));
-}
-
-static bool isCharacterAllowedInBase(DeprecatedChar c, int base)
-{
- ::UChar uc = c.unicode();
- if (uc > 0x7F)
- return false;
- if (isASCIIDigit(uc))
- return uc - '0' < base;
- if (isASCIIAlpha(uc)) {
- if (base > 36)
- base = 36;
- return (uc >= 'a' && uc < 'a' + base - 10)
- || (uc >= 'A' && uc < 'A' + base - 10);
- }
- return false;
-}
-
-// -------------------------------------------------------------------------
-// DeprecatedStringData
-// -------------------------------------------------------------------------
-
-// FIXME, make constructor explicity take a 'copy' flag.
-// This can be used to hand off ownership of allocated data when detaching and
-// deleting QStrings.
-
-DeprecatedStringData::DeprecatedStringData() :
- refCount(1), _length(0), _unicode(0), _ascii(0), _maxUnicode(WEBCORE_DS_INTERNAL_BUFFER_UCHARS), _isUnicodeValid(0), _isHeapAllocated(0), _maxAscii(WEBCORE_DS_INTERNAL_BUFFER_CHARS), _isAsciiValid(1)
-{
- _ascii = _internalBuffer;
- _internalBuffer[0] = 0;
-}
-
-void DeprecatedStringData::initialize()
-{
- refCount = 1;
- _length = 0;
- _unicode = 0;
- _ascii = _internalBuffer;
- _maxUnicode = WEBCORE_DS_INTERNAL_BUFFER_UCHARS;
- _isUnicodeValid = 0;
- _maxAscii = WEBCORE_DS_INTERNAL_BUFFER_CHARS;
- _isAsciiValid = 1;
- _internalBuffer[0] = 0;
- _isHeapAllocated = 0;
-}
-
-// Don't copy data.
-DeprecatedStringData::DeprecatedStringData(DeprecatedChar *u, unsigned l, unsigned m) :
- refCount(1), _length(l), _unicode(u), _ascii(0), _maxUnicode(m), _isUnicodeValid(1), _isHeapAllocated(0), _maxAscii(WEBCORE_DS_INTERNAL_BUFFER_CHARS), _isAsciiValid(0)
-{
- ASSERT(m >= l);
-}
-
-// Don't copy data.
-void DeprecatedStringData::initialize(DeprecatedChar *u, unsigned l, unsigned m)
-{
- ASSERT(m >= l);
- refCount = 1;
- _length = l;
- _unicode = u;
- _ascii = 0;
- _maxUnicode = m;
- _isUnicodeValid = 1;
- _maxAscii = 0;
- _isAsciiValid = 0;
- _isHeapAllocated = 0;
-}
-
-// Copy data
-DeprecatedStringData::DeprecatedStringData(const DeprecatedChar *u, unsigned l)
-{
- initialize (u, l);
-}
-
-// Copy data
-void DeprecatedStringData::initialize(const DeprecatedChar *u, unsigned l)
-{
- refCount = 1;
- _length = l;
- _ascii = 0;
- _isUnicodeValid = 1;
- _maxAscii = 0;
- _isAsciiValid = 0;
- _isHeapAllocated = 0;
-
- if (l > WEBCORE_DS_INTERNAL_BUFFER_UCHARS) {
- _maxUnicode = ALLOC_QCHAR_GOOD_SIZE(l);
- _unicode = WEBCORE_ALLOCATE_CHARACTERS(_maxUnicode);
- memcpy(_unicode, u, l*sizeof(DeprecatedChar));
- } else {
- _maxUnicode = WEBCORE_DS_INTERNAL_BUFFER_UCHARS;
- _unicode = (DeprecatedChar *)_internalBuffer;
- if (l)
- memcpy(_internalBuffer, u, l*sizeof(DeprecatedChar));
- }
-}
-
-
-// Copy data
-DeprecatedStringData::DeprecatedStringData(const char *a, unsigned l)
-{
- initialize(a, l);
-}
-
-
-// Copy data
-void DeprecatedStringData::initialize(const char *a, unsigned l)
-{
- refCount = 1;
- _length = l;
- _unicode = 0;
- _isUnicodeValid = 0;
- _maxUnicode = 0;
- _isAsciiValid = 1;
- _isHeapAllocated = 0;
-
- if (l > WEBCORE_DS_INTERNAL_BUFFER_CHARS) {
- _maxAscii = ALLOC_CHAR_GOOD_SIZE(l+1);
- _ascii = ALLOC_CHAR(_maxAscii);
- if (a)
- memcpy(_ascii, a, l);
- _ascii[l] = 0;
- } else {
- _maxAscii = WEBCORE_DS_INTERNAL_BUFFER_CHARS;
- _ascii = _internalBuffer;
- if (a)
- memcpy(_internalBuffer, a, l);
- _internalBuffer[l] = 0;
- }
-}
-
-DeprecatedStringData* DeprecatedStringData::createAndAdopt(DeprecatedStringData &o)
-{
- DeprecatedStringData* data = new DeprecatedStringData();
- data->adopt(o);
- return data;
-}
-
-void DeprecatedStringData::adopt(DeprecatedStringData& o)
-{
- ASSERT(refCount == 1);
- _length = o._length;
- _unicode = o._unicode;
- _ascii = o._ascii;
- _maxUnicode = o._maxUnicode;
- _isUnicodeValid = o._isUnicodeValid;
- _isHeapAllocated = 0;
- _maxAscii = o._maxAscii;
- _isAsciiValid = o._isAsciiValid;
-
- // Handle the case where either the Unicode or 8-bit pointer was
- // pointing to the internal buffer. We need to point at the
- // internal buffer in the new object, and copy the characters.
- if (_unicode == reinterpret_cast<DeprecatedChar *>(o._internalBuffer)) {
- if (_isUnicodeValid) {
- ASSERT(!_isAsciiValid || _ascii != o._internalBuffer);
- ASSERT(_length <= WEBCORE_DS_INTERNAL_BUFFER_UCHARS);
- memcpy(_internalBuffer, o._internalBuffer, _length * sizeof(DeprecatedChar));
- _unicode = reinterpret_cast<DeprecatedChar *>(_internalBuffer);
- } else {
- _unicode = 0;
- }
- }
- if (_ascii == o._internalBuffer) {
- if (_isAsciiValid) {
- ASSERT(_length <= WEBCORE_DS_INTERNAL_BUFFER_CHARS);
- memcpy(_internalBuffer, o._internalBuffer, _length);
- _internalBuffer[_length] = 0;
- _ascii = _internalBuffer;
- } else {
- _ascii = 0;
- }
- }
-
- // Clean up the other DeprecatedStringData just enough so that it can be destroyed
- // cleanly. It's not in a good enough state to use, but that's OK. It just
- // needs to be in a state where ~DeprecatedStringData won't do anything harmful,
- // and setting these to 0 will do that (preventing any double-free problems).
- o._unicode = 0;
- o._ascii = 0;
-}
-
-DeprecatedStringData *DeprecatedString::makeSharedNull()
-{
- if (!shared_null) {
- shared_null = new DeprecatedStringData;
- shared_null->ref();
- shared_null->_maxAscii = 0;
- shared_null->_maxUnicode = 0;
- shared_null->_unicode = (DeprecatedChar *)&shared_null->_internalBuffer[0];
- shared_null->_isUnicodeValid = 1;
- }
- return shared_null;
-}
-
-DeprecatedStringData **DeprecatedString::makeSharedNullHandle()
-{
- if (!shared_null_handle) {
- shared_null_handle = allocateHandle();
- *shared_null_handle = makeSharedNull();
- }
- return shared_null_handle;
-}
-
-DeprecatedStringData::~DeprecatedStringData()
-{
- ASSERT(refCount == 0);
- if (_unicode && !isUnicodeInternal())
- DELETE_QCHAR(_unicode);
- if (_ascii && !isAsciiInternal())
- DELETE_CHAR(_ascii);
-}
-
-void DeprecatedStringData::increaseAsciiSize(unsigned size)
-{
- ASSERT(this != DeprecatedString::shared_null);
-
- unsigned newSize = (unsigned)ALLOC_CHAR_GOOD_SIZE((size * 3 + 1) / 2);
-
- if (!_isAsciiValid)
- makeAscii();
- ASSERT(_isAsciiValid);
-
- if (isAsciiInternal()) {
- char *newAscii = ALLOC_CHAR(newSize);
- if (_length)
- memcpy(newAscii, _ascii, _length);
- _ascii = newAscii;
- } else {
- _ascii = REALLOC_CHAR(_ascii, newSize);
- }
-
- _maxAscii = newSize;
- _isAsciiValid = 1;
- _isUnicodeValid = 0;
-}
-
-
-void DeprecatedStringData::increaseUnicodeSize(unsigned size)
-{
- ASSERT(size > _length);
- ASSERT(this != DeprecatedString::shared_null);
-
- unsigned newSize = (unsigned)ALLOC_QCHAR_GOOD_SIZE((size * 3 + 1) / 2);
-
- if (!_isUnicodeValid)
- makeUnicode();
- ASSERT(_isUnicodeValid);
-
- if (isUnicodeInternal()) {
- DeprecatedChar *newUni = WEBCORE_ALLOCATE_CHARACTERS(newSize);
- if (_length)
- memcpy(newUni, _unicode, _length*sizeof(DeprecatedChar));
- _unicode = newUni;
- } else {
- _unicode = WEBCORE_REALLOCATE_CHARACTERS(_unicode, newSize);
- }
-
- _maxUnicode = newSize;
- _isUnicodeValid = 1;
- _isAsciiValid = 0;
-}
-
-
-char *DeprecatedStringData::makeAscii()
-{
- ASSERT(this != DeprecatedString::shared_null);
-
- if (_isUnicodeValid){
- DeprecatedChar copyBuf[WEBCORE_DS_INTERNAL_BUFFER_CHARS];
- DeprecatedChar *str;
-
- if (_ascii && !isAsciiInternal())
- DELETE_QCHAR(_ascii);
-
- if (_length < WEBCORE_DS_INTERNAL_BUFFER_CHARS){
- if (isUnicodeInternal()) {
- unsigned i = _length;
- DeprecatedChar *tp = &copyBuf[0], *fp = _unicode;
- while (i--)
- *tp++ = *fp++;
- str = &copyBuf[0];
- _isUnicodeValid = 0;
- }
- else
- str = _unicode;
- _ascii = _internalBuffer;
- _maxAscii = WEBCORE_DS_INTERNAL_BUFFER_CHARS;
- }
- else {
- unsigned newSize = ALLOC_CHAR_GOOD_SIZE(_length+1);
- _ascii = ALLOC_CHAR(newSize);
- _maxAscii = newSize;
- str = _unicode;
- }
-
- unsigned i = _length;
- char* cp = _ascii;
- while (i--)
- // FIXME: this converts non-Latin1 characters to '\0', which may be not what we want in some cases.
- // In particular, toDouble() may fail to report errors, believing that the string ends earlier
- // than it actually does.
- *cp++ = (*str++).latin1();
- *cp = 0;
-
- _isAsciiValid = 1;
- }
- else if (!_isAsciiValid)
- FATAL("ASCII character cache not valid");
-
- return _ascii;
-}
-
-
-DeprecatedChar *DeprecatedStringData::makeUnicode()
-{
- ASSERT(this != DeprecatedString::shared_null);
-
- if (_isAsciiValid){
- char copyBuf[WEBCORE_DS_INTERNAL_BUFFER_CHARS];
- char *str;
-
- if (_unicode && !isUnicodeInternal())
- DELETE_QCHAR(_unicode);
-
- if (_length <= WEBCORE_DS_INTERNAL_BUFFER_UCHARS){
- if (isAsciiInternal()) {
- unsigned i = _length;
- char *tp = &copyBuf[0], *fp = _ascii;
- while (i--)
- *tp++ = *fp++;
- str = &copyBuf[0];
- _isAsciiValid = 0;
- }
- else
- str = _ascii;
- _unicode = (DeprecatedChar *)_internalBuffer;
- _maxUnicode = WEBCORE_DS_INTERNAL_BUFFER_UCHARS;
- }
- else {
- unsigned newSize = ALLOC_QCHAR_GOOD_SIZE(_length);
- _unicode = WEBCORE_ALLOCATE_CHARACTERS(newSize);
- _maxUnicode = newSize;
- str = _ascii;
- }
- unsigned i = _length;
- DeprecatedChar *cp = _unicode;
- while ( i-- )
- *cp++ = *str++;
-
- _isUnicodeValid = 1;
- }
- else if (!_isUnicodeValid)
- FATAL("invalid character cache");
-
- return _unicode;
-}
-
-
-// -------------------------------------------------------------------------
-// DeprecatedString
-// -------------------------------------------------------------------------
-
-
-DeprecatedString DeprecatedString::number(int n)
-{
- DeprecatedString qs;
- qs.setNum(n);
- return qs;
-}
-
-DeprecatedString DeprecatedString::number(unsigned n)
-{
- DeprecatedString qs;
- qs.setNum(n);
- return qs;
-}
-
-DeprecatedString DeprecatedString::number(long n)
-{
- DeprecatedString qs;
- qs.setNum(n);
- return qs;
-}
-
-DeprecatedString DeprecatedString::number(unsigned long n)
-{
- DeprecatedString qs;
- qs.setNum(n);
- return qs;
-}
-
-DeprecatedString DeprecatedString::number(double n)
-{
- DeprecatedString qs;
- qs.setNum(n);
- return qs;
-}
-
-inline void DeprecatedString::detachIfInternal()
-{
- DeprecatedStringData *oldData = *dataHandle;
- if (oldData->refCount > 1 && oldData == &internalData) {
- DeprecatedStringData *newData = DeprecatedStringData::createAndAdopt(*oldData);
- newData->_isHeapAllocated = 1;
- newData->refCount = oldData->refCount;
- oldData->refCount = 1;
- oldData->deref();
- *dataHandle = newData;
- }
-}
-
-const DeprecatedChar *DeprecatedString::stableUnicode()
-{
- // if we're using the internal data of another string, detach now
- if (!dataHandle[0]->_isHeapAllocated && *dataHandle != &internalData) {
- detach();
- }
- return unicode();
-}
-
-
-DeprecatedString::~DeprecatedString()
-{
- ASSERT(dataHandle);
- ASSERT(dataHandle[0]->refCount != 0);
-
- // Only free the handle if no other string has a reference to the
- // data. The handle will be freed by the string that has the
- // last reference to data.
- bool needToFreeHandle = dataHandle[0]->refCount == 1 && *dataHandle != shared_null;
-
- // Copy our internal data if necessary, other strings still need it.
- detachIfInternal();
-
- // Remove our reference. This should always be the last reference
- // if *dataHandle points to our internal DeprecatedStringData. If we just detached,
- // this will remove the extra ref from the new handle.
- dataHandle[0]->deref();
-
- ASSERT(*dataHandle != &internalData || dataHandle[0]->refCount == 0);
-
- if (needToFreeHandle)
- freeHandle(dataHandle);
-
-#ifndef NDEBUG
- dataHandle = 0;
-#endif
-}
-
-
-DeprecatedString::DeprecatedString()
-{
- internalData.deref();
- dataHandle = makeSharedNullHandle();
- dataHandle[0]->ref();
-}
-
-
-// Careful, just used by DeprecatedConstString
-DeprecatedString::DeprecatedString(DeprecatedStringData *constData, bool /*dummy*/)
-{
- internalData.deref();
- dataHandle = allocateHandle();
- *dataHandle = constData;
-
- // The DeprecatedConstString constructor allocated the DeprecatedStringData.
- constData->_isHeapAllocated = 1;
-}
-
-
-DeprecatedString::DeprecatedString(DeprecatedChar qc)
-{
- dataHandle = allocateHandle();
-
- // Copy the DeprecatedChar.
- if (IS_ASCII_QCHAR(qc)) {
- char c = qc.unicode();
- *dataHandle = &internalData;
- internalData.initialize( &c, 1 );
- }
- else {
- *dataHandle = &internalData;
- internalData.initialize( &qc, 1 );
- }
-}
-
-DeprecatedString::DeprecatedString(const DeprecatedChar *unicode, unsigned length)
-{
- if (!unicode || !length) {
- internalData.deref();
- dataHandle = makeSharedNullHandle();
- dataHandle[0]->ref();
- } else {
- dataHandle = allocateHandle();
-
- // Copy the DeprecatedChar *
- *dataHandle = &internalData;
- internalData.initialize(unicode, length);
- }
-}
-
-DeprecatedString::DeprecatedString(const char *chs)
-{
- if (chs) {
- internalData.initialize(chs,strlen(chs));
- dataHandle = allocateHandle();
- *dataHandle = &internalData;
- } else {
- internalData.deref();
- dataHandle = makeSharedNullHandle();
- dataHandle[0]->ref();
- }
-}
-
-DeprecatedString::DeprecatedString(const char *chs, int len)
-{
- dataHandle = allocateHandle();
- *dataHandle = &internalData;
- internalData.initialize(chs,len);
-}
-
-DeprecatedString::DeprecatedString(const DeprecatedString &qs) : dataHandle(qs.dataHandle)
-{
- internalData.deref();
- dataHandle[0]->ref();
-}
-
-DeprecatedString &DeprecatedString::operator=(const DeprecatedString &qs)
-{
- if (this == &qs)
- return *this;
-
- // Free our handle if it isn't the shared null handle, and if no-one else is using it.
- bool needToFreeHandle = dataHandle != shared_null_handle && dataHandle[0]->refCount == 1;
-
- qs.dataHandle[0]->ref();
- deref();
-
- if (needToFreeHandle)
- freeHandle(dataHandle);
-
- dataHandle = qs.dataHandle;
-
- return *this;
-}
-
-DeprecatedString &DeprecatedString::operator=(const DeprecatedCString &qcs)
-{
- return setLatin1(qcs);
-}
-
-DeprecatedString &DeprecatedString::operator=(const char *chs)
-{
- return setLatin1(chs);
-}
-
-DeprecatedString &DeprecatedString::operator=(DeprecatedChar qc)
-{
- return *this = DeprecatedString(qc);
-}
-
-DeprecatedString &DeprecatedString::operator=(char ch)
-{
- return *this = DeprecatedString(DeprecatedChar(ch));
-}
-
-DeprecatedChar DeprecatedString::at(unsigned i) const
-{
- DeprecatedStringData *thisData = *dataHandle;
-
- if (i >= thisData->_length)
- return 0;
-
- if (thisData->_isAsciiValid) {
- return thisData->_ascii[i];
- }
-
- ASSERT(thisData->_isUnicodeValid);
- return thisData->_unicode[i];
-}
-
-int DeprecatedString::compare(const DeprecatedString& s) const
-{
- if (dataHandle[0]->_isAsciiValid && s.dataHandle[0]->_isAsciiValid)
- return strcmp(ascii(), s.ascii());
- return ucstrcmp(*this,s);
-}
-
-int DeprecatedString::compare(const char *chs) const
-{
- if (!chs)
- return isEmpty() ? 0 : 1;
- DeprecatedStringData *d = dataHandle[0];
- if (d->_isAsciiValid)
- return strcmp(ascii(), chs);
- const DeprecatedChar *s = unicode();
- unsigned len = d->_length;
- for (unsigned i = 0; i != len; ++i) {
- char c2 = chs[i];
- if (!c2)
- return 1;
- DeprecatedChar c1 = s[i];
- if (c1.unicode() < c2)
- return -1;
- if (c1.unicode() > c2)
- return 1;
- }
- return chs[len] ? -1 : 0;
-}
-
-bool DeprecatedString::startsWith( const DeprecatedString& s ) const
-{
- if (dataHandle[0]->_isAsciiValid){
- const char *asc = ascii();
-
- for ( int i =0; i < (int) s.dataHandle[0]->_length; i++ ) {
- if ( i >= (int) dataHandle[0]->_length || asc[i] != s[i] )
- return false;
- }
- }
- else if (dataHandle[0]->_isUnicodeValid){
- const DeprecatedChar *uni = unicode();
-
- for ( int i =0; i < (int) s.dataHandle[0]->_length; i++ ) {
- if ( i >= (int) dataHandle[0]->_length || uni[i] != s[i] )
- return false;
- }
- }
- else
- FATAL("invalid character cache");
-
- return true;
-}
-
-bool DeprecatedString::startsWith(const char *prefix) const
-{
- DeprecatedStringData *data = *dataHandle;
-
- unsigned prefixLength = strlen(prefix);
- if (data->_isAsciiValid) {
- return strncmp(prefix, data->_ascii, prefixLength) == 0;
- } else {
- ASSERT(data->_isUnicodeValid);
- if (prefixLength > data->_length) {
- return false;
- }
- const DeprecatedChar *uni = data->_unicode;
- for (unsigned i = 0; i < prefixLength; ++i) {
- if (uni[i] != prefix[i]) {
- return false;
- }
- }
- return true;
- }
-}
-
-bool DeprecatedString::startsWith(const char *prefix, bool caseSensitive) const
-{
- if (caseSensitive) {
- return startsWith(prefix);
- }
-
- DeprecatedStringData *data = *dataHandle;
-
- unsigned prefixLength = strlen(prefix);
- if (data->_isAsciiValid) {
- return strncasecmp(prefix, data->_ascii, prefixLength) == 0;
- } else {
- ASSERT(data->_isUnicodeValid);
- if (prefixLength > data->_length) {
- return false;
- }
- const DeprecatedChar *uni = data->_unicode;
- for (unsigned i = 0; i < prefixLength; ++i) {
- if (!equalCaseInsensitive(uni[i], prefix[i])) {
- return false;
- }
- }
- return true;
- }
-}
-
-bool DeprecatedString::endsWith(const DeprecatedString& s) const
-{
- const DeprecatedChar *uni = unicode();
-
- int length = dataHandle[0]->_length;
- int slength = s.dataHandle[0]->_length;
- if (length < slength)
- return false;
-
- for (int i = length - slength, j = 0; i < length; i++, j++) {
- if (uni[i] != s[j])
- return false;
- }
-
- return true;
-}
-
-bool DeprecatedString::isNull() const
-{
- return dataHandle == shared_null_handle;
-}
-
-int DeprecatedString::find(DeprecatedChar qc, int index) const
-{
- if (dataHandle[0]->_isAsciiValid) {
- if (!IS_ASCII_QCHAR(qc))
- return -1;
- return find(qc.unicode(), index);
- }
- return find(DeprecatedString(qc), index, true);
-}
-
-int DeprecatedString::find(char ch, int index) const
-{
- if (dataHandle[0]->_isAsciiValid){
- const char *cp = ascii();
-
- if ( index < 0 )
- index += dataHandle[0]->_length;
-
- if (index >= (int)dataHandle[0]->_length)
- return -1;
-
- for (int i = index; i < (int)dataHandle[0]->_length; i++)
- if (cp[i] == ch)
- return i;
- }
- else if (dataHandle[0]->_isUnicodeValid)
- return find(DeprecatedChar(ch), index, true);
- else
- FATAL("invalid character cache");
-
- return -1;
-}
-
-int DeprecatedString::find(const DeprecatedString &str, int index, bool caseSensitive) const
-{
- // FIXME, use the first character algorithm
- /*
- We use some weird hashing for efficiency's sake. Instead of
- comparing strings, we compare the sum of str with that of
- a part of this DeprecatedString. Only if that matches, we call memcmp
- or ucstrnicmp.
-
- The hash value of a string is the sum of the cells of its
- QChars.
- */
- if ( index < 0 )
- index += dataHandle[0]->_length;
- int lstr = str.dataHandle[0]->_length;
- int lthis = dataHandle[0]->_length - index;
- if ( (unsigned)lthis > dataHandle[0]->_length )
- return -1;
- int delta = lthis - lstr;
- if ( delta < 0 )
- return -1;
-
- const DeprecatedChar *uthis = unicode() + index;
- const DeprecatedChar *ustr = str.unicode();
- unsigned hthis = 0;
- unsigned hstr = 0;
- int i;
- if ( caseSensitive ) {
- for ( i = 0; i < lstr; i++ ) {
- hthis += uthis[i].unicode();
- hstr += ustr[i].unicode();
- }
- i = 0;
- while ( true ) {
- if ( hthis == hstr && memcmp(uthis + i, ustr, lstr * sizeof(DeprecatedChar)) == 0 )
- return index + i;
- if ( i == delta )
- return -1;
- hthis += uthis[i + lstr].unicode();
- hthis -= uthis[i].unicode();
- i++;
- }
- } else {
- for ( i = 0; i < lstr; i++ ) {
- hthis += toASCIILower(uthis[i].unicode());
- hstr += toASCIILower(ustr[i].unicode());
- }
- i = 0;
- while ( true ) {
- if ( hthis == hstr && equalCaseInsensitive(uthis + i, ustr, lstr) )
- return index + i;
- if ( i == delta )
- return -1;
- hthis += toASCIILower(uthis[i + lstr].unicode());
- hthis -= toASCIILower(uthis[i].unicode());
- i++;
- }
- }
-}
-
-// This function should be as fast as possible, every little bit helps.
-// Our usage patterns are typically small strings. In time trials
-// this simplistic algorithm is much faster than Boyer-Moore or hash
-// based algorithms.
-int DeprecatedString::find(const char *chs, int index, bool caseSensitive) const
-{
- if (!chs || index < 0)
- return -1;
-
- DeprecatedStringData *data = *dataHandle;
-
- int chsLength = strlen(chs);
- int n = data->_length - index;
- if (n < 0)
- return -1;
- n -= chsLength - 1;
- if (n <= 0)
- return -1;
-
- const char *chsPlusOne = chs + 1;
- int chsLengthMinusOne = chsLength - 1;
-
- if (data->_isAsciiValid) {
- char *ptr = data->_ascii + index - 1;
- if (caseSensitive) {
- char c = *chs;
- do {
- if (*++ptr == c && memcmp(ptr + 1, chsPlusOne, chsLengthMinusOne) == 0) {
- return data->_length - chsLength - n + 1;
- }
- } while (--n);
- } else {
- unsigned char lc = toASCIILower(*chs);
- do {
- if (toASCIILower(*++ptr) == lc && equalCaseInsensitive(ptr + 1, chsPlusOne, chsLengthMinusOne)) {
- return data->_length - chsLength - n + 1;
- }
- } while (--n);
- }
- } else {
- ASSERT(data->_isUnicodeValid);
-
- const DeprecatedChar *ptr = data->_unicode + index - 1;
- if (caseSensitive) {
- DeprecatedChar c = *chs;
- do {
- if (*++ptr == c && equal(ptr + 1, chsPlusOne, chsLengthMinusOne)) {
- return data->_length - chsLength - n + 1;
- }
- } while (--n);
- } else {
- unsigned char lc = toASCIILower(*chs);
- do {
- if (toASCIILower((++ptr)->unicode()) == lc && equalCaseInsensitive(ptr + 1, chsPlusOne, chsLengthMinusOne)) {
- return data->_length - chsLength - n + 1;
- }
- } while (--n);
- }
- }
-
- return -1;
-}
-
-int DeprecatedString::find(const RegularExpression &qre, int index) const
-{
- if ( index < 0 )
- index += dataHandle[0]->_length;
- return qre.match( *this, index );
-}
-
-int DeprecatedString::findRev(char ch, int index) const
-{
- if (dataHandle[0]->_isAsciiValid){
- const char *cp = ascii();
-
- if (index < 0)
- index += dataHandle[0]->_length;
- if (index > (int)dataHandle[0]->_length)
- return -1;
-
- for (int i = index; i >= 0; i--) {
- if (cp[i] == ch)
- return i;
- }
- }
- else if (dataHandle[0]->_isUnicodeValid)
- return findRev(DeprecatedString(DeprecatedChar(ch)), index);
- else
- FATAL("invalid character cache");
-
- return -1;
-}
-
-int DeprecatedString::findRev(const char *chs, int index) const
-{
- return findRev(DeprecatedString(chs), index);
-}
-
-int DeprecatedString::findRev( const DeprecatedString& str, int index, bool cs ) const
-{
- // FIXME, use the first character algorithm
- /*
- See DeprecatedString::find() for explanations.
- */
- int lthis = dataHandle[0]->_length;
- if ( index < 0 )
- index += lthis;
-
- int lstr = str.dataHandle[0]->_length;
- int delta = lthis - lstr;
- if ( index < 0 || index > lthis || delta < 0 )
- return -1;
- if ( index > delta )
- index = delta;
-
- const DeprecatedChar *uthis = unicode();
- const DeprecatedChar *ustr = str.unicode();
- unsigned hthis = 0;
- unsigned hstr = 0;
- int i;
- if ( cs ) {
- for ( i = 0; i < lstr; i++ ) {
- hthis += uthis[index + i].unicode();
- hstr += ustr[i].unicode();
- }
- i = index;
- while ( true ) {
- if ( hthis == hstr && memcmp(uthis + i, ustr, lstr * sizeof(DeprecatedChar)) == 0 )
- return i;
- if ( i == 0 )
- return -1;
- i--;
- hthis -= uthis[i + lstr].unicode();
- hthis += uthis[i].unicode();
- }
- } else {
- for ( i = 0; i < lstr; i++ ) {
- hthis += uthis[index + i].lower().unicode();
- hstr += ustr[i].lower().unicode();
- }
- i = index;
- while ( true ) {
- if ( hthis == hstr && equalCaseInsensitive(uthis + i, ustr, lstr) )
- return i;
- if ( i == 0 )
- return -1;
- i--;
- hthis -= uthis[i + lstr].lower().unicode();
- hthis += uthis[i].lower().unicode();
- }
- }
-
- // Should never get here.
- return -1;
-}
-
-
-int DeprecatedString::contains(DeprecatedChar c, bool cs) const
-{
- int count = 0;
-
- DeprecatedStringData *data = *dataHandle;
-
- if (data->_isAsciiValid) {
- if (!IS_ASCII_QCHAR(c))
- return 0;
- const char *cPtr = data->_ascii;
- int n = data->_length;
- char ac = c.unicode();
- if (cs) { // case sensitive
- while (n--)
- count += *cPtr++ == ac;
- } else { // case insensitive
- unsigned char lc = toASCIILower(ac);
- while (n--) {
- count += toASCIILower(*cPtr++) == lc;
- }
- }
- } else {
- ASSERT(data->_isUnicodeValid);
- const DeprecatedChar *uc = data->_unicode;
- int n = data->_length;
- if (cs) { // case sensitive
- while ( n-- )
- count += *uc++ == c;
- } else { // case insensitive
- ::UChar lc = toASCIILower(c.unicode());
- while (n--) {
- count += toASCIILower(uc->unicode()) == lc;
- uc++;
- }
- }
- }
-
- return count;
-}
-
-int DeprecatedString::contains(char ch) const
-{
- return contains(DeprecatedChar(ch), true);
-}
-
-int DeprecatedString::contains(const char *str, bool caseSensitive) const
-{
- if (!str)
- return 0;
-
- int len = strlen(str);
- char c = *str;
-
- DeprecatedStringData *data = *dataHandle;
- int n = data->_length;
-
- n -= len - 1;
- if (n <= 0)
- return 0;
-
- int count = 0;
-
- if (data->_isAsciiValid) {
- const char *p = data->_ascii;
- if (caseSensitive) {
- do {
- count += *p == c && memcmp(p + 1, str + 1, len - 1) == 0;
- p++;
- } while (--n);
- } else {
- char lc = toASCIILower(c);
- do {
- count += toASCIILower(*p) == lc && equalCaseInsensitive(p + 1, str + 1, len - 1);
- p++;
- } while (--n);
- }
- } else {
- ASSERT(data->_isUnicodeValid);
- const DeprecatedChar *p = data->_unicode;
- if (caseSensitive) {
- do {
- count += *p == c && equal(p + 1, str + 1, len - 1);
- p++;
- } while (--n);
- } else {
- unsigned char lc = toASCIILower(c);
- do {
- count += toASCIILower(p->unicode()) == lc && equalCaseInsensitive(p + 1, str + 1, len - 1);
- p++;
- } while (--n);
- }
- }
-
- return count;
-}
-
-int DeprecatedString::contains(const DeprecatedString &str, bool caseSensitive) const
-{
- if (str.isEmpty())
- return 0;
-
- const DeprecatedChar *strP = str.unicode();
- int len = str.dataHandle[0]->_length;
- DeprecatedChar c = *strP;
-
- const DeprecatedChar *p = unicode();
- int n = dataHandle[0]->_length;
-
- n -= len - 1;
- if (n <= 0)
- return 0;
-
- int count = 0;
-
- if (caseSensitive) {
- int byteCount = len * sizeof(DeprecatedChar);
- do {
- count += *p == c && memcmp(p, strP, byteCount) == 0;
- ++p;
- } while (--n);
- } else {
- do {
- count += p->lower() == c && equalCaseInsensitive(p, strP, len) == 0;
- ++p;
- } while (--n);
- }
-
- return count;
-}
-
-bool DeprecatedString::isAllASCII() const
-{
- DeprecatedStringData *data = *dataHandle;
-
- int n = data->_length;
- if (data->_isAsciiValid) {
- const char *p = data->_ascii;
- while (n--) {
- unsigned char c = *p++;
- if (c > 0x7F) {
- return false;
- }
- }
- } else {
- ASSERT(data->_isUnicodeValid);
- const DeprecatedChar *p = data->_unicode;
- while (n--) {
- if ((*p++).unicode() > 0x7F) {
- return false;
- }
- }
- }
-
- return true;
-}
-
-bool DeprecatedString::isAllLatin1() const
-{
- DeprecatedStringData *data = *dataHandle;
-
- if (data->_isAsciiValid) {
- return true;
- }
-
- ASSERT(data->_isUnicodeValid);
- int n = data->_length;
- const DeprecatedChar *p = data->_unicode;
- while (n--) {
- if ((*p++).unicode() > 0xFF) {
- return false;
- }
- }
-
- return true;
-}
-
-bool DeprecatedString::hasFastLatin1() const
-{
- DeprecatedStringData *data = *dataHandle;
- return data->_isAsciiValid;
-}
-
-void DeprecatedString::copyLatin1(char *buffer, unsigned position, unsigned maxLength) const
-{
- DeprecatedStringData *data = *dataHandle;
-
- int length = data->_length;
- if (position > static_cast<unsigned>(length))
- length = 0;
- else
- length -= position;
- if (static_cast<unsigned>(length) > maxLength)
- length = static_cast<int>(maxLength);
-
- buffer[length] = 0;
-
- if (data->_isAsciiValid) {
- memcpy(buffer, data->_ascii + position, length);
- return;
- }
-
- ASSERT(data->_isUnicodeValid);
- const DeprecatedChar* uc = data->_unicode + position;
- while (length--)
- *buffer++ = (*uc++).latin1();
-}
-
-short DeprecatedString::toShort(bool *ok, int base) const
-{
- int v = toInt(ok, base);
- short sv = v;
- if (sv != v) {
- if (ok)
- *ok = false;
- return 0;
- }
- return sv;
-}
-
-unsigned short DeprecatedString::toUShort(bool *ok, int base) const
-{
- unsigned v = toUInt(ok, base);
- unsigned short sv = v;
- if (sv != v) {
- if (ok)
- *ok = false;
- return 0;
- }
- return sv;
-}
-
-template <typename IntegralType> static inline
-IntegralType toIntegralType(const DeprecatedString& string, bool *ok, int base)
-{
- static const IntegralType integralMax = std::numeric_limits<IntegralType>::max();
- static const bool isSigned = std::numeric_limits<IntegralType>::is_signed;
- const DeprecatedChar* p = string.unicode();
- const IntegralType maxMultiplier = integralMax / base;
-
- int length = string.length();
- IntegralType value = 0;
- bool isOk = false;
- bool isNegative = false;
-
- if (!p)
- goto bye;
-
- // skip leading whitespace
- while (length && p->isSpace()) {
- length--;
- p++;
- }
-
- if (isSigned && length && *p == '-') {
- length--;
- p++;
- isNegative = true;
- } else if (length && *p == '+') {
- length--;
- p++;
- }
-
- if (!length || !isCharacterAllowedInBase(*p, base))
- goto bye;
-
- while (length && isCharacterAllowedInBase(*p, base)) {
- length--;
- IntegralType digitValue;
- ::UChar c = p->unicode();
- if (isASCIIDigit(c))
- digitValue = c - '0';
- else if (c >= 'a')
- digitValue = c - 'a' + 10;
- else
- digitValue = c - 'A' + 10;
-
- if (value > maxMultiplier || (value == maxMultiplier && digitValue > (integralMax % base) + isNegative))
- goto bye;
-
- value = base * value + digitValue;
- p++;
- }
-
- if (isNegative)
- value = -value;
-
- // skip trailing space
- while (length && p->isSpace()) {
- length--;
- p++;
- }
-
- if (!length)
- isOk = true;
-bye:
- if (ok)
- *ok = isOk;
- return isOk ? value : 0;
-}
-
-int DeprecatedString::toInt(bool *ok, int base) const
-{
- return toIntegralType<int>(*this, ok, base);
-}
-
-int64_t DeprecatedString::toInt64(bool *ok, int base) const
-{
- return toIntegralType<int64_t>(*this, ok, base);
-}
-
-unsigned DeprecatedString::toUInt(bool *ok, int base) const
-{
- return toIntegralType<unsigned>(*this, ok, base);
-}
-
-uint64_t DeprecatedString::toUInt64(bool *ok, int base) const
-{
- return toIntegralType<uint64_t>(*this, ok, base);
-}
-
-double DeprecatedString::toDouble(bool *ok) const
-{
- if (isEmpty()) {
- if (ok)
- *ok = false;
- return 0;
- }
- const char *s = latin1();
- char *end;
- double val = kjs_strtod(s, &end);
- if (ok)
- *ok = end == 0 || *end == '\0';
- return val;
-}
-
-float DeprecatedString::toFloat(bool* ok) const
-{
- // FIXME: this will return ok even when the string does not fit into a float
- return narrowPrecisionToFloat(toDouble(ok));
-}
-
-DeprecatedString DeprecatedString::left(unsigned len) const
-{
- return mid(0, len);
-}
-
-DeprecatedString DeprecatedString::right(unsigned len) const
-{
- return mid(length() - len, len);
-}
-
-DeprecatedString DeprecatedString::mid(unsigned start, unsigned len) const
-{
- if (dataHandle && *dataHandle) {
- DeprecatedStringData &data = **dataHandle;
-
- // clip length
- if (start >= data._length)
- return DeprecatedString();
-
- if (len > data._length - start)
- len = data._length - start;
-
- if (len == 0)
- return DeprecatedString();
-
- if (start == 0 && len == data._length)
- return *this;
-
- ASSERT(start + len >= start && // unsigned overflow
- start + len <= data._length); // past the end
-
- // ascii case
- if (data._isAsciiValid && data._ascii)
- return DeprecatedString(&data._ascii[start] , len);
-
- // unicode case
- if (data._isUnicodeValid && data._unicode)
- return DeprecatedString(&data._unicode[start], len);
- }
-
- // degenerate case
- return DeprecatedString();
-}
-
-DeprecatedString DeprecatedString::copy() const
-{
- // does not need to be a deep copy
- return DeprecatedString(*this);
-}
-
-DeprecatedString DeprecatedString::lower() const
-{
- DeprecatedString s(*this);
- DeprecatedStringData *d = *s.dataHandle;
- int l = d->_length;
- if (l) {
- bool detached = false;
- if (d->_isAsciiValid) {
- char *p = d->_ascii;
- while (l--) {
- char c = *p;
- // FIXME: Doesn't work for 0x80-0xFF.
- if (c >= 'A' && c <= 'Z') {
- if (!detached) {
- s.detach();
- d = *s.dataHandle;
- p = d->_ascii + d->_length - l - 1;
- detached = true;
- }
- *p = c + ('a' - 'A');
- }
- p++;
- }
- }
- else {
- ASSERT(d->_isUnicodeValid);
- DeprecatedChar *p = d->_unicode;
- while (l--) {
- DeprecatedChar c = *p;
- // FIXME: Doesn't work for 0x80-0xFF.
- if (IS_ASCII_QCHAR(c)) {
- if (c.unicode() >= 'A' && c.unicode() <= 'Z') {
- if (!detached) {
- s.detach();
- d = *s.dataHandle;
- p = d->_unicode + d->_length - l - 1;
- detached = true;
- }
- *p = c.unicode() + ('a' - 'A');
- }
- } else {
- DeprecatedChar clower = c.lower();
- if (clower != c) {
- if (!detached) {
- s.detach();
- d = *s.dataHandle;
- p = d->_unicode + d->_length - l - 1;
- detached = true;
- }
- *p = clower;
- }
- }
- p++;
- }
- }
- }
- return s;
-}
-
-DeprecatedString DeprecatedString::stripWhiteSpace() const
-{
- if ( isEmpty() ) // nothing to do
- return *this;
- if ( !at(0).isSpace() && !at(dataHandle[0]->_length-1).isSpace() )
- return *this;
-
- int start = 0;
- int end = dataHandle[0]->_length - 1;
-
- DeprecatedString result = fromLatin1("");
- while ( start<=end && at(start).isSpace() ) // skip white space from start
- start++;
- if ( start > end ) { // only white space
- return result;
- }
- while ( end && at(end).isSpace() ) // skip white space from end
- end--;
- int l = end - start + 1;
-
- if (dataHandle[0]->_isAsciiValid){
- result.setLength( l );
- if ( l )
- memcpy(const_cast<char*>(result.dataHandle[0]->ascii()), &ascii()[start], l );
- }
- else if (dataHandle[0]->_isUnicodeValid){
- result.setLength( l );
- if ( l )
- memcpy(result.forceUnicode(), &unicode()[start], sizeof(DeprecatedChar)*l );
- }
- else
- FATAL("invalid character cache");
- return result;
-}
-
-DeprecatedString DeprecatedString::simplifyWhiteSpace() const
-{
- if ( isEmpty() ) // nothing to do
- return *this;
-
- DeprecatedString result;
-
- if (dataHandle[0]->_isAsciiValid){
- result.setLength( dataHandle[0]->_length );
- const char *from = ascii();
- const char *fromend = from + dataHandle[0]->_length;
- int outc=0;
-
- char *to = const_cast<char*>(result.ascii());
- while ( true ) {
- while ( from!=fromend && DeprecatedChar(*from).isSpace() )
- from++;
- while ( from!=fromend && !DeprecatedChar(*from).isSpace() )
- to[outc++] = *from++;
- if ( from!=fromend )
- to[outc++] = ' ';
- else
- break;
- }
- if ( outc > 0 && to[outc-1] == ' ' )
- outc--;
- result.truncate( outc );
- }
- else if (dataHandle[0]->_isUnicodeValid){
- result.setLength( dataHandle[0]->_length );
- const DeprecatedChar *from = unicode();
- const DeprecatedChar *fromend = from + dataHandle[0]->_length;
- int outc=0;
-
- DeprecatedChar *to = result.forceUnicode();
- while ( true ) {
- while ( from!=fromend && from->isSpace() )
- from++;
- while ( from!=fromend && !from->isSpace() )
- to[outc++] = *from++;
- if ( from!=fromend )
- to[outc++] = ' ';
- else
- break;
- }
- if ( outc > 0 && to[outc-1] == ' ' )
- outc--;
- result.truncate( outc );
- }
- else
- FATAL("invalid character cache");
-
- return result;
-}
-
-void DeprecatedString::deref()
-{
- dataHandle[0]->deref();
-}
-
-
-DeprecatedString &DeprecatedString::setUnicode(const DeprecatedChar *uni, unsigned len)
-{
- detachAndDiscardCharacters();
-
- // Free our handle if it isn't the shared null handle, and if no-one else is using it.
- bool needToFreeHandle = dataHandle != shared_null_handle && dataHandle[0]->refCount == 1;
-
- if (len == 0) {
- deref();
- if (needToFreeHandle)
- freeHandle(dataHandle);
- dataHandle = makeSharedNullHandle();
- dataHandle[0]->ref();
- } else if (len > dataHandle[0]->_maxUnicode || dataHandle[0]->refCount != 1 || !dataHandle[0]->_isUnicodeValid) {
- deref();
- if (needToFreeHandle)
- freeHandle(dataHandle);
- dataHandle = allocateHandle();
- *dataHandle = new DeprecatedStringData(uni, len);
- dataHandle[0]->_isHeapAllocated = 1;
- } else {
- if ( uni )
- memcpy( (void *)unicode(), uni, sizeof(DeprecatedChar)*len );
- dataHandle[0]->_length = len;
- dataHandle[0]->_isAsciiValid = 0;
- }
-
- return *this;
-}
-
-
-DeprecatedString &DeprecatedString::setLatin1(const char *str, int len)
-{
- if ( str == 0 )
- return setUnicode(0,0);
- if ( len < 0 )
- len = strlen(str);
-
- detachAndDiscardCharacters();
-
- // Free our handle if it isn't the shared null handle, and if no-one else is using it.
- bool needToFreeHandle = dataHandle != shared_null_handle && dataHandle[0]->refCount == 1;
-
- if (len+1 > (int)dataHandle[0]->_maxAscii || dataHandle[0]->refCount != 1 || !dataHandle[0]->_isAsciiValid) {
- deref();
- if (needToFreeHandle)
- freeHandle(dataHandle);
- dataHandle = allocateHandle();
- *dataHandle = new DeprecatedStringData(str,len);
- dataHandle[0]->_isHeapAllocated = 1;
- } else {
- strcpy(const_cast<char*>(ascii()), str );
- dataHandle[0]->_length = len;
- dataHandle[0]->_isUnicodeValid = 0;
- }
- return *this;
-}
-
-DeprecatedString &DeprecatedString::setNum(short n)
-{
- return format("%d", n);
-}
-
-DeprecatedString &DeprecatedString::setNum(unsigned short n)
-{
- return format("%u", n);
-}
-
-DeprecatedString &DeprecatedString::setNum(int n)
-{
- return format("%d", n);
-}
-
-DeprecatedString &DeprecatedString::setNum(unsigned n)
-{
- return format("%u", n);
-}
-
-DeprecatedString &DeprecatedString::setNum(long n)
-{
- return format("%ld", n);
-}
-
-DeprecatedString &DeprecatedString::setNum(unsigned long n)
-{
- return format("%lu", n);
-}
-
-DeprecatedString &DeprecatedString::setNum(double n)
-{
- return format("%.6lg", n);
-}
-
-DeprecatedString &DeprecatedString::format(const char *format, ...)
-{
- // FIXME: this needs the same windows compat fixes as String::format
-
- va_list args;
- va_start(args, format);
-
- // Do the format once to get the length.
-#if COMPILER(MSVC)
- int result = _vscprintf(format, args);
-#else
- char ch;
- int result = vsnprintf(&ch, 1, format, args);
-#endif
-
- // Handle the empty string case to simplify the code below.
- if (result <= 0) { // POSIX returns 0 in error; Windows returns a negative number.
- setUnicode(0, 0);
- return *this;
- }
- unsigned len = result;
-
- // Arrange for storage for the resulting string.
- detachAndDiscardCharacters();
- if (len >= dataHandle[0]->_maxAscii || dataHandle[0]->refCount != 1 || !dataHandle[0]->_isAsciiValid) {
- // Free our handle if it isn't the shared null handle, and if no-one else is using it.
- bool needToFreeHandle = dataHandle != shared_null_handle && dataHandle[0]->refCount == 1;
- deref();
- if (needToFreeHandle)
- freeHandle(dataHandle);
- dataHandle = allocateHandle();
- *dataHandle = new DeprecatedStringData((char *)0, len);
- dataHandle[0]->_isHeapAllocated = 1;
- } else {
- dataHandle[0]->_length = len;
- dataHandle[0]->_isUnicodeValid = 0;
- }
-
- // Now do the formatting again, guaranteed to fit.
- vsprintf(const_cast<char*>(ascii()), format, args);
-
- va_end(args);
- return *this;
-}
-
-DeprecatedString &DeprecatedString::prepend(const DeprecatedString &qs)
-{
- return insert(0, qs);
-}
-
-DeprecatedString &DeprecatedString::prepend(const DeprecatedChar *characters, unsigned length)
-{
- return insert(0, characters, length);
-}
-
-DeprecatedString &DeprecatedString::append(const DeprecatedString &qs)
-{
- return insert(dataHandle[0]->_length, qs);
-}
-
-DeprecatedString &DeprecatedString::append(const char *characters, unsigned length)
-{
- return insert(dataHandle[0]->_length, characters, length);
-}
-
-DeprecatedString &DeprecatedString::append(const DeprecatedChar *characters, unsigned length)
-{
- return insert(dataHandle[0]->_length, characters, length);
-}
-
-DeprecatedString &DeprecatedString::insert(unsigned index, const char *insertChars, unsigned insertLength)
-{
- if (insertLength == 0)
- return *this;
-
- detach();
-
- if (dataHandle[0]->_isAsciiValid){
- unsigned originalLength = dataHandle[0]->_length;
- char *targetChars;
-
- // Ensure that we have enough space.
- setLength (originalLength + insertLength);
- targetChars = const_cast<char*>(ascii());
-
- // Move tail to make space for inserted characters.
- memmove (targetChars+index+insertLength, targetChars+index, originalLength-index);
-
- // Insert characters.
- memcpy (targetChars+index, insertChars, insertLength);
-
- dataHandle[0]->_isUnicodeValid = 0;
- }
- else if (dataHandle[0]->_isUnicodeValid){
- unsigned originalLength = dataHandle[0]->_length;
- DeprecatedChar *targetChars;
-
- // Ensure that we have enough space.
- setLength (originalLength + insertLength);
- targetChars = (DeprecatedChar *)unicode();
-
- // Move tail to make space for inserted characters.
- memmove (targetChars+(index+insertLength), targetChars+index, (originalLength-index)*sizeof(DeprecatedChar));
-
- // Insert characters.
- unsigned i = insertLength;
- DeprecatedChar *target = targetChars+index;
-
- while (i--)
- *target++ = *insertChars++;
- }
- else
- FATAL("invalid character cache");
-
- return *this;
-}
-
-
-DeprecatedString &DeprecatedString::insert(unsigned index, const DeprecatedString &qs)
-{
- if (qs.dataHandle[0]->_length == 0)
- return *this;
-
- if (dataHandle[0]->_isAsciiValid && qs.isAllLatin1()) {
- insert(index, qs.latin1(), qs.length());
- }
- else {
- unsigned insertLength = qs.dataHandle[0]->_length;
- unsigned originalLength = dataHandle[0]->_length;
-
- forceUnicode();
-
- // Ensure that we have enough space.
- setLength (originalLength + insertLength);
- DeprecatedChar *targetChars = const_cast<DeprecatedChar *>(unicode());
-
- // Move tail to make space for inserted characters.
- memmove (targetChars+(index+insertLength), targetChars+index, (originalLength-index)*sizeof(DeprecatedChar));
-
- // Insert characters.
- if (qs.dataHandle[0]->_isAsciiValid){
- unsigned i = insertLength;
- DeprecatedChar *target = targetChars+index;
- char *a = const_cast<char*>(qs.ascii());
-
- while (i--)
- *target++ = *a++;
- }
- else {
- DeprecatedChar *insertChars = (DeprecatedChar *)qs.unicode();
- memcpy (targetChars+index, insertChars, insertLength*sizeof(DeprecatedChar));
- }
-
- dataHandle[0]->_isAsciiValid = 0;
- }
-
- return *this;
-}
-
-
-DeprecatedString &DeprecatedString::insert(unsigned index, const DeprecatedChar *insertChars, unsigned insertLength)
-{
- if (insertLength == 0)
- return *this;
-
- forceUnicode();
-
- unsigned originalLength = dataHandle[0]->_length;
- setLength(originalLength + insertLength);
-
- DeprecatedChar *targetChars = const_cast<DeprecatedChar *>(unicode());
- if (originalLength > index) {
- memmove(targetChars + index + insertLength, targetChars + index, (originalLength - index) * sizeof(DeprecatedChar));
- }
- memcpy(targetChars + index, insertChars, insertLength * sizeof(DeprecatedChar));
-
- return *this;
-}
-
-
-DeprecatedString &DeprecatedString::insert(unsigned index, DeprecatedChar qc)
-{
- detach();
-
- if (dataHandle[0]->_isAsciiValid && IS_ASCII_QCHAR(qc)){
- unsigned originalLength = dataHandle[0]->_length;
- char insertChar = qc.unicode();
- char *targetChars;
-
- // Ensure that we have enough space.
- setLength (originalLength + 1);
- targetChars = const_cast<char*>(ascii());
-
- // Move tail to make space for inserted character.
- memmove (targetChars+index+1, targetChars+index, originalLength-index);
-
- // Insert character.
- targetChars[index] = insertChar;
- targetChars[dataHandle[0]->_length] = 0;
-
- dataHandle[0]->_isUnicodeValid = 0;
- }
- else {
- unsigned originalLength = dataHandle[0]->_length;
-
- forceUnicode();
-
- // Ensure that we have enough space.
- setLength (originalLength + 1);
- DeprecatedChar *targetChars = const_cast<DeprecatedChar *>(unicode());
-
- // Move tail to make space for inserted character.
- memmove (targetChars+(index+1), targetChars+index, (originalLength-index)*sizeof(DeprecatedChar));
-
- targetChars[index] = qc;
- }
-
- return *this;
-}
-
-
-DeprecatedString &DeprecatedString::insert(unsigned index, char ch)
-{
- detach();
-
- if (dataHandle[0]->_isAsciiValid) {
- unsigned originalLength = dataHandle[0]->_length;
- char *targetChars;
-
- // Ensure that we have enough space.
- setLength (originalLength + 1);
- targetChars = const_cast<char*>(ascii());
-
- // Move tail to make space for inserted character.
- memmove (targetChars+index+1, targetChars+index, originalLength-index);
-
- // Insert character.
- targetChars[index] = ch;
- targetChars[dataHandle[0]->_length] = 0;
-
- dataHandle[0]->_isUnicodeValid = 0;
- }
- else if (dataHandle[0]->_isUnicodeValid){
- unsigned originalLength = dataHandle[0]->_length;
- DeprecatedChar *targetChars;
-
- // Ensure that we have enough space.
- setLength (originalLength + 1);
- targetChars = (DeprecatedChar *)unicode();
-
- // Move tail to make space for inserted character.
- memmove (targetChars+(index+1), targetChars+index, (originalLength-index)*sizeof(DeprecatedChar));
-
- targetChars[index] = (DeprecatedChar)ch;
- }
- else
- FATAL("invalid character cache");
-
- return *this;
-}
-
-// Copy DeprecatedStringData if necessary. Must be called before the string data is mutated.
-void DeprecatedString::detach()
-{
- DeprecatedStringData *oldData = *dataHandle;
-
- if (oldData->refCount == 1 && oldData != shared_null)
- return;
-
- // Copy data for this string so we can safely mutate it.
- DeprecatedStringData *newData;
- if (oldData->_isAsciiValid)
- newData = new DeprecatedStringData(oldData->ascii(), oldData->_length);
- else
- newData = new DeprecatedStringData(oldData->unicode(), oldData->_length);
- newData->_isHeapAllocated = 1;
-
- // There is now one less client for the old data.
- oldData->deref();
-
- // If the old data is our internal data, then we'll keep that.
- // This decreases the chance we'll have to do a detachInternal later
- // when this object is destroyed.
- if (oldData == &internalData) {
- newData->refCount = oldData->refCount;
- oldData->refCount = 1;
- *dataHandle = newData;
- newData = oldData;
- }
-
- // Create a new handle.
- dataHandle = allocateHandle();
- *dataHandle = newData;
-}
-
-void DeprecatedString::detachAndDiscardCharacters()
-{
- // Missing optimization: Don't bother copying the old data if we detach.
- detach();
-}
-
-DeprecatedString &DeprecatedString::remove(unsigned index, unsigned len)
-{
- unsigned olen = dataHandle[0]->_length;
- if ( index >= olen ) {
- // range problems
- } else if ( index + len >= olen ) { // index ok
- setLength( index );
- } else if ( len != 0 ) {
- // Missing optimization: Could avoid copying characters we are going to remove
- // by making a special version of detach().
-
- detach();
-
- if (dataHandle[0]->_isAsciiValid){
- memmove( dataHandle[0]->ascii()+index, dataHandle[0]->ascii()+index+len,
- sizeof(char)*(olen-index-len) );
- setLength( olen-len );
- dataHandle[0]->_isUnicodeValid = 0;
- }
- else if (dataHandle[0]->_isUnicodeValid){
- memmove( dataHandle[0]->unicode()+index, dataHandle[0]->unicode()+index+len,
- sizeof(DeprecatedChar)*(olen-index-len) );
- setLength( olen-len );
- }
- else
- FATAL("invalid character cache");
- }
- return *this;
-}
-
-DeprecatedString &DeprecatedString::replace(unsigned index, unsigned len, const DeprecatedString& str)
-{
- return remove(index, len).insert(index, str);
-}
-
-DeprecatedString &DeprecatedString::replace(char pattern, const DeprecatedString &str)
-{
- int slen = str.dataHandle[0]->_length;
- int index = 0;
- while ((index = find(pattern, index)) >= 0) {
- replace(index, 1, str);
- index += slen;
- }
- return *this;
-}
-
-DeprecatedString &DeprecatedString::replace(DeprecatedChar pattern, const DeprecatedString &str)
-{
- int slen = str.dataHandle[0]->_length;
- int index = 0;
- while ((index = find(pattern, index)) >= 0) {
- replace(index, 1, str);
- index += slen;
- }
- return *this;
-}
-
-DeprecatedString &DeprecatedString::replace(const DeprecatedString &pattern, const DeprecatedString &str)
-{
- if (pattern.isEmpty())
- return *this;
- int plen = pattern.dataHandle[0]->_length;
- int slen = str.dataHandle[0]->_length;
- int index = 0;
- while ((index = find(pattern, index)) >= 0) {
- replace(index, plen, str);
- index += slen;
- }
- return *this;
-}
-
-
-DeprecatedString &DeprecatedString::replace(const RegularExpression &qre, const DeprecatedString &str)
-{
- if ( isEmpty() )
- return *this;
- int index = 0;
- int slen = str.dataHandle[0]->_length;
- int len;
- while ( index < (int)dataHandle[0]->_length ) {
- index = qre.match( *this, index, &len);
- if ( index >= 0 ) {
- replace( index, len, str );
- index += slen;
- if ( !len )
- break; // Avoid infinite loop on 0-length matches, e.g. [a-z]*
- }
- else
- break;
- }
- return *this;
-}
-
-
-DeprecatedString &DeprecatedString::replace(DeprecatedChar oldChar, DeprecatedChar newChar)
-{
- if (oldChar != newChar && find(oldChar) != -1) {
- unsigned length = dataHandle[0]->_length;
-
- detach();
- if (dataHandle[0]->_isAsciiValid && IS_ASCII_QCHAR(newChar)) {
- char *p = const_cast<char *>(ascii());
- dataHandle[0]->_isUnicodeValid = 0;
- char oldC = oldChar.unicode();
- char newC = newChar.unicode();
- for (unsigned i = 0; i != length; ++i) {
- if (p[i] == oldC) {
- p[i] = newC;
- }
- }
- } else {
- DeprecatedChar *p = const_cast<DeprecatedChar *>(unicode());
- dataHandle[0]->_isAsciiValid = 0;
- for (unsigned i = 0; i != length; ++i) {
- if (p[i] == oldChar) {
- p[i] = newChar;
- }
- }
- }
- }
-
- return *this;
-}
-
-
-DeprecatedChar *DeprecatedString::forceUnicode()
-{
- detach();
- DeprecatedChar *result = const_cast<DeprecatedChar *>(unicode());
- dataHandle[0]->_isAsciiValid = 0;
- return result;
-}
-
-
-// Increase buffer size if necessary. Newly allocated
-// bytes will contain garbage.
-void DeprecatedString::setLength(unsigned newLen)
-{
- if (newLen == 0) {
- setUnicode(0, 0);
- return;
- }
-
- // Missing optimization: Could avoid copying characters we are going to remove
- // by making a special version of detach().
- detach();
-
- ASSERT(dataHandle != shared_null_handle);
-
- if (dataHandle[0]->_isAsciiValid){
- if (newLen+1 > dataHandle[0]->_maxAscii) {
- dataHandle[0]->increaseAsciiSize(newLen+1);
- }
- // Ensure null termination, although newly allocated
- // bytes contain garbage.
- dataHandle[0]->_ascii[newLen] = 0;
- }
-
- if (dataHandle[0]->_isUnicodeValid){
- if (newLen > dataHandle[0]->_maxUnicode) {
- dataHandle[0]->increaseUnicodeSize(newLen);
- }
- }
-
- dataHandle[0]->_length = newLen;
-}
-
-
-void DeprecatedString::truncate(unsigned newLen)
-{
- if ( newLen < dataHandle[0]->_length )
- setLength( newLen );
-}
-
-void DeprecatedString::fill(DeprecatedChar qc, int len)
-{
- detachAndDiscardCharacters();
-
- // len == -1 means fill to string length.
- if (len < 0) {
- len = dataHandle[0]->_length;
- }
-
- if (len == 0) {
- if (dataHandle != shared_null_handle) {
- ASSERT(dataHandle[0]->refCount == 1);
- deref();
- freeHandle(dataHandle);
- dataHandle = makeSharedNullHandle();
- shared_null->ref();
- }
- } else {
- if (dataHandle[0]->_isAsciiValid && IS_ASCII_QCHAR(qc)) {
- setLength(len);
- char *nd = const_cast<char*>(ascii());
- while (len--)
- *nd++ = qc.unicode();
- dataHandle[0]->_isUnicodeValid = 0;
- } else {
- setLength(len);
- DeprecatedChar *nd = forceUnicode();
- while (len--)
- *nd++ = qc;
- }
- }
-}
-
-DeprecatedString &DeprecatedString::append(DeprecatedChar qc)
-{
- detach();
-
- DeprecatedStringData *thisData = *dataHandle;
- if (thisData->_isUnicodeValid && thisData->_length + 1 < thisData->_maxUnicode){
- thisData->_unicode[thisData->_length] = qc;
- thisData->_length++;
- thisData->_isAsciiValid = 0;
- return *this;
- }
- else if (thisData->_isAsciiValid && IS_ASCII_QCHAR(qc) && thisData->_length + 2 < thisData->_maxAscii){
- thisData->_ascii[thisData->_length] = qc.unicode();
- thisData->_length++;
- thisData->_ascii[thisData->_length] = 0;
- thisData->_isUnicodeValid = 0;
- return *this;
- }
- return insert(thisData->_length, qc);
-}
-
-DeprecatedString &DeprecatedString::append(char ch)
-{
- detach();
-
- DeprecatedStringData *thisData = *dataHandle;
- if (thisData->_isUnicodeValid && thisData->_length + 1 < thisData->_maxUnicode){
- thisData->_unicode[thisData->_length] = (DeprecatedChar)ch;
- thisData->_length++;
- thisData->_isAsciiValid = 0;
- return *this;
- }
- else if (thisData->_isAsciiValid && thisData->_length + 2 < thisData->_maxAscii){
- thisData->_ascii[thisData->_length] = ch;
- thisData->_length++;
- thisData->_ascii[thisData->_length] = 0;
- thisData->_isUnicodeValid = 0;
- return *this;
- }
- return insert(thisData->_length, ch);
-}
-
-void DeprecatedString::reserve(unsigned length)
-{
- if (length > dataHandle[0]->_maxUnicode) {
- detach();
- dataHandle[0]->increaseUnicodeSize(length);
- }
-}
-
-bool operator==(const DeprecatedString &s1, const DeprecatedString &s2)
-{
- if (s1.dataHandle[0]->_isAsciiValid && s2.dataHandle[0]->_isAsciiValid) {
- return strcmp(s1.ascii(), s2.ascii()) == 0;
- }
- return s1.dataHandle[0]->_length == s2.dataHandle[0]->_length
- && memcmp(s1.unicode(), s2.unicode(), s1.dataHandle[0]->_length * sizeof(DeprecatedChar)) == 0;
-}
-
-bool operator==(const DeprecatedString &s1, const char *chs)
-{
- if (!chs)
- return s1.isNull();
- DeprecatedStringData *d = s1.dataHandle[0];
- unsigned len = d->_length;
- if (d->_isAsciiValid) {
- const char *s = s1.ascii();
- for (unsigned i = 0; i != len; ++i) {
- char c = chs[i];
- if (!c || s[i] != c)
- return false;
- }
- } else {
- const DeprecatedChar *s = s1.unicode();
- for (unsigned i = 0; i != len; ++i) {
- char c = chs[i];
- if (!c || s[i] != c)
- return false;
- }
- }
- return chs[len] == '\0';
-}
-
-DeprecatedString operator+(const DeprecatedString &qs1, const DeprecatedString &qs2)
-{
- return DeprecatedString(qs1) += qs2;
-}
-
-DeprecatedString operator+(const DeprecatedString &qs, const char *chs)
-{
- return DeprecatedString(qs) += chs;
-}
-
-DeprecatedString operator+(const DeprecatedString &qs, DeprecatedChar qc)
-{
- return DeprecatedString(qs) += qc;
-}
-
-DeprecatedString operator+(const DeprecatedString &qs, char ch)
-{
- return DeprecatedString(qs) += ch;
-}
-
-DeprecatedString operator+(const char *chs, const DeprecatedString &qs)
-{
- return DeprecatedString(chs) += qs;
-}
-
-DeprecatedString operator+(DeprecatedChar qc, const DeprecatedString &qs)
-{
- return DeprecatedString(qc) += qs;
-}
-
-DeprecatedString operator+(char ch, const DeprecatedString &qs)
-{
- return DeprecatedString(DeprecatedChar(ch)) += qs;
-}
-
-DeprecatedConstString::DeprecatedConstString(const DeprecatedChar* unicode, unsigned length) :
- DeprecatedString(new DeprecatedStringData((DeprecatedChar *)unicode, length, length), true)
-{
-}
-
-DeprecatedConstString::~DeprecatedConstString()
-{
- DeprecatedStringData *data = *dataHandle;
- if (data->refCount > 1) {
- DeprecatedChar *tp;
- if (data->_length <= WEBCORE_DS_INTERNAL_BUFFER_UCHARS) {
- data->_maxUnicode = WEBCORE_DS_INTERNAL_BUFFER_UCHARS;
- tp = (DeprecatedChar *)&data->_internalBuffer[0];
- } else {
- data->_maxUnicode = ALLOC_QCHAR_GOOD_SIZE(data->_length);
- tp = WEBCORE_ALLOCATE_CHARACTERS(data->_maxUnicode);
- }
- memcpy(tp, data->_unicode, data->_length * sizeof(DeprecatedChar));
- data->_unicode = tp;
- data->_isUnicodeValid = 1;
- data->_isAsciiValid = 0;
- } else {
- data->_unicode = 0;
- }
-}
-
-struct HandlePageNode
-{
- HandlePageNode *next;
- HandlePageNode *previous;
- void *nodes;
-};
-
-struct HandleNode {
- union {
- struct {
- unsigned short next;
- unsigned short previous;
- } internalNode;
-
- HandleNode *freeNodes; // Always at block[0] in page.
-
- HandlePageNode *pageNode; // Always at block[1] in page
-
- void *handle;
- } type;
-};
-
-#ifndef CHECK_FOR_HANDLE_LEAKS
-
-static const size_t pageSize = 4096;
-static const uintptr_t pageMask = ~(pageSize - 1);
-static const size_t nodeBlockSize = pageSize / sizeof(HandleNode);
-
-static HandleNode *initializeHandleNodeBlock(HandlePageNode *pageNode)
-{
- unsigned i;
- HandleNode* block;
- HandleNode* aNode;
-
-#if PLATFORM(WIN_OS)
- block = (HandleNode*)VirtualAlloc(0, pageSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
-#elif PLATFORM(SYMBIAN)
- // symbian::fixme needs to do page aligned allocation as valloc is not supported.
- block = NULL;
-#else
- block = (HandleNode*)valloc(pageSize);
-#endif
-
- for (i = 2; i < nodeBlockSize; i++) {
- aNode = &block[i];
- if (i > 2)
- aNode->type.internalNode.previous = i-1;
- else
- aNode->type.internalNode.previous = 0;
- if (i != nodeBlockSize - 1)
- aNode->type.internalNode.next = i+1;
- else
- aNode->type.internalNode.next = 0;
- }
- block[0].type.freeNodes = &block[nodeBlockSize - 1];
- block[1].type.pageNode = pageNode;
-
- return block;
-}
-
-static HandlePageNode *allocatePageNode()
-{
- HandlePageNode *node = (HandlePageNode *)fastMalloc(sizeof(HandlePageNode));
- node->next = node->previous = 0;
- node->nodes = initializeHandleNodeBlock(node);
- return node;
-}
-
-static HandleNode *allocateNode(HandlePageNode *pageNode)
-{
- HandleNode *block = (HandleNode *)pageNode->nodes;
- HandleNode *freeNodes = block[0].type.freeNodes;
- HandleNode *allocated;
-
- // Check to see if we're out of nodes.
- if (freeNodes == 0) {
- FATAL("out of nodes");
- return 0;
- }
-
- // Remove node from end of free list
- allocated = freeNodes;
- if (allocated->type.internalNode.previous >= 2) {
- block[0].type.freeNodes = block + allocated->type.internalNode.previous;
- block[0].type.freeNodes->type.internalNode.next = 0;
- }
- else {
- // Used last node on this page.
- block[0].type.freeNodes = 0;
-
- freeNodeAllocationPages = freeNodeAllocationPages->previous;
- if (freeNodeAllocationPages)
- freeNodeAllocationPages->next = 0;
-
- pageNode->previous = usedNodeAllocationPages;
- pageNode->next = 0;
- if (usedNodeAllocationPages)
- usedNodeAllocationPages->next = pageNode;
- usedNodeAllocationPages = pageNode;
- }
-
- return allocated;
-}
-
-#endif
-
-void freeHandle(DeprecatedStringData **_free)
-{
-#ifdef CHECK_FOR_HANDLE_LEAKS
- fastFree(_free);
- return;
-#else
-
- HandleNode *free = (HandleNode *)_free;
- HandleNode *base = (HandleNode *)((uintptr_t)free & pageMask);
- HandleNode *freeNodes = base[0].type.freeNodes;
- HandlePageNode *pageNode = base[1].type.pageNode;
-
- if (freeNodes == 0){
- free->type.internalNode.previous = 0;
- }
- else {
- // Insert at head of free list.
- free->type.internalNode.previous = freeNodes - base;
- freeNodes->type.internalNode.next = free - base;
- }
- free->type.internalNode.next = 0;
- base[0].type.freeNodes = free;
-
- // Remove page from used/free list and place on free list
- if (freeNodeAllocationPages != pageNode) {
- if (pageNode->previous)
- pageNode->previous->next = pageNode->next;
- if (pageNode->next)
- pageNode->next->previous = pageNode->previous;
- if (usedNodeAllocationPages == pageNode)
- usedNodeAllocationPages = pageNode->previous;
-
- pageNode->previous = freeNodeAllocationPages;
- pageNode->next = 0;
- if (freeNodeAllocationPages)
- freeNodeAllocationPages->next = pageNode;
- freeNodeAllocationPages = pageNode;
- }
-#endif
-}
-
-DeprecatedString DeprecatedString::fromUtf8(const char *chs)
-{
- return UTF8Encoding().decode(chs, strlen(chs)).deprecatedString();
-}
-
-DeprecatedString DeprecatedString::fromUtf8(const char *chs, int len)
-{
- return UTF8Encoding().decode(chs, len).deprecatedString();
-}
-
-DeprecatedCString DeprecatedString::utf8(int& length) const
-{
- DeprecatedCString result = UTF8Encoding().encode((::UChar*)unicode(), this->length()).deprecatedCString();
- length = result.length();
- return result;
-}
-
-DeprecatedString::DeprecatedString(const Identifier& str)
-{
- if (str.isNull()) {
- internalData.deref();
- dataHandle = makeSharedNullHandle();
- dataHandle[0]->ref();
- } else {
- dataHandle = allocateHandle();
- *dataHandle = &internalData;
- internalData.initialize(reinterpret_cast<const DeprecatedChar*>(str.data()), str.size());
- }
-}
-
-DeprecatedString::DeprecatedString(const UString& str)
-{
- if (str.isNull()) {
- internalData.deref();
- dataHandle = makeSharedNullHandle();
- dataHandle[0]->ref();
- } else {
- dataHandle = allocateHandle();
- *dataHandle = &internalData;
- internalData.initialize(reinterpret_cast<const DeprecatedChar*>(str.data()), str.size());
- }
-}
-
-#if PLATFORM(QT)
-DeprecatedString::DeprecatedString(const QString& str)
-{
- if (str.isNull()) {
- internalData.deref();
- dataHandle = makeSharedNullHandle();
- dataHandle[0]->ref();
- } else {
- dataHandle = allocateHandle();
- *dataHandle = &internalData;
- internalData.initialize(reinterpret_cast<const DeprecatedChar*>(str.data()), str.length());
- }
-}
-#endif
-
-DeprecatedString::operator Identifier() const
-{
- if (isNull())
- return Identifier();
- return Identifier(reinterpret_cast<const KJS::UChar*>(unicode()), length());
-}
-
-DeprecatedString::operator UString() const
-{
- if (isNull())
- return UString();
- return UString(reinterpret_cast<const KJS::UChar*>(unicode()), length());
-}
-
-bool equalIgnoringCase(const DeprecatedString& a, const DeprecatedString& b)
-{
- unsigned len = a.length();
- if (len != b.length())
- return false;
-
- DeprecatedStringData* dataA = a.dataHandle[0];
- DeprecatedStringData* dataB = b.dataHandle[0];
-
- if (dataA->_isAsciiValid != dataB->_isAsciiValid)
- return false;
-
- if (dataA->_isAsciiValid && dataB->_isAsciiValid)
- return strncasecmp(dataA->_ascii, dataB->_ascii, len) == 0;
-
- ASSERT(dataA->_isUnicodeValid);
- ASSERT(dataB->_isUnicodeValid);
- return equalCaseInsensitive(dataA->_unicode, dataB->_unicode, len);
-}
-
-} // namespace WebCore