Branch data 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 : : #include "pyuno_impl.hxx"
20 : :
21 : : #include <rtl/ustrbuf.hxx>
22 : :
23 : : #include <typelib/typedescription.hxx>
24 : :
25 : : using rtl::OUString;
26 : : using rtl::OUStringBuffer;
27 : : using rtl::OUStringToOString;
28 : :
29 : : using com::sun::star::uno::RuntimeException;
30 : : using com::sun::star::uno::Sequence;
31 : : using com::sun::star::uno::Type;
32 : : using com::sun::star::uno::Reference;
33 : : using com::sun::star::uno::XInterface;
34 : : using com::sun::star::uno::TypeDescription;
35 : :
36 : : namespace pyuno
37 : : {
38 : :
39 : 2802 : void raisePyExceptionWithAny( const com::sun::star::uno::Any &anyExc )
40 : : {
41 : : try
42 : : {
43 [ + - ]: 2802 : Runtime runtime;
44 [ + - ]: 2802 : PyRef exc = runtime.any2PyObject( anyExc );
45 [ + - ]: 2802 : if( exc.is() )
46 : : {
47 [ + - ]: 2802 : PyRef type( getClass( anyExc.getValueType().getTypeName(),runtime ) );
48 [ + - ][ + - ]: 2802 : PyErr_SetObject( type.get(), exc.get());
49 : : }
50 : : else
51 : : {
52 [ # # ]: 0 : com::sun::star::uno::Exception e;
53 [ # # ]: 0 : anyExc >>= e;
54 : :
55 : 0 : OUStringBuffer buf;
56 [ # # ]: 0 : buf.appendAscii( "Couldn't convert uno exception to a python exception (" );
57 [ # # ]: 0 : buf.append(anyExc.getValueType().getTypeName());
58 [ # # ]: 0 : buf.appendAscii( ": " );
59 [ # # ]: 0 : buf.append(e.Message );
60 [ # # ]: 0 : buf.appendAscii( ")" );
61 : : PyErr_SetString(
62 : : PyExc_SystemError,
63 [ # # ][ # # ]: 0 : OUStringToOString(buf.makeStringAndClear(),RTL_TEXTENCODING_ASCII_US).getStr() );
[ # # ][ # # ]
64 [ + - ][ + - ]: 2802 : }
65 : : }
66 : 0 : catch(const com::sun::star::lang::IllegalArgumentException & e)
67 : : {
68 : : PyErr_SetString( PyExc_SystemError,
69 [ # # # # ]: 0 : OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US).getStr() );
70 : : }
71 : 0 : catch(const com::sun::star::script::CannotConvertException & e)
72 : : {
73 : : PyErr_SetString( PyExc_SystemError,
74 [ # # # # ]: 0 : OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US).getStr() );
75 : : }
76 [ # # # # ]: 0 : catch(const RuntimeException & e)
77 : : {
78 : : PyErr_SetString( PyExc_SystemError,
79 [ # # # # ]: 0 : OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US).getStr() );
80 : : }
81 : 2802 : }
82 : :
83 : :
84 : 3473 : static PyRef createClass( const OUString & name, const Runtime &runtime )
85 : : throw ( RuntimeException )
86 : : {
87 : : // assuming that this is never deleted !
88 : : // note I don't have the knowledge how to initialize these type objects correctly !
89 : 3473 : TypeDescription desc( name );
90 [ + + ]: 3473 : if( ! desc.is() )
91 : : {
92 : 1569 : OUStringBuffer buf;
93 [ + - ]: 1569 : buf.appendAscii( "pyuno.getClass: uno exception " );
94 [ + - ][ + - ]: 1569 : buf.append(name).appendAscii( " is unknown" );
95 [ + - ][ + - ]: 1569 : throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface > () );
96 : : }
97 : :
98 : 1904 : sal_Bool isStruct = desc.get()->eTypeClass == typelib_TypeClass_STRUCT;
99 : 1904 : sal_Bool isExc = desc.get()->eTypeClass == typelib_TypeClass_EXCEPTION;
100 : 1904 : sal_Bool isInterface = desc.get()->eTypeClass == typelib_TypeClass_INTERFACE;
101 [ + + ][ - + ]: 1904 : if( !isStruct && !isExc && ! isInterface )
[ + + ]
102 : : {
103 : 0 : OUStringBuffer buf;
104 [ # # ][ # # ]: 0 : buf.appendAscii( "pyuno.getClass: " ).append(name).appendAscii( "is a " );
[ # # ]
105 : : buf.appendAscii(
106 [ # # ][ # # ]: 0 : typeClassToString( (com::sun::star::uno::TypeClass) desc.get()->eTypeClass));
107 [ # # ]: 0 : buf.appendAscii( ", expected EXCEPTION, STRUCT or INTERFACE" );
108 [ # # ][ # # ]: 0 : throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface>() );
109 : : }
110 : :
111 : : // retrieve base class
112 : 1904 : PyRef base;
113 [ + + ]: 1904 : if( isInterface )
114 : : {
115 : 1232 : typelib_InterfaceTypeDescription *pDesc = (typelib_InterfaceTypeDescription * )desc.get();
116 [ + + ]: 1232 : if( pDesc->pBaseTypeDescription )
117 : : {
118 [ + - ][ + - ]: 1120 : base = getClass( pDesc->pBaseTypeDescription->aBase.pTypeName, runtime );
[ + - ]
119 : : }
120 : : else
121 : : {
122 : : // must be XInterface !
123 : : }
124 : : }
125 : : else
126 : : {
127 : 672 : typelib_CompoundTypeDescription *pDesc = (typelib_CompoundTypeDescription*)desc.get();
128 [ + + ]: 672 : if( pDesc->pBaseTypeDescription )
129 : : {
130 [ + - ][ + - ]: 112 : base = getClass( pDesc->pBaseTypeDescription->aBase.pTypeName, runtime );
[ + - ]
131 : : }
132 : : else
133 : : {
134 [ + + ]: 560 : if( isExc )
135 : : // we are currently creating the root UNO exception
136 [ + - ][ + - ]: 112 : base = PyRef(PyExc_Exception);
137 : : }
138 : : }
139 [ + - ]: 1904 : PyRef args( PyTuple_New( 3 ), SAL_NO_ACQUIRE );
140 : :
141 [ + - ]: 1904 : PyRef pyTypeName = ustring2PyString( name /*.replace( '.', '_' )*/ );
142 : :
143 : 1904 : PyRef bases;
144 [ + + ]: 1904 : if( base.is() )
145 : : {
146 : : { // for CC, keeping ref-count being 1
147 [ + - ][ + - ]: 1344 : bases = PyRef( PyTuple_New( 1 ), SAL_NO_ACQUIRE );
[ + - ]
148 : : }
149 [ + - ]: 1344 : PyTuple_SetItem( bases.get(), 0 , base.getAcquired() );
150 : : }
151 : : else
152 : : {
153 [ + - ][ + - ]: 560 : bases = PyRef( PyTuple_New( 0 ), SAL_NO_ACQUIRE );
[ + - ]
154 : : }
155 : :
156 [ + - ]: 1904 : PyTuple_SetItem( args.get(), 0, pyTypeName.getAcquired());
157 [ + - ]: 1904 : PyTuple_SetItem( args.get(), 1, bases.getAcquired() );
158 [ + - ][ + - ]: 1904 : PyTuple_SetItem( args.get(), 2, PyDict_New() );
159 : :
160 : : PyRef ret(
161 : : PyObject_CallObject(reinterpret_cast<PyObject *>(&PyType_Type) , args.get()),
162 [ + - ]: 1904 : SAL_NO_ACQUIRE );
163 : :
164 : : // now overwrite ctor and attrib functions
165 [ + + ]: 1904 : if( isInterface )
166 : : {
167 : : PyObject_SetAttrString(
168 : : ret.get(), "__pyunointerface__",
169 [ + - ][ + - ]: 1232 : ustring2PyString(name).get() );
[ + - ]
170 : : }
171 : : else
172 : : {
173 [ + - ]: 672 : PyRef ctor = getObjectFromUnoModule( runtime,"_uno_struct__init__" );
174 [ + - ]: 672 : PyRef setter = getObjectFromUnoModule( runtime,"_uno_struct__setattr__" );
175 [ + - ]: 672 : PyRef getter = getObjectFromUnoModule( runtime,"_uno_struct__getattr__" );
176 [ + - ]: 672 : PyRef repr = getObjectFromUnoModule( runtime,"_uno_struct__repr__" );
177 [ + - ]: 672 : PyRef eq = getObjectFromUnoModule( runtime,"_uno_struct__eq__" );
178 : :
179 : : PyObject_SetAttrString(
180 : : ret.get(), "__pyunostruct__",
181 [ + - ][ + - ]: 672 : ustring2PyString(name).get() );
[ + - ]
182 : : PyObject_SetAttrString(
183 : : ret.get(), "typeName",
184 [ + - ][ + - ]: 672 : ustring2PyString(name).get() );
[ + - ]
185 : : PyObject_SetAttrString(
186 [ + - ]: 672 : ret.get(), "__init__", ctor.get() );
187 : : PyObject_SetAttrString(
188 [ + - ]: 672 : ret.get(), "__getattr__", getter.get() );
189 : : PyObject_SetAttrString(
190 [ + - ]: 672 : ret.get(), "__setattr__", setter.get() );
191 : : PyObject_SetAttrString(
192 [ + - ]: 672 : ret.get(), "__repr__", repr.get() );
193 : : PyObject_SetAttrString(
194 [ + - ]: 672 : ret.get(), "__str__", repr.get() );
195 : : PyObject_SetAttrString(
196 [ + - ][ + - ]: 672 : ret.get(), "__eq__", eq.get() );
[ + - ][ + - ]
[ + - ][ + - ]
197 : : }
198 [ + - ][ + - ]: 3473 : return ret;
[ + - ][ + - ]
199 : : }
200 : :
201 : 16915 : bool isInstanceOfStructOrException( PyObject *obj)
202 : : {
203 : : PyRef attr(
204 : : PyObject_GetAttrString(obj, "__class__"),
205 [ + - ]: 16915 : SAL_NO_ACQUIRE );
206 : : return PyObject_HasAttrString(
207 [ + - ][ + - ]: 16915 : attr.get(), "__pyunostruct__");
208 : : }
209 : :
210 : 998 : sal_Bool isInterfaceClass( const Runtime &runtime, PyObject * obj )
211 : : {
212 : 998 : const ClassSet & set = runtime.getImpl()->cargo->interfaceSet;
213 [ + - ][ + - ]: 998 : return set.find( obj ) != set.end();
214 : : }
215 : :
216 : 37792 : PyRef getClass( const OUString & name , const Runtime &runtime)
217 : : {
218 : 37792 : PyRef ret;
219 : :
220 : 37792 : RuntimeCargo *cargo =runtime.getImpl()->cargo;
221 [ + - ]: 37792 : ExceptionClassMap::iterator ii = cargo->exceptionMap.find( name );
222 [ + - ][ + + ]: 37792 : if( ii == cargo->exceptionMap.end() )
223 : : {
224 [ + + ][ + - ]: 3473 : ret = createClass( name, runtime );
[ + - ]
225 [ + - ][ + - ]: 1904 : cargo->exceptionMap[name] = ret;
226 [ + + ]: 1904 : if( PyObject_HasAttrString(
227 [ + - ]: 1904 : ret.get(), "__pyunointerface__" ) )
228 [ + - ]: 1344 : cargo->interfaceSet.insert( ret );
229 : :
230 : : PyObject_SetAttrString(
231 : : ret.get(), "__pyunointerface__",
232 [ + - ][ + - ]: 1904 : ustring2PyString(name).get() );
[ + - ]
233 : : }
234 : : else
235 : : {
236 [ + - ][ + - ]: 36223 : ret = ii->second;
237 : : }
238 : :
239 : 37792 : return ret;
240 : : }
241 : :
242 : :
243 : : }
244 : :
245 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|