1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: assign.hxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
42 //##################################################################################################
43 //#### assignment ##################################################################################
44 //##################################################################################################
47 //--------------------------------------------------------------------------------------------------
48 inline void _assignInterface(
49 void ** ppDest
, void * pSource
,
50 uno_AcquireFunc acquire
, uno_ReleaseFunc release
)
53 _acquire( pSource
, acquire
);
54 void * const pToBeReleased
= *ppDest
;
56 _release( pToBeReleased
, release
);
58 //--------------------------------------------------------------------------------------------------
59 inline void * _queryInterface(
61 typelib_TypeDescriptionReference
* pDestType
,
62 uno_QueryInterfaceFunc queryInterface
)
67 if (0 == queryInterface
)
68 queryInterface
= binuno_queryInterface
;
69 pSource
= (*queryInterface
)( pSource
, pDestType
);
73 //==================================================================================================
74 sal_Bool
assignStruct(
75 void * pDest
, void * pSource
,
76 typelib_CompoundTypeDescription
* pTypeDescr
,
77 uno_QueryInterfaceFunc queryInterface
, uno_AcquireFunc acquire
, uno_ReleaseFunc release
)
79 //--------------------------------------------------------------------------------------------------
80 inline sal_Bool
_assignStruct(
81 void * pDest
, void * pSource
,
82 typelib_CompoundTypeDescription
* pTypeDescr
,
83 uno_QueryInterfaceFunc queryInterface
, uno_AcquireFunc acquire
, uno_ReleaseFunc release
)
86 if (pTypeDescr
->pBaseTypeDescription
)
89 if (! assignStruct( pDest
, pSource
, pTypeDescr
->pBaseTypeDescription
,
90 queryInterface
, acquire
, release
))
96 typelib_TypeDescriptionReference
** ppTypeRefs
= pTypeDescr
->ppTypeRefs
;
97 sal_Int32
* pMemberOffsets
= pTypeDescr
->pMemberOffsets
;
98 sal_Int32 nDescr
= pTypeDescr
->nMembers
;
101 if (! ::uno_type_assignData( (char *)pDest
+ pMemberOffsets
[nDescr
],
103 (char *)pSource
+ pMemberOffsets
[nDescr
],
105 queryInterface
, acquire
, release
))
112 //--------------------------------------------------------------------------------------------------
113 inline sal_Bool
_assignArray(
114 void * pDest
, void * pSource
,
115 typelib_ArrayTypeDescription
* pTypeDescr
,
116 uno_QueryInterfaceFunc queryInterface
, uno_AcquireFunc acquire
, uno_ReleaseFunc release
)
118 typelib_TypeDescriptionReference
* pElementTypeRef
=
119 ((typelib_IndirectTypeDescription
*)pTypeDescr
)->pType
;
120 typelib_TypeDescription
* pElementTypeDescr
= NULL
;
121 TYPELIB_DANGER_GET( &pElementTypeDescr
, pElementTypeRef
);
122 sal_Int32 nTotalElements
= pTypeDescr
->nTotalElements
;
123 sal_Int32 nElementSize
= pElementTypeDescr
->nSize
;
125 sal_Bool bRet
= sal_False
;
127 switch ( pElementTypeRef
->eTypeClass
)
129 case typelib_TypeClass_CHAR
:
130 case typelib_TypeClass_BOOLEAN
:
131 case typelib_TypeClass_BYTE
:
132 case typelib_TypeClass_SHORT
:
133 case typelib_TypeClass_UNSIGNED_SHORT
:
134 case typelib_TypeClass_LONG
:
135 case typelib_TypeClass_UNSIGNED_LONG
:
136 case typelib_TypeClass_HYPER
:
137 case typelib_TypeClass_UNSIGNED_HYPER
:
138 case typelib_TypeClass_FLOAT
:
139 case typelib_TypeClass_DOUBLE
:
140 for (i
=0; i
< nTotalElements
; i
++)
142 ::rtl_copyMemory((sal_Char
*)pDest
+ i
* nElementSize
,
143 (sal_Char
*)pSource
+ i
* nElementSize
,
148 case typelib_TypeClass_STRING
:
149 for (i
=0; i
< nTotalElements
; i
++)
151 ::rtl_uString_assign( (rtl_uString
**)pDest
+ i
,
152 ((rtl_uString
**)pSource
)[i
] );
156 case typelib_TypeClass_TYPE
:
157 for (i
=0; i
< nTotalElements
; i
++)
159 typelib_TypeDescriptionReference
** pp
= (typelib_TypeDescriptionReference
**)pDest
+ i
;
160 ::typelib_typedescriptionreference_release( *pp
);
161 *pp
= *((typelib_TypeDescriptionReference
**)pSource
+ i
);
166 case typelib_TypeClass_ANY
:
167 for (i
=0; i
< nTotalElements
; i
++)
169 _destructAny( (uno_Any
*)pDest
+ i
, release
);
170 _copyConstructAny( (uno_Any
*)pDest
+ i
, (uno_Any
*)pSource
+ i
,
171 pElementTypeRef
, pElementTypeDescr
, acquire
, 0 );
175 case typelib_TypeClass_ENUM
:
176 for (i
=0; i
< nTotalElements
; i
++)
178 *((sal_Int32
*)pDest
+ i
) = *((sal_Int32
*)pSource
+ i
);
182 case typelib_TypeClass_STRUCT
:
183 case typelib_TypeClass_EXCEPTION
:
184 for (i
=0; i
< nTotalElements
; i
++)
186 bRet
= _assignStruct( (sal_Char
*)pDest
+ i
* nElementSize
,
187 (sal_Char
*)pSource
+ i
* nElementSize
,
188 (typelib_CompoundTypeDescription
*)pElementTypeDescr
,
189 queryInterface
, acquire
, release
);
195 case typelib_TypeClass_UNION
:
196 for (i
=0; i
< nTotalElements
; i
++)
198 _destructUnion( (sal_Char
*)pDest
+ i
* nElementSize
, pElementTypeDescr
, release
);
199 _copyConstructUnion( (sal_Char
*)pDest
+ i
* nElementSize
,
200 (sal_Char
*)pSource
+ i
* nElementSize
,
201 pElementTypeDescr
, acquire
, 0 );
205 case typelib_TypeClass_SEQUENCE
:
206 for (i
=0; i
< nTotalElements
; i
++)
208 ::osl_incrementInterlockedCount(
209 &(*((uno_Sequence
**)pSource
+ i
))->nRefCount
);
211 *((uno_Sequence
**)pDest
+ i
),
212 pElementTypeRef
, pElementTypeDescr
, release
);
213 *((uno_Sequence
**)pDest
+ i
) = *((uno_Sequence
**)pSource
+ i
);
217 case typelib_TypeClass_INTERFACE
:
218 for (i
=0; i
< nTotalElements
; i
++)
221 (void **)((sal_Char
*)pDest
+ i
* nElementSize
),
222 *(void **)((sal_Char
*)pSource
+ i
* nElementSize
),
232 TYPELIB_DANGER_RELEASE( pElementTypeDescr
);
235 //--------------------------------------------------------------------------------------------------
236 inline sal_Bool
_assignData(
238 typelib_TypeDescriptionReference
* pDestType
, typelib_TypeDescription
* pDestTypeDescr
,
240 typelib_TypeDescriptionReference
* pSourceType
, typelib_TypeDescription
* pSourceTypeDescr
,
241 uno_QueryInterfaceFunc queryInterface
, uno_AcquireFunc acquire
, uno_ReleaseFunc release
)
244 if (pDest
== pSource
)
245 return _type_equals( pDestType
, pSourceType
);
249 _destructData( pDest
, pDestType
, pDestTypeDescr
, release
);
250 _defaultConstructData( pDest
, pDestType
, pDestTypeDescr
);
253 while (typelib_TypeClass_ANY
== pSourceType
->eTypeClass
)
255 pSourceTypeDescr
= 0;
256 pSourceType
= ((uno_Any
*)pSource
)->pType
;
257 pSource
= ((uno_Any
*)pSource
)->pData
;
258 if (pDest
== pSource
)
262 switch (pDestType
->eTypeClass
)
264 case typelib_TypeClass_VOID
:
265 return pSourceType
->eTypeClass
== typelib_TypeClass_VOID
;
266 case typelib_TypeClass_CHAR
:
267 switch (pSourceType
->eTypeClass
)
269 case typelib_TypeClass_CHAR
:
270 *(sal_Unicode
*)pDest
= *(sal_Unicode
*)pSource
;
275 case typelib_TypeClass_BOOLEAN
:
276 switch (pSourceType
->eTypeClass
)
278 case typelib_TypeClass_BOOLEAN
:
279 *(sal_Bool
*)pDest
= (*(sal_Bool
*)pSource
!= sal_False
);
284 case typelib_TypeClass_BYTE
:
285 switch (pSourceType
->eTypeClass
)
287 case typelib_TypeClass_BYTE
:
288 *(sal_Int8
*)pDest
= *(sal_Int8
*)pSource
;
293 case typelib_TypeClass_SHORT
:
294 switch (pSourceType
->eTypeClass
)
296 case typelib_TypeClass_BYTE
:
297 *(sal_Int16
*)pDest
= *(sal_Int8
*)pSource
;
299 case typelib_TypeClass_SHORT
:
300 case typelib_TypeClass_UNSIGNED_SHORT
:
301 *(sal_Int16
*)pDest
= *(sal_Int16
*)pSource
;
306 case typelib_TypeClass_UNSIGNED_SHORT
:
307 switch (pSourceType
->eTypeClass
)
309 case typelib_TypeClass_BYTE
:
310 *(sal_uInt16
*)pDest
= *(sal_Int8
*)pSource
;
312 case typelib_TypeClass_SHORT
:
313 case typelib_TypeClass_UNSIGNED_SHORT
:
314 *(sal_uInt16
*)pDest
= *(sal_uInt16
*)pSource
;
319 case typelib_TypeClass_LONG
:
320 switch (pSourceType
->eTypeClass
)
322 case typelib_TypeClass_BYTE
:
323 *(sal_Int32
*)pDest
= *(sal_Int8
*)pSource
;
325 case typelib_TypeClass_SHORT
:
326 *(sal_Int32
*)pDest
= *(sal_Int16
*)pSource
;
328 case typelib_TypeClass_UNSIGNED_SHORT
:
329 *(sal_Int32
*)pDest
= *(sal_uInt16
*)pSource
;
331 case typelib_TypeClass_LONG
:
332 case typelib_TypeClass_UNSIGNED_LONG
:
333 *(sal_Int32
*)pDest
= *(sal_Int32
*)pSource
;
338 case typelib_TypeClass_UNSIGNED_LONG
:
339 switch (pSourceType
->eTypeClass
)
341 case typelib_TypeClass_BYTE
:
342 *(sal_uInt32
*)pDest
= *(sal_Int8
*)pSource
;
344 case typelib_TypeClass_SHORT
:
345 *(sal_uInt32
*)pDest
= *(sal_Int16
*)pSource
;
347 case typelib_TypeClass_UNSIGNED_SHORT
:
348 *(sal_uInt32
*)pDest
= *(sal_uInt16
*)pSource
;
350 case typelib_TypeClass_LONG
:
351 case typelib_TypeClass_UNSIGNED_LONG
:
352 *(sal_uInt32
*)pDest
= *(sal_uInt32
*)pSource
;
357 case typelib_TypeClass_HYPER
:
358 switch (pSourceType
->eTypeClass
)
360 case typelib_TypeClass_BYTE
:
361 *(sal_Int64
*)pDest
= *(sal_Int8
*)pSource
;
363 case typelib_TypeClass_SHORT
:
364 *(sal_Int64
*)pDest
= *(sal_Int16
*)pSource
;
366 case typelib_TypeClass_UNSIGNED_SHORT
:
367 *(sal_Int64
*)pDest
= *(sal_uInt16
*)pSource
;
369 case typelib_TypeClass_LONG
:
370 *(sal_Int64
*)pDest
= *(sal_Int32
*)pSource
;
372 case typelib_TypeClass_UNSIGNED_LONG
:
373 *(sal_Int64
*)pDest
= *(sal_uInt32
*)pSource
;
375 case typelib_TypeClass_HYPER
:
376 case typelib_TypeClass_UNSIGNED_HYPER
:
377 *(sal_Int64
*)pDest
= *(sal_Int64
*)pSource
;
382 case typelib_TypeClass_UNSIGNED_HYPER
:
383 switch (pSourceType
->eTypeClass
)
385 case typelib_TypeClass_BYTE
:
386 *(sal_uInt64
*)pDest
= *(sal_Int8
*)pSource
;
388 case typelib_TypeClass_SHORT
:
389 *(sal_uInt64
*)pDest
= *(sal_Int16
*)pSource
;
391 case typelib_TypeClass_UNSIGNED_SHORT
:
392 *(sal_uInt64
*)pDest
= *(sal_uInt16
*)pSource
;
394 case typelib_TypeClass_LONG
:
395 *(sal_uInt64
*)pDest
= *(sal_Int32
*)pSource
;
397 case typelib_TypeClass_UNSIGNED_LONG
:
398 *(sal_uInt64
*)pDest
= *(sal_uInt32
*)pSource
;
400 case typelib_TypeClass_HYPER
:
401 case typelib_TypeClass_UNSIGNED_HYPER
:
402 *(sal_uInt64
*)pDest
= *(sal_uInt64
*)pSource
;
407 case typelib_TypeClass_FLOAT
:
408 switch (pSourceType
->eTypeClass
)
410 case typelib_TypeClass_BYTE
:
411 *(float *)pDest
= *(sal_Int8
*)pSource
;
413 case typelib_TypeClass_SHORT
:
414 *(float *)pDest
= *(sal_Int16
*)pSource
;
416 case typelib_TypeClass_UNSIGNED_SHORT
:
417 *(float *)pDest
= *(sal_uInt16
*)pSource
;
419 case typelib_TypeClass_FLOAT
:
420 *(float *)pDest
= *(float *)pSource
;
425 case typelib_TypeClass_DOUBLE
:
426 switch (pSourceType
->eTypeClass
)
428 case typelib_TypeClass_BYTE
:
429 *(double *)pDest
= *(sal_Int8
*)pSource
;
431 case typelib_TypeClass_SHORT
:
432 *(double *)pDest
= *(sal_Int16
*)pSource
;
434 case typelib_TypeClass_UNSIGNED_SHORT
:
435 *(double *)pDest
= *(sal_uInt16
*)pSource
;
437 case typelib_TypeClass_LONG
:
438 *(double *)pDest
= *(sal_Int32
*)pSource
;
440 case typelib_TypeClass_UNSIGNED_LONG
:
441 *(double *)pDest
= *(sal_uInt32
*)pSource
;
443 case typelib_TypeClass_FLOAT
:
444 *(double *)pDest
= *(float *)pSource
;
446 case typelib_TypeClass_DOUBLE
:
447 *(double *)pDest
= *(double *)pSource
;
452 case typelib_TypeClass_STRING
:
453 switch (pSourceType
->eTypeClass
)
455 case typelib_TypeClass_STRING
:
456 ::rtl_uString_assign( (rtl_uString
**)pDest
, *(rtl_uString
**)pSource
);
461 case typelib_TypeClass_TYPE
:
462 switch (pSourceType
->eTypeClass
)
464 case typelib_TypeClass_TYPE
:
466 typelib_TypeDescriptionReference
** pp
= (typelib_TypeDescriptionReference
**)pDest
;
467 ::typelib_typedescriptionreference_release( *pp
);
468 *pp
= *(typelib_TypeDescriptionReference
**)pSource
;
475 case typelib_TypeClass_ANY
:
476 _destructAny( (uno_Any
*)pDest
, release
);
477 _copyConstructAny( (uno_Any
*)pDest
, pSource
, pSourceType
, pSourceTypeDescr
, acquire
, 0 );
479 case typelib_TypeClass_ENUM
:
480 if (_type_equals( pDestType
, pSourceType
))
482 *(sal_Int32
*)pDest
= *(sal_Int32
*)pSource
;
486 case typelib_TypeClass_STRUCT
:
487 case typelib_TypeClass_EXCEPTION
:
488 if (typelib_TypeClass_STRUCT
== pSourceType
->eTypeClass
||
489 typelib_TypeClass_EXCEPTION
== pSourceType
->eTypeClass
)
491 sal_Bool bRet
= sal_False
;
492 if (pSourceTypeDescr
)
494 typelib_CompoundTypeDescription
* pTypeDescr
=
495 (typelib_CompoundTypeDescription
*)pSourceTypeDescr
;
498 ((typelib_TypeDescription
*)pTypeDescr
)->pWeakRef
, pDestType
))
500 pTypeDescr
= pTypeDescr
->pBaseTypeDescription
;
504 bRet
= _assignStruct(
505 pDest
, pSource
, pTypeDescr
, queryInterface
, acquire
, release
);
510 TYPELIB_DANGER_GET( &pSourceTypeDescr
, pSourceType
);
511 typelib_CompoundTypeDescription
* pTypeDescr
=
512 (typelib_CompoundTypeDescription
*)pSourceTypeDescr
;
515 ((typelib_TypeDescription
*)pTypeDescr
)->pWeakRef
, pDestType
))
517 pTypeDescr
= pTypeDescr
->pBaseTypeDescription
;
521 bRet
= _assignStruct(
522 pDest
, pSource
, pTypeDescr
, queryInterface
, acquire
, release
);
524 TYPELIB_DANGER_RELEASE( pSourceTypeDescr
);
529 case typelib_TypeClass_ARRAY
:
531 sal_Bool bRet
= sal_False
;
532 if (pSourceTypeDescr
)
534 typelib_ArrayTypeDescription
* pTypeDescr
=
535 (typelib_ArrayTypeDescription
*)pSourceTypeDescr
;
536 bRet
= _assignArray( pDest
, pSource
, pTypeDescr
, queryInterface
, acquire
, release
);
540 TYPELIB_DANGER_GET( &pSourceTypeDescr
, pSourceType
);
541 typelib_ArrayTypeDescription
* pTypeDescr
=
542 (typelib_ArrayTypeDescription
*)pSourceTypeDescr
;
546 pDest
, pSource
, pTypeDescr
, queryInterface
, acquire
, release
);
548 TYPELIB_DANGER_RELEASE( pSourceTypeDescr
);
552 case typelib_TypeClass_UNION
:
553 if (_type_equals( pDestType
, pSourceType
))
557 _destructUnion( pDest
, pDestTypeDescr
, release
);
558 _copyConstructUnion( pDest
, pSource
, pDestTypeDescr
, acquire
, 0 );
562 TYPELIB_DANGER_GET( &pDestTypeDescr
, pDestType
);
563 _destructUnion( pDest
, pDestTypeDescr
, release
);
564 _copyConstructUnion( pDest
, pSource
, pDestTypeDescr
, acquire
, 0 );
565 TYPELIB_DANGER_RELEASE( pDestTypeDescr
);
570 case typelib_TypeClass_SEQUENCE
:
571 if (typelib_TypeClass_SEQUENCE
!= pSourceType
->eTypeClass
)
574 if (*(uno_Sequence
**)pSource
== *(uno_Sequence
**)pDest
)
576 if (_type_equals( pDestType
, pSourceType
))
578 ::osl_incrementInterlockedCount(
579 &(*(uno_Sequence
**)pSource
)->nRefCount
);
581 *(uno_Sequence
**)pDest
, pDestType
, pDestTypeDescr
, release
);
582 *(uno_Sequence
**)pDest
= *(uno_Sequence
**)pSource
;
586 case typelib_TypeClass_INTERFACE
:
587 if (typelib_TypeClass_INTERFACE
!= pSourceType
->eTypeClass
)
589 if (_type_equals( pDestType
, pSourceType
))
591 _assignInterface( (void **)pDest
, *(void **)pSource
, acquire
, release
);
594 else if (*static_cast< void ** >(pSource
) == 0)
596 // A null reference of any interface type can be converted to a null
597 // reference of any other interface type:
598 void * const pToBeReleased
= *static_cast< void ** >(pDest
);
599 *static_cast< void ** >(pDest
) = 0;
600 _release( pToBeReleased
, release
);
605 if (pSourceTypeDescr
)
607 typelib_TypeDescription
* pTD
= pSourceTypeDescr
;
608 while (pTD
&& !_type_equals( pTD
->pWeakRef
, pDestType
))
610 pTD
= (typelib_TypeDescription
*)
611 ((typelib_InterfaceTypeDescription
*)pTD
)->pBaseTypeDescription
;
613 if (pTD
) // is base of dest
615 _assignInterface( (void **)pDest
, *(void **)pSource
, acquire
, release
);
620 // query for interface:
621 void * pQueried
= _queryInterface( *static_cast<void **>(pSource
),
622 pDestType
, queryInterface
);
624 void * const pToBeReleased
= *static_cast<void **>(pDest
);
625 *static_cast<void **>(pDest
) = pQueried
;
626 _release( pToBeReleased
, release
);
628 return (pQueried
!= 0);