1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 25 // MARKER(update_precomp.py): autogen include statement, do not remove 26 #include "precompiled_sal.hxx" 27 // autogenerated file with codegen.pl 28 29 #include <testshl/simpleheader.hxx> 30 #include <systools/win32/comtools.hxx> 31 32 class COMObject : public IUnknown 33 { 34 public: 35 COMObject() : ref_count_(0) 36 { 37 } 38 39 ~COMObject() 40 { 41 } 42 43 ULONG __stdcall AddRef() 44 { 45 ref_count_++; 46 return ref_count_; 47 } 48 49 ULONG __stdcall Release() 50 { 51 ULONG cnt = --ref_count_; 52 if (cnt == 0) 53 delete this; 54 return cnt; 55 } 56 57 HRESULT __stdcall QueryInterface(REFIID riid, LPVOID* ppv) 58 { 59 if (riid == IID_IUnknown) 60 { 61 AddRef(); 62 *ppv = this; 63 return S_OK; 64 } 65 return E_NOINTERFACE; 66 } 67 68 ULONG GetRefCount() const 69 { 70 return ref_count_; 71 } 72 73 private: 74 ULONG ref_count_; 75 }; 76 77 sal::systools::COMReference<IUnknown> comObjectSource() 78 { 79 return sal::systools::COMReference<IUnknown>(new COMObject); 80 } 81 82 bool comObjectSink(sal::systools::COMReference<IUnknown> r, ULONG expectedRefCountOnReturn) 83 { 84 r = sal::systools::COMReference<IUnknown>(); 85 COMObject* p = reinterpret_cast<COMObject*>(r.get()); 86 if (p) 87 return (p->GetRefCount() == expectedRefCountOnReturn); 88 else 89 return (0 == expectedRefCountOnReturn); 90 } 91 92 void comObjectSource2(LPVOID* ppv) 93 { 94 COMObject* p = new COMObject; 95 p->AddRef(); 96 *ppv = p; 97 } 98 99 namespace test_comtools 100 { 101 102 class test_COMReference : public CppUnit::TestFixture 103 { 104 105 public: 106 /// test of COMReference<IUnknown> r; 107 void default_ctor() 108 { 109 sal::systools::COMReference<IUnknown> r; 110 CPPUNIT_ASSERT_MESSAGE("COMReference should be empty", r.get() == NULL); 111 } 112 113 void test_ctor_manual_AddRef() 114 { 115 COMObject* p = new COMObject; 116 p->AddRef(); 117 sal::systools::COMReference<IUnknown> r(p, false); 118 CPPUNIT_ASSERT_MESSAGE("Wrong reference count 1 is expected", reinterpret_cast<COMObject*>(r.get())->GetRefCount() == 1); 119 } 120 121 void test_copy_ctor() 122 { 123 sal::systools::COMReference<IUnknown> r(comObjectSource()); 124 CPPUNIT_ASSERT_MESSAGE("Wrong reference count 1 is expected", reinterpret_cast<COMObject*>(r.get())->GetRefCount() == 1); 125 } 126 127 void test_copy_assignment() 128 { 129 sal::systools::COMReference<IUnknown> r; 130 CPPUNIT_ASSERT_MESSAGE("COMReference should be empty", r.get() == NULL); 131 132 r = comObjectSource(); 133 CPPUNIT_ASSERT_MESSAGE("COMReference should be empty", r.get() != NULL); 134 CPPUNIT_ASSERT_MESSAGE("Wrong reference count 1 is expected", reinterpret_cast<COMObject*>(r.get())->GetRefCount() == 1); 135 } 136 137 void test_ref_to_ref_assignment() 138 { 139 sal::systools::COMReference<IUnknown> r1 = comObjectSource(); 140 sal::systools::COMReference<IUnknown> r2 = r1; 141 CPPUNIT_ASSERT_MESSAGE("Wrong reference count 2 is expected", reinterpret_cast<COMObject*>(r2.get())->GetRefCount() == 2); 142 } 143 144 void test_pointer_to_ref_assignment() 145 { 146 sal::systools::COMReference<IUnknown> r; 147 r = new COMObject; 148 CPPUNIT_ASSERT_MESSAGE("Wrong reference count 1 is expected", reinterpret_cast<COMObject*>(r.get())->GetRefCount() == 1); 149 } 150 151 void test_pointer_to_ref_assignment2() 152 { 153 sal::systools::COMReference<IUnknown> r = comObjectSource(); 154 r = new COMObject; 155 CPPUNIT_ASSERT_MESSAGE("Wrong reference count 1 is expected", reinterpret_cast<COMObject*>(r.get())->GetRefCount() == 1); 156 } 157 158 void test_source_sink() 159 { 160 CPPUNIT_ASSERT_MESSAGE("Wrong reference count, 0 is expected", comObjectSink(comObjectSource(), 0)); 161 } 162 163 void test_address_operator() 164 { 165 sal::systools::COMReference<IUnknown> r; 166 comObjectSource2(reinterpret_cast<LPVOID*>(&r)); 167 CPPUNIT_ASSERT_MESSAGE("Wrong reference count, 1 is expected", reinterpret_cast<COMObject*>(r.get())->GetRefCount() == 1); 168 } 169 170 void test_address_operator2() 171 { 172 sal::systools::COMReference<IUnknown> r1 = comObjectSource(); 173 sal::systools::COMReference<IUnknown> r2 = r1; 174 CPPUNIT_ASSERT_MESSAGE("Wrong reference count 2 is expected", reinterpret_cast<COMObject*>(r2.get())->GetRefCount() == 2); 175 comObjectSource2(reinterpret_cast<LPVOID*>(&r1)); 176 CPPUNIT_ASSERT_MESSAGE("Wrong reference count 1 is expected", reinterpret_cast<COMObject*>(r1.get())->GetRefCount() == 1); 177 CPPUNIT_ASSERT_MESSAGE("Wrong reference count 1 is expected", reinterpret_cast<COMObject*>(r2.get())->GetRefCount() == 1); 178 } 179 180 void test_clear() 181 { 182 sal::systools::COMReference<IUnknown> r = comObjectSource(); 183 CPPUNIT_ASSERT_MESSAGE("Wrong reference count 1 is expected", reinterpret_cast<COMObject*>(r.get())->GetRefCount() == 1); 184 r.clear(); 185 CPPUNIT_ASSERT_MESSAGE("Expect reference to be empty", !r.is()); 186 } 187 188 void test_query_interface() 189 { 190 try 191 { 192 sal::systools::COMReference<IUnknown> r1 = comObjectSource(); 193 sal::systools::COMReference<IUnknown> r2 = r1.QueryInterface<IUnknown>(IID_IUnknown); 194 CPPUNIT_ASSERT_MESSAGE("Wrong reference count, 2 is expected", reinterpret_cast<COMObject*>(r2.get())->GetRefCount() == 2); 195 } 196 catch(sal::systools::ComError& ex) 197 { 198 CPPUNIT_ASSERT_MESSAGE("Exception should not have been thrown", false); 199 } 200 } 201 202 void test_query_interface_throw() 203 { 204 try 205 { 206 sal::systools::COMReference<IUnknown> r1 = comObjectSource(); 207 sal::systools::COMReference<IPersistFile> r2 = r1.QueryInterface<IPersistFile>(IID_IPersistFile); 208 } 209 catch(sal::systools::ComError& ex) 210 { 211 return; 212 } 213 CPPUNIT_ASSERT_MESSAGE("Exception should have been thrown", false); 214 } 215 216 // Change the following lines only, if you add, remove or rename 217 // member functions of the current class, 218 // because these macros are need by auto register mechanism. 219 220 CPPUNIT_TEST_SUITE(test_COMReference); 221 CPPUNIT_TEST(default_ctor); 222 CPPUNIT_TEST(test_ctor_manual_AddRef); 223 CPPUNIT_TEST(test_copy_ctor); 224 CPPUNIT_TEST(test_copy_assignment); 225 CPPUNIT_TEST(test_ref_to_ref_assignment); 226 CPPUNIT_TEST(test_pointer_to_ref_assignment); 227 CPPUNIT_TEST(test_pointer_to_ref_assignment2); 228 CPPUNIT_TEST(test_source_sink); 229 CPPUNIT_TEST(test_address_operator); 230 CPPUNIT_TEST(test_address_operator2); 231 CPPUNIT_TEST(test_clear); 232 CPPUNIT_TEST(test_query_interface); 233 CPPUNIT_TEST(test_query_interface_throw); 234 CPPUNIT_TEST_SUITE_END(); 235 }; 236 237 // ----------------------------------------------------------------------------- 238 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_comtools::test_COMReference, "test_comtools"); 239 240 } // namespace rtl_OUString 241 242 243 // this macro creates an empty function, which will called by the RegisterAllFunctions() 244 // to let the user the possibility to also register some functions by hand. 245 NOADDITIONAL; 246 247