LCOV - code coverage report
Current view: top level - comphelper/source/misc - anytostring.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 64 158 40.5 %
Date: 2014-11-03 Functions: 3 4 75.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10