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