Version 7.1.7.1, tag libreoffice-7.1.7.1
[LibreOffice.git] / pyuno / source / module / pyuno_struct.cxx
blob747e759f6b618bc84250ddfa63b84392cfbeff29
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <sal/config.h>
22 #include <com/sun/star/beans/UnknownPropertyException.hpp>
23 #include <com/sun/star/beans/XMaterialHolder.hpp>
24 #include <com/sun/star/script/CannotConvertException.hpp>
25 #include <com/sun/star/script/XInvocation2.hpp>
26 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
28 #include "pyuno_impl.hxx"
30 using com::sun::star::uno::Sequence;
31 using com::sun::star::uno::Reference;
32 using com::sun::star::uno::Any;
33 using com::sun::star::uno::makeAny;
34 using com::sun::star::uno::UNO_QUERY;
35 using com::sun::star::uno::TypeClass;
36 using com::sun::star::uno::RuntimeException;
37 using com::sun::star::uno::Exception;
38 using com::sun::star::lang::XSingleServiceFactory;
39 using com::sun::star::script::XInvocation2;
40 using com::sun::star::beans::XMaterialHolder;
42 namespace pyuno
45 static void PyUNOStruct_del( PyObject* self )
47 PyUNO *me = reinterpret_cast<PyUNO*>( self );
49 PyThreadDetach antiguard;
50 delete me->members;
52 PyObject_Del( self );
55 static PyObject *PyUNOStruct_str( PyObject *self )
57 PyUNO *me = reinterpret_cast<PyUNO*>( self );
58 OString buf;
60 Reference<XMaterialHolder> rHolder( me->members->xInvocation,UNO_QUERY );
61 if( rHolder.is() )
63 PyThreadDetach antiguard;
64 Any a = rHolder->getMaterial();
65 OUString s = val2str( a.getValue(), a.getValueType().getTypeLibType() );
66 buf = OUStringToOString( s, RTL_TEXTENCODING_ASCII_US );
69 return PyUnicode_FromString( buf.getStr());
72 static PyObject *PyUNOStruct_repr( PyObject *self )
74 PyUNO *me = reinterpret_cast<PyUNO*>( self );
75 PyObject *ret = nullptr;
77 if( me->members->wrappedObject.getValueType().getTypeClass()
78 == css::uno::TypeClass_EXCEPTION )
80 Reference< XMaterialHolder > rHolder(me->members->xInvocation,UNO_QUERY);
81 if( rHolder.is() )
83 Any a = rHolder->getMaterial();
84 Exception e;
85 a >>= e;
86 ret = ustring2PyUnicode(e.Message ).getAcquired();
89 else
91 ret = PyUNOStruct_str( self );
94 return ret;
97 static PyObject* PyUNOStruct_dir( PyObject *self )
99 PyUNO *me = reinterpret_cast<PyUNO*>( self );
101 PyObject* member_list = nullptr;
105 member_list = PyList_New( 0 );
106 const css::uno::Sequence<OUString> aMemberNames = me->members->xInvocation->getMemberNames();
107 for( const auto& aMember : aMemberNames )
109 // setitem steals a reference
110 PyList_Append( member_list, ustring2PyString( aMember ).getAcquired() );
113 catch( const RuntimeException &e )
115 raisePyExceptionWithAny( makeAny(e) );
118 return member_list;
121 static PyObject* PyUNOStruct_getattr( PyObject* self, char* name )
123 PyUNO *me = reinterpret_cast<PyUNO*>( self );
127 Runtime runtime;
129 me = reinterpret_cast<PyUNO*>(self);
130 if (strcmp (name, "__dict__") == 0)
132 Py_INCREF (Py_TYPE(me)->tp_dict);
133 return Py_TYPE(me)->tp_dict;
135 if( strcmp( name, "__class__" ) == 0 )
137 return getClass(
138 me->members->wrappedObject.getValueType().getTypeName(), runtime ).getAcquired();
141 PyObject *pRet = PyObject_GenericGetAttr( self, PyUnicode_FromString( name ) );
142 if( pRet )
143 return pRet;
144 PyErr_Clear();
146 OUString attrName( OUString::createFromAscii( name ) );
147 if( me->members->xInvocation->hasProperty( attrName ) )
149 //Return the value of the property
150 Any anyRet;
152 PyThreadDetach antiguard;
153 anyRet = me->members->xInvocation->getValue( attrName );
155 PyRef ret = runtime.any2PyObject( anyRet );
156 Py_XINCREF( ret.get() );
157 return ret.get();
160 //or else...
161 PyErr_SetString (PyExc_AttributeError, name);
163 catch( const css::reflection::InvocationTargetException & e )
165 raisePyExceptionWithAny( e.TargetException );
167 catch( const css::beans::UnknownPropertyException & e )
169 raisePyExceptionWithAny( makeAny(e) );
171 catch( const css::lang::IllegalArgumentException &e )
173 raisePyExceptionWithAny( makeAny(e) );
175 catch( const css::script::CannotConvertException &e )
177 raisePyExceptionWithAny( makeAny(e) );
179 catch( const RuntimeException &e )
181 raisePyExceptionWithAny( makeAny(e) );
184 return nullptr;
187 static int PyUNOStruct_setattr (PyObject* self, char* name, PyObject* value)
189 PyUNO* me;
191 me = reinterpret_cast<PyUNO*>(self);
194 Runtime runtime;
195 Any val= runtime.pyObject2Any(value, ACCEPT_UNO_ANY);
197 OUString attrName( OUString::createFromAscii( name ) );
199 PyThreadDetach antiguard;
200 if (me->members->xInvocation->hasProperty (attrName))
202 me->members->xInvocation->setValue (attrName, val);
203 return 0; //Keep with Python's boolean system
207 catch( const css::reflection::InvocationTargetException & e )
209 raisePyExceptionWithAny( e.TargetException );
210 return 1;
212 catch( const css::beans::UnknownPropertyException & e )
214 raisePyExceptionWithAny( makeAny(e) );
215 return 1;
217 catch( const css::script::CannotConvertException &e )
219 raisePyExceptionWithAny( makeAny(e) );
220 return 1;
222 catch( const RuntimeException & e )
224 raisePyExceptionWithAny( makeAny( e ) );
225 return 1;
227 PyErr_SetString (PyExc_AttributeError, name);
228 return 1; //as above.
232 static PyObject* PyUNOStruct_cmp( PyObject *self, PyObject *that, int op )
234 PyObject *result;
236 if(op != Py_EQ && op != Py_NE)
238 PyErr_SetString( PyExc_TypeError, "only '==' and '!=' comparisons are defined" );
239 return nullptr;
241 if( self == that )
243 result = (op == Py_EQ ? Py_True : Py_False);
244 Py_INCREF( result );
245 return result;
249 Runtime runtime;
250 if( PyObject_IsInstance( that, getPyUnoStructClass().get() ) )
253 PyUNO *me = reinterpret_cast< PyUNO * > ( self );
254 PyUNO *other = reinterpret_cast< PyUNO * > ( that );
255 css::uno::TypeClass tcMe = me->members->wrappedObject.getValueTypeClass();
256 css::uno::TypeClass tcOther = other->members->wrappedObject.getValueTypeClass();
258 if( tcMe == tcOther )
260 if( tcMe == css::uno::TypeClass_STRUCT ||
261 tcMe == css::uno::TypeClass_EXCEPTION )
263 Reference< XMaterialHolder > xMe( me->members->xInvocation,UNO_QUERY );
264 Reference< XMaterialHolder > xOther( other->members->xInvocation,UNO_QUERY );
265 if( xMe->getMaterial() == xOther->getMaterial() )
267 result = (op == Py_EQ ? Py_True : Py_False);
268 Py_INCREF( result );
269 return result;
275 catch( const css::uno::RuntimeException & e)
277 raisePyExceptionWithAny( makeAny( e ) );
280 result = (op == Py_EQ ? Py_False : Py_True);
281 Py_INCREF(result);
282 return result;
285 static PyMethodDef PyUNOStructMethods[] =
287 {"__dir__", reinterpret_cast<PyCFunction>(PyUNOStruct_dir), METH_NOARGS, nullptr},
288 {nullptr, nullptr, 0, nullptr}
291 static PyTypeObject PyUNOStructType =
293 PyVarObject_HEAD_INIT( &PyType_Type, 0 )
294 "pyuno.struct",
295 sizeof (PyUNO),
297 PyUNOStruct_del,
298 #if PY_VERSION_HEX >= 0x03080000
299 0, // Py_ssize_t tp_vectorcall_offset
300 #else
301 nullptr, // printfunc tp_print
302 #endif
303 PyUNOStruct_getattr,
304 PyUNOStruct_setattr,
305 /* this type does not exist in Python 3: (cmpfunc) */ nullptr,
306 PyUNOStruct_repr,
307 nullptr,
308 nullptr,
309 nullptr,
310 nullptr,
311 nullptr,
312 PyUNOStruct_str,
313 nullptr,
314 nullptr,
315 nullptr,
316 Py_TPFLAGS_HAVE_RICHCOMPARE,
317 nullptr,
318 nullptr,
319 nullptr,
320 PyUNOStruct_cmp,
322 nullptr,
323 nullptr,
324 PyUNOStructMethods,
325 nullptr,
326 nullptr,
327 nullptr,
328 nullptr,
329 nullptr,
330 nullptr,
332 nullptr,
333 nullptr,
334 nullptr,
335 nullptr,
336 nullptr,
337 nullptr,
338 nullptr,
339 nullptr,
340 nullptr,
341 nullptr,
342 nullptr
344 #if PY_VERSION_HEX >= 0x03040000
345 , nullptr
346 #if PY_VERSION_HEX >= 0x03080000
347 , nullptr // vectorcallfunc tp_vectorcall
348 #if PY_VERSION_HEX < 0x03090000
349 #if defined __clang__
350 #pragma clang diagnostic push
351 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
352 #endif
353 , nullptr // tp_print
354 #if defined __clang__
355 #pragma clang diagnostic pop
356 #endif
357 #endif
358 #endif
359 #endif
362 int PyUNOStruct_initType()
364 return PyType_Ready( &PyUNOStructType );
367 PyRef getPyUnoStructClass()
369 return PyRef( reinterpret_cast< PyObject * > ( &PyUNOStructType ) );
372 PyRef PyUNOStruct_new (
373 const Any &targetInterface,
374 const Reference<XSingleServiceFactory> &ssf )
376 Reference<XInvocation2> xInvocation;
379 PyThreadDetach antiguard;
380 xInvocation.set(
381 ssf->createInstanceWithArguments( Sequence<Any>( &targetInterface, 1 ) ), css::uno::UNO_QUERY_THROW );
383 if( !Py_IsInitialized() )
384 throw RuntimeException();
386 PyUNO* self = PyObject_New (PyUNO, &PyUNOStructType);
387 if (self == nullptr)
388 return PyRef(); // == error
389 self->members = new PyUNOInternals;
390 self->members->xInvocation = xInvocation;
391 self->members->wrappedObject = targetInterface;
392 return PyRef( reinterpret_cast<PyObject*>(self), SAL_NO_ACQUIRE );
398 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */