1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 29 // MARKER(update_precomp.py): autogen include statement, do not remove 30 #include "precompiled_sal.hxx" 31 // autogenerated file with codegen.pl 32 33 #include <testshl/simpleheader.hxx> 34 #include <systools/win32/comtools.hxx> 35 36 class COMObject : public IUnknown 37 { 38 public: 39 COMObject() : ref_count_(0) 40 { 41 } 42 43 ~COMObject() 44 { 45 } 46 47 ULONG __stdcall AddRef() 48 { 49 ref_count_++; 50 return ref_count_; 51 } 52 53 ULONG __stdcall Release() 54 { 55 ULONG cnt = --ref_count_; 56 if (cnt == 0) 57 delete this; 58 return cnt; 59 } 60 61 HRESULT __stdcall QueryInterface(REFIID riid, LPVOID* ppv) 62 { 63 if (riid == IID_IUnknown) 64 { 65 AddRef(); 66 *ppv = this; 67 return S_OK; 68 } 69 return E_NOINTERFACE; 70 } 71 72 ULONG GetRefCount() const 73 { 74 return ref_count_; 75 } 76 77 private: 78 ULONG ref_count_; 79 }; 80 81 sal::systools::COMReference<IUnknown> comObjectSource() 82 { 83 return sal::systools::COMReference<IUnknown>(new COMObject); 84 } 85 86 bool comObjectSink(sal::systools::COMReference<IUnknown> r, ULONG expectedRefCountOnReturn) 87 { 88 r = sal::systools::COMReference<IUnknown>(); 89 COMObject* p = reinterpret_cast<COMObject*>(r.get()); 90 if (p) 91 return (p->GetRefCount() == expectedRefCountOnReturn); 92 else 93 return (0 == expectedRefCountOnReturn); 94 } 95 96 void comObjectSource2(LPVOID* ppv) 97 { 98 COMObject* p = new COMObject; 99 p->AddRef(); 100 *ppv = p; 101 } 102 103 namespace test_comtools 104 { 105 106 class test_COMReference : public CppUnit::TestFixture 107 { 108 109 public: 110 /// test of COMReference<IUnknown> r; 111 void default_ctor() 112 { 113 sal::systools::COMReference<IUnknown> r; 114 CPPUNIT_ASSERT_MESSAGE("COMReference should be empty", r.get() == NULL); 115 } 116 117 void test_ctor_manual_AddRef() 118 { 119 COMObject* p = new COMObject; 120 p->AddRef(); 121 sal::systools::COMReference<IUnknown> r(p, false); 122 CPPUNIT_ASSERT_MESSAGE("Wrong reference count 1 is expected", reinterpret_cast<COMObject*>(r.get())->GetRefCount() == 1); 123 } 124 125 void test_copy_ctor() 126 { 127 sal::systools::COMReference<IUnknown> r(comObjectSource()); 128 CPPUNIT_ASSERT_MESSAGE("Wrong reference count 1 is expected", reinterpret_cast<COMObject*>(r.get())->GetRefCount() == 1); 129 } 130 131 void test_copy_assignment() 132 { 133 sal::systools::COMReference<IUnknown> r; 134 CPPUNIT_ASSERT_MESSAGE("COMReference should be empty", r.get() == NULL); 135 136 r = comObjectSource(); 137 CPPUNIT_ASSERT_MESSAGE("COMReference should be empty", r.get() != NULL); 138 CPPUNIT_ASSERT_MESSAGE("Wrong reference count 1 is expected", reinterpret_cast<COMObject*>(r.get())->GetRefCount() == 1); 139 } 140 141 void test_ref_to_ref_assignment() 142 { 143 sal::systools::COMReference<IUnknown> r1 = comObjectSource(); 144 sal::systools::COMReference<IUnknown> r2 = r1; 145 CPPUNIT_ASSERT_MESSAGE("Wrong reference count 2 is expected", reinterpret_cast<COMObject*>(r2.get())->GetRefCount() == 2); 146 } 147 148 void test_pointer_to_ref_assignment() 149 { 150 sal::systools::COMReference<IUnknown> r; 151 r = new COMObject; 152 CPPUNIT_ASSERT_MESSAGE("Wrong reference count 1 is expected", reinterpret_cast<COMObject*>(r.get())->GetRefCount() == 1); 153 } 154 155 void test_pointer_to_ref_assignment2() 156 { 157 sal::systools::COMReference<IUnknown> r = comObjectSource(); 158 r = new COMObject; 159 CPPUNIT_ASSERT_MESSAGE("Wrong reference count 1 is expected", reinterpret_cast<COMObject*>(r.get())->GetRefCount() == 1); 160 } 161 162 void test_source_sink() 163 { 164 CPPUNIT_ASSERT_MESSAGE("Wrong reference count, 0 is expected", comObjectSink(comObjectSource(), 0)); 165 } 166 167 void test_address_operator() 168 { 169 sal::systools::COMReference<IUnknown> r; 170 comObjectSource2(reinterpret_cast<LPVOID*>(&r)); 171 CPPUNIT_ASSERT_MESSAGE("Wrong reference count, 1 is expected", reinterpret_cast<COMObject*>(r.get())->GetRefCount() == 1); 172 } 173 174 void test_address_operator2() 175 { 176 sal::systools::COMReference<IUnknown> r1 = comObjectSource(); 177 sal::systools::COMReference<IUnknown> r2 = r1; 178 CPPUNIT_ASSERT_MESSAGE("Wrong reference count 2 is expected", reinterpret_cast<COMObject*>(r2.get())->GetRefCount() == 2); 179 comObjectSource2(reinterpret_cast<LPVOID*>(&r1)); 180 CPPUNIT_ASSERT_MESSAGE("Wrong reference count 1 is expected", reinterpret_cast<COMObject*>(r1.get())->GetRefCount() == 1); 181 CPPUNIT_ASSERT_MESSAGE("Wrong reference count 1 is expected", reinterpret_cast<COMObject*>(r2.get())->GetRefCount() == 1); 182 } 183 184 void test_clear() 185 { 186 sal::systools::COMReference<IUnknown> r = comObjectSource(); 187 CPPUNIT_ASSERT_MESSAGE("Wrong reference count 1 is expected", reinterpret_cast<COMObject*>(r.get())->GetRefCount() == 1); 188 r.clear(); 189 CPPUNIT_ASSERT_MESSAGE("Expect reference to be empty", !r.is()); 190 } 191 192 void test_query_interface() 193 { 194 try 195 { 196 sal::systools::COMReference<IUnknown> r1 = comObjectSource(); 197 sal::systools::COMReference<IUnknown> r2 = r1.QueryInterface<IUnknown>(IID_IUnknown); 198 CPPUNIT_ASSERT_MESSAGE("Wrong reference count, 2 is expected", reinterpret_cast<COMObject*>(r2.get())->GetRefCount() == 2); 199 } 200 catch(sal::systools::ComError& ex) 201 { 202 CPPUNIT_ASSERT_MESSAGE("Exception should not have been thrown", false); 203 } 204 } 205 206 void test_query_interface_throw() 207 { 208 try 209 { 210 sal::systools::COMReference<IUnknown> r1 = comObjectSource(); 211 sal::systools::COMReference<IPersistFile> r2 = r1.QueryInterface<IPersistFile>(IID_IPersistFile); 212 } 213 catch(sal::systools::ComError& ex) 214 { 215 return; 216 } 217 CPPUNIT_ASSERT_MESSAGE("Exception should have been thrown", false); 218 } 219 220 // Change the following lines only, if you add, remove or rename 221 // member functions of the current class, 222 // because these macros are need by auto register mechanism. 223 224 CPPUNIT_TEST_SUITE(test_COMReference); 225 CPPUNIT_TEST(default_ctor); 226 CPPUNIT_TEST(test_ctor_manual_AddRef); 227 CPPUNIT_TEST(test_copy_ctor); 228 CPPUNIT_TEST(test_copy_assignment); 229 CPPUNIT_TEST(test_ref_to_ref_assignment); 230 CPPUNIT_TEST(test_pointer_to_ref_assignment); 231 CPPUNIT_TEST(test_pointer_to_ref_assignment2); 232 CPPUNIT_TEST(test_source_sink); 233 CPPUNIT_TEST(test_address_operator); 234 CPPUNIT_TEST(test_address_operator2); 235 CPPUNIT_TEST(test_clear); 236 CPPUNIT_TEST(test_query_interface); 237 CPPUNIT_TEST(test_query_interface_throw); 238 CPPUNIT_TEST_SUITE_END(); 239 }; 240 241 // ----------------------------------------------------------------------------- 242 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_comtools::test_COMReference, "test_comtools"); 243 244 } // namespace rtl_OUString 245 246 247 // this macro creates an empty function, which will called by the RegisterAllFunctions() 248 // to let the user the possibility to also register some functions by hand. 249 NOADDITIONAL; 250 251