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 <rtl/ustrbuf.hxx>
23 #include <typelib/typedescription.hxx>
24 #include <com/sun/star/lang/XServiceInfo.hpp>
26 #include "typedescriptionref.hxx"
28 using namespace ::com::sun::star
;
29 using ::com::sun::star::uno::TypeDescription
;
30 using ::comphelper::detail::TypeDescriptionRef
;
32 namespace comphelper
{
36 OUStringBuffer
& buf
, const typelib_TypeDescriptionReference
* typeRef
)
38 buf
.append( "<cannot get type description of type " );
39 buf
.append( OUString::unacquired( &typeRef
->pTypeName
) );
43 void appendChar( OUStringBuffer
& buf
, sal_Unicode c
)
45 if (c
< ' ' || c
> '~') {
48 OUString::number( static_cast< sal_Int32
>(c
), 16 ) );
49 for ( sal_Int32 f
= 4 - s
.getLength(); f
> 0; --f
)
59 void appendValue( OUStringBuffer
& buf
,
60 void const * val
, typelib_TypeDescriptionReference
* typeRef
,
63 if (typeRef
->eTypeClass
== typelib_TypeClass_VOID
) {
67 assert(val
!= nullptr);
70 typeRef
->eTypeClass
!= typelib_TypeClass_STRING
&&
71 typeRef
->eTypeClass
!= typelib_TypeClass_CHAR
&&
72 typeRef
->eTypeClass
!= typelib_TypeClass_BOOLEAN
)
75 buf
.append( OUString::unacquired( &typeRef
->pTypeName
) );
79 switch (typeRef
->eTypeClass
) {
80 case typelib_TypeClass_INTERFACE
: {
82 buf
.append( reinterpret_cast< sal_Int64
>(
83 *static_cast< void * const * >(val
) ), 16 );
84 uno::Reference
< lang::XServiceInfo
> xServiceInfo(
85 *static_cast< uno::XInterface
* const * >(val
),
87 if (xServiceInfo
.is()) {
88 buf
.append( " (ImplementationName = \"" );
89 buf
.append( xServiceInfo
->getImplementationName() );
94 case typelib_TypeClass_STRUCT
:
95 case typelib_TypeClass_EXCEPTION
: {
97 TypeDescription
typeDescr( typeRef
);
99 typeDescr
.makeComplete();
100 if (!typeDescr
.is()) {
101 appendTypeError( buf
, typeRef
);
104 typelib_CompoundTypeDescription
* compType
=
105 reinterpret_cast< typelib_CompoundTypeDescription
* >(
107 sal_Int32 nDescr
= compType
->nMembers
;
109 if (compType
->pBaseTypeDescription
) {
111 buf
, val
, reinterpret_cast<
112 typelib_TypeDescription
* >(
113 compType
->pBaseTypeDescription
)->pWeakRef
, false );
118 typelib_TypeDescriptionReference
** ppTypeRefs
=
119 compType
->ppTypeRefs
;
120 sal_Int32
* memberOffsets
= compType
->pMemberOffsets
;
121 rtl_uString
** ppMemberNames
= compType
->ppMemberNames
;
123 for ( sal_Int32 nPos
= 0; nPos
< nDescr
; ++nPos
)
125 buf
.append( ppMemberNames
[ nPos
] );
127 TypeDescriptionRef
memberType( ppTypeRefs
[ nPos
] );
128 if (!memberType
.is()) {
129 appendTypeError( buf
, ppTypeRefs
[ nPos
] );
133 static_cast< char const * >(
134 val
) + memberOffsets
[ nPos
],
135 memberType
->pWeakRef
, true );
137 if (nPos
< (nDescr
- 1))
144 case typelib_TypeClass_SEQUENCE
: {
145 TypeDescriptionRef
typeDescr( typeRef
);
146 if (!typeDescr
.is()) {
147 appendTypeError( buf
,typeRef
);
150 typelib_TypeDescriptionReference
* elementTypeRef
=
152 typelib_IndirectTypeDescription
* >(typeDescr
.get())->pType
;
153 TypeDescriptionRef
elementTypeDescr( elementTypeRef
);
154 if (!elementTypeDescr
.is())
156 appendTypeError( buf
, elementTypeRef
);
160 sal_Int32 nElementSize
= elementTypeDescr
->nSize
;
162 *static_cast< uno_Sequence
* const * >(val
);
163 sal_Int32 nElements
= seq
->nElements
;
168 char const * pElements
= seq
->elements
;
169 for ( sal_Int32 nPos
= 0; nPos
< nElements
; ++nPos
)
172 buf
, pElements
+ (nElementSize
* nPos
),
173 elementTypeDescr
->pWeakRef
, false );
174 if (nPos
< (nElements
- 1))
187 case typelib_TypeClass_ANY
: {
189 uno_Any
const * pAny
= static_cast< uno_Any
const * >(val
);
190 appendValue( buf
, pAny
->pData
, pAny
->pType
, true );
194 case typelib_TypeClass_TYPE
:
195 buf
.append( (*static_cast<
196 typelib_TypeDescriptionReference
* const * >(val
)
199 case typelib_TypeClass_STRING
: {
201 OUString
const & str
= OUString::unacquired(
202 static_cast< rtl_uString
* const * >(val
) );
203 sal_Int32 len
= str
.getLength();
204 for ( sal_Int32 pos
= 0; pos
< len
; ++pos
)
206 sal_Unicode c
= str
[ pos
];
208 buf
.append( "\\\"" );
210 buf
.append( "\\\\" );
212 appendChar( buf
, c
);
217 case typelib_TypeClass_ENUM
: {
218 TypeDescription
typeDescr( typeRef
);
220 typeDescr
.makeComplete();
221 if (!typeDescr
.is()) {
222 appendTypeError( buf
, typeRef
);
226 sal_Int32
* pValues
=
227 reinterpret_cast< typelib_EnumTypeDescription
* >(
228 typeDescr
.get() )->pEnumValues
;
229 sal_Int32 nPos
= reinterpret_cast< typelib_EnumTypeDescription
* >(
230 typeDescr
.get() )->nEnumValues
;
233 if (pValues
[ nPos
] == *static_cast< int const * >(val
))
238 buf
.append( reinterpret_cast< typelib_EnumTypeDescription
* >(
239 typeDescr
.get() )->ppEnumNames
[ nPos
] );
243 buf
.append( "?unknown enum value?" );
248 case typelib_TypeClass_BOOLEAN
:
249 if (*static_cast< sal_Bool
const * >(val
))
250 buf
.append( "true" );
252 buf
.append( "false" );
254 case typelib_TypeClass_CHAR
: {
256 sal_Unicode c
= *static_cast< sal_Unicode
const * >(val
);
258 buf
.append( "\\\'" );
260 buf
.append( "\\\\" );
262 appendChar( buf
, c
);
266 case typelib_TypeClass_FLOAT
:
267 buf
.append( *static_cast< float const * >(val
) );
269 case typelib_TypeClass_DOUBLE
:
270 buf
.append( *static_cast< double const * >(val
) );
272 case typelib_TypeClass_BYTE
:
273 buf
.append( static_cast< sal_Int32
>(
274 *static_cast< sal_Int8
const * >(val
) ) );
276 case typelib_TypeClass_SHORT
:
277 buf
.append( static_cast< sal_Int32
>(
278 *static_cast< sal_Int16
const * >(val
) ) );
280 case typelib_TypeClass_UNSIGNED_SHORT
:
281 buf
.append( static_cast< sal_Int32
>(
282 *static_cast< sal_uInt16
const * >(val
) ) );
284 case typelib_TypeClass_LONG
:
285 buf
.append( *static_cast< sal_Int32
const * >(val
) );
287 case typelib_TypeClass_UNSIGNED_LONG
:
288 buf
.append( static_cast< sal_Int64
>(
289 *static_cast< sal_uInt32
const * >(val
) ) );
291 case typelib_TypeClass_HYPER
:
292 case typelib_TypeClass_UNSIGNED_HYPER
:
293 buf
.append( *static_cast< sal_Int64
const * >(val
) );
295 // case typelib_TypeClass_UNKNOWN:
296 // case typelib_TypeClass_SERVICE:
297 // case typelib_TypeClass_MODULE:
307 OUString
anyToString( uno::Any
const & value
)
310 appendValue( buf
, value
.getValue(), value
.getValueTypeRef(), true );
311 return buf
.makeStringAndClear();
314 } // namespace comphelper
316 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */