peterv%netscape.com f21892e8db Landing TX_BRIDGE_1_1_BRANCH.
Rewrite pretty much all variable and parameter handling. Makes global and local variables be handled differently. Global variables are no longer part of the variables stack, and are lazily evaluated. Fixes bugs 117658, 92929 and some unfiled bugs and fixes remaining parts of bugs 83651 and 96802. Patch by sicking, r=Pike sr=bz.

Fix for bug 156464: fix rounding problems in module, allow patterns without any '0's in the integer part and fix problems with grouping for standalone. Patch by sicking, r=Pike sr=bz.

Fix for bug 157340 (Probable bugs in extensions/transformiix/source/base/txMozillaString.h). Patch by peterv, r=Pike, sr=bz.

Fix for bug 146967 (Clean up Transformiix strings). Patch by peterv, r=sicking, sr=jst.

Fix for bug 156464 (Remove static strings from Transformiix). Patch by peterv, r=Pike, sr=jst.


git-svn-id: svn://10.0.0.236/trunk@126495 18797224-902f-48f8-a5cc-f745e15eee43
2002-08-06 12:28:27 +00:00

439 lines
9.8 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* (C) Copyright The MITRE Corporation 1999 All rights reserved.
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* The program provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* The Copyright owner will not be liable for any damages suffered by
* you as a result of using the Program. In no event will the Copyright
* owner be liable for any special, indirect or consequential damages or
* lost profits even if the Copyright owner has been advised of the
* possibility of their occurrence.
*
* Contributor(s):
*
* Tom Kneeland
* -- original author.
*
* Keith Visco <kvisco@ziplink.net>
* Larry Fitzpatrick
*
*/
#include "TxString.h"
#include <stdlib.h>
#include <string.h>
String::String() : mBuffer(0),
mBufferLength(0),
mLength(0)
{
}
String::String(const String& aSource) : mBuffer(aSource.toUnicode()),
mBufferLength(aSource.mLength),
mLength(aSource.mLength)
{
}
String::String(const UNICODE_CHAR* aSource,
PRUint32 aLength) : mBuffer(0),
mBufferLength(0),
mLength(0)
{
if (!aSource) {
return;
}
if (aLength == 0) {
aLength = unicodeLength(aSource);
}
if (!ensureCapacity(aLength)) {
return;
}
memcpy(mBuffer, aSource, aLength * sizeof(UNICODE_CHAR));
mLength = aLength;
}
String::~String()
{
delete [] mBuffer;
}
void String::append(UNICODE_CHAR aSource)
{
if (!ensureCapacity(1)) {
return;
}
mBuffer[mLength] = aSource;
++mLength;
}
void String::append(const String& aSource)
{
if (!ensureCapacity(aSource.mLength)) {
return;
}
memcpy(&mBuffer[mLength], aSource.mBuffer,
aSource.mLength * sizeof(UNICODE_CHAR));
mLength += aSource.mLength;
}
void String::insert(PRUint32 aOffset, UNICODE_CHAR aSource)
{
if (!ensureCapacity(1)) {
return;
}
if (aOffset < mLength) {
memmove(&mBuffer[aOffset + 1], &mBuffer[aOffset],
(mLength - aOffset) * sizeof(UNICODE_CHAR));
}
mBuffer[aOffset] = aSource;
mLength += 1;
}
void String::insert(PRUint32 aOffset, const String& aSource)
{
if (!ensureCapacity(aSource.mLength)) {
return;
}
if (aOffset < mLength) {
memmove(&mBuffer[aOffset + aSource.mLength], &mBuffer[aOffset],
(mLength - aOffset) * sizeof(UNICODE_CHAR));
}
memcpy(&mBuffer[aOffset], aSource.mBuffer,
aSource.mLength * sizeof(UNICODE_CHAR));
mLength += aSource.mLength;
}
void String::replace(PRUint32 aOffset, UNICODE_CHAR aSource)
{
if (aOffset < mLength) {
mBuffer[aOffset] = aSource;
}
else {
append(aSource);
}
}
void String::replace(PRUint32 aOffset, const String& aSource)
{
if (aOffset < mLength) {
PRUint32 finalLength = aOffset + aSource.mLength;
if (finalLength > mLength) {
if (!ensureCapacity(finalLength - mBufferLength)) {
return;
}
mLength = finalLength;
}
memcpy(&mBuffer[aOffset], aSource.mBuffer,
aSource.mLength * sizeof(UNICODE_CHAR));
}
else {
append(aSource);
}
}
void String::deleteChars(PRUint32 aOffset, PRUint32 aCount)
{
PRUint32 cutEnd = aOffset + aCount;
if (cutEnd < mLength) {
memmove(&mBuffer[aOffset], &mBuffer[cutEnd],
(mLength - cutEnd) * sizeof(UNICODE_CHAR));
mLength -= aCount;
}
else {
mLength = aOffset;
}
}
void String::clear()
{
mLength = 0;
}
PRInt32 String::indexOf(UNICODE_CHAR aData,
PRInt32 aOffset) const
{
NS_ASSERTION(aOffset >= 0, "Passed negative offset to indexOf.");
if (aOffset < 0) {
return kNotFound;
}
PRInt32 searchIndex = aOffset;
while (searchIndex < mLength) {
if (mBuffer[searchIndex] == aData) {
return searchIndex;
}
++searchIndex;
}
return kNotFound;
}
PRInt32 String::indexOf(const String& aData, PRInt32 aOffset) const
{
NS_ASSERTION(aOffset >= 0, "Passed negative offset to indexOf.");
if (aOffset < 0) {
return kNotFound;
}
PRInt32 searchIndex = aOffset;
PRInt32 searchLimit = mLength - aData.mLength;
while (searchIndex <= searchLimit) {
if (memcmp(&mBuffer[searchIndex], aData.mBuffer,
aData.mLength * sizeof(UNICODE_CHAR)) == 0) {
return searchIndex;
}
++searchIndex;
}
return kNotFound;
}
PRInt32 String::lastIndexOf(UNICODE_CHAR aData,
PRInt32 aOffset) const
{
NS_ASSERTION(aOffset >= 0, "Passed negative offset to lastIndexOf.");
if (aOffset < 0) {
return kNotFound;
}
PRUint32 searchIndex = mLength - aOffset;
while (--searchIndex >= 0) {
if (mBuffer[searchIndex] == aData) {
return searchIndex;
}
}
return kNotFound;
}
MBool String::isEqual(const String& aData) const
{
if (mLength != aData.mLength) {
return MB_FALSE;
}
return (memcmp(mBuffer, aData.mBuffer, mLength * sizeof(UNICODE_CHAR)) == 0);
}
MBool String::isEqualIgnoreCase(const String& aData) const
{
if (mLength != aData.mLength) {
return MB_FALSE;
}
UNICODE_CHAR thisChar, otherChar;
PRUint32 compLoop = 0;
while (compLoop < mLength) {
thisChar = mBuffer[compLoop];
if ((thisChar >= 'A') && (thisChar <= 'Z')) {
thisChar += 32;
}
otherChar = aData.mBuffer[compLoop];
if ((otherChar >= 'A') && (otherChar <= 'Z')) {
otherChar += 32;
}
if (thisChar != otherChar) {
return MB_FALSE;
}
++compLoop;
}
return MB_TRUE;
}
void String::truncate(PRUint32 aLength)
{
NS_ASSERTION(aLength <= mBufferLength, "truncate can't increase buffer");
mLength = (aLength > mBufferLength) ? mBufferLength : aLength;
}
String& String::subString(PRUint32 aStart, String& aDest) const
{
return subString(aStart, mLength, aDest);
}
String& String::subString(PRUint32 aStart, PRUint32 aEnd,
String& aDest) const
{
PRUint32 end = (aEnd > mLength) ? mLength : aEnd;
aDest.clear();
if (aStart >= end) {
return aDest;
}
PRUint32 substrLength = end - aStart;
if (!aDest.ensureCapacity(substrLength)) {
return aDest;
}
memcpy(aDest.mBuffer, &mBuffer[aStart],
substrLength * sizeof(UNICODE_CHAR));
aDest.mLength = substrLength;
return aDest;
}
void String::toLowerCase()
{
PRUint32 conversionLoop;
for (conversionLoop = 0; conversionLoop < mLength; ++conversionLoop) {
if ((mBuffer[conversionLoop] >= 'A') &&
(mBuffer[conversionLoop] <= 'Z'))
mBuffer[conversionLoop] += 32;
}
}
void String::toUpperCase()
{
PRUint32 conversionLoop;
for (conversionLoop = 0; conversionLoop < mLength; ++conversionLoop) {
if ((mBuffer[conversionLoop] >= 'a') &&
(mBuffer[conversionLoop] <= 'z'))
mBuffer[conversionLoop] -= 32;
}
}
String& String::operator = (const String& aSource)
{
delete [] mBuffer;
mBuffer = aSource.toUnicode();
mBufferLength = aSource.mLength;
mLength = aSource.mLength;
return *this;
}
MBool String::ensureCapacity(PRUint32 aCapacity)
{
PRUint32 needed = aCapacity + mLength;
if (needed >= 0x8000) {
NS_ASSERTION(0, "Asked for too large a buffer.");
return MB_FALSE;
}
if (needed < mBufferLength) {
return MB_TRUE;
}
UNICODE_CHAR* tempBuffer = new UNICODE_CHAR[needed];
NS_ASSERTION(tempBuffer, "Couldn't allocate string buffer.");
if (!tempBuffer) {
return MB_FALSE;
}
if (mLength > 0) {
memcpy(tempBuffer, mBuffer, mLength * sizeof(UNICODE_CHAR));
}
delete [] mBuffer;
mBuffer = tempBuffer;
mBufferLength = needed;
return MB_TRUE;
}
UNICODE_CHAR* String::toUnicode() const
{
if (mLength == 0) {
return 0;
}
UNICODE_CHAR* tmpBuffer = new UNICODE_CHAR[mLength];
NS_ASSERTION(tmpBuffer, "out of memory");
if (tmpBuffer) {
memcpy(tmpBuffer, mBuffer, mLength * sizeof(UNICODE_CHAR));
}
return tmpBuffer;
}
PRUint32 String::unicodeLength(const UNICODE_CHAR* aData)
{
PRUint32 index = 0;
// Count UNICODE_CHARs Until a Unicode "NULL" is found.
while (aData[index] != 0x0000) {
++index;
}
return index;
}
ostream& operator<<(ostream& aOutput, const String& aSource)
{
PRUint32 outputLoop;
for (outputLoop = 0; outputLoop < aSource.mLength; ++outputLoop) {
aOutput << (char)aSource.charAt(outputLoop);
}
return aOutput;
}
// XXX DEPRECATED
String::String(PRUint32 aSize) : mBuffer(0),
mBufferLength(0),
mLength(0)
{
ensureCapacity(aSize);
}
String::String(const char* aSource) : mBuffer(0),
mBufferLength(0),
mLength(0)
{
if (!aSource) {
return;
}
PRUint32 length = strlen(aSource);
if (!ensureCapacity(length)) {
return;
}
PRUint32 counter;
for (counter = 0; counter < length; ++counter) {
mBuffer[counter] = (UNICODE_CHAR)aSource[counter];
}
mLength = length;
}
void String::append(const char* aSource)
{
if (!aSource) {
return;
}
PRUint32 length = strlen(aSource);
if (!ensureCapacity(length)) {
return;
}
PRUint32 counter;
for (counter = 0; counter < length; ++counter) {
mBuffer[mLength + counter] = (UNICODE_CHAR)aSource[counter];
}
mLength += length;
}
MBool String::isEqual(const char* aData) const
{
if (!aData) {
return MB_FALSE;
}
PRUint32 length = strlen(aData);
if (length != mLength) {
return MB_FALSE;
}
PRUint32 counter;
for (counter = 0; counter < length; ++counter) {
if (mBuffer[counter] != (UNICODE_CHAR)aData[counter]) {
return MB_FALSE;
}
}
return MB_TRUE;
}