1#include "string/sstringw.h"
2#include <soui_mem_wrapper.h>
5#define smin_tsr(a,b) (((a) < (b)) ? (a) : (b))
12 return ::LoadStringW(hInst, uID, lpBuffer, nBufferMax);
21 int len = _vscwprintf(pszFormat, args);
25 *ppszDst = (
wchar_t*)soui_mem_wrapper::SouiMalloc((len + 1) *
sizeof(
wchar_t));
26 vswprintf_s(*ppszDst, len + 1, pszFormat, args);
29 wchar_t* fmt = wcsdup(pszFormat);
30 wchar_t* p = wcsstr(fmt, L
"%s");
33 p = wcsstr(p + 2, L
"%s");
36 int len = vswprintf_s(stkBuf, 512, fmt, args);
38 *ppszDst = (
wchar_t*)soui_mem_wrapper::SouiMalloc((len + 1) *
sizeof(
wchar_t));
39 memcpy(*ppszDst, stkBuf, (len) *
sizeof(
wchar_t));
45 wchar_t* buf = (
wchar_t*)malloc(
sizeof(
wchar_t) * bufLen);
47 len = vswprintf_s(buf, bufLen, fmt, args);
51 if (bufLen > (1 << 16))
54 buf = (
wchar_t*)malloc(
sizeof(
wchar_t) * bufLen);
61 *ppszDst = (
wchar_t*)soui_mem_wrapper::SouiMalloc((len + 1) *
sizeof(
wchar_t));
62 memcpy(*ppszDst, buf, len *
sizeof(
wchar_t));
77 return (
wchar_t)towupper(ch);
82 return (
wchar_t)towlower(ch);
102 return wcsstr(psz, psz2);
107 return wcsrchr(psz, ch);
112 return wcschr(psz, ch);
117 return _wcsicmp(psz1, psz2);
122 return wcscmp(psz1, psz2);
127 return psz ? wcslen(psz) : 0;
135 if (pData != TStringData::InitDataNil())
137 SASSERT(pData->nRefs != 0);
144 SASSERT(nLength >= 0);
145 SASSERT(nLength <= 0x7fffffff);
148 return TStringData::InitDataNil();
150 int nSize =
sizeof(TStringData) + (nLength + 1) *
sizeof(wchar_t);
152 if (pOldData == NULL)
153 pData = (TStringData*)soui_mem_wrapper::SouiMalloc(nSize);
155 pData = (TStringData*)soui_mem_wrapper::SouiRealloc(pOldData, nSize);
160 pData->nDataLength = nLength;
161 pData->nAllocLength = nLength;
163 wchar_t* pchData = (
wchar_t*)pData->data();
164 pchData[nLength] =
'\0';
171 TStringData* pData =
GetData();
172 if (pData != TStringData::InitDataNil())
174 SASSERT(pData->nRefs != 0);
182#define TSTRING_REALLOC
183#ifdef TSTRING_REALLOC
184 TStringData* pData =
GetData();
185 if (!pData->IsShared() && pData != TStringData::InitDataNil())
198 TStringData* pOldData =
GetData();
202 int nLength = smin_tsr(pOldData->nDataLength, nNewLength) + 1;
203 memcpy(
m_pszData, psz, nLength *
sizeof(
wchar_t));
224 TStringData* pData =
GetData();
225 if (pData->IsShared() || nLen > pData->nAllocLength)
230 SASSERT(
GetData()->nRefs <= 1);
236 TStringData* pData =
GetData();
237 if (pData->IsShared())
241 memcpy(
m_pszData, pData->data(), (pData->nDataLength + 1) *
sizeof(
wchar_t));
243 SASSERT(
GetData()->nRefs <= 1);
256 TStringData* pData =
GetData();
257 if (pData->IsShared() || pData->nDataLength + nSrcLen > pData->nAllocLength)
260 int nOldDataLength = pData->nDataLength;
261 int nNewLength = nOldDataLength + nSrcLen;
263 memcpy(
m_pszData + nOldDataLength, pszSrcData, nSrcLen *
sizeof(
wchar_t));
268 memcpy(
m_pszData + pData->nDataLength, pszSrcData, nSrcLen *
sizeof(
wchar_t));
269 pData->nDataLength += nSrcLen;
270 SASSERT(pData->nDataLength <= pData->nAllocLength);
282 int nNewLength = nSrc1Len + nSrc2Len;
288 memcpy(
m_pszData, pszSrc1Data, nSrc1Len *
sizeof(
wchar_t));
289 memcpy(
m_pszData + nSrc1Len, pszSrc2Data, nSrc2Len *
sizeof(
wchar_t));
299 memcpy(
m_pszData, pszSrcData, nSrcLen *
sizeof(
wchar_t));
300 GetData()->nDataLength = nSrcLen;
312 int nNewLen = nCopyLen + nExtraLen;
326 if (pszFormat == NULL || *pszFormat ==
'\0')
329 wchar_t* pszBuffer = NULL;
331 if (nLength > 0 && pszBuffer != NULL)
333 *
this +=
SStringW(pszBuffer, nLength);
334 soui_mem_wrapper::SouiFree(pszBuffer);
340 if (pszFormat == NULL || *pszFormat ==
'\0')
346 wchar_t* pszBuffer = NULL;
348 if (nLength > 0 && pszBuffer != NULL)
350 *
this =
SStringW(pszBuffer, nLength);
351 soui_mem_wrapper::SouiFree(pszBuffer);
363 m_pszData = (
wchar_t*)TStringData::InitPszNil();
379 return GetData()->nAllocLength;
385 TStringData* pData =
GetData();
386 SASSERT(pData->nDataLength <= pData->nAllocLength);
387 if (pData->nDataLength < pData->nAllocLength)
404 SASSERT(nLength >= 0);
405 SASSERT(nLength <=
GetData()->nAllocLength);
407 if (nLength >= 0 && nLength <
GetData()->nAllocLength)
409 GetData()->nDataLength = nLength;
416 SASSERT(nNewLength >= 0);
421 GetData()->nDataLength = nNewLength;
430 if (nNewLength == -1)
433 TStringData* pData =
GetData();
434 SASSERT(nNewLength <= pData->nAllocLength);
435 pData->nDataLength = nNewLength;
441 TStringData* pData =
GetData();
443 nMinBufLength = pData->nAllocLength;
444 if (pData->IsShared() || nMinBufLength > pData->nAllocLength)
447 int nOldLen = pData->nDataLength;
448 if (nMinBufLength < nOldLen)
449 nMinBufLength = nOldLen;
453 SASSERT(
GetData()->nRefs <= 1);
463 va_start(argList, pszFormat);
476 va_start(argList, nFormatID);
484 va_start(argList, pszFormat);
500 va_start(argList, nFormatID);
501 BOOL bRet =
_Format(strFormat, argList);
509 wchar_t buf[1024 + 1];
511 if (nChar == 0)
return FALSE;
518 int nLength =
GetData()->nDataLength;
519 if (nStart > nLength)
526 return (psz == NULL) ? -1 : (int)(psz -
m_pszData);
531 int nLength =
GetData()->nDataLength;
532 if (nStart >= nLength)
539 return (psz == NULL) ? -1 : (int)(psz -
m_pszData);
548 return (psz == NULL) ? -1 : (int)(psz -
m_pszData);
559 while (pstrSource < pstrEnd)
561 if (*pstrSource != chRemove)
563 *pstrDest = *pstrSource;
569 int nCount = (int)(pstrSource - pstrDest);
570 GetData()->nDataLength -= nCount;
588 while (pszStart < pszEnd)
593 pszStart = pszTarget + nSourceLen;
605 TStringData* pOldData =
GetData();
606 int nOldLength = pOldData->nDataLength;
607 int nNewLength = nOldLength + (nReplacementLen - nSourceLen) * nCount;
608 if (pOldData->nAllocLength < nNewLength || pOldData->IsShared())
617 while (pszStart < pszEnd)
621 int nBalance = nOldLength - ((int)(pszTarget -
m_pszData) + nSourceLen);
622 memmove(pszTarget + nReplacementLen, pszTarget + nSourceLen, nBalance *
sizeof(
wchar_t));
623 memcpy(pszTarget, pszNew, nReplacementLen *
sizeof(
wchar_t));
624 pszStart = pszTarget + nReplacementLen;
625 pszStart[nBalance] =
'\0';
626 nOldLength += (nReplacementLen - nSourceLen);
631 GetData()->nDataLength = nNewLength;
647 wchar_t* pszEnd = psz +
GetData()->nDataLength;
666 int nLength =
GetData()->nDataLength;
667 if (nCount > 0 && nIndex < nLength)
669 if((nIndex + nCount) > nLength)
670 nCount = nLength - nIndex;
674 int nBytesToCopy = nLength - (nIndex + nCount) + 1;
675 memmove(
m_pszData + nIndex,
m_pszData + nIndex + nCount, nBytesToCopy *
sizeof(
wchar_t));
677 GetData()->nDataLength = nLength;
689 int nNewLength =
GetData()->nDataLength;
690 if (nInsertLength > 0)
694 if (nIndex > nNewLength)
696 nNewLength += nInsertLength;
698 TStringData* pData =
GetData();
699 if (pData->nAllocLength < nNewLength)
704 memmove(
m_pszData + nIndex + nInsertLength,
m_pszData + nIndex, (nNewLength - nIndex - nInsertLength + 1) *
sizeof(
wchar_t));
705 memcpy(
m_pszData + nIndex, psz, nInsertLength *
sizeof(
wchar_t));
706 GetData()->nDataLength = nNewLength;
718 TStringData* pData =
GetData();
719 int nNewLength = pData->nDataLength;
720 if (nIndex > nNewLength)
724 if (pData->nAllocLength < nNewLength)
729 memmove(
m_pszData + nIndex + 1,
m_pszData + nIndex, (nNewLength - nIndex) *
sizeof(
wchar_t));
731 GetData()->nDataLength = nNewLength;
744 return 0 == _src.
Compare(suffix);
757 return 0 == _src.
Compare(prefix);
767 const wchar_t * p = pbuf;
774 const wchar_t * p1 = p;
776 const wchar_t * p2 = pbuf +
GetLength() - 1;
785 (*
this) =
SStringW(p1, (
int)(p2 - p1 + 1));
790 const wchar_t szBlank[] = { 0x0a,0x0d,0x20,0x09 };
791 for (
int i = 0; i < ARRAYSIZE(szBlank); i++)
793 if (c == szBlank[i])
return true;
811 while (chTarget == *psz)
817 TStringData* pData =
GetData();
818 int nDataLength = pData->nDataLength - (int)(psz -
m_pszData);
819 memmove(
m_pszData, psz, (nDataLength + 1) *
sizeof(
wchar_t));
820 pData->nDataLength = nDataLength;
831 wchar_t* pszLast = NULL;
835 if (*psz == chTarget)
881 TStringData* pData =
GetData();
884 else if (nCount > pData->nDataLength)
885 nCount = pData->nDataLength;
894 TStringData* pData =
GetData();
897 else if (nCount > pData->nDataLength)
898 nCount = pData->nDataLength;
901 AllocCopy(dest, nCount, pData->nDataLength - nCount, 0);
913 TStringData* pData =
GetData();
914 if (nFirst + nCount > pData->nDataLength)
915 nCount = pData->nDataLength - nFirst;
916 if (nFirst > pData->nDataLength)
926 return Mid(nFirst,
GetData()->nDataLength - nFirst);
989 TStringData* pData =
GetData();
990 if ((pData->IsLocked() && pData != TStringData::InitDataNil()) || stringSrc.
GetData()->IsLocked())
999 SASSERT(stringSrc.
GetData() != TStringData::InitDataNil());
1012SStringW::operator
const wchar_t*()
const
1019 SASSERT(nIndex >= 0);
1020 SASSERT(nIndex <
GetData()->nDataLength);
1029 SASSERT(nIndex >= 0);
1030 SASSERT(nIndex <
GetData()->nDataLength);
1036 SASSERT(nIndex >= 0);
1037 SASSERT(nIndex <
GetData()->nDataLength);
1043 TStringData* pData =
GetData();
1044 if (pData->nDataLength == 0)
1047 if (pData->nRefs >= 0)
1051 wchar_t sz[1] = { 0 };
1055 SASSERT(
GetData()->nDataLength == 0);
1061 return GetData()->nDataLength == 0;
1066 return GetData()->nDataLength;
1073 const TStringData * pDataSrc = (
const TStringData *)pSrc->GetPrivData();
1074 TStringData* pData =
GetData();
1075 if ((pData->IsLocked() && pData != TStringData::InitDataNil()) || pDataSrc->IsLocked())
1078 AssignCopy(pDataSrc->nDataLength, pSrc->c_str());
1084 SASSERT(pDataSrc != TStringData::InitDataNil());
1113 TStringData* pData =
GetData();
1114 if (pData != TStringData::InitDataNil())
1125 memcpy(
m_pszData, psz, nLength *
sizeof(
wchar_t));
1136 memcpy(
m_pszData, psz, nLength *
sizeof(
wchar_t));
1147 for (
int i = 0; i < nLength; i++)
1156 TStringData *pData = (TStringData*)src->GetPrivData();
1157 SASSERT(pData->nRefs != 0);
1158 if (pData->nRefs >= 0)
1160 SASSERT(pData != TStringData::InitDataNil());
SStringW()
Default constructor.
void Empty()
Empties the string.
void Assign2(LPCWSTR src, int nLen)
Assigns a substring of a character array to the string.
bool AllocBuffer(int nLength)
Allocates memory for the string buffer.
int CompareNoCase(const wchar_t *psz) SCONST
Compares the string with another string, ignoring case.
void ReleaseBuffer(int nNewLength=-1)
Releases the buffer and sets the new length of the string.
static bool IsBlankChar(const wchar_t &c)
Checks if a character is a blank character.
bool ReallocBuffer(int nNewLength)
Reallocates memory for the string buffer.
void AssignCopy(int nSrcLen, const wchar_t *pszSrcData)
Assigns a substring of a character array to the string.
void SetLength(int nLength)
Sets the length of the string.
void TrimBlank()
Trims leading and trailing whitespace characters from the string.
LPVOID GetPrivData() SCONST
Retrieves private data associated with the string.
long ToLong() SCONST OVERRIDE
Converts the string to a long integer.
int Remove(wchar_t chRemove)
Removes all occurrences of a character from the string.
void AllocCopy(SStringW &dest, int nCopyLen, int nCopyIndex, int nExtraLen) const
Allocates and copies a substring of the string.
void AppendChar(wchar_t ch) OVERRIDE
Appends a character to the string.
SStringW & operator=(const SStringW &stringSrc)
Overloaded assignment operator from another SStringW object.
void Preallocate(int nLength)
Preallocates memory for the string buffer.
int Replace(const wchar_t *pszOld, const wchar_t *pszNew)
Replaces all occurrences of a substring with another substring.
const wchar_t * c_str() SCONST
Retrieves a C-style string representation of the string.
int ReplaceChar(wchar_t chOld, wchar_t chNew)
Replaces all occurrences of a character with another character.
BOOL IsEmpty() SCONST
Checks if the string is empty.
void InitFromIString(const IStringW *stringSrc)
Initializes the string from an IStringW object.
int Compare(const wchar_t *psz) SCONST
Compares the string with another string.
void FreeExtra()
Frees any extra allocated memory in the string buffer.
wchar_t * GetBufferSetLength(int nNewLength)
Retrieves a modifiable buffer for the string and sets the new length.
void TrimLeft(wchar_t chTarget=VK_SPACE) OVERRIDE
Trims leading whitespace characters from the string.
void Copy(const IStringW *src)
Copies the contents of another string into this string.
bool AllocBeforeWrite(int nLen)
Allocates memory for the string before writing to it.
void Trim(wchar_t chTarget=VK_SPACE) OVERRIDE
Trims leading and trailing whitespace characters from the string.
void _ReleaseData()
Releases the data structure of the string.
int GetAllocLength() const
Retrieves the allocated length of the string buffer.
int FindChar(wchar_t ch, int nStart=0) SCONST
Finds the first occurrence of a character in the string.
double ToDouble() SCONST OVERRIDE
Converts the string to a double.
void ConcatInPlace(int nSrcLen, const wchar_t *pszSrcData)
Concatenates a substring to the string in place.
SStringW Mid(int nFirst) const
Extracts a substring from the string.
static int SafeStrlen(const wchar_t *psz)
Computes the length of a null-terminated string safely.
BOOL __cdecl Format(HINSTANCE hInst, UINT nFormatID,...)
Formats a string using a format string and variable arguments.
SStringW & MakeLower()
Converts the string to lowercase.
bool EndsWith(const SStringW &suffix, bool IgnoreCase=false) const
Checks if the string ends with a specified suffix.
bool ConcatCopy(int nSrc1Len, const wchar_t *pszSrc1Data, int nSrc2Len, const wchar_t *pszSrc2Data)
Concatenates two substrings and copies the result to the string.
void Init()
Initializes the string.
SStringW & Append(const SStringW &src)
Appends another SStringW object to the string.
int InsertChar(int nIndex, wchar_t ch)
Inserts a character at a specified index.
void SetAt(int nIndex, wchar_t ch)
Sets the character at a specified index.
void TrimRight(wchar_t chTarget=VK_SPACE) OVERRIDE
Trims trailing whitespace characters from the string.
BOOL _Format(const wchar_t *pszFormat, va_list &args)
Formats a string using a format string and variable arguments.
BOOL ToBool() SCONST OVERRIDE
Converts the string to a boolean.
int Insert(int nIndex, const wchar_t *psz)
Inserts a substring at a specified index.
TStringData * GetData() const
Retrieves the data structure of the string.
float ToFloat() SCONST OVERRIDE
Converts the string to a float.
void _AppendFormat(const wchar_t *pszFormat, va_list &args)
Appends formatted data to the string using a format string and variable arguments.
void Assign(LPCWSTR src)
Assigns a character array to the string.
SStringW Right(int nCount) const
Extracts the rightmost part of the string.
void Release() OVERRIDE
Releases the string and its resources.
SStringW & MakeUpper()
Converts the string to uppercase.
wchar_t * GetBuffer(int nMinBufLength=-1)
Retrieves a modifiable buffer for the string.
int Delete(int nIndex, int nCount=1)
Deletes a substring from the string.
int ToInt() SCONST OVERRIDE
Converts the string to an integer.
void CopyBeforeWrite()
Copies the string before writing to it.
const SStringW & operator+=(const wchar_t *psz)
Overloaded concatenation operator with a character array.
wchar_t * m_pszData
Pointer to the ref counted string data.
static void ReleaseData(TStringData *pData)
Releases a data structure.
UINT ToUint() SCONST OVERRIDE
Converts the string to an unsigned integer.
void __cdecl AppendFormat(HINSTANCE hInst, UINT nFormatID,...)
Appends formatted data to the string using a format string and variable arguments.
int GetLength() SCONST
Retrieves the length of the string.
int Find(const wchar_t *pszSub, int nStart=0) SCONST
Finds the first occurrence of a substring in the string.
wchar_t GetAt(int nIndex) SCONST
Retrieves the character at a specified index.
SStringW Left(int nCount) const
Extracts the leftmost part of the string.
int ReverseFind(wchar_t ch) SCONST
Finds the last occurrence of a character in the string.
void ToUpper() OVERRIDE
Converts the string to uppercase.
wchar_t operator[](int nIndex) const
Retrieves the character at a specified index.
void ToLower() OVERRIDE
Converts the string to lowercase.
void AppendStr(const wchar_t *pszStr, int nLen=-1) OVERRIDE
Appends a substring to the string.
bool StartsWith(const SStringW &prefix, bool IgnoreCase=false) const
Checks if the string starts with a specified prefix.
static TStringData * AllocData(int nLength, TStringData *pOldData=NULL)
Allocates a new data structure for the string.
BOOL LoadString(UINT nID, HINSTANCE hInst)
Loads a string resource from a module.
static int Compare(const wchar_t *psz1, const wchar_t *psz2)
Compares two strings lexicographically.
static wchar_t * CharNext(wchar_t *psz)
Moves to the next character in a string.
static wchar_t CharLower(wchar_t ch)
Converts a character to lowercase.
static size_t StrLen(const wchar_t *psz)
Computes the length of a null-terminated string.
static int CompareNoCase(const wchar_t *psz1, const wchar_t *psz2)
Compares two strings lexicographically, ignoring case.
static int LoadString(HINSTANCE hInst, UINT uID, wchar_t *lpBuffer, int nBufferMax)
Loads a string resource from a module.
static wchar_t * StrLower(wchar_t *psz)
Converts a string to lowercase.
static const wchar_t * StrRChr(const wchar_t *psz, wchar_t ch)
Finds the last occurrence of a character in a string.
static wchar_t * StrUpper(wchar_t *psz)
Converts a string to uppercase.
static const wchar_t * StrChr(const wchar_t *psz, wchar_t ch)
Finds the first occurrence of a character in a string.
static int Format(wchar_t **ppszDst, const wchar_t *pszFormat, va_list &args)
Formats a string using a format string and variable arguments.
static wchar_t CharUpper(wchar_t ch)
Converts a character to uppercase.
static int IsSpace(wchar_t ch)
Checks if a character is a whitespace character.
static const wchar_t * StrStr(const wchar_t *psz, const wchar_t *psz2)
Finds the first occurrence of a substring in a string.