mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 08:25:03 +00:00
[ATL]
- Implement more CComBSTR methods. Patch by Mark Jansen. CORE-10478 #resolve svn path=/trunk/; revision=69815
This commit is contained in:
parent
01e9e3f8a5
commit
0f4f3d7cd8
6 changed files with 267 additions and 3 deletions
|
@ -929,6 +929,11 @@ class CComBSTR
|
|||
public:
|
||||
BSTR m_str;
|
||||
public:
|
||||
CComBSTR() :
|
||||
m_str(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
CComBSTR(LPCOLESTR pSrc)
|
||||
{
|
||||
if (pSrc == NULL)
|
||||
|
@ -936,16 +941,116 @@ public:
|
|||
else
|
||||
m_str = ::SysAllocString(pSrc);
|
||||
}
|
||||
|
||||
CComBSTR(int length)
|
||||
{
|
||||
if (length == 0)
|
||||
m_str = NULL;
|
||||
else
|
||||
m_str = ::SysAllocStringLen(NULL, length);
|
||||
}
|
||||
|
||||
CComBSTR(int length, LPCOLESTR pSrc)
|
||||
{
|
||||
if (length == 0)
|
||||
m_str = NULL;
|
||||
else
|
||||
m_str = ::SysAllocStringLen(pSrc, length);
|
||||
}
|
||||
|
||||
CComBSTR(PCSTR pSrc)
|
||||
{
|
||||
if (pSrc)
|
||||
{
|
||||
int len = MultiByteToWideChar(CP_THREAD_ACP, 0, pSrc, -1, NULL, 0);
|
||||
m_str = ::SysAllocStringLen(NULL, len - 1);
|
||||
if (m_str)
|
||||
{
|
||||
int res = MultiByteToWideChar(CP_THREAD_ACP, 0, pSrc, -1, m_str, len);
|
||||
ATLASSERT(res == len);
|
||||
if (res != len)
|
||||
{
|
||||
::SysFreeString(m_str);
|
||||
m_str = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_str = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
CComBSTR(const CComBSTR &other)
|
||||
{
|
||||
m_str = other.Copy();
|
||||
}
|
||||
|
||||
CComBSTR(REFGUID guid)
|
||||
{
|
||||
OLECHAR szGuid[40];
|
||||
::StringFromGUID2(guid, szGuid, 40);
|
||||
m_str = ::SysAllocString(szGuid);
|
||||
}
|
||||
|
||||
~CComBSTR()
|
||||
{
|
||||
::SysFreeString(m_str);
|
||||
m_str = NULL;
|
||||
}
|
||||
|
||||
|
||||
operator BSTR () const
|
||||
{
|
||||
return m_str;
|
||||
}
|
||||
|
||||
BSTR *operator & ()
|
||||
{
|
||||
return &m_str;
|
||||
}
|
||||
|
||||
CComBSTR &operator = (const CComBSTR &other)
|
||||
{
|
||||
::SysFreeString(m_str);
|
||||
m_str = other.Copy();
|
||||
return *this;
|
||||
}
|
||||
|
||||
BSTR Copy() const
|
||||
{
|
||||
if (!m_str)
|
||||
return NULL;
|
||||
return ::SysAllocStringLen(m_str, ::SysStringLen(m_str));
|
||||
}
|
||||
|
||||
HRESULT CopyTo(BSTR *other) const
|
||||
{
|
||||
if (!other)
|
||||
return E_POINTER;
|
||||
*other = Copy();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
bool LoadString(HMODULE module, DWORD uID)
|
||||
{
|
||||
::SysFreeString(m_str);
|
||||
m_str = NULL;
|
||||
const wchar_t *ptr = NULL;
|
||||
int len = ::LoadStringW(module, uID, (PWSTR)&ptr, 0);
|
||||
if (len)
|
||||
m_str = ::SysAllocStringLen(ptr, len);
|
||||
return m_str != NULL;
|
||||
}
|
||||
|
||||
unsigned int Length() const
|
||||
{
|
||||
return ::SysStringLen(m_str);
|
||||
}
|
||||
|
||||
unsigned int ByteLength() const
|
||||
{
|
||||
return ::SysStringByteLen(m_str);
|
||||
}
|
||||
};
|
||||
|
||||
class CComVariant : public tagVARIANT
|
||||
|
|
140
rostests/apitests/atl/CComBSTR.cpp
Normal file
140
rostests/apitests/atl/CComBSTR.cpp
Normal file
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
* PROJECT: ReactOS api tests
|
||||
* LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
|
||||
* PURPOSE: Test for CComBSTR
|
||||
* PROGRAMMER: Mark Jansen
|
||||
*/
|
||||
|
||||
#include <apitest.h>
|
||||
#include <atlbase.h>
|
||||
#include <atlcom.h>
|
||||
#include "resource.h"
|
||||
|
||||
#define verify_str (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : verify_str_imp
|
||||
#define verify_str2 (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : verify_str_imp2
|
||||
|
||||
|
||||
static void verify_str_imp2(const CComBSTR& comstr, PCWSTR expected, size_t ExpectedLength)
|
||||
{
|
||||
BSTR str = (BSTR)comstr;
|
||||
if (expected || ExpectedLength)
|
||||
{
|
||||
winetest_ok(str != NULL, "Expected str to be a valid pointer\n");
|
||||
if (str)
|
||||
{
|
||||
if (expected)
|
||||
{
|
||||
winetest_ok(!wcscmp(str, expected), "Expected the string to be '%s', was '%s'\n", wine_dbgstr_w(expected), wine_dbgstr_w(str));
|
||||
}
|
||||
size_t Length = comstr.Length();
|
||||
winetest_ok(Length == ExpectedLength, "Expected Length to be %u, was: %u\n", ExpectedLength, Length);
|
||||
Length = comstr.ByteLength();
|
||||
ExpectedLength *= sizeof(WCHAR);
|
||||
winetest_ok(Length == ExpectedLength, "Expected ByteLength to be %u, was: %u\n", ExpectedLength, Length);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
winetest_ok(str == NULL || str[0] == '\0', "Expected str to be empty, was: '%s'\n", wine_dbgstr_w(str));
|
||||
}
|
||||
}
|
||||
|
||||
static void verify_str_imp(const CComBSTR& comstr, PCWSTR expected)
|
||||
{
|
||||
verify_str_imp2(comstr, expected, expected ? wcslen(expected) : 0);
|
||||
}
|
||||
|
||||
void test_construction()
|
||||
{
|
||||
CComBSTR empty1, empty2;
|
||||
CComBSTR happyW(L"I am a happy BSTR");
|
||||
CComBSTR happyA("I am a happy BSTR");
|
||||
CComBSTR happyW4(4, L"I am a happy BSTR");
|
||||
CComBSTR fromlen1(1), fromlen10(10);
|
||||
CComBSTR fromBSTRW(happyW), fromBSTRA(happyA), fromBSTRW4(happyW4);
|
||||
CComBSTR fromBSTRlen1(fromlen1), fromBSTRlen10(fromlen10);
|
||||
|
||||
verify_str(empty1, NULL);
|
||||
verify_str(empty2, NULL);
|
||||
verify_str(happyW, L"I am a happy BSTR");
|
||||
verify_str(happyA, L"I am a happy BSTR");
|
||||
verify_str(happyW4, L"I am");
|
||||
verify_str2(fromlen1, NULL, 1);
|
||||
verify_str2(fromlen10, NULL, 10);
|
||||
verify_str(fromBSTRW, L"I am a happy BSTR");
|
||||
verify_str(fromBSTRA, L"I am a happy BSTR");
|
||||
verify_str(fromBSTRW4, L"I am");
|
||||
verify_str2(fromBSTRlen1, NULL, 1);
|
||||
verify_str2(fromBSTRlen10, NULL, 10);
|
||||
}
|
||||
|
||||
void test_copyassignment()
|
||||
{
|
||||
CComBSTR happy(L"I am a happy BSTR"), empty, odd;
|
||||
CComBSTR happyCopy1, happyCopy2, emptyCopy, oddCopy;
|
||||
|
||||
odd = ::SysAllocStringByteLen("aaaaa", 3);
|
||||
|
||||
happyCopy1 = happy.Copy();
|
||||
happyCopy2 = happy; // Calls happyW.Copy()
|
||||
emptyCopy = empty.Copy();
|
||||
oddCopy = odd.Copy();
|
||||
|
||||
verify_str(happy, L"I am a happy BSTR");
|
||||
verify_str(empty, NULL);
|
||||
verify_str2(odd, L"\u6161a", 2);
|
||||
verify_str(happyCopy1, L"I am a happy BSTR");
|
||||
verify_str(happyCopy2, L"I am a happy BSTR");
|
||||
verify_str(emptyCopy, NULL);
|
||||
verify_str2(oddCopy, L"\u6161a", 2);
|
||||
ok((BSTR)happy != (BSTR)happyCopy1, "Expected pointers to be different\n");
|
||||
ok((BSTR)happy != (BSTR)happyCopy2, "Expected pointers to be different\n");
|
||||
|
||||
|
||||
happyCopy1 = (LPCOLESTR)NULL;
|
||||
happyCopy2 = (LPCSTR)NULL;
|
||||
|
||||
verify_str(happyCopy1, NULL);
|
||||
verify_str(happyCopy2, NULL);
|
||||
|
||||
HRESULT hr = happy.CopyTo(&happyCopy1);
|
||||
ok(hr == S_OK, "Expected hr to be E_POINTER, was: %08lx\n", hr);
|
||||
|
||||
#if 0
|
||||
// This asserts
|
||||
hr = happy.CopyTo((BSTR*)NULL);
|
||||
ok(hr == E_POINTER, "Expected hr to be E_POINTER, was: %u\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
void test_fromguid()
|
||||
{
|
||||
GUID guid = { 0x12345678, 0x9abc, 0xdef0, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0} };
|
||||
CComBSTR fromGuid(guid), empty;
|
||||
verify_str(fromGuid, L"{12345678-9ABC-DEF0-1234-56789ABCDEF0}");
|
||||
verify_str(empty, NULL);
|
||||
empty = fromGuid;
|
||||
verify_str(empty, L"{12345678-9ABC-DEF0-1234-56789ABCDEF0}");
|
||||
}
|
||||
|
||||
void test_loadres()
|
||||
{
|
||||
CComBSTR test1, test2, test3;
|
||||
HMODULE mod = GetModuleHandle(NULL);
|
||||
|
||||
ok(true == test1.LoadString(mod, IDS_TEST1), "Expected LoadString to succeed\n");
|
||||
ok(true == test2.LoadString(mod, IDS_TEST2), "Expected LoadString to succeed\n");
|
||||
ok(false == test3.LoadString(mod, IDS_TEST2 + 1), "Expected LoadString to fail\n");
|
||||
|
||||
verify_str(test1, L"Test string one.");
|
||||
verify_str(test2, L"I am a happy BSTR");
|
||||
verify_str(test3, NULL);
|
||||
}
|
||||
|
||||
START_TEST(CComBSTR)
|
||||
{
|
||||
test_construction();
|
||||
test_copyassignment();
|
||||
test_fromguid();
|
||||
test_loadres();
|
||||
}
|
|
@ -4,9 +4,12 @@ set_cpp(WITH_RUNTIME)
|
|||
include_directories(${REACTOS_SOURCE_DIR}/lib/atl)
|
||||
|
||||
add_executable(atl_apitest
|
||||
CComBSTR.cpp
|
||||
CComHeapPtr.cpp
|
||||
testlist.c)
|
||||
testlist.c
|
||||
atl_apitest.rc)
|
||||
|
||||
target_link_libraries(atl_apitest wine uuid)
|
||||
set_module_type(atl_apitest win32cui)
|
||||
add_importlibs(atl_apitest ole32 oleaut32 msvcrt kernel32)
|
||||
add_importlibs(atl_apitest ole32 oleaut32 user32 msvcrt kernel32)
|
||||
add_cd_file(TARGET atl_apitest DESTINATION reactos/bin FOR all)
|
||||
|
|
11
rostests/apitests/atl/atl_apitest.rc
Normal file
11
rostests/apitests/atl/atl_apitest.rc
Normal file
|
@ -0,0 +1,11 @@
|
|||
#include <windef.h>
|
||||
#include "resource.h"
|
||||
|
||||
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
IDS_TEST1 "Test string one."
|
||||
IDS_TEST2 "I am a happy BSTR"
|
||||
END
|
||||
|
3
rostests/apitests/atl/resource.h
Normal file
3
rostests/apitests/atl/resource.h
Normal file
|
@ -0,0 +1,3 @@
|
|||
|
||||
#define IDS_TEST1 2000
|
||||
#define IDS_TEST2 2001
|
|
@ -1,10 +1,12 @@
|
|||
#define STANDALONE
|
||||
#include <apitest.h>
|
||||
|
||||
extern void func_CComBSTR(void);
|
||||
extern void func_CComHeapPtr(void);
|
||||
|
||||
const struct test winetest_testlist[] =
|
||||
{
|
||||
{ "CComBSTR", func_CComBSTR },
|
||||
{ "CComHeapPtr", func_CComHeapPtr },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue