Update ooo320-m1
[ooovba.git] / pyuno / source / module / pyuno_type.cxx
blobc708d036296b2806b85be57b2c38bfde2ce9e145
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: pyuno_type.cxx,v $
10 * $Revision: 1.7 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
30 #include "pyuno_impl.hxx"
32 #include <rtl/ustrbuf.hxx>
33 #include <rtl/strbuf.hxx>
35 #include <typelib/typedescription.hxx>
37 using rtl::OString;
38 using rtl::OUString;
39 using rtl::OUStringBuffer;
40 using rtl::OUStringToOString;
41 using rtl::OStringBuffer;
43 using com::sun::star::uno::TypeClass;
44 using com::sun::star::uno::Type;
45 using com::sun::star::uno::RuntimeException;
46 using com::sun::star::uno::Any;
47 using com::sun::star::uno::XInterface;
48 using com::sun::star::uno::Reference;
49 using com::sun::star::uno::TypeDescription;
51 #define USTR_ASCII(x) rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( x ) )
52 namespace pyuno
54 const char *typeClassToString( TypeClass t )
56 const char * ret = 0;
57 switch (t)
59 case com::sun::star::uno::TypeClass_VOID:
60 ret = "VOID"; break;
61 case com::sun::star::uno::TypeClass_CHAR:
62 ret = "CHAR"; break;
63 case com::sun::star::uno::TypeClass_BOOLEAN:
64 ret = "BOOLEAN"; break;
65 case com::sun::star::uno::TypeClass_BYTE:
66 ret = "BYTE"; break;
67 case com::sun::star::uno::TypeClass_SHORT:
68 ret = "SHORT"; break;
69 case com::sun::star::uno::TypeClass_UNSIGNED_SHORT:
70 ret = "UNSIGNED_SHORT"; break;
71 case com::sun::star::uno::TypeClass_LONG:
72 ret = "LONG"; break;
73 case com::sun::star::uno::TypeClass_UNSIGNED_LONG:
74 ret = "UNSIGNED_LONG"; break;
75 case com::sun::star::uno::TypeClass_HYPER:
76 ret = "HYPER"; break;
77 case com::sun::star::uno::TypeClass_UNSIGNED_HYPER:
78 ret = "UNSIGNED_HYPER"; break;
79 case com::sun::star::uno::TypeClass_FLOAT:
80 ret = "FLOAT"; break;
81 case com::sun::star::uno::TypeClass_DOUBLE:
82 ret = "DOUBLE"; break;
83 case com::sun::star::uno::TypeClass_STRING:
84 ret = "STRING"; break;
85 case com::sun::star::uno::TypeClass_TYPE:
86 ret = "TYPE"; break;
87 case com::sun::star::uno::TypeClass_ANY:
88 ret = "ANY";break;
89 case com::sun::star::uno::TypeClass_ENUM:
90 ret = "ENUM";break;
91 case com::sun::star::uno::TypeClass_STRUCT:
92 ret = "STRUCT"; break;
93 case com::sun::star::uno::TypeClass_EXCEPTION:
94 ret = "EXCEPTION"; break;
95 case com::sun::star::uno::TypeClass_SEQUENCE:
96 ret = "SEQUENCE"; break;
97 case com::sun::star::uno::TypeClass_INTERFACE:
98 ret = "INTERFACE"; break;
99 case com::sun::star::uno::TypeClass_TYPEDEF:
100 ret = "TYPEDEF"; break;
101 case com::sun::star::uno::TypeClass_UNION:
102 ret = "UNION"; break;
103 case com::sun::star::uno::TypeClass_ARRAY:
104 ret = "ARRAY"; break;
105 case com::sun::star::uno::TypeClass_SERVICE:
106 ret = "SERVICE"; break;
107 case com::sun::star::uno::TypeClass_MODULE:
108 ret = "MODULE"; break;
109 case com::sun::star::uno::TypeClass_INTERFACE_METHOD:
110 ret = "INTERFACE_METHOD"; break;
111 case com::sun::star::uno::TypeClass_INTERFACE_ATTRIBUTE:
112 ret = "INTERFACE_ATTRIBUTE"; break;
113 default:
114 ret = "UNKNOWN"; break;
116 return ret;
119 static PyRef getClass( const Runtime & r , const char * name)
121 return PyRef( PyDict_GetItemString( r.getImpl()->cargo->getUnoModule().get(), (char*) name ) );
124 PyRef getTypeClass( const Runtime & r )
126 return getClass( r , "Type" );
129 PyRef getEnumClass( const Runtime & r )
131 return getClass( r , "Enum" );
134 PyRef getCharClass( const Runtime & r )
136 return getClass( r , "Char" );
139 PyRef getByteSequenceClass( const Runtime & r )
141 return getClass( r , "ByteSequence" );
144 PyRef getAnyClass( const Runtime & r )
146 return getClass( r , "Any" );
150 sal_Unicode PyChar2Unicode( PyObject *obj ) throw ( RuntimeException )
152 PyRef value( PyObject_GetAttrString( obj, const_cast< char * >("value") ), SAL_NO_ACQUIRE );
153 if( ! PyUnicode_Check( value.get() ) )
155 throw RuntimeException(
156 USTR_ASCII( "attribute value of uno.Char is not a unicode string" ),
157 Reference< XInterface > () );
160 if( PyUnicode_GetSize( value.get() ) < 1 )
162 throw RuntimeException(
163 USTR_ASCII( "uno.Char contains an empty unicode string" ),
164 Reference< XInterface > () );
167 sal_Unicode c = (sal_Unicode)PyUnicode_AsUnicode( value.get() )[0];
168 return c;
171 Any PyEnum2Enum( PyObject *obj ) throw ( RuntimeException )
173 Any ret;
174 PyRef typeName( PyObject_GetAttrString( obj,const_cast< char * >("typeName") ), SAL_NO_ACQUIRE);
175 PyRef value( PyObject_GetAttrString( obj, const_cast< char * >("value") ), SAL_NO_ACQUIRE);
176 if( !PyString_Check( typeName.get() ) || ! PyString_Check( value.get() ) )
178 throw RuntimeException(
179 USTR_ASCII( "attributes typeName and/or value of uno.Enum are not strings" ),
180 Reference< XInterface > () );
183 OUString strTypeName( OUString::createFromAscii( PyString_AsString( typeName.get() ) ) );
184 char *stringValue = PyString_AsString( value.get() );
186 TypeDescription desc( strTypeName );
187 if( desc.is() )
189 if(desc.get()->eTypeClass != typelib_TypeClass_ENUM )
191 OUStringBuffer buf;
192 buf.appendAscii( "pyuno.checkEnum: " ).append(strTypeName).appendAscii( "is a " );
193 buf.appendAscii(
194 typeClassToString( (com::sun::star::uno::TypeClass) desc.get()->eTypeClass));
195 buf.appendAscii( ", expected ENUM" );
196 throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface> () );
199 desc.makeComplete();
201 typelib_EnumTypeDescription *pEnumDesc = (typelib_EnumTypeDescription*) desc.get();
202 int i = 0;
203 for( i = 0; i < pEnumDesc->nEnumValues ; i ++ )
205 if( (*((OUString *)&pEnumDesc->ppEnumNames[i])).compareToAscii( stringValue ) == 0 )
207 break;
210 if( i == pEnumDesc->nEnumValues )
212 OUStringBuffer buf;
213 buf.appendAscii( "value " ).appendAscii( stringValue ).appendAscii( "is unknown in enum " );
214 buf.appendAscii( PyString_AsString( typeName.get() ) );
215 throw RuntimeException( buf.makeStringAndClear(), Reference<XInterface> () );
217 ret = Any( &pEnumDesc->pEnumValues[i], desc.get()->pWeakRef );
219 else
221 OUStringBuffer buf;
222 buf.appendAscii( "enum " ).appendAscii( PyString_AsString(typeName.get()) ).appendAscii( " is unknown" );
223 throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface> () );
225 return ret;
229 Type PyType2Type( PyObject * o ) throw(RuntimeException )
231 PyRef pyName( PyObject_GetAttrString( o, const_cast< char * >("typeName") ), SAL_NO_ACQUIRE);
232 if( !PyString_Check( pyName.get() ) )
234 throw RuntimeException(
235 USTR_ASCII( "type object does not have typeName property" ),
236 Reference< XInterface > () );
239 PyRef pyTC( PyObject_GetAttrString( o, const_cast< char * >("typeClass") ), SAL_NO_ACQUIRE );
240 Any enumValue = PyEnum2Enum( pyTC.get() );
242 OUString name( OUString::createFromAscii( PyString_AsString( pyName.get() ) ) );
243 TypeDescription desc( name );
244 if( ! desc.is() )
246 OUStringBuffer buf;
247 buf.appendAscii( "type " ).append(name).appendAscii( " is unknown" );
248 throw RuntimeException(
249 buf.makeStringAndClear(), Reference< XInterface > () );
251 if( desc.get()->eTypeClass != (typelib_TypeClass) *(sal_Int32*)enumValue.getValue() )
253 OUStringBuffer buf;
254 buf.appendAscii( "pyuno.checkType: " ).append(name).appendAscii( " is a " );
255 buf.appendAscii( typeClassToString( (TypeClass) desc.get()->eTypeClass) );
256 buf.appendAscii( ", but type got construct with typeclass " );
257 buf.appendAscii( typeClassToString( (TypeClass) *(sal_Int32*)enumValue.getValue() ) );
258 throw RuntimeException(
259 buf.makeStringAndClear(), Reference< XInterface > () );
261 return desc.get()->pWeakRef;
264 PyObject *importToGlobal(PyObject *str, PyObject *dict, PyObject *target)
266 // maybe a constant ?
267 PyObject *ret = 0;
268 OUString name = pyString2ustring(str);
271 Runtime runtime;
272 TypeDescription desc(name );
273 desc.makeComplete();
274 if( desc.is() )
276 com::sun::star::uno::TypeClass tc =
277 (com::sun::star::uno::TypeClass)desc.get()->eTypeClass;
279 PyRef typesModule( PyDict_GetItemString( dict, "unotypes" ) );
280 if( ! typesModule.is() || ! PyModule_Check( typesModule.get() ))
282 typesModule = PyRef( PyModule_New( const_cast< char * >("unotypes") ), SAL_NO_ACQUIRE );
283 Py_INCREF( typesModule.get() );
284 PyDict_SetItemString( dict, "unotypes" , typesModule.get() );
286 PyModule_AddObject(
287 typesModule.get(),
288 PyString_AsString( target ),
289 PyUNO_Type_new( PyString_AsString(str),tc,runtime ) );
291 if( com::sun::star::uno::TypeClass_EXCEPTION == tc ||
292 com::sun::star::uno::TypeClass_STRUCT == tc )
294 PyRef exc = getClass( name, runtime );
295 PyDict_SetItem( dict, target, exc.getAcquired() );
297 else if( com::sun::star::uno::TypeClass_ENUM == tc )
299 // introduce all enums into the dictionary !
300 typelib_EnumTypeDescription *pDesc =
301 (typelib_EnumTypeDescription *) desc.get();
302 for( int i = 0 ; i < pDesc->nEnumValues; i ++ )
304 OString enumElementName(
305 OUStringToOString( pDesc->ppEnumNames[i], RTL_TEXTENCODING_ASCII_US) );
306 PyDict_SetItemString(
307 dict, (char*)enumElementName.getStr(),
308 PyUNO_Enum_new(PyString_AsString(str) , enumElementName.getStr(), runtime ) );
311 Py_INCREF( Py_None );
312 ret = Py_None;
314 else
316 Any a = runtime.getImpl()->cargo->xTdMgr->getByHierarchicalName(name);
317 if(a.hasValue())
319 PyRef constant = runtime.any2PyObject( a );
320 if( constant.is() )
322 Py_INCREF( constant.get() );
323 PyDict_SetItem( dict, target , constant.get());
324 ret = constant.get();
326 else
328 OStringBuffer buf;
329 buf.append( "constant " ).append(PyString_AsString(str)).append( " unknown" );
330 PyErr_SetString( PyExc_RuntimeError, buf.getStr() );
333 else
335 OUStringBuffer buf;
336 buf.appendAscii( "pyuno.imp unknown type " );
337 buf.append( name );
338 PyErr_SetString(
339 PyExc_RuntimeError,
340 OUStringToOString( buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US).getStr() );
344 catch( com::sun::star::container::NoSuchElementException & )
346 OUStringBuffer buf;
347 buf.appendAscii( "pyuno.imp unknown type " );
348 buf.append( name );
349 PyErr_SetString(
350 PyExc_RuntimeError,
351 OUStringToOString( buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US).getStr() );
353 catch( com::sun::star::script::CannotConvertException & e )
355 raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) );
357 catch( com::sun::star::lang::IllegalArgumentException & e )
359 raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) );
361 catch( RuntimeException &e )
363 raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ));
365 return ret;
368 static PyObject* callCtor( const Runtime &r , const char * clazz, const PyRef & args )
370 PyRef code( PyDict_GetItemString( r.getImpl()->cargo->getUnoModule().get(), (char*)clazz ) );
371 if( ! code.is() )
373 OStringBuffer buf;
374 buf.append( "couldn't access uno." );
375 buf.append( clazz );
376 PyErr_SetString( PyExc_RuntimeError, buf.getStr() );
377 return NULL;
379 PyRef instance( PyObject_CallObject( code.get(), args.get() ), SAL_NO_ACQUIRE);
380 Py_XINCREF( instance.get() );
381 return instance.get();
386 PyObject *PyUNO_Enum_new( const char *enumBase, const char *enumValue, const Runtime &r )
388 PyRef args( PyTuple_New( 2 ), SAL_NO_ACQUIRE );
389 PyTuple_SetItem( args.get() , 0 , PyString_FromString( enumBase ) );
390 PyTuple_SetItem( args.get() , 1 , PyString_FromString( enumValue ) );
392 return callCtor( r, "Enum" , args );
396 PyObject* PyUNO_Type_new (const char *typeName , TypeClass t , const Runtime &r )
398 // retrieve type object
399 PyRef args( PyTuple_New( 2 ), SAL_NO_ACQUIRE );
401 PyTuple_SetItem( args.get() , 0 , PyString_FromString( typeName ) );
402 PyObject *typeClass = PyUNO_Enum_new( "com.sun.star.uno.TypeClass" , typeClassToString(t), r );
403 if( ! typeClass )
404 return NULL;
405 PyTuple_SetItem( args.get() , 1 , typeClass);
407 return callCtor( r, "Type" , args );
410 PyObject* PyUNO_char_new ( sal_Unicode val , const Runtime &r )
412 // retrieve type object
413 PyRef args( PyTuple_New( 1 ), SAL_NO_ACQUIRE );
415 Py_UNICODE u[2];
416 u[0] = val;
417 u[1] = 0;
418 PyTuple_SetItem( args.get() , 0 , PyUnicode_FromUnicode( u ,1) );
420 return callCtor( r, "Char" , args );
423 PyObject *PyUNO_ByteSequence_new(
424 const com::sun::star::uno::Sequence< sal_Int8 > &byteSequence, const Runtime &r )
426 PyRef str(
427 PyString_FromStringAndSize( (char*)byteSequence.getConstArray(), byteSequence.getLength()),
428 SAL_NO_ACQUIRE );
429 PyRef args( PyTuple_New( 1 ), SAL_NO_ACQUIRE );
430 PyTuple_SetItem( args.get() , 0 , str.getAcquired() );
431 return callCtor( r, "ByteSequence" , args );