1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: anydata.cxx,v $
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"
37 #include "typeconverter.hxx"
41 //-----------------------------------------------------------------------------
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
);
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));
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
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
));
180 return getUnoSimpleType(_aType
);
182 //-----------------------------------------------------------------------------
185 AnyData
allocSimpleData(sal_uInt8 _aSimpleType
, uno::Any
const & _aAny
)
187 OSL_ENSURE( _aSimpleType
== (_aSimpleType
& Type::mask_basetype
), "Invalid type code" );
192 switch (_aSimpleType
)
194 case Type::value_string
:
196 rtl::OUString sValue
;
197 OSL_VERIFY(_aAny
>>= sValue
);
198 aResult
.stringValue
= acquireString(sValue
);
202 case Type::value_boolean
:
203 OSL_VERIFY(_aAny
>>= aResult
.boolValue
);
206 case Type::value_short
:
207 OSL_VERIFY(_aAny
>>= aResult
.shortValue
);
210 case Type::value_int
:
211 OSL_VERIFY(_aAny
>>= aResult
.intValue
);
214 case Type::value_long
:
216 sal_Int64 nValue
= 0;
217 OSL_VERIFY(_aAny
>>= nValue
);
219 aResult
.longValue
= new sal_Int64( nValue
);
223 case Type::value_double
:
226 OSL_VERIFY(_aAny
>>= dValue
);
228 aResult
.doubleValue
= new double( dValue
);
232 case Type::value_binary
:
234 uno::Sequence
<sal_Int8
> aValue
;
235 OSL_VERIFY(_aAny
>>= aValue
);
236 aResult
.binaryValue
= allocBinary(aValue
);
240 case Type::value_any
:
241 OSL_ENSURE( false, "Trying to allocate void value" );
245 OSL_ENSURE( false, "Invalid type code" );
251 //-----------------------------------------------------------------------------
255 sal_Sequence
const * extractSequenceData(uno::Sequence
< E
> & _rSeq
, uno::Any
const & _aAny
)
264 OSL_ENSURE(false, "Could not extract sequence from Any");
268 //-----------------------------------------------------------------------------
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
);
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
);
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
);
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
);
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
);
319 case Type::value_double
:
321 uno::Sequence
<double> aSeqValue
;
322 if (sal_Sequence
const * pData
= extractSequenceData(aSeqValue
,_aAny
))
323 aSequence
= allocSequence(_aSimpleType
,pData
);
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
);
335 case Type::value_any
: // results from value_invalid
337 OSL_ENSURE( false, "Invalid type code" );
342 aResult
.sequenceValue
= aSequence
;
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
);
355 return allocSimpleData(_aType
,_aAny
);
357 //-----------------------------------------------------------------------------
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
);
370 case Type::value_boolean
:
371 case Type::value_short
:
372 case Type::value_int
:
376 // free memory for oversized values
377 case Type::value_long
:
378 delete _aData
.longValue
;
381 case Type::value_double
:
382 delete _aData
.doubleValue
;
385 case Type::value_binary
:
386 freeBinary(_aData
.binaryValue
);
389 case Type::value_any
:
390 // nothing to do for void value
394 OSL_ENSURE( false, "Invalid type code" );
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
);
408 freeSimpleData(_aType
,_aData
);
410 //-----------------------------------------------------------------------------
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
450 OSL_ENSURE( false, "Invalid type code" );
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
);
464 return readSimpleData(_aType
,_aData
);
467 //-----------------------------------------------------------------------------
469 //-----------------------------------------------------------------------------