LibreOffice Module comphelper (master)  1
anytostring.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 
22 #include <rtl/ustrbuf.hxx>
23 #include <typelib/typedescription.hxx>
24 #include <com/sun/star/lang/XServiceInfo.hpp>
25 
26 #include "typedescriptionref.hxx"
27 
28 using namespace ::com::sun::star;
29 using ::com::sun::star::uno::TypeDescription;
30 using ::comphelper::detail::TypeDescriptionRef;
31 
32 namespace comphelper {
33 namespace {
34 
35 void appendTypeError(
36  OUStringBuffer & buf, const typelib_TypeDescriptionReference * typeRef )
37 {
38  buf.append( "<cannot get type description of type " );
39  buf.append( OUString::unacquired( &typeRef->pTypeName ) );
40  buf.append( '>' );
41 }
42 
43 void appendChar( OUStringBuffer & buf, sal_Unicode c )
44 {
45  if (c < ' ' || c > '~') {
46  buf.append( "\\X" );
47  OUString const s(
48  OUString::number( static_cast< sal_Int32 >(c), 16 ) );
49  for ( sal_Int32 f = 4 - s.getLength(); f > 0; --f )
50  buf.append( '0' );
51  buf.append( s );
52  }
53  else {
54  buf.append( c );
55  }
56 }
57 
58 
59 void appendValue( OUStringBuffer & buf,
60  void const * val, typelib_TypeDescriptionReference * typeRef,
61  bool prependType )
62 {
63  if (typeRef->eTypeClass == typelib_TypeClass_VOID) {
64  buf.append( "void" );
65  return;
66  }
67  assert(val != nullptr);
68 
69  if (prependType &&
70  typeRef->eTypeClass != typelib_TypeClass_STRING &&
71  typeRef->eTypeClass != typelib_TypeClass_CHAR &&
72  typeRef->eTypeClass != typelib_TypeClass_BOOLEAN)
73  {
74  buf.append( '(' );
75  buf.append( OUString::unacquired( &typeRef->pTypeName ) );
76  buf.append( ") " );
77  }
78 
79  switch (typeRef->eTypeClass) {
80  case typelib_TypeClass_INTERFACE: {
81  buf.append( '@' );
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),
86  uno::UNO_QUERY );
87  if (xServiceInfo.is()) {
88  buf.append( " (ImplementationName = \"" );
89  buf.append( xServiceInfo->getImplementationName() );
90  buf.append( "\")" );
91  }
92  break;
93  }
94  case typelib_TypeClass_STRUCT:
95  case typelib_TypeClass_EXCEPTION: {
96  buf.append( "{ " );
97  TypeDescription typeDescr( typeRef );
98  if (!typeDescr.is())
99  typeDescr.makeComplete();
100  if (!typeDescr.is()) {
101  appendTypeError( buf, typeRef );
102  }
103  else {
104  typelib_CompoundTypeDescription * compType =
105  reinterpret_cast< typelib_CompoundTypeDescription * >(
106  typeDescr.get() );
107  sal_Int32 nDescr = compType->nMembers;
108 
109  if (compType->pBaseTypeDescription) {
110  appendValue(
111  buf, val, reinterpret_cast<
113  compType->pBaseTypeDescription)->pWeakRef, false );
114  if (nDescr > 0)
115  buf.append( ", " );
116  }
117 
118  typelib_TypeDescriptionReference ** ppTypeRefs =
119  compType->ppTypeRefs;
120  sal_Int32 * memberOffsets = compType->pMemberOffsets;
121  rtl_uString ** ppMemberNames = compType->ppMemberNames;
122 
123  for ( sal_Int32 nPos = 0; nPos < nDescr; ++nPos )
124  {
125  buf.append( ppMemberNames[ nPos ] );
126  buf.append( " = " );
127  TypeDescriptionRef memberType( ppTypeRefs[ nPos ] );
128  if (!memberType.is()) {
129  appendTypeError( buf, ppTypeRefs[ nPos ] );
130  }
131  else {
132  appendValue( buf,
133  static_cast< char const * >(
134  val ) + memberOffsets[ nPos ],
135  memberType->pWeakRef, true );
136  }
137  if (nPos < (nDescr - 1))
138  buf.append( ", " );
139  }
140  }
141  buf.append( " }" );
142  break;
143  }
144  case typelib_TypeClass_SEQUENCE: {
145  TypeDescriptionRef typeDescr( typeRef );
146  if (!typeDescr.is()) {
147  appendTypeError( buf,typeRef );
148  }
149  else {
150  typelib_TypeDescriptionReference * elementTypeRef =
151  reinterpret_cast<
152  typelib_IndirectTypeDescription * >(typeDescr.get())->pType;
153  TypeDescriptionRef elementTypeDescr( elementTypeRef );
154  if (!elementTypeDescr.is())
155  {
156  appendTypeError( buf, elementTypeRef );
157  }
158  else
159  {
160  sal_Int32 nElementSize = elementTypeDescr->nSize;
161  uno_Sequence * seq =
162  *static_cast< uno_Sequence * const * >(val);
163  sal_Int32 nElements = seq->nElements;
164 
165  if (nElements > 0)
166  {
167  buf.append( "{ " );
168  char const * pElements = seq->elements;
169  for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
170  {
171  appendValue(
172  buf, pElements + (nElementSize * nPos),
173  elementTypeDescr->pWeakRef, false );
174  if (nPos < (nElements - 1))
175  buf.append( ", " );
176  }
177  buf.append( " }" );
178  }
179  else
180  {
181  buf.append( "{}" );
182  }
183  }
184  }
185  break;
186  }
187  case typelib_TypeClass_ANY: {
188  buf.append( "{ " );
189  uno_Any const * pAny = static_cast< uno_Any const * >(val);
190  appendValue( buf, pAny->pData, pAny->pType, true );
191  buf.append( " }" );
192  break;
193  }
194  case typelib_TypeClass_TYPE:
195  buf.append( (*static_cast<
196  typelib_TypeDescriptionReference * const * >(val)
197  )->pTypeName );
198  break;
199  case typelib_TypeClass_STRING: {
200  buf.append( '\"' );
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 )
205  {
206  sal_Unicode c = str[ pos ];
207  if (c == '\"')
208  buf.append( "\\\"" );
209  else if (c == '\\')
210  buf.append( "\\\\" );
211  else
212  appendChar( buf, c );
213  }
214  buf.append( '\"' );
215  break;
216  }
217  case typelib_TypeClass_ENUM: {
218  TypeDescription typeDescr( typeRef );
219  if (!typeDescr.is())
220  typeDescr.makeComplete();
221  if (!typeDescr.is()) {
222  appendTypeError( buf, typeRef );
223  }
224  else
225  {
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;
231  while (nPos--)
232  {
233  if (pValues[ nPos ] == *static_cast< int const * >(val))
234  break;
235  }
236  if (nPos >= 0)
237  {
238  buf.append( reinterpret_cast< typelib_EnumTypeDescription * >(
239  typeDescr.get() )->ppEnumNames[ nPos ] );
240  }
241  else
242  {
243  buf.append( "?unknown enum value?" );
244  }
245  }
246  break;
247  }
248  case typelib_TypeClass_BOOLEAN:
249  if (*static_cast< sal_Bool const * >(val))
250  buf.append( "true" );
251  else
252  buf.append( "false" );
253  break;
254  case typelib_TypeClass_CHAR: {
255  buf.append( '\'' );
256  sal_Unicode c = *static_cast< sal_Unicode const * >(val);
257  if (c == '\'')
258  buf.append( "\\\'" );
259  else if (c == '\\')
260  buf.append( "\\\\" );
261  else
262  appendChar( buf, c );
263  buf.append( '\'' );
264  break;
265  }
266  case typelib_TypeClass_FLOAT:
267  buf.append( *static_cast< float const * >(val) );
268  break;
269  case typelib_TypeClass_DOUBLE:
270  buf.append( *static_cast< double const * >(val) );
271  break;
272  case typelib_TypeClass_BYTE:
273  buf.append( static_cast< sal_Int32 >(
274  *static_cast< sal_Int8 const * >(val) ) );
275  break;
276  case typelib_TypeClass_SHORT:
277  buf.append( static_cast< sal_Int32 >(
278  *static_cast< sal_Int16 const * >(val) ) );
279  break;
280  case typelib_TypeClass_UNSIGNED_SHORT:
281  buf.append( static_cast< sal_Int32 >(
282  *static_cast< sal_uInt16 const * >(val) ) );
283  break;
284  case typelib_TypeClass_LONG:
285  buf.append( *static_cast< sal_Int32 const * >(val) );
286  break;
287  case typelib_TypeClass_UNSIGNED_LONG:
288  buf.append( static_cast< sal_Int64 >(
289  *static_cast< sal_uInt32 const * >(val) ) );
290  break;
291  case typelib_TypeClass_HYPER:
292  case typelib_TypeClass_UNSIGNED_HYPER:
293  buf.append( *static_cast< sal_Int64 const * >(val) );
294  break;
295 // case typelib_TypeClass_UNKNOWN:
296 // case typelib_TypeClass_SERVICE:
297 // case typelib_TypeClass_MODULE:
298  default:
299  buf.append( '?' );
300  break;
301  }
302 }
303 
304 } // anon namespace
305 
306 
307 OUString anyToString( uno::Any const & value )
308 {
309  OUStringBuffer buf;
310  appendValue( buf, value.getValue(), value.getValueTypeRef(), true );
311  return buf.makeStringAndClear();
312 }
313 
314 } // namespace comphelper
315 
316 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_uInt16 sal_Unicode
size_t pos
sal_Int32 nElements
struct _uno_Any uno_Any
struct _typelib_TypeDescription typelib_TypeDescription
const PropertyValue * pValues
void(* f)(TrueTypeTable *)
sal_uInt16 nPos
OUString anyToString(uno::Any const &value)