Add 'reference' to the iterator_traits, needed by LegacyIterator reqs
[LibreOffice.git] / cppu / qa / typelib.cxx
blob227e5731cc4faebb90e29af015e75992f23f4087
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <sal/config.h>
12 #include <cppunit/TestFixture.h>
13 #include <cppunit/extensions/HelperMacros.h>
14 #include <cppunit/plugin/TestPlugIn.h>
16 #include <com/sun/star/io/XActiveDataSink.hpp>
17 #include <com/sun/star/io/XTextInputStream.hpp>
18 #include <com/sun/star/lang/EventObject.hpp>
19 #include <com/sun/star/script/FinishReason.hpp>
20 #include <com/sun/star/uno/Any.hxx>
21 #include <com/sun/star/uno/Type.hxx>
22 #include <com/sun/star/uno/XInterface.hpp>
23 #include <cppu/unotype.hxx>
24 #include <rtl/ustring.hxx>
25 #include <sal/types.h>
26 #include <typelib/typedescription.h>
27 #include <typelib/typedescription.hxx>
29 // Test that typelib_typedescription_register as called from typelib_typedescription_complete
30 // returns a correct typelib_TypeDescription and keeps pointers from the original
31 // typelib_TypeDescription intact (see tdf#115399 "Data race in typelib_typedescription_register").
32 // This code uses sufficiently "obscure" types in typelib_static_*_type_init to make it unlikely
33 // that they are already instantiated and registered with the type description manager, which might
34 // cause inconsistencies.
36 namespace
38 class Test : public CppUnit::TestFixture
40 public:
41 void testEnum()
43 typelib_TypeDescriptionReference* ref = nullptr;
44 typelib_static_enum_type_init(&ref, "com.sun.star.script.MemberType", 0);
45 CPPUNIT_ASSERT(ref != nullptr);
46 typelib_TypeDescription* td = ref->pType;
47 CPPUNIT_ASSERT(td != nullptr);
48 typelib_typedescription_acquire(td);
49 CPPUNIT_ASSERT(!td->bComplete);
50 auto t = reinterpret_cast<typelib_EnumTypeDescription*>(td);
51 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), t->nDefaultEnumValue);
52 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), t->nEnumValues);
53 CPPUNIT_ASSERT(t->ppEnumNames == nullptr);
54 CPPUNIT_ASSERT(t->pEnumValues == nullptr);
55 CPPUNIT_ASSERT(typelib_typedescription_complete(&td));
56 CPPUNIT_ASSERT(td != nullptr);
57 CPPUNIT_ASSERT(td->bComplete);
58 t = reinterpret_cast<typelib_EnumTypeDescription*>(td);
59 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), t->nDefaultEnumValue);
60 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), t->nEnumValues);
61 CPPUNIT_ASSERT(t->ppEnumNames != nullptr);
62 CPPUNIT_ASSERT_EQUAL(OUString("METHOD"), OUString::unacquired(&t->ppEnumNames[0]));
63 CPPUNIT_ASSERT_EQUAL(OUString("PROPERTY"), OUString::unacquired(&t->ppEnumNames[1]));
64 CPPUNIT_ASSERT_EQUAL(OUString("UNKNOWN"), OUString::unacquired(&t->ppEnumNames[2]));
65 CPPUNIT_ASSERT(t->pEnumValues != nullptr);
66 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), t->pEnumValues[0]);
67 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), t->pEnumValues[1]);
68 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), t->pEnumValues[2]);
69 typelib_typedescription_release(td);
70 typelib_typedescriptionreference_release(ref);
73 void testStruct()
75 auto const t0 = cppu::UnoType<css::lang::EventObject>::get();
76 auto const t1 = cppu::UnoType<css::script::FinishReason>::get();
77 auto const t2 = cppu::UnoType<OUString>::get();
78 auto const t3 = cppu::UnoType<css::uno::Any>::get();
79 typelib_TypeDescriptionReference* ref = nullptr;
80 typelib_TypeDescriptionReference* members[3]
81 = { t1.getTypeLibType(), t2.getTypeLibType(), t3.getTypeLibType() };
82 typelib_static_struct_type_init(&ref, "com.sun.star.script.FinishEngineEvent",
83 t0.getTypeLibType(), 3, members, nullptr);
84 CPPUNIT_ASSERT(ref != nullptr);
85 typelib_TypeDescription* td = ref->pType;
86 CPPUNIT_ASSERT(td != nullptr);
87 typelib_typedescription_acquire(td);
88 CPPUNIT_ASSERT(!td->bComplete);
89 auto t = reinterpret_cast<typelib_StructTypeDescription*>(td);
90 CPPUNIT_ASSERT(css::uno::TypeDescription(&t->aBase.pBaseTypeDescription->aBase).equals(t0));
91 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), t->aBase.nMembers);
92 auto const offsets = t->aBase.pMemberOffsets;
93 CPPUNIT_ASSERT(offsets != nullptr);
94 auto const typerefs = t->aBase.ppTypeRefs;
95 CPPUNIT_ASSERT(typerefs != nullptr);
96 CPPUNIT_ASSERT_EQUAL(t1, css::uno::Type(typerefs[0]));
97 CPPUNIT_ASSERT_EQUAL(t2, css::uno::Type(typerefs[1]));
98 CPPUNIT_ASSERT_EQUAL(t3, css::uno::Type(typerefs[2]));
99 CPPUNIT_ASSERT(t->aBase.ppMemberNames == nullptr);
100 CPPUNIT_ASSERT(t->pParameterizedTypes == nullptr);
101 CPPUNIT_ASSERT(typelib_typedescription_complete(&td));
102 CPPUNIT_ASSERT(td != nullptr);
103 CPPUNIT_ASSERT(td->bComplete);
104 t = reinterpret_cast<typelib_StructTypeDescription*>(td);
105 CPPUNIT_ASSERT(css::uno::TypeDescription(&t->aBase.pBaseTypeDescription->aBase).equals(t0));
106 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), t->aBase.nMembers);
107 CPPUNIT_ASSERT(t->aBase.pMemberOffsets != nullptr);
108 CPPUNIT_ASSERT(t->aBase.ppTypeRefs != nullptr);
109 CPPUNIT_ASSERT_EQUAL(t1, css::uno::Type(t->aBase.ppTypeRefs[0]));
110 CPPUNIT_ASSERT_EQUAL(t2, css::uno::Type(t->aBase.ppTypeRefs[1]));
111 CPPUNIT_ASSERT_EQUAL(t3, css::uno::Type(t->aBase.ppTypeRefs[2]));
112 CPPUNIT_ASSERT(t->aBase.ppMemberNames != nullptr);
113 CPPUNIT_ASSERT_EQUAL(OUString("Finish"), OUString::unacquired(&t->aBase.ppMemberNames[0]));
114 CPPUNIT_ASSERT_EQUAL(OUString("ErrorMessage"),
115 OUString::unacquired(&t->aBase.ppMemberNames[1]));
116 CPPUNIT_ASSERT_EQUAL(OUString("Return"), OUString::unacquired(&t->aBase.ppMemberNames[2]));
117 CPPUNIT_ASSERT(t->pParameterizedTypes == nullptr);
118 // `offsets` and `typerefs` must still be valid:
119 CPPUNIT_ASSERT_EQUAL(t->aBase.pMemberOffsets[0], offsets[0]);
120 CPPUNIT_ASSERT_EQUAL(t->aBase.pMemberOffsets[1], offsets[1]);
121 CPPUNIT_ASSERT_EQUAL(t->aBase.pMemberOffsets[2], offsets[2]);
122 CPPUNIT_ASSERT_EQUAL(css::uno::Type(t->aBase.ppTypeRefs[0]), css::uno::Type(typerefs[0]));
123 CPPUNIT_ASSERT_EQUAL(css::uno::Type(t->aBase.ppTypeRefs[1]), css::uno::Type(typerefs[1]));
124 CPPUNIT_ASSERT_EQUAL(css::uno::Type(t->aBase.ppTypeRefs[2]), css::uno::Type(typerefs[2]));
125 typelib_typedescription_release(td);
126 typelib_typedescriptionreference_release(ref);
129 void testPolyStruct()
131 auto const t1 = cppu::UnoType<bool>::get();
132 auto const t2 = cppu::UnoType<sal_Int32>::get();
133 typelib_TypeDescriptionReference* ref = nullptr;
134 typelib_TypeDescriptionReference* members[2] = { t1.getTypeLibType(), t2.getTypeLibType() };
135 sal_Bool const param[2] = { false, true };
136 typelib_static_struct_type_init(&ref, "com.sun.star.beans.Optional<long>", nullptr, 2,
137 members, param);
138 CPPUNIT_ASSERT(ref != nullptr);
139 typelib_TypeDescription* td = ref->pType;
140 CPPUNIT_ASSERT(td != nullptr);
141 typelib_typedescription_acquire(td);
142 CPPUNIT_ASSERT(!td->bComplete);
143 auto t = reinterpret_cast<typelib_StructTypeDescription*>(td);
144 CPPUNIT_ASSERT(t->aBase.pBaseTypeDescription == nullptr);
145 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), t->aBase.nMembers);
146 auto const offsets = t->aBase.pMemberOffsets;
147 CPPUNIT_ASSERT(offsets != nullptr);
148 auto const typerefs = t->aBase.ppTypeRefs;
149 CPPUNIT_ASSERT(typerefs != nullptr);
150 CPPUNIT_ASSERT_EQUAL(t1, css::uno::Type(typerefs[0]));
151 CPPUNIT_ASSERT_EQUAL(t2, css::uno::Type(typerefs[1]));
152 CPPUNIT_ASSERT(t->aBase.ppMemberNames == nullptr);
153 CPPUNIT_ASSERT(t->pParameterizedTypes != nullptr);
154 CPPUNIT_ASSERT_EQUAL(param[0], t->pParameterizedTypes[0]);
155 CPPUNIT_ASSERT_EQUAL(param[1], t->pParameterizedTypes[1]);
156 CPPUNIT_ASSERT(typelib_typedescription_complete(&td));
157 CPPUNIT_ASSERT(td != nullptr);
158 CPPUNIT_ASSERT(td->bComplete);
159 t = reinterpret_cast<typelib_StructTypeDescription*>(td);
160 CPPUNIT_ASSERT(t->aBase.pBaseTypeDescription == nullptr);
161 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), t->aBase.nMembers);
162 CPPUNIT_ASSERT(t->aBase.pMemberOffsets != nullptr);
163 CPPUNIT_ASSERT(t->aBase.ppTypeRefs != nullptr);
164 CPPUNIT_ASSERT_EQUAL(t1, css::uno::Type(t->aBase.ppTypeRefs[0]));
165 CPPUNIT_ASSERT_EQUAL(t2, css::uno::Type(t->aBase.ppTypeRefs[1]));
166 CPPUNIT_ASSERT(t->aBase.ppMemberNames != nullptr);
167 CPPUNIT_ASSERT_EQUAL(OUString("IsPresent"),
168 OUString::unacquired(&t->aBase.ppMemberNames[0]));
169 CPPUNIT_ASSERT_EQUAL(OUString("Value"), OUString::unacquired(&t->aBase.ppMemberNames[1]));
170 CPPUNIT_ASSERT(t->pParameterizedTypes != nullptr);
171 CPPUNIT_ASSERT_EQUAL(param[0], t->pParameterizedTypes[0]);
172 CPPUNIT_ASSERT_EQUAL(param[1], t->pParameterizedTypes[1]);
173 // `offsets` and `typerefs` must still be valid:
174 CPPUNIT_ASSERT_EQUAL(t->aBase.pMemberOffsets[0], offsets[0]);
175 CPPUNIT_ASSERT_EQUAL(t->aBase.pMemberOffsets[1], offsets[1]);
176 CPPUNIT_ASSERT_EQUAL(css::uno::Type(t->aBase.ppTypeRefs[0]), css::uno::Type(typerefs[0]));
177 CPPUNIT_ASSERT_EQUAL(css::uno::Type(t->aBase.ppTypeRefs[1]), css::uno::Type(typerefs[1]));
178 typelib_typedescription_release(td);
179 typelib_typedescriptionreference_release(ref);
182 void testInterface()
184 auto const t0 = cppu::UnoType<css::uno::XInterface>::get();
185 typelib_TypeDescriptionReference* ref = nullptr;
186 typelib_TypeDescriptionReference* bases[1] = { t0.getTypeLibType() };
187 typelib_static_mi_interface_type_init(&ref, "com.sun.star.script.XTypeConverter", 1, bases);
188 CPPUNIT_ASSERT(ref != nullptr);
189 typelib_TypeDescription* td = ref->pType;
190 CPPUNIT_ASSERT(td != nullptr);
191 typelib_typedescription_acquire(td);
192 CPPUNIT_ASSERT(!td->bComplete);
193 auto t = reinterpret_cast<typelib_InterfaceTypeDescription*>(td);
194 CPPUNIT_ASSERT(css::uno::TypeDescription(&t->pBaseTypeDescription->aBase).equals(t0));
195 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), t->nMembers);
196 CPPUNIT_ASSERT(t->ppMembers == nullptr);
197 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), t->nAllMembers);
198 CPPUNIT_ASSERT(t->ppAllMembers == nullptr);
199 CPPUNIT_ASSERT(t->pMapMemberIndexToFunctionIndex == nullptr);
200 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), t->nMapFunctionIndexToMemberIndex);
201 CPPUNIT_ASSERT(t->pMapFunctionIndexToMemberIndex == nullptr);
202 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), t->nBaseTypes);
203 auto const basetypes = t->ppBaseTypes;
204 CPPUNIT_ASSERT(basetypes != nullptr);
205 CPPUNIT_ASSERT(css::uno::TypeDescription(&basetypes[0]->aBase).equals(t0));
206 CPPUNIT_ASSERT(typelib_typedescription_complete(&td));
207 CPPUNIT_ASSERT(td != nullptr);
208 CPPUNIT_ASSERT(td->bComplete);
209 t = reinterpret_cast<typelib_InterfaceTypeDescription*>(td);
210 CPPUNIT_ASSERT(css::uno::TypeDescription(&t->pBaseTypeDescription->aBase).equals(t0));
211 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), t->nMembers);
212 CPPUNIT_ASSERT(t->ppMembers != nullptr);
213 CPPUNIT_ASSERT_EQUAL(sal_Int32(5), t->nAllMembers);
214 CPPUNIT_ASSERT(t->ppAllMembers != nullptr);
215 CPPUNIT_ASSERT(t->pMapMemberIndexToFunctionIndex != nullptr);
216 CPPUNIT_ASSERT_EQUAL(sal_Int32(5), t->nMapFunctionIndexToMemberIndex);
217 CPPUNIT_ASSERT(t->pMapFunctionIndexToMemberIndex != nullptr);
218 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), t->nBaseTypes);
219 CPPUNIT_ASSERT(t->ppBaseTypes != nullptr);
220 CPPUNIT_ASSERT(css::uno::TypeDescription(&t->ppBaseTypes[0]->aBase).equals(t0));
221 // `basetypes` must still be valid:
222 CPPUNIT_ASSERT(
223 css::uno::TypeDescription(&basetypes[0]->aBase).equals(&t->ppBaseTypes[0]->aBase));
224 typelib_typedescription_release(td);
225 typelib_typedescriptionreference_release(ref);
228 void testMultiInterface()
230 auto const t1 = cppu::UnoType<css::io::XTextInputStream>::get();
231 auto const t2 = cppu::UnoType<css::io::XActiveDataSink>::get();
232 typelib_TypeDescriptionReference* ref = nullptr;
233 typelib_TypeDescriptionReference* bases[2] = { t1.getTypeLibType(), t2.getTypeLibType() };
234 typelib_static_mi_interface_type_init(&ref, "com.sun.star.io.XTextInputStream2", 2, bases);
235 CPPUNIT_ASSERT(ref != nullptr);
236 typelib_TypeDescription* td = ref->pType;
237 CPPUNIT_ASSERT(td != nullptr);
238 typelib_typedescription_acquire(td);
239 CPPUNIT_ASSERT(!td->bComplete);
240 auto t = reinterpret_cast<typelib_InterfaceTypeDescription*>(td);
241 CPPUNIT_ASSERT(css::uno::TypeDescription(&t->pBaseTypeDescription->aBase).equals(t1));
242 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), t->nMembers);
243 CPPUNIT_ASSERT(t->ppMembers == nullptr);
244 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), t->nAllMembers);
245 CPPUNIT_ASSERT(t->ppAllMembers == nullptr);
246 CPPUNIT_ASSERT(t->pMapMemberIndexToFunctionIndex == nullptr);
247 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), t->nMapFunctionIndexToMemberIndex);
248 CPPUNIT_ASSERT(t->pMapFunctionIndexToMemberIndex == nullptr);
249 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), t->nBaseTypes);
250 auto const basetypes = t->ppBaseTypes;
251 CPPUNIT_ASSERT(basetypes != nullptr);
252 CPPUNIT_ASSERT(css::uno::TypeDescription(&basetypes[0]->aBase).equals(t1));
253 CPPUNIT_ASSERT(css::uno::TypeDescription(&basetypes[1]->aBase).equals(t2));
254 CPPUNIT_ASSERT(typelib_typedescription_complete(&td));
255 CPPUNIT_ASSERT(td != nullptr);
256 CPPUNIT_ASSERT(td->bComplete);
257 t = reinterpret_cast<typelib_InterfaceTypeDescription*>(td);
258 CPPUNIT_ASSERT(css::uno::TypeDescription(&t->pBaseTypeDescription->aBase).equals(t1));
259 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), t->nMembers);
260 CPPUNIT_ASSERT(t->ppMembers == nullptr);
261 CPPUNIT_ASSERT_EQUAL(sal_Int32(14), t->nAllMembers);
262 CPPUNIT_ASSERT(t->ppAllMembers != nullptr);
263 CPPUNIT_ASSERT(t->pMapMemberIndexToFunctionIndex != nullptr);
264 CPPUNIT_ASSERT_EQUAL(sal_Int32(14), t->nMapFunctionIndexToMemberIndex);
265 CPPUNIT_ASSERT(t->pMapFunctionIndexToMemberIndex != nullptr);
266 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), t->nBaseTypes);
267 CPPUNIT_ASSERT(t->ppBaseTypes != nullptr);
268 CPPUNIT_ASSERT(css::uno::TypeDescription(&t->ppBaseTypes[0]->aBase).equals(t1));
269 CPPUNIT_ASSERT(css::uno::TypeDescription(&t->ppBaseTypes[1]->aBase).equals(t2));
270 // `basetypes` must still be valid:
271 CPPUNIT_ASSERT(
272 css::uno::TypeDescription(&basetypes[0]->aBase).equals(&t->ppBaseTypes[0]->aBase));
273 CPPUNIT_ASSERT(
274 css::uno::TypeDescription(&basetypes[1]->aBase).equals(&t->ppBaseTypes[1]->aBase));
275 typelib_typedescription_release(td);
276 typelib_typedescriptionreference_release(ref);
279 CPPUNIT_TEST_SUITE(Test);
280 CPPUNIT_TEST(testEnum);
281 CPPUNIT_TEST(testStruct);
282 CPPUNIT_TEST(testPolyStruct);
283 CPPUNIT_TEST(testInterface);
284 CPPUNIT_TEST(testMultiInterface);
285 CPPUNIT_TEST_SUITE_END();
288 CPPUNIT_TEST_SUITE_REGISTRATION(Test);
291 CPPUNIT_PLUGIN_IMPLEMENT();
293 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */