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 .
21 #include <comphelper/anytostring.hxx>
22 #include <osl/diagnose.h>
23 #include <rtl/ustrbuf.hxx>
24 #include <typelib/typedescription.h>
25 #include <com/sun/star/lang/XServiceInfo.hpp>
27 using namespace ::com::sun::star
;
29 namespace comphelper
{
33 OUStringBuffer
& buf
, typelib_TypeDescriptionReference
* typeRef
)
35 buf
.append( "<cannot get type description of type " );
36 buf
.append( OUString::unacquired( &typeRef
->pTypeName
) );
40 inline void appendChar( OUStringBuffer
& buf
, sal_Unicode c
)
42 if (c
< ' ' || c
> '~') {
45 OUString::number( static_cast< sal_Int32
>(c
), 16 ) );
46 for ( sal_Int32 f
= 4 - s
.getLength(); f
> 0; --f
)
56 void appendValue( OUStringBuffer
& buf
,
57 void const * val
, typelib_TypeDescriptionReference
* typeRef
,
60 if (typeRef
->eTypeClass
== typelib_TypeClass_VOID
) {
67 typeRef
->eTypeClass
!= typelib_TypeClass_STRING
&&
68 typeRef
->eTypeClass
!= typelib_TypeClass_CHAR
&&
69 typeRef
->eTypeClass
!= typelib_TypeClass_BOOLEAN
)
72 buf
.append( OUString::unacquired( &typeRef
->pTypeName
) );
76 switch (typeRef
->eTypeClass
) {
77 case typelib_TypeClass_INTERFACE
: {
79 buf
.append( reinterpret_cast< sal_Int64
>(
80 *static_cast< void * const * >(val
) ), 16 );
81 uno::Reference
< lang::XServiceInfo
> xServiceInfo(
82 *static_cast< uno::XInterface
* const * >(val
),
84 if (xServiceInfo
.is()) {
85 buf
.append( " (ImplementationName = \"" );
86 buf
.append( xServiceInfo
->getImplementationName() );
91 case typelib_TypeClass_STRUCT
:
92 case typelib_TypeClass_EXCEPTION
: {
94 typelib_TypeDescription
* typeDescr
= 0;
95 typelib_typedescriptionreference_getDescription( &typeDescr
, typeRef
);
96 if (typeDescr
== 0 || !typelib_typedescription_complete( &typeDescr
)) {
97 appendTypeError( buf
, typeRef
);
100 typelib_CompoundTypeDescription
* compType
=
101 reinterpret_cast< typelib_CompoundTypeDescription
* >(
103 sal_Int32 nDescr
= compType
->nMembers
;
105 if (compType
->pBaseTypeDescription
) {
107 buf
, val
, reinterpret_cast<
108 typelib_TypeDescription
* >(
109 compType
->pBaseTypeDescription
)->pWeakRef
, false );
114 typelib_TypeDescriptionReference
** ppTypeRefs
=
115 compType
->ppTypeRefs
;
116 sal_Int32
* memberOffsets
= compType
->pMemberOffsets
;
117 rtl_uString
** ppMemberNames
= compType
->ppMemberNames
;
119 for ( sal_Int32 nPos
= 0; nPos
< nDescr
; ++nPos
)
121 buf
.append( ppMemberNames
[ nPos
] );
123 typelib_TypeDescription
* memberType
= 0;
124 TYPELIB_DANGER_GET( &memberType
, ppTypeRefs
[ nPos
] );
125 if (memberType
== 0) {
126 appendTypeError( buf
, ppTypeRefs
[ nPos
] );
130 static_cast< char const * >(
131 val
) + memberOffsets
[ nPos
],
132 memberType
->pWeakRef
, true );
133 TYPELIB_DANGER_RELEASE( memberType
);
135 if (nPos
< (nDescr
- 1))
141 typelib_typedescription_release( typeDescr
);
144 case typelib_TypeClass_SEQUENCE
: {
145 typelib_TypeDescription
* typeDescr
= 0;
146 TYPELIB_DANGER_GET( &typeDescr
, typeRef
);
147 if (typeDescr
== 0) {
148 appendTypeError( buf
,typeRef
);
151 typelib_TypeDescriptionReference
* elementTypeRef
=
153 typelib_IndirectTypeDescription
* >(typeDescr
)->pType
;
154 typelib_TypeDescription
* elementTypeDescr
= 0;
155 TYPELIB_DANGER_GET( &elementTypeDescr
, elementTypeRef
);
156 if (elementTypeDescr
== 0)
158 appendTypeError( buf
, elementTypeRef
);
162 sal_Int32 nElementSize
= elementTypeDescr
->nSize
;
164 *static_cast< uno_Sequence
* const * >(val
);
165 sal_Int32 nElements
= seq
->nElements
;
170 char const * pElements
= seq
->elements
;
171 for ( sal_Int32 nPos
= 0; nPos
< nElements
; ++nPos
)
174 buf
, pElements
+ (nElementSize
* nPos
),
175 elementTypeDescr
->pWeakRef
, false );
176 if (nPos
< (nElements
- 1))
185 TYPELIB_DANGER_RELEASE( elementTypeDescr
);
187 TYPELIB_DANGER_RELEASE( typeDescr
);
191 case typelib_TypeClass_ANY
: {
193 uno_Any
const * pAny
= static_cast< uno_Any
const * >(val
);
194 appendValue( buf
, pAny
->pData
, pAny
->pType
, true );
198 case typelib_TypeClass_TYPE
:
199 buf
.append( (*static_cast<
200 typelib_TypeDescriptionReference
* const * >(val
)
203 case typelib_TypeClass_STRING
: {
205 OUString
const & str
= OUString::unacquired(
206 static_cast< rtl_uString
* const * >(val
) );
207 sal_Int32 len
= str
.getLength();
208 for ( sal_Int32 pos
= 0; pos
< len
; ++pos
)
210 sal_Unicode c
= str
[ pos
];
212 buf
.append( "\\\"" );
214 buf
.append( "\\\\" );
216 appendChar( buf
, c
);
221 case typelib_TypeClass_ENUM
: {
222 typelib_TypeDescription
* typeDescr
= 0;
223 typelib_typedescriptionreference_getDescription( &typeDescr
, typeRef
);
224 if (typeDescr
== 0 || !typelib_typedescription_complete( &typeDescr
)) {
225 appendTypeError( buf
, typeRef
);
229 sal_Int32
* pValues
=
230 reinterpret_cast< typelib_EnumTypeDescription
* >(
231 typeDescr
)->pEnumValues
;
232 sal_Int32 nPos
= reinterpret_cast< typelib_EnumTypeDescription
* >(
233 typeDescr
)->nEnumValues
;
236 if (pValues
[ nPos
] == *static_cast< int const * >(val
))
241 buf
.append( reinterpret_cast< typelib_EnumTypeDescription
* >(
242 typeDescr
)->ppEnumNames
[ nPos
] );
246 buf
.append( "?unknown enum value?" );
250 typelib_typedescription_release( typeDescr
);
253 case typelib_TypeClass_BOOLEAN
:
254 if (*static_cast< sal_Bool
const * >(val
) != sal_False
)
255 buf
.append( "true" );
257 buf
.append( "false" );
259 case typelib_TypeClass_CHAR
: {
261 sal_Unicode c
= *static_cast< sal_Unicode
const * >(val
);
263 buf
.append( "\\\'" );
265 buf
.append( "\\\\" );
267 appendChar( buf
, c
);
271 case typelib_TypeClass_FLOAT
:
272 buf
.append( *static_cast< float const * >(val
) );
274 case typelib_TypeClass_DOUBLE
:
275 buf
.append( *static_cast< double const * >(val
) );
277 case typelib_TypeClass_BYTE
:
278 buf
.append( static_cast< sal_Int32
>(
279 *static_cast< sal_Int8
const * >(val
) ) );
281 case typelib_TypeClass_SHORT
:
282 buf
.append( static_cast< sal_Int32
>(
283 *static_cast< sal_Int16
const * >(val
) ) );
285 case typelib_TypeClass_UNSIGNED_SHORT
:
286 buf
.append( static_cast< sal_Int32
>(
287 *static_cast< sal_uInt16
const * >(val
) ) );
289 case typelib_TypeClass_LONG
:
290 buf
.append( *static_cast< sal_Int32
const * >(val
) );
292 case typelib_TypeClass_UNSIGNED_LONG
:
293 buf
.append( static_cast< sal_Int64
>(
294 *static_cast< sal_uInt32
const * >(val
) ) );
296 case typelib_TypeClass_HYPER
:
297 case typelib_TypeClass_UNSIGNED_HYPER
:
298 buf
.append( *static_cast< sal_Int64
const * >(val
) );
300 // case typelib_TypeClass_UNKNOWN:
301 // case typelib_TypeClass_SERVICE:
302 // case typelib_TypeClass_MODULE:
312 OUString
anyToString( uno::Any
const & value
)
315 appendValue( buf
, value
.getValue(), value
.getValueTypeRef(), true );
316 return buf
.makeStringAndClear();
319 } // namespace comphelper
321 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */