Code:
//#if defined(_AFXEXT) && !defined(STRINGEXIMPL_H)
//#error "Dll code must include StringExImpl.h"
//#endif
#ifndef STRINGEX_H__FILE__
#define STRINGEX_H__FILE__
//#include "boost\operators.hpp"
namespace Strings
{
template<typename T, typename Traits> class CTmplStringBase;
template<typename T, typename Traits> CTmplStringBase<T,Traits>& operator += (CTmplStringBase<T,Traits>& rlhs, const T* strData);
template<typename T, typename Traits> CTmplStringBase<T,Traits>& operator += (CTmplStringBase<T,Traits>& rlhs, const T cData);
template<typename T, typename Traits> CTmplStringBase<T,Traits>& operator += (CTmplStringBase<T,Traits>& rlhs, uint64_t nData);
template<typename T, typename Traits> CTmplStringBase<T,Traits>& operator += (CTmplStringBase<T,Traits>& rlhs, int64_t nData);
template<typename T, typename Traits> CTmplStringBase<T,Traits>& operator += (CTmplStringBase<T,Traits>& rlhs, long nData);
template<typename T, typename Traits> bool operator == (CTmplStringBase<T,Traits>& rlhs, const T* strData);
template<typename T, typename Traits> bool operator == (CTmplStringBase<T,Traits>& rlhs, const T cData);
template<typename T, typename Traits> bool operator != (CTmplStringBase<T,Traits>& rlhs, const T* strData);
template<typename T, typename Traits> bool operator != (CTmplStringBase<T,Traits>& rlhs, const T cData);
template<typename T> class StrTraits
{
//protected:
public:
typedef int (fnc_tprintf_s)(T* buffer, size_t sizeOfBuffer, const T* format, ...);
typedef int (fnc_tvprintf_s)(T* buffer, size_t sizeOfBuffer, const T* format, va_list argptr);
typedef int (fnc_tcscmp)(const T* string1, const T* string2);
typedef int (fnc_tvcprintf)(const T* format, va_list argptr);
static const T* UINT64_T_IDENTIFIER;
static const T* INT64_T_IDENTIFIER;
static const T* LONG_IDENTIFIER;
static uint32_t GetLength(const T* strData); // { return strlen(strData); }
static fnc_tprintf_s* GetFormatFunction(const T*);
static fnc_tvprintf_s* GetVFormatFunction(const T*);
static fnc_tvcprintf* GetVFormatCountFunction(const T*);
static fnc_tcscmp* GetCompareFunction(const T*);
};
//template<typename T> uint32_t StrTraits<T>::GetLength(const T* strData) const { return strlen(strData); }
template<typename T, typename Traits> class CTmplStringBase:
//private StrTraits<T>,
public boost::addable<CTmplStringBase<T, Traits>, const T*>,
public boost::addable<CTmplStringBase<T, Traits>, const T>,
public boost::addable<CTmplStringBase<T, Traits>, uint64_t>,
public boost::addable<CTmplStringBase<T, Traits>, int64_t>,
public boost::addable<CTmplStringBase<T, Traits>, long>,
public boost::addable< CTmplStringBase<T, Traits> >
#ifdef _MFC_VER
, public boost::addable< CTmplStringBase<T, Traits>, const CStringT< T, StrTraitMFC_DLL<T> > >
#endif
{
public:
CTmplStringBase();
CTmplStringBase(const CTmplStringBase& rSrc);
#ifdef _MFC_VER
CTmplStringBase(const CStringT< T, StrTraitMFC_DLL<T> >& strSrc);
#endif
CTmplStringBase(const T* strData);
CTmplStringBase(const T cData);
CTmplStringBase(uint64_t nData);
CTmplStringBase(int64_t nData);
CTmplStringBase(long nData);
~CTmplStringBase();
CTmplStringBase& operator = (const T* strData);
CTmplStringBase& operator = (const T cData);
CTmplStringBase& operator = (uint64_t nData);
CTmplStringBase& operator = (int64_t nData);
CTmplStringBase& operator = (long nData);
CTmplStringBase& operator = (const CTmplStringBase& rSrc);
#ifdef _MFC_VER
CTmplStringBase& operator = (const CStringT< T, StrTraitMFC_DLL<T> >& rSrc);
#endif
friend CTmplStringBase<T,Traits>& operator += <> (CTmplStringBase<T,Traits>& rlhs, const T* strData);
friend CTmplStringBase<T,Traits>& operator += <> (CTmplStringBase<T,Traits>& rlhs, const T cData);
friend CTmplStringBase<T,Traits>& operator += <> (CTmplStringBase<T,Traits>& rlhs, uint64_t nData);
friend CTmplStringBase<T,Traits>& operator += <> (CTmplStringBase<T,Traits>& rlhs, int64_t nData);
friend CTmplStringBase<T,Traits>& operator += <> (CTmplStringBase<T,Traits>& rlhs, long nData);
friend bool operator == <> (CTmplStringBase<T,Traits>& rlhs, const T* strData);
friend bool operator == <> (CTmplStringBase<T,Traits>& rlhs, const T cData);
friend bool operator != <> (CTmplStringBase<T,Traits>& rlhs, const T* strData);
friend bool operator != <> (CTmplStringBase<T,Traits>& rlhs, const T cData);
operator const T* () const;
void Replace(const CTmplStringBase& strReplaceWhat, const CTmplStringBase& strReplaceWith);
CTmplStringBase Right(uint32_t nCount) const;
void Delete(uint32_t nStartFrom, uint32_t nCount = 0);
uint32_t GetLength() const;
T* GetBuffer(uint32_t nMinSize);
void ReleaseBuffer();
void Truncate(uint32_t nNewSize);
int32_t Find(const T* strFind, uint32_t nBeginAt = 0) const;
int32_t Find(const T cFind, uint32_t nBeginAt = 0) const;
CTmplStringBase Mid(uint32_t nStart, uint32_t nCount = 0) const;
void Format(const T* strFormat, ...);
void AppendFormat(const T* strFormat, ...);
void Empty();
private:
void Init();
int32_t ReplaceInternal(const CTmplStringBase& strReplaceWhat, const CTmplStringBase& strReplaceWith, bool bReplace);
void FormatInternal(const T* strFormat, va_list arg);
void CopyStr(const T* strData);
void AppendStr(const T* strData);
void CopyStrLowLevel(T* strDst, uint32_t nDstSize, const T* strSrc, T** pUnusedPtr) const;
void PrepareBuffer(uint32_t nNeededSize);
template<typename Type> CTmplStringBase& Assign(Type& Data);
template<typename Type> CTmplStringBase& AppendNum(Type& Data, const T* strFormat);
T* m_pData;
T* m_pUnusedStart;
uint32_t m_nSize; // Number of elements in m_pData
static const uint32_t nDefaultSize = 10;
};
//template<typename T> CTmplStringBase<T, Traits>& operator += (CTmplStringBase<T, Traits>& rlhs, const T* strData);
//template<typename T> CTmplStringBase<T, Traits>& operator += (CTmplStringBase<T, Traits>& rlhs, const T cData);
//template<typename T> CTmplStringBase<T, Traits>& operator += (CTmplStringBase<T, Traits>& rlhs, uint64_t nData);
//template<typename T> CTmplStringBase<T, Traits>& operator += (CTmplStringBase<T, Traits>& rlhs, int64_t nData);
//template<typename T> CTmplStringBase<T, Traits>& operator += (CTmplStringBase<T, Traits>& rlhs, long nData);
//template<typename T> bool operator == (CTmplStringBase<T, Traits>& rlhs, const T* strData);
//template<typename T> bool operator == (CTmplStringBase<T, Traits>& rlhs, const T cData);
//template<typename T> bool operator != (CTmplStringBase<T, Traits>& rlhs, const T* strData);
//template<typename T> bool operator != (CTmplStringBase<T, Traits>& rlhs, const T cData);
//#ifndef STRINGEXIMPL_H
// template<> class __declspec(dllimport) CTmplStringBase<wchar_t>;
// template<> class __declspec(dllimport) CTmplStringBase<char>;
// template<> class __declspec(dllimport) StrTraits<wchar_t>;
// template<> class __declspec(dllimport) StrTraits<char>;
// template<> class __declspec(dllimport) Strings::StrTraits<char>;
// template<> __declspec(dllimport) CTmplStringBase<char>& operator += (CTmplStringBase<char>& rlhs, const char* strData);
// template<> __declspec(dllimport) CTmplStringBase<char>& operator += (CTmplStringBase<char>& rlhs, const char cData);
// template<> __declspec(dllimport) CTmplStringBase<char>& operator += (CTmplStringBase<char>& rlhs, uint64_t nData);
// template<> __declspec(dllimport) CTmplStringBase<char>& operator += (CTmplStringBase<char>& rlhs, int64_t nData);
// template<> __declspec(dllimport) CTmplStringBase<char>& operator += (CTmplStringBase<char>& rlhs, long nData);
// template<> __declspec(dllimport) bool operator == (CTmplStringBase<char>& rlhs, const char* strData);
// template<> __declspec(dllimport) bool operator == (CTmplStringBase<char>& rlhs, const char cData);
// template<> __declspec(dllimport) bool operator != (CTmplStringBase<char>& rlhs, const char* strData);
// template<> __declspec(dllimport) bool operator != (CTmplStringBase<char>& rlhs, const char cData);
// template<> __declspec(dllimport) CTmplStringBase<wchar_t>& operator += (CTmplStringBase<wchar_t>& rlhs, const wchar_t* strData);
// template<> __declspec(dllimport) CTmplStringBase<wchar_t>& operator += (CTmplStringBase<wchar_t>& rlhs, const wchar_t cData);
// template<> __declspec(dllimport) CTmplStringBase<wchar_t>& operator += (CTmplStringBase<wchar_t>& rlhs, uint64_t nData);
// template<> __declspec(dllimport) CTmplStringBase<wchar_t>& operator += (CTmplStringBase<wchar_t>& rlhs, int64_t nData);
// template<> __declspec(dllimport) CTmplStringBase<wchar_t>& operator += (CTmplStringBase<wchar_t>& rlhs, long nData);
// template<> __declspec(dllimport) bool operator == (CTmplStringBase<wchar_t>& rlhs, const wchar_t* strData);
// template<> __declspec(dllimport) bool operator == (CTmplStringBase<wchar_t>& rlhs, const wchar_t cData);
// template<> __declspec(dllimport) bool operator != (CTmplStringBase<wchar_t>& rlhs, const wchar_t* strData);
// template<> __declspec(dllimport) bool operator != (CTmplStringBase<wchar_t>& rlhs, const wchar_t cData);
//#endif
typedef CTmplStringBase< char, StrTraits<char> > CStringExA;
typedef CTmplStringBase< wchar_t, StrTraits<wchar_t> > CStringExW;
typedef CTmplStringBase< TCHAR, StrTraits<TCHAR> > CStringEx;
//}
//#include "StringExImpl.h"
//#ifndef STRINGEXIMPL_H
//#define STRINGEXIMPL_H
//#include "StringEx.h"
//# include "UnsafeCast.h"
//namespace Strings
//{
//template<typename T> uint32_t StrTraits<T>::GetLength(const T* strData) const { ASSERT(FALSE); return 0; }
template<> const char* StrTraits<char>::UINT64_T_IDENTIFIER = "%I64u";
template<> const char* StrTraits<char>::INT64_T_IDENTIFIER = "%I64i";
template<> const char* StrTraits<char>::LONG_IDENTIFIER = "%li";
template<> const wchar_t* StrTraits<wchar_t>::UINT64_T_IDENTIFIER = L"%I64u";
template<> const wchar_t* StrTraits<wchar_t>::INT64_T_IDENTIFIER = L"%I64i";
template<> const wchar_t* StrTraits<wchar_t>::LONG_IDENTIFIER = L"%li";
template<> uint32_t StrTraits<char>::GetLength(const char* strData) { return strlen(strData); }
template<> uint32_t StrTraits<wchar_t>::GetLength(const wchar_t* strData) { return wcslen(strData); }
template<> StrTraits<char>::fnc_tprintf_s* StrTraits<char>::GetFormatFunction(const char*) { return &sprintf_s; }
template<> StrTraits<wchar_t>::fnc_tprintf_s* StrTraits<wchar_t>::GetFormatFunction(const wchar_t*) { return &swprintf_s; }
template<> StrTraits<char>::fnc_tvprintf_s* StrTraits<char>::GetVFormatFunction(const char*) { return &vsprintf_s; }
template<> StrTraits<wchar_t>::fnc_tvprintf_s* StrTraits<wchar_t>::GetVFormatFunction(const wchar_t*) { return &vswprintf_s; }
template<> StrTraits<char>::fnc_tvcprintf* StrTraits<char>::GetVFormatCountFunction(const char*) { return &_vscprintf; }
template<> StrTraits<wchar_t>::fnc_tvcprintf* StrTraits<wchar_t>::GetVFormatCountFunction(const wchar_t*) { return &_vscwprintf; }
template<> StrTraits<char>::fnc_tcscmp* StrTraits<char>::GetCompareFunction(const char*) { return &strcmp; }
template<> StrTraits<wchar_t>::fnc_tcscmp* StrTraits<wchar_t>::GetCompareFunction(const wchar_t*) { return &wcscmp; }
template<typename T, typename Traits> CTmplStringBase<T, Traits>::CTmplStringBase()
{
Init();
}
template<typename T, typename Traits> CTmplStringBase<T, Traits>::CTmplStringBase(const CTmplStringBase<T, Traits>& rSrc)
{
Init();
*this = rSrc;
}
template<typename T, typename Traits> CTmplStringBase<T, Traits>::CTmplStringBase(const T* strData)
{
Init();
*this = strData;
}
template<typename T, typename Traits> CTmplStringBase<T, Traits>::CTmplStringBase(const T cData)
{
Init();
*this = cData;
}
#ifdef _MFC_VER
template<typename T, typename Traits> CTmplStringBase<T, Traits>::CTmplStringBase(const CStringT< T, StrTraitMFC_DLL<T> >& strSrc)
{
Init();
CopyStr(strSrc);
}
#endif
template<typename T, typename Traits> CTmplStringBase<T, Traits>::CTmplStringBase(uint64_t nData)
{
Init();
*this = nData;
}
template<typename T, typename Traits> CTmplStringBase<T, Traits>::CTmplStringBase(int64_t nData)
{
Init();
*this = nData;
}
template<typename T, typename Traits> CTmplStringBase<T, Traits>::CTmplStringBase(long nData)
{
Init();
*this = nData;
}
template<typename T, typename Traits> CTmplStringBase<T, Traits>::~CTmplStringBase()
{
delete [] m_pData;
m_nSize = 0;
}
template<typename T, typename Traits> CTmplStringBase<T, Traits>& CTmplStringBase<T, Traits>::operator = (const T* strData)
{
return Assign(strData);
}
template<typename T, typename Traits> CTmplStringBase<T, Traits>& CTmplStringBase<T, Traits>::operator = (const T cData)
{
return Assign(cData);
}
template<typename T, typename Traits> CTmplStringBase<T, Traits>& CTmplStringBase<T, Traits>::operator = (long nData)
{
return Assign(nData);
}
template<typename T, typename Traits> CTmplStringBase<T, Traits>& CTmplStringBase<T, Traits>::operator = (uint64_t nData)
{
return Assign(nData);
}
template<typename T, typename Traits> CTmplStringBase<T, Traits>& CTmplStringBase<T, Traits>::operator = (int64_t nData)
{
return Assign(nData);
}
template<typename T, typename Traits> CTmplStringBase<T, Traits>& CTmplStringBase<T, Traits>::operator = (const CTmplStringBase& rSrc)
{
CopyStr(rSrc.m_pData);
return *this;
}
#ifdef _MFC_VER
template<typename T, typename Traits> CTmplStringBase<T, Traits>& CTmplStringBase<T, Traits>::operator = (const CStringT< T, StrTraitMFC_DLL<T> >& rSrc)
{
return Assign(rSrc);
}
#endif
template<typename T, typename Traits> CTmplStringBase<T, Traits>& operator += (CTmplStringBase<T, Traits>& rlhs, const T* strData)
{
rlhs.AppendStr(strData);
return rlhs;
}
template<typename T, typename Traits> CTmplStringBase<T, Traits>& operator += (CTmplStringBase<T, Traits>& rlhs, const T cData)
{
rlhs.PrepareBuffer(1);
*rlhs.m_pUnusedStart++ = cData;
*rlhs.m_pUnusedStart = 0;
return rlhs;
}
template<typename T, typename Traits> CTmplStringBase<T, Traits>& operator += (CTmplStringBase<T, Traits>& rlhs, uint64_t nData)
{
return rlhs.AppendNum(nData, CTmplStringBase<T, Traits>::UINT64_T_IDENTIFIER);
}
template<typename T, typename Traits> CTmplStringBase<T, Traits>& operator += (CTmplStringBase<T, Traits>& rlhs, int64_t nData)
{
return rlhs.AppendNum(nData, CTmplStringBase<T, Traits>::INT64_T_IDENTIFIER);
}
template<typename T, typename Traits> CTmplStringBase<T, Traits>& operator += (CTmplStringBase<T, Traits>& rlhs, long nData)
{
return rlhs.AppendNum(nData, CTmplStringBase<T, Traits>::LONG_IDENTIFIER);
}
template<typename T, typename Traits> bool operator == (CTmplStringBase<T, Traits>& rlhs, const T* strData)
{
typename CTmplStringBase<T, Traits>::fnc_tcscmp* Compare = rlhs.GetCompareFunction(strData);
return (Compare(rlhs.m_pData, strData) == 0);
}
template<typename T, typename Traits> bool operator == (CTmplStringBase<T, Traits>& rlhs, const T cData)
{
return (cData == rlhs.m_pData[0]);
}
template<typename T, typename Traits> bool operator != (CTmplStringBase<T, Traits>& rlhs, const T* strData)
{
return !(rlhs == strData);
}
template<typename T, typename Traits> bool operator != (CTmplStringBase<T, Traits>& rlhs, const T cData)
{
return !(rlhs == cData);
}
template<typename T, typename Traits> CTmplStringBase<T, Traits>::operator const T* () const
{
return m_pData;
}
//template<typename T, typename Traits> const T* CTmplStringBase<T, Traits>::GetString() const
//{
// return m_pData;
//}
template<typename T, typename Traits> void CTmplStringBase<T, Traits>::Replace(const CTmplStringBase& strReplaceWhat, const CTmplStringBase& strReplaceWith)
{
int32_t nNeededSize = ReplaceInternal(strReplaceWhat, strReplaceWith, false);
if (nNeededSize > 0) PrepareBuffer(nNeededSize);
ReplaceInternal(strReplaceWhat, strReplaceWith, true);
}
template<typename T, typename Traits> CTmplStringBase<T, Traits> CTmplStringBase<T, Traits>::Right(uint32_t nCount) const
{
CTmplStringBase<T, Traits> strTemp;
unsigned int nSize = ((unsigned int)(m_pUnusedStart - nCount + 1));
T* pBuffer = strTemp.GetBuffer(nSize);
CopyStrLowLevel(pBuffer, nSize, m_pUnusedStart - nCount, NULL);
strTemp.ReleaseBuffer();
return strTemp;
}
template<typename T, typename Traits> void CTmplStringBase<T, Traits>::Delete(uint32_t nStartFrom, uint32_t nCount)
{
if (nCount == 0)
{
m_pData[nStartFrom] = 0;
m_pUnusedStart = &m_pData[nStartFrom];
return;
}
unsigned int nBufferSize = (m_pData + m_nSize) - (m_pData + nStartFrom);
memmove_s(m_pData + nStartFrom, nBufferSize, m_pData + nStartFrom + nCount, nBufferSize);
m_pUnusedStart -= nCount;
}
template<typename T, typename Traits> uint32_t CTmplStringBase<T, Traits>::GetLength() const
{
return m_pUnusedStart - m_pData;
}
template<typename T, typename Traits> T* CTmplStringBase<T, Traits>::GetBuffer(uint32_t nMinSize)
{
PrepareBuffer(nMinSize);
return m_pData;
}
template<typename T, typename Traits> void CTmplStringBase<T, Traits>::ReleaseBuffer()
{
m_pUnusedStart = m_pData + StrTraits<T>::GetLength(m_pData);
}
template<typename T, typename Traits> void CTmplStringBase<T, Traits>::Truncate(uint32_t nNewSize)
{
m_pData[nNewSize] = 0;
m_pUnusedStart = &m_pData[nNewSize];
}
template<typename T, typename Traits> int32_t CTmplStringBase<T, Traits>::Find(const T* strFind, uint32_t nBeginAt) const
{
const T* pStart = m_pData + nBeginAt;
const T* pEnd = m_pData + GetLength();
const T* p = pStart;
uint32_t nFindLength = StrTraits<T>::GetLength(strFind);
while (pStart < pEnd)
{
if (uint32_t(pEnd - pStart) < nFindLength) return -1;
if (*p == *strFind)
{
bool bMatch = true;
for (uint32_t i = 1; i < nFindLength; i++)
{
if (p[i] != strFind[i])
{
bMatch = false;
break;
}
}
if (bMatch) return (p - m_pData);
}
p++;
}
return -1;
}
template<typename T, typename Traits> int32_t CTmplStringBase<T, Traits>::Find(const T cFind, uint32_t nBeginAt) const
{
CTmplStringBase<T, Traits> strTemp = cFind;
return Find(strTemp, nBeginAt);
}
template<typename T, typename Traits> int32_t CTmplStringBase<T, Traits>::ReplaceInternal(const CTmplStringBase& strReplaceWhat, const CTmplStringBase& strReplaceWith, bool bReplace)
{
const T* m_pDataEnd = m_pUnusedStart;
const T* pBufferEnd = m_pData + m_nSize;
uint32_t nReplaceWhatSize = StrTraits<T>::GetLength(strReplaceWhat);
uint32_t nReplaceWithSize = StrTraits<T>::GetLength(strReplaceWith);
int32_t nNeededSize = 0;
int32_t nIndex = 0;
while ( (nIndex = Find(strReplaceWhat, nIndex)) > -1 )
{
if (nIndex >= 0)
{
T* p = m_pData + nIndex;
int32_t nAdjustSize = (nReplaceWhatSize - nReplaceWithSize);
if (!bReplace)
{
nNeededSize += nAdjustSize;
nIndex++;
continue;
}
// Move data so we can copy new data into place:
// This is a test --> This is a test
T* pCopyDataStart = p + nReplaceWithSize;
unsigned int nDataToCopy = m_pDataEnd - pCopyDataStart;
if (nDataToCopy > 0) CopyStrLowLevel(pCopyDataStart, nDataToCopy, pCopyDataStart, NULL);
// Copy new data into place, overwriting old data with new:
// This is a test --> This is an test
// Hint: There is always 0 beyond the end of the data, so out buffer is actually
CopyStrLowLevel(p, pBufferEnd - p, strReplaceWith, NULL);
}
nIndex++;
}
if (bReplace)
m_pUnusedStart = m_pData + StrTraits<T>::GetLength(m_pData);
return nNeededSize;
}
template<typename T, typename Traits> void CTmplStringBase<T, Traits>::FormatInternal(const T* strFormat, va_list arg)
{
typename Traits::fnc_tvprintf_s* vformat_s = Traits::GetVFormatFunction(strFormat);
typename Traits::fnc_tvcprintf* vformat_count = Traits::GetVFormatCountFunction(strFormat);
uint32_t nSizeNeeded = vformat_count(strFormat, arg);
uint32_t nUsedSize = GetLength();
uint32_t nTotalSize = nUsedSize + nSizeNeeded;
PrepareBuffer(nTotalSize);
vformat_s(m_pUnusedStart, m_nSize - GetLength(), strFormat, arg);
m_pUnusedStart = m_pData + StrTraits<T>::GetLength(m_pData);
}
template<typename T, typename Traits> void CTmplStringBase<T, Traits>::Init()
{
m_nSize = nDefaultSize;
m_pUnusedStart = m_pData = new T[m_nSize];
*m_pData = 0;
}
template<typename T, typename Traits> void CTmplStringBase<T, Traits>::CopyStrLowLevel(T* strDst, uint32_t nDstSize, const T* strSrc, T** pUnusedPtr) const
{
uint32_t nSize = StrTraits<T>::GetLength(strSrc) + 1;
memcpy_s(strDst, nDstSize * sizeof(T), strSrc, nSize * sizeof(T));
if (pUnusedPtr) *pUnusedPtr += (nSize - 1);
}
template<typename T, typename Traits> void CTmplStringBase<T, Traits>::CopyStr(const T* strData)
{
PrepareBuffer( GetLength() + 1 + StrTraits<T>::GetLength(strData) );
CopyStrLowLevel(m_pData, m_nSize, strData, &m_pUnusedStart);
}
template<typename T, typename Traits> void CTmplStringBase<T, Traits>::AppendStr(const T* strData)
{
PrepareBuffer( GetLength() + 1 + StrTraits<T>::GetLength(strData) );
CopyStrLowLevel(m_pUnusedStart, m_nSize, strData, &m_pUnusedStart);
}
template<typename T, typename Traits> void CTmplStringBase<T, Traits>::PrepareBuffer(uint32_t nNeededSize)
{
if (m_nSize - GetLength() < nNeededSize)
{
uint32_t nNewSize = m_nSize + nNeededSize * 2 + nDefaultSize;
T* pTemp = new T[nNewSize];
T* pUnusedTemp = pTemp;
CopyStrLowLevel(pTemp, nNewSize, m_pData, &pUnusedTemp);
this->~CTmplStringBase();
m_pData = pTemp;
m_nSize = nNewSize;
m_pUnusedStart = pUnusedTemp;
}
}
template<typename T, typename Traits> template<typename Type> CTmplStringBase<T, Traits>& CTmplStringBase<T, Traits>::Assign(Type& Data)
{
//m_pUnusedStart = m_pData;
Empty();
*this += Data;
return *this;
}
template<typename T, typename Traits> template<typename Type> CTmplStringBase<T, Traits>& CTmplStringBase<T, Traits>::AppendNum(Type& Data, const T* strFormat)
{
T temp[21];
typename CTmplStringBase<T, Traits>::fnc_tprintf_s* tprintf_s = GetFormatFunction(temp);
tprintf_s(temp, sizeof(temp) / sizeof(T), strFormat, Data);
PrepareBuffer( StrTraits<T>::GetLength(temp) );
AppendStr(temp);
return *this;
}
template<typename T, typename Traits> CTmplStringBase<T, Traits> CTmplStringBase<T, Traits>::Mid(uint32_t nStart, uint32_t nCount) const
{
CTmplStringBase<T, Traits> strTemp;
uint32_t nSize = nCount;
if (nSize == 0)
nCount = nSize = m_pUnusedStart - (m_pData + nStart);
nSize++;
T* pBuffer = strTemp.GetBuffer(nSize);
memcpy_s(pBuffer, nSize * sizeof(T), m_pData + nStart, nCount * sizeof(T));
pBuffer[nSize - 1] = 0;
strTemp.ReleaseBuffer();
return strTemp;
}
template<typename T, typename Traits> void CTmplStringBase<T, Traits>::Format(const T* strFormat, ...)
{
Empty();
va_list arg;
va_start(arg, strFormat);
FormatInternal(strFormat, arg);
}
template<typename T, typename Traits> void CTmplStringBase<T, Traits>::AppendFormat(const T* strFormat, ...)
{
va_list arg;
va_start(arg, strFormat);
FormatInternal(strFormat, arg);
}
template<typename T, typename Traits> void CTmplStringBase<T, Traits>::Empty()
{
m_pUnusedStart = m_pData;
*m_pData = 0;
}
}
//#endif // STRINGEXIMPL_H
#endif // STRINGEX_H