1#include <string/sstringa.h>
2#include <soui_mem_wrapper.h>
11#define smin_tsr(a,b) (((a) < (b)) ? (a) : (b))
18 return ::LoadStringA(hInst, uID, lpBuffer, nBufferMax);
27 int len = _vscprintf(pszFormat, args);
31 int len = _vscprintf(pszFormat, va2);
34 if (len <= 0)
return 0;
35 *ppszDst = (
char*)soui_mem_wrapper::SouiMalloc(len + 1);
36 vsprintf_s(*ppszDst, len + 1, pszFormat, args);
43 return (
char*)_mbsinc((
unsigned char*)psz);
51 return (
char)toupper(ch);
56 return (
char)tolower(ch);
62 return _ismbcspace(ch);
71 return (
char*)_mbslwr((
unsigned char*)psz);
80 return (
char*)_mbsupr((
unsigned char*)psz);
89 return (
const char*)_mbsstr((
unsigned char*)psz, (
unsigned char*)psz2);
91 return strstr(psz, psz2);
98 return (
const char*)_mbsrchr((
unsigned char*)psz, ch);
100 return strrchr(psz, ch);
107 return (
const char*)_mbschr((
unsigned char*)psz, ch);
109 return strchr(psz, ch);
116 return _mbsicmp((
unsigned char*)psz1, (
unsigned char*)psz2);
118 return stricmp(psz1, psz2);
125 return _mbscmp((
unsigned char*)psz1, (
unsigned char*)psz2);
127 return strcmp(psz1, psz2);
133 return psz ? strlen(psz) : 0;
141 if (pData != TStringData::InitDataNil())
143 SASSERT(pData->nRefs != 0);
150 SASSERT(nLength >= 0);
151 SASSERT(nLength <= 0x7fffffff);
154 return TStringData::InitDataNil();
156 int nSize =
sizeof(TStringData) + (nLength + 1) *
sizeof(char);
158 if (pOldData == NULL)
159 pData = (TStringData*)soui_mem_wrapper::SouiMalloc(nSize);
161 pData = (TStringData*)soui_mem_wrapper::SouiRealloc(pOldData, nSize);
166 pData->nDataLength = nLength;
167 pData->nAllocLength = nLength;
169 char* pchData = (
char*)pData->data();
170 pchData[nLength] =
'\0';
177 TStringData* pData =
GetData();
178 if (pData != TStringData::InitDataNil())
180 SASSERT(pData->nRefs != 0);
188#define TSTRING_REALLOC
189#ifdef TSTRING_REALLOC
190 TStringData* pData =
GetData();
191 if (!pData->IsShared() && pData != TStringData::InitDataNil())
204 TStringData* pOldData =
GetData();
208 int nLength = smin_tsr(pOldData->nDataLength, nNewLength) + 1;
209 memcpy(
m_pszData, psz, nLength *
sizeof(
char));
230 TStringData* pData =
GetData();
231 if (pData->IsShared() || nLen > pData->nAllocLength)
236 SASSERT(
GetData()->nRefs <= 1);
242 TStringData* pData =
GetData();
243 if (pData->IsShared())
247 memcpy(
m_pszData, pData->data(), (pData->nDataLength + 1) *
sizeof(
char));
249 SASSERT(
GetData()->nRefs <= 1);
262 TStringData* pData =
GetData();
263 if (pData->IsShared() || pData->nDataLength + nSrcLen > pData->nAllocLength)
266 int nOldDataLength = pData->nDataLength;
267 int nNewLength = nOldDataLength + nSrcLen;
269 memcpy(
m_pszData + nOldDataLength, pszSrcData, nSrcLen *
sizeof(
char));
274 memcpy(
m_pszData + pData->nDataLength, pszSrcData, nSrcLen *
sizeof(
char));
275 pData->nDataLength += nSrcLen;
276 SASSERT(pData->nDataLength <= pData->nAllocLength);
288 int nNewLength = nSrc1Len + nSrc2Len;
294 memcpy(
m_pszData, pszSrc1Data, nSrc1Len *
sizeof(
char));
295 memcpy(
m_pszData + nSrc1Len, pszSrc2Data, nSrc2Len *
sizeof(
char));
305 memcpy(
m_pszData, pszSrcData, nSrcLen *
sizeof(
char));
306 GetData()->nDataLength = nSrcLen;
318 int nNewLen = nCopyLen + nExtraLen;
332 if (pszFormat == NULL || *pszFormat ==
'\0')
335 char* pszBuffer = NULL;
337 if (nLength > 0 && pszBuffer != NULL)
339 *
this +=
SStringA(pszBuffer, nLength);
340 soui_mem_wrapper::SouiFree(pszBuffer);
346 if (pszFormat == NULL || *pszFormat ==
'\0')
352 char* pszBuffer = NULL;
354 if (nLength > 0 && pszBuffer != NULL)
356 *
this =
SStringA(pszBuffer, nLength);
357 soui_mem_wrapper::SouiFree(pszBuffer);
369 m_pszData = (
char*)TStringData::InitPszNil();
385 return GetData()->nAllocLength;
391 TStringData* pData =
GetData();
392 SASSERT(pData->nDataLength <= pData->nAllocLength);
393 if (pData->nDataLength < pData->nAllocLength)
410 SASSERT(nLength >= 0);
411 SASSERT(nLength <=
GetData()->nAllocLength);
413 if (nLength >= 0 && nLength <
GetData()->nAllocLength)
415 GetData()->nDataLength = nLength;
424 const TStringData * pDataSrc = (
const TStringData *)pSrc->GetPrivData();
425 TStringData* pData =
GetData();
426 if ((pData->IsLocked() && pData != TStringData::InitDataNil()) || pDataSrc->IsLocked())
429 AssignCopy(pDataSrc->nDataLength, pSrc->c_str());
435 SASSERT(pDataSrc != TStringData::InitDataNil());
459 SASSERT(nNewLength >= 0);
464 GetData()->nDataLength = nNewLength;
473 if (nNewLength == -1)
476 TStringData* pData =
GetData();
477 SASSERT(nNewLength <= pData->nAllocLength);
478 pData->nDataLength = nNewLength;
484 TStringData* pData =
GetData();
486 nMinBufLength = pData->nAllocLength;
488 if (pData->IsShared() || nMinBufLength > pData->nAllocLength)
491 int nOldLen = pData->nDataLength;
492 if (nMinBufLength < nOldLen)
493 nMinBufLength = nOldLen;
497 SASSERT(
GetData()->nRefs <= 1);
507 va_start(argList, pszFormat);
520 va_start(argList, nFormatID);
528 va_start(argList, pszFormat);
544 va_start(argList, nFormatID);
545 BOOL bRet =
_Format(strFormat, argList);
555 if (nChar == 0)
return FALSE;
562 int nLength =
GetData()->nDataLength;
563 if (nStart > nLength)
570 return (psz == NULL) ? -1 : (int)(psz -
m_pszData);
575 int nLength =
GetData()->nDataLength;
576 if (nStart >= nLength)
583 return (psz == NULL) ? -1 : (int)(psz -
m_pszData);
592 return (psz == NULL) ? -1 : (int)(psz -
m_pszData);
603 while (pstrSource < pstrEnd)
605 if (*pstrSource != chRemove)
607 *pstrDest = *pstrSource;
613 int nCount = (int)(pstrSource - pstrDest);
614 GetData()->nDataLength -= nCount;
632 while (pszStart < pszEnd)
637 pszStart = pszTarget + nSourceLen;
649 TStringData* pOldData =
GetData();
650 int nOldLength = pOldData->nDataLength;
651 int nNewLength = nOldLength + (nReplacementLen - nSourceLen) * nCount;
652 if (pOldData->nAllocLength < nNewLength || pOldData->IsShared())
661 while (pszStart < pszEnd)
665 int nBalance = nOldLength - ((int)(pszTarget -
m_pszData) + nSourceLen);
666 memmove(pszTarget + nReplacementLen, pszTarget + nSourceLen, nBalance *
sizeof(
char));
667 memcpy(pszTarget, pszNew, nReplacementLen *
sizeof(
char));
668 pszStart = pszTarget + nReplacementLen;
669 pszStart[nBalance] =
'\0';
670 nOldLength += (nReplacementLen - nSourceLen);
675 GetData()->nDataLength = nNewLength;
691 char* pszEnd = psz +
GetData()->nDataLength;
710 int nLength =
GetData()->nDataLength;
711 if (nCount > 0 && nIndex < nLength)
713 if((nIndex + nCount) > nLength)
714 nCount = nLength - nIndex;
718 int nBytesToCopy = nLength - (nIndex + nCount) + 1;
719 memmove(
m_pszData + nIndex,
m_pszData + nIndex + nCount, nBytesToCopy *
sizeof(
char));
721 GetData()->nDataLength = nLength;
733 int nNewLength =
GetData()->nDataLength;
734 if (nInsertLength > 0)
738 if (nIndex > nNewLength)
740 nNewLength += nInsertLength;
742 TStringData* pData =
GetData();
743 if (pData->nAllocLength < nNewLength)
748 memmove(
m_pszData + nIndex + nInsertLength,
m_pszData + nIndex, (nNewLength - nIndex - nInsertLength + 1) *
sizeof(
char));
749 memcpy(
m_pszData + nIndex, psz, nInsertLength *
sizeof(
char));
750 GetData()->nDataLength = nNewLength;
762 TStringData* pData =
GetData();
763 int nNewLength = pData->nDataLength;
764 if (nIndex > nNewLength)
768 if (pData->nAllocLength < nNewLength)
773 memmove(
m_pszData + nIndex + 1,
m_pszData + nIndex, (nNewLength - nIndex) *
sizeof(
char));
775 GetData()->nDataLength = nNewLength;
788 return 0 == _src.
Compare(suffix);
801 return 0 == _src.
Compare(prefix);
811 const char * p = pbuf;
820 const char * p2 = pbuf +
GetLength() - 1;
829 (*
this) =
SStringA(p1, (
int)(p2 - p1 + 1));
834 const char szBlank[] = { 0x0a,0x0d,0x20,0x09 };
835 for (
int i = 0; i < ARRAYSIZE(szBlank); i++)
837 if (c == szBlank[i])
return true;
855 while (chTarget == *psz)
861 TStringData* pData =
GetData();
862 int nDataLength = pData->nDataLength - (int)(psz -
m_pszData);
863 memmove(
m_pszData, psz, (nDataLength + 1) *
sizeof(
char));
864 pData->nDataLength = nDataLength;
875 char* pszLast = NULL;
879 if (*psz == chTarget)
927 TStringData* pData =
GetData();
930 else if (nCount > pData->nDataLength)
931 nCount = pData->nDataLength;
940 TStringData* pData =
GetData();
943 else if (nCount > pData->nDataLength)
944 nCount = pData->nDataLength;
947 AllocCopy(dest, nCount, pData->nDataLength - nCount, 0);
959 TStringData* pData =
GetData();
960 if (nFirst + nCount > pData->nDataLength)
961 nCount = pData->nDataLength - nFirst;
962 if (nFirst > pData->nDataLength)
972 return Mid(nFirst,
GetData()->nDataLength - nFirst);
1034 TStringData* pData =
GetData();
1035 if ((pData->IsLocked() && pData != TStringData::InitDataNil()) || stringSrc.
GetData()->IsLocked())
1044 SASSERT(stringSrc.
GetData() != TStringData::InitDataNil());
1057SStringA::operator
const char*()
const
1064 SASSERT(nIndex >= 0);
1065 SASSERT(nIndex <
GetData()->nDataLength);
1074 SASSERT(nIndex >= 0);
1075 SASSERT(nIndex <
GetData()->nDataLength);
1081 SASSERT(nIndex >= 0);
1082 SASSERT(nIndex <
GetData()->nDataLength);
1088 TStringData* pData =
GetData();
1089 if (pData->nDataLength == 0)
1092 if (pData->nRefs >= 0)
1100 SASSERT(
GetData()->nDataLength == 0);
1106 return GetData()->nDataLength == 0;
1111 return GetData()->nDataLength;
1117 TStringData* pData =
GetData();
1118 if (pData != TStringData::InitDataNil())
1130 memcpy(
m_pszData, psz, nLength *
sizeof(
char));
1141 memcpy(
m_pszData, psz, nLength *
sizeof(
char));
1152 for (
int i = 0; i < nLength; i++)
1161 TStringData *pData = (TStringData*)stringSrc->GetPrivData();
1162 SASSERT(pData->nRefs != 0);
1163 if (pData->nRefs >= 0)
1165 SASSERT(pData != TStringData::InitDataNil());
SStringA & MakeUpper()
Converts the string to uppercase.
BOOL __cdecl Format(HINSTANCE hInst, UINT nFormatID,...)
Formats a string using a format string and variable arguments.
bool ReallocBuffer(int nNewLength)
Reallocates memory for the string buffer.
void Trim(char chTarget=VK_SPACE) OVERRIDE
Trims leading and trailing whitespace characters from the string.
void Copy(const IStringA *src)
Copies the contents of another string into this string.
static void ReleaseData(TStringData *pData)
Releases a data structure.
void Preallocate(int nLength)
Preallocates memory for the string buffer.
void ConcatInPlace(int nSrcLen, const char *pszSrcData)
Concatenates a substring to the string in place.
void Assign2(LPCSTR src, int nLen)
Assigns a substring of a character array to the string.
SStringA & operator=(const SStringA &stringSrc)
Overloaded assignment operator from another SStringA object.
void ToUpper() OVERRIDE
Converts the string to uppercase.
void CopyBeforeWrite()
Copies the string before writing to it.
int Compare(const char *psz) SCONST
Compares the string with another string.
UINT ToUint() SCONST OVERRIDE
Converts the string to an unsigned integer.
BOOL _Format(const char *pszFormat, va_list &args)
Formats a string using a format string and variable arguments.
LPVOID GetPrivData() SCONST
Retrieves private data associated with the string.
int GetLength() SCONST
Retrieves the length of the string.
void ReleaseBuffer(int nNewLength=-1)
Releases the buffer and sets the new length of the string.
int Delete(int nIndex, int nCount=1)
Deletes a substring from the string.
void AppendStr(const char *pszStr, int nLen=-1) OVERRIDE
Appends a substring to the string.
int Find(const char *pszSub, int nStart=0) SCONST
Finds the first occurrence of a substring in the string.
int ToInt() SCONST OVERRIDE
Converts the string to an integer.
void Assign(LPCSTR src)
Assigns a character array to the string.
void AllocCopy(SStringA &dest, int nCopyLen, int nCopyIndex, int nExtraLen) const
Allocates and copies a substring of the string.
static int SafeStrlen(const char *psz)
Computes the length of a null-terminated string safely.
char GetAt(int nIndex) SCONST
Retrieves the character at a specified index.
bool EndsWith(const SStringA &suffix, bool IgnoreCase=false) const
Checks if the string ends with a specified suffix.
bool StartsWith(const SStringA &prefix, bool IgnoreCase=false) const
Checks if the string starts with a specified prefix.
int ReplaceChar(char chOld, char chNew)
Replaces all occurrences of a character with another character.
char * GetBuffer(int nMinBufLength=-1)
Retrieves a modifiable buffer for the string.
void SetAt(int nIndex, char ch)
Sets the character at a specified index.
SStringA & Append(const SStringA &src)
Appends another SStringA object to the string.
void TrimRight(char chTarget=VK_SPACE) OVERRIDE
Trims trailing whitespace characters from the string.
void InitFromIString(const IStringA *stringSrc)
Initializes the string from an IStringA object.
void _ReleaseData()
Releases the data structure of the string.
void TrimBlank()
Trims leading and trailing whitespace characters from the string.
int Insert(int nIndex, const char *psz)
Inserts a substring at a specified index.
BOOL ToBool() SCONST OVERRIDE
Converts the string to a boolean.
float ToFloat() SCONST OVERRIDE
Converts the string to a float.
void SetLength(int nLength)
Sets the length of the string.
SStringA Mid(int nFirst) const
Extracts a substring from the string.
int Remove(char chRemove)
Removes all occurrences of a character from the string.
SStringA Left(int nCount) const
Extracts the leftmost part of the string.
long ToLong() SCONST OVERRIDE
Converts the string to a long integer.
SStringA & MakeLower()
Converts the string to lowercase.
int FindChar(char ch, int nStart=0) SCONST
Finds the first occurrence of a character in the string.
void FreeExtra()
Frees any extra allocated memory in the string buffer.
void Empty()
Empties the string.
int Replace(const char *pszOld, const char *pszNew)
Replaces all occurrences of a substring with another substring.
bool ConcatCopy(int nSrc1Len, const char *pszSrc1Data, int nSrc2Len, const char *pszSrc2Data)
Concatenates two substrings and copies the result to the string.
static TStringData * AllocData(int nLength, TStringData *pOldData=NULL)
Allocates a new data structure for the string.
char * GetBufferSetLength(int nNewLength)
Retrieves a modifiable buffer for the string and sets the new length.
void __cdecl AppendFormat(HINSTANCE hInst, UINT nFormatID,...)
Appends formatted data to the string using a format string and variable arguments.
void Init()
Initializes the string.
BOOL LoadString(UINT nID, HINSTANCE hInst)
Loads a string resource from a module.
int ReverseFind(char ch) SCONST
Finds the last occurrence of a character in the string.
char operator[](int nIndex) const
Retrieves the character at a specified index.
void AssignCopy(int nSrcLen, const char *pszSrcData)
Assigns a substring of a character array to the string.
void Release() OVERRIDE
Releases the string and its resources.
double ToDouble() SCONST OVERRIDE
Converts the string to a double.
int InsertChar(int nIndex, char ch)
Inserts a character at a specified index.
const SStringA & operator+=(const char *psz)
Overloaded concatenation operator with a character array.
const char * c_str() SCONST
Retrieves a C-style string representation of the string.
char * m_pszData
Pointer to the ref counted string data.
void AppendChar(char ch) OVERRIDE
Appends a character to the string.
static bool IsBlankChar(const char &c)
Checks if a character is a blank character.
void TrimLeft(char chTarget=VK_SPACE) OVERRIDE
Trims leading whitespace characters from the string.
int CompareNoCase(const char *psz) SCONST
Compares the string with another string, ignoring case.
bool AllocBeforeWrite(int nLen)
Allocates memory for the string before writing to it.
void _AppendFormat(const char *pszFormat, va_list &args)
Appends formatted data to the string using a format string and variable arguments.
SStringA()
Default constructor.
TStringData * GetData() const
Retrieves the data structure of the string.
void ToLower() OVERRIDE
Converts the string to lowercase.
int GetAllocLength() const
Retrieves the allocated length of the string buffer.
bool AllocBuffer(int nLength)
Allocates memory for the string buffer.
SStringA Right(int nCount) const
Extracts the rightmost part of the string.
BOOL IsEmpty() SCONST
Checks if the string is empty.
static const char * StrStr(const char *psz, const char *psz2)
Finds the first occurrence of a substring in a string.
static size_t StrLen(const char *psz)
Computes the length of a null-terminated string.
static char * StrUpper(char *psz)
Converts a string to uppercase.
static char * CharNext(char *psz)
Moves to the next character in a string.
static int Format(char **ppszDst, const char *pszFormat, va_list &args)
Formats a string using a format string and variable arguments.
static char CharUpper(char ch)
Converts a character to uppercase.
static int IsSpace(char ch)
Checks if a character is a whitespace character.
static char CharLower(char ch)
Converts a character to lowercase.
static const char * StrRChr(const char *psz, char ch)
Finds the last occurrence of a character in a string.
static int CompareNoCase(const char *psz1, const char *psz2)
Compares two strings lexicographically, ignoring case.
static char * StrLower(char *psz)
Converts a string to lowercase.
static const char * StrChr(const char *psz, char ch)
Finds the first occurrence of a character in a string.
static int Compare(const char *psz1, const char *psz2)
Compares two strings lexicographically.
static int LoadString(HINSTANCE hInst, UINT uID, char *lpBuffer, int nBufferMax)
Loads a string resource from a module.