xref: /aoo42x/main/pyuno/source/module/pyuno_impl.hxx (revision fef82340)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 #ifndef _PYUNO_IMPL_
24 #define _PYUNO_IMPL_
25 
26 #include <pyuno/pyuno.hxx>
27 
28 #include <hash_map>
29 #include <hash_set>
30 
31 #include <com/sun/star/beans/XIntrospection.hpp>
32 #include <com/sun/star/script/XTypeConverter.hpp>
33 #include <com/sun/star/script/XInvocation2.hpp>
34 #include <com/sun/star/script/XInvocationAdapterFactory2.hpp>
35 
36 #include <com/sun/star/reflection/XIdlReflection.hpp>
37 
38 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
39 
40 #include <com/sun/star/lang/XUnoTunnel.hpp>
41 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
42 
43 #include <cppuhelper/implbase2.hxx>
44 #include <cppuhelper/weakref.hxx>
45 
46 //
47 // Local workarounds for compatibility issues
48 //
49 #if PY_MAJOR_VERSION >= 3
50     #define PYSTR_FROMSTR               PyUnicode_FromString
51     #define USTR_TO_PYSTR               ustring2PyUnicode
52     #define PYSTR_CHECK                 PyUnicode_Check
53 #else
54     #define PYSTR_FROMSTR               PyBytes_FromString
55     #define USTR_TO_PYSTR               ustring2PyString
56     #define PYSTR_CHECK                 PyBytes_Check
57 #endif
58 
59 namespace pyuno
60 {
61 
62 //--------------------------------------------------
63 // Logging API - implementation can be found in pyuno_util
64 //--------------------------------------------------
65 struct RuntimeCargo;
66 namespace LogLevel
67 {
68 // when you add a loglevel, extend the log function !
69 static const sal_Int32 NONE = 0;
70 static const sal_Int32 CALL = 1;
71 static const sal_Int32 ARGS = 2;
72 }
73 
74 bool isLog( RuntimeCargo *cargo, sal_Int32 loglevel );
75 void log( RuntimeCargo *cargo, sal_Int32 level, const rtl::OUString &logString );
76 void log( RuntimeCargo *cargo, sal_Int32 level, const char *str );
77 void logCall( RuntimeCargo *cargo, const char *intro,
78               void * ptr, const rtl::OUString & aFunctionName,
79               const com::sun::star::uno::Sequence< com::sun::star::uno::Any > & args );
80 void logReply( RuntimeCargo *cargo, const char *intro,
81               void * ptr, const rtl::OUString & aFunctionName,
82               const com::sun::star::uno::Any &returnValue,
83               const com::sun::star::uno::Sequence< com::sun::star::uno::Any > & args );
84 void logException( RuntimeCargo *cargo, const char *intro,
85                    void * ptr, const rtl::OUString &aFunctionName,
86                    const void * data, const com::sun::star::uno::Type & type );
87 static const sal_Int32 VAL2STR_MODE_DEEP = 0;
88 static const sal_Int32 VAL2STR_MODE_SHALLOW = 1;
89 rtl::OUString val2str( const void * pVal, typelib_TypeDescriptionReference * pTypeRef, sal_Int32 mode = VAL2STR_MODE_DEEP ) SAL_THROW( () );
90 //--------------------------------------------------
91 
92 typedef ::std::hash_map
93 <
94     PyRef,
95     com::sun::star::uno::WeakReference< com::sun::star::script::XInvocation >,
96     PyRef::Hash,
97     std::equal_to< PyRef >
98 > PyRef2Adapter;
99 
100 
101 typedef ::std::hash_map
102 <
103 rtl::OUString,
104 PyRef,
105 rtl::OUStringHash,
106 std::equal_to<rtl::OUString>
107 > ExceptionClassMap;
108 
109 typedef ::std::hash_map
110 <
111     rtl::OUString,
112     com::sun::star::uno::Sequence< sal_Int16 >,
113     rtl::OUStringHash,
114     std::equal_to< rtl::OUString >
115 > MethodOutIndexMap;
116 
117 typedef ::std::hash_set< PyRef , PyRef::Hash , std::equal_to<PyRef> > ClassSet;
118 
119 PyObject* PyUNO_new(
120     const com::sun::star::uno::Any & targetInterface,
121     const com::sun::star::uno::Reference<com::sun::star::lang::XSingleServiceFactory> & ssf);
122 
123 PyObject* PyUNO_new_UNCHECKED (
124     const com::sun::star::uno::Any & targetInterface,
125     const com::sun::star::uno::Reference<com::sun::star::lang::XSingleServiceFactory> & ssf);
126 
127 typedef struct
128 {
129     com::sun::star::uno::Reference <com::sun::star::script::XInvocation2> xInvocation;
130     com::sun::star::uno::Any wrappedObject;
131 } PyUNOInternals;
132 
133 typedef struct
134 {
135     PyObject_HEAD
136     PyUNOInternals* members;
137 } PyUNO;
138 
139 PyRef ustring2PyUnicode( const rtl::OUString &source );
140 PyRef ustring2PyString( const ::rtl::OUString & source );
141 rtl::OUString pyString2ustring( PyObject *str );
142 
143 
144 PyRef AnyToPyObject (const com::sun::star::uno::Any & a, const Runtime &r )
145     throw ( com::sun::star::uno::RuntimeException );
146 
147 com::sun::star::uno::Any PyObjectToAny (PyObject* o)
148     throw ( com::sun::star::uno::RuntimeException );
149 
150 void raiseInvocationTargetExceptionWhenNeeded( const Runtime &runtime )
151     throw ( com::sun::star::reflection::InvocationTargetException );
152 
153 // bool CheckPyObjectTypes (PyObject* o, Sequence<Type> types);
154 // bool CheckPyObjectType (PyObject* o, Type type); //Only check 1 object.
155 
156 com::sun::star::uno::TypeClass StringToTypeClass (char* string);
157 
158 PyRef PyUNO_callable_new (
159     const com::sun::star::uno::Reference<com::sun::star::script::XInvocation2> &xInv,
160     const rtl::OUString &methodName,
161     ConversionMode mode = REJECT_UNO_ANY );
162 
163 PyObject* PyUNO_Type_new (const char *typeName , com::sun::star::uno::TypeClass t , const Runtime &r );
164 PyObject* PyUNO_Enum_new( const char *enumBase, const char *enumValue, const Runtime &r );
165 PyObject* PyUNO_char_new (sal_Unicode c , const Runtime &r);
166 PyObject *PyUNO_ByteSequence_new( const com::sun::star::uno::Sequence< sal_Int8 > &, const Runtime &r );
167 
168 PyObject *importToGlobal( PyObject *typeName, PyObject *dict, PyObject *targetName );
169 
170 PyRef getTypeClass( const Runtime &);
171 PyRef getEnumClass( const Runtime &);
172 PyRef getBoolClass( const Runtime &);
173 PyRef getCharClass( const Runtime &);
174 PyRef getByteSequenceClass( const Runtime & );
175 PyRef getPyUnoClass();
176 PyRef getClass( const rtl::OUString & name , const Runtime & runtime );
177 PyRef getAnyClass( const Runtime &);
178 PyObject *PyUNO_invoke( PyObject *object, const char *name , PyObject *args );
179 
180 com::sun::star::uno::Any PyEnum2Enum( PyObject *obj )
181     throw ( com::sun::star::uno::RuntimeException );
182 sal_Bool PyBool2Bool( PyObject *o, const Runtime & r )
183     throw ( com::sun::star::uno::RuntimeException );
184 sal_Unicode PyChar2Unicode( PyObject *o )
185     throw ( com::sun::star::uno::RuntimeException );
186 com::sun::star::uno::Type PyType2Type( PyObject * o )
187     throw( com::sun::star::uno::RuntimeException );
188 
189 void raisePyExceptionWithAny( const com::sun::star::uno::Any &a );
190 const char *typeClassToString( com::sun::star::uno::TypeClass t );
191 
192 PyRef getObjectFromUnoModule( const Runtime &runtime, const char * object )
193     throw ( com::sun::star::uno::RuntimeException );
194 
195 sal_Bool isInterfaceClass( const Runtime &, PyObject *obj );
196 bool isInstanceOfStructOrException( PyObject *obj);
197 com::sun::star::uno::Sequence<com::sun::star::uno::Type> implementsInterfaces(
198     const Runtime & runtime, PyObject *obj );
199 
200 struct RuntimeCargo
201 {
202     com::sun::star::uno::Reference< com::sun::star::lang::XSingleServiceFactory > xInvocation;
203     com::sun::star::uno::Reference< com::sun::star::script::XTypeConverter> xTypeConverter;
204     com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > xContext;
205     com::sun::star::uno::Reference< com::sun::star::reflection::XIdlReflection > xCoreReflection;
206     com::sun::star::uno::Reference< com::sun::star::container::XHierarchicalNameAccess > xTdMgr;
207     com::sun::star::uno::Reference< com::sun::star::script::XInvocationAdapterFactory2 > xAdapterFactory;
208     com::sun::star::uno::Reference< com::sun::star::beans::XIntrospection > xIntrospection;
209     PyRef dictUnoModule;
210     bool valid;
211     ExceptionClassMap exceptionMap;
212     ClassSet interfaceSet;
213     PyRef2Adapter mappedObjects;
214     FILE *logFile;
215     sal_Int32 logLevel;
216 
217     PyRef getUnoModule();
218 };
219 
220 struct stRuntimeImpl
221 {
222     PyObject_HEAD
223     struct RuntimeCargo *cargo;
224 public:
225     static void del( PyObject *self );
226 
227     static PyRef create(
228         const com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > & xContext )
229         throw ( com::sun::star::uno::RuntimeException );
230 };
231 
232 
233 class Adapter : public cppu::WeakImplHelper2<
234     com::sun::star::script::XInvocation, com::sun::star::lang::XUnoTunnel >
235 {
236     PyRef mWrappedObject;
237     PyInterpreterState *mInterpreter;  // interpreters don't seem to be refcounted !
238     com::sun::star::uno::Sequence< com::sun::star::uno::Type > mTypes;
239     MethodOutIndexMap m_methodOutIndexMap;
240 
241 private:
242     com::sun::star::uno::Sequence< sal_Int16 > getOutIndexes( const rtl::OUString & functionName );
243 
244 public:
245 public:
246     Adapter( const PyRef &obj,
247              const com::sun::star::uno::Sequence< com::sun::star::uno::Type > & types );
248 
249     static com::sun::star::uno::Sequence< sal_Int8 > getUnoTunnelImplementationId();
250     PyRef getWrappedObject() { return mWrappedObject; }
251     com::sun::star::uno::Sequence< com::sun::star::uno::Type > getWrappedTypes() { return mTypes; }
252     virtual ~Adapter();
253 
254     // XInvocation
255     virtual com::sun::star::uno::Reference< ::com::sun::star::beans::XIntrospectionAccess >
256            SAL_CALL getIntrospection(  ) throw (::com::sun::star::uno::RuntimeException);
257     virtual ::com::sun::star::uno::Any SAL_CALL invoke(
258         const ::rtl::OUString& aFunctionName,
259         const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aParams,
260         ::com::sun::star::uno::Sequence< sal_Int16 >& aOutParamIndex,
261         ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aOutParam )
262         throw (::com::sun::star::lang::IllegalArgumentException,
263                ::com::sun::star::script::CannotConvertException,
264                ::com::sun::star::reflection::InvocationTargetException,
265                ::com::sun::star::uno::RuntimeException);
266 
267     virtual void SAL_CALL setValue(
268         const ::rtl::OUString& aPropertyName,
269         const ::com::sun::star::uno::Any& aValue )
270         throw (::com::sun::star::beans::UnknownPropertyException,
271                ::com::sun::star::script::CannotConvertException,
272                ::com::sun::star::reflection::InvocationTargetException,
273                ::com::sun::star::uno::RuntimeException);
274 
275     virtual ::com::sun::star::uno::Any SAL_CALL getValue( const ::rtl::OUString& aPropertyName )
276         throw (::com::sun::star::beans::UnknownPropertyException,
277                ::com::sun::star::uno::RuntimeException);
278     virtual sal_Bool SAL_CALL hasMethod( const ::rtl::OUString& aName )
279         throw (::com::sun::star::uno::RuntimeException);
280     virtual sal_Bool SAL_CALL hasProperty( const ::rtl::OUString& aName )
281         throw (::com::sun::star::uno::RuntimeException);
282 
283     // XUnoTunnel
284     virtual sal_Int64 SAL_CALL getSomething(
285         const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier )
286         throw (::com::sun::star::uno::RuntimeException);
287 };
288 
289 
290 /** releases a refcount on the interpreter object and on another given python object.
291 
292    The function can be called from any thread regardless of whether the global
293    interpreter lock is held.
294 
295  */
296 void decreaseRefCount( PyInterpreterState *interpreter, PyObject *object );
297 
298 }
299 
300 #endif
301