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