Author: tfaber
Date: Thu Nov 5 10:49:52 2015
New Revision: 69815
URL:
http://svn.reactos.org/svn/reactos?rev=69815&view=rev
Log:
[ATL]
- Implement more CComBSTR methods. Patch by Mark Jansen.
CORE-10478 #resolve
Added:
trunk/rostests/apitests/atl/CComBSTR.cpp (with props)
trunk/rostests/apitests/atl/atl_apitest.rc (with props)
trunk/rostests/apitests/atl/resource.h (with props)
Modified:
trunk/reactos/lib/atl/atlbase.h
trunk/rostests/apitests/atl/CMakeLists.txt
trunk/rostests/apitests/atl/testlist.c
Modified: trunk/reactos/lib/atl/atlbase.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/atl/atlbase.h?rev=6981…
==============================================================================
--- trunk/reactos/lib/atl/atlbase.h [iso-8859-1] (original)
+++ trunk/reactos/lib/atl/atlbase.h [iso-8859-1] Thu Nov 5 10:49:52 2015
@@ -929,6 +929,11 @@
public:
BSTR m_str;
public:
+ CComBSTR() :
+ m_str(NULL)
+ {
+ }
+
CComBSTR(LPCOLESTR pSrc)
{
if (pSrc == NULL)
@@ -936,15 +941,115 @@
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);
}
};
Added: trunk/rostests/apitests/atl/CComBSTR.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/atl/CComBSTR.cpp…
==============================================================================
--- trunk/rostests/apitests/atl/CComBSTR.cpp (added)
+++ trunk/rostests/apitests/atl/CComBSTR.cpp [iso-8859-1] Thu Nov 5 10:49:52 2015
@@ -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();
+}
Propchange: trunk/rostests/apitests/atl/CComBSTR.cpp
------------------------------------------------------------------------------
svn:eol-style = native
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] Thu Nov 5 10:49:52 2015
@@ -4,9 +4,12 @@
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)
Added: trunk/rostests/apitests/atl/atl_apitest.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/atl/atl_apitest.…
==============================================================================
--- trunk/rostests/apitests/atl/atl_apitest.rc (added)
+++ trunk/rostests/apitests/atl/atl_apitest.rc [iso-8859-1] Thu Nov 5 10:49:52 2015
@@ -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
+
Propchange: trunk/rostests/apitests/atl/atl_apitest.rc
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/rostests/apitests/atl/resource.h
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/atl/resource.h?r…
==============================================================================
--- trunk/rostests/apitests/atl/resource.h (added)
+++ trunk/rostests/apitests/atl/resource.h [iso-8859-1] Thu Nov 5 10:49:52 2015
@@ -0,0 +1,3 @@
+
+#define IDS_TEST1 2000
+#define IDS_TEST2 2001
Propchange: trunk/rostests/apitests/atl/resource.h
------------------------------------------------------------------------------
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] Thu Nov 5 10:49:52 2015
@@ -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 }
};