xref: /aoo41x/main/cppu/source/uno/assign.hxx (revision cdf0e10c)
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