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 #include <rtl/string.hxx>
PyErr_SetString(PyObject * pyObj,const rtl::OString & rName)60 inline void PyErr_SetString( PyObject* pyObj, const rtl::OString& rName) { PyErr_SetString( pyObj, rName.getStr());}
61 
62 namespace pyuno
63 {
64 
65 //--------------------------------------------------
66 // Logging API - implementation can be found in pyuno_util
67 //--------------------------------------------------
68 struct RuntimeCargo;
69 namespace LogLevel
70 {
71 // when you add a loglevel, extend the log function !
72 static const sal_Int32 NONE = 0;
73 static const sal_Int32 CALL = 1;
74 static const sal_Int32 ARGS = 2;
75 }
76 
77 bool isLog( RuntimeCargo *cargo, sal_Int32 loglevel );
78 void log( RuntimeCargo *cargo, sal_Int32 level, const rtl::OUString &logString );
79 void log( RuntimeCargo *cargo, sal_Int32 level, const char *str );
80 void logCall( RuntimeCargo *cargo, const char *intro,
81               void * ptr, const rtl::OUString & aFunctionName,
82               const com::sun::star::uno::Sequence< com::sun::star::uno::Any > & args );
83 void logReply( RuntimeCargo *cargo, const char *intro,
84               void * ptr, const rtl::OUString & aFunctionName,
85               const com::sun::star::uno::Any &returnValue,
86               const com::sun::star::uno::Sequence< com::sun::star::uno::Any > & args );
87 void logException( RuntimeCargo *cargo, const char *intro,
88                    void * ptr, const rtl::OUString &aFunctionName,
89                    const void * data, const com::sun::star::uno::Type & type );
90 static const sal_Int32 VAL2STR_MODE_DEEP = 0;
91 static const sal_Int32 VAL2STR_MODE_SHALLOW = 1;
92 rtl::OUString val2str( const void * pVal, typelib_TypeDescriptionReference * pTypeRef, sal_Int32 mode = VAL2STR_MODE_DEEP ) SAL_THROW( () );
93 //--------------------------------------------------
94 
95 typedef ::std::hash_map
96 <
97     PyRef,
98     com::sun::star::uno::WeakReference< com::sun::star::script::XInvocation >,
99     PyRef::Hash,
100     std::equal_to< PyRef >
101 > PyRef2Adapter;
102 
103 
104 typedef ::std::hash_map
105 <
106 rtl::OUString,
107 PyRef,
108 rtl::OUStringHash,
109 std::equal_to<rtl::OUString>
110 > ExceptionClassMap;
111 
112 typedef ::std::hash_map
113 <
114     rtl::OUString,
115     com::sun::star::uno::Sequence< sal_Int16 >,
116     rtl::OUStringHash,
117     std::equal_to< rtl::OUString >
118 > MethodOutIndexMap;
119 
120 typedef ::std::hash_set< PyRef , PyRef::Hash , std::equal_to<PyRef> > ClassSet;
121 
122 PyObject* PyUNO_new(
123     const com::sun::star::uno::Any & targetInterface,
124     const com::sun::star::uno::Reference<com::sun::star::lang::XSingleServiceFactory> & ssf);
125 
126 PyObject* PyUNO_new_UNCHECKED (
127     const com::sun::star::uno::Any & targetInterface,
128     const com::sun::star::uno::Reference<com::sun::star::lang::XSingleServiceFactory> & ssf);
129 
130 typedef struct
131 {
132     com::sun::star::uno::Reference <com::sun::star::script::XInvocation2> xInvocation;
133     com::sun::star::uno::Any wrappedObject;
134 } PyUNOInternals;
135 
136 typedef struct
137 {
138     PyObject_HEAD
139     PyUNOInternals* members;
140 } PyUNO;
141 
142 PyRef ustring2PyUnicode( const rtl::OUString &source );
143 PyRef ustring2PyString( const ::rtl::OUString & source );
144 rtl::OUString pyString2ustring( PyObject *str );
145 
146 
147 PyRef AnyToPyObject (const com::sun::star::uno::Any & a, const Runtime &r )
148     throw ( com::sun::star::uno::RuntimeException );
149 
150 com::sun::star::uno::Any PyObjectToAny (PyObject* o)
151     throw ( com::sun::star::uno::RuntimeException );
152 
153 void raiseInvocationTargetExceptionWhenNeeded( const Runtime &runtime )
154     throw ( com::sun::star::reflection::InvocationTargetException );
155 
156 // bool CheckPyObjectTypes (PyObject* o, Sequence<Type> types);
157 // bool CheckPyObjectType (PyObject* o, Type type); //Only check 1 object.
158 
159 com::sun::star::uno::TypeClass StringToTypeClass (char* string);
160 
161 PyRef PyUNO_callable_new (
162     const com::sun::star::uno::Reference<com::sun::star::script::XInvocation2> &xInv,
163     const rtl::OUString &methodName,
164     ConversionMode mode = REJECT_UNO_ANY );
165 
166 PyObject* PyUNO_Type_new (const char *typeName , com::sun::star::uno::TypeClass t , const Runtime &r );
167 PyObject* PyUNO_Enum_new( const char *enumBase, const char *enumValue, const Runtime &r );
168 PyObject* PyUNO_char_new (sal_Unicode c , const Runtime &r);
169 PyObject *PyUNO_ByteSequence_new( const com::sun::star::uno::Sequence< sal_Int8 > &, const Runtime &r );
170 
171 PyObject *importToGlobal( PyObject *typeName, PyObject *dict, PyObject *targetName );
172 
173 PyRef getTypeClass( const Runtime &);
174 PyRef getEnumClass( const Runtime &);
175 PyRef getBoolClass( const Runtime &);
176 PyRef getCharClass( const Runtime &);
177 PyRef getByteSequenceClass( const Runtime & );
178 PyRef getPyUnoClass();
179 PyRef getClass( const rtl::OUString & name , const Runtime & runtime );
180 PyRef getAnyClass( const Runtime &);
181 PyObject *PyUNO_invoke( PyObject *object, const char *name , PyObject *args );
182 
183 com::sun::star::uno::Any PyEnum2Enum( PyObject *obj )
184     throw ( com::sun::star::uno::RuntimeException );
185 sal_Bool PyBool2Bool( PyObject *o, const Runtime & r )
186     throw ( com::sun::star::uno::RuntimeException );
187 sal_Unicode PyChar2Unicode( PyObject *o )
188     throw ( com::sun::star::uno::RuntimeException );
189 com::sun::star::uno::Type PyType2Type( PyObject * o )
190     throw( com::sun::star::uno::RuntimeException );
191 
192 void raisePyExceptionWithAny( const com::sun::star::uno::Any &a );
193 const char *typeClassToString( com::sun::star::uno::TypeClass t );
194 
195 PyRef getObjectFromUnoModule( const Runtime &runtime, const char * object )
196     throw ( com::sun::star::uno::RuntimeException );
197 
198 sal_Bool isInterfaceClass( const Runtime &, PyObject *obj );
199 bool isInstanceOfStructOrException( PyObject *obj);
200 com::sun::star::uno::Sequence<com::sun::star::uno::Type> implementsInterfaces(
201     const Runtime & runtime, PyObject *obj );
202 
203 struct RuntimeCargo
204 {
205     com::sun::star::uno::Reference< com::sun::star::lang::XSingleServiceFactory > xInvocation;
206     com::sun::star::uno::Reference< com::sun::star::script::XTypeConverter> xTypeConverter;
207     com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > xContext;
208     com::sun::star::uno::Reference< com::sun::star::reflection::XIdlReflection > xCoreReflection;
209     com::sun::star::uno::Reference< com::sun::star::container::XHierarchicalNameAccess > xTdMgr;
210     com::sun::star::uno::Reference< com::sun::star::script::XInvocationAdapterFactory2 > xAdapterFactory;
211     com::sun::star::uno::Reference< com::sun::star::beans::XIntrospection > xIntrospection;
212     PyRef dictUnoModule;
213     bool valid;
214     ExceptionClassMap exceptionMap;
215     ClassSet interfaceSet;
216     PyRef2Adapter mappedObjects;
217     FILE *logFile;
218     sal_Int32 logLevel;
219 
220     PyRef getUnoModule();
221 };
222 
223 struct stRuntimeImpl
224 {
225     PyObject_HEAD
226     struct RuntimeCargo *cargo;
227 public:
228     static void del( PyObject *self );
229 
230     static PyRef create(
231         const com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > & xContext )
232         throw ( com::sun::star::uno::RuntimeException );
233 };
234 
235 
236 class Adapter : public cppu::WeakImplHelper2<
237     com::sun::star::script::XInvocation, com::sun::star::lang::XUnoTunnel >
238 {
239     PyRef mWrappedObject;
240     PyInterpreterState *mInterpreter;  // interpreters don't seem to be refcounted !
241     com::sun::star::uno::Sequence< com::sun::star::uno::Type > mTypes;
242     MethodOutIndexMap m_methodOutIndexMap;
243 
244 private:
245     com::sun::star::uno::Sequence< sal_Int16 > getOutIndexes( const rtl::OUString & functionName );
246 
247 public:
248 public:
249     Adapter( const PyRef &obj,
250              const com::sun::star::uno::Sequence< com::sun::star::uno::Type > & types );
251 
252     static com::sun::star::uno::Sequence< sal_Int8 > getUnoTunnelImplementationId();
getWrappedObject()253     PyRef getWrappedObject() { return mWrappedObject; }
getWrappedTypes()254     com::sun::star::uno::Sequence< com::sun::star::uno::Type > getWrappedTypes() { return mTypes; }
255     virtual ~Adapter();
256 
257     // XInvocation
258     virtual com::sun::star::uno::Reference< ::com::sun::star::beans::XIntrospectionAccess >
259            SAL_CALL getIntrospection(  ) throw (::com::sun::star::uno::RuntimeException);
260     virtual ::com::sun::star::uno::Any SAL_CALL invoke(
261         const ::rtl::OUString& aFunctionName,
262         const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aParams,
263         ::com::sun::star::uno::Sequence< sal_Int16 >& aOutParamIndex,
264         ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aOutParam )
265         throw (::com::sun::star::lang::IllegalArgumentException,
266                ::com::sun::star::script::CannotConvertException,
267                ::com::sun::star::reflection::InvocationTargetException,
268                ::com::sun::star::uno::RuntimeException);
269 
270     virtual void SAL_CALL setValue(
271         const ::rtl::OUString& aPropertyName,
272         const ::com::sun::star::uno::Any& aValue )
273         throw (::com::sun::star::beans::UnknownPropertyException,
274                ::com::sun::star::script::CannotConvertException,
275                ::com::sun::star::reflection::InvocationTargetException,
276                ::com::sun::star::uno::RuntimeException);
277 
278     virtual ::com::sun::star::uno::Any SAL_CALL getValue( const ::rtl::OUString& aPropertyName )
279         throw (::com::sun::star::beans::UnknownPropertyException,
280                ::com::sun::star::uno::RuntimeException);
281     virtual sal_Bool SAL_CALL hasMethod( const ::rtl::OUString& aName )
282         throw (::com::sun::star::uno::RuntimeException);
283     virtual sal_Bool SAL_CALL hasProperty( const ::rtl::OUString& aName )
284         throw (::com::sun::star::uno::RuntimeException);
285 
286     // XUnoTunnel
287     virtual sal_Int64 SAL_CALL getSomething(
288         const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier )
289         throw (::com::sun::star::uno::RuntimeException);
290 };
291 
292 
293 /** releases a refcount on the interpreter object and on another given python object.
294 
295    The function can be called from any thread regardless of whether the global
296    interpreter lock is held.
297 
298  */
299 void decreaseRefCount( PyInterpreterState *interpreter, PyObject *object );
300 
301 }
302 
303 #endif
304