xref: /trunk/main/pyuno/source/module/pyuno_impl.hxx (revision 77dc4149)
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     const com::sun::star::uno::Reference<com::sun::star::lang::XSingleServiceFactory> &ssf,
162     const com::sun::star::uno::Reference<com::sun::star::script::XTypeConverter> &tc,
163     ConversionMode mode = REJECT_UNO_ANY );
164 
165 PyObject* PyUNO_Type_new (const char *typeName , com::sun::star::uno::TypeClass t , const Runtime &r );
166 PyObject* PyUNO_Enum_new( const char *enumBase, const char *enumValue, const Runtime &r );
167 PyObject* PyUNO_char_new (sal_Unicode c , const Runtime &r);
168 PyObject *PyUNO_ByteSequence_new( const com::sun::star::uno::Sequence< sal_Int8 > &, const Runtime &r );
169 
170 PyObject *importToGlobal( PyObject *typeName, PyObject *dict, PyObject *targetName );
171 
172 PyRef getTypeClass( const Runtime &);
173 PyRef getEnumClass( const Runtime &);
174 PyRef getBoolClass( const Runtime &);
175 PyRef getCharClass( const Runtime &);
176 PyRef getByteSequenceClass( const Runtime & );
177 PyRef getPyUnoClass();
178 PyRef getClass( const rtl::OUString & name , const Runtime & runtime );
179 PyRef getAnyClass( const Runtime &);
180 PyObject *PyUNO_invoke( PyObject *object, const char *name , PyObject *args );
181 
182 com::sun::star::uno::Any PyEnum2Enum( PyObject *obj )
183     throw ( com::sun::star::uno::RuntimeException );
184 sal_Bool PyBool2Bool( PyObject *o, const Runtime & r )
185     throw ( com::sun::star::uno::RuntimeException );
186 sal_Unicode PyChar2Unicode( PyObject *o )
187     throw ( com::sun::star::uno::RuntimeException );
188 com::sun::star::uno::Type PyType2Type( PyObject * o )
189     throw( com::sun::star::uno::RuntimeException );
190 
191 void raisePyExceptionWithAny( const com::sun::star::uno::Any &a );
192 const char *typeClassToString( com::sun::star::uno::TypeClass t );
193 
194 PyRef getObjectFromUnoModule( const Runtime &runtime, const char * object )
195     throw ( com::sun::star::uno::RuntimeException );
196 
197 sal_Bool isInterfaceClass( const Runtime &, PyObject *obj );
198 bool isInstanceOfStructOrException( PyObject *obj);
199 com::sun::star::uno::Sequence<com::sun::star::uno::Type> implementsInterfaces(
200     const Runtime & runtime, PyObject *obj );
201 
202 struct RuntimeCargo
203 {
204     com::sun::star::uno::Reference< com::sun::star::lang::XSingleServiceFactory > xInvocation;
205     com::sun::star::uno::Reference< com::sun::star::script::XTypeConverter> xTypeConverter;
206     com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > xContext;
207     com::sun::star::uno::Reference< com::sun::star::reflection::XIdlReflection > xCoreReflection;
208     com::sun::star::uno::Reference< com::sun::star::container::XHierarchicalNameAccess > xTdMgr;
209     com::sun::star::uno::Reference< com::sun::star::script::XInvocationAdapterFactory2 > xAdapterFactory;
210     com::sun::star::uno::Reference< com::sun::star::beans::XIntrospection > xIntrospection;
211     PyRef dictUnoModule;
212     bool valid;
213     ExceptionClassMap exceptionMap;
214     ClassSet interfaceSet;
215     PyRef2Adapter mappedObjects;
216     FILE *logFile;
217     sal_Int32 logLevel;
218 
219     PyRef getUnoModule();
220 };
221 
222 struct stRuntimeImpl
223 {
224     PyObject_HEAD
225     struct RuntimeCargo *cargo;
226 public:
227     static void del( PyObject *self );
228 
229     static PyRef create(
230         const com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > & xContext )
231         throw ( com::sun::star::uno::RuntimeException );
232 };
233 
234 
235 class Adapter : public cppu::WeakImplHelper2<
236     com::sun::star::script::XInvocation, com::sun::star::lang::XUnoTunnel >
237 {
238     PyRef mWrappedObject;
239     PyInterpreterState *mInterpreter;  // interpreters don't seem to be refcounted !
240     com::sun::star::uno::Sequence< com::sun::star::uno::Type > mTypes;
241     MethodOutIndexMap m_methodOutIndexMap;
242 
243 private:
244     com::sun::star::uno::Sequence< sal_Int16 > getOutIndexes( const rtl::OUString & functionName );
245 
246 public:
247 public:
248     Adapter( const PyRef &obj,
249              const com::sun::star::uno::Sequence< com::sun::star::uno::Type > & types );
250 
251     static com::sun::star::uno::Sequence< sal_Int8 > getUnoTunnelImplementationId();
252     PyRef getWrappedObject() { return mWrappedObject; }
253     com::sun::star::uno::Sequence< com::sun::star::uno::Type > getWrappedTypes() { return mTypes; }
254     virtual ~Adapter();
255 
256     // XInvocation
257     virtual com::sun::star::uno::Reference< ::com::sun::star::beans::XIntrospectionAccess >
258            SAL_CALL getIntrospection(  ) throw (::com::sun::star::uno::RuntimeException);
259     virtual ::com::sun::star::uno::Any SAL_CALL invoke(
260         const ::rtl::OUString& aFunctionName,
261         const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aParams,
262         ::com::sun::star::uno::Sequence< sal_Int16 >& aOutParamIndex,
263         ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aOutParam )
264         throw (::com::sun::star::lang::IllegalArgumentException,
265                ::com::sun::star::script::CannotConvertException,
266                ::com::sun::star::reflection::InvocationTargetException,
267                ::com::sun::star::uno::RuntimeException);
268 
269     virtual void SAL_CALL setValue(
270         const ::rtl::OUString& aPropertyName,
271         const ::com::sun::star::uno::Any& aValue )
272         throw (::com::sun::star::beans::UnknownPropertyException,
273                ::com::sun::star::script::CannotConvertException,
274                ::com::sun::star::reflection::InvocationTargetException,
275                ::com::sun::star::uno::RuntimeException);
276 
277     virtual ::com::sun::star::uno::Any SAL_CALL getValue( const ::rtl::OUString& aPropertyName )
278         throw (::com::sun::star::beans::UnknownPropertyException,
279                ::com::sun::star::uno::RuntimeException);
280     virtual sal_Bool SAL_CALL hasMethod( const ::rtl::OUString& aName )
281         throw (::com::sun::star::uno::RuntimeException);
282     virtual sal_Bool SAL_CALL hasProperty( const ::rtl::OUString& aName )
283         throw (::com::sun::star::uno::RuntimeException);
284 
285     // XUnoTunnel
286     virtual sal_Int64 SAL_CALL getSomething(
287         const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier )
288         throw (::com::sun::star::uno::RuntimeException);
289 };
290 
291 
292 /** releases a refcount on the interpreter object and on another given python object.
293 
294    The function can be called from any thread regardless of whether the global
295    interpreter lock is held.
296 
297  */
298 void decreaseRefCount( PyInterpreterState *interpreter, PyObject *object );
299 
300 }
301 
302 #endif
303