Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 : #ifndef ASSIGN_HXX
20 : #define ASSIGN_HXX
21 :
22 : #include <string.h>
23 :
24 : #include "prim.hxx"
25 : #include "destr.hxx"
26 : #include "constr.hxx"
27 : #include "copy.hxx"
28 :
29 :
30 : namespace cppu
31 : {
32 :
33 :
34 : //#### assignment ##################################################################################
35 :
36 :
37 :
38 :
39 717730 : inline void _assignInterface(
40 : void ** ppDest, void * pSource,
41 : uno_AcquireFunc acquire, uno_ReleaseFunc release )
42 : SAL_THROW(())
43 : {
44 717730 : _acquire( pSource, acquire );
45 717730 : void * const pToBeReleased = *ppDest;
46 717730 : *ppDest = pSource;
47 717730 : _release( pToBeReleased, release );
48 717730 : }
49 :
50 866342 : inline void * _queryInterface(
51 : void * pSource,
52 : typelib_TypeDescriptionReference * pDestType,
53 : uno_QueryInterfaceFunc queryInterface )
54 : SAL_THROW(())
55 : {
56 866342 : if (pSource)
57 : {
58 866342 : if (0 == queryInterface)
59 0 : queryInterface = binuno_queryInterface;
60 866342 : pSource = (*queryInterface)( pSource, pDestType );
61 : }
62 866342 : return pSource;
63 : }
64 :
65 : bool assignStruct(
66 : void * pDest, void * pSource,
67 : typelib_CompoundTypeDescription * pTypeDescr,
68 : uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release )
69 : SAL_THROW(());
70 :
71 1265011 : inline bool _assignStruct(
72 : void * pDest, void * pSource,
73 : typelib_CompoundTypeDescription * pTypeDescr,
74 : uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release )
75 : SAL_THROW(())
76 : {
77 1265011 : if (pTypeDescr->pBaseTypeDescription)
78 : {
79 : // copy base value
80 91396 : if (! assignStruct( pDest, pSource, pTypeDescr->pBaseTypeDescription,
81 91396 : queryInterface, acquire, release ))
82 : {
83 0 : return false;
84 : }
85 : }
86 : // then copy members
87 1265011 : typelib_TypeDescriptionReference ** ppTypeRefs = pTypeDescr->ppTypeRefs;
88 1265011 : sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets;
89 1265011 : sal_Int32 nDescr = pTypeDescr->nMembers;
90 7264511 : while (nDescr--)
91 : {
92 14203467 : if (! ::uno_type_assignData( (char *)pDest + pMemberOffsets[nDescr],
93 4734489 : ppTypeRefs[nDescr],
94 9468978 : (char *)pSource + pMemberOffsets[nDescr],
95 4734489 : ppTypeRefs[nDescr],
96 23672445 : queryInterface, acquire, release ))
97 : {
98 0 : return false;
99 : }
100 : }
101 1265011 : return true;
102 : }
103 :
104 9785101 : inline bool _assignData(
105 : void * pDest,
106 : typelib_TypeDescriptionReference * pDestType, typelib_TypeDescription * pDestTypeDescr,
107 : void * pSource,
108 : typelib_TypeDescriptionReference * pSourceType, typelib_TypeDescription * pSourceTypeDescr,
109 : uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release )
110 : SAL_THROW(())
111 : {
112 9785101 : if (pDest == pSource)
113 0 : return _type_equals( pDestType, pSourceType );
114 :
115 9785101 : if (! pSource)
116 : {
117 0 : _destructData( pDest, pDestType, pDestTypeDescr, release );
118 0 : _defaultConstructData( pDest, pDestType, pDestTypeDescr );
119 0 : return true;
120 : }
121 20289340 : while (typelib_TypeClass_ANY == pSourceType->eTypeClass)
122 : {
123 719138 : pSourceTypeDescr = 0;
124 719138 : pSourceType = ((uno_Any *)pSource)->pType;
125 719138 : pSource = ((uno_Any *)pSource)->pData;
126 719138 : if (pDest == pSource)
127 0 : return true;
128 : }
129 :
130 9785101 : switch (pDestType->eTypeClass)
131 : {
132 : case typelib_TypeClass_VOID:
133 0 : return pSourceType->eTypeClass == typelib_TypeClass_VOID;
134 : case typelib_TypeClass_CHAR:
135 7 : switch (pSourceType->eTypeClass)
136 : {
137 : case typelib_TypeClass_CHAR:
138 7 : *(sal_Unicode *)pDest = *(sal_Unicode *)pSource;
139 7 : return true;
140 : default:
141 0 : return false;
142 : }
143 : case typelib_TypeClass_BOOLEAN:
144 127900 : switch (pSourceType->eTypeClass)
145 : {
146 : case typelib_TypeClass_BOOLEAN:
147 127884 : *(sal_Bool *)pDest = (*(sal_Bool *)pSource != sal_False);
148 127884 : return true;
149 : default:
150 16 : return false;
151 : }
152 : case typelib_TypeClass_BYTE:
153 13 : switch (pSourceType->eTypeClass)
154 : {
155 : case typelib_TypeClass_BYTE:
156 13 : *(sal_Int8 *)pDest = *(sal_Int8 *)pSource;
157 13 : return true;
158 : default:
159 0 : return false;
160 : }
161 : case typelib_TypeClass_SHORT:
162 476428 : switch (pSourceType->eTypeClass)
163 : {
164 : case typelib_TypeClass_BYTE:
165 29 : *(sal_Int16 *)pDest = *(sal_Int8 *)pSource;
166 29 : return true;
167 : case typelib_TypeClass_SHORT:
168 : case typelib_TypeClass_UNSIGNED_SHORT:
169 476388 : *(sal_Int16 *)pDest = *(sal_Int16 *)pSource;
170 476388 : return true;
171 : default:
172 11 : return false;
173 : }
174 : case typelib_TypeClass_UNSIGNED_SHORT:
175 9236 : switch (pSourceType->eTypeClass)
176 : {
177 : case typelib_TypeClass_BYTE:
178 0 : *(sal_uInt16 *)pDest = *(sal_Int8 *)pSource;
179 0 : return true;
180 : case typelib_TypeClass_SHORT:
181 : case typelib_TypeClass_UNSIGNED_SHORT:
182 9236 : *(sal_uInt16 *)pDest = *(sal_uInt16 *)pSource;
183 9236 : return true;
184 : default:
185 0 : return false;
186 : }
187 : case typelib_TypeClass_LONG:
188 1027504 : switch (pSourceType->eTypeClass)
189 : {
190 : case typelib_TypeClass_BYTE:
191 33 : *(sal_Int32 *)pDest = *(sal_Int8 *)pSource;
192 33 : return true;
193 : case typelib_TypeClass_SHORT:
194 278 : *(sal_Int32 *)pDest = *(sal_Int16 *)pSource;
195 278 : return true;
196 : case typelib_TypeClass_UNSIGNED_SHORT:
197 0 : *(sal_Int32 *)pDest = *(sal_uInt16 *)pSource;
198 0 : return true;
199 : case typelib_TypeClass_LONG:
200 : case typelib_TypeClass_UNSIGNED_LONG:
201 1023972 : *(sal_Int32 *)pDest = *(sal_Int32 *)pSource;
202 1023972 : return true;
203 : default:
204 3221 : return false;
205 : }
206 : case typelib_TypeClass_UNSIGNED_LONG:
207 35681 : switch (pSourceType->eTypeClass)
208 : {
209 : case typelib_TypeClass_BYTE:
210 4 : *(sal_uInt32 *)pDest = *(sal_Int8 *)pSource;
211 4 : return true;
212 : case typelib_TypeClass_SHORT:
213 0 : *(sal_uInt32 *)pDest = *(sal_Int16 *)pSource;
214 0 : return true;
215 : case typelib_TypeClass_UNSIGNED_SHORT:
216 0 : *(sal_uInt32 *)pDest = *(sal_uInt16 *)pSource;
217 0 : return true;
218 : case typelib_TypeClass_LONG:
219 : case typelib_TypeClass_UNSIGNED_LONG:
220 35677 : *(sal_uInt32 *)pDest = *(sal_uInt32 *)pSource;
221 35677 : return true;
222 : default:
223 0 : return false;
224 : }
225 : case typelib_TypeClass_HYPER:
226 1 : switch (pSourceType->eTypeClass)
227 : {
228 : case typelib_TypeClass_BYTE:
229 0 : *(sal_Int64 *)pDest = *(sal_Int8 *)pSource;
230 0 : return true;
231 : case typelib_TypeClass_SHORT:
232 0 : *(sal_Int64 *)pDest = *(sal_Int16 *)pSource;
233 0 : return true;
234 : case typelib_TypeClass_UNSIGNED_SHORT:
235 0 : *(sal_Int64 *)pDest = *(sal_uInt16 *)pSource;
236 0 : return true;
237 : case typelib_TypeClass_LONG:
238 0 : *(sal_Int64 *)pDest = *(sal_Int32 *)pSource;
239 0 : return true;
240 : case typelib_TypeClass_UNSIGNED_LONG:
241 0 : *(sal_Int64 *)pDest = *(sal_uInt32 *)pSource;
242 0 : return true;
243 : case typelib_TypeClass_HYPER:
244 : case typelib_TypeClass_UNSIGNED_HYPER:
245 1 : *(sal_Int64 *)pDest = *(sal_Int64 *)pSource;
246 1 : return true;
247 : default:
248 0 : return false;
249 : }
250 : case typelib_TypeClass_UNSIGNED_HYPER:
251 11 : switch (pSourceType->eTypeClass)
252 : {
253 : case typelib_TypeClass_BYTE:
254 0 : *(sal_uInt64 *)pDest = *(sal_Int8 *)pSource;
255 0 : return true;
256 : case typelib_TypeClass_SHORT:
257 0 : *(sal_uInt64 *)pDest = *(sal_Int16 *)pSource;
258 0 : return true;
259 : case typelib_TypeClass_UNSIGNED_SHORT:
260 0 : *(sal_uInt64 *)pDest = *(sal_uInt16 *)pSource;
261 0 : return true;
262 : case typelib_TypeClass_LONG:
263 0 : *(sal_uInt64 *)pDest = *(sal_Int32 *)pSource;
264 0 : return true;
265 : case typelib_TypeClass_UNSIGNED_LONG:
266 0 : *(sal_uInt64 *)pDest = *(sal_uInt32 *)pSource;
267 0 : return true;
268 : case typelib_TypeClass_HYPER:
269 : case typelib_TypeClass_UNSIGNED_HYPER:
270 11 : *(sal_uInt64 *)pDest = *(sal_uInt64 *)pSource;
271 11 : return true;
272 : default:
273 0 : return false;
274 : }
275 : case typelib_TypeClass_FLOAT:
276 105307 : switch (pSourceType->eTypeClass)
277 : {
278 : case typelib_TypeClass_BYTE:
279 0 : *(float *)pDest = *(sal_Int8 *)pSource;
280 0 : return true;
281 : case typelib_TypeClass_SHORT:
282 0 : *(float *)pDest = *(sal_Int16 *)pSource;
283 0 : return true;
284 : case typelib_TypeClass_UNSIGNED_SHORT:
285 0 : *(float *)pDest = *(sal_uInt16 *)pSource;
286 0 : return true;
287 : case typelib_TypeClass_FLOAT:
288 105307 : *(float *)pDest = *(float *)pSource;
289 105307 : return true;
290 : default:
291 0 : return false;
292 : }
293 : case typelib_TypeClass_DOUBLE:
294 229892 : switch (pSourceType->eTypeClass)
295 : {
296 : case typelib_TypeClass_BYTE:
297 0 : *(double *)pDest = *(sal_Int8 *)pSource;
298 0 : return true;
299 : case typelib_TypeClass_SHORT:
300 0 : *(double *)pDest = *(sal_Int16 *)pSource;
301 0 : return true;
302 : case typelib_TypeClass_UNSIGNED_SHORT:
303 0 : *(double *)pDest = *(sal_uInt16 *)pSource;
304 0 : return true;
305 : case typelib_TypeClass_LONG:
306 0 : *(double *)pDest = *(sal_Int32 *)pSource;
307 0 : return true;
308 : case typelib_TypeClass_UNSIGNED_LONG:
309 0 : *(double *)pDest = *(sal_uInt32 *)pSource;
310 0 : return true;
311 : case typelib_TypeClass_FLOAT:
312 0 : *(double *)pDest = *(float *)pSource;
313 0 : return true;
314 : case typelib_TypeClass_DOUBLE:
315 229892 : *(double *)pDest = *(double *)pSource;
316 229892 : return true;
317 : default:
318 0 : return false;
319 : }
320 : case typelib_TypeClass_STRING:
321 1037549 : switch (pSourceType->eTypeClass)
322 : {
323 : case typelib_TypeClass_STRING:
324 1035590 : ::rtl_uString_assign( (rtl_uString **)pDest, *(rtl_uString **)pSource );
325 1035590 : return true;
326 : default:
327 1959 : return false;
328 : }
329 : case typelib_TypeClass_TYPE:
330 308 : switch (pSourceType->eTypeClass)
331 : {
332 : case typelib_TypeClass_TYPE:
333 : {
334 307 : typelib_TypeDescriptionReference ** pp = (typelib_TypeDescriptionReference **)pDest;
335 307 : ::typelib_typedescriptionreference_release( *pp );
336 307 : *pp = *(typelib_TypeDescriptionReference **)pSource;
337 307 : TYPE_ACQUIRE( *pp );
338 307 : return true;
339 : }
340 : default:
341 1 : return false;
342 : }
343 : case typelib_TypeClass_ANY:
344 719160 : _destructAny( (uno_Any *)pDest, release );
345 719160 : _copyConstructAny( (uno_Any *)pDest, pSource, pSourceType, pSourceTypeDescr, acquire, 0 );
346 719160 : return true;
347 : case typelib_TypeClass_ENUM:
348 969183 : if (_type_equals( pDestType, pSourceType ))
349 : {
350 966461 : *(sal_Int32 *)pDest = *(sal_Int32 *)pSource;
351 966461 : return true;
352 : }
353 2722 : return false;
354 : case typelib_TypeClass_STRUCT:
355 : case typelib_TypeClass_EXCEPTION:
356 1689587 : if (typelib_TypeClass_STRUCT == pSourceType->eTypeClass ||
357 234097 : typelib_TypeClass_EXCEPTION == pSourceType->eTypeClass)
358 : {
359 1221718 : bool bRet = false;
360 1221718 : if (pSourceTypeDescr)
361 : {
362 : typelib_CompoundTypeDescription * pTypeDescr =
363 17 : (typelib_CompoundTypeDescription *)pSourceTypeDescr;
364 51 : while (pTypeDescr &&
365 : !_type_equals(
366 17 : ((typelib_TypeDescription *)pTypeDescr)->pWeakRef, pDestType ))
367 : {
368 0 : pTypeDescr = pTypeDescr->pBaseTypeDescription;
369 : }
370 17 : if (pTypeDescr)
371 : {
372 : bRet = _assignStruct(
373 17 : pDest, pSource, pTypeDescr, queryInterface, acquire, release );
374 : }
375 : }
376 : else
377 : {
378 1221701 : TYPELIB_DANGER_GET( &pSourceTypeDescr, pSourceType );
379 : typelib_CompoundTypeDescription * pTypeDescr =
380 1221701 : (typelib_CompoundTypeDescription *)pSourceTypeDescr;
381 3718258 : while (pTypeDescr &&
382 : !_type_equals(
383 1224227 : ((typelib_TypeDescription *)pTypeDescr)->pWeakRef, pDestType ))
384 : {
385 50629 : pTypeDescr = pTypeDescr->pBaseTypeDescription;
386 : }
387 1221701 : if (pTypeDescr)
388 : {
389 : bRet = _assignStruct(
390 1173598 : pDest, pSource, pTypeDescr, queryInterface, acquire, release );
391 : }
392 1221701 : TYPELIB_DANGER_RELEASE( pSourceTypeDescr );
393 : }
394 1221718 : return bRet;
395 : }
396 233772 : return false;
397 : case typelib_TypeClass_SEQUENCE:
398 1789899 : if (typelib_TypeClass_SEQUENCE != pSourceType->eTypeClass)
399 87197 : return false;
400 : // self assignment:
401 1702702 : if (*(uno_Sequence **)pSource == *(uno_Sequence **)pDest)
402 139870 : return true;
403 1562832 : if (_type_equals( pDestType, pSourceType ))
404 : {
405 1539513 : osl_atomic_increment( &(*(uno_Sequence **)pSource)->nRefCount );
406 : idestructSequence(
407 1539513 : *(uno_Sequence **)pDest, pDestType, pDestTypeDescr, release );
408 1539513 : *(uno_Sequence **)pDest = *(uno_Sequence **)pSource;
409 1539513 : return true;
410 : }
411 23319 : return false;
412 : case typelib_TypeClass_INTERFACE:
413 1801532 : if (typelib_TypeClass_INTERFACE != pSourceType->eTypeClass)
414 37070 : return false;
415 1764462 : if (_type_equals( pDestType, pSourceType ))
416 : {
417 717730 : _assignInterface( (void **)pDest, *(void **)pSource, acquire, release );
418 717730 : return true;
419 : }
420 1046732 : else if (*static_cast< void ** >(pSource) == 0)
421 : {
422 : // A null reference of any interface type can be converted to a null
423 : // reference of any other interface type:
424 180390 : void * const pToBeReleased = *static_cast< void ** >(pDest);
425 180390 : *static_cast< void ** >(pDest) = 0;
426 180390 : _release( pToBeReleased, release );
427 180390 : return true;
428 : }
429 : else
430 : {
431 866342 : if (pSourceTypeDescr)
432 : {
433 0 : typelib_TypeDescription * pTD = pSourceTypeDescr;
434 0 : while (pTD && !_type_equals( pTD->pWeakRef, pDestType ))
435 : {
436 : pTD = (typelib_TypeDescription *)
437 0 : ((typelib_InterfaceTypeDescription *)pTD)->pBaseTypeDescription;
438 : }
439 0 : if (pTD) // is base of dest
440 : {
441 0 : _assignInterface( (void **)pDest, *(void **)pSource, acquire, release );
442 0 : return true;
443 : }
444 : }
445 :
446 : // query for interface:
447 : void * pQueried = _queryInterface( *static_cast<void **>(pSource),
448 866342 : pDestType, queryInterface );
449 866342 : if (pQueried != 0) {
450 823191 : void * const pToBeReleased = *static_cast<void **>(pDest);
451 823191 : *static_cast<void **>(pDest) = pQueried;
452 823191 : _release( pToBeReleased, release );
453 : }
454 866342 : return (pQueried != 0);
455 : }
456 : default:
457 : OSL_ASSERT(false);
458 0 : return false;
459 : }
460 : }
461 :
462 : }
463 :
464 : #endif
465 :
466 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|