1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: pyuno_type.cxx,v $
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>
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 ) )
54 const char *typeClassToString( TypeClass t
)
59 case com::sun::star::uno::TypeClass_VOID
:
61 case com::sun::star::uno::TypeClass_CHAR
:
63 case com::sun::star::uno::TypeClass_BOOLEAN
:
64 ret
= "BOOLEAN"; break;
65 case com::sun::star::uno::TypeClass_BYTE
:
67 case com::sun::star::uno::TypeClass_SHORT
:
69 case com::sun::star::uno::TypeClass_UNSIGNED_SHORT
:
70 ret
= "UNSIGNED_SHORT"; break;
71 case com::sun::star::uno::TypeClass_LONG
:
73 case com::sun::star::uno::TypeClass_UNSIGNED_LONG
:
74 ret
= "UNSIGNED_LONG"; break;
75 case com::sun::star::uno::TypeClass_HYPER
:
77 case com::sun::star::uno::TypeClass_UNSIGNED_HYPER
:
78 ret
= "UNSIGNED_HYPER"; break;
79 case com::sun::star::uno::TypeClass_FLOAT
:
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
:
87 case com::sun::star::uno::TypeClass_ANY
:
89 case com::sun::star::uno::TypeClass_ENUM
:
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;
114 ret
= "UNKNOWN"; break;
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];
171 Any
PyEnum2Enum( PyObject
*obj
) throw ( RuntimeException
)
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
);
189 if(desc
.get()->eTypeClass
!= typelib_TypeClass_ENUM
)
192 buf
.appendAscii( "pyuno.checkEnum: " ).append(strTypeName
).appendAscii( "is a " );
194 typeClassToString( (com::sun::star::uno::TypeClass
) desc
.get()->eTypeClass
));
195 buf
.appendAscii( ", expected ENUM" );
196 throw RuntimeException( buf
.makeStringAndClear(), Reference
< XInterface
> () );
201 typelib_EnumTypeDescription
*pEnumDesc
= (typelib_EnumTypeDescription
*) desc
.get();
203 for( i
= 0; i
< pEnumDesc
->nEnumValues
; i
++ )
205 if( (*((OUString
*)&pEnumDesc
->ppEnumNames
[i
])).compareToAscii( stringValue
) == 0 )
210 if( i
== pEnumDesc
->nEnumValues
)
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
);
222 buf
.appendAscii( "enum " ).appendAscii( PyString_AsString(typeName
.get()) ).appendAscii( " is unknown" );
223 throw RuntimeException( buf
.makeStringAndClear(), Reference
< XInterface
> () );
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
);
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() )
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 ?
268 OUString name
= pyString2ustring(str
);
272 TypeDescription
desc(name
);
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() );
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
);
316 Any a
= runtime
.getImpl()->cargo
->xTdMgr
->getByHierarchicalName(name
);
319 PyRef constant
= runtime
.any2PyObject( a
);
322 Py_INCREF( constant
.get() );
323 PyDict_SetItem( dict
, target
, constant
.get());
324 ret
= constant
.get();
329 buf
.append( "constant " ).append(PyString_AsString(str
)).append( " unknown" );
330 PyErr_SetString( PyExc_RuntimeError
, buf
.getStr() );
336 buf
.appendAscii( "pyuno.imp unknown type " );
340 OUStringToOString( buf
.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US
).getStr() );
344 catch( com::sun::star::container::NoSuchElementException
& )
347 buf
.appendAscii( "pyuno.imp unknown type " );
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
));
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
) );
374 buf
.append( "couldn't access uno." );
376 PyErr_SetString( PyExc_RuntimeError
, buf
.getStr() );
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
);
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
);
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
)
427 PyString_FromStringAndSize( (char*)byteSequence
.getConstArray(), byteSequence
.getLength()),
429 PyRef
args( PyTuple_New( 1 ), SAL_NO_ACQUIRE
);
430 PyTuple_SetItem( args
.get() , 0 , str
.getAcquired() );
431 return callCtor( r
, "ByteSequence" , args
);