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:
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 CppUnit::TestFixture
103 {
104
105 public:
106 /// test of COMReference<IUnknown> r;
default_ctor()107 void default_ctor()
108 {
109 sal::systools::COMReference<IUnknown> r;
110 CPPUNIT_ASSERT_MESSAGE("COMReference should be empty", r.get() == NULL);
111 }
112
test_ctor_manual_AddRef()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
test_copy_ctor()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
test_copy_assignment()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
test_ref_to_ref_assignment()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
test_pointer_to_ref_assignment()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
test_pointer_to_ref_assignment2()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
test_source_sink()158 void test_source_sink()
159 {
160 CPPUNIT_ASSERT_MESSAGE("Wrong reference count, 0 is expected", comObjectSink(comObjectSource(), 0));
161 }
162
test_address_operator()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
test_address_operator2()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
test_clear()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
test_query_interface()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
test_query_interface_throw()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