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:
COMObject()35 COMObject() : ref_count_(0)
36 {
37 }
38
~COMObject()39 ~COMObject()
40 {
41 }
42
AddRef()43 ULONG __stdcall AddRef()
44 {
45 ref_count_++;
46 return ref_count_;
47 }
48
Release()49 ULONG __stdcall Release()
50 {
51 ULONG cnt = --ref_count_;
52 if (cnt == 0)
53 delete this;
54 return cnt;
55 }
56
QueryInterface(REFIID riid,LPVOID * ppv)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
GetRefCount() const68 ULONG GetRefCount() const
69 {
70 return ref_count_;
71 }
72
73 private:
74 ULONG ref_count_;
75 };
76
comObjectSource()77 sal::systools::COMReference<IUnknown> comObjectSource()
78 {
79 return sal::systools::COMReference<IUnknown>(new COMObject);
80 }
81
comObjectSink(sal::systools::COMReference<IUnknown> r,ULONG expectedRefCountOnReturn)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
comObjectSource2(LPVOID * ppv)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;
TEST_F(test_COMReference,default_ctor)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
TEST_F(test_COMReference,test_ctor_manual_AddRef)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
TEST_F(test_COMReference,test_copy_ctor)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
TEST_F(test_COMReference,test_copy_assignment)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
TEST_F(test_COMReference,test_ref_to_ref_assignment)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
TEST_F(test_COMReference,test_pointer_to_ref_assignment)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
TEST_F(test_COMReference,test_pointer_to_ref_assignment2)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
TEST_F(test_COMReference,test_source_sink)158 TEST_F(test_COMReference, test_source_sink)
159 {
160 ASSERT_TRUE(comObjectSink(comObjectSource(), 0)) << "Wrong reference count, 0 is expected";
161 }
162
TEST_F(test_COMReference,test_address_operator)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
TEST_F(test_COMReference,test_address_operator2)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
TEST_F(test_COMReference,test_clear)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
TEST_F(test_COMReference,test_query_interface)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
TEST_F(test_COMReference,test_query_interface_throw)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
main(int argc,char ** argv)218 int main(int argc, char **argv)
219 {
220 ::testing::InitGoogleTest(&argc, argv);
221 return RUN_ALL_TESTS();
222 }
223