merge the formfield patch from ooo-build
[ooovba.git] / configmgr / source / data / anydata.cxx
blobe92b59faf3a974ee9caf8182712e3e2732fecd83
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: anydata.cxx,v $
10 * $Revision: 1.8 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_configmgr.hxx"
34 #include "anydata.hxx"
35 #include "sequence.hxx"
36 #include "flags.hxx"
37 #include "typeconverter.hxx"
39 namespace configmgr
41 //-----------------------------------------------------------------------------
42 namespace sharable
44 //-----------------------------------------------------------------------------
45 namespace Type = data::Type;
46 namespace uno = ::com::sun::star::uno;
47 //-----------------------------------------------------------------------------
49 sal_uInt8 getTypeCode(uno::Type const & _aType)
51 switch (_aType.getTypeClass())
53 case uno::TypeClass_ANY:
54 case uno::TypeClass_VOID:
55 return Type::value_any;
57 case uno::TypeClass_STRING:
58 return Type::value_string;
60 case uno::TypeClass_BOOLEAN:
61 return Type::value_boolean;
63 case uno::TypeClass_SHORT:
64 return Type::value_short;
66 case uno::TypeClass_LONG:
67 return Type::value_int;
69 case uno::TypeClass_HYPER:
70 return Type::value_long;
72 case uno::TypeClass_FLOAT:
73 case uno::TypeClass_DOUBLE:
74 return Type::value_double;
76 case uno::TypeClass_SEQUENCE:
78 uno::Type aElementType = getSequenceElementType(_aType);
80 if (aElementType.getTypeClass() == uno::TypeClass_BYTE)
81 return Type::value_binary;
83 OSL_ASSERT(aElementType != _aType); // would cause infinite recursion
84 sal_uInt8 aElementTC = getTypeCode(aElementType);
86 OSL_ASSERT(Type::value_invalid & Type::flag_sequence); // ensure check works for invalid types
88 if (aElementTC & Type::flag_sequence) // no sequence of sequence
89 return Type::value_invalid;
91 return sal_uInt8( aElementTC | Type::flag_sequence );
93 default:
94 return Type::value_invalid;
97 //-----------------------------------------------------------------------------
99 static uno::Type getUnoSimpleType( sal_uInt8 _aSimpleType)
101 OSL_ENSURE( _aSimpleType == (_aSimpleType & Type::mask_basetype), "Invalid type code" );
103 switch (_aSimpleType)
105 case Type::value_string:
106 return ::getCppuType(static_cast<rtl::OUString const *>(0));
108 case Type::value_boolean:
109 return ::getBooleanCppuType();
111 case Type::value_short:
112 return ::getCppuType(static_cast<sal_Int16 const *>(0));
114 case Type::value_int:
115 return ::getCppuType(static_cast<sal_Int32 const *>(0));
117 case Type::value_long:
118 return ::getCppuType(static_cast<sal_Int64 const *>(0));
120 case Type::value_double:
121 return ::getCppuType(static_cast<double const *>(0));
123 case Type::value_binary:
124 return ::getCppuType(static_cast<uno::Sequence<sal_Int8> const *>(0));
126 case Type::value_any:
127 //return ::getVoidCppuType();
128 return ::getCppuType(static_cast<uno::Any const *>(0));
130 default:
131 OSL_ENSURE( false, "Invalid type code" );
132 return ::getVoidCppuType();
135 //-----------------------------------------------------------------------------
137 static uno::Type getUnoSequenceType( sal_uInt8 _aSimpleType)
139 OSL_ENSURE( _aSimpleType == (_aSimpleType & Type::mask_basetype), "Invalid type code" );
141 switch (_aSimpleType)
143 case Type::value_string:
144 return ::getCppuType(static_cast<uno::Sequence<rtl::OUString> const *>(0));
146 case Type::value_boolean:
147 return ::getCppuType(static_cast<uno::Sequence<sal_Bool> const *>(0));
149 case Type::value_short:
150 return ::getCppuType(static_cast<uno::Sequence<sal_Int16> const *>(0));
152 case Type::value_int:
153 return ::getCppuType(static_cast<uno::Sequence<sal_Int32> const *>(0));
155 case Type::value_long:
156 return ::getCppuType(static_cast<uno::Sequence<sal_Int64> const *>(0));
158 case Type::value_double:
159 return ::getCppuType(static_cast<uno::Sequence<double> const *>(0));
161 case Type::value_binary:
162 return ::getCppuType(static_cast<uno::Sequence<uno::Sequence<sal_Int8> > const *>(0));
164 case Type::value_any: // results from value_invalid
165 default:
166 OSL_ENSURE( false, "Invalid type code" );
167 return ::getVoidCppuType();
170 //-----------------------------------------------------------------------------
172 uno::Type getUnoType( sal_uInt8 _aType)
174 OSL_ENSURE( _aType == (_aType & Type::mask_valuetype), "Invalid type code" );
176 if (_aType & Type::flag_sequence)
177 return getUnoSequenceType( sal_uInt8(_aType & Type::mask_basetype));
179 else
180 return getUnoSimpleType(_aType);
182 //-----------------------------------------------------------------------------
184 static
185 AnyData allocSimpleData(sal_uInt8 _aSimpleType, uno::Any const & _aAny)
187 OSL_ENSURE( _aSimpleType == (_aSimpleType & Type::mask_basetype), "Invalid type code" );
189 AnyData aResult;
190 aResult.data = 0;
192 switch (_aSimpleType)
194 case Type::value_string:
196 rtl::OUString sValue;
197 OSL_VERIFY(_aAny >>= sValue );
198 aResult.stringValue = acquireString(sValue);
200 break;
202 case Type::value_boolean:
203 OSL_VERIFY(_aAny >>= aResult.boolValue );
204 break;
206 case Type::value_short:
207 OSL_VERIFY(_aAny >>= aResult.shortValue);
208 break;
210 case Type::value_int:
211 OSL_VERIFY(_aAny >>= aResult.intValue);
212 break;
214 case Type::value_long:
216 sal_Int64 nValue = 0;
217 OSL_VERIFY(_aAny >>= nValue);
219 aResult.longValue = new sal_Int64( nValue );
221 break;
223 case Type::value_double:
225 double dValue = 0;
226 OSL_VERIFY(_aAny >>= dValue);
228 aResult.doubleValue = new double( dValue );
230 break;
232 case Type::value_binary:
234 uno::Sequence<sal_Int8> aValue;
235 OSL_VERIFY(_aAny >>= aValue);
236 aResult.binaryValue = allocBinary(aValue);
238 break;
240 case Type::value_any:
241 OSL_ENSURE( false, "Trying to allocate void value" );
242 break;
244 default:
245 OSL_ENSURE( false, "Invalid type code" );
246 break;
249 return aResult;
251 //-----------------------------------------------------------------------------
253 template <class E>
254 inline
255 sal_Sequence const * extractSequenceData(uno::Sequence< E > & _rSeq, uno::Any const & _aAny)
257 if (_aAny >>= _rSeq)
259 return _rSeq.get();
262 else
264 OSL_ENSURE(false, "Could not extract sequence from Any");
265 return NULL;
268 //-----------------------------------------------------------------------------
270 static
271 AnyData allocSequenceData(sal_uInt8 _aSimpleType, uno::Any const & _aAny)
273 OSL_ENSURE( _aSimpleType == (_aSimpleType & Type::mask_basetype), "Invalid type code" );
275 sal_uInt8 * aSequence = 0;
277 switch (_aSimpleType)
279 case Type::value_string:
281 uno::Sequence<rtl::OUString> aSeqValue;
282 if (sal_Sequence const * pData = extractSequenceData(aSeqValue,_aAny))
283 aSequence = allocSequence(_aSimpleType,pData);
285 break;
287 case Type::value_boolean:
289 uno::Sequence<sal_Bool> aSeqValue;
290 if (sal_Sequence const * pData = extractSequenceData(aSeqValue,_aAny))
291 aSequence = allocSequence(_aSimpleType,pData);
293 break;
295 case Type::value_short:
297 uno::Sequence<sal_Int16> aSeqValue;
298 if (sal_Sequence const * pData = extractSequenceData(aSeqValue,_aAny))
299 aSequence = allocSequence(_aSimpleType,pData);
301 break;
303 case Type::value_int:
305 uno::Sequence<sal_Int32> aSeqValue;
306 if (sal_Sequence const * pData = extractSequenceData(aSeqValue,_aAny))
307 aSequence = allocSequence(_aSimpleType,pData);
309 break;
311 case Type::value_long:
313 uno::Sequence<sal_Int64> aSeqValue;
314 if (sal_Sequence const * pData = extractSequenceData(aSeqValue,_aAny))
315 aSequence = allocSequence(_aSimpleType,pData);
317 break;
319 case Type::value_double:
321 uno::Sequence<double> aSeqValue;
322 if (sal_Sequence const * pData = extractSequenceData(aSeqValue,_aAny))
323 aSequence = allocSequence(_aSimpleType,pData);
325 break;
327 case Type::value_binary:
329 uno::Sequence<uno::Sequence<sal_Int8> > aSeqValue;
330 if (sal_Sequence const * pData = extractSequenceData(aSeqValue,_aAny))
331 aSequence = allocSequence(_aSimpleType,pData);
333 break;
335 case Type::value_any: // results from value_invalid
336 default:
337 OSL_ENSURE( false, "Invalid type code" );
338 break;
341 AnyData aResult;
342 aResult.sequenceValue = aSequence;
343 return aResult;
345 //-----------------------------------------------------------------------------
347 AnyData allocData(sal_uInt8 _aType, uno::Any const & _aAny)
349 OSL_ENSURE( _aType == (_aType & Type::mask_valuetype), "Invalid type code" );
350 OSL_ENSURE( _aType == getTypeCode(_aAny.getValueType()), "Type code does not match value" );
352 if (_aType & Type::flag_sequence)
353 return allocSequenceData(sal_uInt8( _aType & Type::mask_basetype),_aAny);
354 else
355 return allocSimpleData(_aType,_aAny);
357 //-----------------------------------------------------------------------------
359 static
360 void freeSimpleData(sal_uInt8 _aSimpleType, AnyData const & _aData)
362 OSL_ENSURE( _aSimpleType == (_aSimpleType & Type::mask_basetype), "Invalid type code" );
364 switch (_aSimpleType)
366 case Type::value_string:
367 rtl_uString_release(_aData.stringValue);
368 break;
370 case Type::value_boolean:
371 case Type::value_short:
372 case Type::value_int:
373 // nothing to do
374 break;
376 // free memory for oversized values
377 case Type::value_long:
378 delete _aData.longValue;
379 break;
381 case Type::value_double:
382 delete _aData.doubleValue;
383 break;
385 case Type::value_binary:
386 freeBinary(_aData.binaryValue);
387 break;
389 case Type::value_any:
390 // nothing to do for void value
391 break;
393 default:
394 OSL_ENSURE( false, "Invalid type code" );
395 break;
398 //-----------------------------------------------------------------------------
400 void freeData(sal_uInt8 _aType, AnyData _aData)
402 OSL_ENSURE( _aType == (_aType & Type::mask_valuetype), "Invalid type code" );
404 if (_aType & Type::flag_sequence)
405 freeSequence(sal_uInt8(_aType & Type::mask_basetype),_aData.sequenceValue);
407 else
408 freeSimpleData(_aType,_aData);
410 //-----------------------------------------------------------------------------
412 static
413 uno::Any readSimpleData(sal_uInt8 _aSimpleType, AnyData const & _aData)
415 OSL_ENSURE( _aSimpleType == (_aSimpleType & Type::mask_basetype), "Invalid type code" );
417 switch (_aSimpleType)
419 case Type::value_string:
421 rtl::OUString sValue = rtl::OUString(_aData.stringValue);
422 return uno::makeAny(sValue);
425 case Type::value_boolean:
426 return uno::makeAny( _aData.boolValue );
428 case Type::value_short:
429 return uno::makeAny( _aData.shortValue );
431 case Type::value_int:
432 return uno::makeAny( _aData.intValue );
434 case Type::value_long:
435 return uno::makeAny( *_aData.longValue );
437 case Type::value_double:
438 return uno::makeAny( *_aData.doubleValue );
440 case Type::value_binary:
442 uno::Sequence<sal_Int8> aValue = readBinary( _aData.binaryValue );
443 return uno::makeAny( aValue );
446 case Type::value_any: // void value
447 return uno::Any();
449 default:
450 OSL_ENSURE( false, "Invalid type code" );
451 return uno::Any();
454 //-----------------------------------------------------------------------------
456 uno::Any readData(sal_uInt8 _aType, AnyData _aData)
458 OSL_ENSURE( _aType == (_aType & Type::mask_valuetype), "Invalid type code" );
460 if (_aType & Type::flag_sequence)
461 return readAnySequence(sal_uInt8(_aType & Type::mask_basetype),_aData.sequenceValue);
463 else
464 return readSimpleData(_aType,_aData);
467 //-----------------------------------------------------------------------------
469 //-----------------------------------------------------------------------------
470 } // namespace