xref: /AOO41X/main/cppu/source/uno/assign.hxx (revision c6ed87c9b37761ea466ee21111c4a4a314092829)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 #ifndef ASSIGN_HXX
24 #define ASSIGN_HXX
25 
26 #include "prim.hxx"
27 #include "destr.hxx"
28 #include "constr.hxx"
29 #include "copy.hxx"
30 
31 
32 namespace cppu
33 {
34 
35 //##################################################################################################
36 //#### assignment ##################################################################################
37 //##################################################################################################
38 
39 
40 //--------------------------------------------------------------------------------------------------
_assignInterface(void ** ppDest,void * pSource,uno_AcquireFunc acquire,uno_ReleaseFunc release)41 inline void _assignInterface(
42     void ** ppDest, void * pSource,
43     uno_AcquireFunc acquire, uno_ReleaseFunc release )
44     SAL_THROW( () )
45 {
46     _acquire( pSource, acquire );
47     void * const pToBeReleased = *ppDest;
48     *ppDest = pSource;
49     _release( pToBeReleased, release );
50 }
51 //--------------------------------------------------------------------------------------------------
_queryInterface(void * pSource,typelib_TypeDescriptionReference * pDestType,uno_QueryInterfaceFunc queryInterface)52 inline void * _queryInterface(
53     void * pSource,
54     typelib_TypeDescriptionReference * pDestType,
55     uno_QueryInterfaceFunc queryInterface )
56     SAL_THROW( () )
57 {
58     if (pSource)
59     {
60         if (0 == queryInterface)
61             queryInterface = binuno_queryInterface;
62         pSource = (*queryInterface)( pSource, pDestType );
63     }
64     return pSource;
65 }
66 //==================================================================================================
67 sal_Bool assignStruct(
68     void * pDest, void * pSource,
69     typelib_CompoundTypeDescription * pTypeDescr,
70     uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release )
71     SAL_THROW( () );
72 //--------------------------------------------------------------------------------------------------
_assignStruct(void * pDest,void * pSource,typelib_CompoundTypeDescription * pTypeDescr,uno_QueryInterfaceFunc queryInterface,uno_AcquireFunc acquire,uno_ReleaseFunc release)73 inline sal_Bool _assignStruct(
74     void * pDest, void * pSource,
75     typelib_CompoundTypeDescription * pTypeDescr,
76     uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release )
77     SAL_THROW( () )
78 {
79     if (pTypeDescr->pBaseTypeDescription)
80     {
81         // copy base value
82         if (! assignStruct( pDest, pSource, pTypeDescr->pBaseTypeDescription,
83                             queryInterface, acquire, release ))
84         {
85             return sal_False;
86         }
87     }
88     // then copy members
89     typelib_TypeDescriptionReference ** ppTypeRefs = pTypeDescr->ppTypeRefs;
90     sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets;
91     sal_Int32 nDescr = pTypeDescr->nMembers;
92     while (nDescr--)
93     {
94         if (! ::uno_type_assignData( (char *)pDest + pMemberOffsets[nDescr],
95                                      ppTypeRefs[nDescr],
96                                      (char *)pSource + pMemberOffsets[nDescr],
97                                      ppTypeRefs[nDescr],
98                                      queryInterface, acquire, release ))
99         {
100             return sal_False;
101         }
102     }
103     return sal_True;
104 }
105 //--------------------------------------------------------------------------------------------------
_assignArray(void * pDest,void * pSource,typelib_ArrayTypeDescription * pTypeDescr,uno_QueryInterfaceFunc queryInterface,uno_AcquireFunc acquire,uno_ReleaseFunc release)106 inline sal_Bool _assignArray(
107     void * pDest, void * pSource,
108     typelib_ArrayTypeDescription * pTypeDescr,
109     uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release )
110 {
111     typelib_TypeDescriptionReference * pElementTypeRef =
112         ((typelib_IndirectTypeDescription *)pTypeDescr)->pType;
113     typelib_TypeDescription * pElementTypeDescr = NULL;
114     TYPELIB_DANGER_GET( &pElementTypeDescr, pElementTypeRef );
115     sal_Int32 nTotalElements = pTypeDescr->nTotalElements;
116     sal_Int32 nElementSize = pElementTypeDescr->nSize;
117     sal_Int32 i;
118     sal_Bool bRet = sal_False;
119 
120     switch ( pElementTypeRef->eTypeClass )
121     {
122     case typelib_TypeClass_CHAR:
123     case typelib_TypeClass_BOOLEAN:
124     case typelib_TypeClass_BYTE:
125     case typelib_TypeClass_SHORT:
126     case typelib_TypeClass_UNSIGNED_SHORT:
127     case typelib_TypeClass_LONG:
128     case typelib_TypeClass_UNSIGNED_LONG:
129     case typelib_TypeClass_HYPER:
130     case typelib_TypeClass_UNSIGNED_HYPER:
131     case typelib_TypeClass_FLOAT:
132     case typelib_TypeClass_DOUBLE:
133         for (i=0; i < nTotalElements; i++)
134         {
135             ::rtl_copyMemory((sal_Char *)pDest + i * nElementSize,
136                              (sal_Char *)pSource + i * nElementSize,
137                              nElementSize);
138         }
139         bRet = sal_True;
140         break;
141     case typelib_TypeClass_STRING:
142         for (i=0; i < nTotalElements; i++)
143         {
144             ::rtl_uString_assign( (rtl_uString **)pDest + i,
145                                   ((rtl_uString **)pSource)[i] );
146         }
147         bRet = sal_True;
148         break;
149     case typelib_TypeClass_TYPE:
150         for (i=0; i < nTotalElements; i++)
151         {
152             typelib_TypeDescriptionReference ** pp = (typelib_TypeDescriptionReference **)pDest + i;
153             ::typelib_typedescriptionreference_release( *pp );
154             *pp = *((typelib_TypeDescriptionReference **)pSource + i);
155             TYPE_ACQUIRE( *pp );
156         }
157         bRet = sal_True;
158         break;
159     case typelib_TypeClass_ANY:
160         for (i=0; i < nTotalElements; i++)
161         {
162             _destructAny( (uno_Any *)pDest + i, release );
163             _copyConstructAny( (uno_Any *)pDest + i, (uno_Any *)pSource + i,
164                                pElementTypeRef, pElementTypeDescr, acquire, 0 );
165         }
166         bRet = sal_True;
167         break;
168     case typelib_TypeClass_ENUM:
169         for (i=0; i < nTotalElements; i++)
170         {
171             *((sal_Int32 *)pDest + i) = *((sal_Int32 *)pSource + i);
172         }
173         bRet = sal_True;
174         break;
175     case typelib_TypeClass_STRUCT:
176     case typelib_TypeClass_EXCEPTION:
177         for (i=0; i < nTotalElements; i++)
178         {
179             bRet = _assignStruct( (sal_Char *)pDest + i * nElementSize,
180                                   (sal_Char *)pSource + i * nElementSize,
181                                   (typelib_CompoundTypeDescription *)pElementTypeDescr,
182                                   queryInterface, acquire, release );
183             if (! bRet)
184                 break;
185         }
186         bRet = sal_True;
187         break;
188     case typelib_TypeClass_UNION:
189         for (i=0; i < nTotalElements; i++)
190         {
191             _destructUnion( (sal_Char*)pDest + i * nElementSize, pElementTypeDescr, release );
192             _copyConstructUnion( (sal_Char*)pDest + i * nElementSize,
193                                  (sal_Char*)pSource + i * nElementSize,
194                                  pElementTypeDescr, acquire, 0 );
195         }
196         bRet = sal_True;
197         break;
198     case typelib_TypeClass_SEQUENCE:
199         for (i=0; i < nTotalElements; i++)
200         {
201             ::osl_incrementInterlockedCount(
202                 &(*((uno_Sequence **)pSource + i))->nRefCount );
203             idestructSequence(
204                 *((uno_Sequence **)pDest + i),
205                 pElementTypeRef, pElementTypeDescr, release );
206             *((uno_Sequence **)pDest + i) = *((uno_Sequence **)pSource + i);
207         }
208         bRet = sal_True;
209         break;
210     case typelib_TypeClass_INTERFACE:
211         for (i=0; i < nTotalElements; i++)
212         {
213             _assignInterface(
214                 (void **)((sal_Char*)pDest + i * nElementSize),
215                 *(void **)((sal_Char*)pSource + i * nElementSize),
216                 acquire, release );
217         }
218         bRet = sal_True;
219         break;
220     default:
221         OSL_ASSERT(false);
222         break;
223     }
224 
225     TYPELIB_DANGER_RELEASE( pElementTypeDescr );
226     return bRet;
227 }
228 //--------------------------------------------------------------------------------------------------
_assignData(void * pDest,typelib_TypeDescriptionReference * pDestType,typelib_TypeDescription * pDestTypeDescr,void * pSource,typelib_TypeDescriptionReference * pSourceType,typelib_TypeDescription * pSourceTypeDescr,uno_QueryInterfaceFunc queryInterface,uno_AcquireFunc acquire,uno_ReleaseFunc release)229 inline sal_Bool _assignData(
230     void * pDest,
231     typelib_TypeDescriptionReference * pDestType, typelib_TypeDescription * pDestTypeDescr,
232     void * pSource,
233     typelib_TypeDescriptionReference * pSourceType, typelib_TypeDescription * pSourceTypeDescr,
234     uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release )
235     SAL_THROW( () )
236 {
237     if (pDest == pSource)
238         return _type_equals( pDestType, pSourceType );
239 
240     if (! pSource)
241     {
242         _destructData( pDest, pDestType, pDestTypeDescr, release );
243         _defaultConstructData( pDest, pDestType, pDestTypeDescr );
244         return sal_True;
245     }
246     while (typelib_TypeClass_ANY == pSourceType->eTypeClass)
247     {
248         pSourceTypeDescr = 0;
249         pSourceType = ((uno_Any *)pSource)->pType;
250         pSource = ((uno_Any *)pSource)->pData;
251         if (pDest == pSource)
252             return sal_True;
253     }
254 
255     switch (pDestType->eTypeClass)
256     {
257     case typelib_TypeClass_VOID:
258         return pSourceType->eTypeClass == typelib_TypeClass_VOID;
259     case typelib_TypeClass_CHAR:
260         switch (pSourceType->eTypeClass)
261         {
262         case typelib_TypeClass_CHAR:
263             *(sal_Unicode *)pDest = *(sal_Unicode *)pSource;
264             return sal_True;
265         default:
266             return sal_False;
267         }
268     case typelib_TypeClass_BOOLEAN:
269         switch (pSourceType->eTypeClass)
270         {
271         case typelib_TypeClass_BOOLEAN:
272             *(sal_Bool *)pDest = (*(sal_Bool *)pSource != sal_False);
273             return sal_True;
274         default:
275             return sal_False;
276         }
277     case typelib_TypeClass_BYTE:
278         switch (pSourceType->eTypeClass)
279         {
280         case typelib_TypeClass_BYTE:
281             *(sal_Int8 *)pDest = *(sal_Int8 *)pSource;
282             return sal_True;
283         default:
284             return sal_False;
285         }
286     case typelib_TypeClass_SHORT:
287         switch (pSourceType->eTypeClass)
288         {
289         case typelib_TypeClass_BYTE:
290             *(sal_Int16 *)pDest = *(sal_Int8 *)pSource;
291             return sal_True;
292         case typelib_TypeClass_SHORT:
293         case typelib_TypeClass_UNSIGNED_SHORT:
294             *(sal_Int16 *)pDest = *(sal_Int16 *)pSource;
295             return sal_True;
296         default:
297             return sal_False;
298         }
299     case typelib_TypeClass_UNSIGNED_SHORT:
300         switch (pSourceType->eTypeClass)
301         {
302         case typelib_TypeClass_BYTE:
303             *(sal_uInt16 *)pDest = *(sal_Int8 *)pSource;
304             return sal_True;
305         case typelib_TypeClass_SHORT:
306         case typelib_TypeClass_UNSIGNED_SHORT:
307             *(sal_uInt16 *)pDest = *(sal_uInt16 *)pSource;
308             return sal_True;
309         default:
310             return sal_False;
311         }
312     case typelib_TypeClass_LONG:
313         switch (pSourceType->eTypeClass)
314         {
315         case typelib_TypeClass_BYTE:
316             *(sal_Int32 *)pDest = *(sal_Int8 *)pSource;
317             return sal_True;
318         case typelib_TypeClass_SHORT:
319             *(sal_Int32 *)pDest = *(sal_Int16 *)pSource;
320             return sal_True;
321         case typelib_TypeClass_UNSIGNED_SHORT:
322             *(sal_Int32 *)pDest = *(sal_uInt16 *)pSource;
323             return sal_True;
324         case typelib_TypeClass_LONG:
325         case typelib_TypeClass_UNSIGNED_LONG:
326             *(sal_Int32 *)pDest = *(sal_Int32 *)pSource;
327             return sal_True;
328         default:
329             return sal_False;
330         }
331     case typelib_TypeClass_UNSIGNED_LONG:
332         switch (pSourceType->eTypeClass)
333         {
334         case typelib_TypeClass_BYTE:
335             *(sal_uInt32 *)pDest = *(sal_Int8 *)pSource;
336             return sal_True;
337         case typelib_TypeClass_SHORT:
338             *(sal_uInt32 *)pDest = *(sal_Int16 *)pSource;
339             return sal_True;
340         case typelib_TypeClass_UNSIGNED_SHORT:
341             *(sal_uInt32 *)pDest = *(sal_uInt16 *)pSource;
342             return sal_True;
343         case typelib_TypeClass_LONG:
344         case typelib_TypeClass_UNSIGNED_LONG:
345             *(sal_uInt32 *)pDest = *(sal_uInt32 *)pSource;
346             return sal_True;
347         default:
348             return sal_False;
349         }
350     case typelib_TypeClass_HYPER:
351         switch (pSourceType->eTypeClass)
352         {
353         case typelib_TypeClass_BYTE:
354             *(sal_Int64 *)pDest = *(sal_Int8 *)pSource;
355             return sal_True;
356         case typelib_TypeClass_SHORT:
357             *(sal_Int64 *)pDest = *(sal_Int16 *)pSource;
358             return sal_True;
359         case typelib_TypeClass_UNSIGNED_SHORT:
360             *(sal_Int64 *)pDest = *(sal_uInt16 *)pSource;
361             return sal_True;
362         case typelib_TypeClass_LONG:
363             *(sal_Int64 *)pDest = *(sal_Int32 *)pSource;
364             return sal_True;
365         case typelib_TypeClass_UNSIGNED_LONG:
366             *(sal_Int64 *)pDest = *(sal_uInt32 *)pSource;
367             return sal_True;
368         case typelib_TypeClass_HYPER:
369         case typelib_TypeClass_UNSIGNED_HYPER:
370             *(sal_Int64 *)pDest = *(sal_Int64 *)pSource;
371             return sal_True;
372         default:
373             return sal_False;
374         }
375     case typelib_TypeClass_UNSIGNED_HYPER:
376         switch (pSourceType->eTypeClass)
377         {
378         case typelib_TypeClass_BYTE:
379             *(sal_uInt64 *)pDest = *(sal_Int8 *)pSource;
380             return sal_True;
381         case typelib_TypeClass_SHORT:
382             *(sal_uInt64 *)pDest = *(sal_Int16 *)pSource;
383             return sal_True;
384         case typelib_TypeClass_UNSIGNED_SHORT:
385             *(sal_uInt64 *)pDest = *(sal_uInt16 *)pSource;
386             return sal_True;
387         case typelib_TypeClass_LONG:
388             *(sal_uInt64 *)pDest = *(sal_Int32 *)pSource;
389             return sal_True;
390         case typelib_TypeClass_UNSIGNED_LONG:
391             *(sal_uInt64 *)pDest = *(sal_uInt32 *)pSource;
392             return sal_True;
393         case typelib_TypeClass_HYPER:
394         case typelib_TypeClass_UNSIGNED_HYPER:
395             *(sal_uInt64 *)pDest = *(sal_uInt64 *)pSource;
396             return sal_True;
397         default:
398             return sal_False;
399         }
400     case typelib_TypeClass_FLOAT:
401         switch (pSourceType->eTypeClass)
402         {
403         case typelib_TypeClass_BYTE:
404             *(float *)pDest = *(sal_Int8 *)pSource;
405             return sal_True;
406         case typelib_TypeClass_SHORT:
407             *(float *)pDest = *(sal_Int16 *)pSource;
408             return sal_True;
409         case typelib_TypeClass_UNSIGNED_SHORT:
410             *(float *)pDest = *(sal_uInt16 *)pSource;
411             return sal_True;
412         case typelib_TypeClass_FLOAT:
413             *(float *)pDest = *(float *)pSource;
414             return sal_True;
415         default:
416             return sal_False;
417         }
418     case typelib_TypeClass_DOUBLE:
419         switch (pSourceType->eTypeClass)
420         {
421         case typelib_TypeClass_BYTE:
422             *(double *)pDest = *(sal_Int8 *)pSource;
423             return sal_True;
424         case typelib_TypeClass_SHORT:
425             *(double *)pDest = *(sal_Int16 *)pSource;
426             return sal_True;
427         case typelib_TypeClass_UNSIGNED_SHORT:
428             *(double *)pDest = *(sal_uInt16 *)pSource;
429             return sal_True;
430         case typelib_TypeClass_LONG:
431             *(double *)pDest = *(sal_Int32 *)pSource;
432             return sal_True;
433         case typelib_TypeClass_UNSIGNED_LONG:
434             *(double *)pDest = *(sal_uInt32 *)pSource;
435             return sal_True;
436         case typelib_TypeClass_FLOAT:
437             *(double *)pDest = *(float *)pSource;
438             return sal_True;
439         case typelib_TypeClass_DOUBLE:
440             *(double *)pDest = *(double *)pSource;
441             return sal_True;
442         default:
443             return sal_False;
444         }
445     case typelib_TypeClass_STRING:
446         switch (pSourceType->eTypeClass)
447         {
448         case typelib_TypeClass_STRING:
449             ::rtl_uString_assign( (rtl_uString **)pDest, *(rtl_uString **)pSource );
450             return sal_True;
451         default:
452             return sal_False;
453         }
454     case typelib_TypeClass_TYPE:
455         switch (pSourceType->eTypeClass)
456         {
457         case typelib_TypeClass_TYPE:
458         {
459             typelib_TypeDescriptionReference ** pp = (typelib_TypeDescriptionReference **)pDest;
460             ::typelib_typedescriptionreference_release( *pp );
461             *pp = *(typelib_TypeDescriptionReference **)pSource;
462             TYPE_ACQUIRE( *pp );
463             return sal_True;
464         }
465         default:
466             return sal_False;
467         }
468     case typelib_TypeClass_ANY:
469         _destructAny( (uno_Any *)pDest, release );
470         _copyConstructAny( (uno_Any *)pDest, pSource, pSourceType, pSourceTypeDescr, acquire, 0 );
471         return sal_True;
472     case typelib_TypeClass_ENUM:
473         if (_type_equals( pDestType, pSourceType ))
474         {
475             *(sal_Int32 *)pDest = *(sal_Int32 *)pSource;
476             return sal_True;
477         }
478         return sal_False;
479     case typelib_TypeClass_STRUCT:
480     case typelib_TypeClass_EXCEPTION:
481         if (typelib_TypeClass_STRUCT == pSourceType->eTypeClass ||
482             typelib_TypeClass_EXCEPTION == pSourceType->eTypeClass)
483         {
484             sal_Bool bRet = sal_False;
485             if (pSourceTypeDescr)
486             {
487                 typelib_CompoundTypeDescription * pTypeDescr =
488                     (typelib_CompoundTypeDescription *)pSourceTypeDescr;
489                 while (pTypeDescr &&
490                        !_type_equals(
491                            ((typelib_TypeDescription *)pTypeDescr)->pWeakRef, pDestType ))
492                 {
493                     pTypeDescr = pTypeDescr->pBaseTypeDescription;
494                 }
495                 if (pTypeDescr)
496                 {
497                     bRet = _assignStruct(
498                         pDest, pSource, pTypeDescr, queryInterface, acquire, release );
499                 }
500             }
501             else
502             {
503                 TYPELIB_DANGER_GET( &pSourceTypeDescr, pSourceType );
504                 typelib_CompoundTypeDescription * pTypeDescr =
505                     (typelib_CompoundTypeDescription *)pSourceTypeDescr;
506                 while (pTypeDescr &&
507                        !_type_equals(
508                            ((typelib_TypeDescription *)pTypeDescr)->pWeakRef, pDestType ))
509                 {
510                     pTypeDescr = pTypeDescr->pBaseTypeDescription;
511                 }
512                 if (pTypeDescr)
513                 {
514                     bRet = _assignStruct(
515                         pDest, pSource, pTypeDescr, queryInterface, acquire, release );
516                 }
517                 TYPELIB_DANGER_RELEASE( pSourceTypeDescr );
518             }
519             return bRet;
520         }
521         return sal_False;
522     case typelib_TypeClass_ARRAY:
523         {
524             sal_Bool bRet = sal_False;
525             if (pSourceTypeDescr)
526             {
527                 typelib_ArrayTypeDescription * pTypeDescr =
528                     (typelib_ArrayTypeDescription *)pSourceTypeDescr;
529                 bRet = _assignArray( pDest, pSource, pTypeDescr, queryInterface, acquire, release );
530             }
531             else
532             {
533                 TYPELIB_DANGER_GET( &pSourceTypeDescr, pSourceType );
534                 typelib_ArrayTypeDescription * pTypeDescr =
535                     (typelib_ArrayTypeDescription *)pSourceTypeDescr;
536                 if ( pTypeDescr )
537                 {
538                     bRet = _assignArray(
539                         pDest, pSource, pTypeDescr, queryInterface, acquire, release );
540                 }
541                 TYPELIB_DANGER_RELEASE( pSourceTypeDescr );
542             }
543             return bRet;
544         }
545     case typelib_TypeClass_UNION:
546         if (_type_equals( pDestType, pSourceType ))
547         {
548             if (pDestTypeDescr)
549             {
550                 _destructUnion( pDest, pDestTypeDescr, release );
551                 _copyConstructUnion( pDest, pSource, pDestTypeDescr, acquire, 0 );
552             }
553             else
554             {
555                 TYPELIB_DANGER_GET( &pDestTypeDescr, pDestType );
556                 _destructUnion( pDest, pDestTypeDescr, release );
557                 _copyConstructUnion( pDest, pSource, pDestTypeDescr, acquire, 0 );
558                 TYPELIB_DANGER_RELEASE( pDestTypeDescr );
559             }
560             return sal_True;
561         }
562         return sal_False;
563     case typelib_TypeClass_SEQUENCE:
564         if (typelib_TypeClass_SEQUENCE != pSourceType->eTypeClass)
565             return sal_False;
566         // self assignment:
567         if (*(uno_Sequence **)pSource == *(uno_Sequence **)pDest)
568             return sal_True;
569         if (_type_equals( pDestType, pSourceType ))
570         {
571             ::osl_incrementInterlockedCount(
572                 &(*(uno_Sequence **)pSource)->nRefCount );
573             idestructSequence(
574                 *(uno_Sequence **)pDest, pDestType, pDestTypeDescr, release );
575             *(uno_Sequence **)pDest = *(uno_Sequence **)pSource;
576             return sal_True;
577         }
578         return sal_False;
579     case typelib_TypeClass_INTERFACE:
580         if (typelib_TypeClass_INTERFACE != pSourceType->eTypeClass)
581             return sal_False;
582         if (_type_equals( pDestType, pSourceType ))
583         {
584             _assignInterface( (void **)pDest, *(void **)pSource, acquire, release );
585             return sal_True;
586         }
587         else if (*static_cast< void ** >(pSource) == 0)
588         {
589             // A null reference of any interface type can be converted to a null
590             // reference of any other interface type:
591             void * const pToBeReleased = *static_cast< void ** >(pDest);
592             *static_cast< void ** >(pDest) = 0;
593             _release( pToBeReleased, release );
594             return true;
595         }
596         else
597         {
598             if (pSourceTypeDescr)
599             {
600                 typelib_TypeDescription * pTD = pSourceTypeDescr;
601                 while (pTD && !_type_equals( pTD->pWeakRef, pDestType ))
602                 {
603                     pTD = (typelib_TypeDescription *)
604                         ((typelib_InterfaceTypeDescription *)pTD)->pBaseTypeDescription;
605                 }
606                 if (pTD) // is base of dest
607                 {
608                     _assignInterface( (void **)pDest, *(void **)pSource, acquire, release );
609                     return true;
610                 }
611             }
612 
613             // query for interface:
614             void * pQueried = _queryInterface( *static_cast<void **>(pSource),
615                                                pDestType, queryInterface );
616             if (pQueried != 0) {
617                 void * const pToBeReleased = *static_cast<void **>(pDest);
618                 *static_cast<void **>(pDest) = pQueried;
619                 _release( pToBeReleased, release );
620             }
621             return (pQueried != 0);
622         }
623     default:
624         OSL_ASSERT(false);
625         return sal_False;
626     }
627 }
628 
629 }
630 
631 #endif
632