1*dde7d3faSAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*dde7d3faSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*dde7d3faSAndrew Rist * or more contributor license agreements. See the NOTICE file 5*dde7d3faSAndrew Rist * distributed with this work for additional information 6*dde7d3faSAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*dde7d3faSAndrew Rist * to you under the Apache License, Version 2.0 (the 8*dde7d3faSAndrew Rist * "License"); you may not use this file except in compliance 9*dde7d3faSAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*dde7d3faSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*dde7d3faSAndrew Rist * Unless required by applicable law or agreed to in writing, 14*dde7d3faSAndrew Rist * software distributed under the License is distributed on an 15*dde7d3faSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*dde7d3faSAndrew Rist * KIND, either express or implied. See the License for the 17*dde7d3faSAndrew Rist * specific language governing permissions and limitations 18*dde7d3faSAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*dde7d3faSAndrew Rist *************************************************************/ 21*dde7d3faSAndrew Rist 22*dde7d3faSAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_comphelper.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include "comphelper/anytostring.hxx" 28cdf0e10cSrcweir #include "osl/diagnose.h" 29cdf0e10cSrcweir #include "rtl/ustrbuf.hxx" 30cdf0e10cSrcweir #include "typelib/typedescription.h" 31cdf0e10cSrcweir #include "com/sun/star/lang/XServiceInfo.hpp" 32cdf0e10cSrcweir 33cdf0e10cSrcweir using namespace ::com::sun::star; 34cdf0e10cSrcweir 35cdf0e10cSrcweir namespace comphelper { 36cdf0e10cSrcweir namespace { 37cdf0e10cSrcweir 38cdf0e10cSrcweir void appendTypeError( 39cdf0e10cSrcweir rtl::OUStringBuffer & buf, typelib_TypeDescriptionReference * typeRef ) 40cdf0e10cSrcweir { 41cdf0e10cSrcweir buf.appendAscii( 42cdf0e10cSrcweir RTL_CONSTASCII_STRINGPARAM("<cannot get type description of type ") ); 43cdf0e10cSrcweir buf.append( rtl::OUString::unacquired( &typeRef->pTypeName ) ); 44cdf0e10cSrcweir buf.append( static_cast< sal_Unicode >('>') ); 45cdf0e10cSrcweir } 46cdf0e10cSrcweir 47cdf0e10cSrcweir inline void appendChar( rtl::OUStringBuffer & buf, sal_Unicode c ) 48cdf0e10cSrcweir { 49cdf0e10cSrcweir if (c < ' ' || c > '~') { 50cdf0e10cSrcweir buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\\X") ); 51cdf0e10cSrcweir rtl::OUString const s( 52cdf0e10cSrcweir rtl::OUString::valueOf( static_cast< sal_Int32 >(c), 16 ) ); 53cdf0e10cSrcweir for ( sal_Int32 f = 4 - s.getLength(); f > 0; --f ) 54cdf0e10cSrcweir buf.append( static_cast< sal_Unicode >('0') ); 55cdf0e10cSrcweir buf.append( s ); 56cdf0e10cSrcweir } 57cdf0e10cSrcweir else { 58cdf0e10cSrcweir buf.append( c ); 59cdf0e10cSrcweir } 60cdf0e10cSrcweir } 61cdf0e10cSrcweir 62cdf0e10cSrcweir //------------------------------------------------------------------------------ 63cdf0e10cSrcweir void appendValue( rtl::OUStringBuffer & buf, 64cdf0e10cSrcweir void const * val, typelib_TypeDescriptionReference * typeRef, 65cdf0e10cSrcweir bool prependType ) 66cdf0e10cSrcweir { 67cdf0e10cSrcweir if (typeRef->eTypeClass == typelib_TypeClass_VOID) { 68cdf0e10cSrcweir buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("void") ); 69cdf0e10cSrcweir return; 70cdf0e10cSrcweir } 71cdf0e10cSrcweir OSL_ASSERT( val != 0 ); 72cdf0e10cSrcweir 73cdf0e10cSrcweir if (prependType && 74cdf0e10cSrcweir typeRef->eTypeClass != typelib_TypeClass_STRING && 75cdf0e10cSrcweir typeRef->eTypeClass != typelib_TypeClass_CHAR && 76cdf0e10cSrcweir typeRef->eTypeClass != typelib_TypeClass_BOOLEAN) 77cdf0e10cSrcweir { 78cdf0e10cSrcweir buf.append( static_cast< sal_Unicode >('(') ); 79cdf0e10cSrcweir buf.append( rtl::OUString::unacquired( &typeRef->pTypeName ) ); 80cdf0e10cSrcweir buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(") ") ); 81cdf0e10cSrcweir } 82cdf0e10cSrcweir 83cdf0e10cSrcweir switch (typeRef->eTypeClass) { 84cdf0e10cSrcweir case typelib_TypeClass_INTERFACE: { 85cdf0e10cSrcweir buf.append( static_cast<sal_Unicode>('@') ); 86cdf0e10cSrcweir buf.append( reinterpret_cast< sal_Int64 >( 87cdf0e10cSrcweir *static_cast< void * const * >(val) ), 16 ); 88cdf0e10cSrcweir uno::Reference< lang::XServiceInfo > xServiceInfo( 89cdf0e10cSrcweir *static_cast< uno::XInterface * const * >(val), 90cdf0e10cSrcweir uno::UNO_QUERY ); 91cdf0e10cSrcweir if (xServiceInfo.is()) { 92cdf0e10cSrcweir buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( 93cdf0e10cSrcweir " (ImplementationName = \"") ); 94cdf0e10cSrcweir buf.append( xServiceInfo->getImplementationName() ); 95cdf0e10cSrcweir buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\")") ); 96cdf0e10cSrcweir } 97cdf0e10cSrcweir break; 98cdf0e10cSrcweir } 99cdf0e10cSrcweir case typelib_TypeClass_STRUCT: 100cdf0e10cSrcweir case typelib_TypeClass_EXCEPTION: { 101cdf0e10cSrcweir buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("{ ") ); 102cdf0e10cSrcweir typelib_TypeDescription * typeDescr = 0; 103cdf0e10cSrcweir typelib_typedescriptionreference_getDescription( &typeDescr, typeRef ); 104cdf0e10cSrcweir if (typeDescr == 0 || !typelib_typedescription_complete( &typeDescr )) { 105cdf0e10cSrcweir appendTypeError( buf, typeRef ); 106cdf0e10cSrcweir } 107cdf0e10cSrcweir else { 108cdf0e10cSrcweir typelib_CompoundTypeDescription * compType = 109cdf0e10cSrcweir reinterpret_cast< typelib_CompoundTypeDescription * >( 110cdf0e10cSrcweir typeDescr ); 111cdf0e10cSrcweir sal_Int32 nDescr = compType->nMembers; 112cdf0e10cSrcweir 113cdf0e10cSrcweir if (compType->pBaseTypeDescription) { 114cdf0e10cSrcweir appendValue( 115cdf0e10cSrcweir buf, val, reinterpret_cast< 116cdf0e10cSrcweir typelib_TypeDescription * >( 117cdf0e10cSrcweir compType->pBaseTypeDescription)->pWeakRef, false ); 118cdf0e10cSrcweir if (nDescr > 0) 119cdf0e10cSrcweir buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", ") ); 120cdf0e10cSrcweir } 121cdf0e10cSrcweir 122cdf0e10cSrcweir typelib_TypeDescriptionReference ** ppTypeRefs = 123cdf0e10cSrcweir compType->ppTypeRefs; 124cdf0e10cSrcweir sal_Int32 * memberOffsets = compType->pMemberOffsets; 125cdf0e10cSrcweir rtl_uString ** ppMemberNames = compType->ppMemberNames; 126cdf0e10cSrcweir 127cdf0e10cSrcweir for ( sal_Int32 nPos = 0; nPos < nDescr; ++nPos ) 128cdf0e10cSrcweir { 129cdf0e10cSrcweir buf.append( ppMemberNames[ nPos ] ); 130cdf0e10cSrcweir buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" = ") ); 131cdf0e10cSrcweir typelib_TypeDescription * memberType = 0; 132cdf0e10cSrcweir TYPELIB_DANGER_GET( &memberType, ppTypeRefs[ nPos ] ); 133cdf0e10cSrcweir if (memberType == 0) { 134cdf0e10cSrcweir appendTypeError( buf, ppTypeRefs[ nPos ] ); 135cdf0e10cSrcweir } 136cdf0e10cSrcweir else { 137cdf0e10cSrcweir appendValue( buf, 138cdf0e10cSrcweir static_cast< char const * >( 139cdf0e10cSrcweir val ) + memberOffsets[ nPos ], 140cdf0e10cSrcweir memberType->pWeakRef, true ); 141cdf0e10cSrcweir TYPELIB_DANGER_RELEASE( memberType ); 142cdf0e10cSrcweir } 143cdf0e10cSrcweir if (nPos < (nDescr - 1)) 144cdf0e10cSrcweir buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", ") ); 145cdf0e10cSrcweir } 146cdf0e10cSrcweir } 147cdf0e10cSrcweir buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" }") ); 148cdf0e10cSrcweir if (typeDescr != 0) 149cdf0e10cSrcweir typelib_typedescription_release( typeDescr ); 150cdf0e10cSrcweir break; 151cdf0e10cSrcweir } 152cdf0e10cSrcweir case typelib_TypeClass_SEQUENCE: { 153cdf0e10cSrcweir typelib_TypeDescription * typeDescr = 0; 154cdf0e10cSrcweir TYPELIB_DANGER_GET( &typeDescr, typeRef ); 155cdf0e10cSrcweir if (typeDescr == 0) { 156cdf0e10cSrcweir appendTypeError( buf,typeRef ); 157cdf0e10cSrcweir } 158cdf0e10cSrcweir else { 159cdf0e10cSrcweir typelib_TypeDescriptionReference * elementTypeRef = 160cdf0e10cSrcweir reinterpret_cast< 161cdf0e10cSrcweir typelib_IndirectTypeDescription * >(typeDescr)->pType; 162cdf0e10cSrcweir typelib_TypeDescription * elementTypeDescr = 0; 163cdf0e10cSrcweir TYPELIB_DANGER_GET( &elementTypeDescr, elementTypeRef ); 164cdf0e10cSrcweir if (elementTypeDescr == 0) 165cdf0e10cSrcweir { 166cdf0e10cSrcweir appendTypeError( buf, elementTypeRef ); 167cdf0e10cSrcweir } 168cdf0e10cSrcweir else 169cdf0e10cSrcweir { 170cdf0e10cSrcweir sal_Int32 nElementSize = elementTypeDescr->nSize; 171cdf0e10cSrcweir uno_Sequence * seq = 172cdf0e10cSrcweir *static_cast< uno_Sequence * const * >(val); 173cdf0e10cSrcweir sal_Int32 nElements = seq->nElements; 174cdf0e10cSrcweir 175cdf0e10cSrcweir if (nElements > 0) 176cdf0e10cSrcweir { 177cdf0e10cSrcweir buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("{ ") ); 178cdf0e10cSrcweir char const * pElements = seq->elements; 179cdf0e10cSrcweir for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos ) 180cdf0e10cSrcweir { 181cdf0e10cSrcweir appendValue( 182cdf0e10cSrcweir buf, pElements + (nElementSize * nPos), 183cdf0e10cSrcweir elementTypeDescr->pWeakRef, false ); 184cdf0e10cSrcweir if (nPos < (nElements - 1)) 185cdf0e10cSrcweir buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", ") ); 186cdf0e10cSrcweir } 187cdf0e10cSrcweir buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" }") ); 188cdf0e10cSrcweir } 189cdf0e10cSrcweir else 190cdf0e10cSrcweir { 191cdf0e10cSrcweir buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("{}") ); 192cdf0e10cSrcweir } 193cdf0e10cSrcweir TYPELIB_DANGER_RELEASE( elementTypeDescr ); 194cdf0e10cSrcweir } 195cdf0e10cSrcweir TYPELIB_DANGER_RELEASE( typeDescr ); 196cdf0e10cSrcweir } 197cdf0e10cSrcweir break; 198cdf0e10cSrcweir } 199cdf0e10cSrcweir case typelib_TypeClass_ANY: { 200cdf0e10cSrcweir buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("{ ") ); 201cdf0e10cSrcweir uno_Any const * pAny = static_cast< uno_Any const * >(val); 202cdf0e10cSrcweir appendValue( buf, pAny->pData, pAny->pType, true ); 203cdf0e10cSrcweir buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" }") ); 204cdf0e10cSrcweir break; 205cdf0e10cSrcweir } 206cdf0e10cSrcweir case typelib_TypeClass_TYPE: 207cdf0e10cSrcweir buf.append( (*reinterpret_cast< 208cdf0e10cSrcweir typelib_TypeDescriptionReference * const * >(val) 209cdf0e10cSrcweir )->pTypeName ); 210cdf0e10cSrcweir break; 211cdf0e10cSrcweir case typelib_TypeClass_STRING: { 212cdf0e10cSrcweir buf.append( static_cast< sal_Unicode >('\"') ); 213cdf0e10cSrcweir rtl::OUString const & str = rtl::OUString::unacquired( 214cdf0e10cSrcweir static_cast< rtl_uString * const * >(val) ); 215cdf0e10cSrcweir sal_Int32 len = str.getLength(); 216cdf0e10cSrcweir for ( sal_Int32 pos = 0; pos < len; ++pos ) 217cdf0e10cSrcweir { 218cdf0e10cSrcweir sal_Unicode c = str[ pos ]; 219cdf0e10cSrcweir if (c == '\"') 220cdf0e10cSrcweir buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\\\"") ); 221cdf0e10cSrcweir else if (c == '\\') 222cdf0e10cSrcweir buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\\\\") ); 223cdf0e10cSrcweir else 224cdf0e10cSrcweir appendChar( buf, c ); 225cdf0e10cSrcweir } 226cdf0e10cSrcweir buf.append( static_cast< sal_Unicode >('\"') ); 227cdf0e10cSrcweir break; 228cdf0e10cSrcweir } 229cdf0e10cSrcweir case typelib_TypeClass_ENUM: { 230cdf0e10cSrcweir typelib_TypeDescription * typeDescr = 0; 231cdf0e10cSrcweir typelib_typedescriptionreference_getDescription( &typeDescr, typeRef ); 232cdf0e10cSrcweir if (typeDescr == 0 || !typelib_typedescription_complete( &typeDescr )) { 233cdf0e10cSrcweir appendTypeError( buf, typeRef ); 234cdf0e10cSrcweir } 235cdf0e10cSrcweir else 236cdf0e10cSrcweir { 237cdf0e10cSrcweir sal_Int32 * pValues = 238cdf0e10cSrcweir reinterpret_cast< typelib_EnumTypeDescription * >( 239cdf0e10cSrcweir typeDescr )->pEnumValues; 240cdf0e10cSrcweir sal_Int32 nPos = reinterpret_cast< typelib_EnumTypeDescription * >( 241cdf0e10cSrcweir typeDescr )->nEnumValues; 242cdf0e10cSrcweir while (nPos--) 243cdf0e10cSrcweir { 244cdf0e10cSrcweir if (pValues[ nPos ] == *static_cast< int const * >(val)) 245cdf0e10cSrcweir break; 246cdf0e10cSrcweir } 247cdf0e10cSrcweir if (nPos >= 0) 248cdf0e10cSrcweir { 249cdf0e10cSrcweir buf.append( reinterpret_cast< typelib_EnumTypeDescription * >( 250cdf0e10cSrcweir typeDescr )->ppEnumNames[ nPos ] ); 251cdf0e10cSrcweir } 252cdf0e10cSrcweir else 253cdf0e10cSrcweir { 254cdf0e10cSrcweir buf.appendAscii( 255cdf0e10cSrcweir RTL_CONSTASCII_STRINGPARAM("?unknown enum value?") ); 256cdf0e10cSrcweir } 257cdf0e10cSrcweir } 258cdf0e10cSrcweir if (typeDescr != 0) 259cdf0e10cSrcweir typelib_typedescription_release( typeDescr ); 260cdf0e10cSrcweir break; 261cdf0e10cSrcweir } 262cdf0e10cSrcweir case typelib_TypeClass_BOOLEAN: 263cdf0e10cSrcweir if (*static_cast< sal_Bool const * >(val) != sal_False) 264cdf0e10cSrcweir buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("true") ); 265cdf0e10cSrcweir else 266cdf0e10cSrcweir buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("false") ); 267cdf0e10cSrcweir break; 268cdf0e10cSrcweir case typelib_TypeClass_CHAR: { 269cdf0e10cSrcweir buf.append( static_cast< sal_Unicode >('\'') ); 270cdf0e10cSrcweir sal_Unicode c = *static_cast< sal_Unicode const * >(val); 271cdf0e10cSrcweir if (c == '\'') 272cdf0e10cSrcweir buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\\\'") ); 273cdf0e10cSrcweir else if (c == '\\') 274cdf0e10cSrcweir buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\\\\") ); 275cdf0e10cSrcweir else 276cdf0e10cSrcweir appendChar( buf, c ); 277cdf0e10cSrcweir buf.append( static_cast< sal_Unicode >('\'') ); 278cdf0e10cSrcweir break; 279cdf0e10cSrcweir } 280cdf0e10cSrcweir case typelib_TypeClass_FLOAT: 281cdf0e10cSrcweir buf.append( *static_cast< float const * >(val) ); 282cdf0e10cSrcweir break; 283cdf0e10cSrcweir case typelib_TypeClass_DOUBLE: 284cdf0e10cSrcweir buf.append( *static_cast< double const * >(val) ); 285cdf0e10cSrcweir break; 286cdf0e10cSrcweir case typelib_TypeClass_BYTE: 287cdf0e10cSrcweir buf.append( static_cast< sal_Int32 >( 288cdf0e10cSrcweir *static_cast< sal_Int8 const * >(val) ) ); 289cdf0e10cSrcweir break; 290cdf0e10cSrcweir case typelib_TypeClass_SHORT: 291cdf0e10cSrcweir buf.append( static_cast< sal_Int32 >( 292cdf0e10cSrcweir *static_cast< sal_Int16 const * >(val) ) ); 293cdf0e10cSrcweir break; 294cdf0e10cSrcweir case typelib_TypeClass_UNSIGNED_SHORT: 295cdf0e10cSrcweir buf.append( static_cast< sal_Int32 >( 296cdf0e10cSrcweir *static_cast< sal_uInt16 const * >(val) ) ); 297cdf0e10cSrcweir break; 298cdf0e10cSrcweir case typelib_TypeClass_LONG: 299cdf0e10cSrcweir buf.append( *static_cast< sal_Int32 const * >(val) ); 300cdf0e10cSrcweir break; 301cdf0e10cSrcweir case typelib_TypeClass_UNSIGNED_LONG: 302cdf0e10cSrcweir buf.append( static_cast< sal_Int64 >( 303cdf0e10cSrcweir *static_cast< sal_uInt32 const * >(val) ) ); 304cdf0e10cSrcweir break; 305cdf0e10cSrcweir case typelib_TypeClass_HYPER: 306cdf0e10cSrcweir case typelib_TypeClass_UNSIGNED_HYPER: 307cdf0e10cSrcweir buf.append( *static_cast< sal_Int64 const * >(val) ); 308cdf0e10cSrcweir break; 309cdf0e10cSrcweir // case typelib_TypeClass_UNION: 310cdf0e10cSrcweir // case typelib_TypeClass_ARRAY: 311cdf0e10cSrcweir // case typelib_TypeClass_UNKNOWN: 312cdf0e10cSrcweir // case typelib_TypeClass_SERVICE: 313cdf0e10cSrcweir // case typelib_TypeClass_MODULE: 314cdf0e10cSrcweir default: 315cdf0e10cSrcweir buf.append( static_cast< sal_Unicode >('?') ); 316cdf0e10cSrcweir break; 317cdf0e10cSrcweir } 318cdf0e10cSrcweir } 319cdf0e10cSrcweir 320cdf0e10cSrcweir } // anon namespace 321cdf0e10cSrcweir 322cdf0e10cSrcweir //============================================================================== 323cdf0e10cSrcweir rtl::OUString anyToString( uno::Any const & value ) 324cdf0e10cSrcweir { 325cdf0e10cSrcweir rtl::OUStringBuffer buf; 326cdf0e10cSrcweir appendValue( buf, value.getValue(), value.getValueTypeRef(), true ); 327cdf0e10cSrcweir return buf.makeStringAndClear(); 328cdf0e10cSrcweir } 329cdf0e10cSrcweir 330cdf0e10cSrcweir } // namespace comphelper 331cdf0e10cSrcweir 332