// ------------------------------- //
// -------- start of File -------- //
// ------------------------------- //
// ----------------------------------------------------------- //
// C++ Source Code File Name: ustring.cpp
// Compiler Used: MSVC, BCC32, GCC, HPUX aCC, SOLARIS CC
// Produced By: DataReel Software Development Team
// File Creation Date: 11/29/1996
// Date Last Modified: 11/05/2014
// Copyright (c) 2001-2009 DataReel Software Development
// ----------------------------------------------------------- //
// ------------- Program Description and Details ------------- //
// ----------------------------------------------------------- //
/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA
The user defined string classes are used to construct and manipulate
null-terminated, resizable ASCII and Unicode character strings. The
UStringB class is an abstract base class used to define a general-purpose
set of string functions that operate on both ASCII and Unicode strings.
The UString class is derived from the UStringB class and sets the string
type to ASCII. The UStringw class is derived from the UStringB class and
sets the string type to Unicode. The UStringB class is responsible for
calling the correct operation based on the string type set in the derived
class. Using this hierarchy both ASCII and Unicode strings are available
to the application at the same time and can be used transparently in mixed
environments. NOTE: The integer type used for the wchar_t type will vary
depending on the compiler used. The UStringB class automatically accounts
for all compiler dependent byte alignments. However by nature, Unicode
strings are not portable between Intel and RISC processors due to the
difference in byte ordering. In order to account for Unicode strings
stored in portable database files and shared across network connections
the gxwchar_t type is supplied to account for different byte ordering.
Changes:
==============================================================
07/10/2001: Added __AIX__ conditional directive for the IBM xlC
C and C++ Compilers. This compiler does not define the
strcasecmp() function.
09/12/2001: Modified the UStringB::SetString() function to
ensure that the "s" pointer is initialized before calling
the gxstrlen() function.
09/12/2001: Modified the UStringB::InsertAt() function to check
the byte size to ensure that caller specified a number of bytes
greater then zero.
11/15/2001: Modified the overloaded + const chat *s operator
to append the null terminated "s" string to the end of the
UStringB object.
02/27/2002: The logical length in the UString(unsigned nchars)
constructor is now set to zero when this constructor is called.
06/05/2002: Added Unicode versions of all UStringB functions
included with release 4.1.
06/05/2002: Moved all UString functions to the UStringB class
and added the UStringw and gxwchar_t class used to operate on
Unicode strings.
09/04/2002: All versions of the CaseICmp() functions are no
longer using compiler dependent string case insensitive
functions.
09/10/2002: Added global null pointers used internally to
return null character and null strings.
09/19/2002: Modified the UString::UString(unsigned nchars) and
UStringw::UStringw(unsigned nchars) constructors not to set the
logical length of the string object. The logical length will be
set when a string is assigned or copied into the string object.
10/13/2002: Added additional copy constructors, assignment operators,
and overloaded += operators to support the wxString class.
06/04/2003: Modified all versions of the UStringB::SHN() function to
pad the output stream if the output width is greater then 1.
==============================================================
*/
// ----------------------------------------------------------- //
#include "gxdlcode.h"
#include "ustring.h"
#include "strutil.h"
#ifdef __BCC32__
#pragma warn -8080
#endif
// Initialize the global null character and string pointers
char UStringNULLPtr::UStringNUllChar = '\0';
char UStringNULLPtr::UStringNUllStr[1] = { '\0' };
wchar_t UStringNULLPtr::UStringwNUllChar = '\0';
wchar_t UStringNULLPtr::UStringwNUllStr[1] = { '\0' };
UStringB::~UStringB()
{
// PC-lint 09/08/2005: Function may throw exception in destructor
delete_sptr();
}
int UStringB::set_string(const void *s, unsigned bytes,
gxStringType st, unsigned cs)
// Set the string value for this object. This function will try to
// re-use the current memory segment allocated for this string before
// re-allocating memory for the string. Returns true if successful or
// false if an error occurs. NOTE: The UStringB class guarantees that
// each object is unique by storing a unique copy of the string with
// each object. This ensures that UStringB objects can be safely copy
// constructed, assigned, resized, and deleted by multiple threads.
// Multiple threads accessing shared memory segments must be handled
// by the application. NOTE: The number of bytes must be calculated
// according to the strings bit alignment, which will vary based on the
// string type set in the derived class. ASCII string types will have a
// byte size of 1 multiplied by the number non-null characters in the
// string. Unicode string types will have a byte size of the native
// Unicode character size multiplied by the number non-null characters
// in the string. The number of bytes passed to this function should not
// include a null terminator, which will be accounted for and allocated
// by this function.
{
// Calculate the length of this string if no bytes size is specified
if(bytes == 0) {
if(s) {
// Ensure that the "s" pointer is initialized before
// calling the string length function.
if(st == gxASCII_STRING) {
bytes = (cs * gxstrlen((char *)s));
}
else {
bytes = (cs * gxstrlen((wchar_t *)s));
}
}
else {
return 0; // A null pointer was passed to this function
}
}
// Calculate the number of characters and adjust the byte size
unsigned nchars = bytes/cs;
if(bytes % cs) s_length++;
bytes = nchars * cs;
if(sptr) { // Memory was previously allocated for this object
if(d_length >= bytes) { // Try to reuse this space
s_length = nchars;
memmove(sptr, s, bytes);
null_terminate(st); // Null terminate the string
return 1;
}
else { // Must resize the string
delete_sptr(); // Delete the previous copy and re-allocate memory
}
}
// Allocate memory for the string plus a null-terminator
if(bytes < cs) bytes = 0; // Assume this is a null string
void *nsptr = allocate(bytes, st, cs, nchars);
if(!nsptr) return 0; // Allocation failed
memmove(nsptr, s, bytes); // Create a unique copy of this string
sptr = nsptr;
d_length = bytes;
s_length = nchars;
null_terminate(st); // Null terminate the string
return 1;
}
unsigned UStringB::ReplaceAt(unsigned c_position, const char *s,
unsigned nchars)
{
if(!s) return 0; // Check for null pointers
if(!is_unicode()) { // String type set by the derived class
return replace_at(c_position, s, nchars, gxASCII_STRING, 1);
}
else { // This is a Unicode string so convert the ASCII string and replace
wchar_t *nsptr = ASCII2Unicode(s, nchars);
if(!nsptr) return 0;
unsigned cs = sizeof(wchar_t);
unsigned bytes = replace_at((c_position*cs), nsptr, (nchars*cs),
gxUNICODE_STRING, cs);
delete[] nsptr;
return bytes;
}
}
unsigned UStringB::ReplaceAt(unsigned c_position, const wchar_t *s,
unsigned nchars)
{
if(!s) return 0; // Check for null pointers
if(!is_unicode()) {
char *nsptr = Unicode2ASCII(s, nchars);
if(!nsptr) return 0;
unsigned bytes = replace_at(c_position, nsptr, nchars, gxASCII_STRING, 1);
delete[] nsptr;
return bytes;
}
else {
unsigned cs = sizeof(wchar_t);
return replace_at((c_position*cs), s, (nchars*cs), gxUNICODE_STRING, cs);
}
}
unsigned UStringB::ReplaceAt(unsigned c_position, const UStringB &s,
unsigned nchars)
{
if(!s.sptr) return 0; // Check for null pointers
if((nchars == 0) || (nchars > s.s_length)) nchars = s.s_length;
if(!is_unicode()) {
if(!s.is_unicode()) {
return replace_at(c_position, s.sptr, nchars, gxASCII_STRING, 1);
}
else {
char *nsptr = Unicode2ASCII((wchar_t *)s.sptr, nchars);
if(!nsptr) return 0;
unsigned rv = replace_at(c_position, nsptr, nchars, gxASCII_STRING, 1);
delete[] nsptr;
return rv;
}
}
else {
unsigned cs = sizeof(wchar_t);
if(!s.is_unicode()) {
wchar_t *nsptr = ASCII2Unicode((char *)s.sptr, nchars);
if(!nsptr) return 0;
unsigned rv = replace_at((c_position*cs), nsptr, (nchars*cs),
gxUNICODE_STRING, cs);
delete[] nsptr;
return rv;
}
else {
return replace_at((c_position*cs), s.sptr, (nchars*cs),
gxUNICODE_STRING, cs);
}
}
}
unsigned UStringB::InsertAt(unsigned c_position, const char *s,
unsigned nchars)
{
if(!s) return 0; // Check for null pointers
if(!is_unicode()) { // String type set by the derived class
return insert_at(c_position, s, nchars, gxASCII_STRING, 1);
}
else { // This is a Unicode string so convert the ASCII string and replace
wchar_t *nsptr = ASCII2Unicode(s, nchars);
if(!nsptr) return 0;
unsigned cs = sizeof(wchar_t);
unsigned bytes = insert_at((c_position*cs), nsptr, (nchars*cs),
gxUNICODE_STRING, cs);
delete[] nsptr;
return bytes;
}
}
unsigned UStringB::InsertAt(unsigned c_position, const wchar_t *s,
unsigned nchars)
{
if(!s) return 0; // Check for null pointers
if(!is_unicode()) {
char *nsptr = Unicode2ASCII(s, nchars);
if(!nsptr) return 0;
unsigned bytes = insert_at(c_position, nsptr, nchars, gxASCII_STRING, 1);
delete[] nsptr;
return bytes;
}
else {
unsigned cs = sizeof(wchar_t);
return insert_at((c_position*cs), s, (nchars*cs), gxUNICODE_STRING, cs);
}
}
unsigned UStringB::InsertAt(unsigned c_position, const UStringB &s,
unsigned nchars)
{
if(!s.sptr) return 0; // Check for null pointers and strings
if((nchars == 0) || (nchars > s.s_length)) nchars = s.s_length;
if(!is_unicode()) {
if(!s.is_unicode()) {
return insert_at(c_position, s.sptr, nchars, gxASCII_STRING, 1);
}
else {
char *nsptr = Unicode2ASCII((wchar_t *)s.sptr, nchars);
if(!nsptr) return 0;
unsigned rv = insert_at(c_position, nsptr, nchars, gxASCII_STRING, 1);
delete[] nsptr;
return rv;
}
}
else {
unsigned cs = sizeof(wchar_t);
if(!s.is_unicode()) {
wchar_t *nsptr = ASCII2Unicode((char *)s.sptr, nchars);
if(!nsptr) return 0;
unsigned rv = insert_at((c_position*cs), nsptr, (nchars*cs),
gxUNICODE_STRING, cs);
delete[] nsptr;
return rv;
}
else {
return insert_at((c_position*cs), s.sptr, (nchars*cs),
gxUNICODE_STRING, cs);
}
}
}
int UStringB::SetString(const UStringB &s, unsigned nchars)
{
if(!s.sptr) return 0; // Check for null pointers
if((nchars == 0) || (nchars > s.s_length)) nchars = s.s_length;
if(!is_unicode()) {
if(!s.is_unicode()) {
return set_string(s.sptr, nchars, gxASCII_STRING, 1);
}
else {
char *nsptr = Unicode2ASCII((wchar_t *)s.sptr, nchars);
if(!nsptr) return 0;
int rv = set_string(nsptr, nchars, gxASCII_STRING, 1);
delete[] nsptr;
return rv;
}
}
else {
unsigned cs = sizeof(wchar_t);
if(!s.is_unicode()) {
wchar_t *nsptr = ASCII2Unicode((char *)s.sptr, nchars);
if(!nsptr) return 0;
int rv = set_string(nsptr, (nchars*cs), gxUNICODE_STRING, cs);
delete[] nsptr;
return rv;
}
else {
return set_string(s.sptr, (nchars*cs), gxUNICODE_STRING, cs);
}
}
}
int UStringB::SetString(const char *s, unsigned nchars)
{
if(!s) return 0; // Check for null pointers
if(nchars == 0) nchars = gxstrlen(s);
if(!is_unicode()) {
return set_string(s, nchars, gxASCII_STRING, 1);
}
else { // Convert this ASCII string literal to a Unicode string
wchar_t *nsptr = ASCII2Unicode(s, nchars);
if(!nsptr) return 0;
unsigned cs = sizeof(wchar_t);
int rv = set_string(nsptr, (nchars*cs), gxUNICODE_STRING, cs);
delete[] nsptr;
return rv;
}
}
int UStringB::SetString(const wchar_t *s, unsigned nchars)
{
if(!s) return 0; // Check for null pointers
if(nchars == 0) nchars = gxstrlen(s);
if(!is_unicode()) { // Convert this Unicode string literal to ASCII
char *nsptr = Unicode2ASCII(s, nchars);
if(!nsptr) return 0;
int rv = set_string(nsptr, nchars, gxASCII_STRING, 1);
delete[] nsptr;
return rv;
}
else {
unsigned cs = sizeof(wchar_t);
return set_string(s, (nchars*cs), gxUNICODE_STRING, sizeof(wchar_t));
}
}
unsigned UStringB::Cat(const char *s, unsigned nchars)
{
if(!s) return 0; // Check for null pointers
if(nchars == 0) nchars = gxstrlen(s);
if(!is_unicode()) {
return insert_at(s_length, s, nchars, gxASCII_STRING, 1);
}
else {
wchar_t *nsptr = ASCII2Unicode(s, nchars);
if(!nsptr) return 0;
unsigned cs = sizeof(wchar_t);
unsigned bytes = insert_at((s_length*cs), nsptr, (nchars*cs),
gxUNICODE_STRING, cs);
delete[] nsptr;
return bytes;
}
}
unsigned UStringB::Cat(const wchar_t *s, unsigned nchars)
{
if(!s) return 0; // Check for null pointers
if(nchars == 0) nchars = gxstrlen(s);
if(!is_unicode()) {
char *nsptr = Unicode2ASCII(s, nchars);
if(!nsptr) return 0;
unsigned bytes = insert_at(s_length, nsptr, nchars, gxASCII_STRING, 1);
delete[] nsptr;
return bytes;
}
else {
unsigned cs = sizeof(wchar_t);
return insert_at((s_length*cs), s, (nchars*cs), gxUNICODE_STRING, cs);
}
}
unsigned UStringB::Cat(const UStringB &s, unsigned nchars)
{
if(!s.sptr) return 0; // Check for null pointers
if((nchars == 0) || (nchars > s.s_length)) nchars = s.s_length;
if(!is_unicode()) {
if(!s.is_unicode()) {
return insert_at(s_length, s.sptr, nchars, gxASCII_STRING, 1);
}
else {
char *nsptr = Unicode2ASCII((wchar_t *)s.sptr, nchars);
if(!nsptr) return 0;
unsigned rv = insert_at(s_length, nsptr, nchars, gxASCII_STRING, 1);
delete[] nsptr;
return rv;
}
}
else {
unsigned cs = sizeof(wchar_t);
if(!s.is_unicode()) {
wchar_t *nsptr = ASCII2Unicode((char *)s.sptr, nchars);
if(!nsptr) return 0;
unsigned rv = insert_at((s_length*cs), nsptr, (nchars*cs),
gxUNICODE_STRING, cs);
delete[] nsptr;
return rv;
}
else {
return insert_at((s_length*cs), s.sptr, (nchars*cs),
gxUNICODE_STRING, cs);
}
}
}
void UStringB::Clear(int clear_all)
// Clear this string without freeing its memory segment.
{
Reset(); // Reset all the format specifiers.
s_length = 0; // Reset the string length
if(!sptr) return;
if(clear_all) { // Zero out the memory for the entire string
memset(sptr, 0, d_length);
}
else { // Null the first character and return
if(!is_unicode()) { // Null the string
((char *)sptr)[s_length] = 0;
}
else {
((wchar_t *)sptr)[s_length] = (wchar_t)0;
}
}
}
void UStringB::delete_sptr()
// Internal function used to free heap space memory
// previously allocated for this string.
{
// Cast sptr to unsigned char * type so that the delete
// operator will reference a type other than void *.
if(sptr) delete (unsigned char *)sptr;
// Null the pointer and reset the length variables
sptr = 0;
s_length = d_length = 0;
}
void *UStringB::allocate(unsigned &bytes, gxStringType st, unsigned cs,
unsigned &nchars)
// Internal function used to allocate heap space memory for a
// specified number of bytes. Returns null if memory cannot
// be allocated for the buffer. NOTE: The calling function must
// adjust the string's dimensioned length if the byte size is
// changed during allocation. The number of characters used
// by this string will be passed back in the "nchars" variable.
// This version of the allocate function will account for a
// single null terminator in addition to the number of bytes
// specified.
{
// Not allocating memory for any buffer characters
if(bytes < cs) bytes = 0; // Assume this is a null string
// Calculate the buffer size and adjust the byte size
nchars = bytes/cs;
if(bytes % cs) nchars++; // Allocate extra character in place of remainder
bytes = nchars * cs;
if(st == gxASCII_STRING) {
// Allocate memory for the string plus a null terminator
char *aptr = new char[nchars+1];
if(!aptr) return (void *)0; // Allocation failed
memset(aptr, 0, (bytes+cs)); // Zero out the memory
return (void *)aptr;
}
else { // This is a Unicode string type
// Allocate memory for the string plus a null terminator
wchar_t *uptr = new wchar_t[nchars+1];
if(!uptr) return (void *)0; // Allocation failed
memset(uptr, 0, (bytes+cs)); // Zero out the memory
return (void *)uptr;
}
}
void UStringB::null_terminate(gxStringType st)
// Internal function used to null terminate a ASCII or Unicode string.
{
// PC-lint: 09/14/2005 Possible use of null pointer
if(!sptr) return;
if(st == gxASCII_STRING) {
((char *)sptr)[s_length] = 0;
}
else {
((wchar_t *)sptr)[s_length] = 0;
}
}
unsigned UStringB::insert_at(unsigned position, const void *s, unsigned bytes,
gxStringType st, unsigned cs)
// Insert a specified number of bytes at the specified byte position, keeping
// the current string intact. Returns the number of bytes inserted or
// zero if an error occurs.
{
// Check the byte size to ensure that caller
// specified a number of bytes greater then zero
// or at least one character size.
if(bytes < cs) return 0;
// PC-lint: 09/14/2005 Possible use of null pointer
if(!s) return 0;
// Record the current string length in bytes
unsigned old_length = s_length * cs;
// Ensure that there are enough bytes to hold the insertion
if(!resize_buffer((bytes+(s_length*cs)), 1, st, cs)) return 0;
// PC-lint: 09/14/2005 Possible use of null pointer
if(!sptr) return 0;
if(position < old_length) { // Move the data in the middle of the string
// Cast sptr to unsigned char * type so that the pointer will be
// incremented one byte at a time.
memmove((unsigned char *)sptr+position+bytes,
(unsigned char *)sptr+position, old_length-position);
}
if(position > (s_length * cs)) position = s_length; // Stay in bounds
// Cast sptr to unsigned char * type so that the pointer will be
// incremented one byte at a time.
memmove((unsigned char *)sptr+position, s, bytes);
null_terminate(st); // Ensure null termination
return bytes;
}
unsigned UStringB::replace_at(unsigned position, const void *s, unsigned bytes,
gxStringType st, unsigned cs)
// Replace a specified number of bytes at the specified byte position. Returns
// the number of bytes replaced of zero if an error occurs.
{
// Check the byte size to ensure that caller
// specified a number of bytes greater then zero
// or at least one character size.
if(bytes < cs) return 0;
// Calculate the number characters being replaced
unsigned nchars = bytes/cs;
if(bytes % cs) nchars++;
// PC-lint 09/15/2005: nchars not accessed, so following line was added for
// unicode characters.
bytes = nchars * cs; // Adjust the byte size
if(position > (s_length*cs)) position = (s_length*cs); // Stay in bounds
unsigned end = ((s_length*cs)-position);
if(bytes > end) { // There are not enough bytes to hold the replacement
unsigned needed = (bytes-end)/cs;
if((bytes-end) % cs) needed++;
if(!resize(s_length + needed)) return 0;
}
// PC-lint: 09/14/2005 Possible use of null pointer
if(!sptr) return 0;
// Cast sptr to unsigned char * type so that the pointer will be
// incremented one byte at a time.
memmove((unsigned char *)sptr+position, s , bytes);
null_terminate(st); // Ensure null termination
return bytes;
}
int UStringB::resize(unsigned nchars, int keep)
// Resize the logical length of the buffer. If the
// "keep" variable is true the old data will be
// copied into the new space. By default the old
// data will not be deleted. Returns true if
// successful or false if an error occurs.
{
if(!is_unicode()) {
return resize_buffer(nchars, keep, gxASCII_STRING, 1);
}
else {
return resize_buffer((nchars*sizeof(wchar_t)),
keep, gxUNICODE_STRING, sizeof(wchar_t));
}
}
int UStringB::resize_buffer(unsigned bytes, int keep,
gxStringType st, unsigned cs)
// Resize the dimensioned length of the buffer. If the
// "keep" variable is true the old data will be
// copied into the new space. Returns true if
// successful or false if an error occurs.
{
if(bytes < cs) bytes = cs;
// Calculate the number of characters needed
unsigned nchars = bytes/cs;
if(bytes % cs) s_length++;
bytes = nchars * cs; // Adjust the byte size
// No additional memory has to be re-allocated
if(d_length >= bytes) {
s_length = nchars;
if(!keep) { // Remove the old data
// PC-lint: 09/14/2005 Possible use of null pointer
if(!sptr) return 0;
memset(sptr, 0, (d_length+cs));
}
else { // Keep the old data and resize the string
null_terminate(st);
}
return 1;
}
void *nsptr = allocate(bytes, st, cs, nchars);
if(!nsptr) return 0; // Allocation failed
if((keep == 1) && (sptr != 0)) { // Copy old data into the new memory segment
if(nchars < s_length) s_length = nchars;
memmove(nsptr, sptr, (s_length*cs));
null_terminate(st); // Null terminate the string
}
delete_sptr(); // Free the previously allocated memory
sptr = nsptr; // Point to new string
s_length = nchars; // Record the new character length
d_length = bytes; // Record new allocated length
return 1;
}
unsigned UStringB::DeleteAt(unsigned c_position, unsigned nchars)
// Deletes a specified number of characters starting at the
// specified character position. Returns the total number
// of characters deleted or zero if an error occurs.
{
if(!sptr) return 0; // Check for null pointers
if(!is_unicode()) {
return delete_at(c_position, nchars, gxASCII_STRING, 1);
}
else {
unsigned cs = sizeof(wchar_t);
return delete_at((c_position*cs), (nchars*cs), gxUNICODE_STRING, cs);
}
}
unsigned UStringB::delete_at(unsigned position, unsigned bytes,
gxStringType st, unsigned cs)
// Deletes a specified number of characters starting at the
// specified byte position in the string. Returns the total
// number of bytes deleted or zero if an error occurs.
{
if(bytes < cs) return 0; // Not deleting any characters from the string
// Calculate the character position and the number of characters
unsigned c_position = 0;
unsigned nchars = 0;
if(st == gxASCII_STRING) {
c_position = position;
nchars = bytes;
}
else {
if(position >= cs) { // Delete starting at the second char position
c_position = position/cs;
if(position % cs) c_position++;
}
nchars = bytes/cs;
if(bytes % cs) bytes++;
}
unsigned end;
if(c_position < s_length) {
end = c_position + nchars;
if(end > s_length) end = s_length;
nchars = end - c_position;
// Cast sptr to unsigned char * type so that the pointer will be
// incremented one byte at a time.
// PC-lint: 09/14/2005 Possible use of null pointer
if(!sptr) return 0;
memmove(((unsigned char *)sptr+(c_position*cs)),
((unsigned char *)sptr+(end*cs)), ((s_length*cs)-(end*cs)));
s_length -= nchars;
null_terminate(st);
}
else {
nchars = 0;
}
// Return the number of bytes deleted
return nchars * cs;
}
int UStringB::Find(const char *s, unsigned c_offset) const
// Returns -1 if the pattern is not found.
{
if(!s) return -1; // Check for null pointers
unsigned nchars = gxstrlen(s);
return Find(s, nchars, c_offset);
}
int UStringB::Find(const char *s, unsigned nchars, unsigned c_offset) const
{
if((!s) || !(sptr)) return -1; // Check for null pointers
if(nchars == 0) nchars = gxstrlen(s);
if(!is_unicode()) {
return gxfind_pattern(sptr, s_length, s, nchars,
c_offset, gxASCII_STRING, 1);
}
else {
unsigned cs = sizeof(wchar_t);
wchar_t *nsptr = ASCII2Unicode(s, nchars);
if(!nsptr) return 0;
int rv = gxfind_pattern(sptr, (s_length*cs), nsptr, (nchars*cs),
(c_offset*cs), gxUNICODE_STRING, cs);
delete[] nsptr;
return rv;
}
}
int UStringB::Find(const wchar_t *s, unsigned c_offset) const
{
if(!s) return -1; // Check for null pointers
unsigned nchars = gxstrlen(s);
return Find(s, nchars, c_offset);
}
int UStringB::Find(const wchar_t *s, unsigned nchars, unsigned c_offset) const
{
if((!s) || !(sptr)) return -1; // Check for null pointers
if(nchars == 0) nchars = gxstrlen(s);
if(!is_unicode()) {
char *nsptr = Unicode2ASCII(s, nchars);
if(!nsptr) return 0;
int rv = gxfind_pattern(sptr, s_length, nsptr, nchars,
c_offset, gxASCII_STRING, 1);
delete[] nsptr;
return rv;
}
else {
unsigned cs = sizeof(wchar_t);
return gxfind_pattern(sptr, (s_length*cs), s, (nchars*cs),
(c_offset*cs), gxUNICODE_STRING, cs);
}
}
int UStringB::Find(const UStringB &s, unsigned c_offset) const
{
return Find(s, s.s_length, c_offset);
}
int UStringB::Find(const UStringB &s, unsigned nchars, unsigned c_offset) const
{
if((!s.sptr) || !(sptr)) return -1; // Check for null pointers
if((nchars == 0) || (nchars > s.s_length)) nchars = s.s_length;
if(!is_unicode()) {
if(!s.is_unicode()) {
return gxfind_pattern(sptr, s_length, s.sptr, nchars,
c_offset, gxASCII_STRING, 1);
}
else {
char *nsptr = Unicode2ASCII((wchar_t *)s.sptr, nchars);
if(!nsptr) return 0;
int rv = gxfind_pattern(sptr, s_length, nsptr, nchars,
c_offset, gxASCII_STRING, 1);
delete[] nsptr;
return rv;
}
}
else {
unsigned cs = sizeof(wchar_t);
if(!s.is_unicode()) {
wchar_t *nsptr = ASCII2Unicode((char *)s.sptr, nchars);
if(!nsptr) return 0;
int rv = gxfind_pattern(sptr, (s_length*cs), nsptr, (nchars*cs),
(c_offset*cs), gxUNICODE_STRING, cs);
delete[] nsptr;
return rv;
}
else {
return gxfind_pattern(sptr, (s_length*cs), s.sptr, (nchars*cs),
(c_offset*cs), gxUNICODE_STRING, cs);
}
}
}
int UStringB::IFind(const char *s, unsigned c_offset) const
{
if(!s) return -1; // Check for null pointers
unsigned nchars = gxstrlen(s);
return IFind(s, nchars, c_offset);
}
int UStringB::IFind(const char *s, unsigned nchars, unsigned c_offset) const
{
if((!s) || !(sptr)) return -1; // Check for null pointers
if(nchars == 0) nchars = gxstrlen(s);
if(!is_unicode()) {
return gxifind_pattern(sptr, s_length, s, nchars,
c_offset, gxASCII_STRING, 1);
}
else {
unsigned cs = sizeof(wchar_t);
wchar_t *nsptr = ASCII2Unicode(s, nchars);
if(!nsptr) return 0;
int rv = gxifind_pattern(sptr, (s_length*cs), nsptr, (nchars*cs),
(c_offset*cs), gxUNICODE_STRING, cs);
delete[] nsptr;
return rv;
}
}
int UStringB::IFind(const wchar_t *s, unsigned c_offset) const
{
if(!s) return -1; // Check for null pointers
unsigned nchars = gxstrlen(s);
return IFind(s, nchars, c_offset);
}
int UStringB::IFind(const wchar_t *s, unsigned nchars, unsigned c_offset) const
{
if((!s) || !(sptr)) return -1; // Check for null pointers
if(nchars == 0) nchars = gxstrlen(s);
if(!is_unicode()) {
char *nsptr = Unicode2ASCII(s, nchars);
if(!nsptr) return 0;
int rv = gxifind_pattern(sptr, s_length, nsptr, nchars,
c_offset, gxASCII_STRING, 1);
delete[] nsptr;
return rv;
}
else {
unsigned cs = sizeof(wchar_t);
return gxifind_pattern(sptr, (s_length*cs), s, (nchars*cs),
(c_offset*cs), gxUNICODE_STRING, cs);
}
}
int UStringB::IFind(const UStringB &s, unsigned c_offset) const
{
return IFind(s, s.s_length, c_offset);
}
int UStringB::IFind(const UStringB &s, unsigned nchars,
unsigned c_offset) const
{
if((!s.sptr) || !(sptr)) return -1; // Check for null pointers
if((nchars == 0) || (nchars > s.s_length)) nchars = s.s_length;
if(!is_unicode()) {
if(!s.is_unicode()) {
return gxifind_pattern(sptr, s_length, s.sptr, nchars,
c_offset, gxASCII_STRING, 1);
}
else {
char *nsptr = Unicode2ASCII((wchar_t *)s.sptr, nchars);
if(!nsptr) return 0;
int rv = gxifind_pattern(sptr, s_length, nsptr, nchars,
c_offset, gxASCII_STRING, 1);
delete[] nsptr;
return rv;
}
}
else {
unsigned cs = sizeof(wchar_t);
if(!s.is_unicode()) {
wchar_t *nsptr = ASCII2Unicode((char *)s.sptr, nchars);
if(!nsptr) return 0;
int rv = gxifind_pattern(sptr, (s_length*cs), nsptr, (nchars*cs),
(c_offset*cs), gxUNICODE_STRING, cs);
delete[] nsptr;
return rv;
}
else {
return gxifind_pattern(sptr, (s_length*cs), s.sptr, (nchars*cs),
(c_offset*cs), gxUNICODE_STRING, cs);
}
}
}
int UStringB::Atoi()
{
if((sptr == 0) || (s_length == 0)) return (int)0;
if(!is_unicode()) {
// PC-lint 09/15/2005: atoi() function is considered dangerous
#if defined (__PCLINT_CHECK__)
return 0;
#else
return atoi((char *)sptr);
#endif
}
else {
#if defined (__HAS_UNICODE__) && defined (__WINCE__)
return _wtoi((wchar_t *)sptr);
#elif defined (__HAS_UNICODE__) && defined (__MSVC__)
return _wtoi((wchar_t *)sptr);
#else
char *nsptr = Unicode2ASCII((wchar_t *)sptr, s_length);
if(!nsptr) return 0;
// PC-lint 09/15/2005: atoi() function is considered dangerous
#if defined (__PCLINT_CHECK__)
unsigned rv = 0;
#else
unsigned rv = atol(nsptr);
#endif
delete[] nsptr;
return rv;
#endif // __HAS_UNICODE__
}
}
long UStringB::Atol()
{
if((sptr == 0) || (s_length == 0)) return 0L;
if(!is_unicode()) {
// PC-lint 09/15/2005: atol() function is considered dangerous
#if defined (__PCLINT_CHECK__)
return 0;
#else
return atol((char *)sptr);
#endif
}
else {
#if defined (__HAS_UNICODE__) && defined (__WINCE__)
return _wtol((wchar_t *)sptr);
#elif defined (__HAS_UNICODE__) && defined (__MSVC__)
return _wtol((wchar_t *)sptr);
#else
char *nsptr = Unicode2ASCII((wchar_t *)sptr, s_length);
if(!nsptr) return 0;
// PC-lint 09/15/2005: atol() function is considered dangerous
#if defined (__PCLINT_CHECK__)
unsigned rv = 0;
#else
unsigned rv = atol(nsptr);
#endif
delete[] nsptr;
return rv;
#endif // __HAS_UNICODE__
}
}
unsigned long UStringB::Atou()
{
if((sptr == 0) || (s_length == 0)) return (unsigned long)0;
if(!is_unicode()) {
return StringToULWORD((const char *)sptr);
}
else {
return StringToULWORD((const wchar_t *)sptr);
}
}
double UStringB::Atof()
{
if((sptr == 0) || (s_length == 0)) return (double)0;
if(!is_unicode()) {
// PC-lint 09/15/2005: atof() function is considered dangerous
#if defined (__PCLINT_CHECK__)
return 0;
#else
return atof((char *)sptr);
#endif
}
else {
char *nsptr = Unicode2ASCII((wchar_t *)sptr, s_length);
if(!nsptr) return 0;
// PC-lint 09/15/2005: atof() function is considered dangerous
#if defined (__PCLINT_CHECK__)
double rv = 0;
#else
double rv = atof(nsptr);
#endif
delete[] nsptr;
return rv;
}
}
int UStringB::ToUpper()
// Change all characters in the string to upper case.
// Returns true if successful.
{
if((sptr == 0) || (s_length == 0)) return 0;
unsigned nchars = s_length;
if(!is_unicode()) {
char *start = (char *)sptr;
while(nchars--) {
*start = (char)toupper(*start);
start++;
}
return 1;
}
else {
wchar_t *start = (wchar_t *)sptr;
while(nchars--) {
#if defined (__HAS_UNICODE__)
*start = towupper(*start);
#else
*start = toupper(*start);
#endif // __HAS_UNICODE__
start++;
}
return 1;
}
}
int UStringB::ToLower()
// Change all characters in the string to lower case.
// Returns true if successful.
{
if((sptr == 0) || (s_length == 0)) return 0;
unsigned nchars = s_length;
if(!is_unicode()) {
char *start = (char *)sptr;
while(nchars--) {
*start = (char)tolower(*start);
start++;
}
return 1;
}
else {
wchar_t *start = (wchar_t *)sptr;
while(nchars--) {
#if defined (__HAS_UNICODE__)
*start = towlower(*start);
#else
*start = tolower(*start);
#endif // __HAS_UNICODE__
start++;
}
return 1;
}
}
int UStringB::find_last(const void *s) const
// Returns index of the last occurrence of string s.
// Returns -1 if the pattern is not found.
{
// PC-lint: 09/14/2005 Possible use of null pointer
if(!s) return -1;
if(!sptr) return -1;
if(!is_unicode()) {
unsigned i;
char *end = (char *)sptr + s_length;
char *pattern = (char *)s;
unsigned nchars = gxstrlen(pattern);
pattern += (nchars - 1);
unsigned j = 1;
for(i = s_length; i != 0; i--) {
if(*end == 0) end--; // Skip over the null terminator
if(*end == *pattern) {
if(j == nchars) return (int)i; // pattern was found
j++;
pattern--;
}
else {
pattern = (char *)s;
pattern += (nchars - 1);
j = 1;
}
end--;
}
return -1; // No match was found
}
else {
unsigned i;
wchar_t *end = (wchar_t *)sptr + s_length;
wchar_t *pattern = (wchar_t *)s;
unsigned nchars = gxstrlen(pattern);
pattern += (nchars - 1);
unsigned j = 1;
for(i = s_length; i != 0; i--) {
if(*end == 0) end--; // Skip over the null terminator
if(*end == *pattern) {
if(j == nchars) return (int)i; // pattern was found
j++;
pattern--;
}
else {
pattern = (wchar_t *)s;
pattern += (nchars - 1);
j = 1;
}
end--;
}
return -1; // No match was found
}
}
int UStringB::FindLast(const char *s) const
{
if((!s) || !(sptr)) return -1; // Check for null pointers
if(!is_unicode()) {
return find_last(s);
}
else {
unsigned nchars = gxstrlen(s);
wchar_t *nsptr = ASCII2Unicode(s, nchars);
if(!nsptr) return 0;
int rv = find_last(nsptr);
delete[] nsptr;
return rv;
}
}
int UStringB::FindLast(const wchar_t *s) const
{
if((!s) || !(sptr)) return -1; // Check for null pointers
if(!is_unicode()) {
unsigned nchars = gxstrlen(s);
char *nsptr = Unicode2ASCII(s, nchars);
if(!nsptr) return 0;
int rv = find_last(nsptr);
delete[] nsptr;
return rv;
}
else {
return find_last(s);
}
}
int UStringB::FindLast(const UStringB &s) const
{
// Check for null pointers and strings
if((!s.sptr) || !(sptr)) return -1; // Check for null pointers
if(!is_unicode()) {
if(!s.is_unicode()) {
return find_last(s.sptr);
}
else {
char *nsptr = Unicode2ASCII((wchar_t *)s.sptr, s.s_length);
if(!nsptr) return 0;
int rv = find_last(nsptr);
delete[] nsptr;
return rv;
}
}
else {
if(!s.is_unicode()) {
wchar_t *nsptr = ASCII2Unicode((char *)s.sptr, s.s_length);
if(!nsptr) return 0;
int rv = find_last(nsptr);
delete[] nsptr;
return rv;
}
else {
return find_last(s.sptr);
}
}
}
unsigned UStringB::ReplaceChar(const char c, const char replacement,
unsigned offset)
// Replace the specified character. Returns the number of characters
// replaced in the string.
{
if((sptr == 0) || (s_length == 0)) return 0; // Check for null pointers
if(!is_unicode()) {
unsigned num_replaced = 0;
unsigned i;
char *start = (char *)sptr + offset;
for(i = 0; i < s_length; i++) {
if(start[i] == c) {
start[i] = replacement;
num_replaced++;
}
}
return num_replaced;
}
else {
#if defined (__PCLINT_CHECK__)
return 0;
#else
wchar_t wc = (wchar_t)c;
wchar_t wreplacement = (wchar_t)replacement;
return ReplaceChar(wc, wreplacement, offset);
#endif
}
}
unsigned UStringB::ReplaceChar(const wchar_t c, const wchar_t replacement,
unsigned offset)
// Replace the specified character. Returns the number of characters
// replaced in the string.
{
if((sptr == 0) || (s_length == 0)) return 0; // Check for null pointers
if(!is_unicode()) {
char ac = (char)c;
char areplacement = (char)replacement;
return ReplaceChar(ac, areplacement, offset);
}
else {
unsigned num_replaced = 0;
unsigned i;
wchar_t *start = (wchar_t *)sptr + offset;
for(i = 0; i < s_length; i++) {
if(start[i] == c) {
start[i] = replacement;
num_replaced++;
}
}
return num_replaced;
}
}
unsigned UStringB::ReplaceString(const char *s,
const char *replacement,
unsigned offset)
{
unsigned num_replaced = 0;
while(1) {
offset = Find(s, offset);
if ((int)offset == -1) break;
DeleteAt(offset, gxstrlen(s));
InsertAt(offset, replacement, gxstrlen(replacement));
num_replaced++;
offset += gxstrlen(replacement);
}
return num_replaced;
}
unsigned UStringB::ReplaceString(const wchar_t *s,
const wchar_t *replacement,
unsigned offset)
{
unsigned num_replaced = 0;
while(1) {
offset = Find(s, offset);
if ((int)offset == -1) break;
DeleteAt(offset, gxstrlen(s));
InsertAt(offset, replacement, gxstrlen(replacement));
num_replaced++;
offset += gxstrlen(replacement);
}
return num_replaced;
}
unsigned UStringB::ReplaceString(const UStringB &s,
const UStringB &replacement,
unsigned offset)
{
unsigned num_replaced = 0;
while(1) {
offset = Find(s, offset);
if ((int)offset == -1) break;
DeleteAt(offset, s.s_length);
InsertAt(offset, replacement, replacement.s_length);
num_replaced++;
offset += replacement.s_length;
}
return num_replaced;
}
unsigned UStringB::FilterString(const char *s, unsigned offset)
// Filter the specified string from the object. Returns
// the number of strings filtered from the string.
{
unsigned num_replaced = 0;
while(1) {
offset = Find(s, offset);
if((int)offset == -1) break;
DeleteAt(offset, gxstrlen(s));
num_replaced++;
offset++;
}
return num_replaced;
}
unsigned UStringB::FilterString(const wchar_t *s, unsigned offset)
// Filter the specified string from the object. Returns
// the number of strings filtered from the string.
{
unsigned num_replaced = 0;
while(1) {
offset = Find(s, offset);
if((int)offset == -1) break;
DeleteAt(offset, gxstrlen(s));
num_replaced++;
offset++;
}
return num_replaced;
}
unsigned UStringB::FilterString(const UStringB &s, unsigned offset)
// Filter the specified string from the object. Returns
// the number of strings filtered from the string.
{
unsigned num_replaced = 0;
while(1) {
offset = Find(s, offset);
if ((int)offset == -1) break;
DeleteAt(offset, s.s_length);
num_replaced++;
offset++;
}
return num_replaced;
}
unsigned UStringB::FilterChar(const char c, unsigned offset)
// Filter the specified character from the object. Returns
// the number of characters filtered from the string.
{
if(!is_unicode()) {
char s[2]; // Define a two char array (char_type + null terminator)
s[0] = c; // Character to be filtered
s[1] = 0; // Null-terminate the string so the gxstrlen() function
// will work correctly.
return FilterString((const char *)s, offset);
}
else {
#if defined (__PCLINT_CHECK__)
return 0;
#else
// Define a two char array (char_type + null terminator)
wchar_t ws_char[2];
ws_char[0] = (wchar_t)c; // Character to be filtered
ws_char[1] = 0; // Null-terminate the string so the gxstrlen() function
// will work correctly.
return FilterString((const wchar_t *)ws_char, offset);
#endif
}
}
unsigned UStringB::FilterChar(const wchar_t c, unsigned offset)
// Filter the specified character from the object. Returns
// the number of characters filtered from the string.
{
if(!is_unicode()) {
char s[2]; // Define a two char array (char_type + null terminator)
s[0] = (char)c; // Character to be filtered
s[1] = 0; // Null-terminate the string so the gxstrlen() function
// will work correctly.
return FilterString((const char *)s, offset);
}
else {
#if defined (__PCLINT_CHECK__)
return 0;
#else
// Define a two char array (char_type + null terminator)
wchar_t ws_char[2];
ws_char[0] = c; // Character to be filtered
ws_char[1] = 0; // Null-terminate the string so the gxstrlen() function
// will work correctly.
return FilterString((const wchar_t *)ws_char, offset);
#endif
}
}
unsigned UStringB::TrimLeadingSpaces()
// Filter all leading spaces from a string.
// Returns the number of characters filtered.
{
if((sptr == 0) || (s_length == 0)) return 0; // Check for null pointers
unsigned i, num_l_spaces = 0;
if(!is_unicode()) {
char *start = (char *)sptr;
for(i = 0; i < s_length; i++) {
if(!isspace(start[i])) break;
num_l_spaces++;
}
if(num_l_spaces > 0) DeleteAt(0, num_l_spaces);
return num_l_spaces;
}
else {
wchar_t *start = (wchar_t *)sptr;
for(i = 0; i < s_length; i++) {
#if defined (__HAS_UNICODE__)
if(!iswspace(start[i])) break;
#else
if(!isspace(start[i])) break;
#endif // __HAS_UNICODE__
num_l_spaces++;
}
if(num_l_spaces > 0) DeleteAt(0, num_l_spaces);
return num_l_spaces;
}
}
unsigned UStringB::TrimTrailingSpaces()
// Filter all Trailing spaces from a string.
// Returns the number of characters filtered.
{
if((sptr == 0) || (s_length == 0)) return 0; // Check for null pointers
if(!is_unicode()) {
char *start = (char *)sptr;
unsigned i, num_t_spaces = 0;
for(i = (s_length - 1); i != 0; i--) {
if(!isspace(start[i])) break;
num_t_spaces++;
}
if(num_t_spaces > 0) DeleteAt((s_length - num_t_spaces), num_t_spaces);
return num_t_spaces;
}
else {
wchar_t *start = (wchar_t *)sptr;
unsigned i, num_t_spaces = 0;
for(i = (s_length - 1); i != 0; i--) {
#if defined (__HAS_UNICODE__)
if(!iswspace(start[i])) break;
#else
if(!isspace(start[i])) break;
#endif // __HAS_UNICODE__
num_t_spaces++;
}
if(num_t_spaces > 0) DeleteAt((s_length - num_t_spaces), num_t_spaces);
return num_t_spaces;
}
}
int UStringB::DeleteAfter(const char *s)
// Delete everything after the specified string.
// Returns true if successful.
{
unsigned nchars = s_length;
int offset = Find(s);
if(offset == -1) return 0;
offset += gxstrlen(s); // Keep the delimiting string
DeleteAt(offset, (nchars - offset));
return 1;
}
int UStringB::DeleteAfter(const wchar_t *s)
// Delete everything after the specified string.
// Returns true if successful.
{
unsigned nchars = s_length;
int offset = Find(s);
if(offset == -1) return 0;
offset += gxstrlen(s); // Keep the delimiting string
DeleteAt(offset, (nchars - offset));
return 1;
}
int UStringB::DeleteAfter(const UStringB &s)
// Delete everything after the specified string.
// Returns true if successful.
{
unsigned nchars = s_length;
int offset = Find(s);
if(offset == -1) return 0;
offset += s.s_length; // Keep the delimiting string
DeleteAt(offset, (nchars - offset));
return 1;
}
int UStringB::DeleteBefore(const char *s)
// Delete everything before the specified string.
// Returns true if successful.
{
int offset = Find(s);
if(offset == -1) return 0;
DeleteAt(0, offset);
return 1;
}
int UStringB::DeleteBefore(const wchar_t *s)
// Delete everything before the specified string.
// Returns true if successful.
{
int offset = Find(s);
if(offset == -1) return 0;
DeleteAt(0, offset);
return 1;
}
int UStringB::DeleteBefore(const UStringB &s)
// Delete everything before the specified string.
// Returns true if successful.
{
int offset = Find(s);
if(offset == -1) return 0;
DeleteAt(0, offset);
return 1;
}
int UStringB::DeleteAfterIncluding(const char *s)
// Delete everything after the specified string
// including the string. Returns true if successful.
{
unsigned nchars = s_length;
int offset = Find(s);
if(offset == -1) return 0;
DeleteAt(offset, (nchars - offset));
return 1;
}
int UStringB::DeleteAfterIncluding(const wchar_t *s)
// Delete everything after the specified string
// including the string. Returns true if successful.
{
unsigned nchars = s_length;
int offset = Find(s);
if(offset == -1) return 0;
DeleteAt(offset, (nchars - offset));
return 1;
}
int UStringB::DeleteAfterIncluding(const UStringB &s)
// Delete everything after the specified string
// including the string. Returns true if successful.
{
unsigned nchars = s_length;
int offset = Find(s);
if(offset == -1) return 0;
DeleteAt(offset, (nchars - offset));
return 1;
}
int UStringB::DeleteBeforeIncluding(const char *s)
// Delete everything before the specified string
// including the string. Returns true if successful.
{
int offset = Find(s);
if(offset == -1) return 0;
DeleteAt(0, offset+gxstrlen(s));
return 1;
}
int UStringB::DeleteBeforeIncluding(const wchar_t *s)
// Delete everything before the specified string
// including the string. Returns true if successful.
{
int offset = Find(s);
if(offset == -1) return 0;
DeleteAt(0, offset+gxstrlen(s));
return 1;
}
int UStringB::DeleteBeforeIncluding(const UStringB &s)
// Delete everything before the specified string
// including the string. Returns true if successful.
{
int offset = Find(s);
if(offset == -1) return 0;
DeleteAt(0, offset+s.s_length);
return 1;
}
int UStringB::DeleteAfterLast(const char *s)
// Deletes everything after the last occurrence
// of the specified string. Return true if the
// any characters were deleted.
{
int offset = 0;
int index = 0;
unsigned nchars = s_length;
while(1) {
offset = Find(s, offset);
if(offset != -1) index = offset;
if(offset == -1) break;
offset++;
}
if(index > 0) {
index += gxstrlen(s); // Keep the specified string
DeleteAt(index, (nchars - index));
}
return 1;
}
int UStringB::DeleteAfterLast(const wchar_t *s)
// Deletes everything after the last occurrence
// of the specified string. Return true if the
// any characters were deleted.
{
int offset = 0;
int index = 0;
unsigned nchars = s_length;
while(1) {
offset = Find(s, offset);
if(offset != -1) index = offset;
if(offset == -1) break;
offset++;
}
if(index > 0) {
index += gxstrlen(s); // Keep the specified string
DeleteAt(index, (nchars - index));
}
return 1;
}
int UStringB::DeleteAfterLast(const UStringB &s)
// Deletes everything after the last occurrence
// of the specified string. Return true if the
// any characters were deleted.
{
int offset = 0;
int index = 0;
unsigned nchars = s_length;
while(1) {
offset = Find(s, offset);
if(offset != -1) index = offset;
if(offset == -1) break;
offset++;
}
if(index > 0) {
index += s.s_length; // Keep the specified string
DeleteAt(index, (nchars - index));
}
return 1;
}
int UStringB::DeleteAfterLastIncluding(const char *s)
// Deletes everything after the last occurrence
// of the specified string. Return true if the
// any characters were deleted.
{
int offset = 0;
int index = 0;
unsigned nchars = s_length;
while(1) {
offset = Find(s, offset);
if(offset != -1) index = offset;
if(offset == -1) break;
offset++;
}
if(index > 0) DeleteAt(index, (nchars - index));
return 1;
}
int UStringB::DeleteAfterLastIncluding(const wchar_t *s)
// Deletes everything after the last occurrence
// of the specified string. Return true if the
// any characters were deleted.
{
int offset = 0;
int index = 0;
unsigned nchars = s_length;
while(1) {
offset = Find(s, offset);
if(offset != -1) index = offset;
if(offset == -1) break;
offset++;
}
if(index > 0) DeleteAt(index, (nchars - index));
return 1;
}
int UStringB::DeleteAfterLastIncluding(const UStringB &s)
// Deletes everything after the last occurrence
// of the specified string. Return true if the
// any characters were deleted.
{
int offset = 0;
int index = 0;
unsigned nchars = s_length;
while(1) {
offset = Find(s, offset);
if(offset != -1) index = offset;
if(offset == -1) break;
offset++;
}
if(index > 0) DeleteAt(index, (nchars - index));
return 1;
}
int UStringB::DeleteBeforeLast(const char *s)
// Deletes everything before the last occurrence
// of the specified string. Return true if the
// any characters were deleted.
{
int offset = 0;
int index = 0;
while(1) {
offset = Find(s, offset);
if(offset != -1) index = offset;
if(offset == -1) break;
offset++;
}
if(index > 0) DeleteAt(0, index);
return 1;
}
int UStringB::DeleteBeforeLast(const wchar_t *s)
// Deletes everything before the last occurrence
// of the specified string. Return true if the
// any characters were deleted.
{
int offset = 0;
int index = 0;
while(1) {
offset = Find(s, offset);
if(offset != -1) index = offset;
if(offset == -1) break;
offset++;
}
if(index > 0) DeleteAt(0, index);
return 1;
}
int UStringB::DeleteBeforeLast(const UStringB &s)
// Deletes everything before the last occurrence
// of the specified string. Return true if the
// any characters were deleted.
{
int offset = 0;
int index = 0;
while(1) {
offset = Find(s, offset);
if(offset != -1) index = offset;
if(offset == -1) break;
offset++;
}
if(index > 0) DeleteAt(0, index);
return 1;
}
int UStringB::DeleteBeforeLastIncluding(const char *s)
// Deletes everything before the last occurrence
// of the specified string. Return true if the
// any characters were deleted.
{
int offset = 0;
int index = 0;
while(1) {
offset = Find(s, offset);
if(offset != -1) index = offset;
if(offset == -1) break;
offset++;
}
if(index > 0) DeleteAt(0, (index + gxstrlen(s)));
return 1;
}
int UStringB::DeleteBeforeLastIncluding(const wchar_t *s)
// Deletes everything before the last occurrence
// of the specified string. Return true if the
// any characters were deleted.
{
int offset = 0;
int index = 0;
while(1) {
offset = Find(s, offset);
if(offset != -1) index = offset;
if(offset == -1) break;
offset++;
}
if(index > 0) DeleteAt(0, (index + gxstrlen(s)));
return 1;
}
int UStringB::DeleteBeforeLastIncluding(const UStringB &s)
// Deletes everything before the last occurrence
// of the specified string. Return true if the
// any characters were deleted.
{
int offset = 0;
int index = 0;
while(1) {
offset = Find(s, offset);
if(offset != -1) index = offset;
if(offset == -1) break;
offset++;
}
if(index > 0) DeleteAt(0, (index + s.s_length));
return 1;
}
int UStringB::ConvertEscapeSeq(char esc, int num_octets)
// Function used to convert hex escape sequences within a string
// to printable ASCII characters. This function assumes that
// the number of octets following the escape character is hex
// values that can be converted to an ASCII value. Returns the
// number of escape sequences converted to printable characters.
{
if((sptr == 0) || (s_length == 0)) return 0; // Check for null pointers
if(!is_unicode()) {
unsigned num_esc = 0;
char s[2]; s[0] = esc; s[1] = 0;
const int sbuf_len = 81;
if(num_octets > sbuf_len) num_octets = sbuf_len-1;
if(num_octets <= 0) num_octets = 2;
char sbuf[sbuf_len];
int offset = 0;
char *start = (char *)sptr;
int hex_digits;
while(1) {
offset = Find(s, offset);
if(offset == -1) break;
if(start[offset+1] == esc) {
// This is an escaped escaped sequence, so
// leave one escape character in the string.
DeleteAt(offset, 1); // Remove the first esc
offset++;
continue;
}
DeleteAt(offset, 1); // Remove the esc from this string
memmove(sbuf, (start+offset), num_octets);
sbuf[num_octets] = 0;
sscanf(sbuf, "%x", &hex_digits);
DeleteAt(offset, num_octets); // Remove the octets from this string
sbuf[0] = (char)hex_digits;
InsertAt(offset, sbuf, 1); // Insert the ASCII character
num_esc++;
offset++;
}
return num_esc;
}
else {
#if defined (__PCLINT_CHECK__)
return 0;
#else
return ConvertEscapeSeq((wchar_t)esc, num_octets);
#endif
}
}
int UStringB::ConvertEscapeSeq(wchar_t esc, int num_octets)
// Function used to convert hex escape sequences within a string
// to printable ASCII characters. This function assumes that
// the number of octets following the escape character is hex
// values that can be converted to an ASCII value. Returns the
// number of escape sequences converted to printable characters.
{
if((sptr == 0) || (s_length == 0)) return 0; // Check for null pointers
if(!is_unicode()) {
return ConvertEscapeSeq((char)esc, num_octets);
}
else {
unsigned num_esc = 0;
const unsigned cs = sizeof(wchar_t);
const int max_chars = 81;
const int min_chars = 2;
const int sbuf_len = max_chars * cs;
wchar_t *start = (wchar_t *)sptr;
wchar_t s[2]; s[0] = esc; s[1] = 0;
// Do not exceed the bound of the sbuf array
if(int(num_octets * cs) > sbuf_len) num_octets = max_chars-1;
if(num_octets <= 0) num_octets = min_chars;
wchar_t sbuf[sbuf_len];
int offset = 0;
int hex_digits;
while(1) {
offset = Find(s, offset);
if(offset == -1) break;
if(start[offset+1] == esc) {
// This is an escaped escaped sequence, so
// leave one escape character in the string.
DeleteAt(offset, 1); // Remove the first esc
offset++;
continue;
}
DeleteAt(offset, 1); // Remove the esc from this string
memmove(sbuf, (start+offset), (num_octets * cs));
sbuf[num_octets] = 0;
#if defined (__HAS_UNICODE__) && defined (__WIN32__)
wchar_t wf[3]; char f0 = '%'; char f1 = 'x';
// PC-lint 09/15/2005: Ignore type cast warnings
wf[0] = (wchar_t)f0; wf[1] = (wchar_t)f1; wf[2] = (wchar_t)0;
swscanf(sbuf, wf, &hex_digits);
#else
char *asbuf = Unicode2ASCII(sbuf, num_octets);
sscanf(asbuf, "%x", &hex_digits);
wchar_t *wsbuf = ASCII2Unicode(asbuf, gxstrlen(asbuf));
gxstrcpy(sbuf, wsbuf);
delete[] asbuf;
delete[] wsbuf;
#endif // __HAS_UNICODE__
DeleteAt(offset, num_octets); // Remove the octets from this string
sbuf[0] = (wchar_t)hex_digits;
InsertAt(offset, sbuf, 1); // Insert the Unicode character
num_esc++;
offset++;
}
return num_esc;
}
}
unsigned UStringB::SetLength()
// Function used to set or reset the logical length of this string
// based on the string length returned by the string length function.
// Redundantly returns the logical length of this string.
{
if(!sptr) { // Check for null pointers
s_length = 0;
d_length = 0;
return 0;
}
if(!is_unicode()) {
return s_length = gxstrlen((char *)sptr);
}
else {
return s_length = gxstrlen((wchar_t *)sptr);
}
}
unsigned UStringB::SetLength(unsigned nchars)
// Function used to change the logical length of this string.
// If the dimensioned is exceeded the string will be resized.
// Redundantly returns the logical length of this string.
{
unsigned cs; gxStringType st;
if(!is_unicode()) {
cs = sizeof(char);
st = gxASCII_STRING;
}
else {
cs = sizeof(wchar_t);
st = gxUNICODE_STRING;
}
if((nchars * cs) > (d_length-1)) {
if(!this->resize(nchars+1)) {
nchars = (d_length-1)/cs;
if((d_length-1) % cs) nchars++;
}
}
if(!sptr) { // Check for null pointers after resize
s_length = 0;
d_length = 0;
return 0;
}
s_length = nchars; // Set the logical length
null_terminate(st); // Ensure null termination
return s_length;
}
void UStringB::ResetGlobalNull()
// Function used to reset the global null pointers
// in the event that they have been modified and
// are no longer contain a null character.
{
UStringNULLPtr::UStringNUllChar = '\0';
UStringNULLPtr::UStringNUllStr[0] = '\0';
UStringNULLPtr::UStringwNUllChar = '\0';
UStringNULLPtr::UStringwNUllStr[0] = '\0';
}
void *UStringB::SetSPrt(void *s, unsigned nchars, unsigned bytes)
// Function used to bind this object to another null terminated
// string. The caller must set the logical length of this string
// with the option to set the dimensioned length is there are
// characters past the string's null terminator. Redundantly
// returns a pointer to the string passed to this function.
// NOTE: The memory held by the current pointer will be freed
// unless the UStringB::Release() function is called prior to
// calling this function. The Release() function should be called
// only if other entities are bound to this object's string.
{
unsigned cs;
if(!is_unicode()) {
cs = sizeof(char);
}
else {
cs = sizeof(wchar_t);
}
delete_sptr(); // Free the memory this object is holding
if(s) { // Check for null pointers
sptr = s;
s_length = nchars;
d_length = nchars * cs;
if(bytes > 0) d_length = bytes;
}
return sptr;
}
UStringB &UStringB::operator+=(const char c)
{
Cat((const char *)&c, 1);
return *this;
}
UStringB &UStringB::operator+=(const wchar_t c)
{
Cat((const wchar_t *)&c, 1);
return *this;
}
UStringB &UStringB::operator<<(UStringB & (*_f)(UStringB&))
{
// PC-lint 09/15/2005: Ignore PC-lint type warning
(*_f)(*(this));
return *(this);
}
UStringB &UStringB::operator<<(const char c)
{
if(output_width > 1) {
int i = output_width - 1;
while(i--) *this += output_fill;
}
return *this += c;
}
UStringB& UStringB::operator<<(const long val)
{
char sbuf[81];
if(output_hex == 1) { // Base 16
// Using type cast to int type to eliminate
// warning: int format, long int arg (arg 3) when compiled
// under Linux gcc.
sprintf(sbuf, "%X", (int)val);
}
else if(output_hex == 2) { // Base 8
sprintf(sbuf, "%o", (int)val);
}
else if(output_hex == 3) { // Shorthand notation
SHN((unsigned long)val);
return *this;
}
else if(output_hex == 4) { // Whole number comma notation
WholeNumber((unsigned long)val);
return *this;
}
else { // Default to base 10
sprintf(sbuf, "%d", (int)val);
}
if((output_width > 0) && ((int)strlen(sbuf) < output_width)) {
int i = output_width - strlen(sbuf);
while(i--) *this += output_fill;
}
return *this += sbuf;
}
UStringB& UStringB::operator<<(const unsigned long val)
{
char sbuf[81];
if(output_hex == 1) { // Base 16
// Using type cast to int type to eliminate
// warning: int format, long int arg (arg 3) when compiled
// under Linux gcc.
sprintf(sbuf, "%X", (unsigned int)val);
}
else if(output_hex == 2) { // Base 8
sprintf(sbuf, "%o", (int)val);
}
else if(output_hex == 3) { // Shorthand notation
SHN(val);
return *this;
}
else if(output_hex == 4) { // Whole number comma notation
WholeNumber(val);
return *this;
}
else { // Default to base 10
sprintf(sbuf, "%u", (unsigned int)val);
}
if((output_width > 0) && ((int)strlen(sbuf) < output_width)) {
int i = output_width - strlen(sbuf);
while(i--) *this += output_fill;
}
return *this += sbuf;
}
UStringB& UStringB::operator<<(const double val)
{
char sbuf[81]; char fbuf[81];
sprintf(fbuf, "%%.%df", (int)output_pre);
sprintf(sbuf, (const char *)fbuf, val);
if((output_width > 0) && ((int)strlen(sbuf) < output_width)) {
int i = output_width - strlen(sbuf);
while(i--) *this += output_fill;
}
return *this += sbuf;
}
UStringB& UStringB::operator>>(char *s)
{
if(!s) return *this; // Check for null pointers
if(!sptr) {
gxstrcpy(s, UStringNULLPtr::UStringNUllStr);
return *this;
}
if(!is_unicode()) {
gxstrcpy(s, (char *)sptr); // Assumes enough memory is allocated for *s
}
else {
char *nsptr = Unicode2ASCII((wchar_t *)sptr, s_length);
if(!nsptr) return *this;
gxstrcpy(s, nsptr); // Assumes enough memory is allocated for *s
delete[] nsptr;
}
return *this;
}
UStringB& UStringB::operator>>(char &c)
{
if(!sptr) {
c = UStringNULLPtr::UStringNUllChar;
return *this; // Check for null pointers
}
if(!is_unicode()) {
char *asptr = (char *)sptr;
c = asptr[0];
}
else {
char *wsptr = (char *)sptr;
c = (char)wsptr[0];
}
return *this;
}
UStringB& UStringB::operator>>(long &val)
{
val = this->Atol();
return *this;
}
UStringB& UStringB::operator>>(unsigned long &val)
{
val = (unsigned long)this->Atou();
return *this;
}
UStringB& UStringB::operator>>(int &val)
{
val = this->Atoi();
return *this;
}
UStringB& UStringB::operator>>(unsigned int &val)
{
val = (unsigned int)this->Atou();
return *this;
}
UStringB& UStringB::operator>>(unsigned short &val)
{
val = (unsigned short)this->Atoi();
return *this;
}
UStringB& UStringB::operator>>(short &val)
{
val = (short)this->Atoi();
return *this;
}
UStringB& UStringB::operator>>(float &val)
{
val = (float)this->Atof();
return *this;
}
UStringB& UStringB::operator>>(double &val)
{
val = (double)this->Atof();
return *this;
}
#if defined (__64_BIT_DATABASE_ENGINE__) || defined (__ENABLE_64_BIT_INTEGERS__)
UStringB& UStringB::operator<<(const __LLWORD__ val)
{
char sbuf[81];
if(output_hex == 1) { // Base 16
LLWORDToString(sbuf, val, 16);
}
else if(output_hex == 2) { // Base 8
LLWORDToString(sbuf, val, 8);
}
else if(output_hex == 3) { // Shorthand notation
SHN((__ULLWORD__)val);
return *this;
}
else if(output_hex == 4) { // Whole number comma notation
WholeNumber((__ULLWORD__)val);
return *this;
}
else { // Default to base 10
LLWORDToString(sbuf, val, 10);
}
if((output_width > 0) && ((int)strlen(sbuf) < output_width)) {
int i = output_width - strlen(sbuf);
while(i--) *this += output_fill;
}
return *this += sbuf;
}
UStringB& UStringB::operator<<(const __ULLWORD__ val)
{
char sbuf[81];
if(output_hex == 1) { // Base 16
ULLWORDToString(sbuf, val, 16);
}
else if(output_hex == 2) { // Base 8
ULLWORDToString(sbuf, val, 8);
}
else if(output_hex == 3) { // Shorthand notation
SHN(val);
return *this;
}
else if(output_hex == 4) { // Whole number comma notation
WholeNumber(val);
return *this;
}
else { // Default to base 10
ULLWORDToString(sbuf, val, 10);
}
if((output_width > 0) && ((int)strlen(sbuf) < output_width)) {
int i = output_width - strlen(sbuf);
while(i--) *this += output_fill;
}
return *this += sbuf;
}
__LLWORD__ UStringB::Atoi64()
{
// Check for null pointers
if((sptr == 0) || (s_length == 0)) return (__LLWORD__)0;
if(!is_unicode()) {
return StringToLLWORD((char *)sptr);
}
else {
return StringToLLWORD((wchar_t *)sptr);
}
}
__ULLWORD__ UStringB::Atou64()
{
// Check for null pointers
if((sptr == 0) || (s_length == 0)) return (__ULLWORD__)0;
if(!is_unicode()) {
return StringToULLWORD((char *)sptr);
}
else {
return StringToULLWORD((wchar_t *)sptr);
}
}
UStringB& UStringB::operator>>(__LLWORD__ &val)
{
val = this->Atoi64();
return *this;
}
UStringB& UStringB::operator>>(__ULLWORD__ &val)
{
val = (__ULLWORD__)this->Atou64();
return *this;
}
void UStringB::WholeNumber(__ULLWORD__ bytes)
// Public member function used to insert a comma
// separated whole number into a string.
{
char sbuf[81];
ULLWORDToString(sbuf, bytes, 10);
unsigned start_len = length();
*this += sbuf;
unsigned stop_len = length();
unsigned slen = stop_len - start_len;
stop_len -= slen;
unsigned offset = length();
unsigned num_commas = 0;
if(slen > 3) num_commas = slen/3;
for(unsigned i = 0; i < num_commas; i ++) {
offset -= 3;
if(offset == stop_len) break;
InsertAt(offset, ",", 1);
}
}
void UStringB::SHN(__ULLWORD__ bytes)
{
double shn_n; // Shorthand notation number
char shn_c[2] = { '\0', '\0' }; // Shorthand notation nomenclature
char sbuf[81]; char hbuf[81]; char rbuf[81];
unsigned long lval;
int i;
__ULLWORD__ llval, rlval;
__ULLWORD__ x1G = (1000*1000)*1000;
if(bytes > 1000) { // More than 1K bytes
if(bytes < (1000*1000)) { // Less than 1M
lval = (unsigned long)bytes;
shn_n = (double)lval/double(1000);
shn_c[0] = 'K';
sprintf(sbuf, "%.2f", shn_n);
}
else if(bytes < ((1000*1000)*1000)) { // Less than 1G
lval = (unsigned long)bytes;
shn_n = (double)lval/double(1000*1000);
shn_c[0] = 'M';
sprintf(sbuf, "%.2f", shn_n);
}
else if(bytes < (1000*x1G)) { // Less than 1T
llval = bytes/((1000*1000)*1000);
rlval = bytes%((1000*1000)*1000);
ULLWORDToString(hbuf, llval, 10);
ULLWORDToString(rbuf, rlval, 10);
rbuf[3] = 0;
sprintf(sbuf, "%s.%s", hbuf, rbuf);
shn_c[0] = 'G';
}
else { // 1T or greater
llval = bytes/(1000*x1G);
rlval = bytes%(1000*x1G);
ULLWORDToString(hbuf, llval, 10);
ULLWORDToString(rbuf, rlval, 10);
rbuf[3] = 0;
sprintf(sbuf, "%s.%s", hbuf, rbuf);
shn_c[0] = 'T';
}
}
else {
sprintf(sbuf, "%u", (unsigned int)bytes);
if((output_width > 0) && ((int)strlen(sbuf) < output_width)) {
i = output_width - strlen(sbuf);
while(i--) *this += output_fill;
}
*(this) += sbuf;
return;
}
i = strlen(sbuf);
while(i--) {
if((sbuf[i] == '0') || (sbuf[i] == '.')) {
// Remove all trailing zeros and trailing dots
sbuf[i] = 0;
}
else {
// Break on the first non zero or non dot
break;
}
}
if((output_width > 0) && ((int)strlen(sbuf) < output_width)) {
i = (output_width-1) - strlen(sbuf);
while(i--) *this += output_fill;
}
*(this) += sbuf;
*(this) += shn_c;
}
#endif
int UStringB::StringCompare(const char *s, int check_case) const
// Function used to perform a string compare. If the "check_case"
// variable is false this function will ignore the upper and lower
// case letters. Returns -1 if this->sptr < s, 0 if this->sptr < s,
// and 1 if this->sptr > s.
{
// Comparisons for null pointers and null strings
if((sptr == 0) || (s_length == 0)) {
if(!s) {
return 0; // Both pointers are null
}
if(gxstrlen(s) == 0) return 0; // Both strings are null
return -1; // this->sptr is null
}
if(!s) {
if((sptr == 0) || (s_length == 0)) return 0; // Both pointers are null
return 1; // this->sptr is not null
}
if(!is_unicode()) {
if(check_case) {
return gxbyte_compare(sptr, s_length, s, gxstrlen(s));
}
else {
return gxbyte_icompare(sptr, s_length, s, gxstrlen(s),
gxASCII_STRING);
}
}
else {
unsigned nchars = gxstrlen(s);
unsigned cs = sizeof(wchar_t);
wchar_t *nsptr = ASCII2Unicode(s, nchars);
if(!nsptr) return 0;
int rv;
if(check_case) {
rv = gxbyte_compare(sptr, (s_length*cs), nsptr, (nchars*cs));
}
else {
rv = gxbyte_icompare(sptr, (s_length*cs), nsptr, (nchars*cs),
gxUNICODE_STRING);
}
delete[] nsptr;
return rv;
}
}
int UStringB::StringCompare(const wchar_t *s, int check_case) const
// Function used to perform a string compare. If the "check_case"
// variable is false this function will ignore the upper and lower
// case letters. Returns -1 if this->sptr < s, 0 if this->sptr < s,
// and 1 if this->sptr > s.
{
// Comparisons for null pointers and null strings
if((sptr == 0) || (s_length == 0)) {
if(!s) {
return 0; // Both pointers are null
}
if(gxstrlen(s) == 0) return 0; // Both strings are null
return -1; // this->sptr is null
}
if(!s) {
if((sptr == 0) || (s_length == 0)) return 0; // Both pointers are null
return 1; // this->sptr is not null
}
if(!is_unicode()) {
unsigned nchars = gxstrlen(s);
char *nsptr = Unicode2ASCII(s, nchars);
if(!nsptr) return 0;
int rv;
if(check_case) {
rv = gxbyte_compare(sptr, s_length, nsptr, nchars);
}
else {
rv = gxbyte_icompare(sptr, s_length, nsptr, nchars,
gxASCII_STRING);
}
delete[] nsptr;
return rv;
}
else {
unsigned cs = sizeof(wchar_t);
if(check_case) {
return gxbyte_compare(sptr, (s_length*cs), s, (gxstrlen(s)*cs));
}
else {
return gxbyte_icompare(sptr, (s_length*cs), s, (gxstrlen(s)*cs),
gxUNICODE_STRING);
}
}
}
int UStringB::StringCompare(const UStringB &s, int check_case) const
// Function used to perform a string compare. If the "check_case"
// variable is false this function will ignore the upper and lower
// case letters. Returns -1 if this->sptr < s, 0 if this->sptr < s,
// and 1 if this->sptr > s.
{
// Comparisons for pointers and null strings
if((sptr == 0) || (s_length == 0)) {
if((s.sptr == 0) || (s.s_length == 0)) return 0; // Both strings are null
return -1; // this->sptr is null
}
if((s.sptr == 0) || (s.s_length == 0)) {
if((sptr == 0) || (s_length == 0)) return 0; // Both strings are null
return 1; // this->sptr is not null
}
if(!is_unicode()) {
if(!s.is_unicode()) {
if(check_case) {
return gxbyte_compare(sptr, s_length, s.sptr, s.s_length);
}
else {
return gxbyte_icompare(sptr, s_length, s.sptr, s.s_length,
gxASCII_STRING);
}
}
else {
char *nsptr = Unicode2ASCII((wchar_t *)s.sptr, s.s_length);
if(!nsptr) return 0;
int rv;
if(check_case) {
rv = gxbyte_compare(sptr, s_length, nsptr, s.s_length);
}
else {
rv = gxbyte_icompare(sptr, s_length, nsptr, s.s_length,
gxASCII_STRING);
}
delete[] nsptr;
return rv;
}
}
else {
unsigned cs = sizeof(wchar_t);
if(!s.is_unicode()) {
wchar_t *nsptr = ASCII2Unicode((char *)s.sptr, s.s_length);
if(!nsptr) return 0;
int rv;
if(check_case) {
rv = gxbyte_compare(sptr, (s_length*cs), nsptr, (s.s_length*cs));
}
else {
rv = gxbyte_icompare(sptr, (s_length*cs), nsptr, (s.s_length*cs),
gxUNICODE_STRING);
}
delete[] nsptr;
return rv;
}
else {
if(check_case) {
return gxbyte_compare(sptr, (s_length*cs), s.sptr, (s.s_length*cs));
}
else {
return gxbyte_icompare(sptr, (s_length*cs), s.sptr, (s.s_length*cs),
gxUNICODE_STRING);
}
}
}
}
char *UStringB::c_str(char *sbuf)
// Returns a null terminated string representing this object's
// ASCII value. NOTE: This function assumes that the proper
// amount of memory has been allocated for the "sbuf" string
// buffer. The string buffer "sbuf" is redundantly returned by
// this function.
{
// Check for null pointers
if(!sbuf) return UStringNULLPtr::UStringNUllStr;
if(!sptr) return gxstrcpy(sbuf, UStringNULLPtr::UStringNUllStr);
if(!is_unicode()) {
gxstrcpy(sbuf, (char *)sptr);
return sbuf;
}
else {
char *nsptr = Unicode2ASCII((wchar_t *)sptr, s_length);
gxstrcpy(sbuf, nsptr);
delete nsptr;
return sbuf;
}
}
const char *UStringB::c_str(char *sbuf) const
// Returns a null terminated string representing this object's
// ASCII value. NOTE: This function assumes that the proper
// amount of memory has been allocated for the "sbuf" string
// buffer. The string buffer "sbuf" is redundantly eturned by
// this function.
{
// Check for null pointers
if(!sbuf) return UStringNULLPtr::UStringNUllStr;
if(!sptr) return gxstrcpy(sbuf, UStringNULLPtr::UStringNUllStr);
if(!is_unicode()) {
gxstrcpy(sbuf, (char *)sptr);
return sbuf;
}
else {
char *nsptr = Unicode2ASCII((wchar_t *)sptr, s_length);
gxstrcpy(sbuf, nsptr);
delete nsptr;
return sbuf;
}
}
wchar_t *UStringB::c_wstr(wchar_t *sbuf)
// Returns a null terminated string representing this object's
// Unicode value. NOTE: This function assumes that the proper
// amount of memory has been allocated for the "sbuf" string
// buffer. The string buffer "sbuf" is redundantly returned by
// this function.
{
// Check for null pointers
if(!sbuf) return UStringNULLPtr::UStringwNUllStr;
if(!sptr) return gxstrcpy(sbuf, UStringNULLPtr::UStringwNUllStr);
if(!is_unicode()) {
wchar_t *nsptr = ASCII2Unicode((char *)sptr, s_length);
gxstrcpy(sbuf, nsptr);
delete nsptr;
return sbuf;
}
else {
gxstrcpy(sbuf, (wchar_t *)sptr);
return sbuf;
}
}
const wchar_t *UStringB::c_wstr(wchar_t *sbuf) const
// Returns a null terminated string representing this object's
// Unicode value. NOTE: This function assumes that the proper
// amount of memory has been allocated for the "sbuf" string
// buffer. The string buffer "sbuf" is redundantly returned by
// this function.
{
// Check for null pointers
if(!sbuf) return UStringNULLPtr::UStringwNUllStr;
if(!sptr) return gxstrcpy(sbuf, UStringNULLPtr::UStringwNUllStr);
if(!is_unicode()) {
wchar_t *nsptr = ASCII2Unicode((char *)sptr, s_length);
gxstrcpy(sbuf, nsptr);
delete nsptr;
return sbuf;
}
else {
gxstrcpy(sbuf, (wchar_t *)sptr);
return sbuf;
}
}
UString::UString(unsigned nchars)
// Class constructor used to allocate a specified
// number of charaters for a string without setting
// the string value inside this object. NOTE: This
// function will account for a single null terminator
// in addition to the number of characters specified.
{
reset_all(); // Reset all the string class members
sptr = new char[nchars+1];
if(sptr) {
memset(sptr, 0, (nchars+1)); // Zero out the memory
s_length = 0; // No string has been set at this point
d_length = nchars;
}
}
UString::UString(const gxwchar_t *s, unsigned nchars)
{
reset_all();
if(s) { // Check for null pointers
if(nchars == 0) nchars = gxstrlen(s);
char *nsptr = gxwchar_t2ASCII(s, nchars);
SetSPrt(nsptr, nchars, nchars);
}
}
UString &UString::operator=(const gxwchar_t *s)
{
Clear();
if(s) { // Check for null pointers
unsigned nchars = gxstrlen(s);
char *nsptr = gxwchar_t2ASCII(s, nchars);
SetSPrt(nsptr, nchars, nchars);
}
return *this;
}
UString &UString::operator=(const char *s)
{
Clear();
SetString(s);
return *this;
}
UString &UString::operator=(const wchar_t *s)
{
Clear();
SetString(s);
return *this;
}
UString &UString::operator=(const UString &s)
{
if(this != &s) { // Prevent self assignment
Clear();
output_hex = s.output_hex ;
output_pre = s.output_pre;
output_width = s.output_width;
output_fill = s.output_fill;
SetString((char *)s.sptr, s.s_length);
}
return *this;
}
int UString::is_unicode() const
// ASCII string type derived class interface.
{
return 0; // This is not a unicode type
}
UString *UString::strdup()
// Returns a duplicate string object or a null value if an error
// occurs.
{
return (UString *)new UString((char*)sptr);
}
UString *UString::strdup() const
// Returns a duplicate string object or a null value if an error
// occurs.
{
return (UString *)new UString((char*)sptr);
}
char &UString::operator[](unsigned i)
{
// Check for null pointers
if(!sptr) return UStringNULLPtr::UStringNUllChar;
if(i >= s_length) i = s_length; // If not in bounds truncate to s_length
char *p = (char *)sptr;
return p[i];
}
char &UString::operator[](unsigned i) const
{
// Check for null pointers
if(!sptr) return UStringNULLPtr::UStringNUllChar;
if(i >= s_length) i = s_length; // If not in bounds truncate to s_length
char *p = (char *)sptr;
return p[i];
}
char *UString::c_str()
{
// Check for null pointers
if(!sptr) return UStringNULLPtr::UStringNUllStr;
return (char *)sptr;
}
const char *UString::c_str() const
{
// Check for null pointers
if(!sptr) return UStringNULLPtr::UStringNUllStr;
return (const char *)sptr;
}
wchar_t *UStringw::c_wstr()
{
if(!sptr) return UStringNULLPtr::UStringwNUllStr;
return (wchar_t *)sptr;
}
const wchar_t *UStringw::c_wstr() const
{
if(!sptr) return UStringNULLPtr::UStringwNUllStr;
return (const wchar_t *)sptr;
}
UStringw::UStringw(unsigned nchars)
// Class constructor used to allocate a specified
// number of charaters for a string without setting
// the string value inside this object. NOTE: This
// function will account for a single null terminator
// in addition to the number of characters specified.
{
reset_all(); // Reset all the string class members
unsigned cs = sizeof(wchar_t);
unsigned bytes = nchars * cs;
sptr = new wchar_t[nchars+1];
if(sptr) {
memset(sptr, 0, (bytes+cs)); // Zero out the memory
s_length = 0; // No string has been set at this point
d_length = bytes;
}
}
UStringw &UStringw::operator=(const char *s)
{
Clear();
SetString(s);
return *this;
}
UStringw &UStringw::operator=(const wchar_t *s)
{
Clear();
SetString(s);
return *this;
}
UStringw::UStringw(const gxwchar_t *s, unsigned nchars)
{
reset_all();
if(s) { // Check for null pointers
if(nchars == 0) nchars = gxstrlen(s);
wchar_t *nsptr = gxwchar_t2Unicode(s, nchars);
SetSPrt(nsptr, nchars, (nchars*sizeof(wchar_t)));
}
}
UStringw &UStringw::operator=(const gxwchar_t *s)
{
Clear();
if(s) { // Check for null pointers
unsigned nchars = gxstrlen(s);
wchar_t *nsptr = gxwchar_t2Unicode(s, nchars);
SetSPrt(nsptr, nchars, (nchars*sizeof(wchar_t)));
}
return *this;
}
UStringw &UStringw::operator=(const UStringw &s)
{
if(this != &s) { // Prevent self assignment
Clear();
output_hex = s.output_hex ;
output_pre = s.output_pre;
output_width = s.output_width;
output_fill = s.output_fill;
SetString((wchar_t *)s.sptr, s.s_length);
}
return *this;
}
UStringw *UStringw::strdup()
// Returns a duplicate string object or a null value if an error
// occurs.
{
return (UStringw *)new UStringw((wchar_t*)sptr);
}
UStringw *UStringw::strdup() const
// Returns a duplicate string object or a null value if an error
// occurs.
{
return (UStringw *)new UStringw((wchar_t*)sptr);
}
wchar_t &UStringw::operator[](unsigned i)
{
// Check for null pointers
if(!sptr) return UStringNULLPtr::UStringwNUllChar;
if(i >= s_length) i = s_length; // If not in bounds truncate to s_length
wchar_t *p = (wchar_t *)sptr;
return p[i];
}
wchar_t &UStringw::operator[](unsigned i) const
{
// Check for null pointers
if(!sptr) return UStringNULLPtr::UStringwNUllChar;
if(i >= s_length) i = s_length; // If not in bounds truncate to s_length
wchar_t *p = (wchar_t *)sptr;
return p[i];
}
int UStringw::is_unicode() const
// Unicode string type derived class interface.
{
return 1; // This is a Unicode type
}
GXDLCODE_API int CaseICmp(const UString &s1, const UString &s2)
{
return s1.StringICompare(s2);
}
GXDLCODE_API int CaseICmp(const UString &s1, const char *s)
{
return s1.StringICompare(s);
}
GXDLCODE_API int CaseICmp(const UString &s1, const wchar_t *s)
{
return s1.StringICompare(s);
}
GXDLCODE_API int CaseICmp(const char *s, const UString &s2)
{
return s2.StringICompare(s);
}
GXDLCODE_API int CaseICmp(const wchar_t *s, const UString &s2)
{
return s2.StringICompare(s);
}
GXDLCODE_API int CaseICmp(const UStringw &s1, const UStringw &s2)
{
return s1.StringICompare(s2);
}
GXDLCODE_API int CaseICmp(const UStringw &s1, const char *s)
{
return s1.StringICompare(s);
}
GXDLCODE_API int CaseICmp(const UStringw &s1, const wchar_t *s)
{
return s1.StringICompare(s);
}
GXDLCODE_API int CaseICmp(const char *s, const UStringw &s2)
{
return s2.StringICompare(s);
}
GXDLCODE_API int CaseICmp(const wchar_t *s, const UStringw &s2)
{
return s2.StringICompare(s);
}
#if defined (__USE_CPP_IOSTREAM__)
GXDLCODE_API GXSTD::ostream &operator<<(GXSTD::ostream &os, const UString &s)
{
if(!s) return os; // Check for null pointers
return os.write((char *)s.GetSPtr(), s.length());
}
GXDLCODE_API GXSTD::ostream &operator<<(GXSTD::ostream &os, const UStringw &s)
{
if(!s) return os; // Check for null pointers
char *nsptr = Unicode2ASCII((wchar_t *)s.GetSPtr(), s.length());
os.write(nsptr, s.length());
delete[] nsptr;
return os;
}
GXDLCODE_API GXSTD::istream &operator>>(GXSTD::istream &os, UString &s)
{
const int ibuf_size = 255;
char *nsptr = new char[ibuf_size];
if(!nsptr) {
s.SetString((const char *)"\0", 1);
return os;
}
os >> GXSTD::setw(ibuf_size) >> nsptr;
s.SetString(nsptr, gxstrlen(nsptr));
delete[] nsptr;
return os;
}
GXDLCODE_API GXSTD::istream &operator>>(GXSTD::istream &os, UStringw &s)
{
const int ibuf_size = 255;
char *nsptr = new char[ibuf_size];
if(!nsptr) {
s.SetString((const char *)"\0", 1);
return os;
}
os >> GXSTD::setw(ibuf_size) >> nsptr;
s.SetString(nsptr, gxstrlen(nsptr));
delete[] nsptr;
return os;
}
#endif // __USE_CPP_IOSTREAM__
GXDLCODE_API int StringCompare(const UString &a, const UString &b)
{
return a.StringCompare(b);
}
GXDLCODE_API int StringCompare(const char *s, const UString &b)
{
UString a(s);
return a.StringCompare(b);
}
GXDLCODE_API int StringCompare(const UString &a, const char *s)
{
return a.StringCompare(s);
}
GXDLCODE_API int StringCompare(const wchar_t *s, const UString &b)
{
UString a(s);
return a.StringCompare(b);
}
GXDLCODE_API int StringCompare(const UString &a, const wchar_t *s)
{
return a.StringCompare(s);
}
GXDLCODE_API UString operator+(const UString &a, const UString &b)
{
UString buf(a);
buf += b;
return buf;
}
GXDLCODE_API UString operator+(const char *s, const UString &b)
{
UString buf(s);
buf += b;
return buf;
}
GXDLCODE_API UString operator+(const UString &a, const char *s)
{
UString buf(a);
buf.Cat(s); // Append "s" to the end of the object
return buf;
}
GXDLCODE_API UString operator+(const wchar_t *s, const UString &b)
{
UString buf(s);
buf += b;
return buf;
}
GXDLCODE_API UString operator+(const UString &a, const wchar_t *s)
{
UString buf(a);
buf.Cat(s); // Append "s" to the end of the object
return buf;
}
GXDLCODE_API int operator==(const UString &a, const UString &b)
{
return StringCompare(a, b) == 0;
}
GXDLCODE_API int operator==(const char *a, const UString &b)
{
return StringCompare(a, b) == 0;
}
GXDLCODE_API int operator==(const UString &a, const char *b)
{
return StringCompare(a, b) == 0;
}
GXDLCODE_API int operator==(const wchar_t *a, const UString &b)
{
return StringCompare(a, b) == 0;
}
GXDLCODE_API int operator==(const UString &a, const wchar_t *b)
{
return StringCompare(a, b) != 0;
}
GXDLCODE_API int operator!=(const UString &a, const UString &b)
{
return StringCompare(a, b) != 0;
}
GXDLCODE_API int operator!=(const char *a, const UString &b)
{
return StringCompare(a, b) != 0;
}
GXDLCODE_API int operator!=(const UString &a, const char *b)
{
return StringCompare(a, b) != 0;
}
GXDLCODE_API int operator!=(const wchar_t *a, const UString &b)
{
return StringCompare(a, b) != 0;
}
GXDLCODE_API int operator!=(const UString &a, const wchar_t *b)
{
return StringCompare(a, b) != 0;
}
GXDLCODE_API int operator>(const UString &a, const UString &b)
{
return StringCompare(a, b) > 0;
}
GXDLCODE_API int operator>(const char *a , const UString &b)
{
return StringCompare(a, b) > 0;
}
GXDLCODE_API int operator>(const UString &a, const char *b)
{
return StringCompare(a, b) > 0;
}
GXDLCODE_API int operator>(const wchar_t *a , const UString &b)
{
return StringCompare(a, b) > 0;
}
GXDLCODE_API int operator>(const UString &a, const wchar_t *b)
{
return StringCompare(a, b) > 0;
}
GXDLCODE_API int operator>=(const UString &a, const UString &b)
{
return StringCompare(a, b) >= 0;
}
GXDLCODE_API int operator>=(const char *a, const UString &b)
{
return StringCompare(a, b) >= 0;
}
GXDLCODE_API int operator>=(const UString &a, const char *b)
{
return StringCompare(a, b) >= 0;
}
GXDLCODE_API int operator>=(const wchar_t *a, const UString &b)
{
return StringCompare(a, b) >= 0;
}
GXDLCODE_API int operator>=(const UString &a, const wchar_t *b)
{
return StringCompare(a, b) >= 0;
}
GXDLCODE_API int operator<(const UString &a, const UString &b)
{
return StringCompare(a, b) < 0;
}
GXDLCODE_API int operator<(const char *a, const UString &b)
{
return StringCompare(a, b) < 0;
}
GXDLCODE_API int operator<(const UString &a, const char *b)
{
return StringCompare(a, b) < 0;
}
GXDLCODE_API int operator<(const wchar_t *a, const UString &b)
{
return StringCompare(a, b) < 0;
}
GXDLCODE_API int operator<(const UString &a, const wchar_t *b)
{
return StringCompare(a, b) < 0;
}
GXDLCODE_API int operator<=(const UString &a, const UString &b)
{
return StringCompare(a, b) <= 0;
}
GXDLCODE_API int operator<=(const char *a, const UString &b)
{
return StringCompare(a, b) <= 0;
}
GXDLCODE_API int operator<=(const UString &a, const char *b)
{
return StringCompare(a, b) <= 0;
}
GXDLCODE_API int operator<=(const wchar_t *a, const UString &b)
{
return StringCompare(a, b) <= 0;
}
GXDLCODE_API int operator<=(const UString &a, const wchar_t *b)
{
return StringCompare(a, b) <= 0;
}
GXDLCODE_API int StringCompare(const UStringw &a, const UStringw &b)
{
return a.StringCompare(b);
}
GXDLCODE_API int StringCompare(const char *s, const UStringw &b)
{
UStringw a(s);
return a.StringCompare(b);
}
GXDLCODE_API int StringCompare(const UStringw &a, const char *s)
{
return a.StringCompare(s);
}
GXDLCODE_API int StringCompare(const wchar_t *s, const UStringw &b)
{
UStringw a(s);
return a.StringCompare(b);
}
GXDLCODE_API int StringCompare(const UStringw &a, const wchar_t *s)
{
return a.StringCompare(s);
}
GXDLCODE_API UStringw operator+(const UStringw &a, const UStringw &b)
{
UStringw buf(a);
buf += b;
return buf;
}
GXDLCODE_API UStringw operator+(const char *s, const UStringw &b)
{
UStringw buf(s);
buf += b;
return buf;
}
GXDLCODE_API UStringw operator+(const UStringw &a, const char *s)
{
UStringw buf(a);
buf.Cat(s); // Append "s" to the end of the object
return buf;
}
GXDLCODE_API UStringw operator+(const wchar_t *s, const UStringw &b)
{
UStringw buf(s);
buf += b;
return buf;
}
GXDLCODE_API UStringw operator+(const UStringw &a, const wchar_t *s)
{
UStringw buf(a);
buf.Cat(s); // Append "s" to the end of the object
return buf;
}
GXDLCODE_API int operator==(const UStringw &a, const UStringw &b)
{
return StringCompare(a, b) == 0;
}
GXDLCODE_API int operator==(const char *a, const UStringw &b)
{
return StringCompare(a, b) == 0;
}
GXDLCODE_API int operator==(const UStringw &a, const char *b)
{
return StringCompare(a, b) == 0;
}
GXDLCODE_API int operator==(const wchar_t *a, const UStringw &b)
{
return StringCompare(a, b) == 0;
}
GXDLCODE_API int operator==(const UStringw &a, const wchar_t *b)
{
return StringCompare(a, b) == 0;
}
GXDLCODE_API int operator!=(const UStringw &a, const UStringw &b)
{
return StringCompare(a, b) != 0;
}
GXDLCODE_API int operator!=(const char *a, const UStringw &b)
{
return StringCompare(a, b) != 0;
}
GXDLCODE_API int operator!=(const UStringw &a, const char *b)
{
return StringCompare(a, b) != 0;
}
GXDLCODE_API int operator!=(const wchar_t *a, const UStringw &b)
{
return StringCompare(a, b) != 0;
}
GXDLCODE_API int operator!=(const UStringw &a, const wchar_t *b)
{
return StringCompare(a, b) != 0;
}
GXDLCODE_API int operator>(const UStringw &a, const UStringw &b)
{
return StringCompare(a, b) > 0;
}
GXDLCODE_API int operator>(const char *a , const UStringw &b)
{
return StringCompare(a, b) > 0;
}
GXDLCODE_API int operator>(const UStringw &a, const char *b)
{
return StringCompare(a, b) > 0;
}
GXDLCODE_API int operator>(const wchar_t *a , const UStringw &b)
{
return StringCompare(a, b) > 0;
}
GXDLCODE_API int operator>(const UStringw &a, const wchar_t *b)
{
return StringCompare(a, b) > 0;
}
GXDLCODE_API int operator>=(const UStringw &a, const UStringw &b)
{
return StringCompare(a, b) >= 0;
}
GXDLCODE_API int operator>=(const char *a, const UStringw &b)
{
return StringCompare(a, b) >= 0;
}
GXDLCODE_API int operator>=(const UStringw &a, const char *b)
{
return StringCompare(a, b) >= 0;
}
GXDLCODE_API int operator>=(const wchar_t *a, const UStringw &b)
{
return StringCompare(a, b) >= 0;
}
GXDLCODE_API int operator>=(const UStringw &a, const wchar_t *b)
{
return StringCompare(a, b) >= 0;
}
GXDLCODE_API int operator<(const UStringw &a, const UStringw &b)
{
return StringCompare(a, b) < 0;
}
GXDLCODE_API int operator<(const char *a, const UStringw &b)
{
return StringCompare(a, b) < 0;
}
GXDLCODE_API int operator<(const UStringw &a, const char *b)
{
return StringCompare(a, b) < 0;
}
GXDLCODE_API int operator<(const wchar_t *a, const UStringw &b)
{
return StringCompare(a, b) < 0;
}
GXDLCODE_API int operator<(const UStringw &a, const wchar_t *b)
{
return StringCompare(a, b) < 0;
}
GXDLCODE_API int operator<=(const UStringw &a, const UStringw &b)
{
return StringCompare(a, b) <= 0;
}
GXDLCODE_API int operator<=(const char *a, const UStringw &b)
{
return StringCompare(a, b) <= 0;
}
GXDLCODE_API int operator<=(const UStringw &a, const char *b)
{
return StringCompare(a, b) <= 0;
}
GXDLCODE_API int operator<=(const wchar_t *a, const UStringw &b)
{
return StringCompare(a, b) <= 0;
}
GXDLCODE_API int operator<=(const UStringw &a, const wchar_t *b)
{
return StringCompare(a, b) <= 0;
}
#if defined (__wxWIN201__)
UString &UString::operator=(const wxString &s)
{
Clear();
SetString(s.c_str());
return *this;
}
UStringw &UStringw::operator=(const wxString &s)
{
Clear();
SetString(s.c_str());
return *this;
}
UStringB& UStringB::operator>>(wxString &s)
{
if(!sptr) {
s = UStringNULLPtr::UStringNUllStr;
return *this;
}
if(!is_unicode()) {
s = (char *)sptr;
}
else {
char *nsptr = Unicode2ASCII((wchar_t *)sptr, s_length);
if(!nsptr) return *this;
s = nsptr;
delete[] nsptr;
}
return *this;
}
#endif
#if defined (__wxWIN291__)
UString &UString::operator=(const wxString &s)
{
Clear();
SetString((const char *)s.c_str());
return *this;
}
UStringw &UStringw::operator=(const wxString &s)
{
Clear();
SetString((const char *)s.c_str());
return *this;
}
UStringB& UStringB::operator>>(wxString &s)
{
if(!sptr) {
s = UStringNULLPtr::UStringNUllStr;
return *this;
}
if(!is_unicode()) {
s = (char *)sptr;
}
else {
char *nsptr = Unicode2ASCII((wchar_t *)sptr, s_length);
if(!nsptr) return *this;
s = nsptr;
delete[] nsptr;
}
return *this;
}
#endif
#if defined (__wxWIN302__)
UString &UString::operator=(const wxString &s)
{
Clear();
SetString((const char *)s.c_str());
return *this;
}
UStringw &UStringw::operator=(const wxString &s)
{
Clear();
SetString((const char *)s.c_str());
return *this;
}
UStringB& UStringB::operator>>(wxString &s)
{
if(!sptr) {
s = UStringNULLPtr::UStringNUllStr;
return *this;
}
if(!is_unicode()) {
s = (char *)sptr;
}
else {
char *nsptr = Unicode2ASCII((wchar_t *)sptr, s_length);
if(!nsptr) return *this;
s = nsptr;
delete[] nsptr;
}
return *this;
}
#endif
void UStringB::WholeNumber(unsigned long bytes)
// Public member function used to insert a comma
// separated whole number into a string.
{
char sbuf[81];
sprintf(sbuf, "%u", (unsigned int)bytes);
unsigned start_len = length();
*this += sbuf;
unsigned stop_len = length();
unsigned slen = stop_len - start_len;
stop_len -= slen;
unsigned offset = length();
unsigned num_commas = 0;
if(slen > 3) num_commas = slen/3;
for(unsigned i = 0; i < num_commas; i ++) {
offset -= 3;
if(offset == stop_len) break;
InsertAt(offset, ",", 1);
}
}
void UStringB::SHN(unsigned long bytes)
{
double shn_n; // Shorthand notation number
char shn_c[2] = { '\0', '\0' }; // Shorthand notation nomenclature
char sbuf[81];
int i;
if(bytes > 1000) { // More than 1K bytes
if(bytes < (1000*1000)) { // Less than 1M
shn_n = (double)bytes/double(1000);
shn_c[0] = 'K';
}
else if(bytes < ((1000*1000)*1000)) { // Less than 1G
shn_n = (double)bytes/double(1000*1000);
shn_c[0] = 'M';
}
else { // 1G or greater
shn_n = (double)bytes/double((1000*1000)*1000);
shn_c[0] = 'G';
}
}
else {
sprintf(sbuf, "%u", (unsigned int)bytes);
if((output_width > 0) && ((int)strlen(sbuf) < output_width)) {
i = output_width - strlen(sbuf);
while(i--) *this += output_fill;
}
*(this) += sbuf;
return;
}
sprintf(sbuf, "%.2f", shn_n);
// Append the string
i = strlen(sbuf);
while(i--) {
if((sbuf[i] == '0') || (sbuf[i] == '.')) {
// Remove all trailing zeros and trailing dots
sbuf[i] = 0;
}
else {
// Break on the first non zero or non dot
break;
}
}
if((output_width > 0) && ((int)strlen(sbuf) < output_width)) {
i = (output_width-1) - strlen(sbuf);
while(i--) *this += output_fill;
}
*(this) += sbuf;
*(this) += shn_c;
}
unsigned UStringB::TrimLeading(const char c)
// Filter all leading characters from a string.
// Returns the number of characters filtered.
{
if((sptr == 0) || (s_length == 0)) return 0; // Check for null pointers
unsigned i, num_l_chars = 0;
if(!is_unicode()) {
char *start = (char *)sptr;
for(i = 0; i < s_length; i++) {
if(start[i] != c) break;
num_l_chars++;
}
if(num_l_chars > 0) DeleteAt(0, num_l_chars);
return num_l_chars;
}
else {
wchar_t *start = (wchar_t *)sptr;
for(i = 0; i < s_length; i++) {
#if defined (__PCLINT_CHECK__)
if(start[i] != c) break;
#else
if(start[i] != (wchar_t)c) break;
#endif
num_l_chars++;
}
if(num_l_chars > 0) DeleteAt(0, num_l_chars);
return num_l_chars;
}
}
unsigned UStringB::TrimTrailing(const char c)
// Filter all trailing characters from a string.
// Returns the number of characters filtered.
{
if((sptr == 0) || (s_length == 0)) return 0; // Check for null pointers
if(!is_unicode()) {
char *start = (char *)sptr;
unsigned i, num_t_chars = 0;
for(i = (s_length - 1); i != 0; i--) {
if(start[i] != c) break;
num_t_chars++;
}
if(num_t_chars > 0) DeleteAt((s_length - num_t_chars), num_t_chars);
return num_t_chars;
}
else {
wchar_t *start = (wchar_t *)sptr;
unsigned i, num_t_chars = 0;
for(i = (s_length - 1); i != 0; i--) {
#if defined (__PCLINT_CHECK__)
if(start[i] != c) break;
#else
if(start[i] != (wchar_t)c) break;
#endif
num_t_chars++;
}
if(num_t_chars > 0) DeleteAt((s_length - num_t_chars), num_t_chars);
return num_t_chars;
}
}
unsigned UStringB::TrimLeading(const wchar_t c)
// Filter all leading characters from a string.
// Returns the number of characters filtered.
{
if((sptr == 0) || (s_length == 0)) return 0; // Check for null pointers
unsigned i, num_l_chars = 0;
if(!is_unicode()) {
char *start = (char *)sptr;
for(i = 0; i < s_length; i++) {
if(start[i] != (char)c) break;
num_l_chars++;
}
if(num_l_chars > 0) DeleteAt(0, num_l_chars);
return num_l_chars;
}
else {
wchar_t *start = (wchar_t *)sptr;
for(i = 0; i < s_length; i++) {
if(start[i] != c) break;
num_l_chars++;
}
if(num_l_chars > 0) DeleteAt(0, num_l_chars);
return num_l_chars;
}
}
unsigned UStringB::TrimTrailing(const wchar_t c)
// Filter all trailing characters from a string.
// Returns the number of characters filtered.
{
if((sptr == 0) || (s_length == 0)) return 0; // Check for null pointers
if(!is_unicode()) {
char *start = (char *)sptr;
unsigned i, num_t_chars = 0;
for(i = (s_length - 1); i != 0; i--) {
if(start[i] != (char )c) break;
num_t_chars++;
}
if(num_t_chars > 0) DeleteAt((s_length - num_t_chars), num_t_chars);
return num_t_chars;
}
else {
wchar_t *start = (wchar_t *)sptr;
unsigned i, num_t_chars = 0;
for(i = (s_length - 1); i != 0; i--) {
if(start[i] != c) break;
num_t_chars++;
}
if(num_t_chars > 0) DeleteAt((s_length - num_t_chars), num_t_chars);
return num_t_chars;
}
}
UString::UString(const UString &s, unsigned c_position, unsigned nchars)
// A constructor used to create a subset of this string.
{
reset_all();
// Stay inbounds
if(c_position > (s.s_length-1)) c_position = s.s_length - 1;
if((nchars + c_position) > s.s_length) nchars = s.s_length - c_position;
// Set the substring
SetString(((char *)s.sptr+c_position), nchars);
}
UString UString::Mid(unsigned c_position, unsigned nchars) const
// Returns substring starting at a specified character position,
// for a specified number of characters.
{
UString buf(*this, c_position, nchars);
return buf;
}
UString UString::Left(unsigned nchars) const
// Returns left substring for a specified number of characters
{
UString buf(*this, 0, nchars);
return buf;
}
UString UString::Right(unsigned nchars) const
// Returns right substring for a specified number of characters
{
// Stay inbounds
if(nchars > s_length) nchars = s_length;
UString buf(*this, (s_length - nchars), nchars);
return buf;
}
UStringw::UStringw(const UStringw &s, unsigned c_position, unsigned nchars)
// A constructor used to create a subset of this string.
{
reset_all();
// Stay inbounds
if(c_position > (s.s_length-1)) c_position = s.s_length - 1;
if((nchars + c_position) > s.s_length) nchars = s.s_length - c_position;
// Set the substring
SetString(((wchar_t *)s.sptr+c_position), nchars);
}
UStringw UStringw::Mid(unsigned c_position, unsigned nchars) const
// Returns substring starting at a specified character position,
// for a specified number of characters.
{
UStringw buf(*this, c_position, nchars);
return buf;
}
UStringw UStringw::Left(unsigned nchars) const
// Returns left substring for a specified number of characters
{
UStringw buf(*this, 0, nchars);
return buf;
}
UStringw UStringw::Right(unsigned nchars) const
// Returns right substring for a specified number of characters
{
// Stay inbounds
if(nchars > s_length) nchars = s_length;
UStringw buf(*this, (s_length - nchars), nchars);
return buf;
}
GXDLCODE_API int FindMatch(const UString &str, const UString &s,
int compare_case)
// Standalone function used to find matching string elements separated by
// a single "*" character placed at the beginning, middle, or end of a string.
// Returns true if a match is found or false if no matching element is found
{
if(s == "*") return 1; // Everything matches
UString pattern, p1, p2, s1, s2;
int rv = 0;
if((s[0] == '*') && (s[s.length()-1] == '*')) {
// Find everything in the middle of the string
pattern = s;
pattern.FilterChar('*');
if(compare_case) {
if(str.Find(pattern) != -1) rv = 1;
}
else {
if(str.IFind(pattern) != -1) rv = 1;
}
return rv;
}
int offset = s.Find("*");
if(offset == -1) {
// No wildcard, so search for the entire string
if(compare_case) {
return str == s;
}
else { // Do not compare the string case
s1 = str; s2 = s;
s1.ToLower(); s2.ToLower();
return s1 == s2;
}
}
else {
pattern = s;
pattern.FilterChar('*');
if(offset == 0) {
// Wild card is at the beginning of the string
s1 = str.Right(pattern.length());
if(!compare_case) {
s1.ToLower();
pattern.ToLower();
}
return s1 == pattern;
}
else if(offset > 0) {
if(offset == int(s.length()-1)) {
// Wildcard is at the end of the string
s1 = str.Left(pattern.length());
if(!compare_case) {
s1.ToLower();
pattern.ToLower();
}
return s1 == pattern;
}
else {
// Wildcard is somewhere in the middle of the string
p1 = pattern.Left(offset);
p2 = pattern.Right(pattern.length()-offset);
s1 = str.Left(offset);
s2 = str.Right(pattern.length()-offset);
if(!compare_case) {
p1.ToLower(); p2.ToLower();
s1.ToLower(); s2.ToLower();
}
return ((p1 == s1) && (p2 == s2));
}
}
}
return 0;
}
GXDLCODE_API int FindMatch(const char *str, const char *s,
int compare_case)
// Standalone function used to find matching string elements separated by
// a single "*" character placed at the beginning, middle, or end of a string.
// Returns true if a match is found or false if no matching element is found
{
UString s1(str);
UString s2(s);
return FindMatch(s1, s2, compare_case);
}
GXDLCODE_API UString *ParseStrings(const UString &input_str, const UString &delimiter, unsigned &num_arr,
int trim_spaces, int trim_quotes)
{
UString *output_arr = 0;
num_arr = 0;
UString escaped_str = input_str;
UString escape_sequence;
escape_sequence << clear << "\\" << delimiter;
UString replacement = "<< /> />";
escaped_str.ReplaceString(escape_sequence, replacement);
// We have no delimiter
if(escaped_str.Find(delimiter) == -1) {
output_arr = new UString[1];
num_arr = 1;
output_arr[0] = escaped_str;
return output_arr;
}
int offset = 0;
while(offset != -1) {
offset = escaped_str.Find(delimiter, offset);
if (offset == -1) break;
num_arr++;
offset++;
}
num_arr++; // Account for the last delimiter
output_arr = new UString[num_arr];
offset = 0;
int start = 0;
int curr_pos = 0;
while(offset != -1) {
offset = escaped_str.Find(delimiter, offset);
if (offset == -1) break;
if(offset > start) {
UString strbuf = escaped_str.Mid(start, (offset-start));
if(trim_spaces) {
strbuf.TrimLeadingSpaces();
strbuf.TrimTrailingSpaces();
}
if(trim_quotes) {
strbuf.TrimLeading('\'');
strbuf.TrimTrailing('\'');
strbuf.TrimLeading('\"');
strbuf.TrimTrailing('\"');
}
strbuf.ReplaceString(replacement, delimiter);
output_arr[curr_pos] = strbuf;
}
curr_pos++;
offset += delimiter.length();
start = offset;
}
// Account for the last delimiter
int left_over = escaped_str.length()-start;
if(left_over > 0) {
UString strbuf = escaped_str.Mid(start, left_over);
if(trim_spaces) {
strbuf.TrimLeadingSpaces();
strbuf.TrimTrailingSpaces();
}
if(trim_quotes) {
strbuf.TrimLeading('\'');
strbuf.TrimTrailing('\'');
strbuf.TrimLeading('\"');
strbuf.TrimTrailing('\"');
}
strbuf.ReplaceString(replacement, delimiter);
output_arr[num_arr-1] = strbuf;
}
return output_arr;
}
GXDLCODE_API UStringw *ParseStrings(const UStringw &input_str, const UStringw &delimiter, unsigned &num_arr,
int trim_spaces, int trim_quotes)
{
UStringw *output_arr = 0;
num_arr = 0;
wchar_t wsbuf[255];
UStringw escaped_str = input_str;
UStringw escape_sequence;
escape_sequence << clear << "\\" << delimiter;
UStringw replacement(gxLTCHAR("<< /> />", wsbuf));
escaped_str.ReplaceString(escape_sequence, replacement);
// We have no delimiter
if(escaped_str.Find(delimiter) == -1) {
output_arr = new UStringw[1];
num_arr = 1;
output_arr[0] = escaped_str;
return output_arr;
}
int offset = 0;
while(offset != -1) {
offset = escaped_str.Find(delimiter, offset);
if (offset == -1) break;
num_arr++;
offset++;
}
num_arr++; // Account for the last delimiter
output_arr = new UStringw[num_arr];
offset = 0;
int start = 0;
int curr_pos = 0;
while(offset != -1) {
offset = escaped_str.Find(delimiter, offset);
if (offset == -1) break;
if(offset > start) {
UStringw strbuf = escaped_str.Mid(start, (offset-start));
if(trim_spaces) {
strbuf.TrimLeadingSpaces();
strbuf.TrimTrailingSpaces();
}
if(trim_quotes) {
strbuf.TrimLeading('\'');
strbuf.TrimTrailing('\'');
strbuf.TrimLeading('\"');
strbuf.TrimTrailing('\"');
}
strbuf.ReplaceString(replacement, delimiter);
output_arr[curr_pos] = strbuf;
}
curr_pos++;
offset += delimiter.length();
start = offset;
}
// Account for the last delimiter
int left_over = escaped_str.length()-start;
if(left_over > 0) {
UStringw strbuf = escaped_str.Mid(start, left_over);
if(trim_spaces) {
strbuf.TrimLeadingSpaces();
strbuf.TrimTrailingSpaces();
}
if(trim_quotes) {
strbuf.TrimLeading('\'');
strbuf.TrimTrailing('\'');
strbuf.TrimLeading('\"');
strbuf.TrimTrailing('\"');
}
strbuf.ReplaceString(replacement, delimiter);
output_arr[num_arr-1] = strbuf;
}
return output_arr;
}
#ifdef __BCC32__
#pragma warn .8080
#endif
// ----------------------------------------------------------- //
// ------------------------------- //
// --------- End of File --------- //
// ------------------------------- //