merged tag ooo/DEV300_m102
[LibreOffice.git] / cppu / source / uno / assign.hxx
blob256bb31565dbc8dbd3883e0969e7d86e6d11fda3
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
27 #ifndef ASSIGN_HXX
28 #define ASSIGN_HXX
30 #include "prim.hxx"
31 #include "destr.hxx"
32 #include "constr.hxx"
33 #include "copy.hxx"
36 namespace cppu
39 //##################################################################################################
40 //#### assignment ##################################################################################
41 //##################################################################################################
44 //--------------------------------------------------------------------------------------------------
45 inline void _assignInterface(
46 void ** ppDest, void * pSource,
47 uno_AcquireFunc acquire, uno_ReleaseFunc release )
48 SAL_THROW( () )
50 _acquire( pSource, acquire );
51 void * const pToBeReleased = *ppDest;
52 *ppDest = pSource;
53 _release( pToBeReleased, release );
55 //--------------------------------------------------------------------------------------------------
56 inline void * _queryInterface(
57 void * pSource,
58 typelib_TypeDescriptionReference * pDestType,
59 uno_QueryInterfaceFunc queryInterface )
60 SAL_THROW( () )
62 if (pSource)
64 if (0 == queryInterface)
65 queryInterface = binuno_queryInterface;
66 pSource = (*queryInterface)( pSource, pDestType );
68 return pSource;
70 //==================================================================================================
71 sal_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 inline sal_Bool _assignStruct(
78 void * pDest, void * pSource,
79 typelib_CompoundTypeDescription * pTypeDescr,
80 uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release )
81 SAL_THROW( () )
83 if (pTypeDescr->pBaseTypeDescription)
85 // copy base value
86 if (! assignStruct( pDest, pSource, pTypeDescr->pBaseTypeDescription,
87 queryInterface, acquire, release ))
89 return sal_False;
92 // then copy members
93 typelib_TypeDescriptionReference ** ppTypeRefs = pTypeDescr->ppTypeRefs;
94 sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets;
95 sal_Int32 nDescr = pTypeDescr->nMembers;
96 while (nDescr--)
98 if (! ::uno_type_assignData( (char *)pDest + pMemberOffsets[nDescr],
99 ppTypeRefs[nDescr],
100 (char *)pSource + pMemberOffsets[nDescr],
101 ppTypeRefs[nDescr],
102 queryInterface, acquire, release ))
104 return sal_False;
107 return sal_True;
109 //--------------------------------------------------------------------------------------------------
110 inline sal_Bool _assignArray(
111 void * pDest, void * pSource,
112 typelib_ArrayTypeDescription * pTypeDescr,
113 uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release )
115 typelib_TypeDescriptionReference * pElementTypeRef =
116 ((typelib_IndirectTypeDescription *)pTypeDescr)->pType;
117 typelib_TypeDescription * pElementTypeDescr = NULL;
118 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementTypeRef );
119 sal_Int32 nTotalElements = pTypeDescr->nTotalElements;
120 sal_Int32 nElementSize = pElementTypeDescr->nSize;
121 sal_Int32 i;
122 sal_Bool bRet = sal_False;
124 switch ( pElementTypeRef->eTypeClass )
126 case typelib_TypeClass_CHAR:
127 case typelib_TypeClass_BOOLEAN:
128 case typelib_TypeClass_BYTE:
129 case typelib_TypeClass_SHORT:
130 case typelib_TypeClass_UNSIGNED_SHORT:
131 case typelib_TypeClass_LONG:
132 case typelib_TypeClass_UNSIGNED_LONG:
133 case typelib_TypeClass_HYPER:
134 case typelib_TypeClass_UNSIGNED_HYPER:
135 case typelib_TypeClass_FLOAT:
136 case typelib_TypeClass_DOUBLE:
137 for (i=0; i < nTotalElements; i++)
139 ::rtl_copyMemory((sal_Char *)pDest + i * nElementSize,
140 (sal_Char *)pSource + i * nElementSize,
141 nElementSize);
143 bRet = sal_True;
144 break;
145 case typelib_TypeClass_STRING:
146 for (i=0; i < nTotalElements; i++)
148 ::rtl_uString_assign( (rtl_uString **)pDest + i,
149 ((rtl_uString **)pSource)[i] );
151 bRet = sal_True;
152 break;
153 case typelib_TypeClass_TYPE:
154 for (i=0; i < nTotalElements; i++)
156 typelib_TypeDescriptionReference ** pp = (typelib_TypeDescriptionReference **)pDest + i;
157 ::typelib_typedescriptionreference_release( *pp );
158 *pp = *((typelib_TypeDescriptionReference **)pSource + i);
159 TYPE_ACQUIRE( *pp );
161 bRet = sal_True;
162 break;
163 case typelib_TypeClass_ANY:
164 for (i=0; i < nTotalElements; i++)
166 _destructAny( (uno_Any *)pDest + i, release );
167 _copyConstructAny( (uno_Any *)pDest + i, (uno_Any *)pSource + i,
168 pElementTypeRef, pElementTypeDescr, acquire, 0 );
170 bRet = sal_True;
171 break;
172 case typelib_TypeClass_ENUM:
173 for (i=0; i < nTotalElements; i++)
175 *((sal_Int32 *)pDest + i) = *((sal_Int32 *)pSource + i);
177 bRet = sal_True;
178 break;
179 case typelib_TypeClass_STRUCT:
180 case typelib_TypeClass_EXCEPTION:
181 for (i=0; i < nTotalElements; i++)
183 bRet = _assignStruct( (sal_Char *)pDest + i * nElementSize,
184 (sal_Char *)pSource + i * nElementSize,
185 (typelib_CompoundTypeDescription *)pElementTypeDescr,
186 queryInterface, acquire, release );
187 if (! bRet)
188 break;
190 bRet = sal_True;
191 break;
192 case typelib_TypeClass_UNION:
193 for (i=0; i < nTotalElements; i++)
195 _destructUnion( (sal_Char*)pDest + i * nElementSize, pElementTypeDescr, release );
196 _copyConstructUnion( (sal_Char*)pDest + i * nElementSize,
197 (sal_Char*)pSource + i * nElementSize,
198 pElementTypeDescr, acquire, 0 );
200 bRet = sal_True;
201 break;
202 case typelib_TypeClass_SEQUENCE:
203 for (i=0; i < nTotalElements; i++)
205 ::osl_incrementInterlockedCount(
206 &(*((uno_Sequence **)pSource + i))->nRefCount );
207 idestructSequence(
208 *((uno_Sequence **)pDest + i),
209 pElementTypeRef, pElementTypeDescr, release );
210 *((uno_Sequence **)pDest + i) = *((uno_Sequence **)pSource + i);
212 bRet = sal_True;
213 break;
214 case typelib_TypeClass_INTERFACE:
215 for (i=0; i < nTotalElements; i++)
217 _assignInterface(
218 (void **)((sal_Char*)pDest + i * nElementSize),
219 *(void **)((sal_Char*)pSource + i * nElementSize),
220 acquire, release );
222 bRet = sal_True;
223 break;
224 default:
225 OSL_ASSERT(false);
226 break;
229 TYPELIB_DANGER_RELEASE( pElementTypeDescr );
230 return bRet;
232 //--------------------------------------------------------------------------------------------------
233 inline sal_Bool _assignData(
234 void * pDest,
235 typelib_TypeDescriptionReference * pDestType, typelib_TypeDescription * pDestTypeDescr,
236 void * pSource,
237 typelib_TypeDescriptionReference * pSourceType, typelib_TypeDescription * pSourceTypeDescr,
238 uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release )
239 SAL_THROW( () )
241 if (pDest == pSource)
242 return _type_equals( pDestType, pSourceType );
244 if (! pSource)
246 _destructData( pDest, pDestType, pDestTypeDescr, release );
247 _defaultConstructData( pDest, pDestType, pDestTypeDescr );
248 return sal_True;
250 while (typelib_TypeClass_ANY == pSourceType->eTypeClass)
252 pSourceTypeDescr = 0;
253 pSourceType = ((uno_Any *)pSource)->pType;
254 pSource = ((uno_Any *)pSource)->pData;
255 if (pDest == pSource)
256 return sal_True;
259 switch (pDestType->eTypeClass)
261 case typelib_TypeClass_VOID:
262 return pSourceType->eTypeClass == typelib_TypeClass_VOID;
263 case typelib_TypeClass_CHAR:
264 switch (pSourceType->eTypeClass)
266 case typelib_TypeClass_CHAR:
267 *(sal_Unicode *)pDest = *(sal_Unicode *)pSource;
268 return sal_True;
269 default:
270 return sal_False;
272 case typelib_TypeClass_BOOLEAN:
273 switch (pSourceType->eTypeClass)
275 case typelib_TypeClass_BOOLEAN:
276 *(sal_Bool *)pDest = (*(sal_Bool *)pSource != sal_False);
277 return sal_True;
278 default:
279 return sal_False;
281 case typelib_TypeClass_BYTE:
282 switch (pSourceType->eTypeClass)
284 case typelib_TypeClass_BYTE:
285 *(sal_Int8 *)pDest = *(sal_Int8 *)pSource;
286 return sal_True;
287 default:
288 return sal_False;
290 case typelib_TypeClass_SHORT:
291 switch (pSourceType->eTypeClass)
293 case typelib_TypeClass_BYTE:
294 *(sal_Int16 *)pDest = *(sal_Int8 *)pSource;
295 return sal_True;
296 case typelib_TypeClass_SHORT:
297 case typelib_TypeClass_UNSIGNED_SHORT:
298 *(sal_Int16 *)pDest = *(sal_Int16 *)pSource;
299 return sal_True;
300 default:
301 return sal_False;
303 case typelib_TypeClass_UNSIGNED_SHORT:
304 switch (pSourceType->eTypeClass)
306 case typelib_TypeClass_BYTE:
307 *(sal_uInt16 *)pDest = *(sal_Int8 *)pSource;
308 return sal_True;
309 case typelib_TypeClass_SHORT:
310 case typelib_TypeClass_UNSIGNED_SHORT:
311 *(sal_uInt16 *)pDest = *(sal_uInt16 *)pSource;
312 return sal_True;
313 default:
314 return sal_False;
316 case typelib_TypeClass_LONG:
317 switch (pSourceType->eTypeClass)
319 case typelib_TypeClass_BYTE:
320 *(sal_Int32 *)pDest = *(sal_Int8 *)pSource;
321 return sal_True;
322 case typelib_TypeClass_SHORT:
323 *(sal_Int32 *)pDest = *(sal_Int16 *)pSource;
324 return sal_True;
325 case typelib_TypeClass_UNSIGNED_SHORT:
326 *(sal_Int32 *)pDest = *(sal_uInt16 *)pSource;
327 return sal_True;
328 case typelib_TypeClass_LONG:
329 case typelib_TypeClass_UNSIGNED_LONG:
330 *(sal_Int32 *)pDest = *(sal_Int32 *)pSource;
331 return sal_True;
332 default:
333 return sal_False;
335 case typelib_TypeClass_UNSIGNED_LONG:
336 switch (pSourceType->eTypeClass)
338 case typelib_TypeClass_BYTE:
339 *(sal_uInt32 *)pDest = *(sal_Int8 *)pSource;
340 return sal_True;
341 case typelib_TypeClass_SHORT:
342 *(sal_uInt32 *)pDest = *(sal_Int16 *)pSource;
343 return sal_True;
344 case typelib_TypeClass_UNSIGNED_SHORT:
345 *(sal_uInt32 *)pDest = *(sal_uInt16 *)pSource;
346 return sal_True;
347 case typelib_TypeClass_LONG:
348 case typelib_TypeClass_UNSIGNED_LONG:
349 *(sal_uInt32 *)pDest = *(sal_uInt32 *)pSource;
350 return sal_True;
351 default:
352 return sal_False;
354 case typelib_TypeClass_HYPER:
355 switch (pSourceType->eTypeClass)
357 case typelib_TypeClass_BYTE:
358 *(sal_Int64 *)pDest = *(sal_Int8 *)pSource;
359 return sal_True;
360 case typelib_TypeClass_SHORT:
361 *(sal_Int64 *)pDest = *(sal_Int16 *)pSource;
362 return sal_True;
363 case typelib_TypeClass_UNSIGNED_SHORT:
364 *(sal_Int64 *)pDest = *(sal_uInt16 *)pSource;
365 return sal_True;
366 case typelib_TypeClass_LONG:
367 *(sal_Int64 *)pDest = *(sal_Int32 *)pSource;
368 return sal_True;
369 case typelib_TypeClass_UNSIGNED_LONG:
370 *(sal_Int64 *)pDest = *(sal_uInt32 *)pSource;
371 return sal_True;
372 case typelib_TypeClass_HYPER:
373 case typelib_TypeClass_UNSIGNED_HYPER:
374 *(sal_Int64 *)pDest = *(sal_Int64 *)pSource;
375 return sal_True;
376 default:
377 return sal_False;
379 case typelib_TypeClass_UNSIGNED_HYPER:
380 switch (pSourceType->eTypeClass)
382 case typelib_TypeClass_BYTE:
383 *(sal_uInt64 *)pDest = *(sal_Int8 *)pSource;
384 return sal_True;
385 case typelib_TypeClass_SHORT:
386 *(sal_uInt64 *)pDest = *(sal_Int16 *)pSource;
387 return sal_True;
388 case typelib_TypeClass_UNSIGNED_SHORT:
389 *(sal_uInt64 *)pDest = *(sal_uInt16 *)pSource;
390 return sal_True;
391 case typelib_TypeClass_LONG:
392 *(sal_uInt64 *)pDest = *(sal_Int32 *)pSource;
393 return sal_True;
394 case typelib_TypeClass_UNSIGNED_LONG:
395 *(sal_uInt64 *)pDest = *(sal_uInt32 *)pSource;
396 return sal_True;
397 case typelib_TypeClass_HYPER:
398 case typelib_TypeClass_UNSIGNED_HYPER:
399 *(sal_uInt64 *)pDest = *(sal_uInt64 *)pSource;
400 return sal_True;
401 default:
402 return sal_False;
404 case typelib_TypeClass_FLOAT:
405 switch (pSourceType->eTypeClass)
407 case typelib_TypeClass_BYTE:
408 *(float *)pDest = *(sal_Int8 *)pSource;
409 return sal_True;
410 case typelib_TypeClass_SHORT:
411 *(float *)pDest = *(sal_Int16 *)pSource;
412 return sal_True;
413 case typelib_TypeClass_UNSIGNED_SHORT:
414 *(float *)pDest = *(sal_uInt16 *)pSource;
415 return sal_True;
416 case typelib_TypeClass_FLOAT:
417 *(float *)pDest = *(float *)pSource;
418 return sal_True;
419 default:
420 return sal_False;
422 case typelib_TypeClass_DOUBLE:
423 switch (pSourceType->eTypeClass)
425 case typelib_TypeClass_BYTE:
426 *(double *)pDest = *(sal_Int8 *)pSource;
427 return sal_True;
428 case typelib_TypeClass_SHORT:
429 *(double *)pDest = *(sal_Int16 *)pSource;
430 return sal_True;
431 case typelib_TypeClass_UNSIGNED_SHORT:
432 *(double *)pDest = *(sal_uInt16 *)pSource;
433 return sal_True;
434 case typelib_TypeClass_LONG:
435 *(double *)pDest = *(sal_Int32 *)pSource;
436 return sal_True;
437 case typelib_TypeClass_UNSIGNED_LONG:
438 *(double *)pDest = *(sal_uInt32 *)pSource;
439 return sal_True;
440 case typelib_TypeClass_FLOAT:
441 *(double *)pDest = *(float *)pSource;
442 return sal_True;
443 case typelib_TypeClass_DOUBLE:
444 *(double *)pDest = *(double *)pSource;
445 return sal_True;
446 default:
447 return sal_False;
449 case typelib_TypeClass_STRING:
450 switch (pSourceType->eTypeClass)
452 case typelib_TypeClass_STRING:
453 ::rtl_uString_assign( (rtl_uString **)pDest, *(rtl_uString **)pSource );
454 return sal_True;
455 default:
456 return sal_False;
458 case typelib_TypeClass_TYPE:
459 switch (pSourceType->eTypeClass)
461 case typelib_TypeClass_TYPE:
463 typelib_TypeDescriptionReference ** pp = (typelib_TypeDescriptionReference **)pDest;
464 ::typelib_typedescriptionreference_release( *pp );
465 *pp = *(typelib_TypeDescriptionReference **)pSource;
466 TYPE_ACQUIRE( *pp );
467 return sal_True;
469 default:
470 return sal_False;
472 case typelib_TypeClass_ANY:
473 _destructAny( (uno_Any *)pDest, release );
474 _copyConstructAny( (uno_Any *)pDest, pSource, pSourceType, pSourceTypeDescr, acquire, 0 );
475 return sal_True;
476 case typelib_TypeClass_ENUM:
477 if (_type_equals( pDestType, pSourceType ))
479 *(sal_Int32 *)pDest = *(sal_Int32 *)pSource;
480 return sal_True;
482 return sal_False;
483 case typelib_TypeClass_STRUCT:
484 case typelib_TypeClass_EXCEPTION:
485 if (typelib_TypeClass_STRUCT == pSourceType->eTypeClass ||
486 typelib_TypeClass_EXCEPTION == pSourceType->eTypeClass)
488 sal_Bool bRet = sal_False;
489 if (pSourceTypeDescr)
491 typelib_CompoundTypeDescription * pTypeDescr =
492 (typelib_CompoundTypeDescription *)pSourceTypeDescr;
493 while (pTypeDescr &&
494 !_type_equals(
495 ((typelib_TypeDescription *)pTypeDescr)->pWeakRef, pDestType ))
497 pTypeDescr = pTypeDescr->pBaseTypeDescription;
499 if (pTypeDescr)
501 bRet = _assignStruct(
502 pDest, pSource, pTypeDescr, queryInterface, acquire, release );
505 else
507 TYPELIB_DANGER_GET( &pSourceTypeDescr, pSourceType );
508 typelib_CompoundTypeDescription * pTypeDescr =
509 (typelib_CompoundTypeDescription *)pSourceTypeDescr;
510 while (pTypeDescr &&
511 !_type_equals(
512 ((typelib_TypeDescription *)pTypeDescr)->pWeakRef, pDestType ))
514 pTypeDescr = pTypeDescr->pBaseTypeDescription;
516 if (pTypeDescr)
518 bRet = _assignStruct(
519 pDest, pSource, pTypeDescr, queryInterface, acquire, release );
521 TYPELIB_DANGER_RELEASE( pSourceTypeDescr );
523 return bRet;
525 return sal_False;
526 case typelib_TypeClass_ARRAY:
528 sal_Bool bRet = sal_False;
529 if (pSourceTypeDescr)
531 typelib_ArrayTypeDescription * pTypeDescr =
532 (typelib_ArrayTypeDescription *)pSourceTypeDescr;
533 bRet = _assignArray( pDest, pSource, pTypeDescr, queryInterface, acquire, release );
535 else
537 TYPELIB_DANGER_GET( &pSourceTypeDescr, pSourceType );
538 typelib_ArrayTypeDescription * pTypeDescr =
539 (typelib_ArrayTypeDescription *)pSourceTypeDescr;
540 if ( pTypeDescr )
542 bRet = _assignArray(
543 pDest, pSource, pTypeDescr, queryInterface, acquire, release );
545 TYPELIB_DANGER_RELEASE( pSourceTypeDescr );
547 return bRet;
549 case typelib_TypeClass_UNION:
550 if (_type_equals( pDestType, pSourceType ))
552 if (pDestTypeDescr)
554 _destructUnion( pDest, pDestTypeDescr, release );
555 _copyConstructUnion( pDest, pSource, pDestTypeDescr, acquire, 0 );
557 else
559 TYPELIB_DANGER_GET( &pDestTypeDescr, pDestType );
560 _destructUnion( pDest, pDestTypeDescr, release );
561 _copyConstructUnion( pDest, pSource, pDestTypeDescr, acquire, 0 );
562 TYPELIB_DANGER_RELEASE( pDestTypeDescr );
564 return sal_True;
566 return sal_False;
567 case typelib_TypeClass_SEQUENCE:
568 if (typelib_TypeClass_SEQUENCE != pSourceType->eTypeClass)
569 return sal_False;
570 // self assignment:
571 if (*(uno_Sequence **)pSource == *(uno_Sequence **)pDest)
572 return sal_True;
573 if (_type_equals( pDestType, pSourceType ))
575 ::osl_incrementInterlockedCount(
576 &(*(uno_Sequence **)pSource)->nRefCount );
577 idestructSequence(
578 *(uno_Sequence **)pDest, pDestType, pDestTypeDescr, release );
579 *(uno_Sequence **)pDest = *(uno_Sequence **)pSource;
580 return sal_True;
582 return sal_False;
583 case typelib_TypeClass_INTERFACE:
584 if (typelib_TypeClass_INTERFACE != pSourceType->eTypeClass)
585 return sal_False;
586 if (_type_equals( pDestType, pSourceType ))
588 _assignInterface( (void **)pDest, *(void **)pSource, acquire, release );
589 return sal_True;
591 else if (*static_cast< void ** >(pSource) == 0)
593 // A null reference of any interface type can be converted to a null
594 // reference of any other interface type:
595 void * const pToBeReleased = *static_cast< void ** >(pDest);
596 *static_cast< void ** >(pDest) = 0;
597 _release( pToBeReleased, release );
598 return true;
600 else
602 if (pSourceTypeDescr)
604 typelib_TypeDescription * pTD = pSourceTypeDescr;
605 while (pTD && !_type_equals( pTD->pWeakRef, pDestType ))
607 pTD = (typelib_TypeDescription *)
608 ((typelib_InterfaceTypeDescription *)pTD)->pBaseTypeDescription;
610 if (pTD) // is base of dest
612 _assignInterface( (void **)pDest, *(void **)pSource, acquire, release );
613 return true;
617 // query for interface:
618 void * pQueried = _queryInterface( *static_cast<void **>(pSource),
619 pDestType, queryInterface );
620 if (pQueried != 0) {
621 void * const pToBeReleased = *static_cast<void **>(pDest);
622 *static_cast<void **>(pDest) = pQueried;
623 _release( pToBeReleased, release );
625 return (pQueried != 0);
627 default:
628 OSL_ASSERT(false);
629 return sal_False;
635 #endif