bump product version to 5.0.4.1
[LibreOffice.git] / cppu / source / uno / assign.hxx
blobcd4b21b0041418ac68061e3afbc919d1f7b7e86c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 #ifndef INCLUDED_CPPU_SOURCE_UNO_ASSIGN_HXX
20 #define INCLUDED_CPPU_SOURCE_UNO_ASSIGN_HXX
22 #include <string.h>
24 #include "prim.hxx"
25 #include "destr.hxx"
26 #include "constr.hxx"
27 #include "copy.hxx"
30 namespace cppu
34 //#### assignment ##################################################################################
39 inline void _assignInterface(
40 void ** ppDest, void * pSource,
41 uno_AcquireFunc acquire, uno_ReleaseFunc release )
44 _acquire( pSource, acquire );
45 void * const pToBeReleased = *ppDest;
46 *ppDest = pSource;
47 _release( pToBeReleased, release );
50 inline void * _queryInterface(
51 void * pSource,
52 typelib_TypeDescriptionReference * pDestType,
53 uno_QueryInterfaceFunc queryInterface )
55 if (pSource)
57 if (0 == queryInterface)
58 queryInterface = binuno_queryInterface;
59 pSource = (*queryInterface)( pSource, pDestType );
61 return pSource;
64 bool assignStruct(
65 void * pDest, void * pSource,
66 typelib_CompoundTypeDescription * pTypeDescr,
67 uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release );
69 inline bool _assignStruct(
70 void * pDest, void * pSource,
71 typelib_CompoundTypeDescription * pTypeDescr,
72 uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release )
74 if (pTypeDescr->pBaseTypeDescription)
76 // copy base value
77 if (! assignStruct( pDest, pSource, pTypeDescr->pBaseTypeDescription,
78 queryInterface, acquire, release ))
80 return false;
83 // then copy members
84 typelib_TypeDescriptionReference ** ppTypeRefs = pTypeDescr->ppTypeRefs;
85 sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets;
86 sal_Int32 nDescr = pTypeDescr->nMembers;
87 while (nDescr--)
89 if (! ::uno_type_assignData( static_cast<char *>(pDest) + pMemberOffsets[nDescr],
90 ppTypeRefs[nDescr],
91 static_cast<char *>(pSource) + pMemberOffsets[nDescr],
92 ppTypeRefs[nDescr],
93 queryInterface, acquire, release ))
95 return false;
98 return true;
101 inline bool _assignData(
102 void * pDest,
103 typelib_TypeDescriptionReference * pDestType, typelib_TypeDescription * pDestTypeDescr,
104 void * pSource,
105 typelib_TypeDescriptionReference * pSourceType, typelib_TypeDescription * pSourceTypeDescr,
106 uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release )
108 if (pDest == pSource)
109 return _type_equals( pDestType, pSourceType );
111 if (! pSource)
113 _destructData( pDest, pDestType, pDestTypeDescr, release );
114 _defaultConstructData( pDest, pDestType, pDestTypeDescr );
115 return true;
117 while (typelib_TypeClass_ANY == pSourceType->eTypeClass)
119 pSourceTypeDescr = 0;
120 pSourceType = static_cast<uno_Any *>(pSource)->pType;
121 pSource = static_cast<uno_Any *>(pSource)->pData;
122 if (pDest == pSource)
123 return true;
126 switch (pDestType->eTypeClass)
128 case typelib_TypeClass_VOID:
129 return pSourceType->eTypeClass == typelib_TypeClass_VOID;
130 case typelib_TypeClass_CHAR:
131 switch (pSourceType->eTypeClass)
133 case typelib_TypeClass_CHAR:
134 *static_cast<sal_Unicode *>(pDest) = *static_cast<sal_Unicode *>(pSource);
135 return true;
136 default:
137 return false;
139 case typelib_TypeClass_BOOLEAN:
140 switch (pSourceType->eTypeClass)
142 case typelib_TypeClass_BOOLEAN:
143 *static_cast<sal_Bool *>(pDest) = (*static_cast<sal_Bool *>(pSource) != sal_False);
144 return true;
145 default:
146 return false;
148 case typelib_TypeClass_BYTE:
149 switch (pSourceType->eTypeClass)
151 case typelib_TypeClass_BYTE:
152 *static_cast<sal_Int8 *>(pDest) = *static_cast<sal_Int8 *>(pSource);
153 return true;
154 default:
155 return false;
157 case typelib_TypeClass_SHORT:
158 switch (pSourceType->eTypeClass)
160 case typelib_TypeClass_BYTE:
161 *static_cast<sal_Int16 *>(pDest) = *static_cast<sal_Int8 *>(pSource);
162 return true;
163 case typelib_TypeClass_SHORT:
164 case typelib_TypeClass_UNSIGNED_SHORT:
165 *static_cast<sal_Int16 *>(pDest) = *static_cast<sal_Int16 *>(pSource);
166 return true;
167 default:
168 return false;
170 case typelib_TypeClass_UNSIGNED_SHORT:
171 switch (pSourceType->eTypeClass)
173 case typelib_TypeClass_BYTE:
174 *static_cast<sal_uInt16 *>(pDest) = *static_cast<sal_Int8 *>(pSource);
175 return true;
176 case typelib_TypeClass_SHORT:
177 case typelib_TypeClass_UNSIGNED_SHORT:
178 *static_cast<sal_uInt16 *>(pDest) = *static_cast<sal_uInt16 *>(pSource);
179 return true;
180 default:
181 return false;
183 case typelib_TypeClass_LONG:
184 switch (pSourceType->eTypeClass)
186 case typelib_TypeClass_BYTE:
187 *static_cast<sal_Int32 *>(pDest) = *static_cast<sal_Int8 *>(pSource);
188 return true;
189 case typelib_TypeClass_SHORT:
190 *static_cast<sal_Int32 *>(pDest) = *static_cast<sal_Int16 *>(pSource);
191 return true;
192 case typelib_TypeClass_UNSIGNED_SHORT:
193 *static_cast<sal_Int32 *>(pDest) = *static_cast<sal_uInt16 *>(pSource);
194 return true;
195 case typelib_TypeClass_LONG:
196 case typelib_TypeClass_UNSIGNED_LONG:
197 *static_cast<sal_Int32 *>(pDest) = *static_cast<sal_Int32 *>(pSource);
198 return true;
199 default:
200 return false;
202 case typelib_TypeClass_UNSIGNED_LONG:
203 switch (pSourceType->eTypeClass)
205 case typelib_TypeClass_BYTE:
206 *static_cast<sal_uInt32 *>(pDest) = *static_cast<sal_Int8 *>(pSource);
207 return true;
208 case typelib_TypeClass_SHORT:
209 *static_cast<sal_uInt32 *>(pDest) = *static_cast<sal_Int16 *>(pSource);
210 return true;
211 case typelib_TypeClass_UNSIGNED_SHORT:
212 *static_cast<sal_uInt32 *>(pDest) = *static_cast<sal_uInt16 *>(pSource);
213 return true;
214 case typelib_TypeClass_LONG:
215 case typelib_TypeClass_UNSIGNED_LONG:
216 *static_cast<sal_uInt32 *>(pDest) = *static_cast<sal_uInt32 *>(pSource);
217 return true;
218 default:
219 return false;
221 case typelib_TypeClass_HYPER:
222 switch (pSourceType->eTypeClass)
224 case typelib_TypeClass_BYTE:
225 *static_cast<sal_Int64 *>(pDest) = *static_cast<sal_Int8 *>(pSource);
226 return true;
227 case typelib_TypeClass_SHORT:
228 *static_cast<sal_Int64 *>(pDest) = *static_cast<sal_Int16 *>(pSource);
229 return true;
230 case typelib_TypeClass_UNSIGNED_SHORT:
231 *static_cast<sal_Int64 *>(pDest) = *static_cast<sal_uInt16 *>(pSource);
232 return true;
233 case typelib_TypeClass_LONG:
234 *static_cast<sal_Int64 *>(pDest) = *static_cast<sal_Int32 *>(pSource);
235 return true;
236 case typelib_TypeClass_UNSIGNED_LONG:
237 *static_cast<sal_Int64 *>(pDest) = *static_cast<sal_uInt32 *>(pSource);
238 return true;
239 case typelib_TypeClass_HYPER:
240 case typelib_TypeClass_UNSIGNED_HYPER:
241 *static_cast<sal_Int64 *>(pDest) = *static_cast<sal_Int64 *>(pSource);
242 return true;
243 default:
244 return false;
246 case typelib_TypeClass_UNSIGNED_HYPER:
247 switch (pSourceType->eTypeClass)
249 case typelib_TypeClass_BYTE:
250 *static_cast<sal_uInt64 *>(pDest) = *static_cast<sal_Int8 *>(pSource);
251 return true;
252 case typelib_TypeClass_SHORT:
253 *static_cast<sal_uInt64 *>(pDest) = *static_cast<sal_Int16 *>(pSource);
254 return true;
255 case typelib_TypeClass_UNSIGNED_SHORT:
256 *static_cast<sal_uInt64 *>(pDest) = *static_cast<sal_uInt16 *>(pSource);
257 return true;
258 case typelib_TypeClass_LONG:
259 *static_cast<sal_uInt64 *>(pDest) = *static_cast<sal_Int32 *>(pSource);
260 return true;
261 case typelib_TypeClass_UNSIGNED_LONG:
262 *static_cast<sal_uInt64 *>(pDest) = *static_cast<sal_uInt32 *>(pSource);
263 return true;
264 case typelib_TypeClass_HYPER:
265 case typelib_TypeClass_UNSIGNED_HYPER:
266 *static_cast<sal_uInt64 *>(pDest) = *static_cast<sal_uInt64 *>(pSource);
267 return true;
268 default:
269 return false;
271 case typelib_TypeClass_FLOAT:
272 switch (pSourceType->eTypeClass)
274 case typelib_TypeClass_BYTE:
275 *static_cast<float *>(pDest) = *static_cast<sal_Int8 *>(pSource);
276 return true;
277 case typelib_TypeClass_SHORT:
278 *static_cast<float *>(pDest) = *static_cast<sal_Int16 *>(pSource);
279 return true;
280 case typelib_TypeClass_UNSIGNED_SHORT:
281 *static_cast<float *>(pDest) = *static_cast<sal_uInt16 *>(pSource);
282 return true;
283 case typelib_TypeClass_FLOAT:
284 *static_cast<float *>(pDest) = *static_cast<float *>(pSource);
285 return true;
286 default:
287 return false;
289 case typelib_TypeClass_DOUBLE:
290 switch (pSourceType->eTypeClass)
292 case typelib_TypeClass_BYTE:
293 *static_cast<double *>(pDest) = *static_cast<sal_Int8 *>(pSource);
294 return true;
295 case typelib_TypeClass_SHORT:
296 *static_cast<double *>(pDest) = *static_cast<sal_Int16 *>(pSource);
297 return true;
298 case typelib_TypeClass_UNSIGNED_SHORT:
299 *static_cast<double *>(pDest) = *static_cast<sal_uInt16 *>(pSource);
300 return true;
301 case typelib_TypeClass_LONG:
302 *static_cast<double *>(pDest) = *static_cast<sal_Int32 *>(pSource);
303 return true;
304 case typelib_TypeClass_UNSIGNED_LONG:
305 *static_cast<double *>(pDest) = *static_cast<sal_uInt32 *>(pSource);
306 return true;
307 case typelib_TypeClass_FLOAT:
308 *static_cast<double *>(pDest) = *static_cast<float *>(pSource);
309 return true;
310 case typelib_TypeClass_DOUBLE:
311 *static_cast<double *>(pDest) = *static_cast<double *>(pSource);
312 return true;
313 default:
314 return false;
316 case typelib_TypeClass_STRING:
317 switch (pSourceType->eTypeClass)
319 case typelib_TypeClass_STRING:
320 ::rtl_uString_assign( static_cast<rtl_uString **>(pDest), *static_cast<rtl_uString **>(pSource) );
321 return true;
322 default:
323 return false;
325 case typelib_TypeClass_TYPE:
326 switch (pSourceType->eTypeClass)
328 case typelib_TypeClass_TYPE:
330 typelib_TypeDescriptionReference ** pp = static_cast<typelib_TypeDescriptionReference **>(pDest);
331 ::typelib_typedescriptionreference_release( *pp );
332 *pp = *static_cast<typelib_TypeDescriptionReference **>(pSource);
333 TYPE_ACQUIRE( *pp );
334 return true;
336 default:
337 return false;
339 case typelib_TypeClass_ANY:
340 _destructAny( static_cast<uno_Any *>(pDest), release );
341 _copyConstructAny( static_cast<uno_Any *>(pDest), pSource, pSourceType, pSourceTypeDescr, acquire, 0 );
342 return true;
343 case typelib_TypeClass_ENUM:
344 if (_type_equals( pDestType, pSourceType ))
346 *static_cast<sal_Int32 *>(pDest) = *static_cast<sal_Int32 *>(pSource);
347 return true;
349 return false;
350 case typelib_TypeClass_STRUCT:
351 case typelib_TypeClass_EXCEPTION:
352 if (typelib_TypeClass_STRUCT == pSourceType->eTypeClass ||
353 typelib_TypeClass_EXCEPTION == pSourceType->eTypeClass)
355 bool bRet = false;
356 if (pSourceTypeDescr)
358 typelib_CompoundTypeDescription * pTypeDescr =
359 reinterpret_cast<typelib_CompoundTypeDescription *>(pSourceTypeDescr);
360 while (pTypeDescr &&
361 !_type_equals(pTypeDescr->aBase.pWeakRef, pDestType))
363 pTypeDescr = pTypeDescr->pBaseTypeDescription;
365 if (pTypeDescr)
367 bRet = _assignStruct(
368 pDest, pSource, pTypeDescr, queryInterface, acquire, release );
371 else
373 TYPELIB_DANGER_GET( &pSourceTypeDescr, pSourceType );
374 typelib_CompoundTypeDescription * pTypeDescr =
375 reinterpret_cast<typelib_CompoundTypeDescription *>(pSourceTypeDescr);
376 while (pTypeDescr &&
377 !_type_equals(pTypeDescr->aBase.pWeakRef, pDestType))
379 pTypeDescr = pTypeDescr->pBaseTypeDescription;
381 if (pTypeDescr)
383 bRet = _assignStruct(
384 pDest, pSource, pTypeDescr, queryInterface, acquire, release );
386 TYPELIB_DANGER_RELEASE( pSourceTypeDescr );
388 return bRet;
390 return false;
391 case typelib_TypeClass_SEQUENCE:
392 if (typelib_TypeClass_SEQUENCE != pSourceType->eTypeClass)
393 return false;
394 // self assignment:
395 if (*static_cast<uno_Sequence **>(pSource) == *static_cast<uno_Sequence **>(pDest))
396 return true;
397 if (_type_equals( pDestType, pSourceType ))
399 osl_atomic_increment( &(*static_cast<uno_Sequence **>(pSource))->nRefCount );
400 idestructSequence(
401 *static_cast<uno_Sequence **>(pDest), pDestType, pDestTypeDescr, release );
402 *static_cast<uno_Sequence **>(pDest) = *static_cast<uno_Sequence **>(pSource);
403 return true;
405 return false;
406 case typelib_TypeClass_INTERFACE:
407 if (typelib_TypeClass_INTERFACE != pSourceType->eTypeClass)
408 return false;
409 if (_type_equals( pDestType, pSourceType ))
411 _assignInterface( static_cast<void **>(pDest), *static_cast<void **>(pSource), acquire, release );
412 return true;
414 else if (*static_cast< void ** >(pSource) == 0)
416 // A null reference of any interface type can be converted to a null
417 // reference of any other interface type:
418 void * const pToBeReleased = *static_cast< void ** >(pDest);
419 *static_cast< void ** >(pDest) = 0;
420 _release( pToBeReleased, release );
421 return true;
423 else
425 if (pSourceTypeDescr)
427 typelib_TypeDescription * pTD = pSourceTypeDescr;
428 while (pTD && !_type_equals( pTD->pWeakRef, pDestType ))
430 pTD = &(reinterpret_cast<typelib_InterfaceTypeDescription *>(pTD))->pBaseTypeDescription->aBase;
432 if (pTD) // is base of dest
434 _assignInterface( static_cast<void **>(pDest), *static_cast<void **>(pSource), acquire, release );
435 return true;
439 // query for interface:
440 void * pQueried = _queryInterface( *static_cast<void **>(pSource),
441 pDestType, queryInterface );
442 if (pQueried != 0) {
443 void * const pToBeReleased = *static_cast<void **>(pDest);
444 *static_cast<void **>(pDest) = pQueried;
445 _release( pToBeReleased, release );
447 return (pQueried != 0);
449 default:
450 OSL_ASSERT(false);
451 return false;
457 #endif
459 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */