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 5 : inline void _assignInterface(
40 : void ** ppDest, void * pSource,
41 : uno_AcquireFunc acquire, uno_ReleaseFunc release )
42 : SAL_THROW(())
43 : {
44 5 : _acquire( pSource, acquire );
45 5 : void * const pToBeReleased = *ppDest;
46 5 : *ppDest = pSource;
47 5 : _release( pToBeReleased, release );
48 5 : }
49 :
50 25 : inline void * _queryInterface(
51 : void * pSource,
52 : typelib_TypeDescriptionReference * pDestType,
53 : uno_QueryInterfaceFunc queryInterface )
54 : SAL_THROW(())
55 : {
56 25 : if (pSource)
57 : {
58 25 : if (0 == queryInterface)
59 0 : queryInterface = binuno_queryInterface;
60 25 : pSource = (*queryInterface)( pSource, pDestType );
61 : }
62 25 : 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 3 : 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 3 : if (pTypeDescr->pBaseTypeDescription)
78 : {
79 : // copy base value
80 0 : if (! assignStruct( pDest, pSource, pTypeDescr->pBaseTypeDescription,
81 0 : queryInterface, acquire, release ))
82 : {
83 0 : return false;
84 : }
85 : }
86 : // then copy members
87 3 : typelib_TypeDescriptionReference ** ppTypeRefs = pTypeDescr->ppTypeRefs;
88 3 : sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets;
89 3 : sal_Int32 nDescr = pTypeDescr->nMembers;
90 12 : while (nDescr--)
91 : {
92 18 : if (! ::uno_type_assignData( (char *)pDest + pMemberOffsets[nDescr],
93 6 : ppTypeRefs[nDescr],
94 12 : (char *)pSource + pMemberOffsets[nDescr],
95 6 : ppTypeRefs[nDescr],
96 30 : queryInterface, acquire, release ))
97 : {
98 0 : return false;
99 : }
100 : }
101 3 : return true;
102 : }
103 :
104 41 : 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 41 : if (pDest == pSource)
113 0 : return _type_equals( pDestType, pSourceType );
114 :
115 41 : if (! pSource)
116 : {
117 0 : _destructData( pDest, pDestType, pDestTypeDescr, release );
118 0 : _defaultConstructData( pDest, pDestType, pDestTypeDescr );
119 0 : return true;
120 : }
121 85 : while (typelib_TypeClass_ANY == pSourceType->eTypeClass)
122 : {
123 3 : pSourceTypeDescr = 0;
124 3 : pSourceType = ((uno_Any *)pSource)->pType;
125 3 : pSource = ((uno_Any *)pSource)->pData;
126 3 : if (pDest == pSource)
127 0 : return true;
128 : }
129 :
130 41 : switch (pDestType->eTypeClass)
131 : {
132 : case typelib_TypeClass_VOID:
133 0 : return pSourceType->eTypeClass == typelib_TypeClass_VOID;
134 : case typelib_TypeClass_CHAR:
135 0 : switch (pSourceType->eTypeClass)
136 : {
137 : case typelib_TypeClass_CHAR:
138 0 : *(sal_Unicode *)pDest = *(sal_Unicode *)pSource;
139 0 : return true;
140 : default:
141 0 : return false;
142 : }
143 : case typelib_TypeClass_BOOLEAN:
144 3 : switch (pSourceType->eTypeClass)
145 : {
146 : case typelib_TypeClass_BOOLEAN:
147 3 : *(sal_Bool *)pDest = (*(sal_Bool *)pSource != sal_False);
148 3 : return true;
149 : default:
150 0 : return false;
151 : }
152 : case typelib_TypeClass_BYTE:
153 0 : switch (pSourceType->eTypeClass)
154 : {
155 : case typelib_TypeClass_BYTE:
156 0 : *(sal_Int8 *)pDest = *(sal_Int8 *)pSource;
157 0 : return true;
158 : default:
159 0 : return false;
160 : }
161 : case typelib_TypeClass_SHORT:
162 0 : switch (pSourceType->eTypeClass)
163 : {
164 : case typelib_TypeClass_BYTE:
165 0 : *(sal_Int16 *)pDest = *(sal_Int8 *)pSource;
166 0 : return true;
167 : case typelib_TypeClass_SHORT:
168 : case typelib_TypeClass_UNSIGNED_SHORT:
169 0 : *(sal_Int16 *)pDest = *(sal_Int16 *)pSource;
170 0 : return true;
171 : default:
172 0 : return false;
173 : }
174 : case typelib_TypeClass_UNSIGNED_SHORT:
175 0 : 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 0 : *(sal_uInt16 *)pDest = *(sal_uInt16 *)pSource;
183 0 : return true;
184 : default:
185 0 : return false;
186 : }
187 : case typelib_TypeClass_LONG:
188 0 : switch (pSourceType->eTypeClass)
189 : {
190 : case typelib_TypeClass_BYTE:
191 0 : *(sal_Int32 *)pDest = *(sal_Int8 *)pSource;
192 0 : return true;
193 : case typelib_TypeClass_SHORT:
194 0 : *(sal_Int32 *)pDest = *(sal_Int16 *)pSource;
195 0 : 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 0 : *(sal_Int32 *)pDest = *(sal_Int32 *)pSource;
202 0 : return true;
203 : default:
204 0 : return false;
205 : }
206 : case typelib_TypeClass_UNSIGNED_LONG:
207 0 : switch (pSourceType->eTypeClass)
208 : {
209 : case typelib_TypeClass_BYTE:
210 0 : *(sal_uInt32 *)pDest = *(sal_Int8 *)pSource;
211 0 : 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 0 : *(sal_uInt32 *)pDest = *(sal_uInt32 *)pSource;
221 0 : return true;
222 : default:
223 0 : return false;
224 : }
225 : case typelib_TypeClass_HYPER:
226 0 : 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 0 : *(sal_Int64 *)pDest = *(sal_Int64 *)pSource;
246 0 : return true;
247 : default:
248 0 : return false;
249 : }
250 : case typelib_TypeClass_UNSIGNED_HYPER:
251 0 : 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 0 : *(sal_uInt64 *)pDest = *(sal_uInt64 *)pSource;
271 0 : return true;
272 : default:
273 0 : return false;
274 : }
275 : case typelib_TypeClass_FLOAT:
276 0 : 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 0 : *(float *)pDest = *(float *)pSource;
289 0 : return true;
290 : default:
291 0 : return false;
292 : }
293 : case typelib_TypeClass_DOUBLE:
294 0 : 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 0 : *(double *)pDest = *(double *)pSource;
316 0 : return true;
317 : default:
318 0 : return false;
319 : }
320 : case typelib_TypeClass_STRING:
321 0 : switch (pSourceType->eTypeClass)
322 : {
323 : case typelib_TypeClass_STRING:
324 0 : ::rtl_uString_assign( (rtl_uString **)pDest, *(rtl_uString **)pSource );
325 0 : return true;
326 : default:
327 0 : return false;
328 : }
329 : case typelib_TypeClass_TYPE:
330 0 : switch (pSourceType->eTypeClass)
331 : {
332 : case typelib_TypeClass_TYPE:
333 : {
334 0 : typelib_TypeDescriptionReference ** pp = (typelib_TypeDescriptionReference **)pDest;
335 0 : ::typelib_typedescriptionreference_release( *pp );
336 0 : *pp = *(typelib_TypeDescriptionReference **)pSource;
337 0 : TYPE_ACQUIRE( *pp );
338 0 : return true;
339 : }
340 : default:
341 0 : return false;
342 : }
343 : case typelib_TypeClass_ANY:
344 3 : _destructAny( (uno_Any *)pDest, release );
345 3 : _copyConstructAny( (uno_Any *)pDest, pSource, pSourceType, pSourceTypeDescr, acquire, 0 );
346 3 : return true;
347 : case typelib_TypeClass_ENUM:
348 0 : if (_type_equals( pDestType, pSourceType ))
349 : {
350 0 : *(sal_Int32 *)pDest = *(sal_Int32 *)pSource;
351 0 : return true;
352 : }
353 0 : return false;
354 : case typelib_TypeClass_STRUCT:
355 : case typelib_TypeClass_EXCEPTION:
356 3 : if (typelib_TypeClass_STRUCT == pSourceType->eTypeClass ||
357 0 : typelib_TypeClass_EXCEPTION == pSourceType->eTypeClass)
358 : {
359 3 : bool bRet = false;
360 3 : if (pSourceTypeDescr)
361 : {
362 : typelib_CompoundTypeDescription * pTypeDescr =
363 0 : (typelib_CompoundTypeDescription *)pSourceTypeDescr;
364 0 : while (pTypeDescr &&
365 : !_type_equals(
366 0 : ((typelib_TypeDescription *)pTypeDescr)->pWeakRef, pDestType ))
367 : {
368 0 : pTypeDescr = pTypeDescr->pBaseTypeDescription;
369 : }
370 0 : if (pTypeDescr)
371 : {
372 : bRet = _assignStruct(
373 0 : pDest, pSource, pTypeDescr, queryInterface, acquire, release );
374 : }
375 : }
376 : else
377 : {
378 3 : TYPELIB_DANGER_GET( &pSourceTypeDescr, pSourceType );
379 : typelib_CompoundTypeDescription * pTypeDescr =
380 3 : (typelib_CompoundTypeDescription *)pSourceTypeDescr;
381 9 : while (pTypeDescr &&
382 : !_type_equals(
383 3 : ((typelib_TypeDescription *)pTypeDescr)->pWeakRef, pDestType ))
384 : {
385 0 : pTypeDescr = pTypeDescr->pBaseTypeDescription;
386 : }
387 3 : if (pTypeDescr)
388 : {
389 : bRet = _assignStruct(
390 3 : pDest, pSource, pTypeDescr, queryInterface, acquire, release );
391 : }
392 3 : TYPELIB_DANGER_RELEASE( pSourceTypeDescr );
393 : }
394 3 : return bRet;
395 : }
396 0 : return false;
397 : case typelib_TypeClass_SEQUENCE:
398 0 : if (typelib_TypeClass_SEQUENCE != pSourceType->eTypeClass)
399 0 : return false;
400 : // self assignment:
401 0 : if (*(uno_Sequence **)pSource == *(uno_Sequence **)pDest)
402 0 : return true;
403 0 : if (_type_equals( pDestType, pSourceType ))
404 : {
405 0 : osl_atomic_increment( &(*(uno_Sequence **)pSource)->nRefCount );
406 : idestructSequence(
407 0 : *(uno_Sequence **)pDest, pDestType, pDestTypeDescr, release );
408 0 : *(uno_Sequence **)pDest = *(uno_Sequence **)pSource;
409 0 : return true;
410 : }
411 0 : return false;
412 : case typelib_TypeClass_INTERFACE:
413 32 : if (typelib_TypeClass_INTERFACE != pSourceType->eTypeClass)
414 2 : return false;
415 30 : if (_type_equals( pDestType, pSourceType ))
416 : {
417 5 : _assignInterface( (void **)pDest, *(void **)pSource, acquire, release );
418 5 : return true;
419 : }
420 25 : 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 0 : void * const pToBeReleased = *static_cast< void ** >(pDest);
425 0 : *static_cast< void ** >(pDest) = 0;
426 0 : _release( pToBeReleased, release );
427 0 : return true;
428 : }
429 : else
430 : {
431 25 : 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 25 : pDestType, queryInterface );
449 25 : if (pQueried != 0) {
450 8 : void * const pToBeReleased = *static_cast<void **>(pDest);
451 8 : *static_cast<void **>(pDest) = pQueried;
452 8 : _release( pToBeReleased, release );
453 : }
454 25 : 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: */
|