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 ************************************************************************/
39 //##################################################################################################
40 //#### assignment ##################################################################################
41 //##################################################################################################
44 //--------------------------------------------------------------------------------------------------
45 inline void _assignInterface(
46 void ** ppDest
, void * pSource
,
47 uno_AcquireFunc acquire
, uno_ReleaseFunc release
)
50 _acquire( pSource
, acquire
);
51 void * const pToBeReleased
= *ppDest
;
53 _release( pToBeReleased
, release
);
55 //--------------------------------------------------------------------------------------------------
56 inline void * _queryInterface(
58 typelib_TypeDescriptionReference
* pDestType
,
59 uno_QueryInterfaceFunc queryInterface
)
64 if (0 == queryInterface
)
65 queryInterface
= binuno_queryInterface
;
66 pSource
= (*queryInterface
)( pSource
, pDestType
);
70 //==================================================================================================
71 sal_Bool
assignStruct(
72 void * pDest
, void * pSource
,
73 typelib_CompoundTypeDescription
* pTypeDescr
,
74 uno_QueryInterfaceFunc queryInterface
, uno_AcquireFunc acquire
, uno_ReleaseFunc release
)
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
)
83 if (pTypeDescr
->pBaseTypeDescription
)
86 if (! assignStruct( pDest
, pSource
, pTypeDescr
->pBaseTypeDescription
,
87 queryInterface
, acquire
, release
))
93 typelib_TypeDescriptionReference
** ppTypeRefs
= pTypeDescr
->ppTypeRefs
;
94 sal_Int32
* pMemberOffsets
= pTypeDescr
->pMemberOffsets
;
95 sal_Int32 nDescr
= pTypeDescr
->nMembers
;
98 if (! ::uno_type_assignData( (char *)pDest
+ pMemberOffsets
[nDescr
],
100 (char *)pSource
+ pMemberOffsets
[nDescr
],
102 queryInterface
, acquire
, release
))
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
;
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
,
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
] );
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
);
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 );
172 case typelib_TypeClass_ENUM
:
173 for (i
=0; i
< nTotalElements
; i
++)
175 *((sal_Int32
*)pDest
+ i
) = *((sal_Int32
*)pSource
+ i
);
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
);
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 );
202 case typelib_TypeClass_SEQUENCE
:
203 for (i
=0; i
< nTotalElements
; i
++)
205 ::osl_incrementInterlockedCount(
206 &(*((uno_Sequence
**)pSource
+ i
))->nRefCount
);
208 *((uno_Sequence
**)pDest
+ i
),
209 pElementTypeRef
, pElementTypeDescr
, release
);
210 *((uno_Sequence
**)pDest
+ i
) = *((uno_Sequence
**)pSource
+ i
);
214 case typelib_TypeClass_INTERFACE
:
215 for (i
=0; i
< nTotalElements
; i
++)
218 (void **)((sal_Char
*)pDest
+ i
* nElementSize
),
219 *(void **)((sal_Char
*)pSource
+ i
* nElementSize
),
229 TYPELIB_DANGER_RELEASE( pElementTypeDescr
);
232 //--------------------------------------------------------------------------------------------------
233 inline sal_Bool
_assignData(
235 typelib_TypeDescriptionReference
* pDestType
, typelib_TypeDescription
* pDestTypeDescr
,
237 typelib_TypeDescriptionReference
* pSourceType
, typelib_TypeDescription
* pSourceTypeDescr
,
238 uno_QueryInterfaceFunc queryInterface
, uno_AcquireFunc acquire
, uno_ReleaseFunc release
)
241 if (pDest
== pSource
)
242 return _type_equals( pDestType
, pSourceType
);
246 _destructData( pDest
, pDestType
, pDestTypeDescr
, release
);
247 _defaultConstructData( pDest
, pDestType
, pDestTypeDescr
);
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
)
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
;
272 case typelib_TypeClass_BOOLEAN
:
273 switch (pSourceType
->eTypeClass
)
275 case typelib_TypeClass_BOOLEAN
:
276 *(sal_Bool
*)pDest
= (*(sal_Bool
*)pSource
!= sal_False
);
281 case typelib_TypeClass_BYTE
:
282 switch (pSourceType
->eTypeClass
)
284 case typelib_TypeClass_BYTE
:
285 *(sal_Int8
*)pDest
= *(sal_Int8
*)pSource
;
290 case typelib_TypeClass_SHORT
:
291 switch (pSourceType
->eTypeClass
)
293 case typelib_TypeClass_BYTE
:
294 *(sal_Int16
*)pDest
= *(sal_Int8
*)pSource
;
296 case typelib_TypeClass_SHORT
:
297 case typelib_TypeClass_UNSIGNED_SHORT
:
298 *(sal_Int16
*)pDest
= *(sal_Int16
*)pSource
;
303 case typelib_TypeClass_UNSIGNED_SHORT
:
304 switch (pSourceType
->eTypeClass
)
306 case typelib_TypeClass_BYTE
:
307 *(sal_uInt16
*)pDest
= *(sal_Int8
*)pSource
;
309 case typelib_TypeClass_SHORT
:
310 case typelib_TypeClass_UNSIGNED_SHORT
:
311 *(sal_uInt16
*)pDest
= *(sal_uInt16
*)pSource
;
316 case typelib_TypeClass_LONG
:
317 switch (pSourceType
->eTypeClass
)
319 case typelib_TypeClass_BYTE
:
320 *(sal_Int32
*)pDest
= *(sal_Int8
*)pSource
;
322 case typelib_TypeClass_SHORT
:
323 *(sal_Int32
*)pDest
= *(sal_Int16
*)pSource
;
325 case typelib_TypeClass_UNSIGNED_SHORT
:
326 *(sal_Int32
*)pDest
= *(sal_uInt16
*)pSource
;
328 case typelib_TypeClass_LONG
:
329 case typelib_TypeClass_UNSIGNED_LONG
:
330 *(sal_Int32
*)pDest
= *(sal_Int32
*)pSource
;
335 case typelib_TypeClass_UNSIGNED_LONG
:
336 switch (pSourceType
->eTypeClass
)
338 case typelib_TypeClass_BYTE
:
339 *(sal_uInt32
*)pDest
= *(sal_Int8
*)pSource
;
341 case typelib_TypeClass_SHORT
:
342 *(sal_uInt32
*)pDest
= *(sal_Int16
*)pSource
;
344 case typelib_TypeClass_UNSIGNED_SHORT
:
345 *(sal_uInt32
*)pDest
= *(sal_uInt16
*)pSource
;
347 case typelib_TypeClass_LONG
:
348 case typelib_TypeClass_UNSIGNED_LONG
:
349 *(sal_uInt32
*)pDest
= *(sal_uInt32
*)pSource
;
354 case typelib_TypeClass_HYPER
:
355 switch (pSourceType
->eTypeClass
)
357 case typelib_TypeClass_BYTE
:
358 *(sal_Int64
*)pDest
= *(sal_Int8
*)pSource
;
360 case typelib_TypeClass_SHORT
:
361 *(sal_Int64
*)pDest
= *(sal_Int16
*)pSource
;
363 case typelib_TypeClass_UNSIGNED_SHORT
:
364 *(sal_Int64
*)pDest
= *(sal_uInt16
*)pSource
;
366 case typelib_TypeClass_LONG
:
367 *(sal_Int64
*)pDest
= *(sal_Int32
*)pSource
;
369 case typelib_TypeClass_UNSIGNED_LONG
:
370 *(sal_Int64
*)pDest
= *(sal_uInt32
*)pSource
;
372 case typelib_TypeClass_HYPER
:
373 case typelib_TypeClass_UNSIGNED_HYPER
:
374 *(sal_Int64
*)pDest
= *(sal_Int64
*)pSource
;
379 case typelib_TypeClass_UNSIGNED_HYPER
:
380 switch (pSourceType
->eTypeClass
)
382 case typelib_TypeClass_BYTE
:
383 *(sal_uInt64
*)pDest
= *(sal_Int8
*)pSource
;
385 case typelib_TypeClass_SHORT
:
386 *(sal_uInt64
*)pDest
= *(sal_Int16
*)pSource
;
388 case typelib_TypeClass_UNSIGNED_SHORT
:
389 *(sal_uInt64
*)pDest
= *(sal_uInt16
*)pSource
;
391 case typelib_TypeClass_LONG
:
392 *(sal_uInt64
*)pDest
= *(sal_Int32
*)pSource
;
394 case typelib_TypeClass_UNSIGNED_LONG
:
395 *(sal_uInt64
*)pDest
= *(sal_uInt32
*)pSource
;
397 case typelib_TypeClass_HYPER
:
398 case typelib_TypeClass_UNSIGNED_HYPER
:
399 *(sal_uInt64
*)pDest
= *(sal_uInt64
*)pSource
;
404 case typelib_TypeClass_FLOAT
:
405 switch (pSourceType
->eTypeClass
)
407 case typelib_TypeClass_BYTE
:
408 *(float *)pDest
= *(sal_Int8
*)pSource
;
410 case typelib_TypeClass_SHORT
:
411 *(float *)pDest
= *(sal_Int16
*)pSource
;
413 case typelib_TypeClass_UNSIGNED_SHORT
:
414 *(float *)pDest
= *(sal_uInt16
*)pSource
;
416 case typelib_TypeClass_FLOAT
:
417 *(float *)pDest
= *(float *)pSource
;
422 case typelib_TypeClass_DOUBLE
:
423 switch (pSourceType
->eTypeClass
)
425 case typelib_TypeClass_BYTE
:
426 *(double *)pDest
= *(sal_Int8
*)pSource
;
428 case typelib_TypeClass_SHORT
:
429 *(double *)pDest
= *(sal_Int16
*)pSource
;
431 case typelib_TypeClass_UNSIGNED_SHORT
:
432 *(double *)pDest
= *(sal_uInt16
*)pSource
;
434 case typelib_TypeClass_LONG
:
435 *(double *)pDest
= *(sal_Int32
*)pSource
;
437 case typelib_TypeClass_UNSIGNED_LONG
:
438 *(double *)pDest
= *(sal_uInt32
*)pSource
;
440 case typelib_TypeClass_FLOAT
:
441 *(double *)pDest
= *(float *)pSource
;
443 case typelib_TypeClass_DOUBLE
:
444 *(double *)pDest
= *(double *)pSource
;
449 case typelib_TypeClass_STRING
:
450 switch (pSourceType
->eTypeClass
)
452 case typelib_TypeClass_STRING
:
453 ::rtl_uString_assign( (rtl_uString
**)pDest
, *(rtl_uString
**)pSource
);
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
;
472 case typelib_TypeClass_ANY
:
473 _destructAny( (uno_Any
*)pDest
, release
);
474 _copyConstructAny( (uno_Any
*)pDest
, pSource
, pSourceType
, pSourceTypeDescr
, acquire
, 0 );
476 case typelib_TypeClass_ENUM
:
477 if (_type_equals( pDestType
, pSourceType
))
479 *(sal_Int32
*)pDest
= *(sal_Int32
*)pSource
;
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
;
495 ((typelib_TypeDescription
*)pTypeDescr
)->pWeakRef
, pDestType
))
497 pTypeDescr
= pTypeDescr
->pBaseTypeDescription
;
501 bRet
= _assignStruct(
502 pDest
, pSource
, pTypeDescr
, queryInterface
, acquire
, release
);
507 TYPELIB_DANGER_GET( &pSourceTypeDescr
, pSourceType
);
508 typelib_CompoundTypeDescription
* pTypeDescr
=
509 (typelib_CompoundTypeDescription
*)pSourceTypeDescr
;
512 ((typelib_TypeDescription
*)pTypeDescr
)->pWeakRef
, pDestType
))
514 pTypeDescr
= pTypeDescr
->pBaseTypeDescription
;
518 bRet
= _assignStruct(
519 pDest
, pSource
, pTypeDescr
, queryInterface
, acquire
, release
);
521 TYPELIB_DANGER_RELEASE( pSourceTypeDescr
);
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
);
537 TYPELIB_DANGER_GET( &pSourceTypeDescr
, pSourceType
);
538 typelib_ArrayTypeDescription
* pTypeDescr
=
539 (typelib_ArrayTypeDescription
*)pSourceTypeDescr
;
543 pDest
, pSource
, pTypeDescr
, queryInterface
, acquire
, release
);
545 TYPELIB_DANGER_RELEASE( pSourceTypeDescr
);
549 case typelib_TypeClass_UNION
:
550 if (_type_equals( pDestType
, pSourceType
))
554 _destructUnion( pDest
, pDestTypeDescr
, release
);
555 _copyConstructUnion( pDest
, pSource
, pDestTypeDescr
, acquire
, 0 );
559 TYPELIB_DANGER_GET( &pDestTypeDescr
, pDestType
);
560 _destructUnion( pDest
, pDestTypeDescr
, release
);
561 _copyConstructUnion( pDest
, pSource
, pDestTypeDescr
, acquire
, 0 );
562 TYPELIB_DANGER_RELEASE( pDestTypeDescr
);
567 case typelib_TypeClass_SEQUENCE
:
568 if (typelib_TypeClass_SEQUENCE
!= pSourceType
->eTypeClass
)
571 if (*(uno_Sequence
**)pSource
== *(uno_Sequence
**)pDest
)
573 if (_type_equals( pDestType
, pSourceType
))
575 ::osl_incrementInterlockedCount(
576 &(*(uno_Sequence
**)pSource
)->nRefCount
);
578 *(uno_Sequence
**)pDest
, pDestType
, pDestTypeDescr
, release
);
579 *(uno_Sequence
**)pDest
= *(uno_Sequence
**)pSource
;
583 case typelib_TypeClass_INTERFACE
:
584 if (typelib_TypeClass_INTERFACE
!= pSourceType
->eTypeClass
)
586 if (_type_equals( pDestType
, pSourceType
))
588 _assignInterface( (void **)pDest
, *(void **)pSource
, acquire
, release
);
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
);
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
);
617 // query for interface:
618 void * pQueried
= _queryInterface( *static_cast<void **>(pSource
),
619 pDestType
, queryInterface
);
621 void * const pToBeReleased
= *static_cast<void **>(pDest
);
622 *static_cast<void **>(pDest
) = pQueried
;
623 _release( pToBeReleased
, release
);
625 return (pQueried
!= 0);