summaryrefslogtreecommitdiffstats
path: root/pyuno/source/module/pyuno_struct.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'pyuno/source/module/pyuno_struct.cxx')
-rw-r--r--pyuno/source/module/pyuno_struct.cxx400
1 files changed, 400 insertions, 0 deletions
diff --git a/pyuno/source/module/pyuno_struct.cxx b/pyuno/source/module/pyuno_struct.cxx
new file mode 100644
index 000000000..a5b127dc2
--- /dev/null
+++ b/pyuno/source/module/pyuno_struct.cxx
@@ -0,0 +1,400 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <rtl/strbuf.hxx>
+
+#include <com/sun/star/beans/UnknownPropertyException.hpp>
+#include <com/sun/star/beans/XMaterialHolder.hpp>
+#include <com/sun/star/script/CannotConvertException.hpp>
+#include <com/sun/star/script/XInvocation2.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+
+#include "pyuno_impl.hxx"
+
+using com::sun::star::uno::Sequence;
+using com::sun::star::uno::Reference;
+using com::sun::star::uno::Any;
+using com::sun::star::uno::makeAny;
+using com::sun::star::uno::UNO_QUERY;
+using com::sun::star::uno::TypeClass;
+using com::sun::star::uno::RuntimeException;
+using com::sun::star::uno::Exception;
+using com::sun::star::lang::XSingleServiceFactory;
+using com::sun::star::script::XInvocation2;
+using com::sun::star::beans::XMaterialHolder;
+
+namespace pyuno
+{
+
+static void PyUNOStruct_del( PyObject* self )
+{
+ PyUNO *me = reinterpret_cast<PyUNO*>( self );
+ {
+ PyThreadDetach antiguard;
+ delete me->members;
+ }
+ PyObject_Del( self );
+}
+
+static PyObject *PyUNOStruct_str( PyObject *self )
+{
+ PyUNO *me = reinterpret_cast<PyUNO*>( self );
+ OString buf;
+
+ Reference<XMaterialHolder> rHolder( me->members->xInvocation,UNO_QUERY );
+ if( rHolder.is() )
+ {
+ PyThreadDetach antiguard;
+ Any a = rHolder->getMaterial();
+ OUString s = val2str( a.getValue(), a.getValueType().getTypeLibType() );
+ buf = OUStringToOString( s, RTL_TEXTENCODING_ASCII_US );
+ }
+
+ return PyUnicode_FromString( buf.getStr());
+}
+
+static PyObject *PyUNOStruct_repr( PyObject *self )
+{
+ PyUNO *me = reinterpret_cast<PyUNO*>( self );
+ PyObject *ret = nullptr;
+
+ if( me->members->wrappedObject.getValueType().getTypeClass()
+ == css::uno::TypeClass_EXCEPTION )
+ {
+ Reference< XMaterialHolder > rHolder(me->members->xInvocation,UNO_QUERY);
+ if( rHolder.is() )
+ {
+ Any a = rHolder->getMaterial();
+ Exception e;
+ a >>= e;
+ ret = ustring2PyUnicode(e.Message ).getAcquired();
+ }
+ }
+ else
+ {
+ ret = PyUNOStruct_str( self );
+ }
+
+ return ret;
+}
+
+static PyObject* PyUNOStruct_dir( PyObject *self )
+{
+ PyUNO *me = reinterpret_cast<PyUNO*>( self );
+
+ PyObject* member_list = nullptr;
+
+ try
+ {
+ member_list = PyList_New( 0 );
+ const css::uno::Sequence<OUString> aMemberNames = me->members->xInvocation->getMemberNames();
+ for( const auto& aMember : aMemberNames )
+ {
+ // setitem steals a reference
+ PyList_Append( member_list, ustring2PyString( aMember ).getAcquired() );
+ }
+ }
+ catch( const RuntimeException &e )
+ {
+ raisePyExceptionWithAny( makeAny(e) );
+ }
+
+ return member_list;
+}
+
+static PyObject* PyUNOStruct_getattr( PyObject* self, char* name )
+{
+ PyUNO *me = reinterpret_cast<PyUNO*>( self );
+
+ try
+ {
+ Runtime runtime;
+
+ me = reinterpret_cast<PyUNO*>(self);
+ if (strcmp (name, "__dict__") == 0)
+ {
+ Py_INCREF (Py_TYPE(me)->tp_dict);
+ return Py_TYPE(me)->tp_dict;
+ }
+ if( strcmp( name, "__class__" ) == 0 )
+ {
+ return getClass(
+ me->members->wrappedObject.getValueType().getTypeName(), runtime ).getAcquired();
+ }
+
+ PyObject *pRet = PyObject_GenericGetAttr( self, PyUnicode_FromString( name ) );
+ if( pRet )
+ return pRet;
+ PyErr_Clear();
+
+ OUString attrName( OUString::createFromAscii( name ) );
+ if( me->members->xInvocation->hasProperty( attrName ) )
+ {
+ //Return the value of the property
+ Any anyRet;
+ {
+ PyThreadDetach antiguard;
+ anyRet = me->members->xInvocation->getValue( attrName );
+ }
+ PyRef ret = runtime.any2PyObject( anyRet );
+ Py_XINCREF( ret.get() );
+ return ret.get();
+ }
+
+ //or else...
+ PyErr_SetString (PyExc_AttributeError, name);
+ }
+ catch( const css::reflection::InvocationTargetException & e )
+ {
+ raisePyExceptionWithAny( e.TargetException );
+ }
+ catch( const css::beans::UnknownPropertyException & e )
+ {
+ raisePyExceptionWithAny( makeAny(e) );
+ }
+ catch( const css::lang::IllegalArgumentException &e )
+ {
+ raisePyExceptionWithAny( makeAny(e) );
+ }
+ catch( const css::script::CannotConvertException &e )
+ {
+ raisePyExceptionWithAny( makeAny(e) );
+ }
+ catch( const RuntimeException &e )
+ {
+ raisePyExceptionWithAny( makeAny(e) );
+ }
+
+ return nullptr;
+}
+
+static int PyUNOStruct_setattr (PyObject* self, char* name, PyObject* value)
+{
+ PyUNO* me;
+
+ me = reinterpret_cast<PyUNO*>(self);
+ try
+ {
+ Runtime runtime;
+ Any val= runtime.pyObject2Any(value, ACCEPT_UNO_ANY);
+
+ OUString attrName( OUString::createFromAscii( name ) );
+ {
+ PyThreadDetach antiguard;
+ if (me->members->xInvocation->hasProperty (attrName))
+ {
+ me->members->xInvocation->setValue (attrName, val);
+ return 0; //Keep with Python's boolean system
+ }
+ }
+ }
+ catch( const css::reflection::InvocationTargetException & e )
+ {
+ raisePyExceptionWithAny( e.TargetException );
+ return 1;
+ }
+ catch( const css::beans::UnknownPropertyException & e )
+ {
+ raisePyExceptionWithAny( makeAny(e) );
+ return 1;
+ }
+ catch( const css::script::CannotConvertException &e )
+ {
+ raisePyExceptionWithAny( makeAny(e) );
+ return 1;
+ }
+ catch( const RuntimeException & e )
+ {
+ raisePyExceptionWithAny( makeAny( e ) );
+ return 1;
+ }
+ PyErr_SetString (PyExc_AttributeError, name);
+ return 1; //as above.
+}
+
+
+static PyObject* PyUNOStruct_cmp( PyObject *self, PyObject *that, int op )
+{
+ PyObject *result;
+
+ if(op != Py_EQ && op != Py_NE)
+ {
+ PyErr_SetString( PyExc_TypeError, "only '==' and '!=' comparisons are defined" );
+ return nullptr;
+ }
+ if( self == that )
+ {
+ result = (op == Py_EQ ? Py_True : Py_False);
+ Py_INCREF( result );
+ return result;
+ }
+ try
+ {
+ Runtime runtime;
+ if( PyObject_IsInstance( that, getPyUnoStructClass().get() ) )
+ {
+
+ PyUNO *me = reinterpret_cast< PyUNO * > ( self );
+ PyUNO *other = reinterpret_cast< PyUNO * > ( that );
+ css::uno::TypeClass tcMe = me->members->wrappedObject.getValueTypeClass();
+ css::uno::TypeClass tcOther = other->members->wrappedObject.getValueTypeClass();
+
+ if( tcMe == tcOther )
+ {
+ if( tcMe == css::uno::TypeClass_STRUCT ||
+ tcMe == css::uno::TypeClass_EXCEPTION )
+ {
+ Reference< XMaterialHolder > xMe( me->members->xInvocation,UNO_QUERY );
+ Reference< XMaterialHolder > xOther( other->members->xInvocation,UNO_QUERY );
+ if( xMe->getMaterial() == xOther->getMaterial() )
+ {
+ result = (op == Py_EQ ? Py_True : Py_False);
+ Py_INCREF( result );
+ return result;
+ }
+ }
+ }
+ }
+ }
+ catch( const css::uno::RuntimeException & e)
+ {
+ raisePyExceptionWithAny( makeAny( e ) );
+ }
+
+ result = (op == Py_EQ ? Py_False : Py_True);
+ Py_INCREF(result);
+ return result;
+}
+
+static PyMethodDef PyUNOStructMethods[] =
+{
+ {"__dir__", reinterpret_cast<PyCFunction>(PyUNOStruct_dir), METH_NOARGS, nullptr},
+ {nullptr, nullptr, 0, nullptr}
+};
+
+static PyTypeObject PyUNOStructType =
+{
+ PyVarObject_HEAD_INIT( &PyType_Type, 0 )
+ "pyuno.struct",
+ sizeof (PyUNO),
+ 0,
+ PyUNOStruct_del,
+#if PY_VERSION_HEX >= 0x03080000
+ 0, // Py_ssize_t tp_vectorcall_offset
+#else
+ nullptr, // printfunc tp_print
+#endif
+ PyUNOStruct_getattr,
+ PyUNOStruct_setattr,
+ /* this type does not exist in Python 3: (cmpfunc) */ nullptr,
+ PyUNOStruct_repr,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ PyUNOStruct_str,
+ nullptr,
+ nullptr,
+ nullptr,
+ Py_TPFLAGS_HAVE_RICHCOMPARE,
+ nullptr,
+ nullptr,
+ nullptr,
+ PyUNOStruct_cmp,
+ 0,
+ nullptr,
+ nullptr,
+ PyUNOStructMethods,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ 0,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr
+ , 0
+#if PY_VERSION_HEX >= 0x03040000
+ , nullptr
+#if PY_VERSION_HEX >= 0x03080000
+ , nullptr // vectorcallfunc tp_vectorcall
+#if PY_VERSION_HEX < 0x03090000
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+#endif
+ , nullptr // tp_print
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+#endif
+#endif
+#endif
+};
+
+int PyUNOStruct_initType()
+{
+ return PyType_Ready( &PyUNOStructType );
+}
+
+PyRef getPyUnoStructClass()
+{
+ return PyRef( reinterpret_cast< PyObject * > ( &PyUNOStructType ) );
+}
+
+PyRef PyUNOStruct_new (
+ const Any &targetInterface,
+ const Reference<XSingleServiceFactory> &ssf )
+{
+ Reference<XInvocation2> xInvocation;
+
+ {
+ PyThreadDetach antiguard;
+ xInvocation.set(
+ ssf->createInstanceWithArguments( Sequence<Any>( &targetInterface, 1 ) ), css::uno::UNO_QUERY_THROW );
+ }
+ if( !Py_IsInitialized() )
+ throw RuntimeException();
+
+ PyUNO* self = PyObject_New (PyUNO, &PyUNOStructType);
+ if (self == nullptr)
+ return PyRef(); // == error
+ self->members = new PyUNOInternals;
+ self->members->xInvocation = xInvocation;
+ self->members->wrappedObject = targetInterface;
+ return PyRef( reinterpret_cast<PyObject*>(self), SAL_NO_ACQUIRE );
+
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */