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: convert.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_stoc.hxx"
34 #include <osl/diagnose.h>
35 #include <cppuhelper/factory.hxx>
36 #include <cppuhelper/implementationentry.hxx>
37 #include <cppuhelper/implbase2.hxx>
39 #include <typelib/typedescription.hxx>
49 #include <com/sun/star/lang/XServiceInfo.hpp>
50 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
51 #include <com/sun/star/script/XTypeConverter.hpp>
52 #include <com/sun/star/script/FailReason.hpp>
53 #include <com/sun/star/container/XSet.hpp>
54 #include <com/sun/star/registry/XRegistryKey.hpp>
56 using namespace com::sun::star::uno
;
57 using namespace com::sun::star::lang
;
58 using namespace com::sun::star::script
;
59 using namespace com::sun::star::registry
;
64 #define SERVICENAME "com.sun.star.script.Converter"
65 #define IMPLNAME "com.sun.star.comp.stoc.TypeConverter"
68 extern rtl_StandardModuleCount g_moduleCount
;
70 namespace stoc_services
72 Sequence
< OUString
> tcv_getSupportedServiceNames()
74 static Sequence
< OUString
> *pNames
= 0;
77 MutexGuard
guard( Mutex::getGlobalMutex() );
80 static Sequence
< OUString
> seqNames(1);
81 seqNames
.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM(SERVICENAME
));
88 OUString
tcv_getImplementationName()
90 static OUString
*pImplName
= 0;
93 MutexGuard
guard( Mutex::getGlobalMutex() );
96 static OUString
implName( RTL_CONSTASCII_USTRINGPARAM( IMPLNAME
) );
97 pImplName
= &implName
;
107 static const sal_uInt64 SAL_UINT64_MAX
=
108 ((((sal_uInt64
)0xffffffff) << 32) | (sal_uInt64
)0xffffffff);
109 static const sal_Int64 SAL_INT64_MAX
=
110 (sal_Int64
)((((sal_uInt64
)0x7fffffff) << 32) | (sal_uInt64
)0xffffffff);
111 static const sal_Int64 SAL_INT64_MIN
=
112 (sal_Int64
)(((sal_uInt64
)0x80000000) << 32);
114 /* MS Visual C++ no conversion from unsigned __int64 to double */
116 static const double DOUBLE_SAL_UINT64_MAX
= ((((double)SAL_INT64_MAX
) * 2) + 1);
118 static inline double unsigned_int64_to_double( sal_uInt64 n
) SAL_THROW( () )
120 sal_uInt64 n2
= (n
/ 3);
122 return (((double)(sal_Int64
)n2
) * 2.0) + ((double)(sal_Int64
)n
);
125 static const double DOUBLE_SAL_UINT64_MAX
=
126 (double)((((sal_uInt64
)0xffffffff) << 32) | (sal_uInt64
)0xffffffff);
128 static inline double unsigned_int64_to_double( sal_uInt64 n
) SAL_THROW( () )
135 //--------------------------------------------------------------------------------------------------
136 static inline double round( double aVal
)
138 sal_Bool bPos
= (aVal
>= 0.0); //
139 aVal
= ::fabs( aVal
);
140 double aUpper
= ::ceil( aVal
);
142 aVal
= ((aUpper
-aVal
) <= 0.5) ? aUpper
: (aUpper
- 1.0);
143 return (bPos
? aVal
: -aVal
);
146 //--------------------------------------------------------------------------------------------------
147 static sal_Bool
getNumericValue( double & rfVal
, const OUString
& rStr
)
149 double fRet
= rStr
.toDouble();
152 sal_Int32 nLen
= rStr
.getLength();
153 if (!nLen
|| (nLen
== 1 && rStr
[0] == '0')) // common case
159 OUString
trim( rStr
.trim() );
162 sal_Int32 nX
= trim
.indexOf( 'x' );
164 nX
= trim
.indexOf( 'X' );
166 if (nX
> 0 && trim
[nX
-1] == '0') // 0x
168 sal_Bool bNeg
= sal_False
;
171 case 2: // (+|-)0x...
174 else if (trim
[0] != '+')
182 OUString
aHexRest( trim
.copy( nX
+1 ) );
183 sal_Int64 nRet
= aHexRest
.toInt64( 16 );
187 for ( sal_Int32 nPos
= aHexRest
.getLength(); nPos
--; )
189 if (aHexRest
[nPos
] != '0')
194 rfVal
= (bNeg
? -(double)nRet
: (double)nRet
);
198 nLen
= trim
.getLength();
202 if (nLen
&& (trim
[0] == '-' || trim
[0] == '+'))
205 while (nPos
< nLen
) // skip leading zeros
207 if (trim
[nPos
] != '0')
209 if (trim
[nPos
] != '.')
212 while (nPos
< nLen
) // skip trailing zeros
214 if (trim
[nPos
] != '0')
227 //==================================================================================================
228 static sal_Bool
getHyperValue( sal_Int64
& rnVal
, const OUString
& rStr
)
230 sal_Int32 nLen
= rStr
.getLength();
231 if (!nLen
|| (nLen
== 1 && rStr
[0] == '0')) // common case
237 OUString
trim( rStr
.trim() );
240 sal_Int32 nX
= trim
.indexOf( 'x' );
242 nX
= trim
.indexOf( 'X' );
246 if (nX
> 0 && trim
[nX
-1] == '0') // 0x
248 sal_Bool bNeg
= sal_False
;
251 case 2: // (+|-)0x...
254 else if (trim
[0] != '+')
262 OUString
aHexRest( trim
.copy( nX
+1 ) );
263 sal_Int64 nRet
= aHexRest
.toInt64( 16 );
267 for ( sal_Int32 nPos
= aHexRest
.getLength(); nPos
--; )
269 if (aHexRest
[nPos
] != '0')
274 rnVal
= (bNeg
? -nRet
: nRet
);
281 if (getNumericValue( fVal
, rStr
) &&
282 fVal
>= (double)SAL_INT64_MIN
&&
283 fVal
<= DOUBLE_SAL_UINT64_MAX
)
285 rnVal
= (sal_Int64
)round( fVal
);
291 //==================================================================================================
292 class TypeConverter_Impl
: public WeakImplHelper2
< XTypeConverter
, XServiceInfo
>
294 // ...misc helpers...
296 const Any
& rAny
, sal_Int64 min
= SAL_INT64_MIN
, sal_uInt64 max
= SAL_UINT64_MAX
)
297 throw( CannotConvertException
);
298 double toDouble( const Any
& rAny
, double min
= -DBL_MAX
, double max
= DBL_MAX
) const
299 throw( CannotConvertException
);
302 TypeConverter_Impl();
303 virtual ~TypeConverter_Impl();
306 virtual OUString SAL_CALL
getImplementationName() throw( RuntimeException
);
307 virtual sal_Bool SAL_CALL
supportsService(const OUString
& ServiceName
)
308 throw( RuntimeException
);
309 virtual Sequence
< OUString
> SAL_CALL
getSupportedServiceNames(void)
310 throw( RuntimeException
);
313 virtual Any SAL_CALL
convertTo( const Any
& aFrom
, const Type
& DestinationType
)
314 throw( IllegalArgumentException
, CannotConvertException
, RuntimeException
);
315 virtual Any SAL_CALL
convertToSimpleType( const Any
& aFrom
, TypeClass aDestinationType
)
316 throw( IllegalArgumentException
, CannotConvertException
, RuntimeException
);
319 TypeConverter_Impl::TypeConverter_Impl()
321 g_moduleCount
.modCnt
.acquire( &g_moduleCount
.modCnt
);
324 TypeConverter_Impl::~TypeConverter_Impl()
326 g_moduleCount
.modCnt
.release( &g_moduleCount
.modCnt
);
330 OUString
TypeConverter_Impl::getImplementationName() throw( RuntimeException
)
332 return stoc_services::tcv_getImplementationName();
336 sal_Bool
TypeConverter_Impl::supportsService(const OUString
& ServiceName
) throw( RuntimeException
)
338 Sequence
< OUString
> aSNL
= getSupportedServiceNames();
339 const OUString
* pArray
= aSNL
.getConstArray();
340 for( sal_Int32 i
= 0; i
< aSNL
.getLength(); i
++ )
341 if( pArray
[i
] == ServiceName
)
347 Sequence
< OUString
> TypeConverter_Impl::getSupportedServiceNames(void) throw( RuntimeException
)
349 return stoc_services::tcv_getSupportedServiceNames();
352 //--------------------------------------------------------------------------------------------------
353 sal_Int64
TypeConverter_Impl::toHyper( const Any
& rAny
, sal_Int64 min
, sal_uInt64 max
)
354 throw( CannotConvertException
)
357 TypeClass aDestinationClass
= rAny
.getValueTypeClass();
359 switch (aDestinationClass
)
363 nRet
= *(sal_Int32
*)rAny
.getValue();
366 case TypeClass_BOOLEAN
:
367 nRet
= (*(sal_Bool
*)rAny
.getValue() ? 1 : 0);
371 nRet
= *(sal_Unicode
*)rAny
.getValue();
374 nRet
= *(sal_Int8
*)rAny
.getValue();
377 case TypeClass_SHORT
:
378 nRet
= *(sal_Int16
*)rAny
.getValue();
381 case TypeClass_UNSIGNED_SHORT
:
382 nRet
= *(sal_uInt16
*)rAny
.getValue();
386 nRet
= *(sal_Int32
*)rAny
.getValue();
389 case TypeClass_UNSIGNED_LONG
:
390 nRet
= *(sal_uInt32
*)rAny
.getValue();
393 case TypeClass_HYPER
:
394 nRet
= *(sal_Int64
*)rAny
.getValue();
397 case TypeClass_UNSIGNED_HYPER
:
399 nRet
= *(sal_Int64
*)rAny
.getValue();
400 if ((min
< 0 || (sal_uInt64
)nRet
>= (sal_uInt64
)min
) && // lower bound
401 (sal_uInt64
)nRet
<= max
) // upper bound
405 throw CannotConvertException(
406 OUString( RTL_CONSTASCII_USTRINGPARAM("UNSIGNED HYPER out of range!") ),
407 Reference
<XInterface
>(), aDestinationClass
, FailReason::OUT_OF_RANGE
, 0 );
411 case TypeClass_FLOAT
:
413 double fVal
= round( *(float *)rAny
.getValue() );
414 nRet
= (fVal
> SAL_INT64_MAX
? (sal_Int64
)(sal_uInt64
)fVal
: (sal_Int64
)fVal
);
415 if (fVal
>= min
&& fVal
<= unsigned_int64_to_double( max
))
419 throw CannotConvertException(
420 OUString( RTL_CONSTASCII_USTRINGPARAM("FLOAT out of range!") ),
421 Reference
<XInterface
>(), aDestinationClass
, FailReason::OUT_OF_RANGE
, 0 );
423 case TypeClass_DOUBLE
:
425 double fVal
= round( *(double *)rAny
.getValue() );
426 nRet
= (fVal
> SAL_INT64_MAX
? (sal_Int64
)(sal_uInt64
)fVal
: (sal_Int64
)fVal
);
427 if (fVal
>= min
&& fVal
<= unsigned_int64_to_double( max
))
431 throw CannotConvertException(
432 OUString( RTL_CONSTASCII_USTRINGPARAM("DOUBLE out of range!") ),
433 Reference
<XInterface
>(), aDestinationClass
, FailReason::OUT_OF_RANGE
, 0 );
437 case TypeClass_STRING
:
439 sal_Int64 fVal
= SAL_CONST_INT64(0);
440 if (! getHyperValue( fVal
, *(OUString
const *)rAny
.getValue() ))
442 throw CannotConvertException(
443 OUString( RTL_CONSTASCII_USTRINGPARAM("invalid STRING value!") ),
444 Reference
<XInterface
>(), aDestinationClass
, FailReason::IS_NOT_NUMBER
, 0 );
446 nRet
= (fVal
> SAL_INT64_MAX
? (sal_Int64
)(sal_uInt64
)fVal
: (sal_Int64
)fVal
);
447 if (fVal
>= min
&& (fVal
< 0 || ((sal_uInt64
)fVal
) <= max
))
449 throw CannotConvertException(
450 OUString( RTL_CONSTASCII_USTRINGPARAM("STRING value out of range!") ),
451 Reference
<XInterface
>(), aDestinationClass
, FailReason::OUT_OF_RANGE
, 0 );
455 throw CannotConvertException(
456 OUString( RTL_CONSTASCII_USTRINGPARAM("TYPE is not supported!") ),
457 Reference
<XInterface
>(), aDestinationClass
, FailReason::TYPE_NOT_SUPPORTED
, 0 );
460 if (nRet
>= min
&& (nRet
< 0 || (sal_uInt64
)nRet
<= max
))
462 throw CannotConvertException(
463 OUString( RTL_CONSTASCII_USTRINGPARAM("VALUE is out of range!") ),
464 Reference
<XInterface
>(), aDestinationClass
, FailReason::OUT_OF_RANGE
, 0 );
467 //--------------------------------------------------------------------------------------------------
468 double TypeConverter_Impl::toDouble( const Any
& rAny
, double min
, double max
) const
469 throw( CannotConvertException
)
472 TypeClass aDestinationClass
= rAny
.getValueTypeClass();
474 switch (aDestinationClass
)
478 fRet
= *(sal_Int32
*)rAny
.getValue();
481 case TypeClass_BOOLEAN
:
482 fRet
= (*(sal_Bool
*)rAny
.getValue() ? 1.0 : 0.0);
486 fRet
= *(sal_Unicode
*)rAny
.getValue();
489 fRet
= *(sal_Int8
*)rAny
.getValue();
492 case TypeClass_SHORT
:
493 fRet
= *(sal_Int16
*)rAny
.getValue();
496 case TypeClass_UNSIGNED_SHORT
:
497 fRet
= *(sal_uInt16
*)rAny
.getValue();
501 fRet
= *(sal_Int32
*)rAny
.getValue();
504 case TypeClass_UNSIGNED_LONG
:
505 fRet
= *(sal_uInt32
*)rAny
.getValue();
508 case TypeClass_HYPER
:
509 fRet
= (double)*(sal_Int64
*)rAny
.getValue();
512 case TypeClass_UNSIGNED_HYPER
:
513 fRet
= unsigned_int64_to_double( *(sal_uInt64
const *)rAny
.getValue() );
516 case TypeClass_FLOAT
:
517 fRet
= *(float *)rAny
.getValue();
519 case TypeClass_DOUBLE
:
520 fRet
= *(double *)rAny
.getValue();
524 case TypeClass_STRING
:
526 if (! getNumericValue( fRet
, *(OUString
*)rAny
.getValue() ))
528 throw CannotConvertException(
529 OUString( RTL_CONSTASCII_USTRINGPARAM("invalid STRING value!") ),
530 Reference
<XInterface
>(), aDestinationClass
, FailReason::IS_NOT_NUMBER
, 0 );
536 throw CannotConvertException(
537 OUString( RTL_CONSTASCII_USTRINGPARAM("TYPE is not supported!") ),
538 Reference
< XInterface
>(), aDestinationClass
, FailReason::TYPE_NOT_SUPPORTED
, 0 );
541 if (fRet
>= min
&& fRet
<= max
)
543 throw CannotConvertException(
544 OUString( RTL_CONSTASCII_USTRINGPARAM("VALUE is out of range!") ),
545 Reference
< XInterface
>(), aDestinationClass
, FailReason::OUT_OF_RANGE
, 0 );
548 //--------------------------------------------------------------------------------------------------
549 Any SAL_CALL
TypeConverter_Impl::convertTo( const Any
& rVal
, const Type
& aDestType
)
550 throw( IllegalArgumentException
, CannotConvertException
, RuntimeException
)
552 Type aSourceType
= rVal
.getValueType();
553 if (aSourceType
== aDestType
)
556 TypeClass aSourceClass
= aSourceType
.getTypeClass();
557 TypeClass aDestinationClass
= aDestType
.getTypeClass();
562 switch (aDestinationClass
)
564 // --- to VOID ------------------------------------------------------------------------------
567 // --- to ANY -------------------------------------------------------------------------------
571 // --- to STRUCT, UNION, EXCEPTION ----------------------------------------------------------
572 case TypeClass_STRUCT
:
573 // case TypeClass_UNION: // xxx todo
574 case TypeClass_EXCEPTION
:
576 // same types or destination type is derived source type?
577 TypeDescription
aSourceTD( aSourceType
);
578 TypeDescription
aDestTD( aDestType
);
579 if (typelib_typedescription_isAssignableFrom( aDestTD
.get(), aSourceTD
.get() ))
581 aRet
.setValue( rVal
.getValue(), aDestTD
.get() ); // evtl. .uP.cAsT.
585 throw CannotConvertException(
586 OUString( RTL_CONSTASCII_USTRINGPARAM("value is not of same or derived type!") ),
587 Reference
< XInterface
>(), aDestinationClass
,
588 FailReason::SOURCE_IS_NO_DERIVED_TYPE
, 0 );
592 // --- to INTERFACE -------------------------------------------------------------------------
593 case TypeClass_INTERFACE
:
595 if (! rVal
.hasValue())
597 // void -> interface (null)
599 aRet
.setValue( &null_ref
, aDestType
);
603 if (rVal
.getValueTypeClass() != TypeClass_INTERFACE
||
604 !*(XInterface
* const *)rVal
.getValue())
606 throw CannotConvertException(
607 OUString( RTL_CONSTASCII_USTRINGPARAM("value is no interface!") ),
608 Reference
< XInterface
>(), aDestinationClass
, FailReason::NO_SUCH_INTERFACE
, 0 );
610 if (! (aRet
= (*(XInterface
* const *)rVal
.getValue())->queryInterface(
611 aDestType
)).hasValue())
613 throw CannotConvertException(
614 OUString( RTL_CONSTASCII_USTRINGPARAM("value has no such interface!") ),
615 Reference
< XInterface
>(), aDestinationClass
, FailReason::NO_SUCH_INTERFACE
, 0 );
619 // --- to SEQUENCE --------------------------------------------------------------------------
620 case TypeClass_SEQUENCE
:
622 if (aSourceClass
==TypeClass_SEQUENCE
)
624 if( aSourceType
== aDestType
)
627 TypeDescription
aSourceTD( aSourceType
);
628 TypeDescription
aDestTD( aDestType
);
629 typelib_TypeDescription
* pSourceElementTD
= 0;
632 ((typelib_IndirectTypeDescription
*)aSourceTD
.get())->pType
);
633 typelib_TypeDescription
* pDestElementTD
= 0;
636 ((typelib_IndirectTypeDescription
*)aDestTD
.get())->pType
);
638 sal_uInt32 nPos
= (*(const uno_Sequence
* const *)rVal
.getValue())->nElements
;
639 uno_Sequence
* pRet
= 0;
640 uno_sequence_construct(
641 &pRet
, aDestTD
.get(), 0, nPos
,
642 reinterpret_cast< uno_AcquireFunc
>(cpp_acquire
) );
643 aRet
.setValue( &pRet
, aDestTD
.get() );
645 &pRet
, aDestTD
.get(),
646 reinterpret_cast< uno_ReleaseFunc
>(cpp_release
) );
649 char * pDestElements
= (*(uno_Sequence
* const *)aRet
.getValue())->elements
;
650 const char * pSourceElements
=
651 (*(const uno_Sequence
* const *)rVal
.getValue())->elements
;
655 char * pDestPos
= pDestElements
+ (nPos
* pDestElementTD
->nSize
);
656 const char * pSourcePos
= pSourceElements
+ (nPos
* pSourceElementTD
->nSize
);
659 convertTo( Any( pSourcePos
, pSourceElementTD
), pDestElementTD
->pWeakRef
) );
662 pDestPos
, pDestElementTD
,
663 (pDestElementTD
->eTypeClass
== typelib_TypeClass_ANY
665 : const_cast< void * >( aElement
.getValue() )),
667 reinterpret_cast< uno_QueryInterfaceFunc
>(
669 reinterpret_cast< uno_AcquireFunc
>(cpp_acquire
),
670 reinterpret_cast< uno_ReleaseFunc
>(cpp_release
) ))
675 TYPELIB_DANGER_RELEASE( pDestElementTD
);
676 TYPELIB_DANGER_RELEASE( pSourceElementTD
);
680 // --- to ENUM ------------------------------------------------------------------------------
683 TypeDescription
aEnumTD( aDestType
);
684 aEnumTD
.makeComplete();
687 if (aSourceClass
==TypeClass_STRING
)
689 for ( nPos
= ((typelib_EnumTypeDescription
*)aEnumTD
.get())->nEnumValues
; nPos
--; )
691 if (((const OUString
*)rVal
.getValue())->equalsIgnoreAsciiCase(
692 ((typelib_EnumTypeDescription
*)aEnumTD
.get())->ppEnumNames
[nPos
] ))
696 else if (aSourceClass
!=TypeClass_ENUM
&& // exclude some unwanted types for toHyper()
697 aSourceClass
!=TypeClass_BOOLEAN
&&
698 aSourceClass
!=TypeClass_CHAR
)
700 sal_Int32 nEnumValue
= (sal_Int32
)toHyper( rVal
, -(sal_Int64
)0x80000000, 0x7fffffff );
701 for ( nPos
= ((typelib_EnumTypeDescription
*)aEnumTD
.get())->nEnumValues
; nPos
--; )
703 if (nEnumValue
== ((typelib_EnumTypeDescription
*)aEnumTD
.get())->pEnumValues
[nPos
])
711 &((typelib_EnumTypeDescription
*)aEnumTD
.get())->pEnumValues
[nPos
],
716 throw CannotConvertException(
718 RTL_CONSTASCII_USTRINGPARAM("value cannot be converted to demanded ENUM!") ),
719 Reference
< XInterface
>(), aDestinationClass
, FailReason::IS_NOT_ENUM
, 0 );
725 // else simple type conversion possible?
728 aRet
= convertToSimpleType( rVal
, aDestinationClass
);
730 catch (IllegalArgumentException
&)
732 // ...FailReason::INVALID is thrown
739 throw CannotConvertException(
740 OUString( RTL_CONSTASCII_USTRINGPARAM("conversion not possible!") ),
741 Reference
< XInterface
>(), aDestinationClass
, FailReason::INVALID
, 0 );
744 //--------------------------------------------------------------------------------------------------
745 Any
TypeConverter_Impl::convertToSimpleType( const Any
& rVal
, TypeClass aDestinationClass
)
746 throw( IllegalArgumentException
, CannotConvertException
, RuntimeException
)
748 switch (aDestinationClass
)
750 // only simple Conversion of _simple_ types
751 case TypeClass_INTERFACE
:
752 case TypeClass_SERVICE
:
753 case TypeClass_STRUCT
:
754 case TypeClass_TYPEDEF
:
755 case TypeClass_UNION
:
756 case TypeClass_EXCEPTION
:
757 case TypeClass_ARRAY
:
758 case TypeClass_SEQUENCE
:
760 case TypeClass_UNKNOWN
:
761 case TypeClass_MODULE
:
762 throw IllegalArgumentException(
763 OUString( RTL_CONSTASCII_USTRINGPARAM("destination type is not simple!") ),
764 Reference
< XInterface
>(), (sal_Int16
) 1 );
769 Type aSourceType
= rVal
.getValueType();
770 TypeClass aSourceClass
= aSourceType
.getTypeClass();
771 if (aDestinationClass
== aSourceClass
)
777 switch (aDestinationClass
)
779 // --- to VOID ------------------------------------------------------------------------------
783 // --- to ANY -------------------------------------------------------------------------------
787 // --- to BOOL ------------------------------------------------------------------------------
788 case TypeClass_BOOLEAN
:
789 switch (aSourceClass
)
793 sal_Bool bTmp
= (toDouble( rVal
) != 0.0);
794 aRet
.setValue( &bTmp
, getBooleanCppuType() );
796 case TypeClass_ENUM
: // exclude enums
799 case TypeClass_STRING
:
801 const OUString
& aStr
= *(const OUString
*)rVal
.getValue();
802 if (aStr
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("0") ) ||
803 aStr
.equalsIgnoreAsciiCase( OUString( RTL_CONSTASCII_USTRINGPARAM("false") ) ))
805 sal_Bool bFalse
= sal_False
;
806 aRet
.setValue( &bFalse
, getCppuBooleanType() );
808 else if (aStr
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("1") ) ||
809 aStr
.equalsIgnoreAsciiCase( OUString( RTL_CONSTASCII_USTRINGPARAM("true") ) ))
811 sal_Bool bTrue
= sal_True
;
812 aRet
.setValue( &bTrue
, getCppuBooleanType() );
816 throw CannotConvertException(
817 OUString( RTL_CONSTASCII_USTRINGPARAM("STRING has no boolean value!") ),
818 Reference
< XInterface
>(), aDestinationClass
, FailReason::IS_NOT_BOOL
, 0 );
824 // --- to CHAR, BYTE ------------------------------------------------------------------------
827 if (aSourceClass
==TypeClass_STRING
)
829 if ((*(const OUString
*)rVal
.getValue()).getLength() == 1) // single char
830 aRet
.setValue( (*(const OUString
*)rVal
.getValue()).getStr(), ::getCharCppuType() );
832 else if (aSourceClass
!=TypeClass_ENUM
&& // exclude enums, chars
833 aSourceClass
!=TypeClass_CHAR
)
835 sal_Unicode cRet
= (sal_Unicode
)toHyper( rVal
, 0, 0xffff ); // range
836 aRet
.setValue( &cRet
, ::getCharCppuType() );
841 aRet
<<= (sal_Int8
)( toHyper( rVal
, -(sal_Int64
)0x80, 0x7f ) );
844 // --- to SHORT, UNSIGNED SHORT -------------------------------------------------------------
845 case TypeClass_SHORT
:
846 aRet
<<= (sal_Int16
)( toHyper( rVal
, -(sal_Int64
)0x8000, 0x7fff ) );
848 case TypeClass_UNSIGNED_SHORT
:
849 aRet
<<= (sal_uInt16
)( toHyper( rVal
, 0, 0xffff ) );
852 // --- to LONG, UNSIGNED LONG ---------------------------------------------------------------
854 aRet
<<= (sal_Int32
)( toHyper( rVal
, -(sal_Int64
)0x80000000, 0x7fffffff ) );
856 case TypeClass_UNSIGNED_LONG
:
857 aRet
<<= (sal_uInt32
)( toHyper( rVal
, 0, 0xffffffff ) );
860 // --- to HYPER, UNSIGNED HYPER--------------------------------------------
861 case TypeClass_HYPER
:
862 aRet
<<= toHyper( rVal
, SAL_INT64_MIN
, SAL_INT64_MAX
);
864 case TypeClass_UNSIGNED_HYPER
:
865 aRet
<<= (sal_uInt64
)( toHyper( rVal
, 0, SAL_UINT64_MAX
) );
868 // --- to FLOAT, DOUBLE ---------------------------------------------------------------------
869 case TypeClass_FLOAT
:
870 aRet
<<= (float)( toDouble( rVal
, -FLT_MAX
, FLT_MAX
) );
872 case TypeClass_DOUBLE
:
873 aRet
<<= (double)( toDouble( rVal
, -DBL_MAX
, DBL_MAX
) );
876 // --- to STRING ----------------------------------------------------------------------------
877 case TypeClass_STRING
:
878 switch (aSourceClass
)
882 TypeDescription
aEnumTD( aSourceType
);
883 aEnumTD
.makeComplete();
885 sal_Int32 nEnumValue
= *(sal_Int32
*)rVal
.getValue();
886 for ( nPos
= ((typelib_EnumTypeDescription
*)aEnumTD
.get())->nEnumValues
; nPos
--; )
888 if (nEnumValue
== ((typelib_EnumTypeDescription
*)aEnumTD
.get())->pEnumValues
[nPos
])
894 &((typelib_EnumTypeDescription
*)aEnumTD
.get())->ppEnumNames
[nPos
],
895 ::getCppuType( (const OUString
*)0 ) );
899 throw CannotConvertException(
900 OUString( RTL_CONSTASCII_USTRINGPARAM("value is not ENUM!") ),
901 Reference
< XInterface
>(), aDestinationClass
, FailReason::IS_NOT_ENUM
, 0 );
906 case TypeClass_BOOLEAN
:
907 aRet
<<= OUString::createFromAscii( (*(sal_Bool
*)rVal
.getValue() ? "true" : "false") );
910 aRet
<<= OUString( (sal_Unicode
*)rVal
.getValue(), 1 );
914 aRet
<<= OUString::valueOf( (sal_Int32
)*(sal_Int8
const *)rVal
.getValue() );
916 case TypeClass_SHORT
:
917 aRet
<<= OUString::valueOf( (sal_Int32
)*(sal_Int16
const *)rVal
.getValue() );
919 case TypeClass_UNSIGNED_SHORT
:
920 aRet
<<= OUString::valueOf( (sal_Int32
)*(sal_uInt16
const *)rVal
.getValue() );
923 aRet
<<= OUString::valueOf( *(sal_Int32
const *)rVal
.getValue() );
925 case TypeClass_UNSIGNED_LONG
:
926 aRet
<<= OUString::valueOf( (sal_Int64
)*(sal_uInt32
const *)rVal
.getValue() );
928 case TypeClass_HYPER
:
929 aRet
<<= OUString::valueOf( *(sal_Int64
const *)rVal
.getValue() );
931 // case TypeClass_UNSIGNED_HYPER:
932 // aRet <<= OUString::valueOf( (sal_Int64)*(sal_uInt64 const *)rVal.getValue() );
934 // handle unsigned hyper like double
937 aRet
<<= OUString::valueOf( toDouble( rVal
) );
949 throw CannotConvertException(
950 OUString( RTL_CONSTASCII_USTRINGPARAM("conversion not possible!") ),
951 Reference
< XInterface
>(), aDestinationClass
, FailReason::INVALID
, 0 );
955 namespace stoc_services
957 //*************************************************************************
958 Reference
< XInterface
> SAL_CALL
TypeConverter_Impl_CreateInstance(
959 const Reference
< XComponentContext
> & )
960 throw( RuntimeException
)
962 static Reference
< XInterface
> s_ref( (OWeakObject
*) new stoc_tcv::TypeConverter_Impl() );