peterv%netscape.com 627640cc69 Fix for bug 96647 (Change the way output is constructed in Transformiix). r=sicking, Pike, sr=jst.
git-svn-id: svn://10.0.0.236/trunk@112688 18797224-902f-48f8-a5cc-f745e15eee43
2002-01-24 13:38:51 +00:00

1214 lines
29 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* (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 <stdlib.h>
#include <string.h>
#include "TxString.h"
#include <iostream.h>
//
//Default Constructor, create an empty String
//
String::String()
{
strBuffer = NULL;
bufferLength = 0;
strLength = 0;
}
//
//Create an empty String of a specific size
//
String::String(PRInt32 initSize)
{
strBuffer = new UNICODE_CHAR[initSize];
bufferLength = initSize;
strLength = 0;
}
//
//Create a copy of the source String
//TK 12/09/1999 - To ensure compatibility with sub classes of String, this
// constructor has been modified to use String's public
// interface only.
//
String::String(const String& source)
{
PRInt32 copyLoop;
//Allocate space for the source string
strLength = source.length();
//-- modified by kvisco to only use necessay amount of space
//-- was: bufferLength = source.bufferLength;
bufferLength = strLength;
strBuffer = new UNICODE_CHAR[bufferLength];
//Copy the new string data after the old data
for (copyLoop=0;copyLoop<strLength;copyLoop++)
strBuffer[copyLoop] = source.charAt(copyLoop);
}
//
//Create a String from the characters
//
String::String(const char* source)
{
PRInt32 copyLoop;
if (source)
{
strLength = bufferLength = strlen(source);
//Set up the new buffer to be the same size as the input char array.
strBuffer = new UNICODE_CHAR[bufferLength];
//Now store the char array in the new string buffer.
//Can't use strcpy since the destination is a UNICODE_CHAR buffer.
//Also make sure to pick up the null terminator at the end of the char
//array.
for (copyLoop=0; copyLoop<strLength; copyLoop++)
strBuffer[copyLoop] = (PRInt32)source[copyLoop];
}
else
{
//Create an empty string
strBuffer = NULL;
bufferLength = 0;
strLength = 0;
}
}
//
//Create a String from a null terminated array of UNICODE_CHARs
//
String::String(const UNICODE_CHAR* source)
{
PRInt32 copyLoop;
if (source)
{
strLength = bufferLength = UnicodeLength(source);
//Set up the new buffer to be the same size as the input char array.
strBuffer = new UNICODE_CHAR[bufferLength];
//Now store the char array in the new string buffer.
//Can't use strcpy since the destination is a UNICODE_CHAR buffer.
//Also make sure to pick up the null terminator at the end of the char
//array.
for (copyLoop=0; copyLoop<strLength; copyLoop++)
strBuffer[copyLoop] = source[copyLoop];
}
else
{
//Create an empty string
strBuffer = NULL;
bufferLength = 0;
strLength = 0;
}
}
//
//Create a String from a UNICODE_CHAR buffer and a supplied string length
//
String::String(const UNICODE_CHAR* source, PRInt32 length)
{
PRInt32 copyLoop;
if (source)
{
strLength = bufferLength = length;
//Set up the new buffer to be the same size as the input char array.
strBuffer = new UNICODE_CHAR[bufferLength];
//Now store the char array in the new string buffer.
//Can't use strcpy since the destination is a UNICODE_CHAR buffer.
//Also make sure to pick up the null terminator at the end of the char
//array.
for (copyLoop=0; copyLoop<strLength; copyLoop++)
strBuffer[copyLoop] = source[copyLoop];
}
else
{
//Create an empty string
strBuffer = NULL;
bufferLength = 0;
strLength = 0;
}
}
//
//Destroy the String, and free memory
//
String::~String()
{
//cout << "~String() deleting " << *this <<endl;
if (strBuffer)
delete strBuffer;
}
//
//Convert the UNICODE_CHARs of this String to Chars, and output them to the given
//ostream
//
ostream& operator<<(ostream& output, const String& source)
{
PRInt32 outputLoop;
for (outputLoop=0;outputLoop<source.length();outputLoop++)
output << (char)source.charAt(outputLoop);
return output;
}
//
//Overloaded '=' operator to assign the value of the source string to this
//string.
//TK 12/09/1999 - Modified to interact only with the public interface of the
// source "String" object. This ensures compatibility with
// subclasses of String.
//
String& String::operator=(const String& source)
{
PRInt32 copyLoop;
//Make sure string is not being copied onto itself
if (&source != this) {
//Check to see if this string is already big enough for source
//-- set size of current string length to 0 before making this call (kvisco)
strLength = 0;
ensureCapacity(source.length());
for (copyLoop=0; copyLoop<source.length(); copyLoop++)
strBuffer[copyLoop] = source.charAt(copyLoop);
strLength = copyLoop;
}
return *this;
}
//
//Overloaded '=' operator to assign the value of the source C string to this
//string
//
String& String::operator=(const char* source)
{
PRInt32 copyLoop;
PRInt32 sourceLength;
if (source)
{
sourceLength = strlen(source);
ensureCapacity(sourceLength);
for (copyLoop=0; copyLoop<sourceLength; copyLoop++)
strBuffer[copyLoop] = source[copyLoop];
strLength = copyLoop;
}
else
clear();
return *this;
}
//
//Overloaded '=' operator to assign the value of a UNICODE_CHAR string to this
//string. Note: The soucre is "NULL" terminated.
//
String& String::operator=(const UNICODE_CHAR* source)
{
PRInt32 copyLoop;
PRInt32 sourceLength;
if (source)
{
sourceLength = UnicodeLength(source);
ensureCapacity(sourceLength);
for (copyLoop=0; copyLoop<sourceLength; copyLoop++)
strBuffer[copyLoop] = source[copyLoop];
strLength = copyLoop;
}
else
clear();
return *this;
}
//
//Overloaded '=' operator to assign an integer to this string.
//
String& String::operator=(PRInt32 source)
{
ConvertInt(source, *this);
return *this; //-- added, LF
} //-- operator=
//
//Grow buffer by 1 if necessary, and append the source character
//
void String::append(UNICODE_CHAR source)
{
//Enlarge string buffer to fit source character if necessary
ensureCapacity(1);
//Insert the character and increment the length
strBuffer[strLength++] = source;
}
//
//Append a character to the string
//
void String::append(char source)
{
append((UNICODE_CHAR)source);
}
//
//Append String
//TK 12/09/199 - Modified to use the "source" String's public interface only,
// to ensure compatibility with sub classes
//
void String::append(const String& source)
{
PRInt32 copyLoop;
//Enlarge buffer to fit string if necessary
ensureCapacity(source.length());
//Copy the new string data after the old data
for (copyLoop=0;copyLoop<source.length();copyLoop++)
strBuffer[strLength+copyLoop] = source.charAt(copyLoop);
//Update the length
strLength += source.length();
}
//
//Append a string of characters (null terminated arry of chars)
//
void String::append(const char* source)
{
PRInt32 copyLoop;
PRInt32 initLength = strlen(source);
//Enlarge buffer to fit new string if necessary
ensureCapacity(initLength);
//Copy the new string data after the old data
for (copyLoop=0;copyLoop<initLength;copyLoop++)
strBuffer[strLength+copyLoop] = source[copyLoop];
//Update the length
strLength += initLength;
}
//
//Append a string of unicode chars (null terminated array of Unicode chars)
//
void String::append(const UNICODE_CHAR* source)
{
append(source, UnicodeLength(source));
}
//
//Append a string of DOM Characters whose length is also defined
//
void String::append(const UNICODE_CHAR* source, PRInt32 length)
{
PRInt32 copyLoop;
//Enlarge buffer to fit new string if necessary
ensureCapacity(length);
//Copy the new string data after the old data
for (copyLoop=0;copyLoop<length;copyLoop++)
strBuffer[strLength+copyLoop] = source[copyLoop];
//Update the length
strLength += length;
}
//
//Convert source from an integer to a string, and append it to the current
//string
//
void String::append(PRInt32 source)
{
String convertString;
append(ConvertInt(source, convertString));
}
//
//Insert a single UNICODE_CHAR into the string starting at offset
//
void String::insert(PRInt32 offset, const UNICODE_CHAR source)
{
PRInt32 moveLoop;
PRInt32 moveIndex;
offset = offset < 0 ? 0 : offset;
if (offset < strLength)
{
moveLoop = strLength - offset;
moveIndex = strLength - 1;
//Enlarge string buffer to fit source character
ensureCapacity(1);
//Bump all characters down one position to make room for new character
while (moveLoop--)
strBuffer[moveIndex+1] = strBuffer[moveIndex--];
strBuffer[moveIndex+1] = source;
strLength += 1;
}
else
append(source);
}
//
//Insert a single C type character into the string starting at offset
//
void String::insert(PRInt32 offset, const char source)
{
insert(offset, (UNICODE_CHAR)source);
}
//
//Insert the source string starting at the current offset
//TK 12/09/1999 - Modified to use the "source" String's public interface only,
// to ensure compatibility with subclasses of String
//
void String::insert(PRInt32 offset, const String& source)
{
PRInt32 moveLoop;
PRInt32 moveIndex;
PRInt32 copyLoop;
offset = offset < 0 ? 0 : offset;
if (offset < strLength)
{
moveLoop = strLength - offset;
moveIndex = strLength - 1;
//Enlarge string buffer to fit source character
ensureCapacity(source.length());
//Bump all characters down one position to make room for new character
while (moveLoop--)
strBuffer[moveIndex+source.length()] = strBuffer[moveIndex--];
moveIndex += 1;
for (copyLoop=0;copyLoop<source.strLength;copyLoop++)
strBuffer[moveIndex+copyLoop] = source.charAt(copyLoop);
strLength += source.length();
}
else
append(source);
}
//
//Insert the source "C" type string into this string starting at offset
//
void String::insert(PRInt32 offset, const char* source)
{
PRInt32 moveLoop;
PRInt32 moveIndex;
PRInt32 copyLoop;
PRInt32 sourceLength;
offset = offset < 0 ? 0 : offset;
if (offset < strLength)
{
moveLoop = strLength - offset;
moveIndex = strLength - 1;
sourceLength = strlen(source);
//Enlarge string buffer to fit source character
ensureCapacity(sourceLength);
//Bump all characters down to make room for new character
while (moveLoop--)
strBuffer[moveIndex+sourceLength] = strBuffer[moveIndex--];
moveIndex += 1;
for (copyLoop=0;copyLoop<sourceLength;copyLoop++)
strBuffer[moveIndex+copyLoop] = source[copyLoop];
strLength += sourceLength;
}
else
append(source);
}
//
//Insert the source UNICODE_CHAR type string into this string starting at
//offset. Note that the source is Null Terminated.
//
void String::insert(PRInt32 offset, const UNICODE_CHAR* source)
{
insert(offset, source, UnicodeLength(source));
}
void String::insert(PRInt32 offset, const UNICODE_CHAR* source,
PRInt32 sourceLength)
{
PRInt32 moveLoop;
PRInt32 moveIndex;
PRInt32 copyLoop;
offset = offset < 0 ? 0 : offset;
if (offset < strLength)
{
moveLoop = strLength - offset;
moveIndex = strLength - 1;
//Enlarge string buffer to fit source character
ensureCapacity(sourceLength);
//Bump all characters down to make room for new character
while (moveLoop--)
strBuffer[moveIndex+sourceLength] = strBuffer[moveIndex--];
moveIndex += 1;
for (copyLoop=0;copyLoop<sourceLength;copyLoop++)
strBuffer[moveIndex+copyLoop] = source[copyLoop];
strLength += sourceLength;
}
else
append(source, sourceLength);
}
//
//Convert source from an integer to a string, and then insert.
//
void String::insert(PRInt32 offset, PRInt32 source)
{
String convertString;
insert(offset, ConvertInt(source, convertString));
}
//
//Replace the character specified by offset with the UNICODE_CHAR source
//
void String::replace(PRInt32 offset, const UNICODE_CHAR source)
{
offset = offset < 0 ? 0 : offset;
if (offset < strLength)
{
strBuffer[offset] = source;
}
else
append(source);
}
//
//Replace the character specified by offset with the C style character source
//
void String::replace(PRInt32 offset, const char source)
{
replace(offset, (UNICODE_CHAR)source);
}
//
//Replace the substring starting at offset with the String specified by source.
//Enlarge the string buffer if source will require more characters than
//currently available.
//TK 12/09/1999 - Modified to use the "source" String's public interface only,
// to ensure compatibility with classes derived from String
//
void String::replace(PRInt32 offset, const String& source)
{
PRInt32 totalOffset = 0;
PRInt32 replaceLoop;
if (offset < strLength)
{
offset = offset < 0 ? 0 : offset;
totalOffset = offset + source.length();
if (totalOffset > strLength)
{
ensureCapacity(totalOffset - strLength);
strLength += totalOffset - strLength;
}
for (replaceLoop=0;replaceLoop<source.length();replaceLoop++)
strBuffer[offset + replaceLoop] = source.charAt(replaceLoop);
}
else
append(source);
}
//
//Replace the substring starting at offset with the "C" style character string.
//enlarge the string buffer if source will require more characters than
//currently available.
//
void String::replace(PRInt32 offset, const char* source)
{
PRInt32 totalOffset = 0;
PRInt32 replaceLoop;
PRInt32 sourceLength;
if (offset < strLength)
{
offset = offset < 0 ? 0 : offset;
sourceLength = strlen(source);
totalOffset = offset + sourceLength;
if (totalOffset > strLength)
{
ensureCapacity(totalOffset - strLength);
strLength += totalOffset - strLength;
}
for (replaceLoop=0;replaceLoop<sourceLength;replaceLoop++)
strBuffer[offset + replaceLoop] = source[replaceLoop];
}
else
append(source);
}
//
//Replace the substring starting at offset with the Unicode string.
//enlarge the string buffer if source will require more characters than
//currently available.
//TK 12/21/1999 - Simply deffer functionality to the replace function
// below (accepting a length for the Unicode buffer).
//
void String::replace(PRInt32 offset, const UNICODE_CHAR* source)
{
replace(offset, source, UnicodeLength(source));
}
//
//Replace the substring starting at offset with the Unicode string.
//enlarge the string buffer if source will require more characters than
//currently available.
//
void String::replace(PRInt32 offset, const UNICODE_CHAR* source, PRInt32 srcLength)
{
PRInt32 totalOffset = 0;
PRInt32 replaceLoop;
if (offset < strLength)
{
offset = offset < 0 ? 0 : offset;
totalOffset = offset + srcLength;
if (totalOffset > strLength)
{
ensureCapacity(totalOffset - strLength);
strLength += totalOffset - strLength;
}
for (replaceLoop=0;replaceLoop<srcLength;replaceLoop++)
strBuffer[offset + replaceLoop] = source[replaceLoop];
}
else
append(source);
}
//
//Convert source from an integer to a String, and perform a replacement.
//
void String::replace(PRInt32 offset, PRInt32 source)
{
String convertString;
replace(offset, ConvertInt(source, convertString));
}
/**
* Sets the Length of this String, if length is less than 0, it will
* be set to 0; if length > current length, the string will be extended
* and padded with '\0' null characters. Otherwise the String
* will be truncated
**/
void String::setLength(PRInt32 length) {
setLength(length, '\0');
} //-- setLength
/**
* Sets the Length of this String, if length is less than 0, it will
* be set to 0; if length > current length, the string will be extended
* and padded with given pad character. Otherwise the String
* will be truncated
**/
void String::setLength(PRInt32 length, UNICODE_CHAR padChar) {
if ( length < 0 ) strLength = 0;
else if ( length > strLength ) {
PRInt32 diff = length-strLength;
ensureCapacity(diff);
for ( PRInt32 i = strLength; i < length; i++ )
strBuffer[i] = padChar;
strLength = length;
}
else strLength = length;
} //-- setLength
//
//Delete the "substring" starting at "offset" and proceeding for "count" number
//of characters (or until the end of the string, whichever comes first).
//
void String::deleteChars(PRInt32 offset, PRInt32 count)
{
PRInt32 deleteLoop;
PRInt32 offsetCount;
offset = offset < 0 ? 0 : offset;
offsetCount = offset + count;
if (offsetCount < strLength)
{
for (deleteLoop=0;deleteLoop<strLength-offsetCount;deleteLoop++)
strBuffer[offset + deleteLoop] = strBuffer[offsetCount + deleteLoop];
strLength -= count;
}
else
strLength = offset;
}
/**
* Returns the character at index.
* If the index is out of bounds, -1 will be returned.
**/
UNICODE_CHAR String::charAt(PRInt32 index) const
{
if ((index < strLength) && (index >= 0))
return strBuffer[index];
else
return (UNICODE_CHAR)-1;
}
//
//Clear out the string by simply setting the length to zero. The buffer is
//left intact.
//
void String::clear()
{
strLength = 0;
}
//
//Make sure the buffer has room for 'capacity' UNICODE_CHARS.
//
void String::ensureCapacity(PRInt32 capacity)
{
UNICODE_CHAR* tempStrBuffer = NULL;
//Check for the desired capacity
PRInt32 freeSpace = bufferLength - strLength; //(added by kvisco)
if (freeSpace < capacity) {
//-- modified by kvisco to only add needed capacity,
//-- not extra bytes as before
//-- old : bufferLength += capacity;
bufferLength += capacity - freeSpace;
tempStrBuffer = new UNICODE_CHAR[bufferLength];
copyString(tempStrBuffer);
//If the old string contained any data, delete it, and save the new.
if (strBuffer)
delete strBuffer;
strBuffer = tempStrBuffer;
}
}
/**
* Performs a CASE SENSITIVE search of the string for the first occurence
* of 'data'. If found return the index, else return NOT_FOUND.
* -- changed by kvisco to call indexOf(UNICODE_CHAR, PRInt32)
**/
PRInt32 String::indexOf(UNICODE_CHAR data) const
{
return indexOf(data, 0);
} //-- indexOf
//
//Starting at 'offset' perform a CASE SENSITIVE search of the string looking
//for the first occurence of 'data'. If found return the index, else return
//NOT_FOUND. If the offset is less than zero, then start at zero.
//
PRInt32 String::indexOf(UNICODE_CHAR data, PRInt32 offset) const
{
PRInt32 searchIndex = offset < 0 ? searchIndex = 0 : searchIndex = offset;
while (1)
{
if (searchIndex >= strLength)
return NOT_FOUND;
else if (strBuffer[searchIndex] == data)
return searchIndex;
else
++searchIndex;
}
} //-- indexOf
//
//Returns the index of the first occurence of data
//TK 12/09/1999 - Modified to simply use indexOf(const String&, PRInt32).
//
PRInt32 String::indexOf(const String& data) const
{
return indexOf(data, 0);
}
//
//Returns the index of the first occurrence of data starting at offset
//TK 12/09/1999 - Modified to use the "data" String's public interface to
// retreive the Unicode Char buffer when calling isEqual.
// This ensures compatibility with classes derrived from String.
//
PRInt32 String::indexOf(const String& data, PRInt32 offset) const
{
PRInt32 searchIndex = offset < 0 ? 0 : offset;
while (1)
{
if (searchIndex <= (strLength - data.length()))
{
if (isEqual(&strBuffer[searchIndex], data.toUnicode(), data.length()))
return searchIndex;
}
else
return NOT_FOUND;
searchIndex++;
}
}
//
//Check for equality between this string, and data
//TK 12/09/1999 - Modified to use data.toUnicode() public member function
// when working with data's unicode buffer. This ensures
// compatibility with derrived classes.
//
MBool String::isEqual(const String& data) const
{
if (strLength != data.length())
return MB_FALSE;
return isEqual(strBuffer, data.toUnicode(), data.length());
}
MBool String::isEqualIgnoreCase(const String& data) const
{
if (strLength != data.length())
return MB_FALSE;
const UNICODE_CHAR* otherBuffer = data.strBuffer;
UNICODE_CHAR thisChar, otherChar;
PRInt32 compLoop = 0;
while (compLoop < strLength) {
thisChar = strBuffer[compLoop];
if ((thisChar >= 'A') && (thisChar <= 'Z'))
thisChar += 32;
otherChar = otherBuffer[compLoop];
if ((otherChar >= 'A') && (otherChar <= 'Z'))
otherChar += 32;
if (thisChar != otherChar)
return MB_FALSE;
++compLoop;
}
return MB_TRUE;
}
/**
* Returns index of last occurrence of data
**/
PRInt32 String::lastIndexOf(UNICODE_CHAR data) const
{
return lastIndexOf(data, strLength-1);
} //-- lastIndexOf
/**
* Returns the index of the last occurrence of data starting at offset
**/
PRInt32 String::lastIndexOf(UNICODE_CHAR data, PRInt32 offset) const
{
if ((offset < 0) || (offset >= strLength)) return NOT_FOUND;
PRInt32 searchIndex = offset;
while (searchIndex >= 0) {
if (strBuffer[searchIndex] == data) return searchIndex;
--searchIndex;
}
return NOT_FOUND;
} //-- lastIndexOf
/**
* Returns the index of the last occurrence of data
**/
PRInt32 String::lastIndexOf(const String& data) const
{
return lastIndexOf(data, strLength-1);
} //-- lastIndexOf
/**
* Returns the index of the last occurrence of data starting at offset
**/
PRInt32 String::lastIndexOf(const String& data, PRInt32 offset) const
{
PRInt32 searchIndex;
const UNICODE_CHAR* dataStrBuffer = NULL;
if ((offset < 0) || (offset >= strLength))
return NOT_FOUND;
else
{
searchIndex = offset;
//If there is not enough space between searchIndex and the length of the of
//the string for "data" to appear, then there is no reason to search it.
if ((strLength - searchIndex) < data.length())
searchIndex = strLength - data.length();
dataStrBuffer = data.toUnicode();
while (searchIndex >= 0)
{
if (isEqual(&strBuffer[searchIndex], data.toUnicode(), data.length()))
return searchIndex;
--searchIndex;
}
}
return NOT_FOUND;
}
//
//Checks whether the string is empty
//
MBool String::isEmpty() const
{
return (strLength == 0);
}
//
//Returns the length of the String
//
PRInt32 String::length() const
{
return strLength;
}
//
//Returns a subString starting at start
//TK 12/09/1999 - Modified to simply use subString(PRInt32, PRInt32, String&)
//
String& String::subString(PRInt32 start, String& dest) const
{
return subString(start, strLength, dest);
}
/**
* Returns the subString starting at start and ending at end
* Note: the dest String is cleared before use
* TK 12/09/1999 - Modified to use the "dest" String's public interface to
* ensure compatibility wtih derrived classes.
**/
String& String::subString(PRInt32 start, PRInt32 end, String& dest) const
{
PRInt32 srcLoop;
start = start < 0 ? 0 : start;
end = end > strLength ? strLength : end;
dest.clear();
if (start < end)
{
dest.ensureCapacity(end - start);
for (srcLoop=start;srcLoop<end;srcLoop++)
dest.append(strBuffer[srcLoop]);
}
return dest;
}
/**
* Instantiate a new character buffer (remembering the null terminator) and pass
* it to toChar(char*).
**/
char* String::toCharArray() const
{
char* tmpBuffer = new char[strLength+1];
NS_ASSERTION(tmpBuffer, "out of memory");
return toCharArray(tmpBuffer);
}
/**
* Convert the internally represented string to a character buffer. Store
* the resultant character array in the buffer provided by the caller. A
* null terminator will be placed at the end of the array, make sure
* space has been provided.
**/
char* String::toCharArray(char* dest) const
{
if (!dest)
return 0;
PRInt32 copyLoop;
for (copyLoop = 0; copyLoop < strLength; copyLoop++)
dest[copyLoop] = (char)strBuffer[copyLoop];
//Place a NULL terminator at the end of the character buffer
dest[copyLoop] = 0;
return dest;
}
/**
* Returns the internal UNICODE_CHAR array so the caller can have access to the
* to the UNICODE_CHAR representation of the string. Will not place a null
* terminator at the end of the array, as in a call to toChar will do.
**/
UNICODE_CHAR* String::toUnicode(UNICODE_CHAR* dest) const
{
PRInt32 copyLoop;
for (copyLoop=0;copyLoop<strLength;copyLoop++)
dest[copyLoop] = strBuffer[copyLoop];
//-- removed null terminator at end (kvisco)
return dest;
}
//
//This fuction returns the actual UNICODE_CHAR* buffer storing the string.
//This provides a more efficient means to interact with the buffer in a read
//only fahsion.
//
const UNICODE_CHAR* String::toUnicode() const
{
return strBuffer;
}
//
//Convert String to lowercase
//
void String::toLowerCase()
{
PRInt32 conversionLoop;
for (conversionLoop=0;conversionLoop<strLength;conversionLoop++)
{
if ((strBuffer[conversionLoop] >= 'A') &&
(strBuffer[conversionLoop] <= 'Z'))
strBuffer[conversionLoop] += 32;
}
}
//
//Convert String to uppercase
//
void String::toUpperCase()
{
PRInt32 conversionLoop;
for (conversionLoop=0;conversionLoop<strLength;conversionLoop++)
{
if ((strBuffer[conversionLoop] >= 'a') &&
(strBuffer[conversionLoop] <= 'z'))
strBuffer[conversionLoop] -= 32;
}
}
//
//Trim whitespace from both ends of String
//
void String::trim()
{
PRInt32 trimLoop = strLength - 1;
PRInt32 cutLoop;
MBool done = MB_FALSE;
//As long as we are not working on an emtpy string, trim from the right
//first, so we don't have to move useless spaces when we trim from the left.
if (strLength > 0)
{
while (!done)
{
switch (strBuffer[trimLoop])
{
case ' ' :
case '\t' :
case '\n' :
case '\r' :
--strLength;
--trimLoop;
break;
default :
done = MB_TRUE;
break;
}
}
}
//Now, if there are any characters left to the string, Trim to the left.
//First count the number of "left" spaces. Then move all characters to the
//left by that ammount.
if (strLength > 0)
{
done = MB_FALSE;
trimLoop = 0;
while (!done)
{
switch (strBuffer[trimLoop])
{
case ' ' :
case '\t' :
case '\n' :
case '\r' :
++trimLoop;
break;
default :
done = MB_TRUE;
break;
}
}
if (trimLoop < strLength)
{
for (cutLoop=trimLoop;cutLoop<strLength;cutLoop++)
strBuffer[cutLoop-trimLoop] = strBuffer[cutLoop];
}
strLength -= trimLoop;
}
}
//
//Cause the string to reverse itself
//
void String::reverse()
{
PRInt32 reverseLoop;
UNICODE_CHAR tempChar;
for (reverseLoop=0;reverseLoop<(strLength/2); reverseLoop++)
{
tempChar = strBuffer[reverseLoop];
strBuffer[reverseLoop] = strBuffer[strLength - reverseLoop - 1];
strBuffer[strLength - reverseLoop - 1] = tempChar;
}
}
//
//String copies itself to the destination
//
void String::copyString(UNICODE_CHAR* dest)
{
PRInt32 copyLoop;
for (copyLoop=0;copyLoop<strLength;copyLoop++)
dest[copyLoop] = strBuffer[copyLoop];
}
//
//Compare the two string representations for equality
//
MBool String::isEqual(const UNICODE_CHAR* data, const UNICODE_CHAR* search,
PRInt32 length) const
{
PRInt32 compLoop = 0;
while (compLoop < length)
{
if (data[compLoop] != search[compLoop])
return MB_FALSE;
compLoop++;
}
return MB_TRUE;
}
//
//Convert an PRInt32 into a String by storing it in target
//
String& String::ConvertInt(PRInt32 value, String& target)
{
UNICODE_CHAR charDigit;
target.clear();
while (value)
{
charDigit = (value % 10) + 48;
target.append(charDigit);
value /=10;
}
target.reverse();
return target;
}
//
//Calculate the length of a null terminated UNICODE_CHAR string
//
PRInt32 String::UnicodeLength(const UNICODE_CHAR* data)
{
PRInt32 index = 0;
//Count UNICODE_CHARs Until a Unicode "NULL" is found.
while (data[index] != 0x0000)
index++;
return index;
}