LCOV - code coverage report
Current view: top level - pyuno/source/module - pyuno.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 82 344 23.8 %
Date: 2014-04-11 Functions: 8 13 61.5 %
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             : #include "pyuno_impl.hxx"
      21             : 
      22             : #include <rtl/strbuf.hxx>
      23             : #include <rtl/ustrbuf.hxx>
      24             : 
      25             : #include <osl/thread.h>
      26             : 
      27             : #include <com/sun/star/lang/XServiceInfo.hpp>
      28             : #include <com/sun/star/lang/XTypeProvider.hpp>
      29             : #include <com/sun/star/beans/XPropertySet.hpp>
      30             : #include <com/sun/star/beans/XMaterialHolder.hpp>
      31             : 
      32             : using com::sun::star::uno::Sequence;
      33             : using com::sun::star::uno::Reference;
      34             : using com::sun::star::uno::XInterface;
      35             : using com::sun::star::uno::Any;
      36             : using com::sun::star::uno::makeAny;
      37             : using com::sun::star::uno::UNO_QUERY;
      38             : using com::sun::star::uno::Type;
      39             : using com::sun::star::uno::TypeClass;
      40             : using com::sun::star::uno::RuntimeException;
      41             : using com::sun::star::uno::Exception;
      42             : using com::sun::star::uno::XComponentContext;
      43             : using com::sun::star::lang::XSingleServiceFactory;
      44             : using com::sun::star::lang::XServiceInfo;
      45             : using com::sun::star::lang::XTypeProvider;
      46             : using com::sun::star::script::XTypeConverter;
      47             : using com::sun::star::script::XInvocation2;
      48             : using com::sun::star::beans::XMaterialHolder;
      49             : 
      50             : namespace pyuno
      51             : {
      52             : 
      53             : PyObject *PyUNO_str( PyObject * self );
      54             : 
      55         476 : void PyUNO_del (PyObject* self)
      56             : {
      57         476 :     PyUNO* me = reinterpret_cast< PyUNO* > (self);
      58             :     {
      59         476 :         PyThreadDetach antiguard;
      60         476 :         delete me->members;
      61             :     }
      62         476 :     PyObject_Del (self);
      63         476 : }
      64             : 
      65             : 
      66             : 
      67           0 : OUString val2str( const void * pVal, typelib_TypeDescriptionReference * pTypeRef , sal_Int32 mode ) SAL_THROW(())
      68             : {
      69             :     OSL_ASSERT( pVal );
      70           0 :     if (pTypeRef->eTypeClass == typelib_TypeClass_VOID)
      71           0 :         return OUString("void");
      72             : 
      73           0 :     OUStringBuffer buf( 64 );
      74           0 :     buf.append( '(' );
      75           0 :     buf.append( pTypeRef->pTypeName );
      76           0 :     buf.append( ')' );
      77             : 
      78           0 :     switch (pTypeRef->eTypeClass)
      79             :     {
      80             :     case typelib_TypeClass_INTERFACE:
      81             :     {
      82           0 :         buf.append( "0x" );
      83           0 :         buf.append( reinterpret_cast< sal_IntPtr >(*(void **)pVal), 16 );
      84           0 :         if( VAL2STR_MODE_DEEP == mode )
      85             :         {
      86           0 :             buf.append( "{" );        Reference< XInterface > r = *( Reference< XInterface > * ) pVal;
      87           0 :             Reference< XServiceInfo > serviceInfo( r, UNO_QUERY);
      88           0 :             Reference< XTypeProvider > typeProvider(r,UNO_QUERY);
      89           0 :             if( serviceInfo.is() )
      90             :             {
      91           0 :                 buf.append("implementationName=" );
      92           0 :                 buf.append(serviceInfo->getImplementationName() );
      93           0 :                 buf.append(", supportedServices={" );
      94           0 :                 Sequence< OUString > seq = serviceInfo->getSupportedServiceNames();
      95           0 :                 for( int i = 0 ; i < seq.getLength() ; i ++ )
      96             :                 {
      97           0 :                     buf.append( seq[i] );
      98           0 :                     if( i +1 != seq.getLength() )
      99           0 :                         buf.append( "," );
     100             :                 }
     101           0 :                 buf.append("}");
     102             :             }
     103             : 
     104           0 :             if( typeProvider.is() )
     105             :             {
     106           0 :                 buf.append(", supportedInterfaces={" );
     107           0 :                 Sequence< Type > seq (typeProvider->getTypes());
     108           0 :                 for( int i = 0 ; i < seq.getLength() ; i ++ )
     109             :                 {
     110           0 :                     buf.append(seq[i].getTypeName());
     111           0 :                     if( i +1 != seq.getLength() )
     112           0 :                         buf.append( "," );
     113             :                 }
     114           0 :                 buf.append("}");
     115             :             }
     116           0 :             buf.append( "}" );
     117             :         }
     118             : 
     119           0 :         break;
     120             :     }
     121             :     case typelib_TypeClass_STRUCT:
     122             :     case typelib_TypeClass_EXCEPTION:
     123             :     {
     124           0 :         buf.append( "{ " );
     125           0 :         typelib_TypeDescription * pTypeDescr = 0;
     126           0 :         TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
     127             :         OSL_ASSERT( pTypeDescr );
     128             : 
     129           0 :         typelib_CompoundTypeDescription * pCompType = (typelib_CompoundTypeDescription *)pTypeDescr;
     130           0 :         sal_Int32 nDescr = pCompType->nMembers;
     131             : 
     132           0 :         if (pCompType->pBaseTypeDescription)
     133             :         {
     134           0 :             buf.append( val2str( pVal, ((typelib_TypeDescription *)pCompType->pBaseTypeDescription)->pWeakRef,mode ) );
     135           0 :             if (nDescr)
     136           0 :                 buf.append( ", " );
     137             :         }
     138             : 
     139           0 :         typelib_TypeDescriptionReference ** ppTypeRefs = pCompType->ppTypeRefs;
     140           0 :         sal_Int32 * pMemberOffsets = pCompType->pMemberOffsets;
     141           0 :         rtl_uString ** ppMemberNames = pCompType->ppMemberNames;
     142             : 
     143           0 :         for ( sal_Int32 nPos = 0; nPos < nDescr; ++nPos )
     144             :         {
     145           0 :             buf.append( ppMemberNames[nPos] );
     146           0 :             buf.append( " = " );
     147           0 :             typelib_TypeDescription * pMemberType = 0;
     148           0 :             TYPELIB_DANGER_GET( &pMemberType, ppTypeRefs[nPos] );
     149           0 :             buf.append( val2str( (char *)pVal + pMemberOffsets[nPos], pMemberType->pWeakRef, mode ) );
     150           0 :             TYPELIB_DANGER_RELEASE( pMemberType );
     151           0 :             if (nPos < (nDescr -1))
     152           0 :                 buf.append( ", " );
     153             :         }
     154             : 
     155           0 :         TYPELIB_DANGER_RELEASE( pTypeDescr );
     156             : 
     157           0 :         buf.append( " }" );
     158           0 :         break;
     159             :     }
     160             :     case typelib_TypeClass_SEQUENCE:
     161             :     {
     162           0 :         typelib_TypeDescription * pTypeDescr = 0;
     163           0 :         TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
     164             : 
     165           0 :         uno_Sequence * pSequence = *(uno_Sequence **)pVal;
     166           0 :         typelib_TypeDescription * pElementTypeDescr = 0;
     167           0 :         TYPELIB_DANGER_GET( &pElementTypeDescr, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType );
     168             : 
     169           0 :         sal_Int32 nElementSize = pElementTypeDescr->nSize;
     170           0 :         sal_Int32 nElements = pSequence->nElements;
     171             : 
     172           0 :         if (nElements)
     173             :         {
     174           0 :             buf.append( "{ " );
     175           0 :             char * pElements = pSequence->elements;
     176           0 :             for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
     177             :             {
     178           0 :                 buf.append( val2str( pElements + (nElementSize * nPos), pElementTypeDescr->pWeakRef, mode ) );
     179           0 :                 if (nPos < (nElements -1))
     180           0 :                     buf.append( ", " );
     181             :             }
     182           0 :             buf.append( " }" );
     183             :         }
     184             :         else
     185             :         {
     186           0 :             buf.append( "{}" );
     187             :         }
     188           0 :         TYPELIB_DANGER_RELEASE( pElementTypeDescr );
     189           0 :         TYPELIB_DANGER_RELEASE( pTypeDescr );
     190           0 :         break;
     191             :     }
     192             :     case typelib_TypeClass_ANY:
     193           0 :         buf.append( "{ " );
     194             :         buf.append( val2str( ((uno_Any *)pVal)->pData,
     195             :                              ((uno_Any *)pVal)->pType ,
     196           0 :                              mode) );
     197           0 :         buf.append( " }" );
     198           0 :         break;
     199             :     case typelib_TypeClass_TYPE:
     200           0 :         buf.append( (*(typelib_TypeDescriptionReference **)pVal)->pTypeName );
     201           0 :         break;
     202             :     case typelib_TypeClass_STRING:
     203           0 :         buf.append( '\"' );
     204           0 :         buf.append( *(rtl_uString **)pVal );
     205           0 :         buf.append( '\"' );
     206           0 :         break;
     207             :     case typelib_TypeClass_ENUM:
     208             :     {
     209           0 :         typelib_TypeDescription * pTypeDescr = 0;
     210           0 :         TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
     211             : 
     212           0 :         sal_Int32 * pValues = ((typelib_EnumTypeDescription *)pTypeDescr)->pEnumValues;
     213           0 :         sal_Int32 nPos = ((typelib_EnumTypeDescription *)pTypeDescr)->nEnumValues;
     214           0 :         while (nPos--)
     215             :         {
     216           0 :             if (pValues[nPos] == *(int *)pVal)
     217           0 :                 break;
     218             :         }
     219           0 :         if (nPos >= 0)
     220           0 :             buf.append( ((typelib_EnumTypeDescription *)pTypeDescr)->ppEnumNames[nPos] );
     221             :         else
     222           0 :             buf.append( '?' );
     223             : 
     224           0 :         TYPELIB_DANGER_RELEASE( pTypeDescr );
     225           0 :         break;
     226             :     }
     227             :     case typelib_TypeClass_BOOLEAN:
     228           0 :         if (*(sal_Bool *)pVal)
     229           0 :             buf.append( "true" );
     230             :         else
     231           0 :             buf.append( "false" );
     232           0 :         break;
     233             :     case typelib_TypeClass_CHAR:
     234           0 :         buf.append( '\'' );
     235           0 :         buf.append( *(sal_Unicode *)pVal );
     236           0 :         buf.append( '\'' );
     237           0 :         break;
     238             :     case typelib_TypeClass_FLOAT:
     239           0 :         buf.append( *(float *)pVal );
     240           0 :         break;
     241             :     case typelib_TypeClass_DOUBLE:
     242           0 :         buf.append( *(double *)pVal );
     243           0 :         break;
     244             :     case typelib_TypeClass_BYTE:
     245           0 :         buf.append( "0x" );
     246           0 :         buf.append( (sal_Int32)*(sal_Int8 *)pVal, 16 );
     247           0 :         break;
     248             :     case typelib_TypeClass_SHORT:
     249           0 :         buf.append( "0x" );
     250           0 :         buf.append( (sal_Int32)*(sal_Int16 *)pVal, 16 );
     251           0 :         break;
     252             :     case typelib_TypeClass_UNSIGNED_SHORT:
     253           0 :         buf.append( "0x" );
     254           0 :         buf.append( (sal_Int32)*(sal_uInt16 *)pVal, 16 );
     255           0 :         break;
     256             :     case typelib_TypeClass_LONG:
     257           0 :         buf.append( "0x" );
     258           0 :         buf.append( *(sal_Int32 *)pVal, 16 );
     259           0 :         break;
     260             :     case typelib_TypeClass_UNSIGNED_LONG:
     261           0 :         buf.append( "0x" );
     262           0 :         buf.append( (sal_Int64)*(sal_uInt32 *)pVal, 16 );
     263           0 :         break;
     264             :     case typelib_TypeClass_HYPER:
     265             :     case typelib_TypeClass_UNSIGNED_HYPER:
     266           0 :         buf.append( "0x" );
     267             : #if defined(__GNUC__) && defined(SPARC)
     268             : // I guess this really should check if there are strict alignment
     269             : // requirements, not just "GCC on SPARC".
     270             :         {
     271             :             sal_Int64 aVal;
     272             :             *(sal_Int32 *)&aVal = *(sal_Int32 *)pVal;
     273             :             *((sal_Int32 *)&aVal +1)= *((sal_Int32 *)pVal +1);
     274             :             buf.append( aVal, 16 );
     275             :         }
     276             : #else
     277           0 :         buf.append( *(sal_Int64 *)pVal, 16 );
     278             : #endif
     279           0 :         break;
     280             : 
     281             :     case typelib_TypeClass_VOID:
     282             :     case typelib_TypeClass_UNKNOWN:
     283             :     case typelib_TypeClass_SERVICE:
     284             :     case typelib_TypeClass_MODULE:
     285             :     default:
     286           0 :         buf.append( '?' );
     287             :     }
     288             : 
     289           0 :     return buf.makeStringAndClear();
     290             : }
     291             : 
     292             : 
     293           1 : PyObject *PyUNO_repr( PyObject  * self )
     294             : {
     295           1 :     PyUNO *me = (PyUNO * ) self;
     296           1 :     PyObject * ret = 0;
     297             : 
     298           1 :     if( me->members->wrappedObject.getValueType().getTypeClass()
     299             :         == com::sun::star::uno::TypeClass_EXCEPTION )
     300             :     {
     301           1 :         Reference< XMaterialHolder > rHolder(me->members->xInvocation,UNO_QUERY);
     302           1 :         if( rHolder.is() )
     303             :         {
     304           1 :             Any a = rHolder->getMaterial();
     305           2 :             Exception e;
     306           1 :             a >>= e;
     307           2 :             ret = ustring2PyUnicode(e.Message ).getAcquired();
     308           1 :         }
     309             :     }
     310             :     else
     311             :     {
     312           0 :         ret = PyUNO_str( self );
     313             :     }
     314           1 :     return ret;
     315             : }
     316             : 
     317           0 : PyObject *PyUNO_invoke( PyObject *object, const char *name , PyObject *args )
     318             : {
     319           0 :     PyRef ret;
     320             :     try
     321             :     {
     322           0 :         Runtime runtime;
     323             : 
     324           0 :         PyRef paras,callable;
     325           0 :         if( PyObject_IsInstance( object, getPyUnoClass().get() ) )
     326             :         {
     327           0 :             PyUNO* me = (PyUNO*) object;
     328           0 :             OUString attrName = OUString::createFromAscii(name);
     329           0 :             if (! me->members->xInvocation->hasMethod (attrName))
     330             :             {
     331           0 :                 OUStringBuffer buf;
     332           0 :                 buf.append( "Attribute " );
     333           0 :                 buf.append( attrName );
     334           0 :                 buf.append( " unknown" );
     335           0 :                 throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface > () );
     336             :             }
     337           0 :             callable = PyUNO_callable_new (
     338             :                 me->members->xInvocation,
     339             :                 attrName,
     340           0 :                 ACCEPT_UNO_ANY);
     341           0 :             paras = args;
     342             :         }
     343             :         else
     344             :         {
     345             :             // clean the tuple from uno.Any !
     346           0 :             int size = PyTuple_Size( args );
     347             :             { // for CC, keeping ref-count of tuple being 1
     348           0 :             paras = PyRef(PyTuple_New( size ), SAL_NO_ACQUIRE);
     349             :             }
     350           0 :             for( int i = 0 ; i < size ;i ++ )
     351             :             {
     352           0 :                 PyObject * element = PyTuple_GetItem( args , i );
     353           0 :                 if( PyObject_IsInstance( element , getAnyClass( runtime ).get() ) )
     354             :                 {
     355             :                     element = PyObject_GetAttrString(
     356           0 :                         element, "value" );
     357             :                 }
     358             :                 else
     359             :                 {
     360           0 :                     Py_XINCREF( element );
     361             :                 }
     362           0 :                 PyTuple_SetItem( paras.get(), i , element );
     363             :             }
     364           0 :             callable = PyRef( PyObject_GetAttrString( object , (char*)name ), SAL_NO_ACQUIRE );
     365           0 :             if( !callable.is() )
     366           0 :                 return 0;
     367             :         }
     368           0 :         ret = PyRef( PyObject_CallObject( callable.get(), paras.get() ), SAL_NO_ACQUIRE );
     369             :     }
     370           0 :     catch (const ::com::sun::star::lang::IllegalArgumentException &e)
     371             :     {
     372           0 :         raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) );
     373             :     }
     374           0 :     catch (const ::com::sun::star::script::CannotConvertException &e)
     375             :     {
     376           0 :         raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) );
     377             :     }
     378           0 :     catch (const ::com::sun::star::uno::RuntimeException &e)
     379             :     {
     380           0 :         raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) );
     381             :     }
     382           0 :     catch (const ::com::sun::star::uno::Exception &e)
     383             :     {
     384           0 :         raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) );
     385             :     }
     386             : 
     387           0 :     return ret.getAcquired();
     388             : }
     389             : 
     390           0 : PyObject *PyUNO_str( PyObject * self )
     391             : {
     392           0 :     PyUNO *me = ( PyUNO * ) self;
     393             : 
     394           0 :     OStringBuffer buf;
     395             : 
     396             : 
     397           0 :     if( me->members->wrappedObject.getValueType().getTypeClass()
     398           0 :         == com::sun::star::uno::TypeClass_STRUCT ||
     399           0 :         me->members->wrappedObject.getValueType().getTypeClass()
     400             :         == com::sun::star::uno::TypeClass_EXCEPTION)
     401             :     {
     402           0 :         Reference< XMaterialHolder > rHolder(me->members->xInvocation,UNO_QUERY);
     403           0 :         if( rHolder.is() )
     404             :         {
     405           0 :             PyThreadDetach antiguard;
     406           0 :             Any a = rHolder->getMaterial();
     407           0 :             OUString s = val2str( (void*) a.getValue(), a.getValueType().getTypeLibType() );
     408           0 :             buf.append( OUStringToOString(s,RTL_TEXTENCODING_ASCII_US) );
     409           0 :         }
     410             :     }
     411             :     else
     412             :     {
     413             :         // a common UNO object
     414           0 :         PyThreadDetach antiguard;
     415           0 :         buf.append( "pyuno object " );
     416             : 
     417             :         OUString s = val2str( (void*)me->members->wrappedObject.getValue(),
     418           0 :                               me->members->wrappedObject.getValueType().getTypeLibType() );
     419           0 :         buf.append( OUStringToOString(s,RTL_TEXTENCODING_ASCII_US) );
     420             :     }
     421             : 
     422           0 :     return PyStr_FromString( buf.getStr());
     423             : }
     424             : 
     425           0 : PyObject* PyUNO_dir (PyObject* self)
     426             : {
     427           0 :     PyUNO* me = (PyUNO*) self;
     428             : 
     429           0 :     PyObject* member_list = NULL;
     430           0 :     Sequence<OUString> oo_member_list;
     431             : 
     432             :     try
     433             :     {
     434           0 :         oo_member_list = me->members->xInvocation->getMemberNames ();
     435           0 :         member_list = PyList_New (oo_member_list.getLength ());
     436           0 :         for (int i = 0; i < oo_member_list.getLength (); i++)
     437             :         {
     438             :             // setitem steals a reference
     439           0 :             PyList_SetItem (member_list, i, ustring2PyString(oo_member_list[i]).getAcquired() );
     440             :         }
     441             :     }
     442           0 :     catch( const RuntimeException &e )
     443             :     {
     444           0 :         raisePyExceptionWithAny( makeAny(e) );
     445             :     }
     446             : 
     447           0 :     return member_list;
     448             : }
     449             : 
     450             : 
     451        1719 : PyObject* PyUNO_getattr (PyObject* self, char* name)
     452             : {
     453             :     PyUNO* me;
     454             : 
     455             :     try
     456             :     {
     457             : 
     458        1719 :         Runtime runtime;
     459             : 
     460        1719 :         me = (PyUNO*) self;
     461        1719 :         if (strcmp (name, "__dict__") == 0)
     462             :         {
     463           0 :             Py_INCREF (Py_TYPE(me)->tp_dict);
     464           0 :             return Py_TYPE(me)->tp_dict;
     465             :         }
     466        1719 :         if (strcmp (name, "__class__") == 0)
     467             :         {
     468        1800 :             if( me->members->wrappedObject.getValueTypeClass() ==
     469        1180 :                 com::sun::star::uno::TypeClass_STRUCT ||
     470         280 :                 me->members->wrappedObject.getValueTypeClass() ==
     471             :                 com::sun::star::uno::TypeClass_EXCEPTION )
     472             :             {
     473             :                 return getClass(
     474         760 :                     me->members->wrappedObject.getValueType().getTypeName(), runtime ).getAcquired();
     475             :             }
     476         140 :             Py_INCREF (Py_None);
     477         140 :             return Py_None;
     478             :         }
     479             : 
     480         819 :         OUString attrName( OUString::createFromAscii( name ) );
     481             :         //We need to find out if it's a method...
     482         819 :         if (me->members->xInvocation->hasMethod (attrName))
     483             :         {
     484             :             //Create a callable object to invoke this...
     485             :             PyRef ret = PyUNO_callable_new (
     486             :                 me->members->xInvocation,
     487         372 :                 attrName);
     488         372 :             Py_XINCREF( ret.get() );
     489         372 :             return ret.get();
     490             : 
     491             :         }
     492             : 
     493             :         //or a property
     494         447 :         if (me->members->xInvocation->hasProperty ( attrName))
     495             :         {
     496             :             //Return the value of the property
     497         447 :             Any anyRet;
     498             :             {
     499         447 :                 PyThreadDetach antiguard;
     500         447 :                 anyRet = me->members->xInvocation->getValue (attrName);
     501             :             }
     502         894 :             PyRef ret = runtime.any2PyObject(anyRet);
     503         447 :             Py_XINCREF( ret.get() );
     504         894 :             return ret.get();
     505             :         }
     506             : 
     507             :         //or else...
     508           0 :         PyErr_SetString (PyExc_AttributeError, name);
     509             :     }
     510           0 :     catch( const com::sun::star::reflection::InvocationTargetException & e )
     511             :     {
     512           0 :         raisePyExceptionWithAny( makeAny(e.TargetException) );
     513             :     }
     514           0 :     catch( const com::sun::star::beans::UnknownPropertyException & e )
     515             :     {
     516           0 :         raisePyExceptionWithAny( makeAny(e) );
     517             :     }
     518           0 :     catch( const com::sun::star::lang::IllegalArgumentException &e )
     519             :     {
     520           0 :         raisePyExceptionWithAny( makeAny(e) );
     521             :     }
     522           0 :     catch( const com::sun::star::script::CannotConvertException &e )
     523             :     {
     524           0 :         raisePyExceptionWithAny( makeAny(e) );
     525             :     }
     526           0 :     catch( const RuntimeException &e )
     527             :     {
     528           0 :         raisePyExceptionWithAny( makeAny(e) );
     529             :     }
     530             : 
     531           0 :     return NULL;
     532             : }
     533             : 
     534          77 : int PyUNO_setattr (PyObject* self, char* name, PyObject* value)
     535             : {
     536             :     PyUNO* me;
     537             : 
     538          77 :     me = (PyUNO*) self;
     539             :     try
     540             :     {
     541          77 :         Runtime runtime;
     542         147 :         Any val= runtime.pyObject2Any(value, ACCEPT_UNO_ANY);
     543             : 
     544         147 :         OUString attrName( OUString::createFromAscii( name ) );
     545             :         {
     546          77 :             PyThreadDetach antiguard;
     547          77 :             if (me->members->xInvocation->hasProperty (attrName))
     548             :             {
     549           7 :                 me->members->xInvocation->setValue (attrName, val);
     550           7 :                 return 0; //Keep with Python's boolean system
     551          70 :             }
     552          70 :         }
     553             :     }
     554           0 :     catch( const com::sun::star::reflection::InvocationTargetException & e )
     555             :     {
     556           0 :         raisePyExceptionWithAny( makeAny(e.TargetException) );
     557           0 :         return 1;
     558             :     }
     559           0 :     catch( const com::sun::star::beans::UnknownPropertyException & e )
     560             :     {
     561           0 :         raisePyExceptionWithAny( makeAny(e) );
     562           0 :         return 1;
     563             :     }
     564           0 :     catch( const com::sun::star::script::CannotConvertException &e )
     565             :     {
     566           0 :         raisePyExceptionWithAny( makeAny(e) );
     567           0 :         return 1;
     568             :     }
     569           0 :     catch( const RuntimeException & e )
     570             :     {
     571           0 :         raisePyExceptionWithAny( makeAny( e ) );
     572           0 :         return 1;
     573             :     }
     574          70 :     PyErr_SetString (PyExc_AttributeError, name);
     575          70 :     return 1; //as above.
     576             : }
     577             : 
     578             : // ensure object identity and struct equality
     579           0 : static PyObject* PyUNO_cmp( PyObject *self, PyObject *that, int op )
     580             : {
     581             :     PyObject *result;
     582             : 
     583           0 :     if(op != Py_EQ && op != Py_NE)
     584             :     {
     585           0 :         PyErr_SetString(PyExc_TypeError, "only '==' and '!=' comparisions are defined");
     586           0 :         return 0;
     587             :     }
     588           0 :     if( self == that )
     589             :     {
     590           0 :         result = (op == Py_EQ ? Py_True : Py_False);
     591           0 :         Py_INCREF(result);
     592           0 :         return result;
     593             :     }
     594             :     try
     595             :     {
     596           0 :         Runtime runtime;
     597           0 :         if( PyObject_IsInstance( that, getPyUnoClass().get() ) )
     598             :         {
     599             : 
     600           0 :             PyUNO *me = reinterpret_cast< PyUNO*> ( self );
     601           0 :             PyUNO *other = reinterpret_cast< PyUNO *> (that );
     602           0 :             com::sun::star::uno::TypeClass tcMe = me->members->wrappedObject.getValueTypeClass();
     603           0 :             com::sun::star::uno::TypeClass tcOther = other->members->wrappedObject.getValueTypeClass();
     604             : 
     605           0 :             if( tcMe == tcOther )
     606             :             {
     607           0 :                 if( tcMe == com::sun::star::uno::TypeClass_STRUCT ||
     608             :                     tcMe == com::sun::star::uno::TypeClass_EXCEPTION )
     609             :                 {
     610           0 :                     Reference< XMaterialHolder > xMe( me->members->xInvocation,UNO_QUERY);
     611           0 :                     Reference< XMaterialHolder > xOther( other->members->xInvocation,UNO_QUERY );
     612           0 :                     if( xMe->getMaterial() == xOther->getMaterial() )
     613             :                     {
     614           0 :                         result = (op == Py_EQ ? Py_True : Py_False);
     615           0 :                         Py_INCREF(result);
     616           0 :                         return result;
     617           0 :                     }
     618             :                 }
     619           0 :                 else if( tcMe == com::sun::star::uno::TypeClass_INTERFACE )
     620             :                 {
     621           0 :                     if( me->members->wrappedObject == other->members->wrappedObject )
     622             :                     {
     623           0 :                         result = (op == Py_EQ ? Py_True : Py_False);
     624           0 :                         Py_INCREF(result);
     625           0 :                         return result;
     626             :                     }
     627             :                 }
     628             :             }
     629           0 :         }
     630             :     }
     631           0 :     catch( const com::sun::star::uno::RuntimeException & e)
     632             :     {
     633           0 :         raisePyExceptionWithAny( makeAny( e ) );
     634             :     }
     635             : 
     636           0 :     result = (op == Py_EQ ? Py_False : Py_True);
     637           0 :     Py_INCREF(result);
     638           0 :     return result;
     639             : }
     640             : 
     641             : static PyMethodDef PyUNOMethods[] =
     642             : {
     643             :     {"__dir__", (PyCFunction)PyUNO_dir, METH_NOARGS, NULL},
     644             :     {NULL,      NULL,                   0,           NULL}
     645             : };
     646             : 
     647             : 
     648             : /* Python 2 has a tp_flags value for rich comparisons.  Python 3 does not (on by default) */
     649             : #ifdef Py_TPFLAGS_HAVE_RICHCOMPARE
     650             : #define TP_FLAGS (Py_TPFLAGS_HAVE_RICHCOMPARE)
     651             : #else
     652             : #define TP_FLAGS 0
     653             : #endif
     654             : 
     655             : static PyTypeObject PyUNOType =
     656             : {
     657             :     PyVarObject_HEAD_INIT( &PyType_Type, 0 )
     658             :     "pyuno",
     659             :     sizeof (PyUNO),
     660             :     0,
     661             :     (destructor) PyUNO_del,
     662             :     (printfunc) 0,
     663             :     (getattrfunc) PyUNO_getattr,
     664             :     (setattrfunc) PyUNO_setattr,
     665             :     /* this type does not exist in Python 3: (cmpfunc) */ 0,
     666             :     (reprfunc) PyUNO_repr,
     667             :     0,
     668             :     0,
     669             :     0,
     670             :     (hashfunc) 0,
     671             :     (ternaryfunc) 0,
     672             :     (reprfunc) PyUNO_str,
     673             :     (getattrofunc)0,
     674             :     (setattrofunc)0,
     675             :     NULL,
     676             :     TP_FLAGS,
     677             :     NULL,
     678             :     (traverseproc)0,
     679             :     (inquiry)0,
     680             :     (richcmpfunc) PyUNO_cmp,
     681             :     0,
     682             :     (getiterfunc)0,
     683             :     (iternextfunc)0,
     684             :     PyUNOMethods,
     685             :     NULL,
     686             :     NULL,
     687             :     NULL,
     688             :     NULL,
     689             :     (descrgetfunc)0,
     690             :     (descrsetfunc)0,
     691             :     0,
     692             :     (initproc)0,
     693             :     (allocfunc)0,
     694             :     (newfunc)0,
     695             :     (freefunc)0,
     696             :     (inquiry)0,
     697             :     NULL,
     698             :     NULL,
     699             :     NULL,
     700             :     NULL,
     701             :     NULL,
     702             :     (destructor)0
     703             : #if PY_VERSION_HEX >= 0x02060000
     704             :     , 0
     705             : #endif
     706             : };
     707             : 
     708           2 : int PyUNO_initType()
     709             : {
     710           2 :     return PyType_Ready(&PyUNOType);
     711             : }
     712             : 
     713          39 : PyRef getPyUnoClass()
     714             : {
     715          39 :     return PyRef( reinterpret_cast< PyObject * > ( &PyUNOType ) );
     716             : }
     717             : 
     718          94 : PyObject* PyUNO_new (
     719             :     const Any & targetInterface, const Reference<XSingleServiceFactory> &ssf)
     720             : {
     721          94 :     Reference<XInterface> tmp_interface;
     722             : 
     723          94 :     targetInterface >>= tmp_interface;
     724             : 
     725          94 :     if (!tmp_interface.is ())
     726             :     {
     727             :         // empty reference !
     728           1 :         Py_INCREF( Py_None );
     729           1 :         return Py_None;
     730             :     }
     731          93 :    return PyUNO_new_UNCHECKED (targetInterface, ssf);
     732             : }
     733             : 
     734             : 
     735         497 : PyObject* PyUNO_new_UNCHECKED (
     736             :     const Any &targetInterface,
     737             :     const Reference<XSingleServiceFactory> &ssf )
     738             : {
     739         497 :     Reference<XInterface> tmp_interface;
     740         994 :     Reference<XInvocation2> tmp_invocation;
     741             :     {
     742         497 :         PyThreadDetach antiguard;
     743         994 :         Sequence<Any> arguments(1);
     744         497 :         arguments[0] <<= targetInterface;
     745         497 :         tmp_interface = ssf->createInstanceWithArguments(arguments);
     746         497 :         tmp_invocation.set(tmp_interface, UNO_QUERY);
     747         497 :         if (!tmp_invocation.is() && tmp_interface.is()) {
     748             :             throw RuntimeException(
     749             :                 "XInvocation2 not implemented, cannot interact with object",
     750           0 :                 Reference<XInterface>());
     751         497 :         }
     752             :     }
     753         497 :     if (!tmp_interface.is())
     754             :     {
     755           0 :         Py_INCREF( Py_None );
     756           0 :         return Py_None;
     757             :     }
     758         497 :     PyUNO* self = PyObject_New (PyUNO, &PyUNOType);
     759         497 :     if (self == NULL)
     760           0 :         return NULL; // == error
     761         497 :     self->members = new PyUNOInternals();
     762         497 :     self->members->xInvocation = tmp_invocation;
     763         497 :     self->members->wrappedObject = targetInterface;
     764         994 :     return (PyObject*) self;
     765             : }
     766             : 
     767             : }
     768             : 
     769             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10