update dev300-m58
[ooovba.git] / cppu / source / uno / assign.hxx
blob38b46cfd550612dfd96ef8b71274fa2812f5dac0
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: assign.hxx,v $
10 * $Revision: 1.19 $
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 ************************************************************************/
30 #ifndef ASSIGN_HXX
31 #define ASSIGN_HXX
33 #include "prim.hxx"
34 #include "destr.hxx"
35 #include "constr.hxx"
36 #include "copy.hxx"
39 namespace cppu
42 //##################################################################################################
43 //#### assignment ##################################################################################
44 //##################################################################################################
47 //--------------------------------------------------------------------------------------------------
48 inline void _assignInterface(
49 void ** ppDest, void * pSource,
50 uno_AcquireFunc acquire, uno_ReleaseFunc release )
51 SAL_THROW( () )
53 _acquire( pSource, acquire );
54 void * const pToBeReleased = *ppDest;
55 *ppDest = pSource;
56 _release( pToBeReleased, release );
58 //--------------------------------------------------------------------------------------------------
59 inline void * _queryInterface(
60 void * pSource,
61 typelib_TypeDescriptionReference * pDestType,
62 uno_QueryInterfaceFunc queryInterface )
63 SAL_THROW( () )
65 if (pSource)
67 if (0 == queryInterface)
68 queryInterface = binuno_queryInterface;
69 pSource = (*queryInterface)( pSource, pDestType );
71 return pSource;
73 //==================================================================================================
74 sal_Bool assignStruct(
75 void * pDest, void * pSource,
76 typelib_CompoundTypeDescription * pTypeDescr,
77 uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release )
78 SAL_THROW( () );
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 )
84 SAL_THROW( () )
86 if (pTypeDescr->pBaseTypeDescription)
88 // copy base value
89 if (! assignStruct( pDest, pSource, pTypeDescr->pBaseTypeDescription,
90 queryInterface, acquire, release ))
92 return sal_False;
95 // then copy members
96 typelib_TypeDescriptionReference ** ppTypeRefs = pTypeDescr->ppTypeRefs;
97 sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets;
98 sal_Int32 nDescr = pTypeDescr->nMembers;
99 while (nDescr--)
101 if (! ::uno_type_assignData( (char *)pDest + pMemberOffsets[nDescr],
102 ppTypeRefs[nDescr],
103 (char *)pSource + pMemberOffsets[nDescr],
104 ppTypeRefs[nDescr],
105 queryInterface, acquire, release ))
107 return sal_False;
110 return sal_True;
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;
124 sal_Int32 i;
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,
144 nElementSize);
146 bRet = sal_True;
147 break;
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] );
154 bRet = sal_True;
155 break;
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);
162 TYPE_ACQUIRE( *pp );
164 bRet = sal_True;
165 break;
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 );
173 bRet = sal_True;
174 break;
175 case typelib_TypeClass_ENUM:
176 for (i=0; i < nTotalElements; i++)
178 *((sal_Int32 *)pDest + i) = *((sal_Int32 *)pSource + i);
180 bRet = sal_True;
181 break;
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 );
190 if (! bRet)
191 break;
193 bRet = sal_True;
194 break;
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 );
203 bRet = sal_True;
204 break;
205 case typelib_TypeClass_SEQUENCE:
206 for (i=0; i < nTotalElements; i++)
208 ::osl_incrementInterlockedCount(
209 &(*((uno_Sequence **)pSource + i))->nRefCount );
210 idestructSequence(
211 *((uno_Sequence **)pDest + i),
212 pElementTypeRef, pElementTypeDescr, release );
213 *((uno_Sequence **)pDest + i) = *((uno_Sequence **)pSource + i);
215 bRet = sal_True;
216 break;
217 case typelib_TypeClass_INTERFACE:
218 for (i=0; i < nTotalElements; i++)
220 _assignInterface(
221 (void **)((sal_Char*)pDest + i * nElementSize),
222 *(void **)((sal_Char*)pSource + i * nElementSize),
223 acquire, release );
225 bRet = sal_True;
226 break;
227 default:
228 OSL_ASSERT(false);
229 break;
232 TYPELIB_DANGER_RELEASE( pElementTypeDescr );
233 return bRet;
235 //--------------------------------------------------------------------------------------------------
236 inline sal_Bool _assignData(
237 void * pDest,
238 typelib_TypeDescriptionReference * pDestType, typelib_TypeDescription * pDestTypeDescr,
239 void * pSource,
240 typelib_TypeDescriptionReference * pSourceType, typelib_TypeDescription * pSourceTypeDescr,
241 uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release )
242 SAL_THROW( () )
244 if (pDest == pSource)
245 return _type_equals( pDestType, pSourceType );
247 if (! pSource)
249 _destructData( pDest, pDestType, pDestTypeDescr, release );
250 _defaultConstructData( pDest, pDestType, pDestTypeDescr );
251 return sal_True;
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)
259 return sal_True;
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;
271 return sal_True;
272 default:
273 return sal_False;
275 case typelib_TypeClass_BOOLEAN:
276 switch (pSourceType->eTypeClass)
278 case typelib_TypeClass_BOOLEAN:
279 *(sal_Bool *)pDest = (*(sal_Bool *)pSource != sal_False);
280 return sal_True;
281 default:
282 return sal_False;
284 case typelib_TypeClass_BYTE:
285 switch (pSourceType->eTypeClass)
287 case typelib_TypeClass_BYTE:
288 *(sal_Int8 *)pDest = *(sal_Int8 *)pSource;
289 return sal_True;
290 default:
291 return sal_False;
293 case typelib_TypeClass_SHORT:
294 switch (pSourceType->eTypeClass)
296 case typelib_TypeClass_BYTE:
297 *(sal_Int16 *)pDest = *(sal_Int8 *)pSource;
298 return sal_True;
299 case typelib_TypeClass_SHORT:
300 case typelib_TypeClass_UNSIGNED_SHORT:
301 *(sal_Int16 *)pDest = *(sal_Int16 *)pSource;
302 return sal_True;
303 default:
304 return sal_False;
306 case typelib_TypeClass_UNSIGNED_SHORT:
307 switch (pSourceType->eTypeClass)
309 case typelib_TypeClass_BYTE:
310 *(sal_uInt16 *)pDest = *(sal_Int8 *)pSource;
311 return sal_True;
312 case typelib_TypeClass_SHORT:
313 case typelib_TypeClass_UNSIGNED_SHORT:
314 *(sal_uInt16 *)pDest = *(sal_uInt16 *)pSource;
315 return sal_True;
316 default:
317 return sal_False;
319 case typelib_TypeClass_LONG:
320 switch (pSourceType->eTypeClass)
322 case typelib_TypeClass_BYTE:
323 *(sal_Int32 *)pDest = *(sal_Int8 *)pSource;
324 return sal_True;
325 case typelib_TypeClass_SHORT:
326 *(sal_Int32 *)pDest = *(sal_Int16 *)pSource;
327 return sal_True;
328 case typelib_TypeClass_UNSIGNED_SHORT:
329 *(sal_Int32 *)pDest = *(sal_uInt16 *)pSource;
330 return sal_True;
331 case typelib_TypeClass_LONG:
332 case typelib_TypeClass_UNSIGNED_LONG:
333 *(sal_Int32 *)pDest = *(sal_Int32 *)pSource;
334 return sal_True;
335 default:
336 return sal_False;
338 case typelib_TypeClass_UNSIGNED_LONG:
339 switch (pSourceType->eTypeClass)
341 case typelib_TypeClass_BYTE:
342 *(sal_uInt32 *)pDest = *(sal_Int8 *)pSource;
343 return sal_True;
344 case typelib_TypeClass_SHORT:
345 *(sal_uInt32 *)pDest = *(sal_Int16 *)pSource;
346 return sal_True;
347 case typelib_TypeClass_UNSIGNED_SHORT:
348 *(sal_uInt32 *)pDest = *(sal_uInt16 *)pSource;
349 return sal_True;
350 case typelib_TypeClass_LONG:
351 case typelib_TypeClass_UNSIGNED_LONG:
352 *(sal_uInt32 *)pDest = *(sal_uInt32 *)pSource;
353 return sal_True;
354 default:
355 return sal_False;
357 case typelib_TypeClass_HYPER:
358 switch (pSourceType->eTypeClass)
360 case typelib_TypeClass_BYTE:
361 *(sal_Int64 *)pDest = *(sal_Int8 *)pSource;
362 return sal_True;
363 case typelib_TypeClass_SHORT:
364 *(sal_Int64 *)pDest = *(sal_Int16 *)pSource;
365 return sal_True;
366 case typelib_TypeClass_UNSIGNED_SHORT:
367 *(sal_Int64 *)pDest = *(sal_uInt16 *)pSource;
368 return sal_True;
369 case typelib_TypeClass_LONG:
370 *(sal_Int64 *)pDest = *(sal_Int32 *)pSource;
371 return sal_True;
372 case typelib_TypeClass_UNSIGNED_LONG:
373 *(sal_Int64 *)pDest = *(sal_uInt32 *)pSource;
374 return sal_True;
375 case typelib_TypeClass_HYPER:
376 case typelib_TypeClass_UNSIGNED_HYPER:
377 *(sal_Int64 *)pDest = *(sal_Int64 *)pSource;
378 return sal_True;
379 default:
380 return sal_False;
382 case typelib_TypeClass_UNSIGNED_HYPER:
383 switch (pSourceType->eTypeClass)
385 case typelib_TypeClass_BYTE:
386 *(sal_uInt64 *)pDest = *(sal_Int8 *)pSource;
387 return sal_True;
388 case typelib_TypeClass_SHORT:
389 *(sal_uInt64 *)pDest = *(sal_Int16 *)pSource;
390 return sal_True;
391 case typelib_TypeClass_UNSIGNED_SHORT:
392 *(sal_uInt64 *)pDest = *(sal_uInt16 *)pSource;
393 return sal_True;
394 case typelib_TypeClass_LONG:
395 *(sal_uInt64 *)pDest = *(sal_Int32 *)pSource;
396 return sal_True;
397 case typelib_TypeClass_UNSIGNED_LONG:
398 *(sal_uInt64 *)pDest = *(sal_uInt32 *)pSource;
399 return sal_True;
400 case typelib_TypeClass_HYPER:
401 case typelib_TypeClass_UNSIGNED_HYPER:
402 *(sal_uInt64 *)pDest = *(sal_uInt64 *)pSource;
403 return sal_True;
404 default:
405 return sal_False;
407 case typelib_TypeClass_FLOAT:
408 switch (pSourceType->eTypeClass)
410 case typelib_TypeClass_BYTE:
411 *(float *)pDest = *(sal_Int8 *)pSource;
412 return sal_True;
413 case typelib_TypeClass_SHORT:
414 *(float *)pDest = *(sal_Int16 *)pSource;
415 return sal_True;
416 case typelib_TypeClass_UNSIGNED_SHORT:
417 *(float *)pDest = *(sal_uInt16 *)pSource;
418 return sal_True;
419 case typelib_TypeClass_FLOAT:
420 *(float *)pDest = *(float *)pSource;
421 return sal_True;
422 default:
423 return sal_False;
425 case typelib_TypeClass_DOUBLE:
426 switch (pSourceType->eTypeClass)
428 case typelib_TypeClass_BYTE:
429 *(double *)pDest = *(sal_Int8 *)pSource;
430 return sal_True;
431 case typelib_TypeClass_SHORT:
432 *(double *)pDest = *(sal_Int16 *)pSource;
433 return sal_True;
434 case typelib_TypeClass_UNSIGNED_SHORT:
435 *(double *)pDest = *(sal_uInt16 *)pSource;
436 return sal_True;
437 case typelib_TypeClass_LONG:
438 *(double *)pDest = *(sal_Int32 *)pSource;
439 return sal_True;
440 case typelib_TypeClass_UNSIGNED_LONG:
441 *(double *)pDest = *(sal_uInt32 *)pSource;
442 return sal_True;
443 case typelib_TypeClass_FLOAT:
444 *(double *)pDest = *(float *)pSource;
445 return sal_True;
446 case typelib_TypeClass_DOUBLE:
447 *(double *)pDest = *(double *)pSource;
448 return sal_True;
449 default:
450 return sal_False;
452 case typelib_TypeClass_STRING:
453 switch (pSourceType->eTypeClass)
455 case typelib_TypeClass_STRING:
456 ::rtl_uString_assign( (rtl_uString **)pDest, *(rtl_uString **)pSource );
457 return sal_True;
458 default:
459 return sal_False;
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;
469 TYPE_ACQUIRE( *pp );
470 return sal_True;
472 default:
473 return sal_False;
475 case typelib_TypeClass_ANY:
476 _destructAny( (uno_Any *)pDest, release );
477 _copyConstructAny( (uno_Any *)pDest, pSource, pSourceType, pSourceTypeDescr, acquire, 0 );
478 return sal_True;
479 case typelib_TypeClass_ENUM:
480 if (_type_equals( pDestType, pSourceType ))
482 *(sal_Int32 *)pDest = *(sal_Int32 *)pSource;
483 return sal_True;
485 return sal_False;
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;
496 while (pTypeDescr &&
497 !_type_equals(
498 ((typelib_TypeDescription *)pTypeDescr)->pWeakRef, pDestType ))
500 pTypeDescr = pTypeDescr->pBaseTypeDescription;
502 if (pTypeDescr)
504 bRet = _assignStruct(
505 pDest, pSource, pTypeDescr, queryInterface, acquire, release );
508 else
510 TYPELIB_DANGER_GET( &pSourceTypeDescr, pSourceType );
511 typelib_CompoundTypeDescription * pTypeDescr =
512 (typelib_CompoundTypeDescription *)pSourceTypeDescr;
513 while (pTypeDescr &&
514 !_type_equals(
515 ((typelib_TypeDescription *)pTypeDescr)->pWeakRef, pDestType ))
517 pTypeDescr = pTypeDescr->pBaseTypeDescription;
519 if (pTypeDescr)
521 bRet = _assignStruct(
522 pDest, pSource, pTypeDescr, queryInterface, acquire, release );
524 TYPELIB_DANGER_RELEASE( pSourceTypeDescr );
526 return bRet;
528 return sal_False;
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 );
538 else
540 TYPELIB_DANGER_GET( &pSourceTypeDescr, pSourceType );
541 typelib_ArrayTypeDescription * pTypeDescr =
542 (typelib_ArrayTypeDescription *)pSourceTypeDescr;
543 if ( pTypeDescr )
545 bRet = _assignArray(
546 pDest, pSource, pTypeDescr, queryInterface, acquire, release );
548 TYPELIB_DANGER_RELEASE( pSourceTypeDescr );
550 return bRet;
552 case typelib_TypeClass_UNION:
553 if (_type_equals( pDestType, pSourceType ))
555 if (pDestTypeDescr)
557 _destructUnion( pDest, pDestTypeDescr, release );
558 _copyConstructUnion( pDest, pSource, pDestTypeDescr, acquire, 0 );
560 else
562 TYPELIB_DANGER_GET( &pDestTypeDescr, pDestType );
563 _destructUnion( pDest, pDestTypeDescr, release );
564 _copyConstructUnion( pDest, pSource, pDestTypeDescr, acquire, 0 );
565 TYPELIB_DANGER_RELEASE( pDestTypeDescr );
567 return sal_True;
569 return sal_False;
570 case typelib_TypeClass_SEQUENCE:
571 if (typelib_TypeClass_SEQUENCE != pSourceType->eTypeClass)
572 return sal_False;
573 // self assignment:
574 if (*(uno_Sequence **)pSource == *(uno_Sequence **)pDest)
575 return sal_True;
576 if (_type_equals( pDestType, pSourceType ))
578 ::osl_incrementInterlockedCount(
579 &(*(uno_Sequence **)pSource)->nRefCount );
580 idestructSequence(
581 *(uno_Sequence **)pDest, pDestType, pDestTypeDescr, release );
582 *(uno_Sequence **)pDest = *(uno_Sequence **)pSource;
583 return sal_True;
585 return sal_False;
586 case typelib_TypeClass_INTERFACE:
587 if (typelib_TypeClass_INTERFACE != pSourceType->eTypeClass)
588 return sal_False;
589 if (_type_equals( pDestType, pSourceType ))
591 _assignInterface( (void **)pDest, *(void **)pSource, acquire, release );
592 return sal_True;
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 );
601 return true;
603 else
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 );
616 return true;
620 // query for interface:
621 void * pQueried = _queryInterface( *static_cast<void **>(pSource),
622 pDestType, queryInterface );
623 if (pQueried != 0) {
624 void * const pToBeReleased = *static_cast<void **>(pDest);
625 *static_cast<void **>(pDest) = pQueried;
626 _release( pToBeReleased, release );
628 return (pQueried != 0);
630 default:
631 OSL_ASSERT(false);
632 return sal_False;
638 #endif