1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
20 #include <sal/config.h>
22 #include <o3tl/any.hxx>
23 #include <osl/diagnose.h>
24 #include <cppuhelper/factory.hxx>
25 #include <cppuhelper/implementationentry.hxx>
26 #include <cppuhelper/implbase.hxx>
27 #include <cppuhelper/supportsservice.hxx>
29 #include <typelib/typedescription.hxx>
39 #include <com/sun/star/lang/XServiceInfo.hpp>
40 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
41 #include <com/sun/star/script/CannotConvertException.hpp>
42 #include <com/sun/star/script/XTypeConverter.hpp>
43 #include <com/sun/star/script/FailReason.hpp>
44 #include <com/sun/star/container/XSet.hpp>
45 #include <com/sun/star/registry/XRegistryKey.hpp>
46 #include <com/sun/star/uno/XComponentContext.hpp>
48 using namespace css::uno
;
49 using namespace css::lang
;
50 using namespace css::script
;
51 using namespace css::registry
;
58 static const sal_uInt64 SAL_UINT64_MAX
=
59 (((sal_uInt64(0xffffffff)) << 32) | sal_uInt64(0xffffffff));
60 static const sal_Int64 SAL_INT64_MAX
=
61 sal_Int64(((sal_uInt64(0x7fffffff)) << 32) | sal_uInt64(0xffffffff));
62 static const sal_Int64 SAL_INT64_MIN
=
63 sal_Int64((sal_uInt64(0x80000000)) << 32);
65 /* MS Visual C++ no conversion from unsigned __int64 to double */
67 static const double DOUBLE_SAL_UINT64_MAX
= (((double(SAL_INT64_MAX
)) * 2) + 1);
69 static inline double unsigned_int64_to_double( sal_uInt64 n
)
71 sal_uInt64 n2
= (n
/ 3);
73 return (static_cast<double>(static_cast<sal_Int64
>(n2
)) * 2.0) + static_cast<double>(static_cast<sal_Int64
>(n
));
76 static const double DOUBLE_SAL_UINT64_MAX
=
77 double(((sal_uInt64(0xffffffff)) << 32) | sal_uInt64(0xffffffff));
79 static inline double unsigned_int64_to_double( sal_uInt64 n
)
81 return static_cast<double>(n
);
86 static inline double round( double aVal
)
88 bool bPos
= (aVal
>= 0.0);
89 aVal
= ::fabs( aVal
);
90 double aUpper
= ::ceil( aVal
);
92 aVal
= ((aUpper
-aVal
) <= 0.5) ? aUpper
: (aUpper
- 1.0);
93 return (bPos
? aVal
: -aVal
);
97 static bool getNumericValue( double & rfVal
, const OUString
& rStr
)
99 double fRet
= rStr
.toDouble();
102 sal_Int32 nLen
= rStr
.getLength();
103 if (!nLen
|| (nLen
== 1 && rStr
[0] == '0')) // common case
109 OUString
trim( rStr
.trim() );
112 sal_Int32 nX
= trim
.indexOf( 'x' );
114 nX
= trim
.indexOf( 'X' );
116 if (nX
> 0 && trim
[nX
-1] == '0') // 0x
121 case 2: // (+|-)0x...
124 else if (trim
[0] != '+')
133 OUString
aHexRest( trim
.copy( nX
+1 ) );
134 sal_uInt64 nRet
= aHexRest
.toUInt64( 16 );
138 for ( sal_Int32 nPos
= aHexRest
.getLength(); nPos
--; )
140 if (aHexRest
[nPos
] != '0')
145 rfVal
= (bNeg
? -static_cast<double>(nRet
) : static_cast<double>(nRet
));
149 nLen
= trim
.getLength();
153 if (nLen
&& (trim
[0] == '-' || trim
[0] == '+'))
156 while (nPos
< nLen
) // skip leading zeros
158 if (trim
[nPos
] != '0')
160 if (trim
[nPos
] != '.')
163 while (nPos
< nLen
) // skip trailing zeros
165 if (trim
[nPos
] != '0')
179 static bool getHyperValue( sal_Int64
& rnVal
, const OUString
& rStr
)
181 sal_Int32 nLen
= rStr
.getLength();
182 if (!nLen
|| (nLen
== 1 && rStr
[0] == '0')) // common case
188 OUString
trim( rStr
.trim() );
191 sal_Int32 nX
= trim
.indexOf( 'x' );
193 nX
= trim
.indexOf( 'X' );
197 if (nX
> 0 && trim
[nX
-1] == '0') // 0x
202 case 2: // (+|-)0x...
205 else if (trim
[0] != '+')
214 OUString
aHexRest( trim
.copy( nX
+1 ) );
215 sal_uInt64 nRet
= aHexRest
.toUInt64( 16 );
219 for ( sal_Int32 nPos
= aHexRest
.getLength(); nPos
--; )
221 if (aHexRest
[nPos
] != '0')
226 rnVal
= (bNeg
? -static_cast<sal_Int64
>(nRet
) : nRet
);
233 if (getNumericValue( fVal
, rStr
) &&
234 fVal
>= double(SAL_INT64_MIN
) &&
235 fVal
<= DOUBLE_SAL_UINT64_MAX
)
237 rnVal
= static_cast<sal_Int64
>(round( fVal
));
244 class TypeConverter_Impl
: public WeakImplHelper
< XTypeConverter
, XServiceInfo
>
246 // ...misc helpers...
247 /// @throws CannotConvertException
248 static sal_Int64
toHyper(
249 const Any
& rAny
, sal_Int64 min
, sal_uInt64 max
= SAL_UINT64_MAX
);
250 /// @throws CannotConvertException
251 static double toDouble( const Any
& rAny
, double min
= -DBL_MAX
, double max
= DBL_MAX
);
254 TypeConverter_Impl();
257 virtual OUString SAL_CALL
getImplementationName() override
;
258 virtual sal_Bool SAL_CALL
supportsService(const OUString
& ServiceName
) override
;
259 virtual Sequence
< OUString
> SAL_CALL
getSupportedServiceNames() override
;
262 virtual Any SAL_CALL
convertTo( const Any
& aFrom
, const Type
& DestinationType
) override
;
263 virtual Any SAL_CALL
convertToSimpleType( const Any
& aFrom
, TypeClass aDestinationType
) override
;
266 TypeConverter_Impl::TypeConverter_Impl() {}
269 OUString
TypeConverter_Impl::getImplementationName()
271 return OUString("com.sun.star.comp.stoc.TypeConverter");
275 sal_Bool
TypeConverter_Impl::supportsService(const OUString
& ServiceName
)
277 return cppu::supportsService(this, ServiceName
);
281 Sequence
< OUString
> TypeConverter_Impl::getSupportedServiceNames()
283 Sequence
< OUString
> seqNames
{ "com.sun.star.script.Converter" };
288 sal_Int64
TypeConverter_Impl::toHyper( const Any
& rAny
, sal_Int64 min
, sal_uInt64 max
)
291 TypeClass aDestinationClass
= rAny
.getValueTypeClass();
293 switch (aDestinationClass
)
297 nRet
= *static_cast<sal_Int32
const *>(rAny
.getValue());
300 case TypeClass_BOOLEAN
:
301 nRet
= *o3tl::forceAccess
<bool>(rAny
) ? 1 : 0;
305 nRet
= *o3tl::forceAccess
<sal_Unicode
>(rAny
);
308 nRet
= *o3tl::forceAccess
<sal_Int8
>(rAny
);
311 case TypeClass_SHORT
:
312 nRet
= *o3tl::forceAccess
<sal_Int16
>(rAny
);
315 case TypeClass_UNSIGNED_SHORT
:
316 nRet
= *o3tl::forceAccess
<sal_uInt16
>(rAny
);
320 nRet
= *o3tl::forceAccess
<sal_Int32
>(rAny
);
323 case TypeClass_UNSIGNED_LONG
:
324 nRet
= *o3tl::forceAccess
<sal_uInt32
>(rAny
);
327 case TypeClass_HYPER
:
328 nRet
= *o3tl::forceAccess
<sal_Int64
>(rAny
);
331 case TypeClass_UNSIGNED_HYPER
:
333 nRet
= static_cast<sal_Int64
>(*o3tl::forceAccess
<sal_uInt64
>(rAny
));
334 if ((min
< 0 || static_cast<sal_uInt64
>(nRet
) >= static_cast<sal_uInt64
>(min
)) && // lower bound
335 static_cast<sal_uInt64
>(nRet
) <= max
) // upper bound
339 throw CannotConvertException(
340 "UNSIGNED HYPER out of range!",
341 Reference
<XInterface
>(), aDestinationClass
, FailReason::OUT_OF_RANGE
, 0 );
345 case TypeClass_FLOAT
:
347 double fVal
= round( *o3tl::forceAccess
<float>(rAny
) );
348 nRet
= (fVal
> SAL_INT64_MAX
? static_cast<sal_Int64
>(static_cast<sal_uInt64
>(fVal
)) : static_cast<sal_Int64
>(fVal
));
349 if (fVal
>= min
&& fVal
<= unsigned_int64_to_double( max
))
353 throw CannotConvertException(
354 "FLOAT out of range!",
355 Reference
<XInterface
>(), aDestinationClass
, FailReason::OUT_OF_RANGE
, 0 );
357 case TypeClass_DOUBLE
:
359 double fVal
= round( *o3tl::forceAccess
<double>(rAny
) );
360 nRet
= (fVal
> SAL_INT64_MAX
? static_cast<sal_Int64
>(static_cast<sal_uInt64
>(fVal
)) : static_cast<sal_Int64
>(fVal
));
361 if (fVal
>= min
&& fVal
<= unsigned_int64_to_double( max
))
365 throw CannotConvertException(
366 "DOUBLE out of range!",
367 Reference
<XInterface
>(), aDestinationClass
, FailReason::OUT_OF_RANGE
, 0 );
371 case TypeClass_STRING
:
373 sal_Int64 nVal
= SAL_CONST_INT64(0);
374 if (! getHyperValue( nVal
, *o3tl::forceAccess
<OUString
>(rAny
) ))
376 throw CannotConvertException(
377 "invalid STRING value!",
378 Reference
<XInterface
>(), aDestinationClass
, FailReason::IS_NOT_NUMBER
, 0 );
381 if (nVal
>= min
&& (nVal
< 0 || static_cast<sal_uInt64
>(nVal
) <= max
))
383 throw CannotConvertException(
384 "STRING value out of range!",
385 Reference
<XInterface
>(), aDestinationClass
, FailReason::OUT_OF_RANGE
, 0 );
389 throw CannotConvertException(
390 "TYPE is not supported!",
391 Reference
<XInterface
>(), aDestinationClass
, FailReason::TYPE_NOT_SUPPORTED
, 0 );
394 if (nRet
>= min
&& (nRet
< 0 || static_cast<sal_uInt64
>(nRet
) <= max
))
396 throw CannotConvertException(
397 "VALUE is out of range!",
398 Reference
<XInterface
>(), aDestinationClass
, FailReason::OUT_OF_RANGE
, 0 );
402 double TypeConverter_Impl::toDouble( const Any
& rAny
, double min
, double max
)
405 TypeClass aDestinationClass
= rAny
.getValueTypeClass();
407 switch (aDestinationClass
)
411 fRet
= *static_cast<sal_Int32
const *>(rAny
.getValue());
414 case TypeClass_BOOLEAN
:
415 fRet
= *o3tl::forceAccess
<bool>(rAny
) ? 1.0 : 0.0;
419 fRet
= *o3tl::forceAccess
<sal_Unicode
>(rAny
);
422 fRet
= *o3tl::forceAccess
<sal_Int8
>(rAny
);
425 case TypeClass_SHORT
:
426 fRet
= *o3tl::forceAccess
<sal_Int16
>(rAny
);
429 case TypeClass_UNSIGNED_SHORT
:
430 fRet
= *o3tl::forceAccess
<sal_uInt16
>(rAny
);
434 fRet
= *o3tl::forceAccess
<sal_Int32
>(rAny
);
437 case TypeClass_UNSIGNED_LONG
:
438 fRet
= *o3tl::forceAccess
<sal_uInt32
>(rAny
);
441 case TypeClass_HYPER
:
442 fRet
= static_cast<double>(*o3tl::forceAccess
<sal_Int64
>(rAny
));
445 case TypeClass_UNSIGNED_HYPER
:
446 fRet
= unsigned_int64_to_double( *o3tl::forceAccess
<sal_uInt64
>(rAny
) );
449 case TypeClass_FLOAT
:
450 fRet
= *o3tl::forceAccess
<float>(rAny
);
452 case TypeClass_DOUBLE
:
453 fRet
= *o3tl::forceAccess
<double>(rAny
);
457 case TypeClass_STRING
:
459 if (! getNumericValue( fRet
, *o3tl::forceAccess
<OUString
>(rAny
) ))
461 throw CannotConvertException(
462 "invalid STRING value!",
463 Reference
<XInterface
>(), aDestinationClass
, FailReason::IS_NOT_NUMBER
, 0 );
469 throw CannotConvertException(
470 "TYPE is not supported!",
471 Reference
< XInterface
>(), aDestinationClass
, FailReason::TYPE_NOT_SUPPORTED
, 0 );
474 if (fRet
>= min
&& fRet
<= max
)
476 throw CannotConvertException(
477 "VALUE is out of range!",
478 Reference
< XInterface
>(), aDestinationClass
, FailReason::OUT_OF_RANGE
, 0 );
482 Any SAL_CALL
TypeConverter_Impl::convertTo( const Any
& rVal
, const Type
& aDestType
)
484 const Type
& aSourceType
= rVal
.getValueType();
485 if (aSourceType
== aDestType
)
488 TypeClass aSourceClass
= aSourceType
.getTypeClass();
489 TypeClass aDestinationClass
= aDestType
.getTypeClass();
494 switch (aDestinationClass
)
496 // --- to VOID ------------------------------------------------------------------------------
499 // --- to ANY -------------------------------------------------------------------------------
503 // --- to STRUCT, EXCEPTION ----------------------------------------------------------
504 case TypeClass_STRUCT
:
505 case TypeClass_EXCEPTION
:
507 // same types or destination type is derived source type?
508 TypeDescription
aSourceTD( aSourceType
);
509 TypeDescription
aDestTD( aDestType
);
510 if (!typelib_typedescription_isAssignableFrom( aDestTD
.get(), aSourceTD
.get() ))
512 throw CannotConvertException(
513 "value is not of same or derived type!",
514 Reference
< XInterface
>(), aDestinationClass
,
515 FailReason::SOURCE_IS_NO_DERIVED_TYPE
, 0 );
517 aRet
.setValue( rVal
.getValue(), aDestTD
.get() ); // evtl. .uP.cAsT.
520 // --- to INTERFACE -------------------------------------------------------------------------
521 case TypeClass_INTERFACE
:
523 if (! rVal
.hasValue())
525 // void -> interface (null)
526 void * null_ref
= nullptr;
527 aRet
.setValue( &null_ref
, aDestType
);
531 auto ifc
= o3tl::tryAccess
<css::uno::Reference
<css::uno::XInterface
>>(
533 if (!ifc
|| !ifc
->is())
535 throw CannotConvertException(
536 "value is not interface",
537 Reference
< XInterface
>(), aDestinationClass
, FailReason::NO_SUCH_INTERFACE
, 0 );
539 if (! (aRet
= (*ifc
)->queryInterface(aDestType
)).hasValue())
541 throw CannotConvertException(
542 "value does not implement " + aDestType
.getTypeName(),
543 Reference
< XInterface
>(), aDestinationClass
, FailReason::NO_SUCH_INTERFACE
, 0 );
547 // --- to SEQUENCE --------------------------------------------------------------------------
548 case TypeClass_SEQUENCE
:
550 if (aSourceClass
==TypeClass_SEQUENCE
)
552 if( aSourceType
== aDestType
)
555 TypeDescription
aSourceTD( aSourceType
);
556 TypeDescription
aDestTD( aDestType
);
557 typelib_TypeDescription
* pSourceElementTD
= nullptr;
560 reinterpret_cast<typelib_IndirectTypeDescription
*>(aSourceTD
.get())->pType
);
561 typelib_TypeDescription
* pDestElementTD
= nullptr;
564 reinterpret_cast<typelib_IndirectTypeDescription
*>(aDestTD
.get())->pType
);
566 sal_uInt32 nPos
= (*static_cast<const uno_Sequence
* const *>(rVal
.getValue()))->nElements
;
567 uno_Sequence
* pRet
= nullptr;
568 uno_sequence_construct(
569 &pRet
, aDestTD
.get(), nullptr, nPos
,
570 reinterpret_cast< uno_AcquireFunc
>(cpp_acquire
) );
571 aRet
.setValue( &pRet
, aDestTD
.get() );
573 &pRet
, aDestTD
.get(),
574 reinterpret_cast< uno_ReleaseFunc
>(cpp_release
) );
577 char * pDestElements
= (*static_cast<uno_Sequence
* const *>(aRet
.getValue()))->elements
;
578 const char * pSourceElements
=
579 (*static_cast<const uno_Sequence
* const *>(rVal
.getValue()))->elements
;
583 char * pDestPos
= pDestElements
+ (nPos
* pDestElementTD
->nSize
);
584 const char * pSourcePos
= pSourceElements
+ (nPos
* pSourceElementTD
->nSize
);
587 convertTo( Any( pSourcePos
, pSourceElementTD
), pDestElementTD
->pWeakRef
) );
590 pDestPos
, pDestElementTD
,
591 (pDestElementTD
->eTypeClass
== typelib_TypeClass_ANY
593 : const_cast< void * >( aElement
.getValue() )),
595 reinterpret_cast< uno_QueryInterfaceFunc
>(
597 reinterpret_cast< uno_AcquireFunc
>(cpp_acquire
),
598 reinterpret_cast< uno_ReleaseFunc
>(cpp_release
) ))
603 TYPELIB_DANGER_RELEASE( pDestElementTD
);
604 TYPELIB_DANGER_RELEASE( pSourceElementTD
);
608 // --- to ENUM ------------------------------------------------------------------------------
611 TypeDescription
aEnumTD( aDestType
);
612 aEnumTD
.makeComplete();
615 if (aSourceClass
==TypeClass_STRING
)
617 for ( nPos
= reinterpret_cast<typelib_EnumTypeDescription
*>(aEnumTD
.get())->nEnumValues
; nPos
--; )
619 if (o3tl::forceAccess
<OUString
>(rVal
)->equalsIgnoreAsciiCase(
620 reinterpret_cast<typelib_EnumTypeDescription
*>(aEnumTD
.get())->ppEnumNames
[nPos
] ))
624 else if (aSourceClass
!=TypeClass_ENUM
&& // exclude some unwanted types for toHyper()
625 aSourceClass
!=TypeClass_BOOLEAN
&&
626 aSourceClass
!=TypeClass_CHAR
)
628 sal_Int32 nEnumValue
= static_cast<sal_Int32
>(toHyper( rVal
, -sal_Int64(0x80000000), 0x7fffffff ));
629 for ( nPos
= reinterpret_cast<typelib_EnumTypeDescription
*>(aEnumTD
.get())->nEnumValues
; nPos
--; )
631 if (nEnumValue
== reinterpret_cast<typelib_EnumTypeDescription
*>(aEnumTD
.get())->pEnumValues
[nPos
])
638 throw CannotConvertException(
639 "value cannot be converted to demanded ENUM!",
640 Reference
< XInterface
>(), aDestinationClass
, FailReason::IS_NOT_ENUM
, 0 );
644 &reinterpret_cast<typelib_EnumTypeDescription
*>(aEnumTD
.get())->pEnumValues
[nPos
],
651 // else simple type conversion possible?
654 aRet
= convertToSimpleType( rVal
, aDestinationClass
);
656 catch (IllegalArgumentException
&)
658 // ...FailReason::INVALID is thrown
665 throw CannotConvertException(
666 "conversion not possible!",
667 Reference
< XInterface
>(), aDestinationClass
, FailReason::INVALID
, 0 );
671 Any
TypeConverter_Impl::convertToSimpleType( const Any
& rVal
, TypeClass aDestinationClass
)
673 switch (aDestinationClass
)
675 // only simple Conversion of _simple_ types
677 case TypeClass_BOOLEAN
:
679 case TypeClass_SHORT
:
680 case TypeClass_UNSIGNED_SHORT
:
682 case TypeClass_UNSIGNED_LONG
:
683 case TypeClass_HYPER
:
684 case TypeClass_UNSIGNED_HYPER
:
685 case TypeClass_FLOAT
:
686 case TypeClass_DOUBLE
:
688 case TypeClass_STRING
:
693 throw IllegalArgumentException(
694 "destination type is not simple!",
695 Reference
< XInterface
>(), sal_Int16(1) );
698 const Type
& aSourceType
= rVal
.getValueType();
699 TypeClass aSourceClass
= aSourceType
.getTypeClass();
700 if (aDestinationClass
== aSourceClass
)
706 switch (aDestinationClass
)
708 // --- to VOID ------------------------------------------------------------------------------
712 // --- to ANY -------------------------------------------------------------------------------
716 // --- to BOOL ------------------------------------------------------------------------------
717 case TypeClass_BOOLEAN
:
718 switch (aSourceClass
)
721 aRet
<<= (toDouble( rVal
) != 0.0);
723 case TypeClass_ENUM
: // exclude enums
726 case TypeClass_STRING
:
728 const OUString
& aStr
= *o3tl::forceAccess
<OUString
>(rVal
);
729 if ( aStr
== "0" || aStr
.equalsIgnoreAsciiCase( "false" ))
733 else if ( aStr
== "1" || aStr
.equalsIgnoreAsciiCase( "true" ))
739 throw CannotConvertException(
740 "STRING has no boolean value, " + aStr
,
741 Reference
< XInterface
>(), aDestinationClass
, FailReason::IS_NOT_BOOL
, 0 );
747 // --- to CHAR, BYTE ------------------------------------------------------------------------
750 if (aSourceClass
==TypeClass_STRING
)
752 auto const s
= o3tl::forceAccess
<OUString
>(rVal
);
753 if (s
->getLength() == 1) // single char
756 else if (aSourceClass
!=TypeClass_ENUM
&& // exclude enums, chars
757 aSourceClass
!=TypeClass_CHAR
)
759 aRet
<<= sal_Unicode(toHyper( rVal
, 0, 0xffff )); // range
764 aRet
<<= static_cast<sal_Int8
>( toHyper( rVal
, -sal_Int64(0x80), 0x7f ) );
767 // --- to SHORT, UNSIGNED SHORT -------------------------------------------------------------
768 case TypeClass_SHORT
:
769 aRet
<<= static_cast<sal_Int16
>( toHyper( rVal
, -sal_Int64(0x8000), 0x7fff ) );
771 case TypeClass_UNSIGNED_SHORT
:
772 aRet
<<= static_cast<sal_uInt16
>( toHyper( rVal
, 0, 0xffff ) );
775 // --- to LONG, UNSIGNED LONG ---------------------------------------------------------------
777 aRet
<<= static_cast<sal_Int32
>( toHyper( rVal
, -sal_Int64(0x80000000), 0x7fffffff ) );
779 case TypeClass_UNSIGNED_LONG
:
780 aRet
<<= static_cast<sal_uInt32
>( toHyper( rVal
, 0, 0xffffffff ) );
783 // --- to HYPER, UNSIGNED HYPER--------------------------------------------
784 case TypeClass_HYPER
:
785 aRet
<<= toHyper( rVal
, SAL_INT64_MIN
, SAL_INT64_MAX
);
787 case TypeClass_UNSIGNED_HYPER
:
788 aRet
<<= static_cast<sal_uInt64
>( toHyper( rVal
, 0 ) );
791 // --- to FLOAT, DOUBLE ---------------------------------------------------------------------
792 case TypeClass_FLOAT
:
793 aRet
<<= static_cast<float>( toDouble( rVal
, -FLT_MAX
, FLT_MAX
) );
795 case TypeClass_DOUBLE
:
796 aRet
<<= toDouble( rVal
, -DBL_MAX
, DBL_MAX
);
799 // --- to STRING ----------------------------------------------------------------------------
800 case TypeClass_STRING
:
801 switch (aSourceClass
)
805 TypeDescription
aEnumTD( aSourceType
);
806 aEnumTD
.makeComplete();
808 sal_Int32 nEnumValue
= *static_cast<sal_Int32
const *>(rVal
.getValue());
809 for ( nPos
= reinterpret_cast<typelib_EnumTypeDescription
*>(aEnumTD
.get())->nEnumValues
; nPos
--; )
811 if (nEnumValue
== reinterpret_cast<typelib_EnumTypeDescription
*>(aEnumTD
.get())->pEnumValues
[nPos
])
816 throw CannotConvertException(
817 "value is not ENUM!",
818 Reference
< XInterface
>(), aDestinationClass
, FailReason::IS_NOT_ENUM
, 0 );
821 aRet
<<= OUString::unacquired(
822 &reinterpret_cast<typelib_EnumTypeDescription
*>(aEnumTD
.get())->ppEnumNames
[nPos
]);
827 case TypeClass_BOOLEAN
:
828 aRet
<<= *o3tl::forceAccess
<bool>(rVal
) ?
833 aRet
<<= OUString(*o3tl::forceAccess
<sal_Unicode
>(rVal
));
837 aRet
<<= OUString::number( *o3tl::forceAccess
<sal_Int8
>(rVal
) );
839 case TypeClass_SHORT
:
840 aRet
<<= OUString::number( *o3tl::forceAccess
<sal_Int16
>(rVal
) );
842 case TypeClass_UNSIGNED_SHORT
:
843 aRet
<<= OUString::number( *o3tl::forceAccess
<sal_uInt16
>(rVal
) );
846 aRet
<<= OUString::number( *o3tl::forceAccess
<sal_Int32
>(rVal
) );
848 case TypeClass_UNSIGNED_LONG
:
849 aRet
<<= OUString::number( *o3tl::forceAccess
<sal_uInt32
>(rVal
) );
851 case TypeClass_HYPER
:
852 aRet
<<= OUString::number( *o3tl::forceAccess
<sal_Int64
>(rVal
) );
854 // case TypeClass_UNSIGNED_HYPER:
855 // aRet <<= OUString::valueOf( (sal_Int64)*(sal_uInt64 const *)rVal.getValue() );
857 // handle unsigned hyper like double
860 aRet
<<= OUString::number( toDouble( rVal
) );
872 throw CannotConvertException(
873 "conversion not possible!",
874 Reference
< XInterface
>(), aDestinationClass
, FailReason::INVALID
, 0 );
879 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
880 com_sun_star_comp_stoc_TypeConverter_get_implementation(css::uno::XComponentContext
*,
881 css::uno::Sequence
<css::uno::Any
> const &)
883 return ::cppu::acquire(new stoc_tcv::TypeConverter_Impl());
886 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */