Version 4.0.2.1, tag libreoffice-4.0.2.1
[LibreOffice.git] / cppu / source / uno / assign.hxx
blob66b065cb834b64678345155f55f3733986efc29c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
19 #ifndef ASSIGN_HXX
20 #define ASSIGN_HXX
22 #include <string.h>
24 #include "prim.hxx"
25 #include "destr.hxx"
26 #include "constr.hxx"
27 #include "copy.hxx"
30 namespace cppu
33 //##################################################################################################
34 //#### assignment ##################################################################################
35 //##################################################################################################
38 //--------------------------------------------------------------------------------------------------
39 inline void _assignInterface(
40 void ** ppDest, void * pSource,
41 uno_AcquireFunc acquire, uno_ReleaseFunc release )
42 SAL_THROW(())
44 _acquire( pSource, acquire );
45 void * const pToBeReleased = *ppDest;
46 *ppDest = pSource;
47 _release( pToBeReleased, release );
49 //--------------------------------------------------------------------------------------------------
50 inline void * _queryInterface(
51 void * pSource,
52 typelib_TypeDescriptionReference * pDestType,
53 uno_QueryInterfaceFunc queryInterface )
54 SAL_THROW(())
56 if (pSource)
58 if (0 == queryInterface)
59 queryInterface = binuno_queryInterface;
60 pSource = (*queryInterface)( pSource, pDestType );
62 return pSource;
64 //==================================================================================================
65 sal_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 inline 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(())
77 if (pTypeDescr->pBaseTypeDescription)
79 // copy base value
80 if (! assignStruct( pDest, pSource, pTypeDescr->pBaseTypeDescription,
81 queryInterface, acquire, release ))
83 return sal_False;
86 // then copy members
87 typelib_TypeDescriptionReference ** ppTypeRefs = pTypeDescr->ppTypeRefs;
88 sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets;
89 sal_Int32 nDescr = pTypeDescr->nMembers;
90 while (nDescr--)
92 if (! ::uno_type_assignData( (char *)pDest + pMemberOffsets[nDescr],
93 ppTypeRefs[nDescr],
94 (char *)pSource + pMemberOffsets[nDescr],
95 ppTypeRefs[nDescr],
96 queryInterface, acquire, release ))
98 return sal_False;
101 return sal_True;
103 //--------------------------------------------------------------------------------------------------
104 inline sal_Bool _assignArray(
105 void * pDest, void * pSource,
106 typelib_ArrayTypeDescription * pTypeDescr,
107 uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release )
109 typelib_TypeDescriptionReference * pElementTypeRef =
110 ((typelib_IndirectTypeDescription *)pTypeDescr)->pType;
111 typelib_TypeDescription * pElementTypeDescr = NULL;
112 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementTypeRef );
113 sal_Int32 nTotalElements = pTypeDescr->nTotalElements;
114 sal_Int32 nElementSize = pElementTypeDescr->nSize;
115 sal_Int32 i;
116 sal_Bool bRet = sal_False;
118 switch ( pElementTypeRef->eTypeClass )
120 case typelib_TypeClass_CHAR:
121 case typelib_TypeClass_BOOLEAN:
122 case typelib_TypeClass_BYTE:
123 case typelib_TypeClass_SHORT:
124 case typelib_TypeClass_UNSIGNED_SHORT:
125 case typelib_TypeClass_LONG:
126 case typelib_TypeClass_UNSIGNED_LONG:
127 case typelib_TypeClass_HYPER:
128 case typelib_TypeClass_UNSIGNED_HYPER:
129 case typelib_TypeClass_FLOAT:
130 case typelib_TypeClass_DOUBLE:
131 for (i=0; i < nTotalElements; i++)
133 memcpy((sal_Char *)pDest + i * nElementSize,
134 (sal_Char *)pSource + i * nElementSize,
135 nElementSize);
137 bRet = sal_True;
138 break;
139 case typelib_TypeClass_STRING:
140 for (i=0; i < nTotalElements; i++)
142 ::rtl_uString_assign( (rtl_uString **)pDest + i,
143 ((rtl_uString **)pSource)[i] );
145 bRet = sal_True;
146 break;
147 case typelib_TypeClass_TYPE:
148 for (i=0; i < nTotalElements; i++)
150 typelib_TypeDescriptionReference ** pp = (typelib_TypeDescriptionReference **)pDest + i;
151 ::typelib_typedescriptionreference_release( *pp );
152 *pp = *((typelib_TypeDescriptionReference **)pSource + i);
153 TYPE_ACQUIRE( *pp );
155 bRet = sal_True;
156 break;
157 case typelib_TypeClass_ANY:
158 for (i=0; i < nTotalElements; i++)
160 _destructAny( (uno_Any *)pDest + i, release );
161 _copyConstructAny( (uno_Any *)pDest + i, (uno_Any *)pSource + i,
162 pElementTypeRef, pElementTypeDescr, acquire, 0 );
164 bRet = sal_True;
165 break;
166 case typelib_TypeClass_ENUM:
167 for (i=0; i < nTotalElements; i++)
169 *((sal_Int32 *)pDest + i) = *((sal_Int32 *)pSource + i);
171 bRet = sal_True;
172 break;
173 case typelib_TypeClass_STRUCT:
174 case typelib_TypeClass_EXCEPTION:
175 for (i=0; i < nTotalElements; i++)
177 bRet = _assignStruct( (sal_Char *)pDest + i * nElementSize,
178 (sal_Char *)pSource + i * nElementSize,
179 (typelib_CompoundTypeDescription *)pElementTypeDescr,
180 queryInterface, acquire, release );
181 if (! bRet)
182 break;
184 bRet = sal_True;
185 break;
186 case typelib_TypeClass_UNION:
187 for (i=0; i < nTotalElements; i++)
189 _destructUnion( (sal_Char*)pDest + i * nElementSize, pElementTypeDescr, release );
190 _copyConstructUnion( (sal_Char*)pDest + i * nElementSize,
191 (sal_Char*)pSource + i * nElementSize,
192 pElementTypeDescr, acquire, 0 );
194 bRet = sal_True;
195 break;
196 case typelib_TypeClass_SEQUENCE:
197 for (i=0; i < nTotalElements; i++)
199 osl_atomic_increment( &(*((uno_Sequence **)pSource + i))->nRefCount );
200 idestructSequence(
201 *((uno_Sequence **)pDest + i),
202 pElementTypeRef, pElementTypeDescr, release );
203 *((uno_Sequence **)pDest + i) = *((uno_Sequence **)pSource + i);
205 bRet = sal_True;
206 break;
207 case typelib_TypeClass_INTERFACE:
208 for (i=0; i < nTotalElements; i++)
210 _assignInterface(
211 (void **)((sal_Char*)pDest + i * nElementSize),
212 *(void **)((sal_Char*)pSource + i * nElementSize),
213 acquire, release );
215 bRet = sal_True;
216 break;
217 default:
218 OSL_ASSERT(false);
219 break;
222 TYPELIB_DANGER_RELEASE( pElementTypeDescr );
223 return bRet;
225 //--------------------------------------------------------------------------------------------------
226 inline sal_Bool _assignData(
227 void * pDest,
228 typelib_TypeDescriptionReference * pDestType, typelib_TypeDescription * pDestTypeDescr,
229 void * pSource,
230 typelib_TypeDescriptionReference * pSourceType, typelib_TypeDescription * pSourceTypeDescr,
231 uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release )
232 SAL_THROW(())
234 if (pDest == pSource)
235 return _type_equals( pDestType, pSourceType );
237 if (! pSource)
239 _destructData( pDest, pDestType, pDestTypeDescr, release );
240 _defaultConstructData( pDest, pDestType, pDestTypeDescr );
241 return sal_True;
243 while (typelib_TypeClass_ANY == pSourceType->eTypeClass)
245 pSourceTypeDescr = 0;
246 pSourceType = ((uno_Any *)pSource)->pType;
247 pSource = ((uno_Any *)pSource)->pData;
248 if (pDest == pSource)
249 return sal_True;
252 switch (pDestType->eTypeClass)
254 case typelib_TypeClass_VOID:
255 return pSourceType->eTypeClass == typelib_TypeClass_VOID;
256 case typelib_TypeClass_CHAR:
257 switch (pSourceType->eTypeClass)
259 case typelib_TypeClass_CHAR:
260 *(sal_Unicode *)pDest = *(sal_Unicode *)pSource;
261 return sal_True;
262 default:
263 return sal_False;
265 case typelib_TypeClass_BOOLEAN:
266 switch (pSourceType->eTypeClass)
268 case typelib_TypeClass_BOOLEAN:
269 *(sal_Bool *)pDest = (*(sal_Bool *)pSource != sal_False);
270 return sal_True;
271 default:
272 return sal_False;
274 case typelib_TypeClass_BYTE:
275 switch (pSourceType->eTypeClass)
277 case typelib_TypeClass_BYTE:
278 *(sal_Int8 *)pDest = *(sal_Int8 *)pSource;
279 return sal_True;
280 default:
281 return sal_False;
283 case typelib_TypeClass_SHORT:
284 switch (pSourceType->eTypeClass)
286 case typelib_TypeClass_BYTE:
287 *(sal_Int16 *)pDest = *(sal_Int8 *)pSource;
288 return sal_True;
289 case typelib_TypeClass_SHORT:
290 case typelib_TypeClass_UNSIGNED_SHORT:
291 *(sal_Int16 *)pDest = *(sal_Int16 *)pSource;
292 return sal_True;
293 default:
294 return sal_False;
296 case typelib_TypeClass_UNSIGNED_SHORT:
297 switch (pSourceType->eTypeClass)
299 case typelib_TypeClass_BYTE:
300 *(sal_uInt16 *)pDest = *(sal_Int8 *)pSource;
301 return sal_True;
302 case typelib_TypeClass_SHORT:
303 case typelib_TypeClass_UNSIGNED_SHORT:
304 *(sal_uInt16 *)pDest = *(sal_uInt16 *)pSource;
305 return sal_True;
306 default:
307 return sal_False;
309 case typelib_TypeClass_LONG:
310 switch (pSourceType->eTypeClass)
312 case typelib_TypeClass_BYTE:
313 *(sal_Int32 *)pDest = *(sal_Int8 *)pSource;
314 return sal_True;
315 case typelib_TypeClass_SHORT:
316 *(sal_Int32 *)pDest = *(sal_Int16 *)pSource;
317 return sal_True;
318 case typelib_TypeClass_UNSIGNED_SHORT:
319 *(sal_Int32 *)pDest = *(sal_uInt16 *)pSource;
320 return sal_True;
321 case typelib_TypeClass_LONG:
322 case typelib_TypeClass_UNSIGNED_LONG:
323 *(sal_Int32 *)pDest = *(sal_Int32 *)pSource;
324 return sal_True;
325 default:
326 return sal_False;
328 case typelib_TypeClass_UNSIGNED_LONG:
329 switch (pSourceType->eTypeClass)
331 case typelib_TypeClass_BYTE:
332 *(sal_uInt32 *)pDest = *(sal_Int8 *)pSource;
333 return sal_True;
334 case typelib_TypeClass_SHORT:
335 *(sal_uInt32 *)pDest = *(sal_Int16 *)pSource;
336 return sal_True;
337 case typelib_TypeClass_UNSIGNED_SHORT:
338 *(sal_uInt32 *)pDest = *(sal_uInt16 *)pSource;
339 return sal_True;
340 case typelib_TypeClass_LONG:
341 case typelib_TypeClass_UNSIGNED_LONG:
342 *(sal_uInt32 *)pDest = *(sal_uInt32 *)pSource;
343 return sal_True;
344 default:
345 return sal_False;
347 case typelib_TypeClass_HYPER:
348 switch (pSourceType->eTypeClass)
350 case typelib_TypeClass_BYTE:
351 *(sal_Int64 *)pDest = *(sal_Int8 *)pSource;
352 return sal_True;
353 case typelib_TypeClass_SHORT:
354 *(sal_Int64 *)pDest = *(sal_Int16 *)pSource;
355 return sal_True;
356 case typelib_TypeClass_UNSIGNED_SHORT:
357 *(sal_Int64 *)pDest = *(sal_uInt16 *)pSource;
358 return sal_True;
359 case typelib_TypeClass_LONG:
360 *(sal_Int64 *)pDest = *(sal_Int32 *)pSource;
361 return sal_True;
362 case typelib_TypeClass_UNSIGNED_LONG:
363 *(sal_Int64 *)pDest = *(sal_uInt32 *)pSource;
364 return sal_True;
365 case typelib_TypeClass_HYPER:
366 case typelib_TypeClass_UNSIGNED_HYPER:
367 *(sal_Int64 *)pDest = *(sal_Int64 *)pSource;
368 return sal_True;
369 default:
370 return sal_False;
372 case typelib_TypeClass_UNSIGNED_HYPER:
373 switch (pSourceType->eTypeClass)
375 case typelib_TypeClass_BYTE:
376 *(sal_uInt64 *)pDest = *(sal_Int8 *)pSource;
377 return sal_True;
378 case typelib_TypeClass_SHORT:
379 *(sal_uInt64 *)pDest = *(sal_Int16 *)pSource;
380 return sal_True;
381 case typelib_TypeClass_UNSIGNED_SHORT:
382 *(sal_uInt64 *)pDest = *(sal_uInt16 *)pSource;
383 return sal_True;
384 case typelib_TypeClass_LONG:
385 *(sal_uInt64 *)pDest = *(sal_Int32 *)pSource;
386 return sal_True;
387 case typelib_TypeClass_UNSIGNED_LONG:
388 *(sal_uInt64 *)pDest = *(sal_uInt32 *)pSource;
389 return sal_True;
390 case typelib_TypeClass_HYPER:
391 case typelib_TypeClass_UNSIGNED_HYPER:
392 *(sal_uInt64 *)pDest = *(sal_uInt64 *)pSource;
393 return sal_True;
394 default:
395 return sal_False;
397 case typelib_TypeClass_FLOAT:
398 switch (pSourceType->eTypeClass)
400 case typelib_TypeClass_BYTE:
401 *(float *)pDest = *(sal_Int8 *)pSource;
402 return sal_True;
403 case typelib_TypeClass_SHORT:
404 *(float *)pDest = *(sal_Int16 *)pSource;
405 return sal_True;
406 case typelib_TypeClass_UNSIGNED_SHORT:
407 *(float *)pDest = *(sal_uInt16 *)pSource;
408 return sal_True;
409 case typelib_TypeClass_FLOAT:
410 *(float *)pDest = *(float *)pSource;
411 return sal_True;
412 default:
413 return sal_False;
415 case typelib_TypeClass_DOUBLE:
416 switch (pSourceType->eTypeClass)
418 case typelib_TypeClass_BYTE:
419 *(double *)pDest = *(sal_Int8 *)pSource;
420 return sal_True;
421 case typelib_TypeClass_SHORT:
422 *(double *)pDest = *(sal_Int16 *)pSource;
423 return sal_True;
424 case typelib_TypeClass_UNSIGNED_SHORT:
425 *(double *)pDest = *(sal_uInt16 *)pSource;
426 return sal_True;
427 case typelib_TypeClass_LONG:
428 *(double *)pDest = *(sal_Int32 *)pSource;
429 return sal_True;
430 case typelib_TypeClass_UNSIGNED_LONG:
431 *(double *)pDest = *(sal_uInt32 *)pSource;
432 return sal_True;
433 case typelib_TypeClass_FLOAT:
434 *(double *)pDest = *(float *)pSource;
435 return sal_True;
436 case typelib_TypeClass_DOUBLE:
437 *(double *)pDest = *(double *)pSource;
438 return sal_True;
439 default:
440 return sal_False;
442 case typelib_TypeClass_STRING:
443 switch (pSourceType->eTypeClass)
445 case typelib_TypeClass_STRING:
446 ::rtl_uString_assign( (rtl_uString **)pDest, *(rtl_uString **)pSource );
447 return sal_True;
448 default:
449 return sal_False;
451 case typelib_TypeClass_TYPE:
452 switch (pSourceType->eTypeClass)
454 case typelib_TypeClass_TYPE:
456 typelib_TypeDescriptionReference ** pp = (typelib_TypeDescriptionReference **)pDest;
457 ::typelib_typedescriptionreference_release( *pp );
458 *pp = *(typelib_TypeDescriptionReference **)pSource;
459 TYPE_ACQUIRE( *pp );
460 return sal_True;
462 default:
463 return sal_False;
465 case typelib_TypeClass_ANY:
466 _destructAny( (uno_Any *)pDest, release );
467 _copyConstructAny( (uno_Any *)pDest, pSource, pSourceType, pSourceTypeDescr, acquire, 0 );
468 return sal_True;
469 case typelib_TypeClass_ENUM:
470 if (_type_equals( pDestType, pSourceType ))
472 *(sal_Int32 *)pDest = *(sal_Int32 *)pSource;
473 return sal_True;
475 return sal_False;
476 case typelib_TypeClass_STRUCT:
477 case typelib_TypeClass_EXCEPTION:
478 if (typelib_TypeClass_STRUCT == pSourceType->eTypeClass ||
479 typelib_TypeClass_EXCEPTION == pSourceType->eTypeClass)
481 sal_Bool bRet = sal_False;
482 if (pSourceTypeDescr)
484 typelib_CompoundTypeDescription * pTypeDescr =
485 (typelib_CompoundTypeDescription *)pSourceTypeDescr;
486 while (pTypeDescr &&
487 !_type_equals(
488 ((typelib_TypeDescription *)pTypeDescr)->pWeakRef, pDestType ))
490 pTypeDescr = pTypeDescr->pBaseTypeDescription;
492 if (pTypeDescr)
494 bRet = _assignStruct(
495 pDest, pSource, pTypeDescr, queryInterface, acquire, release );
498 else
500 TYPELIB_DANGER_GET( &pSourceTypeDescr, pSourceType );
501 typelib_CompoundTypeDescription * pTypeDescr =
502 (typelib_CompoundTypeDescription *)pSourceTypeDescr;
503 while (pTypeDescr &&
504 !_type_equals(
505 ((typelib_TypeDescription *)pTypeDescr)->pWeakRef, pDestType ))
507 pTypeDescr = pTypeDescr->pBaseTypeDescription;
509 if (pTypeDescr)
511 bRet = _assignStruct(
512 pDest, pSource, pTypeDescr, queryInterface, acquire, release );
514 TYPELIB_DANGER_RELEASE( pSourceTypeDescr );
516 return bRet;
518 return sal_False;
519 case typelib_TypeClass_ARRAY:
521 sal_Bool bRet = sal_False;
522 if (pSourceTypeDescr)
524 typelib_ArrayTypeDescription * pTypeDescr =
525 (typelib_ArrayTypeDescription *)pSourceTypeDescr;
526 bRet = _assignArray( pDest, pSource, pTypeDescr, queryInterface, acquire, release );
528 else
530 TYPELIB_DANGER_GET( &pSourceTypeDescr, pSourceType );
531 typelib_ArrayTypeDescription * pTypeDescr =
532 (typelib_ArrayTypeDescription *)pSourceTypeDescr;
533 if ( pTypeDescr )
535 bRet = _assignArray(
536 pDest, pSource, pTypeDescr, queryInterface, acquire, release );
538 TYPELIB_DANGER_RELEASE( pSourceTypeDescr );
540 return bRet;
542 case typelib_TypeClass_UNION:
543 if (_type_equals( pDestType, pSourceType ))
545 if (pDestTypeDescr)
547 _destructUnion( pDest, pDestTypeDescr, release );
548 _copyConstructUnion( pDest, pSource, pDestTypeDescr, acquire, 0 );
550 else
552 TYPELIB_DANGER_GET( &pDestTypeDescr, pDestType );
553 _destructUnion( pDest, pDestTypeDescr, release );
554 _copyConstructUnion( pDest, pSource, pDestTypeDescr, acquire, 0 );
555 TYPELIB_DANGER_RELEASE( pDestTypeDescr );
557 return sal_True;
559 return sal_False;
560 case typelib_TypeClass_SEQUENCE:
561 if (typelib_TypeClass_SEQUENCE != pSourceType->eTypeClass)
562 return sal_False;
563 // self assignment:
564 if (*(uno_Sequence **)pSource == *(uno_Sequence **)pDest)
565 return sal_True;
566 if (_type_equals( pDestType, pSourceType ))
568 osl_atomic_increment( &(*(uno_Sequence **)pSource)->nRefCount );
569 idestructSequence(
570 *(uno_Sequence **)pDest, pDestType, pDestTypeDescr, release );
571 *(uno_Sequence **)pDest = *(uno_Sequence **)pSource;
572 return sal_True;
574 return sal_False;
575 case typelib_TypeClass_INTERFACE:
576 if (typelib_TypeClass_INTERFACE != pSourceType->eTypeClass)
577 return sal_False;
578 if (_type_equals( pDestType, pSourceType ))
580 _assignInterface( (void **)pDest, *(void **)pSource, acquire, release );
581 return sal_True;
583 else if (*static_cast< void ** >(pSource) == 0)
585 // A null reference of any interface type can be converted to a null
586 // reference of any other interface type:
587 void * const pToBeReleased = *static_cast< void ** >(pDest);
588 *static_cast< void ** >(pDest) = 0;
589 _release( pToBeReleased, release );
590 return true;
592 else
594 if (pSourceTypeDescr)
596 typelib_TypeDescription * pTD = pSourceTypeDescr;
597 while (pTD && !_type_equals( pTD->pWeakRef, pDestType ))
599 pTD = (typelib_TypeDescription *)
600 ((typelib_InterfaceTypeDescription *)pTD)->pBaseTypeDescription;
602 if (pTD) // is base of dest
604 _assignInterface( (void **)pDest, *(void **)pSource, acquire, release );
605 return true;
609 // query for interface:
610 void * pQueried = _queryInterface( *static_cast<void **>(pSource),
611 pDestType, queryInterface );
612 if (pQueried != 0) {
613 void * const pToBeReleased = *static_cast<void **>(pDest);
614 *static_cast<void **>(pDest) = pQueried;
615 _release( pToBeReleased, release );
617 return (pQueried != 0);
619 default:
620 OSL_ASSERT(false);
621 return sal_False;
627 #endif
629 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */