1335 lines
25 KiB
C++
1335 lines
25 KiB
C++
/*
|
|
** Command & Conquer Renegade(tm)
|
|
** Copyright 2025 Electronic Arts Inc.
|
|
**
|
|
** This program is free software: you can redistribute it and/or modify
|
|
** it under the terms of the GNU General Public License as published by
|
|
** the Free Software Foundation, either version 3 of the License, or
|
|
** (at your option) any later version.
|
|
**
|
|
** This program is distributed in the hope that it will be useful,
|
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
** GNU General Public License for more details.
|
|
**
|
|
** You should have received a copy of the GNU General Public License
|
|
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/******************************************************************************
|
|
*
|
|
* FILE
|
|
* $Archive: /Commando/Code/Launcher/Toolkit/Support/UString.cpp $
|
|
*
|
|
* DESCRIPTION
|
|
* String management class (Unicode)
|
|
*
|
|
* PROGRAMMER
|
|
* Denzil E. Long, Jr.
|
|
* $Author: Denzil_l $
|
|
*
|
|
* VERSION INFO
|
|
* $Modtime: 8/18/00 10:39a $
|
|
* $Revision: 1 $
|
|
*
|
|
******************************************************************************/
|
|
|
|
#include "VisualC.h"
|
|
#include "UString.h"
|
|
#include "StringConvert.h"
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <assert.h>
|
|
|
|
// Convert character to lowercase
|
|
template<typename T> T CharToLower(const T ch)
|
|
{
|
|
if ((ch >= (T)'A') && (ch <= (T)'Z'))
|
|
{
|
|
return (ch + 32);
|
|
}
|
|
|
|
return ch;
|
|
}
|
|
|
|
// Convert character to uppercase
|
|
template<typename T> T CharToUpper(const T ch)
|
|
{
|
|
if ((ch >= (T)'a') && (ch <= (T)'z'))
|
|
{
|
|
return (ch - 32);
|
|
}
|
|
|
|
return ch;
|
|
}
|
|
|
|
|
|
// Check if character is one of the specified characters
|
|
template<typename T>bool IsCharacter(WChar ch, const T* oneOf)
|
|
{
|
|
assert(oneOf != NULL);
|
|
|
|
int length = 0;
|
|
|
|
while (oneOf[length] != 0)
|
|
{
|
|
length++;
|
|
}
|
|
|
|
for (int index = 0; index < length; index++)
|
|
{
|
|
if (ch == (WChar)oneOf[index])
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
// Strip all left side characters that are trim chars
|
|
template<typename T> bool StripLeft(WChar* string, const T* trimChars)
|
|
{
|
|
// Strip leading trim characters from the string.
|
|
WChar* start = string;
|
|
|
|
while ((*start != 0) && IsCharacter<T>(*start, trimChars))
|
|
{
|
|
start++;
|
|
}
|
|
|
|
if (start != string)
|
|
{
|
|
wcscpy(string, start);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
// Strip all right side characters that are trim chars
|
|
template<typename T> bool StripRight(WChar* string, const T* trimChars)
|
|
{
|
|
int length = wcslen(string) - 1;
|
|
int index = length;
|
|
|
|
while (index >= 0)
|
|
{
|
|
if (!IsCharacter<T>(string[index], trimChars))
|
|
{
|
|
break;
|
|
}
|
|
|
|
string[index] = 0;
|
|
index--;
|
|
}
|
|
|
|
return (index != length);
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* UString::UString - Default constructor
|
|
*
|
|
* DESCRIPTION
|
|
* Create a new empty UString.
|
|
*
|
|
* INPUTS
|
|
* NONE
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
UString::UString()
|
|
: mData(NULL),
|
|
mCapacity(0)
|
|
{
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* UString::UString - Capacity contructor
|
|
*
|
|
* DESCRIPTION
|
|
* Create a new empty UString with the specified capacity.
|
|
*
|
|
* INPUTS
|
|
* Capacity - Number of characters to allocated to string.
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
UString::UString(UInt capacity)
|
|
: mData(NULL),
|
|
mCapacity(0)
|
|
{
|
|
AllocString(capacity);
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* UString::UString - ANSI string literal constructor
|
|
*
|
|
* DESCRIPTION
|
|
* Create a new UString from an ANSI string literal
|
|
*
|
|
* INPUTS
|
|
* String - Pointer to a NULL terminated ANSI string
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
UString::UString(const Char* s)
|
|
: mData(NULL),
|
|
mCapacity(0)
|
|
{
|
|
Copy(s);
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* UString::UString - UNICODE string literal constructor
|
|
*
|
|
* DESCRIPTION
|
|
* Create a new UString from a UNICODE string literal
|
|
*
|
|
* INPUTS
|
|
* String - Pointer to a NULL terminated UNICODE string
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
UString::UString(const WChar* ws)
|
|
: mData(NULL),
|
|
mCapacity(0)
|
|
{
|
|
Copy(ws);
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* UString::UString - Copy constructor
|
|
*
|
|
* DESCRIPTION
|
|
* Create a new UString from another UString
|
|
*
|
|
* INPUTS
|
|
* String - Reference to UString to copy
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
UString::UString(const UString& s)
|
|
: mData(NULL),
|
|
mCapacity(0)
|
|
{
|
|
Copy(s);
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* UString::~UString - Destructor
|
|
*
|
|
* DESCRIPTION
|
|
* Destroy the object
|
|
*
|
|
* INPUTS
|
|
* NONE
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
UString::~UString()
|
|
{
|
|
if (mData != NULL)
|
|
{
|
|
delete mData;
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* UString::Length
|
|
*
|
|
* DESCRIPTION
|
|
* Retrieve the length of the string in characters.
|
|
*
|
|
* INPUTS
|
|
* NONE
|
|
*
|
|
* RESULT
|
|
* Length - Length of string
|
|
*
|
|
******************************************************************************/
|
|
|
|
UInt UString::Length(void) const
|
|
{
|
|
if (mData == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return wcslen(mData);
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* UString::Copy - ANSI string literal
|
|
*
|
|
* DESCRIPTION
|
|
* Copy ANSI string literal.
|
|
*
|
|
* INPUTS
|
|
* String - Pointer to ANSI string literal
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
void UString::Copy(const Char* s)
|
|
{
|
|
assert(s != NULL);
|
|
UInt length = strlen(s);
|
|
|
|
if (length == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (Capacity() < length)
|
|
{
|
|
AllocString(length);
|
|
}
|
|
|
|
// Copy and convert ansi string to unicode
|
|
assert(Capacity() >= length);
|
|
WChar* wsPtr = mData;
|
|
const Char* sPtr = s;
|
|
|
|
while (length-- > 0)
|
|
{
|
|
*wsPtr++ = (WChar)*sPtr++;
|
|
}
|
|
|
|
*wsPtr = 0;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* UString::Copy - Unicode string literal
|
|
*
|
|
* DESCRIPTION
|
|
* Copy a Unicode string literal
|
|
*
|
|
* INPUTS
|
|
* String - Pointer to UNICODE string literal
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
void UString::Copy(const WChar* ws)
|
|
{
|
|
assert(ws != NULL);
|
|
UInt length = wcslen(ws);
|
|
|
|
if (length == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (Capacity() < length)
|
|
{
|
|
AllocString(length);
|
|
}
|
|
|
|
assert(Capacity() >= length);
|
|
wcscpy(mData, ws);
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* UString::Copy
|
|
*
|
|
* DESCRIPTION
|
|
* Copy string
|
|
*
|
|
* INPUTS
|
|
* String - Reference to UString
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
void UString::Copy(const UString& s)
|
|
{
|
|
Copy(s.Get());
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* UString::Concat - ANSI string literal
|
|
*
|
|
* DESCRIPTION
|
|
* Concatenate an ANSI string literal to this string
|
|
*
|
|
* INPUTS
|
|
* String - Pointer to ANSI string literal
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
void UString::Concat(const Char* s)
|
|
{
|
|
// Parameter check
|
|
assert(s != NULL);
|
|
|
|
UInt length = Length();
|
|
UInt additional = strlen(s);
|
|
UInt totalLength = (length + additional);
|
|
|
|
// Resize the string if the combined size is to small
|
|
if (Capacity() < totalLength)
|
|
{
|
|
Resize(totalLength);
|
|
}
|
|
|
|
// Concatenate and convert ansi string to unicode
|
|
WChar* wsPtr = &mData[length];
|
|
const Char* sPtr = s;
|
|
|
|
while (additional-- > 0)
|
|
{
|
|
*wsPtr++ = (WChar)*sPtr++;
|
|
}
|
|
|
|
*wsPtr = 0;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* UString::Concat - Unicode string literal
|
|
*
|
|
* DESCRIPTION
|
|
* Concatenate a Unicode string literal to this string
|
|
*
|
|
* INPUTS
|
|
* String - Pointer to UNICODE string literal
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
void UString::Concat(const WChar* ws)
|
|
{
|
|
assert(ws != NULL);
|
|
UInt length = (Length() + wcslen(ws));
|
|
|
|
if (Capacity() < length)
|
|
{
|
|
Resize(length);
|
|
}
|
|
|
|
wcscat(mData, ws);
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* UString::Concat
|
|
*
|
|
* DESCRIPTION
|
|
* Concatenate string
|
|
*
|
|
* INPUTS
|
|
* String - Reference to UString
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
void UString::Concat(const UString& s)
|
|
{
|
|
Concat(s.Get());
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* UString::Compare - ANSI string literal
|
|
*
|
|
* DESCRIPTION
|
|
* Compare strings, returning a value representing their relationship.
|
|
*
|
|
* INPUTS
|
|
* String - String to compare against
|
|
*
|
|
* RESULT
|
|
* Relationship - < 0 String less than this.
|
|
* = 0 Strings identical
|
|
* > 0 String greater than this.
|
|
*
|
|
******************************************************************************/
|
|
|
|
Int UString::Compare(const Char* s) const
|
|
{
|
|
// If comparing string is NULL and this string is NULL then strings are equal,
|
|
// otherwise comparing string is less than this string.
|
|
if (s == NULL)
|
|
{
|
|
if (Get() == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
// If this string is NULL then comparing string is greater
|
|
if (Get() == NULL)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
// Compare each character
|
|
const WChar* ws = Get();
|
|
Int index = 0;
|
|
|
|
for (;;)
|
|
{
|
|
// Difference between characters
|
|
Int diff = ((WChar)s[index] - ws[index]);
|
|
|
|
// If the difference is not zero then the characters differ
|
|
if (diff != 0)
|
|
{
|
|
return diff;
|
|
}
|
|
|
|
// If the end of either string has been reached then terminate loop
|
|
if ((ws[index] == L'\0') || (s[index] == '\0'))
|
|
{
|
|
break;
|
|
}
|
|
|
|
// Advance to next character
|
|
index++;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* UString::Compare - Unicode string literal
|
|
*
|
|
* DESCRIPTION
|
|
* Compare strings, returning a value representing their relationship.
|
|
*
|
|
* INPUTS
|
|
* String - String to compare against
|
|
*
|
|
* RESULT
|
|
* Relationship - < 0 String less than this.
|
|
* = 0 Strings identical
|
|
* > 0 String greater than this.
|
|
*
|
|
******************************************************************************/
|
|
|
|
Int UString::Compare(const WChar* ws) const
|
|
{
|
|
return wcscmp(ws, Get());
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* UString::Compare
|
|
*
|
|
* DESCRIPTION
|
|
* Compare strings, returning a value representing their relationship.
|
|
*
|
|
* INPUTS
|
|
* String - String to compare against
|
|
*
|
|
* RESULT
|
|
* Relationship - < 0 String less than this.
|
|
* = 0 Strings identical
|
|
* > 0 String greater than this.
|
|
*
|
|
******************************************************************************/
|
|
|
|
Int UString::Compare(const UString& s) const
|
|
{
|
|
return Compare(s.Get());
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* UString::CompareNoCase - ANSI string literal
|
|
*
|
|
* DESCRIPTION
|
|
* Compare strings (case insensitive), returning a value representing their
|
|
* relationship.
|
|
*
|
|
* INPUTS
|
|
* String - String to compare against
|
|
*
|
|
* RESULT
|
|
* Relationship - < 0 String less than this.
|
|
* = 0 Strings identical
|
|
* > 0 String greater than this.
|
|
*
|
|
******************************************************************************/
|
|
|
|
Int UString::CompareNoCase(const Char* s) const
|
|
{
|
|
// If comparing string is NULL and this string is NULL then strings are
|
|
// equal, otherwise comparing string is less than this string.
|
|
if (s == NULL)
|
|
{
|
|
if (Get() == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
// If this string is NULL then comparing string is greater.
|
|
if (Get() == NULL)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
// Compare each character
|
|
const WChar* ws = Get();
|
|
Int index = 0;
|
|
|
|
for (;;)
|
|
{
|
|
// Convert to lowercase for compare
|
|
WChar sc = (WChar)CharToLower<Char>(s[index]);
|
|
WChar wc = CharToLower<WChar>(ws[index]);
|
|
|
|
// Difference between characters.
|
|
Int diff = (sc - wc);
|
|
|
|
// If the difference is not zero then the characters differ.
|
|
if (diff != 0)
|
|
{
|
|
return diff;
|
|
}
|
|
|
|
// If the end of either string has been reached then terminate loop.
|
|
if ((ws[index] == L'\0') || (s[index] == '\0'))
|
|
{
|
|
break;
|
|
}
|
|
|
|
// Advance to next character
|
|
index++;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* UString::CompareNoCase - Unicode string literal
|
|
*
|
|
* DESCRIPTION
|
|
* Compare strings (case insensitive), returning a value representing their
|
|
* relationship.
|
|
*
|
|
* INPUTS
|
|
* String - String to compare against
|
|
*
|
|
* RESULT
|
|
* Relationship - < 0 String less than this.
|
|
* = 0 Strings identical
|
|
* > 0 String greater than this.
|
|
*
|
|
******************************************************************************/
|
|
|
|
Int UString::CompareNoCase(const WChar* ws) const
|
|
{
|
|
return wcsicmp(ws, Get());
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* UString::CompareNoCase
|
|
*
|
|
* DESCRIPTION
|
|
* Compare strings (case insensitive), returning a value representing their
|
|
* relationship.
|
|
*
|
|
* INPUTS
|
|
* String - String to compare against
|
|
*
|
|
* RESULT
|
|
* Relationship - < 0 String less than this.
|
|
* = 0 Strings identical
|
|
* > 0 String greater than this.
|
|
*
|
|
******************************************************************************/
|
|
|
|
Int UString::CompareNoCase(const UString& s) const
|
|
{
|
|
return CompareNoCase(s.Get());
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* UString::Find - ANSI character
|
|
*
|
|
* DESCRIPTION
|
|
* Find the first occurance of character
|
|
*
|
|
* INPUTS
|
|
* Char - ANSI character to search for
|
|
*
|
|
* RESULT
|
|
* Position - Position of character (-1 if not found)
|
|
*
|
|
******************************************************************************/
|
|
|
|
Int UString::Find(Char c) const
|
|
{
|
|
return Find((WChar)c);
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* UString::Find - Unicode character
|
|
*
|
|
* DESCRIPTION
|
|
* Find the first occurance of character
|
|
*
|
|
* INPUTS
|
|
* Char - Unicode character to search for.
|
|
*
|
|
* RESULT
|
|
* Position - Position of character (-1 if not found)
|
|
*
|
|
******************************************************************************/
|
|
|
|
Int UString::Find(WChar c) const
|
|
{
|
|
WChar* ptr = wcschr(Get(), c);
|
|
|
|
// Not found?
|
|
if (ptr == NULL)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
return ((ptr - mData) / sizeof(WChar));
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* UString::FindLast - ANSI character
|
|
*
|
|
* DESCRIPTION
|
|
* Find the last occurance of a character
|
|
*
|
|
* INPUTS
|
|
* Char - ANSI character
|
|
*
|
|
* RESULT
|
|
* Position - Position of character (-1 if not found)
|
|
*
|
|
******************************************************************************/
|
|
|
|
Int UString::FindLast(Char c) const
|
|
{
|
|
return FindLast((WChar)c);
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* UString::FindLast - Unicode character
|
|
*
|
|
* DESCRIPTION
|
|
* Find the last occurance of a character
|
|
*
|
|
* INPUTS
|
|
* Char - Unicode character
|
|
*
|
|
* RESULT
|
|
* Position - Position of character (-1 if not found)
|
|
*
|
|
******************************************************************************/
|
|
|
|
Int UString::FindLast(WChar c) const
|
|
{
|
|
assert(mData != NULL);
|
|
WChar* ptr = wcsrchr(mData, (WChar)c);
|
|
|
|
// Not found?
|
|
if (ptr == NULL)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
return ((ptr - mData) / sizeof(WChar));
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* UString::SubString - ANSI string literal
|
|
*
|
|
* DESCRIPTION
|
|
* Find a substring
|
|
*
|
|
* INPUTS
|
|
* SubString - Substring to search for.
|
|
*
|
|
* RESULT
|
|
*
|
|
*
|
|
******************************************************************************/
|
|
|
|
UString UString::SubString(const Char* s)
|
|
{
|
|
assert(false);
|
|
assert(s != NULL);
|
|
return UString("");
|
|
}
|
|
|
|
|
|
UString UString::SubString(const WChar* ws)
|
|
{
|
|
assert(false);
|
|
assert(ws != NULL);
|
|
return UString("");
|
|
}
|
|
|
|
|
|
UString UString::SubString(const UString& s)
|
|
{
|
|
assert(false);
|
|
return SubString(s.mData);
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* UString::Left
|
|
*
|
|
* DESCRIPTION
|
|
* Extract left part of the string.
|
|
*
|
|
* INPUTS
|
|
* Count - Number of characters to extract
|
|
*
|
|
* RESULT
|
|
* Left - Extracted left part of the string
|
|
*
|
|
******************************************************************************/
|
|
|
|
UString UString::Left(UInt count)
|
|
{
|
|
assert(false);
|
|
|
|
// If the count is zero then return an empty string.
|
|
if ((Length() == 0) || (count == 0))
|
|
{
|
|
return UString("");
|
|
}
|
|
|
|
return UString("");
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* UString::Middle
|
|
*
|
|
* DESCRIPTION
|
|
* Extract middle part of the string.
|
|
*
|
|
* INPUTS
|
|
* First - Position of first character
|
|
* Count - Number of characters to extract
|
|
*
|
|
* RESULT
|
|
* Middle - Extracted middle part of the string
|
|
*
|
|
******************************************************************************/
|
|
|
|
UString UString::Middle(UInt first, UInt count)
|
|
{
|
|
assert(false);
|
|
|
|
// If the first character position is greater than the length of the string
|
|
// or the count is zero then return an empty string.
|
|
if ((Length() < first) || (count == 0))
|
|
{
|
|
return UString("");
|
|
}
|
|
|
|
return UString("");
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* UString::Right
|
|
*
|
|
* DESCRIPTION
|
|
* Extract right part of the string.
|
|
*
|
|
* INPUTS
|
|
* Count - Number of characters to extract
|
|
*
|
|
* RESULT
|
|
* Right - Extracted right part of the string
|
|
*
|
|
******************************************************************************/
|
|
|
|
UString UString::Right(UInt count)
|
|
{
|
|
UInt length = Length();
|
|
|
|
// If the count is zero then return an empty string.
|
|
if ((length == 0) || (count == 0))
|
|
{
|
|
return UString("");
|
|
}
|
|
|
|
const WChar* ptr = Get();
|
|
UInt pos = (length - count);
|
|
|
|
return UString(ptr[pos]);
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* UString::ToUpper
|
|
*
|
|
* DESCRIPTION
|
|
* Convert string to uppercase
|
|
*
|
|
* INPUTS
|
|
* NONE
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
void UString::ToUpper(void)
|
|
{
|
|
if (mData != NULL)
|
|
{
|
|
wcsupr(mData);
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* UString::ToLower
|
|
*
|
|
* DESCRIPTION
|
|
* Convert string to lowercase
|
|
*
|
|
* INPUTS
|
|
* NONE
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
void UString::ToLower(void)
|
|
{
|
|
if (mData != NULL)
|
|
{
|
|
wcslwr(mData);
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* UString::Reverse
|
|
*
|
|
* DESCRIPTION
|
|
* Reverse characters of string
|
|
*
|
|
* INPUTS
|
|
* NONE
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
void UString::Reverse(void)
|
|
{
|
|
if (mData != NULL)
|
|
{
|
|
wcsrev(mData);
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* UString::Trim
|
|
*
|
|
* DESCRIPTION
|
|
* Remove leading and trailing characters from string.
|
|
*
|
|
* INPUTS
|
|
* TrimChars - Characters to trim
|
|
*
|
|
* RESULT
|
|
* Removed - True if any characters removed
|
|
*
|
|
******************************************************************************/
|
|
|
|
bool UString::Trim(const Char* trimChars)
|
|
{
|
|
bool leftRemoved = TrimLeft(trimChars);
|
|
bool rightRemoved = TrimRight(trimChars);
|
|
return (leftRemoved || rightRemoved);
|
|
}
|
|
|
|
|
|
bool UString::Trim(const WChar* trimChars)
|
|
{
|
|
bool leftRemoved = TrimLeft(trimChars);
|
|
bool rightRemoved = TrimRight(trimChars);
|
|
return (leftRemoved || rightRemoved);
|
|
}
|
|
|
|
|
|
bool UString::Trim(const UString& trimChars)
|
|
{
|
|
bool leftRemoved = TrimLeft(trimChars);
|
|
bool rightRemoved = TrimRight(trimChars);
|
|
return (leftRemoved || rightRemoved);
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* UString::TrimLeft
|
|
*
|
|
* DESCRIPTION
|
|
* Remove characters from left side of string
|
|
*
|
|
* INPUTS
|
|
* TrimChars - Characters to trim
|
|
*
|
|
* RESULT
|
|
* Removed - True if any characters removed
|
|
*
|
|
******************************************************************************/
|
|
|
|
bool UString::TrimLeft(const Char* trimChars)
|
|
{
|
|
if ((trimChars == NULL) || (strlen(trimChars) == 0))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return StripLeft<Char>(mData, trimChars);
|
|
}
|
|
|
|
|
|
bool UString::TrimLeft(const WChar* trimChars)
|
|
{
|
|
if ((trimChars == NULL) || (wcslen(trimChars) == 0))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return StripLeft<WChar>(mData, trimChars);
|
|
}
|
|
|
|
|
|
bool UString::TrimLeft(const UString& trimChars)
|
|
{
|
|
return TrimLeft(trimChars.Get());
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* UString::TrimRight
|
|
*
|
|
* DESCRIPTION
|
|
* Remove characters from right side of string
|
|
*
|
|
* INPUTS
|
|
* TrimChars - Characters to trim
|
|
*
|
|
* RESULT
|
|
* Removed - True if any characters removed
|
|
*
|
|
******************************************************************************/
|
|
|
|
bool UString::TrimRight(const Char* trimChars)
|
|
{
|
|
if ((trimChars == NULL) || (strlen(trimChars) == 0))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return StripRight<Char>(mData, trimChars);
|
|
}
|
|
|
|
|
|
bool UString::TrimRight(const WChar* trimChars)
|
|
{
|
|
if ((trimChars == NULL) || (wcslen(trimChars) == 0))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return StripRight<WChar>(mData, trimChars);
|
|
}
|
|
|
|
|
|
bool UString::TrimRight(const UString& trimChars)
|
|
{
|
|
return TrimRight(trimChars.mData);
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* UString::ConvertToANSI
|
|
*
|
|
* DESCRIPTION
|
|
* Convert the string to ANSI string
|
|
*
|
|
* INPUTS
|
|
* Buffer - Buffer to convert into
|
|
* Length - Maximum length of buffer
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
void UString::ConvertToANSI(Char* buffer, UInt bufferLength) const
|
|
{
|
|
UStringToANSI(*this, buffer, bufferLength);
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* UString::Size
|
|
*
|
|
* DESCRIPTION
|
|
* Retrieve the size of the string in bytes
|
|
*
|
|
* INPUTS
|
|
* NONE
|
|
*
|
|
* RESULT
|
|
* Size - Size of string in bytes
|
|
*
|
|
******************************************************************************/
|
|
|
|
UInt UString::Size(void) const
|
|
{
|
|
if (mData == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return ((Length() + 1) * sizeof(WChar));
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* UString::Capacity
|
|
*
|
|
* DESCRIPTION
|
|
* Retrieve the capacity (maximum number of characters) of the string.
|
|
*
|
|
* INPUTS
|
|
* NONE
|
|
*
|
|
* RESULT
|
|
* Capacity - Maximum number of characters that string can hold.
|
|
*
|
|
******************************************************************************/
|
|
|
|
UInt UString::Capacity(void) const
|
|
{
|
|
return mCapacity;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* UString::Resize
|
|
*
|
|
* DESCRIPTION
|
|
* Resize the string capacity.
|
|
*
|
|
* INPUTS
|
|
* NewSize - Size to resize string to.
|
|
*
|
|
* RESULT
|
|
* Success - True if successful; otherwise false
|
|
*
|
|
******************************************************************************/
|
|
|
|
bool UString::Resize(UInt size)
|
|
{
|
|
// Allocate new storage
|
|
assert(size > 0);
|
|
WChar* data = new WChar[size + 1];
|
|
assert(data != NULL);
|
|
|
|
if (data == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// Copy existing string into new storage buffer
|
|
if (mData != NULL)
|
|
{
|
|
UInt minSize = __min(Capacity(), size);
|
|
wcsncpy(data, mData, minSize);
|
|
data[minSize] = 0;
|
|
delete mData;
|
|
}
|
|
|
|
// Set new storage
|
|
mData = data;
|
|
mCapacity = size;
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* UString::AllocString
|
|
*
|
|
* DESCRIPTION
|
|
* Allocate string storage
|
|
*
|
|
* INPUTS
|
|
* Size - Number of characters
|
|
*
|
|
* RESULT
|
|
* Success - True if allocate successful; otherwise false
|
|
*
|
|
******************************************************************************/
|
|
|
|
bool UString::AllocString(UInt size)
|
|
{
|
|
WChar* data = new WChar[size + 1];
|
|
assert(data != NULL);
|
|
|
|
if (data == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
data[0] = 0;
|
|
|
|
if (mData != NULL)
|
|
{
|
|
delete mData;
|
|
}
|
|
|
|
mData = data;
|
|
mCapacity = size;
|
|
|
|
return true;
|
|
}
|