rubyuno 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,263 @@
1
+ /**************************************************************
2
+ * Copyright 2011 Tsutomu Uchino
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing,
11
+ * software distributed under the License is distributed on an
12
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13
+ * KIND, either express or implied. See the License for the
14
+ * specific language governing permissions and limitations
15
+ * under the License.
16
+ *
17
+ *************************************************************/
18
+
19
+ #ifndef _RUBYUNO_HXX_
20
+ #define _RUBYUNO_HXX_
21
+
22
+ #include "ruby.h"
23
+ #include <ruby/st.h>
24
+ #include <stl/hash_map>
25
+
26
+ #include <rtl/ustring.hxx>
27
+
28
+ #include <cppuhelper/implbase2.hxx>
29
+ #include <cppuhelper/weakref.hxx>
30
+
31
+ #include <com/sun/star/beans/XIntrospection.hpp>
32
+ #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
33
+ #include <com/sun/star/lang/XSingleServiceFactory.hpp>
34
+ #include <com/sun/star/lang/XUnoTunnel.hpp>
35
+ #include <com/sun/star/reflection/InvocationTargetException.hpp>
36
+ #include <com/sun/star/reflection/XIdlReflection.hpp>
37
+ #include <com/sun/star/reflection/XTypeDescription.hpp>
38
+ #include <com/sun/star/script/XInvocation2.hpp>
39
+ #include <com/sun/star/script/XInvocationAdapterFactory2.hpp>
40
+ #include <com/sun/star/script/XTypeConverter.hpp>
41
+ #include <com/sun/star/uno/XComponentContext.hpp>
42
+
43
+ #ifdef WIN32
44
+ # define RUBYUNO_DLLEXPORT __declspec(dllexport)
45
+ #else
46
+ # define RUBYUNO_DLLEXPORT
47
+ #endif
48
+
49
+ #define UNO_TYPE_NAME "UNO_TYPE_NAME"
50
+ #define ADAPTED_OBJECTS "ADAPTED_OBJECTS"
51
+ #define UNO_PROXY "UnoProxy"
52
+ #define UNO_STRUCT "UnoStruct"
53
+ #define UNO_EXCEPTION "UnoException"
54
+ #define UNO_ERRROR "UnoError"
55
+ #define UNO_TYPES "UNO_TYPES"
56
+
57
+ #define UNO_MODULE "Uno"
58
+ #define ENUM_CLASS "Enum"
59
+ #define CHAR_CLASS "Char"
60
+ #define ANY_CLASS "Any"
61
+ #define TYPE_CLASS "Type"
62
+ #define BYTES_CLASS "Bytes"
63
+ #define CSS_MODULE "CSS"
64
+
65
+ #define OUSTRING_TO_ASCII(str)\
66
+ OUStringToOString(str, RTL_TEXTENCODING_ASCII_US).getStr()
67
+
68
+ #define OUSTRING_CONST(str)\
69
+ OUString(RTL_CONSTASCII_USTRINGPARAM(str))
70
+
71
+ namespace rubyuno
72
+ {
73
+
74
+ /*
75
+ * Wrapping enum, any, types and so on.
76
+ */
77
+ typedef struct
78
+ {
79
+ com::sun::star::uno::Any value;
80
+ } RubyunoValue;
81
+
82
+ /*
83
+ * Wrappes UNO interface.
84
+ */
85
+ typedef struct
86
+ {
87
+ com::sun::star::uno::Reference < com::sun::star::script::XInvocation2 > invocation;
88
+ com::sun::star::uno::Any wrapped;
89
+ } RubyunoInternal;
90
+
91
+ /* module.cxx */
92
+
93
+
94
+ /* string.cxx */
95
+ /* OUString <-> VALUE (String) conversion */
96
+ VALUE oustring_to_rb_str(const ::rtl::OUString &str);
97
+ ::rtl::OUString rb_str_to_oustring(const VALUE &str);
98
+
99
+ ::rtl::OUString ascii_rb_str_to_oustring(const VALUE &str);
100
+ VALUE ascii_oustring_to_rb_str(const ::rtl::OUString &str);
101
+ VALUE bytes_to_rb_str(const com::sun::star::uno::Sequence< sal_Int8 > &bytes);
102
+ VALUE asciiOUString2VALUE(const ::rtl::OUString &str);
103
+ ::rtl::OUString rbString2OUString(VALUE rbstr);
104
+ VALUE ustring2RString(const ::rtl::OUString &str);
105
+ ::rtl::OUString asciiVALUE2OUString(VALUE str);
106
+ VALUE bytes2VALUE(const com::sun::star::uno::Sequence< sal_Int8 > &bytes);
107
+
108
+ void init_external_encoding(void);
109
+ //void set_external_encoding(void);
110
+
111
+ /* types.cxx */
112
+ /* Get class from Ruby runtime. */
113
+ VALUE get_uno_module(void);
114
+ VALUE get_proxy_class(void);
115
+ VALUE get_enum_class(void);
116
+ VALUE get_type_class(void);
117
+ VALUE get_char_class(void);
118
+ VALUE get_struct_class(void);
119
+ VALUE get_exception_class(void);
120
+ VALUE get_any_class(void);
121
+ VALUE get_bytes_class(void);
122
+ VALUE get_interface_class(void);
123
+ VALUE get_css_uno_exception_class(void);
124
+ VALUE get_uno_error_class(void);
125
+
126
+ VALUE find_interface(com::sun::star::uno::Reference< com::sun::star::reflection::XTypeDescription > &xTd);
127
+ void raise_rb_exception(const com::sun::star::uno::Any &a);
128
+
129
+ VALUE new_rubyuno_object(const com::sun::star::uno::Any &a, const com::sun::star::uno::Reference< com::sun::star::lang::XSingleServiceFactory > &xFactory);
130
+ VALUE new_rubyuno_proxy(const com::sun::star::uno::Any &object, const com::sun::star::uno::Reference< com::sun::star::lang::XSingleServiceFactory > &xFactory, VALUE klass);
131
+ void set_rubyuno_struct(const com::sun::star::uno::Any &object, const com::sun::star::uno::Reference< com::sun::star::lang::XSingleServiceFactory > &xFactory, VALUE &self);
132
+
133
+ /* define module according to UNO module name. */
134
+ VALUE create_module(const ::rtl::OUString &name);
135
+ /* find struct or exception class, class is created if not found */
136
+ VALUE find_class(const ::rtl::OUString &name, typelib_TypeClass typeClass);
137
+
138
+ VALUE rubyuno_new_type(const rtl::OUString &typeName, const VALUE &type_class);
139
+ VALUE rubyuno_new_enum(const rtl::OUString &typeName, const rtl::OUString &value);
140
+
141
+ rtl::OUString valueToOUString(const void *pVal, typelib_TypeDescriptionReference *pTypeRef);
142
+
143
+ struct VALUE_hash {
144
+ /* size_t operator()(const VALUE &v) const {
145
+ return static_cast< size_t >;
146
+ }
147
+ */
148
+ sal_IntPtr operator()(const VALUE &v) const
149
+ {
150
+ return sal_IntPtr(v);
151
+ }
152
+ };
153
+
154
+ typedef ::std::hash_map<
155
+ VALUE,
156
+ com::sun::star::uno::WeakReference< com::sun::star::script::XInvocation >,
157
+ VALUE_hash,
158
+ std::equal_to< VALUE >
159
+ > AdapterMap;
160
+
161
+ /*
162
+ * Keeps runtime environment.
163
+ */
164
+ typedef struct RuntimeImpl
165
+ {
166
+ com::sun::star::uno::Reference < com::sun::star::uno::XComponentContext > xComponentContext;
167
+ com::sun::star::uno::Reference < com::sun::star::lang::XSingleServiceFactory> xInvocation;
168
+ com::sun::star::uno::Reference < com::sun::star::script::XTypeConverter > xTypeConverter;
169
+ com::sun::star::uno::Reference < com::sun::star::reflection::XIdlReflection > xCoreReflection;
170
+ com::sun::star::uno::Reference < com::sun::star::container::XHierarchicalNameAccess > xTypeDescription;
171
+ com::sun::star::uno::Reference < com::sun::star::script::XInvocationAdapterFactory2 > xAdapterFactory;
172
+ com::sun::star::uno::Reference < com::sun::star::beans::XIntrospection > xIntrospection;
173
+ bool valid;
174
+ AdapterMap adapterMap;
175
+ st_table *map;
176
+ ID getTypesID;
177
+ } RuntimeImpl;
178
+
179
+
180
+ class RUBYUNO_DLLEXPORT Runtime
181
+ {
182
+ RuntimeImpl *impl;
183
+ public:
184
+
185
+ Runtime() throw(com::sun::star::uno::RuntimeException);
186
+
187
+ ~Runtime();
188
+
189
+ static void initialize(const com::sun::star::uno::Reference < com::sun::star::uno::XComponentContext > &ctx) throw (com::sun::star::uno::RuntimeException);
190
+ static bool isInitialized() throw (com::sun::star::uno::RuntimeException);
191
+ RuntimeImpl * getImpl() const {return impl;}
192
+
193
+ VALUE any_to_VALUE(const com::sun::star::uno::Any &a) const throw (com::sun::star::uno::RuntimeException);
194
+ com::sun::star::uno::Any value_to_any(VALUE value) const throw (com::sun::star::uno::RuntimeException);
195
+ com::sun::star::uno::Sequence< com::sun::star::uno::Type > getTypes(const Runtime &runtime, VALUE *value) const;
196
+ };
197
+
198
+
199
+ class RUBYUNO_DLLEXPORT Adapter : public cppu::WeakImplHelper2 < com::sun::star::script::XInvocation, com::sun::star::lang::XUnoTunnel >
200
+ {
201
+ VALUE m_wrapped;
202
+ com::sun::star::uno::Sequence< com::sun::star::uno::Type > m_types;
203
+
204
+ com::sun::star::uno::Sequence< sal_Int16 > getOutParamIndexes(const rtl::OUString &methodName);
205
+
206
+ public:
207
+ Adapter(const VALUE &obj, const com::sun::star::uno::Sequence< com::sun::star::uno::Type > &types);
208
+
209
+ virtual ~Adapter();
210
+
211
+ static com::sun::star::uno::Sequence< sal_Int8 > getUnoTunnelImplementationId();
212
+ static com::sun::star::uno::Sequence< sal_Int8 > getTunnelImplId();
213
+
214
+ VALUE getWrapped();
215
+ com::sun::star::uno::Sequence< com::sun::star::uno::Type > getWrappedTypes();
216
+
217
+ virtual com::sun::star::uno::Reference < com::sun::star::beans::XIntrospectionAccess > SAL_CALL getIntrospection() throw (com::sun::star::uno::RuntimeException);
218
+
219
+ virtual com::sun::star::uno::Any SAL_CALL invoke(
220
+ const rtl::OUString & aFunctionName,
221
+ const com::sun::star::uno::Sequence < com::sun::star::uno::Any > &aParams,
222
+ com::sun::star::uno::Sequence < sal_Int16 > &aOutParamIndex,
223
+ com::sun::star::uno::Sequence < com::sun::star::uno::Any > &aOutParam)
224
+ throw (
225
+ com::sun::star::lang::IllegalArgumentException,
226
+ com::sun::star::script::CannotConvertException,
227
+ com::sun::star::reflection::InvocationTargetException,
228
+ com::sun::star::uno::RuntimeException);
229
+
230
+ virtual void SAL_CALL setValue(
231
+ const rtl::OUString &aPropertyName,
232
+ const com::sun::star::uno::Any &aValue)
233
+ throw (
234
+ com::sun::star::beans::UnknownPropertyException,
235
+ com::sun::star::script::CannotConvertException,
236
+ com::sun::star::reflection::InvocationTargetException,
237
+ com::sun::star::uno::RuntimeException);
238
+
239
+ virtual com::sun::star::uno::Any SAL_CALL getValue(
240
+ const rtl::OUString &aPropertyName)
241
+ throw (
242
+ com::sun::star::beans::UnknownPropertyException,
243
+ com::sun::star::uno::RuntimeException);
244
+
245
+ virtual sal_Bool SAL_CALL hasMethod(
246
+ const rtl::OUString &aName)
247
+ throw (
248
+ com::sun::star::uno::RuntimeException);
249
+
250
+ virtual sal_Bool SAL_CALL hasProperty(
251
+ const rtl::OUString &aName)
252
+ throw (
253
+ com::sun::star::uno::RuntimeException);
254
+
255
+ virtual sal_Int64 SAL_CALL getSomething(
256
+ const com::sun::star::uno::Sequence < sal_Int8 > &aIdentifier)
257
+ throw (
258
+ com::sun::star::uno::RuntimeException);
259
+ };
260
+
261
+ }
262
+
263
+ #endif
@@ -0,0 +1,2 @@
1
+ EXPORTS
2
+ Init_runo
@@ -0,0 +1,524 @@
1
+
2
+ #include "rubyuno.hxx"
3
+
4
+ #include <osl/thread.h>
5
+ #include <typelib/typedescription.hxx>
6
+
7
+ #include <com/sun/star/reflection/XEnumTypeDescription.hpp>
8
+ #include <com/sun/star/beans/XMaterialHolder.hpp>
9
+
10
+ using com::sun::star::script::XInvocationAdapterFactory2;
11
+ using com::sun::star::beans::XIntrospection;
12
+ using com::sun::star::beans::XMaterialHolder;
13
+ using com::sun::star::container::XHierarchicalNameAccess;
14
+ using com::sun::star::lang::XSingleServiceFactory;
15
+ using com::sun::star::reflection::XEnumTypeDescription;
16
+ using com::sun::star::reflection::XIdlReflection;
17
+ using com::sun::star::script::XInvocation;
18
+ using com::sun::star::script::XInvocation2;
19
+ using com::sun::star::script::XTypeConverter;
20
+ using com::sun::star::uno::Any;
21
+ using com::sun::star::uno::Reference;
22
+ using com::sun::star::uno::RuntimeException;
23
+ using com::sun::star::uno::TypeClass;
24
+ using com::sun::star::uno::TypeDescription;
25
+ using com::sun::star::uno::XComponentContext;
26
+ using com::sun::star::uno::UNO_QUERY;
27
+
28
+ using rtl::OString;
29
+ using rtl::OUString;
30
+ using rtl::OUStringToOString;
31
+
32
+ using namespace com::sun::star::uno;
33
+
34
+ namespace rubyuno
35
+ {
36
+
37
+ static RuntimeImpl *gImpl;
38
+
39
+ bool Runtime::isInitialized() throw (RuntimeException)
40
+ {
41
+ if (gImpl)
42
+ return gImpl->valid;
43
+ return false;
44
+ }
45
+
46
+
47
+ Runtime::Runtime() throw (RuntimeException)
48
+ {
49
+ impl = gImpl;
50
+ }
51
+
52
+
53
+ Runtime::~Runtime()
54
+ {
55
+ impl = NULL;
56
+ }
57
+
58
+ void Runtime::initialize(const Reference< XComponentContext > &ctx) throw (RuntimeException)
59
+ {
60
+ if (gImpl)
61
+ {
62
+ throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM("rubyuno runtime is already initialized.")), Reference< XInterface >());
63
+ }
64
+ gImpl = new RuntimeImpl();
65
+
66
+ gImpl->xComponentContext = ctx;
67
+
68
+ gImpl->xInvocation = Reference < XSingleServiceFactory > (
69
+ ctx->getServiceManager()->createInstanceWithContext(
70
+ OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.script.Invocation")),
71
+ ctx), UNO_QUERY);
72
+
73
+ if (!gImpl->xInvocation.is())
74
+ {
75
+ throw RuntimeException(
76
+ OUString(RTL_CONSTASCII_USTRINGPARAM("rubyuno: failed to instantiate com.sun.star.script.Invocation.")), Reference< XInterface >());
77
+ }
78
+ gImpl->xIntrospection = Reference < XIntrospection > (
79
+ ctx->getServiceManager()->createInstanceWithContext(
80
+ OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.beans.Introspection")),
81
+ ctx), UNO_QUERY);
82
+ if (!gImpl->xIntrospection.is())
83
+ {
84
+ throw RuntimeException(
85
+ OUString(RTL_CONSTASCII_USTRINGPARAM("rubyuno: failed to instantiate com.sun.star.beans.Instrospection")), Reference< XInterface >());
86
+ }
87
+ gImpl->xCoreReflection = Reference < XIdlReflection > (
88
+ ctx->getServiceManager()->createInstanceWithContext(
89
+ OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.reflection.CoreReflection")),
90
+ ctx), UNO_QUERY);
91
+ if (!gImpl->xCoreReflection.is())
92
+ {
93
+ throw RuntimeException(
94
+ OUString(RTL_CONSTASCII_USTRINGPARAM("rubyuno: failfed to instantiate com.sun.star.reflection.CoreReflection.")), Reference< XInterface >());
95
+ }
96
+ gImpl->xTypeConverter = Reference < XTypeConverter > (
97
+ ctx->getServiceManager()->createInstanceWithContext(
98
+ OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.script.Converter")),
99
+ ctx), UNO_QUERY);
100
+ if (!gImpl->xTypeConverter.is())
101
+ {
102
+ throw RuntimeException(
103
+ OUString(RTL_CONSTASCII_USTRINGPARAM("rubyuno: failfed to instantiate com.sun.star.script.Converter.")), Reference< XInterface >());
104
+ }
105
+ gImpl->xAdapterFactory = Reference < XInvocationAdapterFactory2 > (
106
+ ctx->getServiceManager()->createInstanceWithContext(
107
+ OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.script.InvocationAdapterFactory")),
108
+ ctx), UNO_QUERY);
109
+ if (!gImpl->xTypeConverter.is())
110
+ {
111
+ throw RuntimeException(
112
+ OUString(RTL_CONSTASCII_USTRINGPARAM("rubyuno: failed to instantiate com.sun.star.script.InvocationAdapterFactory.")), Reference< XInterface >());
113
+ }
114
+ Any tdm = ctx->getValueByName(
115
+ OUString(RTL_CONSTASCII_USTRINGPARAM("/singletons/com.sun.star.reflection.theTypeDescriptionManager")));
116
+ tdm >>= gImpl->xTypeDescription;
117
+ if (! gImpl->xTypeDescription.is())
118
+ {
119
+ throw RuntimeException(
120
+ OUString(RTL_CONSTASCII_USTRINGPARAM("rubyuno: failed to get /singletons/com.sun.star.reflection.theTypeDescriptionManager.")), Reference< XInterface >());
121
+ }
122
+ gImpl->valid = true;
123
+ }
124
+
125
+
126
+ static Sequence< Type >
127
+ getTypes(const Runtime &runtime, VALUE *value)
128
+ {
129
+ Sequence< Type > ret;
130
+ ID id = rb_intern("getTypes");
131
+
132
+ if (! rb_respond_to(*value, id))
133
+ rb_raise(rb_eArgError, "illegal argument does not support com.sun.star.lang.XTypeProvider interface");
134
+ VALUE types = rb_funcall(*value, id, 0);
135
+
136
+ long size = RARRAY_LEN(types);
137
+ ret.realloc(size + 1);
138
+ for (long i = 0; i < size; i++)
139
+ {
140
+ Any a = runtime.value_to_any(rb_ary_entry(types, i));
141
+ a >>= ret[i];
142
+ }
143
+ ret[size] = getCppuType((Reference< com::sun::star::lang::XUnoTunnel > *)0);
144
+ return ret;
145
+ }
146
+
147
+
148
+ /*
149
+ * Convert UNO Any to Ruby VALUE.
150
+ */
151
+ VALUE Runtime::any_to_VALUE(const Any &a) const throw (RuntimeException)
152
+ {
153
+ switch (a.getValueTypeClass())
154
+ {
155
+ case typelib_TypeClass_BOOLEAN:
156
+ {
157
+ sal_Bool b = sal_Bool();
158
+ if ((a >>= b) && b)
159
+ {
160
+ return Qtrue;
161
+ } else {
162
+ return Qfalse;
163
+ }
164
+ }
165
+ case typelib_TypeClass_BYTE:
166
+ case typelib_TypeClass_SHORT:
167
+ case typelib_TypeClass_UNSIGNED_SHORT:
168
+ {
169
+ sal_Int32 l = 0;
170
+ a >>= l;
171
+ return INT2FIX(l);
172
+ }
173
+ case typelib_TypeClass_LONG:
174
+ case typelib_TypeClass_UNSIGNED_LONG:
175
+ case typelib_TypeClass_HYPER:
176
+ case typelib_TypeClass_UNSIGNED_HYPER:
177
+ {
178
+ sal_Int64 l = 0;
179
+ a >>= l;
180
+ return INT2NUM(l);
181
+ }
182
+ case typelib_TypeClass_FLOAT:
183
+ {
184
+ float f;
185
+ a >>= f;
186
+ #ifdef DBL2NUM
187
+ return DBL2NUM(f);
188
+ #else
189
+ NEWOBJ(flt, struct RFloat);
190
+ OBJSETUP(flt, rb_cFloat, T_FLOAT);
191
+
192
+ flt->value = f;
193
+ return (VALUE)flt;
194
+ #endif
195
+ }
196
+ case typelib_TypeClass_DOUBLE:
197
+ {
198
+ double d;
199
+ a >>= d;
200
+ #ifdef DBL2NUM
201
+ return DBL2NUM(d);
202
+ #else
203
+ NEWOBJ(flt, struct RFloat);
204
+ OBJSETUP(flt, rb_cFloat, T_FLOAT);
205
+
206
+ flt->value = d;
207
+ return (VALUE)flt;
208
+ #endif
209
+
210
+ }
211
+ case typelib_TypeClass_STRING:
212
+ {
213
+ OUString s;
214
+ a >>= s;
215
+ return ustring2RString(s);
216
+ }
217
+ case typelib_TypeClass_ENUM:
218
+ {
219
+ sal_Int32 v = *(sal_Int32 *) a.getValue();
220
+ TypeDescription desc(a.getValueType());
221
+ if (desc.is())
222
+ {
223
+ desc.makeComplete();
224
+ typelib_EnumTypeDescription * pEnumDesc = (typelib_EnumTypeDescription *) desc.get();
225
+ for (int i = 0; i < pEnumDesc->nEnumValues; i++)
226
+ {
227
+ if (pEnumDesc->pEnumValues[i] == v)
228
+ {
229
+ OUString typeName = pEnumDesc->aBase.pTypeName;
230
+ OUString valueName = pEnumDesc->ppEnumNames[i];
231
+
232
+ VALUE type_name = ustring2RString(typeName);
233
+ VALUE value_name = ustring2RString(valueName);
234
+ VALUE enumValue = rb_funcall(get_enum_class(), rb_intern("new"), 2, type_name, value_name);
235
+ return enumValue;
236
+ }
237
+ }
238
+ }
239
+ throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM("illegal enum")), Reference< XInterface >());
240
+ }
241
+ case typelib_TypeClass_STRUCT:
242
+ case typelib_TypeClass_EXCEPTION:
243
+ {
244
+ VALUE klass;
245
+ Runtime runtime;
246
+ klass = find_class(a.getValueTypeName(), (typelib_TypeClass)a.getValueTypeClass());
247
+ if (NIL_P(klass))
248
+ rb_raise(rb_eRuntimeError, "failed to create class (%s)", OUStringToOString(a.getValueTypeName(), RTL_TEXTENCODING_ASCII_US).getStr());
249
+
250
+ return new_rubyuno_proxy(a, runtime.getImpl()->xInvocation, klass);
251
+ }
252
+ case typelib_TypeClass_SEQUENCE:
253
+ {
254
+ Sequence< Any > s;
255
+
256
+ TypeDescription desc(OUString(RTL_CONSTASCII_USTRINGPARAM("[]byte")));
257
+ if (a.getValueTypeRef()->pType == desc.get())
258
+ {
259
+ Sequence< sal_Int8 > bytes;
260
+ a >>= bytes;
261
+ VALUE klass = get_bytes_class();
262
+ return rb_funcall(klass, rb_intern("new"), 1, bytes2VALUE(bytes));
263
+ }
264
+ else
265
+ {
266
+ Reference< XTypeConverter > tc = getImpl()->xTypeConverter;
267
+ tc->convertTo(a, ::getCppuType(&s)) >>= s;
268
+ VALUE ary = Qnil;
269
+ ary = rb_ary_new2(s.getLength());
270
+ int i = 0;
271
+ try{
272
+ for (i = 0; i < s.getLength(); i++)
273
+ {
274
+ rb_ary_push(ary, any_to_VALUE(tc->convertTo(s[i], s[i].getValueType())));
275
+ }
276
+ }
277
+ catch (com::sun::star::uno::Exception &e)
278
+ {
279
+ for (; i < s.getLength(); i++)
280
+ {
281
+ rb_ary_push(ary, Qnil);
282
+ }
283
+ }
284
+ return ary;
285
+ }
286
+ }
287
+ case typelib_TypeClass_INTERFACE:
288
+ {
289
+ return new_rubyuno_object(a, getImpl()->xInvocation);
290
+ }
291
+ case typelib_TypeClass_TYPE:
292
+ {
293
+ Type t;
294
+ a >>= t;
295
+ OString o = OUStringToOString(t.getTypeName(), RTL_TEXTENCODING_ASCII_US);
296
+ VALUE type_class = any_to_VALUE(Any((com::sun::star::uno::TypeClass)t.getTypeClass()));
297
+ VALUE type;
298
+ type = rb_funcall(get_type_class(), rb_intern("new"), 2, rb_str_new2(o.getStr()), type_class);
299
+ return type;
300
+ }
301
+ case typelib_TypeClass_VOID:
302
+ {
303
+ return Qnil;
304
+ }
305
+ case typelib_TypeClass_CHAR:
306
+ {
307
+ sal_Unicode c = *(sal_Unicode*)a.getValue();
308
+ VALUE v = ustring2RString(OUString(c));
309
+ VALUE char_class = get_char_class();
310
+ return rb_funcall(char_class, rb_intern("new"), 1, v);
311
+ }
312
+ case typelib_TypeClass_ANY:
313
+ {
314
+ return Qnil; // unknown
315
+ }
316
+ default:
317
+ {
318
+ throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM("Unknown type.")), Reference< XInterface >());
319
+ }
320
+ }
321
+ return Qnil;
322
+ }
323
+
324
+ /*
325
+ * Convert Ruby VALUE to UNO Any.
326
+ */
327
+ Any Runtime::value_to_any(VALUE value) const throw (com::sun::star::uno::RuntimeException)
328
+ {
329
+ //printf("value_to_any: %s\n", rb_obj_classname(value));
330
+ Any a;
331
+
332
+ switch (TYPE(value))
333
+ {
334
+ case T_NIL:
335
+ {
336
+ break;
337
+ }
338
+ case T_TRUE:
339
+ {
340
+ sal_Bool b = sal_True;
341
+ a = Any(&b, getBooleanCppuType());
342
+ break;
343
+ }
344
+ case T_FALSE:
345
+ {
346
+ sal_Bool b = sal_False;
347
+ a = Any(&b, getBooleanCppuType());
348
+ break;
349
+ }
350
+ case T_FIXNUM:
351
+ {
352
+ // 63bit Fixnum be over flow
353
+ sal_Int32 l = (sal_Int32) FIX2LONG(value);
354
+ if (l <= 127 && l >= -128)
355
+ {
356
+ sal_Int8 b = (sal_Int8) l;
357
+ a <<= b;
358
+ }
359
+ else if (l <= 0x7fff && l >= -0x8000)
360
+ {
361
+ sal_Int16 i = (sal_Int16) l;
362
+ a <<= i;
363
+ }
364
+ else
365
+ {
366
+ a <<= l;
367
+ }
368
+ break;
369
+ }
370
+ case T_BIGNUM:
371
+ {
372
+ sal_Int64 l = (sal_Int64) NUM2LONG(value);
373
+ if (l <= 127 && l >= -128)
374
+ {
375
+ sal_Int8 b = (sal_Int8) l;
376
+ a <<= b;
377
+ }
378
+ else if (l <= 0x7fff && l >= -0x8000)
379
+ {
380
+ sal_Int16 i = (sal_Int16) l;
381
+ a <<= i;
382
+ }
383
+ else if (l <= SAL_CONST_INT64(0x7fffffff) && l >= -SAL_CONST_INT64(0x80000000))
384
+ {
385
+ sal_Int32 l32 = (sal_Int32) l;
386
+ a <<= l32;
387
+ }
388
+ else
389
+ {
390
+ a <<= l;
391
+ }
392
+ break;
393
+ }
394
+ case T_FLOAT:
395
+ {
396
+ double d = NUM2DBL(value);
397
+ a <<= d;
398
+ break;
399
+ }
400
+ case T_STRING:
401
+ {
402
+ if (rb_obj_is_kind_of(value, get_bytes_class()))
403
+ {
404
+ char *s = RSTRING_PTR(value);
405
+ Sequence< sal_Int8 > seq((sal_Int8*)s, (sal_Int32)RSTRING_LEN(value));
406
+ a <<= seq;
407
+ }
408
+ else
409
+ {
410
+ a <<= rbString2OUString(value);
411
+ }
412
+ break;
413
+ }
414
+ case T_ARRAY:
415
+ {
416
+ Sequence< Any > s(RARRAY_LEN(value));
417
+ for (long i = 0; i < RARRAY_LEN(value); i++)
418
+ {
419
+ s[i] = value_to_any(rb_ary_entry(value, i)); // long?
420
+ }
421
+ a <<= s;
422
+ break;
423
+ }
424
+ case T_DATA:
425
+ {
426
+ if (rb_obj_is_kind_of(value, get_proxy_class()))
427
+ {
428
+ RubyunoInternal *rubyuno;
429
+ Data_Get_Struct(value, RubyunoInternal, rubyuno);
430
+ if (rubyuno)
431
+ {
432
+ a = rubyuno->wrapped;
433
+ }
434
+ }
435
+ else if (rb_obj_is_kind_of(value, get_enum_class()) ||
436
+ rb_obj_is_kind_of(value, get_type_class()))
437
+ {
438
+ RubyunoValue *ptr;
439
+ Data_Get_Struct(value, RubyunoValue, ptr);
440
+ if (ptr)
441
+ {
442
+ a <<= ptr->value;
443
+ }
444
+ }
445
+ else if (rb_obj_is_kind_of(value, get_struct_class()) ||
446
+ rb_obj_is_kind_of(value, get_exception_class()))
447
+ {
448
+ RubyunoInternal *rubyuno;
449
+ Data_Get_Struct(value, RubyunoInternal, rubyuno);
450
+ Reference< XMaterialHolder > xholder(rubyuno->invocation, UNO_QUERY);
451
+ if (xholder.is())
452
+ a = xholder->getMaterial();
453
+ else
454
+ {
455
+ throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM("XMaterialHolder is not supported.")), Reference< XInterface >());
456
+ }
457
+ }
458
+ else if (rb_obj_is_kind_of(value, get_any_class()))
459
+ {
460
+ a = value_to_any(rb_iv_get(value, "@value"));
461
+ Type t;
462
+ value_to_any(rb_iv_get(value, "@type")) >>= t;
463
+ try
464
+ {
465
+ a = getImpl()->xTypeConverter->convertTo(a, t);
466
+ }
467
+ catch (com::sun::star::uno::Exception &e)
468
+ {
469
+ throw RuntimeException(e.Message, e.Context);
470
+ }
471
+ }
472
+ else if (rb_obj_is_kind_of(value, get_char_class()))
473
+ {
474
+ RubyunoInternal *rubyuno;
475
+ Data_Get_Struct(value, RubyunoInternal, rubyuno);
476
+ sal_Unicode c;
477
+ rubyuno->wrapped >>= c;
478
+ a.setValue(&c, getCharCppuType());
479
+ }
480
+ break;
481
+ }
482
+ default:
483
+ {
484
+ Reference< XInterface > mapped;
485
+ Reference< XInvocation > adapted;
486
+
487
+ AdapterMap::iterator it = impl->adapterMap.find(value);
488
+ if (it != impl->adapterMap.end())
489
+ {
490
+ adapted = it->second;
491
+ }
492
+ if (adapted.is())
493
+ {
494
+ Reference< com::sun::star::lang::XUnoTunnel > tunnel(adapted, UNO_QUERY);
495
+ Adapter *adapter = (Adapter *) sal::static_int_cast< sal_IntPtr >(tunnel->getSomething(Adapter::getTunnelImplId()));
496
+
497
+ mapped = impl->xAdapterFactory->createAdapter(adapted, adapter->getWrappedTypes());
498
+ }
499
+ else
500
+ {
501
+ Sequence< Type > types = getTypes(*this, &value);
502
+ if (types.getLength())
503
+ {
504
+ Adapter *adapter = new Adapter(value, types);
505
+ mapped = getImpl()->xAdapterFactory->createAdapter(adapter, types);
506
+ impl->adapterMap[value] = com::sun::star::uno::WeakReference< XInvocation >(adapter);
507
+ }
508
+ }
509
+ if (mapped.is())
510
+ {
511
+ a = makeAny(mapped);
512
+ }
513
+ else
514
+ {
515
+ rb_raise(rb_eArgError, "unknown type (%s)", rb_obj_classname(value));
516
+ }
517
+ }
518
+ }
519
+ return a;
520
+ }
521
+
522
+ }
523
+
524
+