From 4875a3dd9b183dcd2256e2abfc4ccf7484c233b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Wed, 7 Dec 2022 13:17:14 +0100 Subject: New upstream version 4.0.2 --- src/core/xbstring.cpp | 1839 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1839 insertions(+) create mode 100755 src/core/xbstring.cpp (limited to 'src/core/xbstring.cpp') diff --git a/src/core/xbstring.cpp b/src/core/xbstring.cpp new file mode 100755 index 0000000..872062f --- /dev/null +++ b/src/core/xbstring.cpp @@ -0,0 +1,1839 @@ +/* xbstring.cpp + +XBase64 Software Library + +Copyright (c) 1997,2003,2014,2021,2022 Gary A Kunkel + +The xb64 software library is covered under the terms of the GPL Version 3, 2007 license. + +Email Contact: + + XDB-devel@lists.sourceforge.net + XDB-users@lists.sourceforge.net + +*/ + +//#ifdef __GNU LesserG__ +// #pragma implementation "xbstring.h" +//#endif + +#include "xbase.h" + + +namespace xb{ + +XBDLLEXPORT const char * xbString::NullString = ""; +XBDLLEXPORT char xbString::cJunkBuf; + +/************************************************************************/ +//! @brief Destructor + +xbString::~xbString(){ + if (data != NULL) + free(data); + +} + +/************************************************************************/ +//! @brief Constructor +/*! + \param ulSize - Allocation size. The allocation size is normally handled internally + by the class, but it can be set in this constructor. +*/ +xbString::xbString(xbUInt32 ulSize) { + data = (char *)calloc(1, ulSize); + this->size = ulSize; +// memset( data, 0x00, ulSize ); - redundant, initialized by calloc +} +/************************************************************************/ +//! @brief Constructor +/*! + \param c - Initialize string to c. +*/ +xbString::xbString(char c) { + data = (char *)calloc(1, 2); + data[0] = c; + data[1] = 0; + size = 2; +} +/************************************************************************/ +//! @brief Constructor +/*! + \param s - Initialize string to s. +*/ +xbString::xbString( const char *s ) { + + if( s == NULL ){ + size = 0; + data = NULL; + } else { + size = (xbUInt32) (strlen(s) + 1 ); + data = (char *) calloc( 1, size ); + xb_strcpy( data, s ); + } + // ctor(s); +} +/************************************************************************/ +//! @brief Constructor +/*! + \param d - Initiailize string to d. +*/ +xbString::xbString( xbDouble d ) { + data = NULL; + size = 0; + Sprintf("%f", d); +} +/************************************************************************/ +//! @brief Constructor +/*! + \param s Initialize string to s. + \param ulMaxLen Maximum length of string. Truncate any characters greater than ulMaxLen. +*/ +xbString::xbString( const char *s, xbUInt32 ulMaxLen ) { + xbUInt32 sSize = (xbUInt32) strlen( s ); + if( sSize < ulMaxLen ) + size = sSize; + else + size = ulMaxLen; + data = (char *)calloc(1, size+1); + for( xbUInt32 i = 0; i < size; i++ ) + data[i] = s[i]; + data[size] = '\0'; + size++; // account for null trailing byte + return; +} +/************************************************************************/ +//! @brief Constructor +/*! + \param s Initialize string to s. +*/ +xbString::xbString( const xbString &s ) { + ctor(s.Str()); +} + +/************************************************************************/ +//! @brief Operator const char * +/*! + \returns Pointer to string data. +*/ +xbString::operator const char *() const { + return data ? data : NullString; +} + +/************************************************************************/ +//! @brief Set operator = +/*! + \param s - Set the string to the string on the right of the equal sign. +*/ +xbString &xbString::operator=( const xbString &s ) { + return Set(s); +} +/************************************************************************/ +//! @brief Set operator = +/*! + \param s - Set the string to the string on the right of the equal sign. +*/ +xbString &xbString::operator=( const char *s ) { + return Set(s); +} + +/************************************************************************/ +//! @brief Stream insertion operator << +/*! + std::cout << MyString << std::endl; + + \param os Output stream + \param s String to send to output stream +*/ +std::ostream& operator<< ( std::ostream& os, const xbString & s ) { + return os << s.Str(); +} +/************************************************************************/ +//! @brief Append operator += +/*! + \param s - Append s to the string. +*/ +xbString &xbString::operator+=( const xbString &s ) { + + if (s.IsNull()) + return (*this); + + xbUInt32 Len = s.Len(); + xbUInt32 oldLen = this->Len(); + xbUInt32 newLen = Len + oldLen; + + data = (char *)realloc(data, newLen+1); + if( !data ) + return (*this); + + if(oldLen == 0) + data[0] = 0; + + char *t = data; + t+= oldLen; + for( xbUInt32 i = 0; i < Len; i++ ) + *t++ = s.GetCharacter(i+1); + + data[newLen] = '\0'; + size += Len; + + return (*this); +} +/************************************************************************/ +//! @brief Append operator += +/*! + \param s - Append s to the string. +*/ +xbString &xbString::operator+=( const char *s ) { + + if (s == NULL) + return (*this); + xbUInt32 Len = (xbUInt32) strlen(s); + xbUInt32 oldLen = this->Len(); + xbUInt32 newLen = Len + oldLen; + data = (char *)realloc(data, newLen+1); + if(oldLen == 0) + data[0] = 0; + for( xbUInt32 i = 0; i < Len; i++ ) + data[i+oldLen] = s[i]; + data[newLen] = '\0'; + size += Len; + return (*this); +} +/************************************************************************/ +//! @brief Append operator += +/*! + \param c - Append c to the string. +*/ +xbString &xbString::operator+=( char c ) { + xbUInt32 Len = 1; + xbUInt32 oldLen = this->Len(); + data = (char *)realloc(data, oldLen+Len+1); + data[oldLen] = c; + data[oldLen+1] = 0; + size++; + return (*this); +} +/************************************************************************/ +//! @brief Append operator -= +/*! + Append s to the right of this string, right trimming both strings. + \param s - Append s to the right of the string value. +*/ +xbString &xbString::operator-=( const xbString &s ) { + + Rtrim(); + if (s.IsNull()) + return (*this); + xbUInt32 Len = s.Len(); + xbUInt32 oldLen = this->Len(); + xbUInt32 newLen = Len + oldLen; + + data = (char *)realloc(data, newLen+1); + if(oldLen == 0) + data[0] = 0; + + for( xbUInt32 i = 0; i < Len; i++ ) + data[i+oldLen] = s.GetCharacter(i+1); + + data[newLen] = '\0'; + size += Len; + Rtrim(); + return (*this); +} +/************************************************************************/ +//! @brief Append operator -= +/*! + Append s to the right of this string, right trimming both strings. + \param s - Append s to the right of the string value. +*/ +xbString &xbString::operator-=(const char *s) { + + Rtrim(); + if (s == NULL) + return (*this); + xbUInt32 Len = (xbUInt32) strlen(s); + xbUInt32 oldLen = this->Len(); + xbUInt32 newLen = Len + oldLen; + + data = (char *)realloc(data, newLen+1); + + if(oldLen == 0) + data[0] = 0; + + for( xbUInt32 i = 0; i < Len; i++ ) + data[i+oldLen] = s[i]; + data[newLen] = '\0'; + + size += Len; + Rtrim(); + return (*this); +} +/************************************************************************/ +//! @brief Append operator -= +/*! + Append c to the right of this string, trimming right space on this string first. + \param c - Append s to the right of the string value. +*/ +xbString &xbString::operator-=(const char c) { + Rtrim(); + xbUInt32 oldSize = size; + size += 1; + data = (char *)realloc( data, size ); + if( oldSize == 0 ) data[0] = 0; + data[size-2] = c; + data[size-1] = 0; + Trim(); + return (*this); +} +/************************************************************************/ +//! @brief Concatonate operator - +/*! + Concatonate left string with right string returning reference to new string. + Both strings are trimmed. + + \param s1 Right string operator. +*/ +xbString xbString::operator-(const xbString &s1) { + xbString tmp( data ); + tmp -= s1; + return tmp; +} +/************************************************************************/ +//! @brief Concatonate operator + +/*! + Concatonate left string with right string returning reference to new string. + + \param s1 Right string operator. +*/ +xbString xbString::operator+( const char *s1) { + xbString tmp( data ); + tmp += s1; + return tmp; +} +/************************************************************************/ +//! @brief Concatonate operator + +/*! + Concatonate left string with right string returning reference to new string. + + \param s1 Right string operator. +*/ +xbString xbString::operator+( const xbString &s1) { + xbString tmp( data ); + tmp += s1; + return tmp; +} +/************************************************************************/ +//! @brief Concatonate operator + +/*! + Concatonate left string with right string returning reference to new string. + + \param c Right string operator. +*/ + +xbString xbString::operator+( const char c) { + xbString tmp( data ); + tmp += c; + return tmp; +} +/************************************************************************/ +//! @brief operator [] +/*! + \param n - Offset into the string of the byte to retrieve. + \returns c - The character to return from the offset within the [] brackets. +*/ +char &xbString::operator[]( xbUInt32 n ) const { + if( n > 0 && n <= size ) + return data[n-1]; + else + return cJunkBuf; +} +/************************************************************************/ +//! @brief operator [] +/*! + \param n - Offset into the string of the byte to retrieve. + \returns c - The character to return from the offset within the [] brackets. +*/ +char &xbString::operator[]( xbInt32 n ) const { + if( n > 0 && n <= (xbInt32) size ) + return data[n-1]; + else + return cJunkBuf; +} +/************************************************************************/ +//! @brief operator == +/*! + \param s String to compare + \returns xbTrue - Strings match.
+ zbFalse - Strings don't match.
+ +*/ +xbBool xbString::operator==( const xbString &s ) const { + + if( data == NULL || data[0] == 0 ) { + if( s.data == NULL || s.data[0] == 0 ) + return true; + return false; + } else { + if( s.data == NULL || s.data[0] == 0 ) + return false; + return( strcmp(data,s.data) == 0 ? xbTrue : xbFalse ); + } +} +/************************************************************************/ +//! @brief operator == +/*! + \param s String to compare + \returns xbTrue - Strings match.
+ zbFalse - Strings don't match.
+*/ +xbBool xbString::operator==( const char *s ) const { + + if (s == NULL) { + if ( data == NULL) + return true; + return false; + } + if ((s[0] == 0) && data == NULL) + return true; + if ( data == NULL) + return false; + return( strcmp( data, s) == 0 ? xbTrue : xbFalse ); +} +/************************************************************************/ +//! @brief operator != +/*! + \param s String to compare + \returns xbTrue - Strings don't match.
+ xbFalse - Strings match.
+*/ +xbBool xbString::operator!=( const xbString &s ) const { + if( data == NULL || data[0] == 0 ) { + if( s.data == NULL || s.data[0] == 0 ) + return xbFalse; // NULL != NULL + return xbTrue; // NULL != !NULL + } else { + if( s.data == NULL || s.data[0] == 0 ) + return xbTrue; // !NULL != NULL + return( strcmp( data, s.data ) != 0 ? xbTrue : xbFalse ); // !NULL != !NULL + } +} +/************************************************************************/ +//! @brief operator != +/*! + \param s String to compare + \returns xbTrue - Strings don't match.
+ zbFalse - Strings match.
+*/ +xbBool xbString::operator!=( const char *s ) const { + if( s == NULL || s[0] == 0 ) { + if( data == NULL || data[0] == 0 ) + return xbFalse; // NULL != NULL + return xbTrue; // NULL != !NULL + } else { + if( s == NULL || s[0] == 0 ) + return xbTrue; // !NULL != NULL + return( strcmp( data, s ) != 0 ? xbTrue : xbFalse ); // !NULL != !NULL + } +} +/************************************************************************/ +//! @brief operator < +/*! + \param s String to compare + \returns xbTrue - Left string is less than the right string.
+ zbFalse - Left string is not less than the right string.
+*/ +xbBool xbString::operator< ( const xbString &s ) const { + + if( data == NULL || data[0] == 0 ) { + if( s.data == NULL || s.data[0] == 0 ) + return false; + return true; + } else { + if( s.data == NULL || s.data[0] == 0 ) + return false; + return ( strcmp(data, s.data) < 0 ? xbTrue : xbFalse ); + } +} +/************************************************************************/ +//! @brief operator > +/*! + \param s String to compare + \returns xbTrue - Left string is greater than the right string.
+ zbFalse - Left string is not greater than the right string.
+*/ +xbBool xbString::operator> ( const xbString &s ) const { + if( data == NULL || data[0] == 0 ) { + if( s.data == NULL || s.data[0] == 0 ) + return false; + return false; + } else { + if( s.data == NULL || s.data[0] == 0 ) + return true; + return( strcmp(data,s.data) > 0 ? xbTrue : xbFalse ); + } +} +/************************************************************************/ +//! @brief operator <= +/*! + \param s String to compare + \returns xbTrue - Left string is less than or equal to the right string.
+ zbFalse - Left string is not less than or equal to the right string.
+*/ +xbBool xbString::operator<=( const xbString &s ) const { + if( data == NULL || data[0] == 0 ) { + if( s.data == NULL || s.data[0] == 0 ) + return true; + return true; + } else { + if( s.data == NULL || s.data[0] == 0 ) + return false; + return( strcmp(data,s.data) <= 0 ? xbTrue : xbFalse ); + } +} +/************************************************************************/ +//! @brief operator >= +/*! + \param s String to compare + \returns xbTrue - Left string is greater than or equal to the right string.
+ zbFalse - Left string is not greater than or equal to the right string.
+*/ +xbBool xbString::operator>=( const xbString &s ) const { + if( data == NULL || data[0] == 0 ) { + if( s.data == NULL || s.data[0] == 0 ) + return true; + return false; + } else { + if( s.data == NULL || s.data[0] == 0 ) + return true; + return( strcmp(data, s.data) >= 0 ? xbTrue : xbFalse ); + } +} + +/************************************************************************/ +//! @brief Add a prefixing back slash to specified characters in the string. +/*! + \param c Character to prefix with a backslash. + \returns Reference to this string. +*/ +xbString &xbString::AddBackSlash( char c ) { + + xbUInt32 lCnt = CountChar( c ); + if( lCnt == 0 ) + return *this; + char *p; + if(( p = (char *)calloc( 1, size + lCnt )) == NULL ) + return *this; + + char *p2 = p; + for( xbUInt32 lS = 0; lS < size; lS++ ){ + if( data[lS] == c ) + *p2++ = '\\'; + *p2++ = data[lS]; + } + if( data ) + free( data ); + data = p; + size += lCnt; + return *this; +} +/************************************************************************/ +//! @brief Append data to string. +/*! + \param s String data to append. + \returns Reference to this string. +*/ +xbString &xbString::Append( const xbString &s ) { + *this += s; + return *this; +} + +/************************************************************************/ +//! @brief Append data to string. +/*! + \param s String data to append. + \returns Reference to this string. +*/ +xbString &xbString::Append( const char *s ) { + *this += s; + return *this; +} +/************************************************************************/ +//! @brief Append data to string. +/*! + \param c String data to append. + \returns Reference to this string. +*/ +xbString &xbString::Append( char c ) { + *this += c; + return *this; +} +/************************************************************************/ +//! @brief Append data to string. +/*! + \param s String data to append. + \param ulByteCount Maximum number of bytes to append. + \returns Reference to this string. +*/ +xbString &xbString::Append( const char *s, xbUInt32 ulByteCount ) { + + if (s == NULL) return (*this); + xbUInt32 oldLen = this->Len(); + xbUInt32 newLen = ulByteCount + oldLen; + + data = (char *)realloc(data, newLen+1); + + if(oldLen == 0) + data[0] = 0; + + for( xbUInt32 i = 0; i < ulByteCount; i++ ) + data[i+oldLen] = s[i]; + + data[newLen] = '\0'; + size += ulByteCount; + return (*this); +} + +/************************************************************************/ +//! @brief Assign portion of string. +/*! + \param sStr - Source string for copy operation. sStr needs to be a Null terminated string. + \param ulStartPos - Starting position within source string. + \param ulCopyLen - Length of data to copy. + \returns Reference to this string. +*/ +xbString &xbString::Assign(const char * sStr, xbUInt32 ulStartPos, xbUInt32 ulCopyLen){ + if(data){ + free(data); + data = 0; + size = 0; + } + xbUInt32 lLen = (xbUInt32) strlen( sStr ); + if( ulStartPos > lLen ){ + size = 0; + return( *this ); + } + if((( ulCopyLen - 1) + ulStartPos ) > lLen ) + ulCopyLen = lLen - ulStartPos + 1; + data = (char *)calloc(1, ulCopyLen + 1); + size = ulCopyLen; + for( xbUInt32 i = 0; i < ulCopyLen; i++ ) + data[i] = sStr[i + ulStartPos - ((xbUInt32) 1)]; + data[ulCopyLen] = '\0'; + return (*this); +} +/************************************************************************/ +//! @brief Assign portion of string. +/*! + \param sStr - Source string for copy operation. sStr needs to be a Null terminated string. + \param ulStartPos - Starting position within source string. + \returns Reference to this string. +*/ +xbString &xbString::Assign(const char * sStr, xbUInt32 ulStartPos){ + if(data){ + free(data); + data = 0; + size = 0; + } + xbUInt32 ulSrcLen = (xbUInt32) strlen( sStr ); + if( ulStartPos > ulSrcLen ){ + size = 0; + return( *this ); + } + xbUInt32 ulCopyLen; + ulCopyLen = ulSrcLen - ulStartPos + 1; + data = (char *)calloc(1, ulCopyLen + 1); + size = ulCopyLen; + for( xbUInt32 i = 0; i < ulCopyLen; i++ ) + data[i] = sStr[i + ulStartPos - ((xbUInt32) 1)]; + data[ulCopyLen] = '\0'; + return (*this); +} + +/************************************************************************/ +//! @brief Assign portion of string. +/*! + \param sStr - Source string for copy operation. sStr needs to be a Null terminated string. + \param ulStartPos - Starting position within source string. + \param ulCopyLen - Length of data to copy. + \returns Reference to this string. +*/ +xbString &xbString::Assign(const xbString& sStr, xbUInt32 ulStartPos, xbUInt32 ulCopyLen){ + if(data){ + free(data); + data = 0; + size = 0; + } + xbUInt32 ulSrcLen = sStr.Len(); + if( ulStartPos > ulSrcLen ){ + size = 0; + return( *this ); + } + if((( ulCopyLen - 1) + ulStartPos ) > ulSrcLen ) + ulCopyLen = ulSrcLen - ulStartPos + 1; + data = (char *)calloc(1, ulCopyLen + 1); + size = ulCopyLen; + for( xbUInt32 i = 0; i < ulCopyLen; i++ ) + data[i] = sStr[i + ulStartPos]; + data[ulCopyLen] = '\0'; + return (*this); +} +/************************************************************************/ +//! @brief Assign portion of string. +/*! + \param sStr - Source string for copy operation. sStr needs to be a Null terminated string. + \param ulStartPos - Starting position within source string. + \returns Reference to this string. +*/ +xbString &xbString::Assign(const xbString& sStr, xbUInt32 ulStartPos){ + if(data){ + free(data); + data = 0; + size = 0; + } + xbUInt32 ulSrcLen = sStr.Len(); + if( ulStartPos > ulSrcLen ){ + size = 0; + return( *this ); + } + xbUInt32 ulCopyLen; + ulCopyLen = ulSrcLen - ulStartPos + 1; + data = (char *)calloc(1, ulCopyLen + 1); + size = ulCopyLen; + for( xbUInt32 i = 0; i < ulCopyLen; i++ ) + data[i] = sStr[i + ulStartPos]; + data[ulCopyLen] = '\0'; + return (*this); +} +/************************************************************************/ +//! @brief Copy a string +/*! + \returns xbString. +*/ +xbString xbString::Copy() const { + return( *this ); +} +/************************************************************************/ +//! @brief Count the number of characters in the string. +/*! + \param c Character to count. + \param iOpt 0 - Count the number of characters.
+ 1 - Count the number of characters not between single or double quotes. + \returns The number of characters. +*/ +xbUInt32 xbString::CountChar( char c, xbInt16 iOpt ) const { + if( iOpt == 0 ) + return CountChar( c ); + else{ + xbBool bSingleQuote = xbFalse; + xbBool bDoubleQuote = xbFalse; + char cPrevChar = 0x00; + xbUInt32 i,j; + for( i = 0, j = 0; i < size; i++ ){ + if( bSingleQuote && data[i] == '\'' && cPrevChar != '\\' ){ + bSingleQuote = xbFalse; + } + else if( bDoubleQuote && data[i] == '"' && cPrevChar != '\\' ){ + bDoubleQuote = xbFalse; + } + else if( data[i] == '\'' && cPrevChar != '\\' && !bDoubleQuote ){ + bSingleQuote = xbTrue; + } + else if( data[i] == '"' && cPrevChar != '\\' && !bSingleQuote ){ + bDoubleQuote = xbTrue; + } + else if( !bDoubleQuote && !bSingleQuote && data[i] == c ){ + j++; + } + cPrevChar = data[i]; + } + return j; + } +} +/************************************************************************/ +//! @brief Count the number of characters in the string. +/*! + \param c Character to count. + \returns The number of characters. +*/ +xbUInt32 xbString::CountChar( char c ) const { + xbUInt32 i,j; + for( i = 0,j = 0; i < size; i++ ) + if( data[i] == c ) + j++; + return j; +} +/************************************************************************/ +void xbString::ctor( const char *s ) { + + // this routine assumes it was called by one of the constructors. + + if (s == NULL) { + data = NULL; + size = 0; + return; + } + + size = (xbUInt32) (strlen(s) + 1); + data = (char *) calloc( 1, size); + + xb_strcpy(data, s); +} +/************************************************************************/ +//! @brief Convert hex character to string. +/*! + This routine converts a four byte string in the format of 0x00 to a one byte char value. + The first four bytes of the string must be in the format 0x00. + Anything past the first four bytes is disregarded. + + \param cOut Output character. + \returns XB_INVALID_PARM on error
+ XB_NO_ERROR on success. +*/ +xbInt16 xbString::CvtHexChar( char &cOut ){ + + int j, k; + char c; + + if( Len() < 4 || data[0] != '0' || (data[1]!='X' && data[1]!='x' )) + return XB_INVALID_PARM; + + c = (char) toupper( data[2] ); + j = ( c > '9' ? c - 'A' + 10 : c - '0' ); + c = (char)toupper( data[3] ); + k = ( c > '9' ? c - 'A' + 10 : c - '0' ); + j = ( j << 4 ) + k; + + cOut = ( char ) j; + return XB_NO_ERROR; +} +/************************************************************************/ +//! @brief Convert string of hex characters to string. +/*! + + This routine converts a string of four byte format of 0x00 to a string of one byte chars. + + \param sOut Output string of converted characters. + \returns XB_INVALID_PARM on error
+ XB_NO_ERROR on success. +*/ +xbInt16 xbString::CvtHexString( xbString &sOut ){ + char c; + xbString ws; + ws = data; + sOut = ""; + xbInt16 iRc; + while( ws.Len()){ + if(( iRc= ws.CvtHexChar( c )) != XB_NO_ERROR ) + return iRc; + sOut += c; + ws.Ltrunc( 4 ); + } + return XB_NO_ERROR; +} +/************************************************************************/ +//! @brief Convert string to xbUInt64 number +/*! + \param ullOut - output unsigned long long. + \returns XB_NO_ERROR +*/ +xbInt16 xbString::CvtULongLong( xbUInt64 &ullOut ){ + + // version 1 - fast, but no data checking + ullOut = 0; + char *s = data; + int i = 0; + while( *s ){ + ullOut *= 10; + ullOut += (xbUInt64) *s - '0'; + s++; + i++; + } + return XB_NO_ERROR; +} +/************************************************************************/ +//! @brief Convert string to xbInt64 number +/*! + \param llOut - output long long. + \returns XB_NO_ERROR +*/ +xbInt16 xbString::CvtLongLong( xbInt64 &llOut ){ + + // version 1 - fast, but no data checking + llOut = 0; + char *s = data; + int i = 0; + while( *s ){ + llOut *= 10; + llOut += (xbInt64) *s - '0'; + s++; + i++; + } + return XB_NO_ERROR; +} + +/************************************************************************/ +#ifdef XB_DEBUG_SUPPORT +void xbString::Dump( const char * title, xbInt16 iHexOption ) const { + fprintf(stdout, "%s StringSize[%d] DataLen=[%d] data=[%s]\n", title, size, Len(), data ); + if( iHexOption ){ + std::cout << "Hex values" << std::endl; + for( xbUInt32 i = 0; i < strlen( data ); i++ ) + printf( " %x", data[i] ); + std::cout << std::endl; + } +} +void xbString::Dump( const char * title ) const { + Dump( title, 0 ); +} + +void xbString::DumpHex( const char * title ) const { + Dump( title, 1 ); +} +#endif + +/************************************************************************/ +//! @brief Extract an element out of a delimited string. +/*! + \param pSrc Source string. + \param cDelim Delimiter. + \param lSkipCnt Number of delimiters to skip. + \param iOpt 0 - ignore single and double quotes.
+ 1 - ignore delimiters between single or double quotes. + \returns Reference to string extracted from element. +*/ +xbString &xbString::ExtractElement( const char *pSrc, char cDelim, xbUInt32 lSkipCnt, xbInt16 iOpt ) +{ + /* opt values + 0 - ignore single and double quotes + 1 - ignore delimiters between single or double quotes + */ + + xbUInt32 lLen; + xbUInt32 lCurCnt = 0; + xbBool bInSingleQuotes = xbFalse; + xbBool bInDoubleQuotes = xbFalse; + char cPrevChar = 0x00; + const char *s = pSrc; + const char *pAnchor; + + /* skip past skipcnt delimiters */ + while( *s && lCurCnt < (lSkipCnt-1) ){ + if( iOpt == 0 ){ + if( *s == cDelim ) + lCurCnt++; + } else { + if( *s == cDelim && !bInSingleQuotes && !bInDoubleQuotes ){ + lCurCnt++; + } else if( *s == '\'' && !bInDoubleQuotes && cPrevChar != '\\' ){ + if( bInSingleQuotes == xbTrue ) + bInSingleQuotes = xbFalse; + else + bInSingleQuotes = xbTrue; + } else if( *s == '"' && !bInSingleQuotes && cPrevChar != '\\' ){ + if( bInDoubleQuotes == xbTrue ) + bInDoubleQuotes = xbFalse; + else + bInDoubleQuotes = xbTrue; + } + } + cPrevChar = *s; + s++; + } + + /* at the beginning of the field */ + pAnchor = s; + xbBool bDone = xbFalse; + while( *s && !bDone ){ + if( iOpt == 0 ){ + if( *s == cDelim ) + bDone = xbTrue; + } else { + if( *s == cDelim && !bInSingleQuotes && !bInDoubleQuotes ){ + bDone = xbTrue; + } else if( *s == '\'' && !bInDoubleQuotes && cPrevChar != '\\' ){ + if( bInSingleQuotes == xbTrue ) + bInSingleQuotes = xbFalse; + else + bInSingleQuotes = xbTrue; + } else if( *s == '"' && !bInSingleQuotes && cPrevChar != '\\' ){ + if( bInDoubleQuotes == xbTrue ) + bInDoubleQuotes = xbFalse; + else + bInDoubleQuotes = xbTrue; + } + } + cPrevChar = *s; + s++; + } + + // if at end of string, go back one and drop the delimiter + if( *s ) s--; + + lLen = (xbUInt32)(s - pAnchor); + + /* copy data */ + data = (char *) realloc( data, lLen+1 ); + memcpy( data, pAnchor, lLen ); + data[lLen] = 0; + this->size = lLen+1; + return *this; +} + +/************************************************************************/ +//! @brief Get a character by position +/*! + \param n - Position in string to extract. First position is 1 (not 0). + \returns Character from position n, or null. +*/ +char xbString::GetCharacter( xbUInt32 n ) const { + if( n > 0 && n <= size ) + return data[n-1]; + else + return 0x00; +} +/************************************************************************/ +//! @brief Get the position of the last occurrence of a given character. +/*! + \param c - Character to search for. + \returns Last position of character in the string. +*/ +xbUInt32 xbString::GetLastPos(char c) const { + + if (data == NULL) + return 0; + + char *p = data; + xbUInt32 iPos = 0; + xbUInt32 hPos = 0; + while( *p && iPos++ < ( size - 1 )){ + if( *p == c ) + hPos = iPos; + p++; + } + if( hPos ) + return hPos; + else + return 0; +} +/************************************************************************/ +//! @brief Get the position of the last occurrence of a given string. +/*! + \param s - String to search for. + \returns Last position of character in the string. +*/ +xbUInt32 xbString::GetLastPos(const char* s) const{ + + if (data == NULL) + return 0; + + char *p = data; + char *saveP = NULL; + while( p ){ + p = strstr( p, s); + if( p ){ + saveP = p; + p++; + } + } + if (saveP == NULL) + return 0; + return (xbUInt32)(saveP - data) + 1; +} +/************************************************************************/ +//! @brief Get the path separator out of the string. +/*! + \returns Char value containing either / or \ depending on OS. +*/ +char xbString::GetPathSeparator() const { + + if (data == NULL) + return 0x00; + char *p = data; + while( *p ){ + if( *p == '\\' || *p == '/' ) + return *p; + else + p++; + } + return 0x00; +} + +/************************************************************************/ +//! @brief Retrieve the size of the string buffer. +/*! + \returns Size of string buffer including the null terminating byte. +*/ +xbUInt32 xbString::GetSize() const { + return size; +} + +/************************************************************************/ +//! @brief Determine if the string has any alpha characters +/*! + \returns xbTrue - String contains one or more aloha characters.
+ xbFalse - String contains no alpha characters. +*/ +xbBool xbString::HasAlphaChars() const { + for( xbUInt32 i = 0; i < size; i++ ) + if( isalpha( data[i] )) + return xbTrue; + return xbFalse; +} + + +/************************************************************************/ +//! @brief Determine if string is empty +/*! + \returns xbTrue if string is empty.
+ xbFalse if string is not empty. +*/ +xbBool xbString::IsEmpty() const { + if( data == NULL ) + return true; + if( data[0] == 0 ) + return xbTrue; + return xbFalse; +} + +/************************************************************************/ +//! @brief Determine if string is NULL +/*! + \returns xbTrue if string is NULL.
+ xbFalse if string is not NULL. +*/ +xbBool xbString::IsNull() const { + return( data == NULL ); +} + + +/************************************************************************/ +//! @brief Retain left part of string, drop rightmost characters. +/*! + \param ulLen New string length, truncate rightmost excess. + \returns Reference to string. +*/ +xbString &xbString::Left( xbUInt32 ulLen ) { + return Mid( 1, ulLen ); +} + +/************************************************************************/ +//! @brief Retrieve length of current string. +/*! + \returns String length, excluding the terminating null byte. +*/ +// return length of string +xbUInt32 xbString::Len() const { + return( data ? (xbUInt32) strlen(data) : 0 ); +} + +/************************************************************************/ +//! @brief Left trim white space from string. +/*! + \returns Reference to this string. +*/ +xbString &xbString::Ltrim(){ + + if( !data ) + return *this; + + char *p = data; + if( !*p || (*p && *p != ' ') ) + return *this; /* nothing to do */ + + xbUInt32 s = 0; + while( *p && *p == ' ' ){ + p++; + s++; + size--; + } + xbUInt32 i; + for( i = 0; i < size; i++ ) + data[i] = data[i+s]; + data[i] = 0x00; + data = (char *) realloc( data, size ); + return *this; +} + +/************************************************************************/ +//! @brief Left truncate string +/*! + \param ulCnt Number of bytes to remove from the left. + \returns Reference to this string. +*/ +xbString &xbString::Ltrunc( xbUInt32 ulCnt ){ + // left truncate cnt bytes + + char * ndata; + char * p; + if( ulCnt >= size ){ + if( size > 0 ){ + free( data ); + data = NULL; + size = 0; + } + return *this; + } + ndata = (char *) calloc( 1, size - ulCnt ); + p = data; + p += ulCnt; + xb_strcpy( ndata, p ); + free( data ); + data = ndata; + size = size - ulCnt; + return *this; +} + +/************************************************************************/ +//! @brief Extract portion of data from string +/*! + \param ulStartPos Starting position + \param ulTargLen Length + \returns Reference to string +*/ +xbString &xbString::Mid( xbUInt32 ulStartPos, xbUInt32 ulTargLen ){ + + // this is a 1 based routine + if( ulStartPos == 0 ) + return *this; + + if( data == NULL ) + return( *this ); + if( data[0] == 0 ) + return( *this ); + if( ulStartPos > Len() ) + return( *this ); + char *pTarg = data; + char *pSrc = data + ulStartPos - 1; + for( xbUInt32 l = 0; l < ulTargLen; l++ ) + *pTarg++ = *pSrc++; + *pTarg = 0x00; + Resize( ulTargLen + 1 ); + return *this; +} + +/************************************************************************/ +//! @brief Left pad string +/*! + \param c Padding character. + \param ulNewLen New string length. + \returns Reference to this string. +*/ +xbString &xbString::PadLeft( char c, xbUInt32 ulNewLen ){ + + xbUInt32 srcLen; + if( data ) + srcLen = (xbUInt32) strlen( data ); + else + srcLen = 0; + + if( srcLen >= ulNewLen ) + return *this; + + char * newData = (char *) calloc( 1, ulNewLen + 1 ); + xbUInt32 i; + for( i = 0; i < ulNewLen - srcLen; i++ ) + newData[i] = c; + + char *targ = &newData[i]; + xb_strcpy( targ, data ); + free( data ); + data = newData; + size = ulNewLen + 1; + return *this; +} + +/************************************************************************/ +//! @brief Right pad string +/*! + \param c Padding character. + \param ulNewLen New string length. + \returns Reference to this string. +*/ +xbString &xbString::PadRight( char c, xbUInt32 ulNewLen ){ + xbUInt32 srcLen = (xbUInt32) strlen( data ); + if( srcLen >= ulNewLen ) + return *this; + data = (char *) realloc( data, ulNewLen + 1 ); + xbUInt32 i; + for( i = srcLen; i < ulNewLen; i++ ) + data[i] = c; + data[i] = 0x00; + size = ulNewLen + 1; + return *this; +} + +/************************************************************************/ +//! @brief Determine position of a given character +/*! + \param c Seek character + \returns Position within string. Returns 0 if not found. +*/ +xbUInt32 xbString::Pos(char c) const { + + if (data == NULL) + return 0; + char *p = data; + xbUInt32 iPos = 0; + int iFound = 0; + while( *p && !iFound && iPos < ( size - 1 )){ + if( *p == c ) + iFound = 1; + else { + iPos++; + p++; + } + } + + if( iFound ) + return iPos + 1; + else + return 0; +} + +/************************************************************************/ +//! @brief Determine position of a given substring +/*! + \param s Substring + \returns Position within string. Returns 0 if not found. +*/ +xbUInt32 xbString::Pos(const char* s) const{ + + if (data == NULL) + return 0; + + char *p = strstr(data, s); + if ( p == NULL) + return 0; + + return (xbUInt32)(p - data + 1); +} + +/************************************************************************/ +//! @brief Insert character into string +/*! + \param ulPos Insertion position. + \param c Character to insert. + \returns Reference to this string. +*/ +xbString &xbString::PutAt(xbUInt32 ulPos, char c){ + if((ulPos-1) > Len() ) + return *this; + data[ulPos-1] = c; + return *this; +} + +/************************************************************************/ +//! @brief Remove portion of string. +/*! + \param ulStartPos Starting position for removal operation. + \param ulDelSize Size of deletion. + \returns Reference to string. +*/ +xbString &xbString::Remove(xbUInt32 ulStartPos, xbUInt32 ulDelSize ) { + if( data == NULL ) + return( *this ); + if( data[0] == 0 ) + return( *this ); + xbUInt32 srcLen = Len(); + + if( ulStartPos > srcLen || ulStartPos < 1 || ulDelSize < 1 ) + return( *this ); + + if(( ulStartPos + ulDelSize - 1) >= size ){ + data[ulStartPos-1] = 0x00; + size = ulStartPos; + return( *this ); + } + + char *t; + char *s; + t = data + (ulStartPos - 1); + s = t + ulDelSize; + size -= ulDelSize; + while( *s ) + *t++ = *s++; + *t = 0x00; + return( *this ); +} + + +/************************************************************************/ +//! @brief Resize a string +/*! + \param ulSize - New string size, including null termination byte. + \returns Reference to this string. +*/ +//the new size includes the null termination byte +xbString &xbString::Resize(xbUInt32 ulSize) { + +// data = (char *) realloc((void *) data, ulSize ); + + +// original + data = (char *)realloc(data, ulSize); + + + if( ulSize > 0 ) + data[ulSize-1] = 0; + this->size = ulSize; + return *this; +} +/************************************************************************/ +//! @brief Right trim the string. +/*! + This routine removes any trailing white space on the string. + + \returns Reference to string. +*/ +xbString &xbString::Rtrim(){ + + xbUInt32 l = Len(); + if( l == 0 ) + return *this; + l--; + + for(;;) { + if( data[l] != ' ' ) + break; + data[l] = 0; + size--; + if( l == 0 ) + break; + l--; + } + return *this; +} + +/************************************************************************/ +//! @brief Set the value of the string. +/*! + + Note: This routine fails if you try to set the string to itself or some part of itself. + + \param s Value to set the string. + \returns Reference to string. + +*/ +xbString &xbString::Set( const char *s ) { + + if(data != NULL){ + free(data); + data = NULL; + } + if(s == NULL ) { + if( data ) + free( data ); + data = NULL; + size = 0; + } else { + //data = (char *)calloc(1, strlen(s) + 1 ); + data = (char *) realloc( data, strlen(s) + 1 ); + xb_strcpy(data, s); + size = (xbUInt32) (strlen(data) + 1); + } + return (*this); +} +/************************************************************************/ +//! @brief Set the value of the string. +/*! + \param s Value to set the string. + \returns Reference to string. +*/ +xbString &xbString::Set( const xbString &s ) { + + if( s.Str() == NULL ){ + if( data ) free( data ); + data = NULL; + size = 0; + } else { + char *p = (char *) calloc( 1, s.Len() + 1 ); + xb_strcpy( p, s.Str()); + size = s.Len() + 1; + if( data ) free( data ); + data = p; + } + return (*this ); +} + +/************************************************************************/ +//! @brief Set the value of the string. +/*! + + Note: This routine fails if you try to set the string to itself or some part of itself. + + \param s Value to set the string. + \param ulSize Maximum size of resultant string. + \returns Reference to string. +*/ + +xbString &xbString::Set(const char *s, xbUInt32 ulSize) { + + if( data != NULL ) + free( data ); + + if(s == NULL) { + data = NULL; + size = 0; + return (*this); + } + + data = (char *) calloc( 1, ulSize+1 ); + char *pTarget = data; + for( xbUInt32 i = 0; i < ulSize; i++ ){ + *pTarget = *s; + pTarget++; + s++; + } + this->size = ulSize + 1; + return *this; +} + + +/************************************************************************/ +//! @brief Set the string to long integer numeric value. +/*! + \param lNum Value to set the string + \returns Reference to this string. +*/ +xbString &xbString::SetNum(xbInt32 lNum) { + Sprintf("%ld", lNum); + return *this; +} + +/************************************************************************/ +//! @brief Printf routine for formatting a string. +/*! + See documentation on the standard C printf function for how to use this. + + MyString.Sprintf( "a number %d some text %s", 100, "test text data" ); + + \param sFormat A format specifier + \returns Reference to a formatted string +*/ +xbString &xbString::Sprintf( const char *sFormat, ...) { + + xbInt32 iRc; + va_list ap; + + char *t; + +// if( data ) +// free( data ); + +#ifdef HAVE__VSNPRINTF_S_F + + va_start( ap, sFormat ); + size = (xbUInt32) _vsnprintf_s( NULL, 0, sFormat, ap ) + 1; + va_end( ap ); + + t = (char *) malloc( size ); + if( !t ){ + size = 0; + return( *this ); + } + + va_start( ap, sFormat ); + iRc = _vsnprintf_s( t, size, sFormat, ap ); + va_end( ap ); + +#else +#ifdef HAVE_VSPRINTF_S_F + + va_start( ap, sFormat ); + // size = (xbUInt32) vsprintf_s( NULL, 0, sFormat, ap ) + 1; + size = _vscprintf( sFormat, ap ) + 1; + va_end( ap ); + + t = (char *) malloc( size ); + if( !t ){ + size = 0; + return( *this ); + } + + va_start( ap, sFormat ); + iRc = vsprintf_s( t, size, sFormat, ap ); + va_end( ap ); + +#else +#ifdef HAVE_VSNPRINTF_F + + va_start( ap, sFormat ); + size = (xbUInt32) vsnprintf( NULL, 0, sFormat, ap) + 1; + va_end( ap ); + + t = (char *) calloc( 1, size ); + if( !t ){ + size = 0; + return( *this ); + } + va_start( ap, sFormat ); + iRc = vsnprintf( t, size, sFormat, ap ); + va_end( ap ); + +# else +# error "Fatal error building [xbstring.cpp] - You have neither _vsnprintf_s nor vsnprintf_s." +# endif +#endif +#endif + + if( iRc < 0 ){ + if( data ) + free( data ); + data = NULL; + size = 0; + } else { + if( data ) + free( data ); + data = t; + } + return( *this ); +} + +/************************************************************************/ +//! @brief Return string data +/*! + \returns char * to string data or NULL if string is empty +*/ +const char *xbString::Str() const { + return data ? data : NullString; +} + +/************************************************************************/ +//! @brief Copy all or part of string to character array +/*! + \param cDest pointer to destination buffer. + \param n Number of bytest to copy. It is the responsibility of the application + to verify the buffer is large enough to hold the string contents. + \returns char * to result + +*/ +char *xbString::strncpy( char * cDest, xbUInt32 n ) const { + xbUInt32 i; + xbUInt32 ulLen; + n > (size-1) ? ulLen = size-1 : ulLen = n; + memset( cDest, 0x00, ulLen ); + for( i = 0; i < ulLen; i++ ) + cDest[i] = data[i]; +// cDest[i] = 0x00; + return cDest; +} +/************************************************************************/ +//! @brief Swap characters +/*! + \param cFrom character to replace. + \param cTo character to replace with. + \returns Reference to this string. +*/ +xbString &xbString::SwapChars( char cFrom, char cTo ){ + xbUInt32 i; + for( i = 0; i < size; i++ ) + if( data[i] == cFrom ) + data[i] = cTo; + return *this; +} + + +/************************************************************************/ +//! @brief Replace all upper case charaters with lower case characters +/*! + \returns Reference to this string. +*/ +xbString &xbString::ToLowerCase(){ + xbUInt32 Len = this->Len(); + for (xbUInt32 i=0; iLen(); + for (xbUInt32 i=0;i + + \returns xbTrue if the data is valid logical data.
+ xbFalse if not valid logical data. +*/ + +xbBool xbString::ValidLogicalValue() const { + if( Len() == 1 ) + if( data[0] == 'T' || data[0] == 'F' || data[0] == 'Y' || data[0] == 'N' || data[0] == '?' ) + return xbTrue; + return xbFalse; +} +/************************************************************************/ +//! @brief This function returns true if the data is valid numeric data +/*! + \returns xbTrue if valid numeric data.
+ xbFalse if not valid numeric daata. +*/ + +xbBool xbString::ValidNumericValue() const { + const char *p; + p = data; + while( *p ){ + if( *p != '+' && *p != '-' && *p != '.' && *p != '0' && *p != '1' && + *p != '2' && *p != '3' && *p != '4' && *p != '5' && *p != '6' && + *p != '7' && *p != '8' && *p != '9' ) + return xbFalse; + else + p++; + } + return xbTrue; +} + + +/************************************************************************/ +//! @brief Remove every instance of a character from a string. +/*! + \param c character to remove from string. + \returns Reference to this stirng.void +*/ + +xbString &xbString::ZapChar( char c ){ + + if( data == NULL ) + return *this; + if( data[0] == 0 ) + return *this; + + char *s; + char *t; + + s = data; + t = data; + while( *s ){ + if( *s == c ){ + s++; + size--; + } else { + *t++ = *s++; + } + } + *t = 0x00; + Resize( size ); + return *this; +} + +/************************************************************************/ +//! @brief Remove leading character from a string. +/*! + \param c character to remove from beginning of string. + \returns Reference to this string. +*/ +xbString &xbString::ZapLeadingChar( char c ){ + /* left truncate all of character c */ + xbUInt32 iLen = 0; + char *p; + p = data; + while( *p && *p == c ){ + iLen++; + p++; + } + if( iLen ) + Ltrunc( iLen ); + return *this; +} + + +/************************************************************************/ +//! @brief Remove trailing character from a string. +/*! + \param c character to remove from ending of string. + \returns Reference to this string. +*/ +xbString &xbString::ZapTrailingChar( char c ){ + + xbUInt32 l = Len(); + if( l == 0 ) + return *this; + + l--; + for(;;) { + if( data[l] != c ) + break; + data[l] = 0; + size--; + if( l == 0 ) + break; + l--; + } + return *this; +} + +} /* namespace */ \ No newline at end of file -- cgit v1.2.3