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 <o3tl/safeint.hxx>
24 #include <osl/diagnose.h>
25 #include <cppuhelper/implbase.hxx>
26 #include <cppuhelper/supportsservice.hxx>
28 #include <typelib/typedescription.hxx>
38 #include <com/sun/star/lang/IllegalArgumentException.hpp>
39 #include <com/sun/star/lang/XServiceInfo.hpp>
40 #include <com/sun/star/script/CannotConvertException.hpp>
41 #include <com/sun/star/script/XTypeConverter.hpp>
42 #include <com/sun/star/script/FailReason.hpp>
44 namespace com::sun::star::uno
{ class XComponentContext
; }
46 using namespace css::uno
;
47 using namespace css::lang
;
48 using namespace css::script
;
55 static double round( double aVal
)
57 bool bPos
= (aVal
>= 0.0);
58 aVal
= ::fabs( aVal
);
59 double aUpper
= ::ceil( aVal
);
61 aVal
= ((aUpper
-aVal
) <= 0.5) ? aUpper
: (aUpper
- 1.0);
62 return (bPos
? aVal
: -aVal
);
66 static bool getNumericValue( double & rfVal
, const OUString
& rStr
)
68 double fRet
= rStr
.toDouble();
71 sal_Int32 nLen
= rStr
.getLength();
72 if (!nLen
|| (nLen
== 1 && rStr
[0] == '0')) // common case
78 OUString
trim( rStr
.trim() );
81 sal_Int32 nX
= trim
.indexOf( 'x' );
83 nX
= trim
.indexOf( 'X' );
85 if (nX
> 0 && trim
[nX
-1] == '0') // 0x
93 else if (trim
[0] != '+')
102 OUString
aHexRest( trim
.copy( nX
+1 ) );
103 sal_uInt64 nRet
= aHexRest
.toUInt64( 16 );
107 for ( sal_Int32 nPos
= aHexRest
.getLength(); nPos
--; )
109 if (aHexRest
[nPos
] != '0')
114 rfVal
= (bNeg
? -static_cast<double>(nRet
) : static_cast<double>(nRet
));
118 nLen
= trim
.getLength();
122 if (nLen
&& (trim
[0] == '-' || trim
[0] == '+'))
125 while (nPos
< nLen
) // skip leading zeros
127 if (trim
[nPos
] != '0')
129 if (trim
[nPos
] != '.')
132 while (nPos
< nLen
) // skip trailing zeros
134 if (trim
[nPos
] != '0')
148 static bool getHyperValue( sal_Int64
& rnVal
, const OUString
& rStr
)
150 sal_Int32 nLen
= rStr
.getLength();
151 if (!nLen
|| (nLen
== 1 && rStr
[0] == '0')) // common case
157 OUString
trim( rStr
.trim() );
160 sal_Int32 nX
= trim
.indexOf( 'x' );
162 nX
= trim
.indexOf( 'X' );
166 if (nX
> 0 && trim
[nX
-1] == '0') // 0x
171 case 2: // (+|-)0x...
174 else if (trim
[0] != '+')
183 OUString
aHexRest( trim
.copy( nX
+1 ) );
184 sal_uInt64 nRet
= aHexRest
.toUInt64( 16 );
188 for ( sal_Int32 nPos
= aHexRest
.getLength(); nPos
--; )
190 if (aHexRest
[nPos
] != '0')
195 rnVal
= (bNeg
? -static_cast<sal_Int64
>(nRet
) : nRet
);
202 if (getNumericValue( fVal
, rStr
) &&
203 fVal
>= double(SAL_MIN_INT64
) &&
204 fVal
<= double(SAL_MAX_UINT64
))
206 rnVal
= static_cast<sal_Int64
>(round( fVal
));
214 class TypeConverter_Impl
: public WeakImplHelper
< XTypeConverter
, XServiceInfo
>
216 // ...misc helpers...
217 /// @throws CannotConvertException
218 static sal_Int64
toHyper(
219 const Any
& rAny
, sal_Int64 min
, sal_uInt64 max
= SAL_MAX_UINT64
);
220 /// @throws CannotConvertException
221 static double toDouble( const Any
& rAny
, double min
= -DBL_MAX
, double max
= DBL_MAX
);
224 TypeConverter_Impl();
227 virtual OUString SAL_CALL
getImplementationName() override
;
228 virtual sal_Bool SAL_CALL
supportsService(const OUString
& ServiceName
) override
;
229 virtual Sequence
< OUString
> SAL_CALL
getSupportedServiceNames() override
;
232 virtual Any SAL_CALL
convertTo( const Any
& aFrom
, const Type
& DestinationType
) override
;
233 virtual Any SAL_CALL
convertToSimpleType( const Any
& aFrom
, TypeClass aDestinationType
) override
;
238 TypeConverter_Impl::TypeConverter_Impl() {}
241 OUString
TypeConverter_Impl::getImplementationName()
243 return "com.sun.star.comp.stoc.TypeConverter";
247 sal_Bool
TypeConverter_Impl::supportsService(const OUString
& ServiceName
)
249 return cppu::supportsService(this, ServiceName
);
253 Sequence
< OUString
> TypeConverter_Impl::getSupportedServiceNames()
255 return { "com.sun.star.script.Converter" };
259 sal_Int64
TypeConverter_Impl::toHyper( const Any
& rAny
, sal_Int64 min
, sal_uInt64 max
)
262 TypeClass aDestinationClass
= rAny
.getValueTypeClass();
264 switch (aDestinationClass
)
268 nRet
= *static_cast<sal_Int32
const *>(rAny
.getValue());
271 case TypeClass_BOOLEAN
:
272 nRet
= *o3tl::forceAccess
<bool>(rAny
) ? 1 : 0;
276 nRet
= *o3tl::forceAccess
<sal_Unicode
>(rAny
);
279 nRet
= *o3tl::forceAccess
<sal_Int8
>(rAny
);
282 case TypeClass_SHORT
:
283 nRet
= *o3tl::forceAccess
<sal_Int16
>(rAny
);
286 case TypeClass_UNSIGNED_SHORT
:
287 nRet
= *o3tl::forceAccess
<sal_uInt16
>(rAny
);
291 nRet
= *o3tl::forceAccess
<sal_Int32
>(rAny
);
294 case TypeClass_UNSIGNED_LONG
:
295 nRet
= *o3tl::forceAccess
<sal_uInt32
>(rAny
);
298 case TypeClass_HYPER
:
299 nRet
= *o3tl::forceAccess
<sal_Int64
>(rAny
);
302 case TypeClass_UNSIGNED_HYPER
:
304 auto const n
= *o3tl::forceAccess
<sal_uInt64
>(rAny
);
305 if ((min
< 0 || n
>= o3tl::make_unsigned(min
)) && // lower bound
306 n
<= max
) // upper bound
308 return static_cast<sal_Int64
>(n
);
310 throw CannotConvertException(
311 "UNSIGNED HYPER out of range!",
312 Reference
<XInterface
>(), aDestinationClass
, FailReason::OUT_OF_RANGE
, 0 );
316 case TypeClass_FLOAT
:
318 double fVal
= round( *o3tl::forceAccess
<float>(rAny
) );
319 if (fVal
>= min
&& fVal
<= max
)
321 nRet
= (fVal
>= 0.0 ? static_cast<sal_Int64
>(static_cast<sal_uInt64
>(fVal
)) : static_cast<sal_Int64
>(fVal
));
324 throw CannotConvertException(
325 "FLOAT out of range!",
326 Reference
<XInterface
>(), aDestinationClass
, FailReason::OUT_OF_RANGE
, 0 );
328 case TypeClass_DOUBLE
:
330 double fVal
= round( *o3tl::forceAccess
<double>(rAny
) );
331 if (fVal
>= min
&& fVal
<= max
)
333 nRet
= (fVal
>= 0.0 ? static_cast<sal_Int64
>(static_cast<sal_uInt64
>(fVal
)) : static_cast<sal_Int64
>(fVal
));
336 throw CannotConvertException(
337 "DOUBLE out of range!",
338 Reference
<XInterface
>(), aDestinationClass
, FailReason::OUT_OF_RANGE
, 0 );
342 case TypeClass_STRING
:
344 sal_Int64 nVal
= SAL_CONST_INT64(0);
345 if (! getHyperValue( nVal
, *o3tl::forceAccess
<OUString
>(rAny
) ))
347 throw CannotConvertException(
348 "invalid STRING value!",
349 Reference
<XInterface
>(), aDestinationClass
, FailReason::IS_NOT_NUMBER
, 0 );
352 if (nVal
>= min
&& (nVal
< 0 || o3tl::make_unsigned(nVal
) <= max
))
354 throw CannotConvertException(
355 "STRING value out of range!",
356 Reference
<XInterface
>(), aDestinationClass
, FailReason::OUT_OF_RANGE
, 0 );
360 throw CannotConvertException(
361 "TYPE is not supported!",
362 Reference
<XInterface
>(), aDestinationClass
, FailReason::TYPE_NOT_SUPPORTED
, 0 );
365 if (nRet
>= min
&& (nRet
< 0 || o3tl::make_unsigned(nRet
) <= max
))
367 throw CannotConvertException(
368 "VALUE is out of range!",
369 Reference
<XInterface
>(), aDestinationClass
, FailReason::OUT_OF_RANGE
, 0 );
373 double TypeConverter_Impl::toDouble( const Any
& rAny
, double min
, double max
)
376 TypeClass aDestinationClass
= rAny
.getValueTypeClass();
378 switch (aDestinationClass
)
382 fRet
= *static_cast<sal_Int32
const *>(rAny
.getValue());
385 case TypeClass_BOOLEAN
:
386 fRet
= *o3tl::forceAccess
<bool>(rAny
) ? 1.0 : 0.0;
390 fRet
= *o3tl::forceAccess
<sal_Unicode
>(rAny
);
393 fRet
= *o3tl::forceAccess
<sal_Int8
>(rAny
);
396 case TypeClass_SHORT
:
397 fRet
= *o3tl::forceAccess
<sal_Int16
>(rAny
);
400 case TypeClass_UNSIGNED_SHORT
:
401 fRet
= *o3tl::forceAccess
<sal_uInt16
>(rAny
);
405 fRet
= *o3tl::forceAccess
<sal_Int32
>(rAny
);
408 case TypeClass_UNSIGNED_LONG
:
409 fRet
= *o3tl::forceAccess
<sal_uInt32
>(rAny
);
412 case TypeClass_HYPER
:
413 fRet
= static_cast<double>(*o3tl::forceAccess
<sal_Int64
>(rAny
));
416 case TypeClass_UNSIGNED_HYPER
:
417 fRet
= static_cast<double>(*o3tl::forceAccess
<sal_uInt64
>(rAny
));
420 case TypeClass_FLOAT
:
421 fRet
= *o3tl::forceAccess
<float>(rAny
);
423 case TypeClass_DOUBLE
:
424 fRet
= *o3tl::forceAccess
<double>(rAny
);
428 case TypeClass_STRING
:
430 if (! getNumericValue( fRet
, *o3tl::forceAccess
<OUString
>(rAny
) ))
432 throw CannotConvertException(
433 "invalid STRING value!",
434 Reference
<XInterface
>(), aDestinationClass
, FailReason::IS_NOT_NUMBER
, 0 );
440 throw CannotConvertException(
441 "TYPE is not supported!",
442 Reference
< XInterface
>(), aDestinationClass
, FailReason::TYPE_NOT_SUPPORTED
, 0 );
445 if (fRet
>= min
&& fRet
<= max
)
447 throw CannotConvertException(
448 "VALUE is out of range!",
449 Reference
< XInterface
>(), aDestinationClass
, FailReason::OUT_OF_RANGE
, 0 );
453 Any SAL_CALL
TypeConverter_Impl::convertTo( const Any
& rVal
, const Type
& aDestType
)
455 const Type
& aSourceType
= rVal
.getValueType();
456 if (aSourceType
== aDestType
)
459 TypeClass aSourceClass
= aSourceType
.getTypeClass();
460 TypeClass aDestinationClass
= aDestType
.getTypeClass();
465 switch (aDestinationClass
)
467 // --- to VOID ------------------------------------------------------------------------------
470 // --- to ANY -------------------------------------------------------------------------------
474 // --- to STRUCT, EXCEPTION ----------------------------------------------------------
475 case TypeClass_STRUCT
:
476 case TypeClass_EXCEPTION
:
478 // same types or destination type is derived source type?
479 TypeDescription
aSourceTD( aSourceType
);
480 TypeDescription
aDestTD( aDestType
);
481 if (!typelib_typedescription_isAssignableFrom( aDestTD
.get(), aSourceTD
.get() ))
483 throw CannotConvertException(
484 "value is not of same or derived type!",
485 Reference
< XInterface
>(), aDestinationClass
,
486 FailReason::SOURCE_IS_NO_DERIVED_TYPE
, 0 );
488 aRet
.setValue( rVal
.getValue(), aDestTD
.get() ); // evtl. .uP.cAsT.
491 // --- to INTERFACE -------------------------------------------------------------------------
492 case TypeClass_INTERFACE
:
494 if (! rVal
.hasValue())
496 // void -> interface (null)
497 void * null_ref
= nullptr;
498 aRet
.setValue( &null_ref
, aDestType
);
502 auto ifc
= o3tl::tryAccess
<css::uno::Reference
<css::uno::XInterface
>>(
504 if (!ifc
|| !ifc
->is())
506 throw CannotConvertException(
507 "value is not interface",
508 Reference
< XInterface
>(), aDestinationClass
, FailReason::NO_SUCH_INTERFACE
, 0 );
510 aRet
= (*ifc
)->queryInterface(aDestType
);
511 if (! aRet
.hasValue())
513 throw CannotConvertException(
514 "value does not implement " + aDestType
.getTypeName(),
515 Reference
< XInterface
>(), aDestinationClass
, FailReason::NO_SUCH_INTERFACE
, 0 );
519 // --- to SEQUENCE --------------------------------------------------------------------------
520 case TypeClass_SEQUENCE
:
522 if (aSourceClass
==TypeClass_SEQUENCE
)
524 if( aSourceType
== aDestType
)
527 TypeDescription
aSourceTD( aSourceType
);
528 TypeDescription
aDestTD( aDestType
);
529 typelib_TypeDescription
* pSourceElementTD
= nullptr;
532 reinterpret_cast<typelib_IndirectTypeDescription
*>(aSourceTD
.get())->pType
);
533 typelib_TypeDescription
* pDestElementTD
= nullptr;
536 reinterpret_cast<typelib_IndirectTypeDescription
*>(aDestTD
.get())->pType
);
538 sal_uInt32 nPos
= (*static_cast<const uno_Sequence
* const *>(rVal
.getValue()))->nElements
;
539 uno_Sequence
* pRet
= nullptr;
540 uno_sequence_construct(
541 &pRet
, aDestTD
.get(), nullptr, nPos
,
542 reinterpret_cast< uno_AcquireFunc
>(cpp_acquire
) );
543 aRet
.setValue( &pRet
, aDestTD
.get() );
545 &pRet
, aDestTD
.get(),
546 reinterpret_cast< uno_ReleaseFunc
>(cpp_release
) );
549 char * pDestElements
= (*static_cast<uno_Sequence
* const *>(aRet
.getValue()))->elements
;
550 const char * pSourceElements
=
551 (*static_cast<const uno_Sequence
* const *>(rVal
.getValue()))->elements
;
555 char * pDestPos
= pDestElements
+ (nPos
* pDestElementTD
->nSize
);
556 const char * pSourcePos
= pSourceElements
+ (nPos
* pSourceElementTD
->nSize
);
559 convertTo( Any( pSourcePos
, pSourceElementTD
), pDestElementTD
->pWeakRef
) );
562 pDestPos
, pDestElementTD
,
563 (pDestElementTD
->eTypeClass
== typelib_TypeClass_ANY
565 : const_cast< void * >( aElement
.getValue() )),
567 reinterpret_cast< uno_QueryInterfaceFunc
>(
569 reinterpret_cast< uno_AcquireFunc
>(cpp_acquire
),
570 reinterpret_cast< uno_ReleaseFunc
>(cpp_release
) ))
575 TYPELIB_DANGER_RELEASE( pDestElementTD
);
576 TYPELIB_DANGER_RELEASE( pSourceElementTD
);
580 // --- to ENUM ------------------------------------------------------------------------------
583 TypeDescription
aEnumTD( aDestType
);
584 aEnumTD
.makeComplete();
587 if (aSourceClass
==TypeClass_STRING
)
589 for ( nPos
= reinterpret_cast<typelib_EnumTypeDescription
*>(aEnumTD
.get())->nEnumValues
; nPos
--; )
591 if (o3tl::forceAccess
<OUString
>(rVal
)->equalsIgnoreAsciiCase(
592 OUString::unacquired(&reinterpret_cast<typelib_EnumTypeDescription
*>(aEnumTD
.get())->ppEnumNames
[nPos
]) ))
596 else if (aSourceClass
!=TypeClass_ENUM
&& // exclude some unwanted types for toHyper()
597 aSourceClass
!=TypeClass_BOOLEAN
&&
598 aSourceClass
!=TypeClass_CHAR
)
600 sal_Int32 nEnumValue
= static_cast<sal_Int32
>(toHyper( rVal
, -sal_Int64(0x80000000), 0x7fffffff ));
601 for ( nPos
= reinterpret_cast<typelib_EnumTypeDescription
*>(aEnumTD
.get())->nEnumValues
; nPos
--; )
603 if (nEnumValue
== reinterpret_cast<typelib_EnumTypeDescription
*>(aEnumTD
.get())->pEnumValues
[nPos
])
610 throw CannotConvertException(
611 "value cannot be converted to demanded ENUM!",
612 Reference
< XInterface
>(), aDestinationClass
, FailReason::IS_NOT_ENUM
, 0 );
616 &reinterpret_cast<typelib_EnumTypeDescription
*>(aEnumTD
.get())->pEnumValues
[nPos
],
623 // else simple type conversion possible?
626 aRet
= convertToSimpleType( rVal
, aDestinationClass
);
628 catch (IllegalArgumentException
&)
630 // ...FailReason::INVALID is thrown
637 throw CannotConvertException(
638 "conversion not possible!",
639 Reference
< XInterface
>(), aDestinationClass
, FailReason::INVALID
, 0 );
643 Any
TypeConverter_Impl::convertToSimpleType( const Any
& rVal
, TypeClass aDestinationClass
)
645 switch (aDestinationClass
)
647 // only simple Conversion of _simple_ types
649 case TypeClass_BOOLEAN
:
651 case TypeClass_SHORT
:
652 case TypeClass_UNSIGNED_SHORT
:
654 case TypeClass_UNSIGNED_LONG
:
655 case TypeClass_HYPER
:
656 case TypeClass_UNSIGNED_HYPER
:
657 case TypeClass_FLOAT
:
658 case TypeClass_DOUBLE
:
660 case TypeClass_STRING
:
665 throw IllegalArgumentException(
666 "destination type is not simple!",
667 Reference
< XInterface
>(), sal_Int16(1) );
670 const Type
& aSourceType
= rVal
.getValueType();
671 TypeClass aSourceClass
= aSourceType
.getTypeClass();
672 if (aDestinationClass
== aSourceClass
)
678 switch (aDestinationClass
)
680 // --- to VOID ------------------------------------------------------------------------------
684 // --- to ANY -------------------------------------------------------------------------------
688 // --- to BOOL ------------------------------------------------------------------------------
689 case TypeClass_BOOLEAN
:
690 switch (aSourceClass
)
693 aRet
<<= (toDouble( rVal
) != 0.0);
695 case TypeClass_ENUM
: // exclude enums
698 case TypeClass_STRING
:
700 const OUString
& aStr
= *o3tl::forceAccess
<OUString
>(rVal
);
701 if ( aStr
== "0" || aStr
.equalsIgnoreAsciiCase( "false" ))
705 else if ( aStr
== "1" || aStr
.equalsIgnoreAsciiCase( "true" ))
711 throw CannotConvertException(
712 "STRING has no boolean value, " + aStr
,
713 Reference
< XInterface
>(), aDestinationClass
, FailReason::IS_NOT_BOOL
, 0 );
719 // --- to CHAR, BYTE ------------------------------------------------------------------------
722 if (aSourceClass
==TypeClass_STRING
)
724 auto const s
= o3tl::forceAccess
<OUString
>(rVal
);
725 if (s
->getLength() == 1) // single char
728 else if (aSourceClass
!=TypeClass_ENUM
&& // exclude enums, chars
729 aSourceClass
!=TypeClass_CHAR
)
731 aRet
<<= sal_Unicode(toHyper( rVal
, 0, 0xffff )); // range
736 aRet
<<= static_cast<sal_Int8
>( toHyper( rVal
, -sal_Int64(0x80), 0x7f ) );
739 // --- to SHORT, UNSIGNED SHORT -------------------------------------------------------------
740 case TypeClass_SHORT
:
741 aRet
<<= static_cast<sal_Int16
>( toHyper( rVal
, -sal_Int64(0x8000), 0x7fff ) );
743 case TypeClass_UNSIGNED_SHORT
:
744 aRet
<<= static_cast<sal_uInt16
>( toHyper( rVal
, 0, 0xffff ) );
747 // --- to LONG, UNSIGNED LONG ---------------------------------------------------------------
749 aRet
<<= static_cast<sal_Int32
>( toHyper( rVal
, -sal_Int64(0x80000000), 0x7fffffff ) );
751 case TypeClass_UNSIGNED_LONG
:
752 aRet
<<= static_cast<sal_uInt32
>( toHyper( rVal
, 0, 0xffffffff ) );
755 // --- to HYPER, UNSIGNED HYPER--------------------------------------------
756 case TypeClass_HYPER
:
757 aRet
<<= toHyper( rVal
, SAL_MIN_INT64
, SAL_MAX_INT64
);
759 case TypeClass_UNSIGNED_HYPER
:
760 aRet
<<= static_cast<sal_uInt64
>( toHyper( rVal
, 0 ) );
763 // --- to FLOAT, DOUBLE ---------------------------------------------------------------------
764 case TypeClass_FLOAT
:
765 aRet
<<= static_cast<float>( toDouble( rVal
, -FLT_MAX
, FLT_MAX
) );
767 case TypeClass_DOUBLE
:
768 aRet
<<= toDouble( rVal
, -DBL_MAX
, DBL_MAX
);
771 // --- to STRING ----------------------------------------------------------------------------
772 case TypeClass_STRING
:
773 switch (aSourceClass
)
777 TypeDescription
aEnumTD( aSourceType
);
778 aEnumTD
.makeComplete();
780 sal_Int32 nEnumValue
= *static_cast<sal_Int32
const *>(rVal
.getValue());
781 for ( nPos
= reinterpret_cast<typelib_EnumTypeDescription
*>(aEnumTD
.get())->nEnumValues
; nPos
--; )
783 if (nEnumValue
== reinterpret_cast<typelib_EnumTypeDescription
*>(aEnumTD
.get())->pEnumValues
[nPos
])
788 throw CannotConvertException(
789 "value is not ENUM!",
790 Reference
< XInterface
>(), aDestinationClass
, FailReason::IS_NOT_ENUM
, 0 );
793 aRet
<<= OUString::unacquired(
794 &reinterpret_cast<typelib_EnumTypeDescription
*>(aEnumTD
.get())->ppEnumNames
[nPos
]);
799 case TypeClass_BOOLEAN
:
800 aRet
<<= *o3tl::forceAccess
<bool>(rVal
) ?
805 aRet
<<= OUString(*o3tl::forceAccess
<sal_Unicode
>(rVal
));
809 aRet
<<= OUString::number( *o3tl::forceAccess
<sal_Int8
>(rVal
) );
811 case TypeClass_SHORT
:
812 aRet
<<= OUString::number( *o3tl::forceAccess
<sal_Int16
>(rVal
) );
814 case TypeClass_UNSIGNED_SHORT
:
815 aRet
<<= OUString::number( *o3tl::forceAccess
<sal_uInt16
>(rVal
) );
818 aRet
<<= OUString::number( *o3tl::forceAccess
<sal_Int32
>(rVal
) );
820 case TypeClass_UNSIGNED_LONG
:
821 aRet
<<= OUString::number( *o3tl::forceAccess
<sal_uInt32
>(rVal
) );
823 case TypeClass_HYPER
:
824 aRet
<<= OUString::number( *o3tl::forceAccess
<sal_Int64
>(rVal
) );
826 // case TypeClass_UNSIGNED_HYPER:
827 // aRet <<= OUString::valueOf( (sal_Int64)*(sal_uInt64 const *)rVal.getValue() );
829 // handle unsigned hyper like double
832 aRet
<<= OUString::number( toDouble( rVal
) );
844 throw CannotConvertException(
845 "conversion not possible!",
846 Reference
< XInterface
>(), aDestinationClass
, FailReason::INVALID
, 0 );
851 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
852 com_sun_star_comp_stoc_TypeConverter_get_implementation(css::uno::XComponentContext
*,
853 css::uno::Sequence
<css::uno::Any
> const &)
855 return ::cppu::acquire(new stoc_tcv::TypeConverter_Impl());
858 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */