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 "gtest/gtest.h" 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 ::testing::Test 103 { 104 }; 105 106 /// test of COMReference<IUnknown> r; 107 TEST_F(test_COMReference, default_ctor) 108 { 109 sal::systools::COMReference<IUnknown> r; 110 ASSERT_TRUE(r.get() == NULL) << "COMReference should be empty"; 111 } 112 113 TEST_F(test_COMReference, test_ctor_manual_AddRef) 114 { 115 COMObject* p = new COMObject; 116 p->AddRef(); 117 sal::systools::COMReference<IUnknown> r(p, false); 118 ASSERT_TRUE(reinterpret_cast<COMObject*>(r.get())->GetRefCount() == 1) << "Wrong reference count 1 is expected"; 119 } 120 121 TEST_F(test_COMReference, test_copy_ctor) 122 { 123 sal::systools::COMReference<IUnknown> r(comObjectSource()); 124 ASSERT_TRUE(reinterpret_cast<COMObject*>(r.get())->GetRefCount() == 1) << "Wrong reference count 1 is expected"; 125 } 126 127 TEST_F(test_COMReference, test_copy_assignment) 128 { 129 sal::systools::COMReference<IUnknown> r; 130 ASSERT_TRUE(r.get() == NULL) << "COMReference should be empty"; 131 132 r = comObjectSource(); 133 ASSERT_TRUE(r.get() != NULL) << "COMReference should be empty"; 134 ASSERT_TRUE(reinterpret_cast<COMObject*>(r.get())->GetRefCount() == 1) << "Wrong reference count 1 is expected"; 135 } 136 137 TEST_F(test_COMReference, test_ref_to_ref_assignment) 138 { 139 sal::systools::COMReference<IUnknown> r1 = comObjectSource(); 140 sal::systools::COMReference<IUnknown> r2 = r1; 141 ASSERT_TRUE(reinterpret_cast<COMObject*>(r2.get())->GetRefCount() == 2) << "Wrong reference count 2 is expected"; 142 } 143 144 TEST_F(test_COMReference, test_pointer_to_ref_assignment) 145 { 146 sal::systools::COMReference<IUnknown> r; 147 r = new COMObject; 148 ASSERT_TRUE(reinterpret_cast<COMObject*>(r.get())->GetRefCount() == 1) << "Wrong reference count 1 is expected"; 149 } 150 151 TEST_F(test_COMReference, test_pointer_to_ref_assignment2) 152 { 153 sal::systools::COMReference<IUnknown> r = comObjectSource(); 154 r = new COMObject; 155 ASSERT_TRUE(reinterpret_cast<COMObject*>(r.get())->GetRefCount() == 1) << "Wrong reference count 1 is expected"; 156 } 157 158 TEST_F(test_COMReference, test_source_sink) 159 { 160 ASSERT_TRUE(comObjectSink(comObjectSource(), 0)) << "Wrong reference count, 0 is expected"; 161 } 162 163 TEST_F(test_COMReference, test_address_operator) 164 { 165 sal::systools::COMReference<IUnknown> r; 166 comObjectSource2(reinterpret_cast<LPVOID*>(&r)); 167 ASSERT_TRUE(reinterpret_cast<COMObject*>(r.get())->GetRefCount() == 1) << "Wrong reference count, 1 is expected"; 168 } 169 170 TEST_F(test_COMReference, test_address_operator2) 171 { 172 sal::systools::COMReference<IUnknown> r1 = comObjectSource(); 173 sal::systools::COMReference<IUnknown> r2 = r1; 174 ASSERT_TRUE(reinterpret_cast<COMObject*>(r2.get())->GetRefCount() == 2) << "Wrong reference count 2 is expected"; 175 comObjectSource2(reinterpret_cast<LPVOID*>(&r1)); 176 ASSERT_TRUE(reinterpret_cast<COMObject*>(r1.get())->GetRefCount() == 1) << "Wrong reference count 1 is expected"; 177 ASSERT_TRUE(reinterpret_cast<COMObject*>(r2.get())->GetRefCount() == 1) << "Wrong reference count 1 is expected"; 178 } 179 180 TEST_F(test_COMReference, test_clear) 181 { 182 sal::systools::COMReference<IUnknown> r = comObjectSource(); 183 ASSERT_TRUE(reinterpret_cast<COMObject*>(r.get())->GetRefCount() == 1) << "Wrong reference count 1 is expected"; 184 r.clear(); 185 ASSERT_TRUE(!r.is()) << "Expect reference to be empty"; 186 } 187 188 TEST_F(test_COMReference, 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 ASSERT_TRUE(reinterpret_cast<COMObject*>(r2.get())->GetRefCount() == 2) << "Wrong reference count, 2 is expected"; 195 } 196 catch(sal::systools::ComError& ex) 197 { 198 ASSERT_TRUE(false) << "Exception should not have been thrown"; 199 } 200 } 201 202 TEST_F(test_COMReference, 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 ASSERT_TRUE(false) << "Exception should have been thrown"; 214 } 215 216 } // namespace rtl_OUString 217 218 int main(int argc, char **argv) 219 { 220 ::testing::InitGoogleTest(&argc, argv); 221 return RUN_ALL_TESTS(); 222 } 223