Author: mjansen
Date: Sat Jul 30 19:07:43 2016
New Revision: 72061
URL:
http://svn.reactos.org/svn/reactos?rev=72061&view=rev
Log:
[ATL][ATL_APITEST] Implement / Improve CString, based upon the code that was already
there. CORE-11579 #resolve
Add code + tests for:
Conversion of A->W and W->A, equality operators, MakeLower, MakeUpper, Find,
FindOneOf, ReverseFind, Compare, Mid, Left, Right, Format, Replace, Trim, TrimLeft,
TrimRight.
Added:
trunk/rostests/apitests/atl/CString.cpp (with props)
trunk/rostests/apitests/atl/CString.inl (with props)
Modified:
trunk/reactos/sdk/lib/atl/atlsimpstr.h
trunk/reactos/sdk/lib/atl/atlstr.h
trunk/reactos/sdk/lib/atl/cstringt.h
trunk/rostests/apitests/atl/CMakeLists.txt
trunk/rostests/apitests/atl/testlist.c
Modified: trunk/reactos/sdk/lib/atl/atlsimpstr.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/sdk/lib/atl/atlsimpstr.h?r…
==============================================================================
--- trunk/reactos/sdk/lib/atl/atlsimpstr.h [iso-8859-1] (original)
+++ trunk/reactos/sdk/lib/atl/atlsimpstr.h [iso-8859-1] Sat Jul 30 19:07:43 2016
@@ -200,6 +200,28 @@
return *this;
}
+ CSimpleStringT& operator=(_In_ const CSimpleStringT& strSrc)
+ {
+ CStringData* pData = GetData();
+ CStringData* pNewData = strSrc.GetData();
+
+ if (pNewData != pData)
+ {
+ if (!pData->IsLocked() && (pNewData->pStringMgr ==
pData->pStringMgr))
+ {
+ pNewData = CloneData(pNewData);
+ pData->Release();
+ Attach(pNewData);
+ }
+ else
+ {
+ SetString(strSrc.GetString(), strSrc.GetLength());
+ }
+ }
+
+ return *this;
+ }
+
CSimpleStringT& operator+=(_In_ const CSimpleStringT& strSrc)
{
Append(strSrc);
@@ -495,7 +517,7 @@
if (pOldData->IsShared())
{
Fork(nLength);
- ATLASSERT(FALSE);
+ //ATLASSERT(FALSE);
}
else if (pOldData->nAllocLength < nLength)
{
Modified: trunk/reactos/sdk/lib/atl/atlstr.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/sdk/lib/atl/atlstr.h?rev=7…
==============================================================================
--- trunk/reactos/sdk/lib/atl/atlstr.h [iso-8859-1] (original)
+++ trunk/reactos/sdk/lib/atl/atlstr.h [iso-8859-1] Sat Jul 30 19:07:43 2016
@@ -124,6 +124,12 @@
typedef CStringT< wchar_t, StrTraitATL< wchar_t, ChTraitsCRT<wchar_t> >
> CAtlStringW;
+typedef CStringT< char, StrTraitATL< char, ChTraitsCRT<char> > >
CAtlStringA;
+
+
+typedef CAtlStringW CStringW;
+typedef CAtlStringA CStringA;
+
}
Modified: trunk/reactos/sdk/lib/atl/cstringt.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/sdk/lib/atl/cstringt.h?rev…
==============================================================================
--- trunk/reactos/sdk/lib/atl/cstringt.h [iso-8859-1] (original)
+++ trunk/reactos/sdk/lib/atl/cstringt.h [iso-8859-1] Sat Jul 30 19:07:43 2016
@@ -28,14 +28,28 @@
static int __cdecl GetBaseTypeLength(_In_z_ LPCWSTR pszSource) throw()
{
- return ::WideCharToMultiByte(_AtlGetConversionACP(), 0, pszSource, -1, NULL, 0,
NULL, NULL) - 1;
+ if (pszSource == NULL) return -1;
+ return static_cast<int>(wcslen(pszSource));
+ }
+
+ static int __cdecl GetBaseTypeLength(_In_z_ LPCSTR pszSource) throw()
+ {
+ if (pszSource == NULL) return 0;
+ return ::MultiByteToWideChar(_AtlGetConversionACP(), 0, pszSource, -1, NULL, 0) -
1;
}
static int __cdecl GetBaseTypeLength(
_In_reads_(nLength) LPCWSTR pszSource,
_In_ int nLength) throw()
{
- return ::WideCharToMultiByte(_AtlGetConversionACP(), 0, pszSource, nLength, NULL,
0, NULL, NULL);
+ return nLength;
+ }
+
+ static int __cdecl GetBaseTypeLength(
+ _In_reads_(nLength) LPCSTR pszSource,
+ _In_ int nLength) throw()
+ {
+ return ::MultiByteToWideChar(_AtlGetConversionACP(), 0, pszSource, nLength, NULL,
0);
}
static void __cdecl ConvertToBaseType(
@@ -49,8 +63,197 @@
wmemcpy(pszDest, pszSrc, nSrcLength);
}
+
+ static void __cdecl ConvertToBaseType(
+ _Out_writes_(nDestLength) LPWSTR pszDest,
+ _In_ int nDestLength,
+ _In_ LPCSTR pszSrc,
+ _In_ int nSrcLength = -1)
+ {
+ if (nSrcLength == -1)
+ nSrcLength = 1 + GetBaseTypeLength(pszSrc);
+
+ ::MultiByteToWideChar(_AtlGetConversionACP(), 0, pszSrc, nSrcLength, pszDest,
nDestLength);
+ }
+
+ static void __cdecl MakeLower(
+ _Out_writes_(nSrcLength) LPWSTR pszSource,
+ _In_ int nSrcLength)
+ {
+ ::CharLowerBuffW(pszSource, nSrcLength);
+ }
+
+ static void __cdecl MakeUpper(
+ _Out_writes_(nSrcLength) LPWSTR pszSource,
+ _In_ int nSrcLength)
+ {
+ ::CharUpperBuffW(pszSource, nSrcLength);
+ }
+
+ static LPWSTR __cdecl FindString(
+ _In_z_ LPCWSTR pszSource,
+ _In_z_ LPCWSTR pszSub)
+ {
+ return ::wcsstr(pszSource, pszSub);
+ }
+
+ static LPWSTR __cdecl FindChar(
+ _In_z_ LPCWSTR pszSource,
+ _In_ WCHAR ch)
+ {
+ return ::wcschr(pszSource, ch);
+ }
+
+ static LPWSTR __cdecl FindCharReverse(
+ _In_z_ LPCWSTR pszSource,
+ _In_ WCHAR ch)
+ {
+ return ::wcsrchr(pszSource, ch);
+ }
+
+ static LPWSTR __cdecl FindOneOf(
+ _In_z_ LPCWSTR pszSource,
+ _In_z_ LPCWSTR pszCharSet)
+ {
+ return ::wcspbrk(pszSource, pszCharSet);
+ }
+
+ static int __cdecl Compare(
+ _In_z_ LPCWSTR psz1,
+ _In_z_ LPCWSTR psz2)
+ {
+ return ::wcscmp(psz1, psz2);
+ }
+
+ static int __cdecl FormatV(
+ _In_opt_z_ LPWSTR pszDest,
+ _In_z_ LPCWSTR pszFormat,
+ _In_ va_list args)
+ {
+ if (pszDest == NULL)
+ return ::_vscwprintf(pszFormat, args);
+ return ::vswprintf(pszDest, pszFormat, args);
+ }
+
};
+
+// Template specialization
+
+template<>
+class ChTraitsCRT<char> : public ChTraitsBase<char>
+{
+public:
+
+ static int __cdecl GetBaseTypeLength(_In_z_ LPCWSTR pszSource) throw()
+ {
+ return ::WideCharToMultiByte(_AtlGetConversionACP(), 0, pszSource, -1, NULL, 0,
NULL, NULL) - 1;
+ }
+
+ static int __cdecl GetBaseTypeLength(_In_z_ LPCSTR pszSource) throw()
+ {
+ if (pszSource == NULL) return 0;
+ return static_cast<int>(strlen(pszSource));
+ }
+
+ static int __cdecl GetBaseTypeLength(
+ _In_reads_(nLength) LPCWSTR pszSource,
+ _In_ int nLength) throw()
+ {
+ return ::WideCharToMultiByte(_AtlGetConversionACP(), 0, pszSource, nLength, NULL,
0, NULL, NULL);
+ }
+
+ static int __cdecl GetBaseTypeLength(
+ _In_reads_(nLength) LPCSTR pszSource,
+ _In_ int nLength) throw()
+ {
+ return nLength;
+ }
+
+ static void __cdecl ConvertToBaseType(
+ _Out_writes_(nDestLength) LPSTR pszDest,
+ _In_ int nDestLength,
+ _In_ LPCWSTR pszSrc,
+ _In_ int nSrcLength = -1)
+ {
+ if (nSrcLength == -1)
+ nSrcLength = 1 + GetBaseTypeLength(pszSrc);
+
+ ::WideCharToMultiByte(_AtlGetConversionACP(), 0, pszSrc, nSrcLength, pszDest,
nDestLength, NULL, NULL);
+ }
+
+ static void __cdecl ConvertToBaseType(
+ _Out_writes_(nDestLength) LPSTR pszDest,
+ _In_ int nDestLength,
+ _In_ LPCSTR pszSrc,
+ _In_ int nSrcLength = -1)
+ {
+ if (nSrcLength == -1)
+ nSrcLength = 1 + GetBaseTypeLength(pszSrc);
+
+ memcpy(pszDest, pszSrc, nSrcLength);
+ }
+
+ static void __cdecl MakeLower(
+ _Out_writes_(nSrcLength) LPSTR pszSource,
+ _In_ int nSrcLength)
+ {
+ ::CharLowerBuffA(pszSource, nSrcLength);
+ }
+
+ static void __cdecl MakeUpper(
+ _Out_writes_(nSrcLength) LPSTR pszSource,
+ _In_ int nSrcLength)
+ {
+ ::CharUpperBuffA(pszSource, nSrcLength);
+ }
+
+ static LPSTR __cdecl FindString(
+ _In_z_ LPCSTR pszSource,
+ _In_z_ LPCSTR pszSub)
+ {
+ return ::strstr(pszSource, pszSub);
+ }
+
+ static LPSTR __cdecl FindChar(
+ _In_z_ LPCSTR pszSource,
+ _In_ CHAR ch)
+ {
+ return ::strchr(pszSource, ch);
+ }
+
+ static LPSTR __cdecl FindCharReverse(
+ _In_z_ LPCSTR pszSource,
+ _In_ CHAR ch)
+ {
+ return ::strrchr(pszSource, ch);
+ }
+
+ static LPSTR __cdecl FindOneOf(
+ _In_z_ LPCSTR pszSource,
+ _In_z_ LPCSTR pszCharSet)
+ {
+ return ::strpbrk(pszSource, pszCharSet);
+ }
+
+ static int __cdecl Compare(
+ _In_z_ LPCSTR psz1,
+ _In_z_ LPCSTR psz2)
+ {
+ return ::strcmp(psz1, psz2);
+ }
+
+ static int __cdecl FormatV(
+ _In_opt_z_ LPSTR pszDest,
+ _In_z_ LPCSTR pszFormat,
+ _In_ va_list args)
+ {
+ if (pszDest == NULL)
+ return ::_vscprintf(pszFormat, args);
+ return ::vsprintf(pszDest, pszFormat, args);
+ }
+
+};
namespace _CSTRING_IMPL_
@@ -62,6 +265,8 @@
};
}
+
+// TODO: disable conversion functions when _CSTRING_DISABLE_NARROW_WIDE_CONVERSION is
defined.
template <typename BaseType, class StringTraits>
class CStringT :
@@ -90,12 +295,19 @@
static void __cdecl Construct(_In_ CStringT* pString)
{
- pString = new CStringT;
+ new(pString) CStringT;
}
CStringT(_In_ const CStringT& strSrc) :
CThisSimpleString(strSrc)
{
+ }
+
+ template<class StringTraits_>
+ CStringT(_In_ const CStringT<YCHAR, StringTraits_> & strSrc) :
+ CThisSimpleString(StringTraits::GetDefaultManager())
+ {
+ *this = static_cast<const YCHAR*>(strSrc);
}
CStringT(_In_opt_z_ const XCHAR* pszSrc) :
@@ -114,6 +326,36 @@
*this = pszSrc;
}
+ CStringT(_In_opt_z_ const YCHAR* pszSrc) :
+ CThisSimpleString( StringTraits::GetDefaultManager() )
+ {
+ // FIXME: Check whether pszSrc is not a resource string ID!
+ *this = pszSrc;
+ }
+
+ CStringT(
+ _In_opt_z_ const YCHAR* pszSrc,
+ _In_ IAtlStringMgr* pStringMgr) :
+ CThisSimpleString( pStringMgr )
+ {
+ // FIXME: Check whether pszSrc is not a resource string ID!
+ *this = pszSrc;
+ }
+
+ CStringT(
+ _In_reads_z_(nLength) const XCHAR* pch,
+ _In_ int nLength) :
+ CThisSimpleString(pch, nLength, StringTraits::GetDefaultManager())
+ {
+ }
+
+ CStringT(
+ _In_reads_z_(nLength) const YCHAR* pch,
+ _In_ int nLength) :
+ CThisSimpleString(pch, nLength, StringTraits::GetDefaultManager())
+ {
+ }
+
CStringT& operator=(_In_ const CStringT& strSrc)
{
CThisSimpleString::operator=(strSrc);
@@ -124,6 +366,59 @@
{
CThisSimpleString::operator=(pszSrc);
return *this;
+ }
+
+ CStringT& operator=(_In_opt_z_ PCYSTR pszSrc)
+ {
+ int length = pszSrc ? StringTraits::GetBaseTypeLength(pszSrc) : 0;
+ if (length > 0)
+ {
+ PXSTR result = CThisSimpleString::GetBuffer(length);
+ StringTraits::ConvertToBaseType(result, length, pszSrc);
+ CThisSimpleString::ReleaseBufferSetLength(length);
+ }
+ else
+ {
+ CThisSimpleString::Empty();
+ }
+ return *this;
+ }
+
+ friend bool operator==(const CStringT& str1, const CStringT& str2) throw()
+ {
+ return str1.Compare(str2) == 0;
+ }
+
+ friend bool operator==(const CStringT& str1, PCXSTR psz2) throw()
+ {
+ return str1.Compare(psz2) == 0;
+ }
+
+ friend bool operator==(const CStringT& str1, PCYSTR psz2) throw()
+ {
+ CStringT tmp(psz2, str1.GetManager());
+ return tmp == str1;
+ }
+
+ friend bool operator==(const CStringT& str1, XCHAR ch2) throw()
+ {
+ return str1.GetLength() == 1 && str1[0] == ch2;
+ }
+
+ friend bool operator==(PCXSTR psz1, const CStringT& str2) throw()
+ {
+ return str2.Compare(psz1) == 0;
+ }
+
+ friend bool operator==(PCYSTR psz1, const CStringT& str2) throw()
+ {
+ CStringT tmp(psz1, str2.GetManager());
+ return tmp.Compare(str2) == 0;
+ }
+
+ friend bool operator==(XCHAR ch1, const CStringT& str2) throw()
+ {
+ return str2.GetLength() == 1 && str2[0] == ch1;
}
CStringT& operator+=(_In_ const CThisSimpleString& str)
@@ -151,6 +446,299 @@
return TRUE;
}
+
+ CStringT& MakeLower()
+ {
+ int nLength = CThisSimpleString::GetLength();
+ PXSTR pszBuffer = CThisSimpleString::GetBuffer(nLength);
+
+ StringTraits::MakeLower(pszBuffer, nLength);
+ CThisSimpleString::ReleaseBufferSetLength(nLength);
+
+ return *this;
+ }
+
+ CStringT& MakeUpper()
+ {
+ int nLength = CThisSimpleString::GetLength();
+ PXSTR pszBuffer = CThisSimpleString::GetBuffer(nLength);
+
+ StringTraits::MakeUpper(pszBuffer, nLength);
+ CThisSimpleString::ReleaseBufferSetLength(nLength);
+
+ return *this;
+ }
+
+ int Find(_In_ PCXSTR pszSub, _In_opt_ int iStart = 0) const throw()
+ {
+ int nLength = CThisSimpleString::GetLength();
+
+ if (iStart >= nLength || iStart < 0)
+ return -1;
+
+ PCXSTR pszString = CThisSimpleString::GetString();
+ PCXSTR pszResult = StringTraits::FindString(pszString + iStart, pszSub);
+
+ return pszResult ? ((int)(pszResult - pszString)) : -1;
+ }
+
+ int Find(_In_ XCHAR ch, _In_opt_ int iStart = 0) const throw()
+ {
+ int nLength = CThisSimpleString::GetLength();
+
+ if (iStart >= nLength || iStart < 0)
+ return -1;
+
+ PCXSTR pszString = CThisSimpleString::GetString();
+ PCXSTR pszResult = StringTraits::FindChar(pszString + iStart, ch);
+
+ return pszResult ? ((int)(pszResult - pszString)) : -1;
+ }
+
+ int FindOneOf(_In_ PCXSTR pszCharSet) const throw()
+ {
+ PCXSTR pszString = CThisSimpleString::GetString();
+ PCXSTR pszResult = StringTraits::FindOneOf(pszString, pszCharSet);
+
+ return pszResult ? ((int)(pszResult - pszString)) : -1;
+ }
+
+ int ReverseFind(_In_ XCHAR ch) const throw()
+ {
+ PCXSTR pszString = CThisSimpleString::GetString();
+ PCXSTR pszResult = StringTraits::FindCharReverse(pszString, ch);
+
+ return pszResult ? ((int)(pszResult - pszString)) : -1;
+ }
+
+ int Compare(_In_z_ PCXSTR psz) const
+ {
+ return StringTraits::Compare(CThisSimpleString::GetString(), psz);
+ }
+
+
+ CStringT Mid(int iFirst, int nCount) const
+ {
+ int nLength = CThisSimpleString::GetLength();
+
+ if (iFirst < 0)
+ iFirst = 0;
+ if (nCount < 0)
+ nCount = 0;
+ if (iFirst > nLength)
+ iFirst = nLength;
+ if (iFirst + nCount > nLength)
+ nCount = nLength - iFirst;
+
+ return CStringT(CThisSimpleString::GetString() + iFirst, nCount);
+ }
+
+ CStringT Mid(int iFirst) const
+ {
+ int nLength = CThisSimpleString::GetLength();
+
+ if (iFirst < 0)
+ iFirst = 0;
+ if (iFirst > nLength)
+ iFirst = nLength;
+
+ return CStringT(CThisSimpleString::GetString() + iFirst, nLength - iFirst);
+ }
+
+ CStringT Left(int nCount) const
+ {
+ int nLength = CThisSimpleString::GetLength();
+
+ if (nCount < 0)
+ nCount = 0;
+ if (nCount > nLength)
+ nCount = nLength;
+
+ return CStringT(CThisSimpleString::GetString(), nCount);
+ }
+
+ CStringT Right(int nCount) const
+ {
+ int nLength = CThisSimpleString::GetLength();
+
+ if (nCount < 0)
+ nCount = 0;
+ if (nCount > nLength)
+ nCount = nLength;
+
+ return CStringT(CThisSimpleString::GetString() + nLength - nCount, nCount);
+ }
+
+
+ //void __cdecl Format(UINT nFormatID, ...)
+ //{
+ // va_list args;
+ // va_start(args, dwMessageId);
+ // CStringT formatString;
+ // formatString.LoadString(?????);
+ // FormatV(formatString, args);
+ // va_end(args);
+ //}
+
+ void __cdecl Format(PCXSTR pszFormat, ...)
+ {
+ va_list args;
+ va_start(args, pszFormat);
+ FormatV(pszFormat, args);
+ va_end(args);
+ }
+
+ void FormatV(PCXSTR pszFormat, va_list args)
+ {
+ int nLength = StringTraits::FormatV(NULL, pszFormat, args);
+
+ PXSTR pszBuffer = CThisSimpleString::GetBuffer(nLength);
+ StringTraits::FormatV(pszBuffer, pszFormat, args);
+ CThisSimpleString::ReleaseBufferSetLength(nLength);
+ }
+
+
+ int Replace(PCXSTR pszOld, PCXSTR pszNew)
+ {
+ PCXSTR pszString = CThisSimpleString::GetString();
+
+ const int nLength = CThisSimpleString::GetLength();
+ const int nOldLen = StringTraits::GetBaseTypeLength(pszOld);
+ const int nNewLen = StringTraits::GetBaseTypeLength(pszNew);
+ const int nDiff = nNewLen - nOldLen;
+ int nResultLength = nLength;
+
+ PCXSTR pszFound;
+ while ((pszFound = StringTraits::FindString(pszString, pszOld)))
+ {
+ nResultLength += nDiff;
+ pszString = pszFound + nOldLen;
+ }
+
+ if (pszString == CThisSimpleString::GetString())
+ return 0;
+
+ PXSTR pszResult = CThisSimpleString::GetBuffer(nResultLength);
+ PXSTR pszNext;
+ int nCount = 0, nRemaining = nLength;
+ while (nRemaining && (pszNext = StringTraits::FindString(pszResult,
pszOld)))
+ {
+ nRemaining -= (pszNext - pszResult);
+ nRemaining -= nOldLen;
+ if (nRemaining > 0)
+ CThisSimpleString::CopyCharsOverlapped(pszNext + nNewLen, nRemaining + 1,
pszNext + nOldLen, nRemaining + 1);
+ CThisSimpleString::CopyCharsOverlapped(pszNext, nNewLen, pszNew, nNewLen);
+ pszResult = pszNext + nNewLen;
+ nCount++;
+ }
+
+ CThisSimpleString::ReleaseBufferSetLength(nResultLength);
+
+ return nCount;
+ }
+
+ int Replace(XCHAR chOld, XCHAR chNew)
+ {
+ PCXSTR pszString = CThisSimpleString::GetString();
+ PXSTR pszFirst = StringTraits::FindChar(pszString, chOld);
+ if (!pszFirst)
+ return 0;
+
+ int nLength = CThisSimpleString::GetLength();
+ int nCount = 0;
+
+ PXSTR pszBuffer = CThisSimpleString::GetBuffer(nLength);
+ pszFirst = pszBuffer + (pszFirst - pszString);
+ do {
+ *pszFirst = chNew;
+ ++nCount;
+ } while ((pszFirst = StringTraits::FindChar(pszFirst + 1, chOld)));
+
+ CThisSimpleString::ReleaseBufferSetLength(nLength);
+ return nCount;
+ }
+
+
+ static PCXSTR DefaultTrimChars()
+ {
+ static XCHAR str[] = { ' ', '\t', '\r', '\n', 0
};
+ return str;
+ }
+
+
+ CStringT& TrimLeft()
+ {
+ return TrimLeft(DefaultTrimChars());
+ }
+
+ CStringT& TrimLeft(XCHAR chTarget)
+ {
+ XCHAR str[2] = { chTarget, 0 };
+ return TrimLeft(str);
+ }
+
+ CStringT& TrimLeft(PCXSTR pszTargets)
+ {
+ int nLength = CThisSimpleString::GetLength();
+ PXSTR pszBuffer = CThisSimpleString::GetBuffer(nLength);
+ int nCount = 0;
+
+ while (nCount < nLength && StringTraits::FindChar(pszTargets,
pszBuffer[nCount]))
+ nCount++;
+
+ if (nCount > 0)
+ {
+ CThisSimpleString::CopyCharsOverlapped(pszBuffer, nLength - nCount, pszBuffer
+ nCount, nLength - nCount);
+ nLength -= nCount;
+ }
+ CThisSimpleString::ReleaseBufferSetLength(nLength);
+
+ return *this;
+ }
+
+
+ CStringT& TrimRight()
+ {
+ return TrimRight(DefaultTrimChars());
+ }
+
+ CStringT& TrimRight(XCHAR chTarget)
+ {
+ XCHAR str[2] = { chTarget, 0 };
+ return TrimRight(str);
+ }
+
+ CStringT& TrimRight(PCXSTR pszTargets)
+ {
+ int nLength = CThisSimpleString::GetLength();
+ PXSTR pszBuffer = CThisSimpleString::GetBuffer(nLength);
+
+ while (nLength > 0 && StringTraits::FindChar(pszTargets,
pszBuffer[nLength-1]))
+ nLength--;
+
+ CThisSimpleString::ReleaseBufferSetLength(nLength);
+
+ return *this;
+ }
+
+
+ CStringT& Trim()
+ {
+ return Trim(DefaultTrimChars());
+ }
+
+ CStringT& Trim(XCHAR chTarget)
+ {
+ XCHAR str[2] = { chTarget, 0 };
+ return Trim(str);
+ }
+
+ CStringT& Trim(PCXSTR pszTargets)
+ {
+ return TrimRight(pszTargets).TrimLeft(pszTargets);
+ }
+
+
};
} //namespace ATL
Modified: trunk/rostests/apitests/atl/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/atl/CMakeLists.t…
==============================================================================
--- trunk/rostests/apitests/atl/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/rostests/apitests/atl/CMakeLists.txt [iso-8859-1] Sat Jul 30 19:07:43 2016
@@ -1,11 +1,12 @@
-set_cpp(WITH_RUNTIME)
+set_cpp(WITH_RUNTIME WITH_EXCEPTIONS)
include_directories(${REACTOS_SOURCE_DIR}/sdk/lib/atl)
add_executable(atl_apitest
CComBSTR.cpp
CComHeapPtr.cpp
+ CString.cpp
testlist.c
atl_apitest.rc)
Added: trunk/rostests/apitests/atl/CString.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/atl/CString.cpp?…
==============================================================================
--- trunk/rostests/apitests/atl/CString.cpp (added)
+++ trunk/rostests/apitests/atl/CString.cpp [iso-8859-1] Sat Jul 30 19:07:43 2016
@@ -0,0 +1,176 @@
+/*
+ * PROJECT: ReactOS api tests
+ * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
+ * PURPOSE: Test for CString
+ * PROGRAMMER: Mark Jansen
+ */
+
+#include <apitest.h>
+#include <atlstr.h>
+
+
+struct traits_test
+{
+ const char* strA;
+ const wchar_t* strW;
+ int str_len;
+ int exp_1, exp_2, exp_3, exp_4;
+};
+
+traits_test g_Tests[] = {
+ // inputs outputs
+ { NULL, NULL, 0, 0, 0, -1, 0 },
+ { NULL, NULL, -1, 0, -1, -1, 0 },
+ { NULL, NULL, 1, 0, 1, -1, 0 },
+
+ { "", L"", 0, 0, 0, 0, 0 },
+ { "", L"", -1, 0, -1, 0, 1 },
+ { "", L"", 1, 0, 1, 0, 1 },
+
+ { "AAABBB", L"AAABBB", 0, 6, 0, 6, 0 },
+ { "AAABBB", L"AAABBB", 3, 6, 3, 6, 3 },
+ { "AAABBB", L"AAABBB", -1, 6, -1, 6, 7 },
+};
+
+static void test_basetypes()
+{
+ int len;
+ char bufA[10];
+ wchar_t bufW[10];
+
+ for (size_t n = 0; n < _countof(g_Tests); ++n)
+ {
+ len = ChTraitsCRT<char>::GetBaseTypeLength(g_Tests[n].strA);
+ ok(len == g_Tests[n].exp_1, "Expected len to be %i, was %i for %u
(A)\n", g_Tests[n].exp_1, len, n);
+
+ len = ChTraitsCRT<char>::GetBaseTypeLength(g_Tests[n].strA,
g_Tests[n].str_len);
+ ok(len == g_Tests[n].exp_2, "Expected len to be %i, was %i for %u
(A,len)\n", g_Tests[n].exp_2, len, n);
+
+ len = ChTraitsCRT<char>::GetBaseTypeLength(g_Tests[n].strW);
+ ok(len == g_Tests[n].exp_3, "Expected len to be %i, was %i for %u
(W)\n", g_Tests[n].exp_3, len, n);
+
+ len = ChTraitsCRT<char>::GetBaseTypeLength(g_Tests[n].strW,
g_Tests[n].str_len);
+ ok(len == g_Tests[n].exp_4, "Expected len to be %i, was %i for %u
(W,len)\n", g_Tests[n].exp_4, len, n);
+
+ if (g_Tests[n].strA && g_Tests[n].strW)
+ {
+ memset(bufA, 'x', sizeof(bufA));
+ ChTraitsCRT<char>::ConvertToBaseType(bufA, g_Tests[n].exp_1+1,
g_Tests[n].strA);
+ char ch = bufA[g_Tests[n].exp_1];
+ ok(ch == '\0', "Expected %i to be \\0, was: %c (%i) for
%u\n", g_Tests[n].exp_1, ch, (int)ch, n);
+ ok(!strcmp(bufA, g_Tests[n].strA), "Expected bufA to be %s, was: %s for
%u\n", g_Tests[n].strA, bufA, n);
+ ch = bufA[g_Tests[n].exp_1+1];
+ ok(ch == 'x', "Expected %i to be 'x', was: %c (%i) for
%u\n", g_Tests[n].exp_1+1, ch, (int)ch, n);
+ }
+
+ if (g_Tests[n].strA && g_Tests[n].strW)
+ {
+ memset(bufA, 'x', sizeof(bufA));
+ ChTraitsCRT<char>::ConvertToBaseType(bufA, g_Tests[n].exp_1+1,
g_Tests[n].strW);
+ char ch = bufA[g_Tests[n].exp_1];
+ ok(ch == '\0', "Expected %i to be \\0, was: %c (%i) for
%u\n", g_Tests[n].exp_1, ch, (int)ch, n);
+ ok(!strcmp(bufA, g_Tests[n].strA), "Expected bufA to be %s, was: %s for
%u\n", g_Tests[n].strA, bufA, n);
+ ch = bufA[g_Tests[n].exp_1+1];
+ ok(ch == 'x', "Expected %i to be 'x', was: %c (%i) for
%u\n", g_Tests[n].exp_1+1, ch, (int)ch, n);
+ }
+
+ // wchar_t --> please note, swapped the expectations from 2 and 4 !
+ len = ChTraitsCRT<wchar_t>::GetBaseTypeLength(g_Tests[n].strA);
+ ok(len == g_Tests[n].exp_1, "Expected len to be %i, was %i for %u
(A)\n", g_Tests[n].exp_1, len, n);
+
+ len = ChTraitsCRT<wchar_t>::GetBaseTypeLength(g_Tests[n].strA,
g_Tests[n].str_len);
+ ok(len == g_Tests[n].exp_4, "Expected len to be %i, was %i for %u
(A,len)\n", g_Tests[n].exp_4, len, n);
+
+ len = ChTraitsCRT<wchar_t>::GetBaseTypeLength(g_Tests[n].strW);
+ ok(len == g_Tests[n].exp_3, "Expected len to be %i, was %i for %u
(W)\n", g_Tests[n].exp_3, len, n);
+
+ len = ChTraitsCRT<wchar_t>::GetBaseTypeLength(g_Tests[n].strW,
g_Tests[n].str_len);
+ ok(len == g_Tests[n].exp_2, "Expected len to be %i, was %i for %u
(W,len)\n", g_Tests[n].exp_2, len, n);
+
+ if (g_Tests[n].strA && g_Tests[n].strW)
+ {
+ memset(bufW, 'x', sizeof(bufW));
+ ChTraitsCRT<wchar_t>::ConvertToBaseType(bufW, g_Tests[n].exp_1+1,
g_Tests[n].strA);
+ wchar_t ch = bufW[g_Tests[n].exp_1];
+ ok(ch == L'\0', "Expected %i to be \\0, was: %c (%i) for
%u\n", g_Tests[n].exp_1, ch, (int)ch, n);
+ ok(!wcscmp(bufW, g_Tests[n].strW), "Expected bufW to be %s, was: %s for
%u\n", wine_dbgstr_w(g_Tests[n].strW), wine_dbgstr_w(bufW), n);
+ ch = bufW[g_Tests[n].exp_1+1];
+ ok(ch == 30840, "Expected %i to be %i for %u\n",
g_Tests[n].exp_1+1, (int)ch, n);
+ }
+
+ if (g_Tests[n].strA && g_Tests[n].strW)
+ {
+ memset(bufW, 'x', sizeof(bufW));
+ ChTraitsCRT<wchar_t>::ConvertToBaseType(bufW, g_Tests[n].exp_1+1,
g_Tests[n].strW);
+ wchar_t ch = bufW[g_Tests[n].exp_1];
+ ok(ch == '\0', "Expected %i to be \\0, was: %c (%i) for
%u\n", g_Tests[n].exp_1, ch, (int)ch, n);
+ ok(!wcscmp(bufW, g_Tests[n].strW), "Expected bufW to be %s, was: %s for
%u\n", wine_dbgstr_w(g_Tests[n].strW), wine_dbgstr_w(bufW), n);
+ ch = bufW[g_Tests[n].exp_1+1];
+ ok(ch == 30840, "Expected %i to be %i for %u\n",
g_Tests[n].exp_1+1, (int)ch, n);
+ }
+ }
+}
+
+// Allocation strategy seems to differ a bit between us and MS's atl.
+// if someone cares enough to find out why, feel free to change the macro below.
+#define ALLOC_EXPECT(a, b) b
+
+
+#undef ok
+#undef _T
+
+#define TEST_NAMEX(name) void test_##name##W()
+#define CStringX CStringW
+#define _X(x) L ## x
+#define XCHAR WCHAR
+#define dbgstrx(x) wine_dbgstr_w(x)
+#define ok ok_("CStringW:\n" __FILE__, __LINE__)
+#include "CString.inl"
+
+
+#undef CStringX
+#undef TEST_NAMEX
+#undef _X
+#undef XCHAR
+#undef dbgstrx
+#undef ok
+
+#define TEST_NAMEX(name) void test_##name##A()
+#define CStringX CStringA
+#define _X(x) x
+#define XCHAR CHAR
+#define dbgstrx(x) (const char*)x
+#define ok ok_("CStringA:\n" __FILE__, __LINE__)
+#include "CString.inl"
+
+
+START_TEST(CString)
+{
+ test_basetypes();
+
+ if ((ALLOC_EXPECT(1, 2)) == 2)
+ {
+ skip("Ignoring real GetAllocLength() lenght\n");
+ }
+
+ test_operators_initW();
+ test_operators_initA();
+
+ test_compareW();
+ test_compareA();
+
+ test_findW();
+ test_findA();
+
+ test_formatW();
+ test_formatA();
+
+ test_substrW();
+ test_substrA();
+
+ test_replaceW();
+ test_replaceA();
+
+ test_trimW();
+ test_trimA();
+}
Propchange: trunk/rostests/apitests/atl/CString.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/rostests/apitests/atl/CString.inl
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/atl/CString.inl?…
==============================================================================
--- trunk/rostests/apitests/atl/CString.inl (added)
+++ trunk/rostests/apitests/atl/CString.inl [iso-8859-1] Sat Jul 30 19:07:43 2016
@@ -0,0 +1,358 @@
+
+TEST_NAMEX(operators_init)
+{
+ CStringX test;
+ ok(test.IsEmpty() == true, "Expected test to be empty\n");
+ ok(test.GetLength() == 0, "Expected GetLength() to be 0, was: %i\n",
test.GetLength());
+ ok(test.GetAllocLength() == 0, "Expected GetAllocLength() to be 0, was:
%i\n", test.GetAllocLength());
+
+ // Operator
+ const XCHAR* cstring = (const XCHAR*)test;
+ ok(cstring != NULL, "Expected a valid pointer\n");
+ if (cstring)
+ {
+ ok(cstring[0] == '\0', "Expected \\0, got: %c (%i)\n",
cstring[0], (int)cstring[0]);
+ }
+
+ CStringX first(_X("First "));
+ ok(first.IsEmpty() != true, "Expected first to not be empty\n");
+ ok(first.GetLength() == 6, "Expected GetLength() to be 6, was: %i\n",
first.GetLength());
+ ok(first.GetAllocLength() == ALLOC_EXPECT(7, 6), "Expected GetAllocLength() to
be %i, was: %i\n", ALLOC_EXPECT(7, 6), first.GetAllocLength());
+
+ CStringX second(_X("Second"));
+ ok(second.IsEmpty() != true, "Expected second to not be empty\n");
+ ok(second.GetLength() == 6, "Expected GetLength() to be 6, was: %i\n",
second.GetLength());
+ ok(second.GetAllocLength() == ALLOC_EXPECT(7, 6), "Expected GetAllocLength() to
be %i, was: %i\n", ALLOC_EXPECT(7, 6), second.GetAllocLength());
+
+ test = first;
+ ok(test.IsEmpty() != true, "Expected test to not be empty\n");
+ ok(test.GetLength() == 6, "Expected GetLength() to be 6, was: %i\n",
test.GetLength());
+ ok(test.GetAllocLength() == ALLOC_EXPECT(7, 6), "Expected GetAllocLength() to be
%i, was: %i\n", ALLOC_EXPECT(7, 6), test.GetAllocLength());
+
+ test.Empty();
+ ok(test.IsEmpty() == true, "Expected test to be empty\n");
+ ok(test.GetLength() == 0, "Expected GetLength() to be 0, was: %i\n",
test.GetLength());
+ ok(test.GetAllocLength() == 0, "Expected GetAllocLength() to be 0, was:
%i\n", test.GetAllocLength());
+
+ test = _X("First ");
+ ok(test.IsEmpty() != true, "Expected test to not be empty\n");
+ ok(test.GetLength() == 6, "Expected GetLength() to be 6, was: %i\n",
test.GetLength());
+ ok(test.GetAllocLength() == ALLOC_EXPECT(7, 6), "Expected GetAllocLength() to be
%i, was: %i\n", ALLOC_EXPECT(7, 6), test.GetAllocLength());
+
+ test += second;
+ ok(test.IsEmpty() != true, "Expected test to not be empty\n");
+ ok(test.GetLength() == 12, "Expected GetLength() to be 12, was: %i\n",
test.GetLength());
+ ok(test.GetAllocLength() == ALLOC_EXPECT(15, 12), "Expected GetAllocLength() to
be %i, was: %i\n", ALLOC_EXPECT(15, 12), test.GetAllocLength());
+
+ test = first + second;
+ ok(test.IsEmpty() != true, "Expected test to not be empty\n");
+ ok(test.GetLength() == 12, "Expected GetLength() to be 12, was: %i\n",
test.GetLength());
+ ok(test.GetAllocLength() == ALLOC_EXPECT(15, 12), "Expected GetAllocLength() to
be %i, was: %i\n", ALLOC_EXPECT(15, 12), test.GetAllocLength());
+
+ test = first + second + _X(".");
+ ok(test.IsEmpty() != true, "Expected test to not be empty\n");
+ ok(test.GetLength() == 13, "Expected GetLength() to be 13, was: %i\n",
test.GetLength());
+ ok(test.GetAllocLength() == ALLOC_EXPECT(15, 18), "Expected GetAllocLength() to
be %i, was: %i\n", ALLOC_EXPECT(15, 18), test.GetAllocLength());
+
+ CStringX test2(test);
+ ok(test2.IsEmpty() != true, "Expected test2 to not be empty\n");
+ ok(test2.GetLength() == 13, "Expected GetLength() to be 13, was: %i\n",
test2.GetLength());
+ ok(test2.GetAllocLength() == ALLOC_EXPECT(15, 18), "Expected GetAllocLength() to
be %i, was: %i\n", ALLOC_EXPECT(15, 18), test2.GetAllocLength());
+
+ // Clear it again
+ test.Empty();
+ ok(test.IsEmpty() == true, "Expected test to be empty\n");
+ ok(test.GetLength() == 0, "Expected GetLength() to be 0, was: %i\n",
test.GetLength());
+ ok(test.GetAllocLength() == 0, "Expected GetAllocLength() to be 0, was:
%i\n", test.GetAllocLength());
+
+ // Assign string
+ test = "First ";
+ ok(test.IsEmpty() != true, "Expected test to not be empty\n");
+ ok(test.GetLength() == 6, "Expected GetLength() to be 6, was: %i\n",
test.GetLength());
+ ok(test.GetAllocLength() == ALLOC_EXPECT(7, 6), "Expected GetAllocLength() to be
7, was: %i\n", test.GetAllocLength());
+
+ CStringA testA = test;
+ ok(testA.IsEmpty() != true, "Expected testA to not be empty\n");
+ ok(testA.GetLength() == 6, "Expected GetLength() to be 6, was: %i\n",
testA.GetLength());
+ ok(testA.GetAllocLength() == ALLOC_EXPECT(7, 6), "Expected GetAllocLength() to
be 7, was: %i\n", testA.GetAllocLength());
+
+ CStringW testW = test;
+ ok(testW.IsEmpty() != true, "Expected testW to not be empty\n");
+ ok(testW.GetLength() == 6, "Expected GetLength() to be 6, was: %i\n",
testW.GetLength());
+ ok(testW.GetAllocLength() == ALLOC_EXPECT(7, 6), "Expected GetAllocLength() to
be 7, was: %i\n", testW.GetAllocLength());
+
+ // Assign wstring
+ test = L"First ";
+ ok(test.IsEmpty() != true, "Expected test to not be empty\n");
+ ok(test.GetLength() == 6, "Expected GetLength() to be 6, was: %i\n",
test.GetLength());
+ ok(test.GetAllocLength() == ALLOC_EXPECT(7, 6), "Expected GetAllocLength() to be
7, was: %i\n", test.GetAllocLength());
+}
+
+
+TEST_NAMEX(compare)
+{
+ CStringX s1, s2;
+ s1 = s2 = _X("some text 1!");
+
+ int c = s1.Compare(s2);
+ ok(c == 0, "Expected c to be 1, was: %i\n", c);
+
+ c = s1.Compare(_X("r"));
+ ok(c == 1, "Expected c to be 1, was: %i\n", c);
+
+ c = s1.Compare(_X("s"));
+ ok(c == 1, "Expected c to be 1, was: %i\n", c);
+
+ c = s1.Compare(_X("t"));
+ ok(c == -1, "Expected c to be -1, was: %i\n", c);
+
+ c = s1.Compare(_X("R"));
+ ok(c == 1, "Expected c to be 1, was: %i\n", c);
+
+ c = s1.Compare(_X("S"));
+ ok(c == 1, "Expected c to be 1, was: %i\n", c);
+
+ c = s1.Compare(_X("T"));
+ ok(c == 1, "Expected c to be 1, was: %i\n", c);
+
+ ok(s1 == s2, "Expected s1 and s2 to be equal: '%s' ==
'%s'\n", dbgstrx(s1), dbgstrx(s2));
+
+ s1.MakeUpper(); // Does not modify s2
+ ok(s1[0] == _X('S'), "Expected s1[0] to be S, was: %c\n",
(char)s1[0]);
+ ok(s2[0] == _X('s'), "Expected s2[0] to be s, was: %c\n",
(char)s2[0]);
+
+ ok(s1 == _X("SOME TEXT 1!"), "Expected s1 to be 'SOME TEXT
1!', was: %s\n", dbgstrx(s1));
+
+ CStringX s3 = s1.MakeLower();
+ ok(s1 == _X("some text 1!"), "Expected s1 to be 'some text
1!', was: %s\n", dbgstrx(s1));
+ ok(s1 == s3, "Expected s1 and s3 to be equal: '%s' ==
'%s'\n", dbgstrx(s1), dbgstrx(s3));
+}
+
+
+TEST_NAMEX(find)
+{
+ CStringX s(_X("adbcdef"));
+ int n = s.Find(_X('c'));
+ ok(n == 3, "Expected n to be 2, was %i\n", n);
+ n = s.Find(_X("de"));
+ ok(n == 4, "Expected n to be 4, was %i\n", n);
+
+ CStringX str(_X("The waves are still"));
+ n = str.Find(_X('e'), 5);
+ ok(n == 7, "Expected n to be 7, was %i\n", n);
+ n = str.Find(_X('e'), 7);
+ ok(n == 7, "Expected n to be 7, was %i\n", n);
+
+ s = _X("abcdefGHIJKLMNop");
+ n = s.FindOneOf(_X("Nd"));
+ ok(n == 3, "Expected n to be 3, was %i\n", n);
+ n = s.FindOneOf(_X("Np"));
+ ok(n == 13, "Expected n to be 13, was %i\n", n);
+
+ n = str.ReverseFind(_X('l'));
+ ok(n == 18, "Expected n to be 18, was %i\n", n);
+
+ n = str.ReverseFind(_X('e'));
+ ok(n == 12, "Expected n to be 12, was %i\n", n);
+}
+
+
+void WriteString(const XCHAR* pstrFormat, ...)
+{
+ CStringX str;
+
+ va_list args;
+ va_start(args, pstrFormat);
+
+ str.FormatV(pstrFormat, args);
+ va_end(args);
+
+ ok(str == _X("10e 1351l"), "Expected str to be '10e 1351l',
was: %s\n", dbgstrx(str));
+}
+
+TEST_NAMEX(format)
+{
+ CStringX str;
+
+ str.Format(_X("FP: %.2f"), 12345.12345);
+ ok(str == _X("FP: 12345.12"), "Expected str to be 'FP:
12345.12', was: %s\n", dbgstrx(str));
+
+ str.Format(_X("int: %.6d"), 35);
+ ok(str == _X("int: 000035"), "Expected str to be 'int:
000035', was: %s\n", dbgstrx(str));
+
+ WriteString(_X("%de %dl"), 10, 1351);
+}
+
+
+TEST_NAMEX(substr)
+{
+ CStringX s(_X("abcdef"));
+
+ CStringX m = s.Mid(2, 3);
+ ok(m == _X("cde"), "Expected str to be 'cde', was: %s\n",
dbgstrx(m));
+ ok(m.GetLength() == 3, "Expected GetLength() to be 3, was: %i\n",
m.GetLength());
+
+ m = s.Mid(-5, 3);
+ ok(m == _X("abc"), "Expected str to be 'abc', was: %s\n",
dbgstrx(m));
+ ok(m.GetLength() == 3, "Expected GetLength() to be 3, was: %i\n",
m.GetLength());
+
+ m = s.Mid(3, 20);
+ ok(m == _X("def"), "Expected str to be 'def', was: %s\n",
dbgstrx(m));
+ ok(m.GetLength() == 3, "Expected GetLength() to be 3, was: %i\n",
m.GetLength());
+
+ m = s.Mid(3, -1);
+ ok(m == _X(""), "Expected str to be '', was: %s\n",
dbgstrx(m));
+ ok(m.GetLength() == 0, "Expected GetLength() to be 0, was: %i\n",
m.GetLength());
+
+ m = s.Mid(2);
+ ok(m == _X("cdef"), "Expected str to be 'cdef', was:
%s\n", dbgstrx(m));
+ ok(m.GetLength() == 4, "Expected GetLength() to be 4, was: %i\n",
m.GetLength());
+
+ m = s.Mid(-3);
+ ok(m == _X("abcdef"), "Expected str to be 'abcdef', was:
%s\n", dbgstrx(m));
+ ok(m.GetLength() == 6, "Expected GetLength() to be 6, was: %i\n",
m.GetLength());
+
+ m = s.Mid(20);
+ ok(m == _X(""), "Expected str to be '', was: %s\n",
dbgstrx(m));
+ ok(m.GetLength() == 0, "Expected GetLength() to be 0, was: %i\n",
m.GetLength());
+
+ m = s.Left(2);
+ ok(m == _X("ab"), "Expected str to be 'ab', was: %s\n",
dbgstrx(m));
+ ok(m.GetLength() == 2, "Expected GetLength() to be 2, was: %i\n",
m.GetLength());
+
+ m = s.Left(40);
+ ok(m == _X("abcdef"), "Expected str to be 'abcdef', was:
%s\n", dbgstrx(m));
+ ok(m.GetLength() == 6, "Expected GetLength() to be 6, was: %i\n",
m.GetLength());
+
+ m = s.Left(-10);
+ ok(m == _X(""), "Expected str to be '', was: %s\n",
dbgstrx(m));
+ ok(m.GetLength() == 0, "Expected GetLength() to be 0, was: %i\n",
m.GetLength());
+
+ m = s.Right(2);
+ ok(m == _X("ef"), "Expected str to be 'ef', was: %s\n",
dbgstrx(m));
+ ok(m.GetLength() == 2, "Expected GetLength() to be 2, was: %i\n",
m.GetLength());
+
+ m = s.Right(-40);
+ ok(m == _X(""), "Expected str to be '', was: %s\n",
dbgstrx(m));
+ ok(m.GetLength() == 0, "Expected GetLength() to be 0, was: %i\n",
m.GetLength());
+
+ m = s.Right(99);
+ ok(m == _X("abcdef"), "Expected str to be 'abcdef', was:
%s\n", dbgstrx(m));
+ ok(m.GetLength() == 6, "Expected GetLength() to be 6, was: %i\n",
m.GetLength());
+}
+
+
+TEST_NAMEX(replace)
+{
+ CStringX str(_X("abcde"));
+ int n = str.Replace(_X("b"), _X("bx"));
+ ok(n == 1, "Expected n to be 1, was %i\n", n);
+ ok(str == _X("abxcde"), "Expected str to be 'abxcde', was:
%s\n", dbgstrx(str));
+ ok(str.GetLength() == 6, "Expected GetLength() to be 6, was: %i\n",
str.GetLength());
+
+ CStringX strBang(_X("The quick brown fox is lazy today of all days"));
+
+ n = strBang.Replace(_X("is"), _X("was"));
+ ok(n == 1, "Expected n to be 1, was %i\n", n);
+ ok(strBang == _X("The quick brown fox was lazy today of all days"),
+ "Expected str to be 'The quick brown fox was lazy today of all
days', was: %s\n", dbgstrx(strBang));
+ ok(strBang.GetLength() == 46, "Expected GetLength() to be 46, was: %i\n",
strBang.GetLength());
+
+ n = strBang.Replace(_X("is"), _X("was"));
+ ok(n == 0, "Expected n to be 0, was %i\n", n);
+ ok(strBang == _X("The quick brown fox was lazy today of all days"),
+ "Expected str to be 'The quick brown fox was lazy today of all
days', was: %s\n", dbgstrx(strBang));
+ ok(strBang.GetLength() == 46, "Expected GetLength() to be 46, was: %i\n",
strBang.GetLength());
+
+ n = strBang.Replace(_X('o'), _X('0'));
+ ok(n == 4, "Expected n to be 4, was %i\n", n);
+ ok(strBang == _X("The quick br0wn f0x was lazy t0day 0f all days"),
+ "Expected str to be 'The quick br0wn f0x was lazy t0day 0f all
days', was: %s\n", dbgstrx(strBang));
+ ok(strBang.GetLength() == 46, "Expected GetLength() to be 46, was: %i\n",
strBang.GetLength());
+
+ n = strBang.Replace(_X('o'), _X('0'));
+ ok(n == 0, "Expected n to be 0, was %i\n", n);
+ ok(strBang == _X("The quick br0wn f0x was lazy t0day 0f all days"),
+ "Expected str to be 'The quick br0wn f0x was lazy t0day 0f all
days', was: %s\n", dbgstrx(strBang));
+ ok(strBang.GetLength() == 46, "Expected GetLength() to be 46, was: %i\n",
strBang.GetLength());
+
+ n = strBang.Replace(_X("y "), _X("y, "));
+ ok(n == 2, "Expected n to be 2, was %i\n", n);
+ ok(strBang == _X("The quick br0wn f0x was lazy, t0day, 0f all days"),
+ "Expected str to be 'The quick br0wn f0x was lazy, t0day, 0f all
days', was: %s\n", dbgstrx(strBang));
+ ok(strBang.GetLength() == 48, "Expected GetLength() to be 48, was: %i\n",
strBang.GetLength());
+
+ n = strBang.Replace(_X(", 0f all days"), _X(""));
+ ok(n == 1, "Expected n to be 1, was %i\n", n);
+ ok(strBang == _X("The quick br0wn f0x was lazy, t0day"),
+ "Expected str to be 'The quick br0wn f0x was lazy, t0day', was:
%s\n", dbgstrx(strBang));
+ ok(strBang.GetLength() == 35, "Expected GetLength() to be 35, was: %i\n",
strBang.GetLength());
+
+ n = strBang.Replace(_X(" lazy, "), _X(" fast "));
+ ok(n == 1, "Expected n to be 1, was %i\n", n);
+ ok(strBang == _X("The quick br0wn f0x was fast t0day"),
+ "Expected str to be 'The quick br0wn f0x was fast t0day', was:
%s\n", dbgstrx(strBang));
+ ok(strBang.GetLength() == 34, "Expected GetLength() to be 34, was: %i\n",
strBang.GetLength());
+
+ n = strBang.Replace(_X("The "), _X(""));
+ ok(n == 1, "Expected n to be 1, was %i\n", n);
+ ok(strBang == _X("quick br0wn f0x was fast t0day"),
+ "Expected str to be 'quick br0wn f0x was fast t0day', was:
%s\n", dbgstrx(strBang));
+ ok(strBang.GetLength() == 30, "Expected GetLength() to be 30, was: %i\n",
strBang.GetLength());
+
+ n = strBang.Replace(_X(" t0day"), _X(""));
+ ok(n == 1, "Expected n to be 1, was %i\n", n);
+ ok(strBang == _X("quick br0wn f0x was fast"),
+ "Expected str to be 'quick br0wn f0x was fast', was: %s\n",
dbgstrx(strBang));
+ ok(strBang.GetLength() == 24, "Expected GetLength() to be 24, was: %i\n",
strBang.GetLength());
+
+ n = strBang.Replace(_X("quick"), _X("The fast, quick"));
+ ok(n == 1, "Expected n to be 1, was %i\n", n);
+ ok(strBang == _X("The fast, quick br0wn f0x was fast"),
+ "Expected str to be 'The fast, quick br0wn f0x was fast', was:
%s\n", dbgstrx(strBang));
+ ok(strBang.GetLength() == 34, "Expected GetLength() to be 34, was: %i\n",
strBang.GetLength());
+}
+
+
+TEST_NAMEX(trim)
+{
+ CStringX str;
+ str = _X(" \t\r\n******Trim some text!?!?!?!?!\n\r\t ");
+
+ str.TrimLeft();
+ ok(str == _X("******Trim some text!?!?!?!?!\n\r\t "), "Expected str to
be '******Trim some text!?!?!?!?!\n\r\t ', was: %s\n", dbgstrx(str));
+ ok(str.GetLength() == 33, "Expected GetLength() to be 33, was: %i\n",
str.GetLength());
+
+ str.TrimRight();
+ ok(str == _X("******Trim some text!?!?!?!?!"), "Expected str to be
'******Trim some text!?!?!?!?!', was: %s\n", dbgstrx(str));
+ ok(str.GetLength() == 29, "Expected GetLength() to be 29, was: %i\n",
str.GetLength());
+
+ CStringX str2 = str.Trim(_X("?!*"));
+ ok(str2 == _X("Trim some text"), "Expected str to be 'Trim some
text', was: %s\n", dbgstrx(str2));
+ ok(str2.GetLength() == 14, "Expected GetLength() to be 14, was: %i\n",
str2.GetLength());
+
+ str = _X("\t\t ****Trim some text!");
+ str2 = str.TrimLeft(_X("\t *"));
+ ok(str2 == _X("Trim some text!"), "Expected str to be 'Trim some
text!', was: %s\n", dbgstrx(str2));
+ ok(str2.GetLength() == 15, "Expected GetLength() to be 15, was: %i\n",
str2.GetLength());
+
+ str = _X("Trim some text!?!?!?!?!");
+ str2 = str.TrimRight(_X("?!"));
+ ok(str2 == _X("Trim some text"), "Expected str to be 'Trim some
text', was: %s\n", dbgstrx(str2));
+ ok(str2.GetLength() == 14, "Expected GetLength() to be 14, was: %i\n",
str2.GetLength());
+
+ str = _X("\t\t\t\t\t");
+ str2 = str.TrimLeft();
+ ok(str2 == _X(""), "Expected str2 to be '', was: %s\n",
dbgstrx(str2));
+ ok(str2.GetLength() == 0, "Expected GetLength() to be 0, was: %i\n",
str2.GetLength());
+
+ str = _X("\t\t\t\t\t");
+ str2 = str.TrimRight();
+ ok(str2 == _X(""), "Expected str2 to be '', was: %s\n",
dbgstrx(str2));
+ ok(str2.GetLength() == 0, "Expected GetLength() to be 0, was: %i\n",
str2.GetLength());
+
+ str = _X("\t\t\t\t\t");
+ str2 = str.Trim();
+ ok(str2 == _X(""), "Expected str2 to be '', was: %s\n",
dbgstrx(str2));
+ ok(str2.GetLength() == 0, "Expected GetLength() to be 0, was: %i\n",
str2.GetLength());
+}
Propchange: trunk/rostests/apitests/atl/CString.inl
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/rostests/apitests/atl/testlist.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/atl/testlist.c?r…
==============================================================================
--- trunk/rostests/apitests/atl/testlist.c [iso-8859-1] (original)
+++ trunk/rostests/apitests/atl/testlist.c [iso-8859-1] Sat Jul 30 19:07:43 2016
@@ -3,10 +3,12 @@
extern void func_CComBSTR(void);
extern void func_CComHeapPtr(void);
+extern void func_CString(void);
const struct test winetest_testlist[] =
{
{ "CComBSTR", func_CComBSTR },
{ "CComHeapPtr", func_CComHeapPtr },
+ { "CString", func_CString },
{ 0, 0 }
};