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