1*67c7d1c1SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*67c7d1c1SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*67c7d1c1SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*67c7d1c1SAndrew Rist * distributed with this work for additional information 6*67c7d1c1SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*67c7d1c1SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*67c7d1c1SAndrew Rist * "License"); you may not use this file except in compliance 9*67c7d1c1SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*67c7d1c1SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*67c7d1c1SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*67c7d1c1SAndrew Rist * software distributed under the License is distributed on an 15*67c7d1c1SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*67c7d1c1SAndrew Rist * KIND, either express or implied. See the License for the 17*67c7d1c1SAndrew Rist * specific language governing permissions and limitations 18*67c7d1c1SAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*67c7d1c1SAndrew Rist *************************************************************/ 21*67c7d1c1SAndrew Rist 22*67c7d1c1SAndrew Rist 23cdf0e10cSrcweir #include "pyuno_impl.hxx" 24cdf0e10cSrcweir 25cdf0e10cSrcweir #include <rtl/ustrbuf.hxx> 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include <typelib/typedescription.hxx> 28cdf0e10cSrcweir 29cdf0e10cSrcweir using rtl::OUString; 30cdf0e10cSrcweir using rtl::OUStringBuffer; 31cdf0e10cSrcweir using rtl::OUStringToOString; 32cdf0e10cSrcweir 33cdf0e10cSrcweir using com::sun::star::uno::RuntimeException; 34cdf0e10cSrcweir using com::sun::star::uno::Sequence; 35cdf0e10cSrcweir using com::sun::star::uno::Type; 36cdf0e10cSrcweir using com::sun::star::uno::Reference; 37cdf0e10cSrcweir using com::sun::star::uno::XInterface; 38cdf0e10cSrcweir using com::sun::star::uno::TypeDescription; 39cdf0e10cSrcweir 40cdf0e10cSrcweir namespace pyuno 41cdf0e10cSrcweir { 42cdf0e10cSrcweir 43cdf0e10cSrcweir void raisePyExceptionWithAny( const com::sun::star::uno::Any &anyExc ) 44cdf0e10cSrcweir { 45cdf0e10cSrcweir try 46cdf0e10cSrcweir { 47cdf0e10cSrcweir Runtime runtime; 48cdf0e10cSrcweir PyRef exc = runtime.any2PyObject( anyExc ); 49cdf0e10cSrcweir if( exc.is() ) 50cdf0e10cSrcweir { 51cdf0e10cSrcweir PyRef type( getClass( anyExc.getValueType().getTypeName(),runtime ) ); 52cdf0e10cSrcweir PyErr_SetObject( type.get(), exc.get()); 53cdf0e10cSrcweir } 54cdf0e10cSrcweir else 55cdf0e10cSrcweir { 56cdf0e10cSrcweir com::sun::star::uno::Exception e; 57cdf0e10cSrcweir anyExc >>= e; 58cdf0e10cSrcweir 59cdf0e10cSrcweir OUStringBuffer buf; 60cdf0e10cSrcweir buf.appendAscii( "Couldn't convert uno exception to a python exception (" ); 61cdf0e10cSrcweir buf.append(anyExc.getValueType().getTypeName()); 62cdf0e10cSrcweir buf.appendAscii( ": " ); 63cdf0e10cSrcweir buf.append(e.Message ); 64cdf0e10cSrcweir buf.appendAscii( ")" ); 65cdf0e10cSrcweir PyErr_SetString( 66cdf0e10cSrcweir PyExc_SystemError, 67cdf0e10cSrcweir OUStringToOString(buf.makeStringAndClear(),RTL_TEXTENCODING_ASCII_US) ); 68cdf0e10cSrcweir } 69cdf0e10cSrcweir } 70cdf0e10cSrcweir catch( com::sun::star::lang::IllegalArgumentException & e) 71cdf0e10cSrcweir { 72cdf0e10cSrcweir PyErr_SetString( PyExc_SystemError, 73cdf0e10cSrcweir OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US) ); 74cdf0e10cSrcweir } 75cdf0e10cSrcweir catch( com::sun::star::script::CannotConvertException & e) 76cdf0e10cSrcweir { 77cdf0e10cSrcweir PyErr_SetString( PyExc_SystemError, 78cdf0e10cSrcweir OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US) ); 79cdf0e10cSrcweir } 80cdf0e10cSrcweir catch( RuntimeException & e) 81cdf0e10cSrcweir { 82cdf0e10cSrcweir PyErr_SetString( PyExc_SystemError, 83cdf0e10cSrcweir OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US) ); 84cdf0e10cSrcweir } 85cdf0e10cSrcweir } 86cdf0e10cSrcweir 87cdf0e10cSrcweir 88cdf0e10cSrcweir static PyRef createClass( const OUString & name, const Runtime &runtime ) 89cdf0e10cSrcweir throw ( RuntimeException ) 90cdf0e10cSrcweir { 91cdf0e10cSrcweir // assuming that this is never deleted ! 92cdf0e10cSrcweir // note I don't have the knowledge how to initialize these type objects correctly ! 93cdf0e10cSrcweir TypeDescription desc( name ); 94cdf0e10cSrcweir if( ! desc.is() ) 95cdf0e10cSrcweir { 96cdf0e10cSrcweir OUStringBuffer buf; 97cdf0e10cSrcweir buf.appendAscii( "pyuno.getClass: uno exception " ); 98cdf0e10cSrcweir buf.append(name).appendAscii( " is unknown" ); 99cdf0e10cSrcweir throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface > () ); 100cdf0e10cSrcweir } 101cdf0e10cSrcweir 102cdf0e10cSrcweir sal_Bool isStruct = desc.get()->eTypeClass == typelib_TypeClass_STRUCT; 103cdf0e10cSrcweir sal_Bool isExc = desc.get()->eTypeClass == typelib_TypeClass_EXCEPTION; 104cdf0e10cSrcweir sal_Bool isInterface = desc.get()->eTypeClass == typelib_TypeClass_INTERFACE; 105cdf0e10cSrcweir if( !isStruct && !isExc && ! isInterface ) 106cdf0e10cSrcweir { 107cdf0e10cSrcweir OUStringBuffer buf; 108cdf0e10cSrcweir buf.appendAscii( "pyuno.getClass: " ).append(name).appendAscii( "is a " ); 109cdf0e10cSrcweir buf.appendAscii( 110cdf0e10cSrcweir typeClassToString( (com::sun::star::uno::TypeClass) desc.get()->eTypeClass)); 111cdf0e10cSrcweir buf.appendAscii( ", expected EXCEPTION, STRUCT or INTERFACE" ); 112cdf0e10cSrcweir throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface>() ); 113cdf0e10cSrcweir } 114cdf0e10cSrcweir 115cdf0e10cSrcweir // retrieve base class 116cdf0e10cSrcweir PyRef base; 117cdf0e10cSrcweir if( isInterface ) 118cdf0e10cSrcweir { 119cdf0e10cSrcweir typelib_InterfaceTypeDescription *pDesc = (typelib_InterfaceTypeDescription * )desc.get(); 120cdf0e10cSrcweir if( pDesc->pBaseTypeDescription ) 121cdf0e10cSrcweir { 122cdf0e10cSrcweir base = getClass( pDesc->pBaseTypeDescription->aBase.pTypeName, runtime ); 123cdf0e10cSrcweir } 124cdf0e10cSrcweir else 125cdf0e10cSrcweir { 126cdf0e10cSrcweir // must be XInterface ! 127cdf0e10cSrcweir } 128cdf0e10cSrcweir } 129cdf0e10cSrcweir else 130cdf0e10cSrcweir { 131cdf0e10cSrcweir typelib_CompoundTypeDescription *pDesc = (typelib_CompoundTypeDescription*)desc.get(); 132cdf0e10cSrcweir if( pDesc->pBaseTypeDescription ) 133cdf0e10cSrcweir { 134cdf0e10cSrcweir base = getClass( pDesc->pBaseTypeDescription->aBase.pTypeName, runtime ); 135cdf0e10cSrcweir } 136cdf0e10cSrcweir else 137cdf0e10cSrcweir { 138cdf0e10cSrcweir if( isExc ) 139cdf0e10cSrcweir // we are currently creating the root UNO exception 140cdf0e10cSrcweir base = PyRef(PyExc_Exception); 141cdf0e10cSrcweir } 142cdf0e10cSrcweir } 143cdf0e10cSrcweir PyRef args( PyTuple_New( 3 ), SAL_NO_ACQUIRE ); 144cdf0e10cSrcweir 145cdf0e10cSrcweir PyRef pyTypeName = ustring2PyString( name /*.replace( '.', '_' )*/ ); 146cdf0e10cSrcweir 147cdf0e10cSrcweir PyRef bases; 148cdf0e10cSrcweir if( base.is() ) 149cdf0e10cSrcweir { 150cdf0e10cSrcweir { // for CC, keeping ref-count being 1 151cdf0e10cSrcweir bases = PyRef( PyTuple_New( 1 ), SAL_NO_ACQUIRE ); 152cdf0e10cSrcweir } 153cdf0e10cSrcweir PyTuple_SetItem( bases.get(), 0 , base.getAcquired() ); 154cdf0e10cSrcweir } 155cdf0e10cSrcweir else 156cdf0e10cSrcweir { 157cdf0e10cSrcweir bases = PyRef( PyTuple_New( 0 ), SAL_NO_ACQUIRE ); 158cdf0e10cSrcweir } 159cdf0e10cSrcweir 160cdf0e10cSrcweir PyTuple_SetItem( args.get(), 0, pyTypeName.getAcquired()); 161cdf0e10cSrcweir PyTuple_SetItem( args.get(), 1, bases.getAcquired() ); 162cdf0e10cSrcweir PyTuple_SetItem( args.get(), 2, PyDict_New() ); 163cdf0e10cSrcweir 164cdf0e10cSrcweir PyRef ret( 165cdf0e10cSrcweir PyObject_CallObject(reinterpret_cast<PyObject *>(&PyClass_Type) , args.get()), 166cdf0e10cSrcweir SAL_NO_ACQUIRE ); 167cdf0e10cSrcweir 168cdf0e10cSrcweir // now overwrite ctor and attrib functions 169cdf0e10cSrcweir if( isInterface ) 170cdf0e10cSrcweir { 171cdf0e10cSrcweir PyObject_SetAttrString( 172cdf0e10cSrcweir ret.get(), const_cast< char * >("__pyunointerface__"), 173cdf0e10cSrcweir ustring2PyString(name).get() ); 174cdf0e10cSrcweir } 175cdf0e10cSrcweir else 176cdf0e10cSrcweir { 177cdf0e10cSrcweir PyRef ctor = getObjectFromUnoModule( runtime,"_uno_struct__init__" ); 178cdf0e10cSrcweir PyRef setter = getObjectFromUnoModule( runtime,"_uno_struct__setattr__" ); 179cdf0e10cSrcweir PyRef getter = getObjectFromUnoModule( runtime,"_uno_struct__getattr__" ); 180cdf0e10cSrcweir PyRef repr = getObjectFromUnoModule( runtime,"_uno_struct__repr__" ); 181cdf0e10cSrcweir PyRef eq = getObjectFromUnoModule( runtime,"_uno_struct__eq__" ); 182cdf0e10cSrcweir 183cdf0e10cSrcweir PyObject_SetAttrString( 184cdf0e10cSrcweir ret.get(), const_cast< char * >("__pyunostruct__"), 185cdf0e10cSrcweir ustring2PyString(name).get() ); 186cdf0e10cSrcweir PyObject_SetAttrString( 187cdf0e10cSrcweir ret.get(), const_cast< char * >("typeName"), 188cdf0e10cSrcweir ustring2PyString(name).get() ); 189cdf0e10cSrcweir PyObject_SetAttrString( 190cdf0e10cSrcweir ret.get(), const_cast< char * >("__init__"), ctor.get() ); 191cdf0e10cSrcweir PyObject_SetAttrString( 192cdf0e10cSrcweir ret.get(), const_cast< char * >("__getattr__"), getter.get() ); 193cdf0e10cSrcweir PyObject_SetAttrString( 194cdf0e10cSrcweir ret.get(), const_cast< char * >("__setattr__"), setter.get() ); 195cdf0e10cSrcweir PyObject_SetAttrString( 196cdf0e10cSrcweir ret.get(), const_cast< char * >("__repr__"), repr.get() ); 197cdf0e10cSrcweir PyObject_SetAttrString( 198cdf0e10cSrcweir ret.get(), const_cast< char * >("__str__"), repr.get() ); 199cdf0e10cSrcweir PyObject_SetAttrString( 200cdf0e10cSrcweir ret.get(), const_cast< char * >("__eq__"), eq.get() ); 201cdf0e10cSrcweir } 202cdf0e10cSrcweir return ret; 203cdf0e10cSrcweir } 204cdf0e10cSrcweir 205cdf0e10cSrcweir bool isInstanceOfStructOrException( PyObject *obj) 206cdf0e10cSrcweir { 207cdf0e10cSrcweir PyRef attr( 208cdf0e10cSrcweir PyObject_GetAttrString(obj, const_cast< char * >("__class__")), 209cdf0e10cSrcweir SAL_NO_ACQUIRE ); 210cdf0e10cSrcweir return PyObject_HasAttrString( 211cdf0e10cSrcweir attr.get(), const_cast< char * >("__pyunostruct__")); 212cdf0e10cSrcweir } 213cdf0e10cSrcweir 214cdf0e10cSrcweir sal_Bool isInterfaceClass( const Runtime &runtime, PyObject * obj ) 215cdf0e10cSrcweir { 216cdf0e10cSrcweir const ClassSet & set = runtime.getImpl()->cargo->interfaceSet; 217cdf0e10cSrcweir return set.find( obj ) != set.end(); 218cdf0e10cSrcweir } 219cdf0e10cSrcweir 220cdf0e10cSrcweir PyRef getClass( const OUString & name , const Runtime &runtime) 221cdf0e10cSrcweir { 222cdf0e10cSrcweir PyRef ret; 223cdf0e10cSrcweir 224cdf0e10cSrcweir RuntimeCargo *cargo =runtime.getImpl()->cargo; 225cdf0e10cSrcweir ExceptionClassMap::iterator ii = cargo->exceptionMap.find( name ); 226cdf0e10cSrcweir if( ii == cargo->exceptionMap.end() ) 227cdf0e10cSrcweir { 228cdf0e10cSrcweir ret = createClass( name, runtime ); 229cdf0e10cSrcweir cargo->exceptionMap[name] = ret; 230cdf0e10cSrcweir if( PyObject_HasAttrString( 231cdf0e10cSrcweir ret.get(), const_cast< char * >("__pyunointerface__") ) ) 232cdf0e10cSrcweir cargo->interfaceSet.insert( ret ); 233cdf0e10cSrcweir 234cdf0e10cSrcweir PyObject_SetAttrString( 235cdf0e10cSrcweir ret.get(), const_cast< char * >("__pyunointerface__"), 236cdf0e10cSrcweir ustring2PyString(name).get() ); 237cdf0e10cSrcweir } 238cdf0e10cSrcweir else 239cdf0e10cSrcweir { 240cdf0e10cSrcweir ret = ii->second; 241cdf0e10cSrcweir } 242cdf0e10cSrcweir 243cdf0e10cSrcweir return ret; 244cdf0e10cSrcweir } 245cdf0e10cSrcweir 246cdf0e10cSrcweir 247cdf0e10cSrcweir } 248