LibreOffice Module bridges (master)  1
jni_data.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <sal/config.h>
21 
22 #include <cassert>
23 #include <memory>
24 
25 #include "jni_bridge.h"
26 
27 #include <rtl/strbuf.hxx>
28 #include <uno/sequence2.h>
29 
30 namespace jni_uno
31 {
32 
33 
34 static std::unique_ptr<rtl_mem> seq_allocate(
35  sal_Int32 nElements, sal_Int32 nSize )
36 {
37  std::unique_ptr< rtl_mem > seq(
38  rtl_mem::allocate( SAL_SEQUENCE_HEADER_SIZE + (nElements * nSize) ) );
39  uno_Sequence * p = reinterpret_cast<uno_Sequence *>(seq.get());
40  p->nRefCount = 1;
41  p->nElements = nElements;
42  return seq;
43 }
44 
45 
46 namespace {
47 
48 void createDefaultUnoValue(
49  JNI_context const & jni, void * uno_data,
50  typelib_TypeDescriptionReference * type,
51  JNI_type_info const * info /* maybe 0 */, bool assign)
52 {
53  switch (type->eTypeClass) {
54  case typelib_TypeClass_BOOLEAN:
55  *static_cast< sal_Bool * >(uno_data) = false;
56  break;
57 
58  case typelib_TypeClass_BYTE:
59  *static_cast< sal_Int8 * >(uno_data) = 0;
60  break;
61 
62  case typelib_TypeClass_SHORT:
63  *static_cast< sal_Int16 * >(uno_data) = 0;
64  break;
65 
66  case typelib_TypeClass_UNSIGNED_SHORT:
67  *static_cast< sal_uInt16 * >(uno_data) = 0;
68  break;
69 
70  case typelib_TypeClass_LONG:
71  *static_cast< sal_Int32 * >(uno_data) = 0;
72  break;
73 
74  case typelib_TypeClass_UNSIGNED_LONG:
75  *static_cast< sal_uInt32 * >(uno_data) = 0;
76  break;
77 
78  case typelib_TypeClass_HYPER:
79  *static_cast< sal_Int64 * >(uno_data) = 0;
80  break;
81 
82  case typelib_TypeClass_UNSIGNED_HYPER:
83  *static_cast< sal_uInt64 * >(uno_data) = 0;
84  break;
85 
86  case typelib_TypeClass_FLOAT:
87  *static_cast< float * >(uno_data) = 0;
88  break;
89 
90  case typelib_TypeClass_DOUBLE:
91  *static_cast< double * >(uno_data) = 0;
92  break;
93 
94  case typelib_TypeClass_CHAR:
95  *static_cast< sal_Unicode * >(uno_data) = 0;
96  break;
97 
98  case typelib_TypeClass_STRING:
99  if (!assign) {
100  *static_cast< rtl_uString ** >(uno_data) = nullptr;
101  }
102  rtl_uString_new(static_cast< rtl_uString ** >(uno_data));
103  break;
104 
105  case typelib_TypeClass_TYPE:
106  if (assign) {
108  *static_cast< typelib_TypeDescriptionReference ** >(uno_data));
109  }
110  *static_cast< typelib_TypeDescriptionReference ** >(uno_data)
111  = *typelib_static_type_getByTypeClass(typelib_TypeClass_VOID);
112  assert(
113  *static_cast< typelib_TypeDescriptionReference ** >(uno_data) != nullptr);
115  *static_cast< typelib_TypeDescriptionReference ** >(uno_data));
116  break;
117 
118  case typelib_TypeClass_ANY:
119  if (assign) {
120  uno_any_destruct(static_cast< uno_Any * >(uno_data), nullptr);
121  }
123  static_cast< uno_Any * >(uno_data), nullptr,
124  jni.get_info()->m_XInterface_type_info->m_td.get(), nullptr);
125  break;
126 
127  case typelib_TypeClass_SEQUENCE:
128  {
129  std::unique_ptr< rtl_mem > seq(seq_allocate(0, 0));
130  if (assign) {
131  uno_type_destructData(uno_data, type, nullptr);
132  }
133  *static_cast< uno_Sequence ** >(uno_data)
134  = reinterpret_cast< uno_Sequence * >(seq.release());
135  break;
136  }
137 
138  case typelib_TypeClass_ENUM:
139  {
140  typelib_TypeDescription * td = nullptr;
141  TYPELIB_DANGER_GET(&td, type);
142  *static_cast< sal_Int32 * >(uno_data)
143  = (reinterpret_cast< typelib_EnumTypeDescription * >(td)->
144  nDefaultEnumValue);
145  TYPELIB_DANGER_RELEASE(td);
146  break;
147  }
148 
149  case typelib_TypeClass_STRUCT:
150  {
151  if (info == nullptr) {
152  info = jni.get_info()->get_type_info(jni, type);
153  }
154  JNI_compound_type_info const * comp_info
155  = static_cast< JNI_compound_type_info const * >(info);
156  typelib_CompoundTypeDescription * comp_td
157  = reinterpret_cast< typelib_CompoundTypeDescription * >(
158  comp_info->m_td.get());
159  sal_Int32 nPos = 0;
160  sal_Int32 nMembers = comp_td->nMembers;
161  try {
162  if (comp_td->pBaseTypeDescription != nullptr) {
163  createDefaultUnoValue(
164  jni, uno_data,
165  comp_td->pBaseTypeDescription->aBase.pWeakRef,
166  comp_info->m_base, assign);
167  }
168  for (; nPos < nMembers; ++nPos) {
169  createDefaultUnoValue(
170  jni,
171  (static_cast< char * >(uno_data)
172  + comp_td->pMemberOffsets[nPos]),
173  comp_td->ppTypeRefs[nPos], nullptr, assign);
174  }
175  } catch (...) {
176  if (!assign) {
177  for (sal_Int32 i = 0; i < nPos; ++i) {
179  (static_cast< char * >(uno_data)
180  + comp_td->pMemberOffsets[i]),
181  comp_td->ppTypeRefs[i], nullptr);
182  }
183  if (comp_td->pBaseTypeDescription != nullptr) {
185  uno_data, &comp_td->pBaseTypeDescription->aBase, nullptr);
186  }
187  }
188  throw;
189  }
190  }
191  break;
192 
193  case typelib_TypeClass_INTERFACE:
194  if (assign) {
195  uno_Interface * p = *static_cast< uno_Interface ** >(uno_data);
196  if (p != nullptr) {
197  (*p->release)(p);
198  }
199  }
200  *static_cast< uno_Interface ** >(uno_data) = nullptr;
201  break;
202 
203  default:
204  assert(false);
205  break;
206  }
207 }
208 
209 }
210 
212  JNI_context const & jni,
213  void * uno_data, jvalue java_data,
214  typelib_TypeDescriptionReference * type,
215  JNI_type_info const * info /* maybe 0 */,
216  bool assign, bool out_param,
217  bool special_wrapped_integral_types ) const
218 {
219  assert(
220  !out_param ||
221  (jni->GetArrayLength( static_cast<jarray>(java_data.l) ) == 1) );
222 
223  switch (type->eTypeClass)
224  {
225  case typelib_TypeClass_CHAR:
226  if (out_param)
227  {
228  jni->GetCharArrayRegion(
229  static_cast<jcharArray>(java_data.l), 0, 1, static_cast<jchar *>(uno_data) );
230  jni.ensure_no_exception();
231  }
232  else if (special_wrapped_integral_types)
233  {
234  *static_cast<jchar *>(uno_data) = jni->CallCharMethodA(
235  java_data.l, getJniInfo()->m_method_Character_charValue, nullptr );
236  jni.ensure_no_exception();
237  }
238  else
239  {
240  *static_cast<jchar *>(uno_data) = java_data.c;
241  }
242  break;
243  case typelib_TypeClass_BOOLEAN:
244  if (out_param)
245  {
246  jni->GetBooleanArrayRegion(
247  static_cast<jbooleanArray>(java_data.l), 0, 1, static_cast<jboolean *>(uno_data) );
248  jni.ensure_no_exception();
249  }
250  else if (special_wrapped_integral_types)
251  {
252  *static_cast<jboolean *>(uno_data) = jni->CallBooleanMethodA(
253  java_data.l, getJniInfo()->m_method_Boolean_booleanValue, nullptr );
254  jni.ensure_no_exception();
255  }
256  else
257  {
258  *static_cast<jboolean *>(uno_data) = java_data.z;
259  }
260  break;
261  case typelib_TypeClass_BYTE:
262  if (out_param)
263  {
264  jni->GetByteArrayRegion(
265  static_cast<jbyteArray>(java_data.l), 0, 1, static_cast<jbyte *>(uno_data) );
266  jni.ensure_no_exception();
267  }
268  else if (special_wrapped_integral_types)
269  {
270  *static_cast<jbyte *>(uno_data) = jni->CallByteMethodA(
271  java_data.l, getJniInfo()->m_method_Byte_byteValue, nullptr );
272  jni.ensure_no_exception();
273  }
274  else
275  {
276  *static_cast<jbyte *>(uno_data) = java_data.b;
277  }
278  break;
279  case typelib_TypeClass_SHORT:
280  case typelib_TypeClass_UNSIGNED_SHORT:
281  if (out_param)
282  {
283  jni->GetShortArrayRegion(
284  static_cast<jshortArray>(java_data.l), 0, 1, static_cast<jshort *>(uno_data) );
285  jni.ensure_no_exception();
286  }
287  else if (special_wrapped_integral_types)
288  {
289  *static_cast<jshort *>(uno_data) = jni->CallShortMethodA(
290  java_data.l, getJniInfo()->m_method_Short_shortValue, nullptr );
291  jni.ensure_no_exception();
292  }
293  else
294  {
295  *static_cast<jshort *>(uno_data) = java_data.s;
296  }
297  break;
298  case typelib_TypeClass_LONG:
299  case typelib_TypeClass_UNSIGNED_LONG:
300  if (out_param)
301  {
302  jni->GetIntArrayRegion(
303  static_cast<jintArray>(java_data.l), 0, 1, static_cast<jint *>(uno_data) );
304  jni.ensure_no_exception();
305  }
306  else if (special_wrapped_integral_types)
307  {
308  *static_cast<jint *>(uno_data) = jni->CallIntMethodA(
309  java_data.l, getJniInfo()->m_method_Integer_intValue, nullptr );
310  jni.ensure_no_exception();
311  }
312  else
313  {
314  *static_cast<jint *>(uno_data) = java_data.i;
315  }
316  break;
317  case typelib_TypeClass_HYPER:
318  case typelib_TypeClass_UNSIGNED_HYPER:
319  if (out_param)
320  {
321  jni->GetLongArrayRegion(
322  static_cast<jlongArray>(java_data.l), 0, 1, static_cast<jlong *>(uno_data) );
323  jni.ensure_no_exception();
324  }
325  else if (special_wrapped_integral_types)
326  {
327  *static_cast<jlong *>(uno_data) = jni->CallLongMethodA(
328  java_data.l, getJniInfo()->m_method_Long_longValue, nullptr );
329  jni.ensure_no_exception();
330  }
331  else
332  {
333  *static_cast<jlong *>(uno_data) = java_data.j;
334  }
335  break;
336  case typelib_TypeClass_FLOAT:
337  if (out_param)
338  {
339  jni->GetFloatArrayRegion(
340  static_cast<jfloatArray>(java_data.l), 0, 1, static_cast<jfloat *>(uno_data) );
341  jni.ensure_no_exception();
342  }
343  else if (special_wrapped_integral_types)
344  {
345  *static_cast<jfloat *>(uno_data) = jni->CallFloatMethodA(
346  java_data.l, getJniInfo()->m_method_Float_floatValue, nullptr );
347  jni.ensure_no_exception();
348  }
349  else
350  {
351  *static_cast<jfloat *>(uno_data) = java_data.f;
352  }
353  break;
354  case typelib_TypeClass_DOUBLE:
355  if (out_param)
356  {
357  jni->GetDoubleArrayRegion(
358  static_cast<jdoubleArray>(java_data.l), 0, 1, static_cast<jdouble *>(uno_data) );
359  jni.ensure_no_exception();
360  }
361  else if (special_wrapped_integral_types)
362  {
363  *static_cast<jdouble *>(uno_data) = jni->CallDoubleMethodA(
364  java_data.l, getJniInfo()->m_method_Double_doubleValue, nullptr );
365  jni.ensure_no_exception();
366  }
367  else
368  {
369  *static_cast<jdouble *>(uno_data) = java_data.d;
370  }
371  break;
372  case typelib_TypeClass_STRING:
373  {
374  JLocalAutoRef jo_out_holder( jni );
375  if (out_param)
376  {
377  jo_out_holder.reset(
378  jni->GetObjectArrayElement( static_cast<jobjectArray>(java_data.l), 0 ) );
379  jni.ensure_no_exception();
380  java_data.l = jo_out_holder.get();
381  }
382  if (java_data.l == nullptr)
383  {
384  throw BridgeRuntimeError(
385  "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
386  + "] null-ref given!" + jni.get_stack_trace() );
387  }
388  if (! assign)
389  *static_cast<rtl_uString **>(uno_data) = nullptr;
391  jni, static_cast<rtl_uString **>(uno_data), static_cast<jstring>(java_data.l) );
392  break;
393  }
394  case typelib_TypeClass_TYPE:
395  {
396  JLocalAutoRef jo_out_holder( jni );
397  if (out_param)
398  {
399  jo_out_holder.reset(
400  jni->GetObjectArrayElement( static_cast<jobjectArray>(java_data.l), 0 ) );
401  jni.ensure_no_exception();
402  java_data.l = jo_out_holder.get();
403  }
404  if (java_data.l == nullptr)
405  {
406  throw BridgeRuntimeError(
407  "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
408  + "] null-ref given!" + jni.get_stack_trace() );
409  }
410 
411  // type name
412  JLocalAutoRef jo_type_name(
413  jni, jni->GetObjectField(
414  java_data.l, getJniInfo()->m_field_Type_typeName ) );
415  if (! jo_type_name.is())
416  {
417  throw BridgeRuntimeError(
418  "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
419  + "] incomplete type object: no type name!"
420  + jni.get_stack_trace() );
421  }
422  OUString type_name(
423  jstring_to_oustring( jni, static_cast<jstring>(jo_type_name.get()) ) );
424  ::com::sun::star::uno::TypeDescription td( type_name );
425  if (! td.is())
426  {
427  throw BridgeRuntimeError(
428  "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
429  + "] UNO type not found: " + type_name
430  + jni.get_stack_trace() );
431  }
432  typelib_typedescriptionreference_acquire( td.get()->pWeakRef );
433  if (assign)
434  {
436  *static_cast<typelib_TypeDescriptionReference **>(uno_data) );
437  }
438  *static_cast<typelib_TypeDescriptionReference **>(uno_data) = td.get()->pWeakRef;
439  break;
440  }
441  case typelib_TypeClass_ANY:
442  {
443  JLocalAutoRef jo_out_holder( jni );
444  if (out_param)
445  {
446  jo_out_holder.reset(
447  jni->GetObjectArrayElement( static_cast<jobjectArray>(java_data.l), 0 ) );
448  jni.ensure_no_exception();
449  java_data.l = jo_out_holder.get();
450  }
451 
452  uno_Any * pAny = static_cast<uno_Any *>(uno_data);
453  if (java_data.l == nullptr) // null-ref maps to XInterface null-ref
454  {
455  if (assign)
456  uno_any_destruct( pAny, nullptr );
458  pAny, nullptr, getJniInfo()->m_XInterface_type_info->m_td.get(), nullptr );
459  break;
460  }
461 
462  JLocalAutoRef jo_type( jni );
463  JLocalAutoRef jo_wrapped_holder( jni );
464 
465  if (jni->IsInstanceOf( java_data.l, getJniInfo()->m_class_Any ))
466  {
467  // boxed any
468  jo_type.reset( jni->GetObjectField(
469  java_data.l, getJniInfo()->m_field_Any_type ) );
470  if (! jo_type.is())
471  {
472  throw BridgeRuntimeError(
473  "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
474  + "] no type set at com.sun.star.uno.Any!"
475  + jni.get_stack_trace() );
476  }
477  // wrapped value
478  jo_wrapped_holder.reset(
479  jni->GetObjectField(
480  java_data.l, getJniInfo()->m_field_Any_object ) );
481  java_data.l = jo_wrapped_holder.get();
482  }
483  else
484  {
485  // create type out of class
486  JLocalAutoRef jo_class( jni, jni->GetObjectClass( java_data.l ) );
487  jo_type.reset( create_type( jni, static_cast<jclass>(jo_class.get()) ) );
488  }
489 
490  // get type name
491  JLocalAutoRef jo_type_name(
492  jni, jni->GetObjectField(
493  jo_type.get(), getJniInfo()->m_field_Type_typeName ) );
494  jni.ensure_no_exception();
495  OUString type_name(
496  jstring_to_oustring( jni, static_cast<jstring>(jo_type_name.get()) ) );
497 
498  ::com::sun::star::uno::TypeDescription value_td( type_name );
499  if (! value_td.is())
500  {
501  throw BridgeRuntimeError(
502  "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
503  + "] UNO type not found: " + type_name
504  + jni.get_stack_trace() );
505  }
506  typelib_TypeClass type_class = value_td.get()->eTypeClass;
507 
508  if (assign)
509  {
510  uno_any_destruct( pAny, nullptr );
511  }
512  try
513  {
514  switch (type_class)
515  {
516  case typelib_TypeClass_VOID:
517  pAny->pData = &pAny->pReserved;
518  break;
519  case typelib_TypeClass_CHAR:
520  pAny->pData = &pAny->pReserved;
521  *static_cast<jchar *>(pAny->pData) = jni->CallCharMethodA(
522  java_data.l, getJniInfo()->m_method_Character_charValue, nullptr );
523  jni.ensure_no_exception();
524  break;
525  case typelib_TypeClass_BOOLEAN:
526  pAny->pData = &pAny->pReserved;
527  *static_cast<jboolean *>(pAny->pData) = jni->CallBooleanMethodA(
528  java_data.l, getJniInfo()->m_method_Boolean_booleanValue, nullptr );
529  jni.ensure_no_exception();
530  break;
531  case typelib_TypeClass_BYTE:
532  pAny->pData = &pAny->pReserved;
533  *static_cast<jbyte *>(pAny->pData) = jni->CallByteMethodA(
534  java_data.l, getJniInfo()->m_method_Byte_byteValue, nullptr );
535  jni.ensure_no_exception();
536  break;
537  case typelib_TypeClass_SHORT:
538  case typelib_TypeClass_UNSIGNED_SHORT:
539  pAny->pData = &pAny->pReserved;
540  *static_cast<jshort *>(pAny->pData) = jni->CallShortMethodA(
541  java_data.l, getJniInfo()->m_method_Short_shortValue, nullptr );
542  jni.ensure_no_exception();
543  break;
544  case typelib_TypeClass_LONG:
545  case typelib_TypeClass_UNSIGNED_LONG:
546  pAny->pData = &pAny->pReserved;
547  *static_cast<jint *>(pAny->pData) = jni->CallIntMethodA(
548  java_data.l, getJniInfo()->m_method_Integer_intValue, nullptr );
549  jni.ensure_no_exception();
550  break;
551  case typelib_TypeClass_HYPER:
552  case typelib_TypeClass_UNSIGNED_HYPER:
553  if (sizeof (sal_Int64) <= sizeof (void *))
554  {
555  pAny->pData = &pAny->pReserved;
556  *static_cast<jlong *>(pAny->pData) = jni->CallLongMethodA(
557  java_data.l, getJniInfo()->m_method_Long_longValue, nullptr );
558  jni.ensure_no_exception();
559  }
560  else
561  {
562  std::unique_ptr< rtl_mem > mem(
563  rtl_mem::allocate( sizeof (sal_Int64) ) );
564  *reinterpret_cast<jlong *>(mem.get()) = jni->CallLongMethodA(
565  java_data.l, getJniInfo()->m_method_Long_longValue, nullptr );
566  jni.ensure_no_exception();
567  pAny->pData = mem.release();
568  }
569  break;
570  case typelib_TypeClass_FLOAT:
571  if (sizeof (float) <= sizeof (void *))
572  {
573  pAny->pData = &pAny->pReserved;
574  *static_cast<jfloat *>(pAny->pData) = jni->CallFloatMethodA(
575  java_data.l, getJniInfo()->m_method_Float_floatValue, nullptr );
576  jni.ensure_no_exception();
577  }
578  else
579  {
580  std::unique_ptr< rtl_mem > mem(
581  rtl_mem::allocate( sizeof (float) ) );
582  *reinterpret_cast<jfloat *>(mem.get()) = jni->CallFloatMethodA(
583  java_data.l, getJniInfo()->m_method_Float_floatValue, nullptr );
584  jni.ensure_no_exception();
585  pAny->pData = mem.release();
586  }
587  break;
588  case typelib_TypeClass_DOUBLE:
589  if (sizeof (double) <= sizeof (void *))
590  {
591  pAny->pData = &pAny->pReserved;
592  *static_cast<jdouble *>(pAny->pData) =
593  jni->CallDoubleMethodA(
594  java_data.l,
595  getJniInfo()->m_method_Double_doubleValue, nullptr );
596  jni.ensure_no_exception();
597  }
598  else
599  {
600  std::unique_ptr< rtl_mem > mem(
601  rtl_mem::allocate( sizeof (double) ) );
602  *reinterpret_cast<jdouble *>(mem.get()) =
603  jni->CallDoubleMethodA(
604  java_data.l,
605  getJniInfo()->m_method_Double_doubleValue, nullptr );
606  jni.ensure_no_exception();
607  pAny->pData = mem.release();
608  }
609  break;
610  case typelib_TypeClass_STRING:
611  // opt: anies often contain strings; copy string directly
612  pAny->pReserved = nullptr;
613  pAny->pData = &pAny->pReserved;
615  jni, static_cast<rtl_uString **>(pAny->pData),
616  static_cast<jstring>(java_data.l) );
617  break;
618  case typelib_TypeClass_TYPE:
619  case typelib_TypeClass_ENUM:
620  case typelib_TypeClass_SEQUENCE:
621  case typelib_TypeClass_INTERFACE:
622  pAny->pData = &pAny->pReserved;
623  map_to_uno(
624  jni, pAny->pData, java_data,
625  value_td.get()->pWeakRef, nullptr,
626  false /* no assign */, false /* no out param */ );
627  break;
628  case typelib_TypeClass_STRUCT:
629  case typelib_TypeClass_EXCEPTION:
630  {
631  std::unique_ptr< rtl_mem > mem(
632  rtl_mem::allocate( value_td.get()->nSize ) );
633  map_to_uno(
634  jni, mem.get(), java_data, value_td.get()->pWeakRef, nullptr,
635  false /* no assign */, false /* no out param */ );
636  pAny->pData = mem.release();
637  break;
638  }
639  default:
640  {
641  throw BridgeRuntimeError(
642  "[map_to_uno():" + type_name
643  + "] unsupported value type of any!"
644  + jni.get_stack_trace() );
645  }
646  }
647  }
648  catch (...)
649  {
650  if (assign)
651  {
652  // restore to valid any
653  uno_any_construct( pAny, nullptr, nullptr, nullptr );
654  }
655  throw;
656  }
657  typelib_typedescriptionreference_acquire( value_td.get()->pWeakRef );
658  pAny->pType = value_td.get()->pWeakRef;
659  break;
660  }
661  case typelib_TypeClass_ENUM:
662  {
663  JLocalAutoRef jo_out_holder( jni );
664  if (out_param)
665  {
666  jo_out_holder.reset(
667  jni->GetObjectArrayElement( static_cast<jobjectArray>(java_data.l), 0 ) );
668  jni.ensure_no_exception();
669  java_data.l = jo_out_holder.get();
670  }
671  if (java_data.l == nullptr)
672  {
673  throw BridgeRuntimeError(
674  "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
675  + "] null-ref given!" + jni.get_stack_trace() );
676  }
677 
678  *static_cast<jint *>(uno_data) = jni->GetIntField(
679  java_data.l, getJniInfo()->m_field_Enum_m_value );
680  break;
681  }
682  case typelib_TypeClass_STRUCT:
683  case typelib_TypeClass_EXCEPTION:
684  {
685  JLocalAutoRef jo_out_holder( jni );
686  if (out_param)
687  {
688  jo_out_holder.reset(
689  jni->GetObjectArrayElement( static_cast<jobjectArray>(java_data.l), 0 ) );
690  jni.ensure_no_exception();
691  java_data.l = jo_out_holder.get();
692  }
693  if (java_data.l == nullptr)
694  {
695  throw BridgeRuntimeError(
696  "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
697  + "] null-ref given!" + jni.get_stack_trace() );
698  }
699 
700  if (info == nullptr)
701  info = getJniInfo()->get_type_info( jni, type );
702  JNI_compound_type_info const * comp_info =
703  static_cast< JNI_compound_type_info const * >( info );
704 
705  typelib_CompoundTypeDescription * comp_td =
706  reinterpret_cast<typelib_CompoundTypeDescription *>(comp_info->m_td.get());
707  bool polymorphic
708  = comp_td->aBase.eTypeClass == typelib_TypeClass_STRUCT
709  && reinterpret_cast< typelib_StructTypeDescription * >(
710  comp_td)->pParameterizedTypes != nullptr;
711 
712  sal_Int32 nPos = 0;
713  sal_Int32 nMembers = comp_td->nMembers;
714  try
715  {
716  if (comp_td->pBaseTypeDescription != nullptr)
717  {
718  map_to_uno(
719  jni, uno_data, java_data,
720  comp_td->pBaseTypeDescription->aBase.pWeakRef,
721  comp_info->m_base,
722  assign, false /* no out param */ );
723  }
724 
725  for ( ; nPos < nMembers; ++nPos )
726  {
727  void * p = static_cast<char *>(uno_data) + comp_td->pMemberOffsets[ nPos ];
728  typelib_TypeDescriptionReference * member_type =
729  comp_td->ppTypeRefs[ nPos ];
730  jfieldID field_id = comp_info->m_fields[ nPos ];
731  bool parameterizedType = polymorphic
732  && reinterpret_cast< typelib_StructTypeDescription * >(
733  comp_td)->pParameterizedTypes[nPos];
734  switch (member_type->eTypeClass)
735  {
736  case typelib_TypeClass_CHAR:
737  if (parameterizedType) {
738  JLocalAutoRef jo(
739  jni, jni->GetObjectField( java_data.l, field_id ) );
740  if ( jo.get() == nullptr ) {
741  *static_cast<jchar *>(p) = 0;
742  } else {
743  jvalue val;
744  val.l = jo.get();
745  map_to_uno(
746  jni, p, val, member_type, nullptr, assign, false,
747  true );
748  }
749  } else {
750  *static_cast<jchar *>(p) = jni->GetCharField(
751  java_data.l, field_id );
752  }
753  break;
754  case typelib_TypeClass_BOOLEAN:
755  if (parameterizedType) {
756  JLocalAutoRef jo(
757  jni, jni->GetObjectField( java_data.l, field_id ) );
758  if ( jo.get() == nullptr ) {
759  *static_cast<jboolean *>(p) = false;
760  } else {
761  jvalue val;
762  val.l = jo.get();
763  map_to_uno(
764  jni, p, val, member_type, nullptr, assign, false,
765  true );
766  }
767  } else {
768  *static_cast<jboolean *>(p) = jni->GetBooleanField(
769  java_data.l, field_id );
770  }
771  break;
772  case typelib_TypeClass_BYTE:
773  if (parameterizedType) {
774  JLocalAutoRef jo(
775  jni, jni->GetObjectField( java_data.l, field_id ) );
776  if ( jo.get() == nullptr ) {
777  *static_cast<jbyte *>(p) = 0;
778  } else {
779  jvalue val;
780  val.l = jo.get();
781  map_to_uno(
782  jni, p, val, member_type, nullptr, assign, false,
783  true );
784  }
785  } else {
786  *static_cast<jbyte *>(p) = jni->GetByteField(
787  java_data.l, field_id );
788  }
789  break;
790  case typelib_TypeClass_SHORT:
791  case typelib_TypeClass_UNSIGNED_SHORT:
792  if (parameterizedType) {
793  JLocalAutoRef jo(
794  jni, jni->GetObjectField( java_data.l, field_id ) );
795  if ( jo.get() == nullptr ) {
796  *static_cast<jshort *>(p) = 0;
797  } else {
798  jvalue val;
799  val.l = jo.get();
800  map_to_uno(
801  jni, p, val, member_type, nullptr, assign, false,
802  true );
803  }
804  } else {
805  *static_cast<jshort *>(p) = jni->GetShortField(
806  java_data.l, field_id );
807  }
808  break;
809  case typelib_TypeClass_LONG:
810  case typelib_TypeClass_UNSIGNED_LONG:
811  if (parameterizedType) {
812  JLocalAutoRef jo(
813  jni, jni->GetObjectField( java_data.l, field_id ) );
814  if ( jo.get() == nullptr ) {
815  *static_cast<jint *>(p) = 0;
816  } else {
817  jvalue val;
818  val.l = jo.get();
819  map_to_uno(
820  jni, p, val, member_type, nullptr, assign, false,
821  true );
822  }
823  } else {
824  *static_cast<jint *>(p) = jni->GetIntField( java_data.l, field_id );
825  }
826  break;
827  case typelib_TypeClass_HYPER:
828  case typelib_TypeClass_UNSIGNED_HYPER:
829  if (parameterizedType) {
830  JLocalAutoRef jo(
831  jni, jni->GetObjectField( java_data.l, field_id ) );
832  if ( jo.get() == nullptr ) {
833  *static_cast<jlong *>(p) = 0;
834  } else {
835  jvalue val;
836  val.l = jo.get();
837  map_to_uno(
838  jni, p, val, member_type, nullptr, assign, false,
839  true );
840  }
841  } else {
842  *static_cast<jlong *>(p) = jni->GetLongField(
843  java_data.l, field_id );
844  }
845  break;
846  case typelib_TypeClass_FLOAT:
847  if (parameterizedType) {
848  JLocalAutoRef jo(
849  jni, jni->GetObjectField( java_data.l, field_id ) );
850  if ( jo.get() == nullptr ) {
851  *static_cast<jfloat *>(p) = 0;
852  } else {
853  jvalue val;
854  val.l = jo.get();
855  map_to_uno(
856  jni, p, val, member_type, nullptr, assign, false,
857  true );
858  }
859  } else {
860  *static_cast<jfloat *>(p) = jni->GetFloatField(
861  java_data.l, field_id );
862  }
863  break;
864  case typelib_TypeClass_DOUBLE:
865  if (parameterizedType) {
866  JLocalAutoRef jo(
867  jni, jni->GetObjectField( java_data.l, field_id ) );
868  if ( jo.get() == nullptr ) {
869  *static_cast<jdouble *>(p) = 0;
870  } else {
871  jvalue val;
872  val.l = jo.get();
873  map_to_uno(
874  jni, p, val, member_type, nullptr, assign, false,
875  true );
876  }
877  } else {
878  *static_cast<jdouble *>(p) = jni->GetDoubleField(
879  java_data.l, field_id );
880  }
881  break;
882  default:
883  {
884  JLocalAutoRef jo_field( jni );
885  bool checkNull;
886  if (field_id == nullptr)
887  {
888  // special for Message: call Throwable.getMessage()
889  assert(
890  type_equals(
891  type,
892  getJniInfo()->m_Exception_type.getTypeLibType() )
893  || type_equals(
894  type,
896  getTypeLibType() ) );
897  assert( nPos == 0 ); // first member
898  // call getMessage()
899  jo_field.reset(
900  jni->CallObjectMethodA(
901  java_data.l,
902  getJniInfo()->m_method_Throwable_getMessage, nullptr )
903  );
904  jni.ensure_no_exception();
905  checkNull = true;
906  }
907  else
908  {
909  jo_field.reset(
910  jni->GetObjectField( java_data.l, field_id ) );
911  checkNull = parameterizedType;
912  }
913  if (checkNull && !jo_field.is()) {
914  createDefaultUnoValue(jni, p, member_type, nullptr, assign);
915  } else {
916  jvalue val;
917  val.l = jo_field.get();
918  map_to_uno(
919  jni, p, val, member_type, nullptr,
920  assign, false /* no out param */ );
921  }
922  break;
923  }
924  }
925  }
926  }
927  catch (...)
928  {
929  if (! assign)
930  {
931  // cleanup
932  for ( sal_Int32 nCleanup = 0; nCleanup < nPos; ++nCleanup )
933  {
934  void * p =
935  static_cast<char *>(uno_data) + comp_td->pMemberOffsets[ nCleanup ];
937  p, comp_td->ppTypeRefs[ nCleanup ], nullptr );
938  }
939  if (comp_td->pBaseTypeDescription != nullptr)
940  {
942  uno_data, &comp_td->pBaseTypeDescription->aBase, nullptr );
943  }
944  }
945  throw;
946  }
947  break;
948  }
949  case typelib_TypeClass_SEQUENCE:
950  {
951  JLocalAutoRef jo_out_holder( jni );
952  if (out_param)
953  {
954  jo_out_holder.reset(
955  jni->GetObjectArrayElement( static_cast<jobjectArray>(java_data.l), 0 ) );
956  jni.ensure_no_exception();
957  java_data.l = jo_out_holder.get();
958  }
959  if (java_data.l == nullptr)
960  {
961  throw BridgeRuntimeError(
962  "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
963  + "] null-ref given!" + jni.get_stack_trace() );
964  }
965 
966  TypeDescr td( type );
967  typelib_TypeDescriptionReference * element_type =
968  reinterpret_cast<typelib_IndirectTypeDescription *>(td.get())->pType;
969 
970  std::unique_ptr< rtl_mem > seq;
971  sal_Int32 nElements = jni->GetArrayLength( static_cast<jarray>(java_data.l) );
972 
973  switch (element_type->eTypeClass)
974  {
975  case typelib_TypeClass_CHAR:
976  seq = seq_allocate( nElements, sizeof (sal_Unicode) );
977  jni->GetCharArrayRegion(
978  static_cast<jcharArray>(java_data.l), 0, nElements,
979  reinterpret_cast<jchar *>(reinterpret_cast<uno_Sequence *>(seq.get())->elements) );
980  jni.ensure_no_exception();
981  break;
982  case typelib_TypeClass_BOOLEAN:
983  seq = seq_allocate( nElements, sizeof (sal_Bool) );
984  jni->GetBooleanArrayRegion(
985  static_cast<jbooleanArray>(java_data.l), 0, nElements,
986  reinterpret_cast<jboolean *>(reinterpret_cast<uno_Sequence *>(seq.get())->elements) );
987  jni.ensure_no_exception();
988  break;
989  case typelib_TypeClass_BYTE:
990  seq = seq_allocate( nElements, sizeof (sal_Int8) );
991  jni->GetByteArrayRegion(
992  static_cast<jbyteArray>(java_data.l), 0, nElements,
993  reinterpret_cast<jbyte *>(reinterpret_cast<uno_Sequence *>(seq.get())->elements) );
994  jni.ensure_no_exception();
995  break;
996  case typelib_TypeClass_SHORT:
997  case typelib_TypeClass_UNSIGNED_SHORT:
998  seq = seq_allocate( nElements, sizeof (sal_Int16) );
999  jni->GetShortArrayRegion(
1000  static_cast<jshortArray>(java_data.l), 0, nElements,
1001  reinterpret_cast<jshort *>(reinterpret_cast<uno_Sequence *>(seq.get())->elements) );
1002  jni.ensure_no_exception();
1003  break;
1004  case typelib_TypeClass_LONG:
1005  case typelib_TypeClass_UNSIGNED_LONG:
1006  seq = seq_allocate( nElements, sizeof (sal_Int32) );
1007  jni->GetIntArrayRegion(
1008  static_cast<jintArray>(java_data.l), 0, nElements,
1009  reinterpret_cast<jint *>(reinterpret_cast<uno_Sequence *>(seq.get())->elements) );
1010  jni.ensure_no_exception();
1011  break;
1012  case typelib_TypeClass_HYPER:
1013  case typelib_TypeClass_UNSIGNED_HYPER:
1014  seq = seq_allocate( nElements, sizeof (sal_Int64) );
1015  jni->GetLongArrayRegion(
1016  static_cast<jlongArray>(java_data.l), 0, nElements,
1017  reinterpret_cast<jlong *>(reinterpret_cast<uno_Sequence *>(seq.get())->elements) );
1018  jni.ensure_no_exception();
1019  break;
1020  case typelib_TypeClass_FLOAT:
1021  seq = seq_allocate( nElements, sizeof (float) );
1022  jni->GetFloatArrayRegion(
1023  static_cast<jfloatArray>(java_data.l), 0, nElements,
1024  reinterpret_cast<jfloat *>(reinterpret_cast<uno_Sequence *>(seq.get())->elements) );
1025  jni.ensure_no_exception();
1026  break;
1027  case typelib_TypeClass_DOUBLE:
1028  seq = seq_allocate( nElements, sizeof (double) );
1029  jni->GetDoubleArrayRegion(
1030  static_cast<jdoubleArray>(java_data.l), 0, nElements,
1031  reinterpret_cast<jdouble *>(reinterpret_cast<uno_Sequence *>(seq.get())->elements) );
1032  jni.ensure_no_exception();
1033  break;
1034  case typelib_TypeClass_STRING:
1035  case typelib_TypeClass_TYPE:
1036  case typelib_TypeClass_ANY:
1037  case typelib_TypeClass_ENUM:
1038  case typelib_TypeClass_STRUCT:
1039  case typelib_TypeClass_EXCEPTION:
1040  case typelib_TypeClass_SEQUENCE:
1041  case typelib_TypeClass_INTERFACE:
1042  {
1043  TypeDescr element_td( element_type );
1044  seq = seq_allocate( nElements, element_td.get()->nSize );
1045 
1046  JNI_type_info const * element_info;
1047  if (element_type->eTypeClass == typelib_TypeClass_STRUCT ||
1048  element_type->eTypeClass == typelib_TypeClass_EXCEPTION ||
1049  element_type->eTypeClass == typelib_TypeClass_INTERFACE)
1050  {
1051  element_info =
1052  getJniInfo()->get_type_info( jni, element_td.get() );
1053  }
1054  else
1055  {
1056  element_info = nullptr;
1057  }
1058 
1059  for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
1060  {
1061  try
1062  {
1063  JLocalAutoRef jo(
1064  jni, jni->GetObjectArrayElement(
1065  static_cast<jobjectArray>(java_data.l), nPos ) );
1066  jni.ensure_no_exception();
1067  jvalue val;
1068  val.l = jo.get();
1069  void * p =
1070  reinterpret_cast<uno_Sequence *>(seq.get())->elements +
1071  (nPos * element_td.get()->nSize);
1072  map_to_uno(
1073  jni, p, val, element_td.get()->pWeakRef, element_info,
1074  false /* no assign */, false /* no out param */ );
1075  }
1076  catch (...)
1077  {
1078  // cleanup
1079  for ( sal_Int32 nCleanPos = 0;
1080  nCleanPos < nPos; ++nCleanPos )
1081  {
1082  void * p =
1083  reinterpret_cast<uno_Sequence *>(seq.get())->elements +
1084  (nCleanPos * element_td.get()->nSize);
1085  uno_destructData( p, element_td.get(), nullptr );
1086  }
1087  throw;
1088  }
1089  }
1090  break;
1091  }
1092  default:
1093  {
1094  throw BridgeRuntimeError(
1095  "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
1096  + "] unsupported sequence element type: "
1097  + OUString::unacquired( &element_type->pTypeName )
1098  + jni.get_stack_trace() );
1099  }
1100  }
1101 
1102  if (assign)
1103  uno_destructData( uno_data, td.get(), nullptr );
1104  *static_cast<uno_Sequence **>(uno_data) = reinterpret_cast<uno_Sequence *>(seq.release());
1105  break;
1106  }
1107  case typelib_TypeClass_INTERFACE:
1108  {
1109  JLocalAutoRef jo_out_holder( jni );
1110  if (out_param)
1111  {
1112  jo_out_holder.reset(
1113  jni->GetObjectArrayElement( static_cast<jobjectArray>(java_data.l), 0 ) );
1114  jni.ensure_no_exception();
1115  java_data.l = jo_out_holder.get();
1116  }
1117 
1118  if (java_data.l == nullptr) // null-ref
1119  {
1120  if (assign)
1121  {
1122  uno_Interface * p = *static_cast<uno_Interface **>(uno_data);
1123  if (p != nullptr)
1124  (*p->release)( p );
1125  }
1126  *static_cast<uno_Interface **>(uno_data) = nullptr;
1127  }
1128  else
1129  {
1130  if (info == nullptr)
1131  info = getJniInfo()->get_type_info( jni, type );
1132  JNI_interface_type_info const * iface_info =
1133  static_cast< JNI_interface_type_info const * >( info );
1134  uno_Interface * pUnoI = map_to_uno( jni, java_data.l, iface_info );
1135  if (assign)
1136  {
1137  uno_Interface * p = *static_cast<uno_Interface **>(uno_data);
1138  if (p != nullptr)
1139  (*p->release)( p );
1140  }
1141  *static_cast<uno_Interface **>(uno_data) = pUnoI;
1142  }
1143  break;
1144  }
1145  default:
1146  {
1147  throw BridgeRuntimeError(
1148  "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
1149  + "] unsupported type!" + jni.get_stack_trace() );
1150  }
1151  }
1152 }
1153 
1154 
1156  JNI_context const & jni,
1157  jvalue * java_data, void const * uno_data,
1158  typelib_TypeDescriptionReference * type,
1159  JNI_type_info const * info /* maybe 0 */,
1160  bool in_param, bool out_param,
1161  bool special_wrapped_integral_types ) const
1162 {
1163  // 4th param of Set*ArrayRegion changed from pointer to non-const to pointer
1164  // to const between <http://docs.oracle.com/javase/6/docs/technotes/guides/
1165  // jni/spec/functions.html#wp22933> and <http://docs.oracle.com/javase/7/
1166  // docs/technotes/guides/jni/spec/functions.html#wp22933>; work around that
1167  // difference in a way that doesn't trigger loplugin:redundantcast:
1168  void * data = const_cast<void *>(uno_data);
1169 
1170  switch (type->eTypeClass)
1171  {
1172  case typelib_TypeClass_CHAR:
1173  if (out_param)
1174  {
1175  if (java_data->l == nullptr)
1176  {
1177  JLocalAutoRef jo_ar( jni, jni->NewCharArray( 1 ) );
1178  jni.ensure_no_exception();
1179  if (in_param)
1180  {
1181  jni->SetCharArrayRegion(
1182  static_cast<jcharArray>(jo_ar.get()), 0, 1, static_cast<jchar *>(data) );
1183  jni.ensure_no_exception();
1184  }
1185  java_data->l = jo_ar.release();
1186  }
1187  else
1188  {
1189  if (in_param)
1190  {
1191  jni->SetCharArrayRegion(
1192  static_cast<jcharArray>(java_data->l), 0, 1, static_cast<jchar *>(data) );
1193  jni.ensure_no_exception();
1194  }
1195  }
1196  }
1197  else if (special_wrapped_integral_types)
1198  {
1199  jvalue arg;
1200  arg.c = *static_cast<jchar const *>(uno_data);
1201  java_data->l = jni->NewObjectA(
1202  getJniInfo()->m_class_Character,
1203  getJniInfo()->m_ctor_Character_with_char, &arg );
1204  jni.ensure_no_exception();
1205  }
1206  else
1207  {
1208  java_data->c = *static_cast<jchar const *>(uno_data);
1209  }
1210  break;
1211  case typelib_TypeClass_BOOLEAN:
1212  if (out_param)
1213  {
1214  if (java_data->l == nullptr)
1215  {
1216  JLocalAutoRef jo_ar( jni, jni->NewBooleanArray( 1 ) );
1217  jni.ensure_no_exception();
1218  if (in_param)
1219  {
1220  jni->SetBooleanArrayRegion(
1221  static_cast<jbooleanArray>(jo_ar.get()),
1222  0, 1, static_cast<jboolean *>(data) );
1223  jni.ensure_no_exception();
1224  }
1225  java_data->l = jo_ar.release();
1226  }
1227  else
1228  {
1229  if (in_param)
1230  {
1231  jni->SetBooleanArrayRegion(
1232  static_cast<jbooleanArray>(java_data->l),
1233  0, 1, static_cast<jboolean *>(data) );
1234  jni.ensure_no_exception();
1235  }
1236  }
1237  }
1238  else if (special_wrapped_integral_types)
1239  {
1240  jvalue arg;
1241  arg.z = *static_cast<jboolean const *>(uno_data);
1242  java_data->l = jni->NewObjectA(
1243  getJniInfo()->m_class_Boolean,
1244  getJniInfo()->m_ctor_Boolean_with_boolean, &arg );
1245  jni.ensure_no_exception();
1246  }
1247  else
1248  {
1249  java_data->z = *static_cast<jboolean const *>(uno_data);
1250  }
1251  break;
1252  case typelib_TypeClass_BYTE:
1253  if (out_param)
1254  {
1255  if (java_data->l == nullptr)
1256  {
1257  JLocalAutoRef jo_ar( jni, jni->NewByteArray( 1 ) );
1258  jni.ensure_no_exception();
1259  if (in_param)
1260  {
1261  jni->SetByteArrayRegion(
1262  static_cast<jbyteArray>(jo_ar.get()), 0, 1, static_cast<jbyte *>(data) );
1263  jni.ensure_no_exception();
1264  }
1265  java_data->l = jo_ar.release();
1266  }
1267  else
1268  {
1269  if (in_param)
1270  {
1271  jni->SetByteArrayRegion(
1272  static_cast<jbyteArray>(java_data->l), 0, 1, static_cast<jbyte *>(data) );
1273  jni.ensure_no_exception();
1274  }
1275  }
1276  }
1277  else if (special_wrapped_integral_types)
1278  {
1279  jvalue arg;
1280  arg.b = *static_cast<jbyte const *>(uno_data);
1281  java_data->l = jni->NewObjectA(
1282  getJniInfo()->m_class_Byte,
1283  getJniInfo()->m_ctor_Byte_with_byte, &arg );
1284  jni.ensure_no_exception();
1285  }
1286  else
1287  {
1288  java_data->b = *static_cast<jbyte const *>(uno_data);
1289  }
1290  break;
1291  case typelib_TypeClass_SHORT:
1292  case typelib_TypeClass_UNSIGNED_SHORT:
1293  if (out_param)
1294  {
1295  if (java_data->l == nullptr)
1296  {
1297  JLocalAutoRef jo_ar( jni, jni->NewShortArray( 1 ) );
1298  jni.ensure_no_exception();
1299  if (in_param)
1300  {
1301  jni->SetShortArrayRegion(
1302  static_cast<jshortArray>(jo_ar.get()), 0, 1, static_cast<jshort *>(data) );
1303  jni.ensure_no_exception();
1304  }
1305  java_data->l = jo_ar.release();
1306  }
1307  else
1308  {
1309  if (in_param)
1310  {
1311  jni->SetShortArrayRegion(
1312  static_cast<jshortArray>(java_data->l), 0, 1, static_cast<jshort *>(data) );
1313  jni.ensure_no_exception();
1314  }
1315  }
1316  }
1317  else if (special_wrapped_integral_types)
1318  {
1319  jvalue arg;
1320  arg.s = *static_cast<jshort const *>(uno_data);
1321  java_data->l = jni->NewObjectA(
1322  getJniInfo()->m_class_Short,
1323  getJniInfo()->m_ctor_Short_with_short, &arg );
1324  jni.ensure_no_exception();
1325  }
1326  else
1327  {
1328  java_data->s = *static_cast<jshort const *>(uno_data);
1329  }
1330  break;
1331  case typelib_TypeClass_LONG:
1332  case typelib_TypeClass_UNSIGNED_LONG:
1333  if (out_param)
1334  {
1335  if (java_data->l == nullptr)
1336  {
1337  JLocalAutoRef jo_ar( jni, jni->NewIntArray( 1 ) );
1338  jni.ensure_no_exception();
1339  if (in_param)
1340  {
1341  jni->SetIntArrayRegion(
1342  static_cast<jintArray>(jo_ar.get()), 0, 1, static_cast<jint *>(data) );
1343  jni.ensure_no_exception();
1344  }
1345  java_data->l = jo_ar.release();
1346  }
1347  else
1348  {
1349  if (in_param)
1350  {
1351  jni->SetIntArrayRegion(
1352  static_cast<jintArray>(java_data->l), 0, 1, static_cast<jint *>(data) );
1353  jni.ensure_no_exception();
1354  }
1355  }
1356  }
1357  else if (special_wrapped_integral_types)
1358  {
1359  jvalue arg;
1360  arg.i = *static_cast<jint const *>(uno_data);
1361  java_data->l = jni->NewObjectA(
1362  getJniInfo()->m_class_Integer,
1363  getJniInfo()->m_ctor_Integer_with_int, &arg );
1364  jni.ensure_no_exception();
1365  }
1366  else
1367  {
1368  java_data->i = *static_cast<jint const *>(uno_data);
1369  }
1370  break;
1371  case typelib_TypeClass_HYPER:
1372  case typelib_TypeClass_UNSIGNED_HYPER:
1373  if (out_param)
1374  {
1375  if (java_data->l == nullptr)
1376  {
1377  JLocalAutoRef jo_ar( jni, jni->NewLongArray( 1 ) );
1378  jni.ensure_no_exception();
1379  if (in_param)
1380  {
1381  jni->SetLongArrayRegion(
1382  static_cast<jlongArray>(jo_ar.get()), 0, 1, static_cast<jlong *>(data) );
1383  jni.ensure_no_exception();
1384  }
1385  java_data->l = jo_ar.release();
1386  }
1387  else
1388  {
1389  if (in_param)
1390  {
1391  jni->SetLongArrayRegion(
1392  static_cast<jlongArray>(java_data->l), 0, 1, static_cast<jlong *>(data) );
1393  jni.ensure_no_exception();
1394  }
1395  }
1396  }
1397  else if (special_wrapped_integral_types)
1398  {
1399  jvalue arg;
1400  arg.j = *static_cast<jlong const *>(uno_data);
1401  java_data->l = jni->NewObjectA(
1402  getJniInfo()->m_class_Long,
1403  getJniInfo()->m_ctor_Long_with_long, &arg );
1404  jni.ensure_no_exception();
1405  }
1406  else
1407  {
1408  java_data->j = *static_cast<jlong const *>(uno_data);
1409  }
1410  break;
1411  case typelib_TypeClass_FLOAT:
1412  if (out_param)
1413  {
1414  if (java_data->l == nullptr)
1415  {
1416  JLocalAutoRef jo_ar( jni, jni->NewFloatArray( 1 ) );
1417  jni.ensure_no_exception();
1418  if (in_param)
1419  {
1420  jni->SetFloatArrayRegion(
1421  static_cast<jfloatArray>(jo_ar.get()), 0, 1, static_cast<jfloat *>(data) );
1422  jni.ensure_no_exception();
1423  }
1424  java_data->l = jo_ar.release();
1425  }
1426  else
1427  {
1428  if (in_param)
1429  {
1430  jni->SetFloatArrayRegion(
1431  static_cast<jfloatArray>(java_data->l), 0, 1, static_cast<jfloat *>(data) );
1432  jni.ensure_no_exception();
1433  }
1434  }
1435  }
1436  else if (special_wrapped_integral_types)
1437  {
1438  jvalue arg;
1439  arg.f = *static_cast<jfloat const *>(uno_data);
1440  java_data->l = jni->NewObjectA(
1441  getJniInfo()->m_class_Float,
1442  getJniInfo()->m_ctor_Float_with_float, &arg );
1443  jni.ensure_no_exception();
1444  }
1445  else
1446  {
1447  java_data->f = *static_cast<jfloat const *>(uno_data);
1448  }
1449  break;
1450  case typelib_TypeClass_DOUBLE:
1451  if (out_param)
1452  {
1453  if (java_data->l == nullptr)
1454  {
1455  JLocalAutoRef jo_ar( jni, jni->NewDoubleArray( 1 ) );
1456  jni.ensure_no_exception();
1457  if (in_param)
1458  {
1459  jni->SetDoubleArrayRegion(
1460  static_cast<jdoubleArray>(jo_ar.get()),
1461  0, 1, static_cast<jdouble *>(data) );
1462  jni.ensure_no_exception();
1463  }
1464  java_data->l = jo_ar.release();
1465  }
1466  else
1467  {
1468  if (in_param)
1469  {
1470  jni->SetDoubleArrayRegion(
1471  static_cast<jdoubleArray>(java_data->l),
1472  0, 1, static_cast<jdouble *>(data) );
1473  jni.ensure_no_exception();
1474  }
1475  }
1476  }
1477  else if (special_wrapped_integral_types)
1478  {
1479  jvalue arg;
1480  arg.d = *static_cast<double const *>(uno_data);
1481  java_data->l = jni->NewObjectA(
1482  getJniInfo()->m_class_Double,
1483  getJniInfo()->m_ctor_Double_with_double, &arg );
1484  jni.ensure_no_exception();
1485  }
1486  else
1487  {
1488  java_data->d = *static_cast<jdouble const *>(uno_data);
1489  }
1490  break;
1491  case typelib_TypeClass_STRING:
1492  {
1493  if (out_param)
1494  {
1495  JLocalAutoRef jo_in( jni );
1496  if (in_param)
1497  {
1498  jo_in.reset(
1500  jni, *static_cast<rtl_uString * const *>(uno_data) ) );
1501  }
1502  if (java_data->l == nullptr)
1503  {
1504  java_data->l = jni->NewObjectArray(
1505  1, getJniInfo()->m_class_String, jo_in.get() );
1506  jni.ensure_no_exception();
1507  }
1508  else
1509  {
1510  jni->SetObjectArrayElement(
1511  static_cast<jobjectArray>(java_data->l), 0, jo_in.get() );
1512  jni.ensure_no_exception();
1513  }
1514  }
1515  else
1516  {
1517  assert( in_param );
1518  java_data->l =
1519  ustring_to_jstring( jni, *static_cast<rtl_uString * const *>(uno_data) );
1520  }
1521  break;
1522  }
1523  case typelib_TypeClass_TYPE:
1524  {
1525  if (out_param)
1526  {
1527  JLocalAutoRef jo_in( jni );
1528  if (in_param)
1529  {
1530  jo_in.reset(
1531  create_type(
1532  jni,
1533  *static_cast<typelib_TypeDescriptionReference * const *>(uno_data) )
1534  );
1535  }
1536  if (java_data->l == nullptr)
1537  {
1538  java_data->l = jni->NewObjectArray(
1539  1, getJniInfo()->m_class_Type, jo_in.get() );
1540  jni.ensure_no_exception();
1541  }
1542  else
1543  {
1544  jni->SetObjectArrayElement(
1545  static_cast<jobjectArray>(java_data->l), 0, jo_in.get() );
1546  jni.ensure_no_exception();
1547  }
1548  }
1549  else
1550  {
1551  assert( in_param );
1552  java_data->l =
1553  create_type(
1554  jni,
1555  *static_cast<typelib_TypeDescriptionReference * const *>(uno_data) );
1556  }
1557  break;
1558  }
1559  case typelib_TypeClass_ANY:
1560  {
1561  JLocalAutoRef jo_any( jni );
1562  if (in_param)
1563  {
1564  uno_Any const * pAny = static_cast<uno_Any const *>(uno_data);
1565  switch (pAny->pType->eTypeClass)
1566  {
1567  case typelib_TypeClass_VOID:
1568  jo_any.reset(
1569  jni->NewLocalRef( getJniInfo()->m_object_Any_VOID ) );
1570  break;
1571  case typelib_TypeClass_UNSIGNED_SHORT:
1572  {
1573  jvalue args[ 2 ];
1574  args[ 0 ].s = *static_cast<jshort const *>(pAny->pData);
1575  JLocalAutoRef jo_val(
1576  jni, jni->NewObjectA(
1577  getJniInfo()->m_class_Short,
1578  getJniInfo()->m_ctor_Short_with_short, args ) );
1579  jni.ensure_no_exception();
1580  // box up in com.sun.star.uno.Any
1581  args[ 0 ].l = getJniInfo()->m_object_Type_UNSIGNED_SHORT;
1582  args[ 1 ].l = jo_val.get();
1583  jo_any.reset(
1584  jni->NewObjectA(
1585  getJniInfo()->m_class_Any,
1586  getJniInfo()->m_ctor_Any_with_Type_Object, args ) );
1587  jni.ensure_no_exception();
1588  break;
1589  }
1590  case typelib_TypeClass_UNSIGNED_LONG:
1591  {
1592  jvalue args[ 2 ];
1593  args[ 0 ].i = *static_cast<jint const *>(pAny->pData);
1594  JLocalAutoRef jo_val(
1595  jni, jni->NewObjectA(
1596  getJniInfo()->m_class_Integer,
1597  getJniInfo()->m_ctor_Integer_with_int, args ) );
1598  jni.ensure_no_exception();
1599  // box up in com.sun.star.uno.Any
1600  args[ 0 ].l = getJniInfo()->m_object_Type_UNSIGNED_LONG;
1601  args[ 1 ].l = jo_val.get();
1602  jo_any.reset(
1603  jni->NewObjectA(
1604  getJniInfo()->m_class_Any,
1605  getJniInfo()->m_ctor_Any_with_Type_Object, args ) );
1606  jni.ensure_no_exception();
1607  break;
1608  }
1609  case typelib_TypeClass_UNSIGNED_HYPER:
1610  {
1611  jvalue args[ 2 ];
1612  args[ 0 ].j = *static_cast<jlong const *>(pAny->pData);
1613  JLocalAutoRef jo_val(
1614  jni, jni->NewObjectA(
1615  getJniInfo()->m_class_Long,
1616  getJniInfo()->m_ctor_Long_with_long, args ) );
1617  jni.ensure_no_exception();
1618  // box up in com.sun.star.uno.Any
1619  args[ 0 ].l = getJniInfo()->m_object_Type_UNSIGNED_HYPER;
1620  args[ 1 ].l = jo_val.get();
1621  jo_any.reset(
1622  jni->NewObjectA(
1623  getJniInfo()->m_class_Any,
1624  getJniInfo()->m_ctor_Any_with_Type_Object, args ) );
1625  jni.ensure_no_exception();
1626  break;
1627  }
1628  case typelib_TypeClass_STRING: // opt strings
1629  jo_any.reset( ustring_to_jstring(
1630  jni, static_cast<rtl_uString *>(pAny->pReserved) ) );
1631  break;
1632  case typelib_TypeClass_SEQUENCE:
1633  {
1634  jvalue java_data2;
1635  // prefetch sequence td
1636  TypeDescr seq_td( pAny->pType );
1637  map_to_java(
1638  jni, &java_data2, pAny->pData, seq_td.get()->pWeakRef, nullptr,
1639  true /* in */, false /* no out */,
1640  true /* create integral wrappers */ );
1641  jo_any.reset( java_data2.l );
1642 
1643  // determine inner element type
1644  ::com::sun::star::uno::Type element_type(
1645  reinterpret_cast<typelib_IndirectTypeDescription *>(seq_td.get())->pType );
1646  while (element_type.getTypeLibType()->eTypeClass ==
1647  typelib_TypeClass_SEQUENCE)
1648  {
1649  TypeDescr element_td( element_type.getTypeLibType() );
1651  reinterpret_cast< typelib_TypeDescriptionReference ** >(
1652  &element_type ),
1653  reinterpret_cast<typelib_IndirectTypeDescription *>(element_td.get())
1654  ->pType );
1655  }
1656  // box up only if unsigned element type
1657  switch (element_type.getTypeLibType()->eTypeClass)
1658  {
1659  case typelib_TypeClass_UNSIGNED_SHORT:
1660  case typelib_TypeClass_UNSIGNED_LONG:
1661  case typelib_TypeClass_UNSIGNED_HYPER:
1662  {
1663  jvalue args[ 2 ];
1664  JLocalAutoRef jo_type(
1665  jni, create_type( jni, seq_td.get()->pWeakRef ) );
1666  args[ 0 ].l = jo_type.get();
1667  args[ 1 ].l = jo_any.get();
1668  jo_any.reset(
1669  jni->NewObjectA(
1670  getJniInfo()->m_class_Any,
1671  getJniInfo()->m_ctor_Any_with_Type_Object, args ) );
1672  jni.ensure_no_exception();
1673  break;
1674  }
1675  default:
1676  break;
1677  }
1678  break;
1679  }
1680  case typelib_TypeClass_INTERFACE:
1681  {
1682  uno_Interface * pUnoI = static_cast<uno_Interface *>(pAny->pReserved);
1683  if (is_XInterface( pAny->pType ))
1684  {
1685  if (pUnoI != nullptr)
1686  {
1687  jo_any.reset(
1688  map_to_java(
1689  jni, pUnoI,
1690  getJniInfo()->m_XInterface_type_info ) );
1691  }
1692  // else: empty XInterface ref maps to null-ref
1693  }
1694  else
1695  {
1696  JNI_interface_type_info const * iface_info =
1697  static_cast< JNI_interface_type_info const * >(
1698  getJniInfo()->get_type_info( jni, pAny->pType ) );
1699  if (pUnoI != nullptr)
1700  {
1701  jo_any.reset( map_to_java( jni, pUnoI, iface_info ) );
1702  }
1703  // box up in com.sun.star.uno.Any
1704  jvalue args[ 2 ];
1705  args[ 0 ].l = iface_info->m_type;
1706  args[ 1 ].l = jo_any.get();
1707  jo_any.reset(
1708  jni->NewObjectA(
1709  getJniInfo()->m_class_Any,
1710  getJniInfo()->m_ctor_Any_with_Type_Object, args ) );
1711  jni.ensure_no_exception();
1712  }
1713  break;
1714  }
1715  case typelib_TypeClass_STRUCT:
1716  {
1717  // Do not lose information about type arguments of instantiated
1718  // polymorphic struct types:
1719  OUString const & name = OUString::unacquired(
1720  &pAny->pType->pTypeName);
1721  assert(!name.isEmpty());
1722  if (name[name.getLength() - 1] == '>')
1723  {
1724  // Box up in com.sun.star.uno.Any:
1725  JLocalAutoRef jo_type(jni, create_type(jni, pAny->pType));
1726  jvalue java_data2;
1727  map_to_java(
1728  jni, &java_data2, pAny->pData, pAny->pType, nullptr, true,
1729  false);
1730  jo_any.reset(java_data2.l);
1731  jvalue args[2];
1732  args[0].l = jo_type.get();
1733  args[1].l = jo_any.get();
1734  jo_any.reset(
1735  jni->NewObjectA(
1736  getJniInfo()->m_class_Any,
1737  getJniInfo()->m_ctor_Any_with_Type_Object, args));
1738  jni.ensure_no_exception();
1739  break;
1740  }
1741  [[fallthrough]];
1742  }
1743  default:
1744  {
1745  jvalue java_data2;
1746  map_to_java(
1747  jni, &java_data2, pAny->pData, pAny->pType, nullptr,
1748  true /* in */, false /* no out */,
1749  true /* create integral wrappers */ );
1750  jo_any.reset( java_data2.l );
1751  break;
1752  }
1753  }
1754  }
1755 
1756  if (out_param)
1757  {
1758  if (java_data->l == nullptr)
1759  {
1760  java_data->l = jni->NewObjectArray(
1761  1, getJniInfo()->m_class_Object, jo_any.get() );
1762  jni.ensure_no_exception();
1763  }
1764  else
1765  {
1766  jni->SetObjectArrayElement(
1767  static_cast<jobjectArray>(java_data->l), 0, jo_any.get() );
1768  jni.ensure_no_exception();
1769  }
1770  }
1771  else
1772  {
1773  java_data->l = jo_any.release();
1774  }
1775  break;
1776  }
1777  case typelib_TypeClass_ENUM:
1778  {
1779  OUString const & type_name = OUString::unacquired( &type->pTypeName );
1780  OString class_name(
1781  OUStringToOString( type_name, RTL_TEXTENCODING_JAVA_UTF8 ) );
1782  JLocalAutoRef jo_enum_class(
1783  jni, find_class( jni, class_name.getStr() ) );
1784 
1785  JLocalAutoRef jo_enum( jni );
1786  if (in_param)
1787  {
1788  // call static <enum_class>.fromInt( int )
1789  OString sig = "(I)L" + class_name.replace( '.', '/' ) + ";";
1790  jmethodID method_id = jni->GetStaticMethodID(
1791  static_cast<jclass>(jo_enum_class.get()), "fromInt", sig.getStr() );
1792  jni.ensure_no_exception();
1793  assert( method_id != nullptr );
1794 
1795  jvalue arg;
1796  arg.i = *static_cast<jint const *>(uno_data);
1797  jo_enum.reset(
1798  jni->CallStaticObjectMethodA(
1799  static_cast<jclass>(jo_enum_class.get()), method_id, &arg ) );
1800  jni.ensure_no_exception();
1801  }
1802  if (out_param)
1803  {
1804  if (java_data->l == nullptr)
1805  {
1806  java_data->l = jni->NewObjectArray(
1807  1, static_cast<jclass>(jo_enum_class.get()), jo_enum.get() );
1808  jni.ensure_no_exception();
1809  }
1810  else
1811  {
1812  jni->SetObjectArrayElement(
1813  static_cast<jobjectArray>(java_data->l), 0, jo_enum.get() );
1814  jni.ensure_no_exception();
1815  }
1816  }
1817  else
1818  {
1819  java_data->l = jo_enum.release();
1820  }
1821  break;
1822  }
1823  case typelib_TypeClass_STRUCT:
1824  case typelib_TypeClass_EXCEPTION:
1825  {
1826  if (info == nullptr)
1827  info = getJniInfo()->get_type_info( jni, type );
1828  JNI_compound_type_info const * comp_info =
1829  static_cast< JNI_compound_type_info const * >( info );
1830 
1831  JLocalAutoRef jo_comp( jni );
1832  if (in_param)
1833  {
1834  if (type->eTypeClass == typelib_TypeClass_EXCEPTION)
1835  {
1836  JLocalAutoRef jo_message(
1837  jni, ustring_to_jstring( jni, *static_cast<rtl_uString * const *>(uno_data) ) );
1838  jvalue arg;
1839  arg.l = jo_message.get();
1840  jo_comp.reset(
1841  jni->NewObjectA(
1842  comp_info->m_class, comp_info->m_exc_ctor, &arg ) );
1843  jni.ensure_no_exception();
1844  }
1845  else
1846  {
1847  jo_comp.reset( jni->AllocObject( comp_info->m_class ) );
1848  jni.ensure_no_exception();
1849  }
1850 
1851  for ( JNI_compound_type_info const * linfo = comp_info;
1852  linfo != nullptr;
1853  linfo = static_cast< JNI_compound_type_info const * >(
1854  linfo->m_base ) )
1855  {
1856  typelib_CompoundTypeDescription * comp_td =
1857  reinterpret_cast<typelib_CompoundTypeDescription *>(linfo->m_td.get());
1858  typelib_TypeDescriptionReference ** ppMemberTypeRefs =
1859  comp_td->ppTypeRefs;
1860  sal_Int32 * pMemberOffsets = comp_td->pMemberOffsets;
1861  bool polymorphic
1862  = comp_td->aBase.eTypeClass == typelib_TypeClass_STRUCT
1863  && reinterpret_cast< typelib_StructTypeDescription * >(
1864  comp_td)->pParameterizedTypes != nullptr;
1865  for ( sal_Int32 nPos = comp_td->nMembers; nPos--; )
1866  {
1867  jfieldID field_id = linfo->m_fields[ nPos ];
1868  if (field_id != nullptr)
1869  {
1870  void const * p =
1871  static_cast<char const *>(uno_data) + pMemberOffsets[ nPos ];
1872  typelib_TypeDescriptionReference * member_type =
1873  ppMemberTypeRefs[ nPos ];
1874  bool parameterizedType = polymorphic
1875  && (reinterpret_cast<
1876  typelib_StructTypeDescription * >(comp_td)->
1877  pParameterizedTypes[nPos]);
1878  switch (member_type->eTypeClass)
1879  {
1880  case typelib_TypeClass_CHAR:
1881  if (parameterizedType) {
1882  jvalue arg;
1883  arg.c = *static_cast<jchar const *>(p);
1884  JLocalAutoRef jo(
1885  jni,
1886  jni->NewObjectA(
1887  getJniInfo()->m_class_Character,
1888  getJniInfo()->m_ctor_Character_with_char,
1889  &arg ) );
1890  jni.ensure_no_exception();
1891  jni->SetObjectField(
1892  jo_comp.get(), field_id, jo.get() );
1893  } else {
1894  jni->SetCharField(
1895  jo_comp.get(),
1896  field_id, *static_cast<jchar const *>(p) );
1897  }
1898  break;
1899  case typelib_TypeClass_BOOLEAN:
1900  if (parameterizedType) {
1901  jvalue arg;
1902  arg.z = *static_cast<jboolean const *>(p);
1903  JLocalAutoRef jo(
1904  jni,
1905  jni->NewObjectA(
1906  getJniInfo()->m_class_Boolean,
1907  getJniInfo()->m_ctor_Boolean_with_boolean,
1908  &arg ) );
1909  jni.ensure_no_exception();
1910  jni->SetObjectField(
1911  jo_comp.get(), field_id, jo.get() );
1912  } else {
1913  jni->SetBooleanField(
1914  jo_comp.get(),
1915  field_id, *static_cast<jboolean const *>(p) );
1916  }
1917  break;
1918  case typelib_TypeClass_BYTE:
1919  if (parameterizedType) {
1920  jvalue arg;
1921  arg.b = *static_cast<jbyte const *>(p);
1922  JLocalAutoRef jo(
1923  jni,
1924  jni->NewObjectA(
1925  getJniInfo()->m_class_Byte,
1926  getJniInfo()->m_ctor_Byte_with_byte,
1927  &arg ) );
1928  jni.ensure_no_exception();
1929  jni->SetObjectField(
1930  jo_comp.get(), field_id, jo.get() );
1931  } else {
1932  jni->SetByteField(
1933  jo_comp.get(),
1934  field_id, *static_cast<jbyte const *>(p) );
1935  }
1936  break;
1937  case typelib_TypeClass_SHORT:
1938  case typelib_TypeClass_UNSIGNED_SHORT:
1939  if (parameterizedType) {
1940  jvalue arg;
1941  arg.s = *static_cast<jshort const *>(p);
1942  JLocalAutoRef jo(
1943  jni,
1944  jni->NewObjectA(
1945  getJniInfo()->m_class_Short,
1946  getJniInfo()->m_ctor_Short_with_short,
1947  &arg ) );
1948  jni.ensure_no_exception();
1949  jni->SetObjectField(
1950  jo_comp.get(), field_id, jo.get() );
1951  } else {
1952  jni->SetShortField(
1953  jo_comp.get(),
1954  field_id, *static_cast<jshort const *>(p) );
1955  }
1956  break;
1957  case typelib_TypeClass_LONG:
1958  case typelib_TypeClass_UNSIGNED_LONG:
1959  if (parameterizedType) {
1960  jvalue arg;
1961  arg.i = *static_cast<jint const *>(p);
1962  JLocalAutoRef jo(
1963  jni,
1964  jni->NewObjectA(
1965  getJniInfo()->m_class_Integer,
1966  getJniInfo()->m_ctor_Integer_with_int,
1967  &arg ) );
1968  jni.ensure_no_exception();
1969  jni->SetObjectField(
1970  jo_comp.get(), field_id, jo.get() );
1971  } else {
1972  jni->SetIntField(
1973  jo_comp.get(),
1974  field_id, *static_cast<jint const *>(p) );
1975  }
1976  break;
1977  case typelib_TypeClass_HYPER:
1978  case typelib_TypeClass_UNSIGNED_HYPER:
1979  if (parameterizedType) {
1980  jvalue arg;
1981  arg.j = *static_cast<jlong const *>(p);
1982  JLocalAutoRef jo(
1983  jni,
1984  jni->NewObjectA(
1985  getJniInfo()->m_class_Long,
1986  getJniInfo()->m_ctor_Long_with_long,
1987  &arg ) );
1988  jni.ensure_no_exception();
1989  jni->SetObjectField(
1990  jo_comp.get(), field_id, jo.get() );
1991  } else {
1992  jni->SetLongField(
1993  jo_comp.get(),
1994  field_id, *static_cast<jlong const *>(p) );
1995  }
1996  break;
1997  case typelib_TypeClass_FLOAT:
1998  if (parameterizedType) {
1999  jvalue arg;
2000  arg.f = *static_cast<jfloat const *>(p);
2001  JLocalAutoRef jo(
2002  jni,
2003  jni->NewObjectA(
2004  getJniInfo()->m_class_Float,
2005  getJniInfo()->m_ctor_Float_with_float,
2006  &arg ) );
2007  jni.ensure_no_exception();
2008  jni->SetObjectField(
2009  jo_comp.get(), field_id, jo.get() );
2010  } else {
2011  jni->SetFloatField(
2012  jo_comp.get(),
2013  field_id, *static_cast<jfloat const *>(p) );
2014  }
2015  break;
2016  case typelib_TypeClass_DOUBLE:
2017  if (parameterizedType) {
2018  jvalue arg;
2019  arg.d = *static_cast<jdouble const *>(p);
2020  JLocalAutoRef jo(
2021  jni,
2022  jni->NewObjectA(
2023  getJniInfo()->m_class_Double,
2024  getJniInfo()->m_ctor_Double_with_double,
2025  &arg ) );
2026  jni.ensure_no_exception();
2027  jni->SetObjectField(
2028  jo_comp.get(), field_id, jo.get() );
2029  } else {
2030  jni->SetDoubleField(
2031  jo_comp.get(),
2032  field_id, *static_cast<jdouble const *>(p) );
2033  }
2034  break;
2035  case typelib_TypeClass_STRING: // string opt here
2036  {
2037  JLocalAutoRef jo_string(
2038  jni, ustring_to_jstring(
2039  jni, *static_cast<rtl_uString * const *>(p) ) );
2040  jni->SetObjectField(
2041  jo_comp.get(), field_id, jo_string.get() );
2042  break;
2043  }
2044  default:
2045  {
2046  jvalue java_data2;
2047  map_to_java(
2048  jni, &java_data2, p, member_type, nullptr,
2049  true /* in */, false /* no out */ );
2050  JLocalAutoRef jo_obj( jni, java_data2.l );
2051  jni->SetObjectField(
2052  jo_comp.get(), field_id, jo_obj.get() );
2053  break;
2054  }
2055  }
2056  }
2057  }
2058  }
2059  }
2060  if (out_param)
2061  {
2062  if (java_data->l == nullptr)
2063  {
2064  java_data->l =
2065  jni->NewObjectArray( 1, comp_info->m_class, jo_comp.get() );
2066  jni.ensure_no_exception();
2067  }
2068  else
2069  {
2070  jni->SetObjectArrayElement(
2071  static_cast<jobjectArray>(java_data->l), 0, jo_comp.get() );
2072  jni.ensure_no_exception();
2073  }
2074  }
2075  else
2076  {
2077  java_data->l = jo_comp.release();
2078  }
2079  break;
2080  }
2081  case typelib_TypeClass_SEQUENCE:
2082  {
2083  // xxx todo: possible opt for pure out sequences
2084  JLocalAutoRef jo_ar( jni );
2085 
2086  sal_Int32 nElements;
2087  uno_Sequence * seq = nullptr;
2088  if (in_param)
2089  {
2090  seq = *static_cast<uno_Sequence * const *>(uno_data);
2091  nElements = seq->nElements;
2092  }
2093  else
2094  {
2095  nElements = 0;
2096  }
2097 
2098  TypeDescr td( type );
2099  typelib_TypeDescriptionReference * element_type =
2100  reinterpret_cast<typelib_IndirectTypeDescription *>(td.get())->pType;
2101 
2102  switch (element_type->eTypeClass)
2103  {
2104  case typelib_TypeClass_CHAR:
2105  jo_ar.reset( jni->NewCharArray( nElements ) );
2106  jni.ensure_no_exception();
2107  if (0 < nElements)
2108  {
2109  jni->SetCharArrayRegion(
2110  static_cast<jcharArray>(jo_ar.get()),
2111  0, nElements, reinterpret_cast<jchar *>(seq->elements) );
2112  jni.ensure_no_exception();
2113  }
2114  break;
2115  case typelib_TypeClass_BOOLEAN:
2116  jo_ar.reset( jni->NewBooleanArray( nElements ) );
2117  jni.ensure_no_exception();
2118  if (0 < nElements)
2119  {
2120  jni->SetBooleanArrayRegion(
2121  static_cast<jbooleanArray>(jo_ar.get()),
2122  0, nElements, reinterpret_cast<jboolean *>(seq->elements) );
2123  jni.ensure_no_exception();
2124  }
2125  break;
2126  case typelib_TypeClass_BYTE:
2127  jo_ar.reset( jni->NewByteArray( nElements ) );
2128  jni.ensure_no_exception();
2129  if (0 < nElements)
2130  {
2131  jni->SetByteArrayRegion(
2132  static_cast<jbyteArray>(jo_ar.get()),
2133  0, nElements, reinterpret_cast<jbyte *>(seq->elements) );
2134  jni.ensure_no_exception();
2135  }
2136  break;
2137  case typelib_TypeClass_SHORT:
2138  case typelib_TypeClass_UNSIGNED_SHORT:
2139  jo_ar.reset( jni->NewShortArray( nElements ) );
2140  jni.ensure_no_exception();
2141  if (0 < nElements)
2142  {
2143  jni->SetShortArrayRegion(
2144  static_cast<jshortArray>(jo_ar.get()),
2145  0, nElements, reinterpret_cast<jshort *>(seq->elements) );
2146  jni.ensure_no_exception();
2147  }
2148  break;
2149  case typelib_TypeClass_LONG:
2150  case typelib_TypeClass_UNSIGNED_LONG:
2151  jo_ar.reset( jni->NewIntArray( nElements ) );
2152  jni.ensure_no_exception();
2153  if (0 < nElements)
2154  {
2155  jni->SetIntArrayRegion(
2156  static_cast<jintArray>(jo_ar.get()),
2157  0, nElements, reinterpret_cast<jint *>(seq->elements) );
2158  jni.ensure_no_exception();
2159  }
2160  break;
2161  case typelib_TypeClass_HYPER:
2162  case typelib_TypeClass_UNSIGNED_HYPER:
2163  jo_ar.reset( jni->NewLongArray( nElements ) );
2164  jni.ensure_no_exception();
2165  if (0 < nElements)
2166  {
2167  jni->SetLongArrayRegion(
2168  static_cast<jlongArray>(jo_ar.get()),
2169  0, nElements, reinterpret_cast<jlong *>(seq->elements) );
2170  jni.ensure_no_exception();
2171  }
2172  break;
2173  case typelib_TypeClass_FLOAT:
2174  jo_ar.reset( jni->NewFloatArray( nElements ) );
2175  jni.ensure_no_exception();
2176  if (0 < nElements)
2177  {
2178  jni->SetFloatArrayRegion(
2179  static_cast<jfloatArray>(jo_ar.get()),
2180  0, nElements, reinterpret_cast<jfloat *>(seq->elements) );
2181  jni.ensure_no_exception();
2182  }
2183  break;
2184  case typelib_TypeClass_DOUBLE:
2185  jo_ar.reset( jni->NewDoubleArray( nElements ) );
2186  jni.ensure_no_exception();
2187  if (0 < nElements)
2188  {
2189  jni->SetDoubleArrayRegion(
2190  static_cast<jdoubleArray>(jo_ar.get()),
2191  0, nElements, reinterpret_cast<jdouble *>(seq->elements) );
2192  jni.ensure_no_exception();
2193  }
2194  break;
2195  case typelib_TypeClass_STRING:
2196  jo_ar.reset(
2197  jni->NewObjectArray(
2198  nElements, getJniInfo()->m_class_String, nullptr ) );
2199  jni.ensure_no_exception();
2200  if (in_param)
2201  {
2202  rtl_uString * const * pp =
2203  reinterpret_cast<rtl_uString * const *>(seq->elements);
2204  for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
2205  {
2206  JLocalAutoRef jo_string(
2207  jni, ustring_to_jstring( jni, pp[ nPos ] ) );
2208  jni->SetObjectArrayElement(
2209  static_cast<jobjectArray>(jo_ar.get()), nPos, jo_string.get() );
2210  jni.ensure_no_exception();
2211  }
2212  }
2213  break;
2214  case typelib_TypeClass_TYPE:
2215  jo_ar.reset(
2216  jni->NewObjectArray( nElements, getJniInfo()->m_class_Type, nullptr ) );
2217  jni.ensure_no_exception();
2218  if (in_param)
2219  {
2220  typelib_TypeDescriptionReference * const * pp =
2221  reinterpret_cast<typelib_TypeDescriptionReference * const *>(seq->elements);
2222  for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
2223  {
2224  jvalue val;
2225  map_to_java(
2226  jni, &val, &pp[ nPos ], element_type, nullptr,
2227  true /* in */, false /* no out */ );
2228  JLocalAutoRef jo_element( jni, val.l );
2229  jni->SetObjectArrayElement(
2230  static_cast<jobjectArray>(jo_ar.get()), nPos, jo_element.get() );
2231  jni.ensure_no_exception();
2232  }
2233  }
2234  break;
2235  case typelib_TypeClass_ANY:
2236  jo_ar.reset(
2237  jni->NewObjectArray(
2238  nElements, getJniInfo()->m_class_Object, nullptr ) );
2239  jni.ensure_no_exception();
2240  if (in_param)
2241  {
2242  uno_Any const * p = reinterpret_cast<uno_Any const *>(seq->elements);
2243  for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
2244  {
2245  jvalue val;
2246  map_to_java(
2247  jni, &val, &p[ nPos ], element_type, nullptr,
2248  true /* in */, false /* no out */ );
2249  JLocalAutoRef jo_element( jni, val.l );
2250  jni->SetObjectArrayElement(
2251  static_cast<jobjectArray>(jo_ar.get()), nPos, jo_element.get() );
2252  jni.ensure_no_exception();
2253  }
2254  }
2255  break;
2256  case typelib_TypeClass_ENUM:
2257  {
2258  OUString const & element_type_name =
2259  OUString::unacquired( &element_type->pTypeName );
2260  OString class_name(
2262  element_type_name, RTL_TEXTENCODING_JAVA_UTF8 ) );
2263  JLocalAutoRef jo_enum_class(
2264  jni, find_class( jni, class_name.getStr() ) );
2265 
2266  jo_ar.reset(
2267  jni->NewObjectArray(
2268  nElements, static_cast<jclass>(jo_enum_class.get()), nullptr ) );
2269  jni.ensure_no_exception();
2270 
2271  if (0 < nElements)
2272  {
2273  // call static <enum_class>.fromInt( int )
2274  OString sig = "(I)L" + class_name.replace( '.', '/' ) + ";";
2275  jmethodID method_id = jni->GetStaticMethodID(
2276  static_cast<jclass>(jo_enum_class.get()), "fromInt", sig.getStr() );
2277  jni.ensure_no_exception();
2278  assert( method_id != nullptr );
2279 
2280  sal_Int32 const * p = reinterpret_cast<sal_Int32 const *>(seq->elements);
2281  for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
2282  {
2283  jvalue arg;
2284  arg.i = p[ nPos ];
2285  JLocalAutoRef jo_enum(
2286  jni, jni->CallStaticObjectMethodA(
2287  static_cast<jclass>(jo_enum_class.get()), method_id, &arg ) );
2288  jni.ensure_no_exception();
2289  jni->SetObjectArrayElement(
2290  static_cast<jobjectArray>(jo_ar.get()), nPos, jo_enum.get() );
2291  jni.ensure_no_exception();
2292  }
2293  }
2294  break;
2295  }
2296  case typelib_TypeClass_STRUCT:
2297  case typelib_TypeClass_EXCEPTION:
2298  {
2299  JNI_type_info const * element_info =
2300  getJniInfo()->get_type_info( jni, element_type );
2301 
2302  jo_ar.reset(
2303  jni->NewObjectArray( nElements, element_info->m_class, nullptr ) );
2304  jni.ensure_no_exception();
2305 
2306  if (0 < nElements)
2307  {
2308  char * p = const_cast<char *>(seq->elements);
2309  sal_Int32 nSize = element_info->m_td.get()->nSize;
2310  for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
2311  {
2312  jvalue val;
2313  map_to_java(
2314  jni, &val, p + (nSize * nPos),
2315  element_type, element_info,
2316  true /* in */, false /* no out */ );
2317  JLocalAutoRef jo_element( jni, val.l );
2318  jni->SetObjectArrayElement(
2319  static_cast<jobjectArray>(jo_ar.get()), nPos, jo_element.get() );
2320  jni.ensure_no_exception();
2321  }
2322  }
2323  break;
2324  }
2325  case typelib_TypeClass_SEQUENCE:
2326  {
2327  OStringBuffer buf( 64 );
2329  &buf, element_type, false /* use class XInterface */,
2330  false /* '.' instead of '/' */ );
2331  OString class_name( buf.makeStringAndClear() );
2332  JLocalAutoRef jo_seq_class(
2333  jni, find_class( jni, class_name.getStr() ) );
2334 
2335  jo_ar.reset(
2336  jni->NewObjectArray(
2337  nElements, static_cast<jclass>(jo_seq_class.get()), nullptr ) );
2338  jni.ensure_no_exception();
2339 
2340  if (0 < nElements)
2341  {
2342  uno_Sequence * const * elements = reinterpret_cast<uno_Sequence * const *>(seq->elements);
2343  for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
2344  {
2345  jvalue java_data2;
2346  map_to_java(
2347  jni, &java_data2, elements + nPos, element_type, nullptr,
2348  true /* in */, false /* no out */ );
2349  JLocalAutoRef jo_seq( jni, java_data2.l );
2350  jni->SetObjectArrayElement(
2351  static_cast<jobjectArray>(jo_ar.get()), nPos, jo_seq.get() );
2352  jni.ensure_no_exception();
2353  }
2354  }
2355  break;
2356  }
2357  case typelib_TypeClass_INTERFACE:
2358  {
2359  JNI_interface_type_info const * iface_info =
2360  static_cast< JNI_interface_type_info const * >(
2361  getJniInfo()->get_type_info( jni, element_type ) );
2362 
2363  jo_ar.reset(
2364  jni->NewObjectArray( nElements, iface_info->m_class, nullptr ) );
2365  jni.ensure_no_exception();
2366 
2367  if (0 < nElements)
2368  {
2369  uno_Interface * const * pp = reinterpret_cast<uno_Interface * const *>(seq->elements);
2370  for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
2371  {
2372  uno_Interface * pUnoI = pp[ nPos ];
2373  if (pUnoI != nullptr)
2374  {
2375  JLocalAutoRef jo_element(
2376  jni, map_to_java( jni, pUnoI, iface_info ) );
2377  jni->SetObjectArrayElement(
2378  static_cast<jobjectArray>(jo_ar.get()),
2379  nPos, jo_element.get() );
2380  jni.ensure_no_exception();
2381  }
2382  }
2383  }
2384  break;
2385  }
2386  default:
2387  {
2388  throw BridgeRuntimeError(
2389  "[map_to_java():" + OUString::unacquired( &type->pTypeName )
2390  + "] unsupported element type: "
2391  + OUString::unacquired( &element_type->pTypeName )
2392  + jni.get_stack_trace() );
2393  }
2394  }
2395 
2396  if (out_param)
2397  {
2398  if (java_data->l == nullptr)
2399  {
2400  JLocalAutoRef jo_element_class(
2401  jni, jni->GetObjectClass( jo_ar.get() ) );
2402  if (in_param)
2403  {
2404  java_data->l = jni->NewObjectArray(
2405  1, static_cast<jclass>(jo_element_class.get()), jo_ar.get() );
2406  }
2407  else
2408  {
2409  java_data->l = jni->NewObjectArray(
2410  1, static_cast<jclass>(jo_element_class.get()), nullptr );
2411  }
2412  jni.ensure_no_exception();
2413  }
2414  else
2415  {
2416  jni->SetObjectArrayElement(
2417  static_cast<jobjectArray>(java_data->l), 0, jo_ar.get() );
2418  jni.ensure_no_exception();
2419  }
2420  }
2421  else
2422  {
2423  java_data->l = jo_ar.release();
2424  }
2425  break;
2426  }
2427  case typelib_TypeClass_INTERFACE:
2428  {
2429  JLocalAutoRef jo_iface( jni );
2430  if (in_param)
2431  {
2432  uno_Interface * pUnoI = *static_cast<uno_Interface * const *>(uno_data);
2433  if (pUnoI != nullptr)
2434  {
2435  if (info == nullptr)
2436  info = getJniInfo()->get_type_info( jni, type );
2437  JNI_interface_type_info const * iface_info =
2438  static_cast< JNI_interface_type_info const * >( info );
2439  jo_iface.reset( map_to_java( jni, pUnoI, iface_info ) );
2440  }
2441  }
2442  if (out_param)
2443  {
2444  if (java_data->l == nullptr)
2445  {
2446  if (info == nullptr)
2447  info = getJniInfo()->get_type_info( jni, type );
2448  java_data->l =
2449  jni->NewObjectArray( 1, info->m_class, jo_iface.get() );
2450  jni.ensure_no_exception();
2451  }
2452  else
2453  {
2454  jni->SetObjectArrayElement(
2455  static_cast<jobjectArray>(java_data->l), 0, jo_iface.get() );
2456  jni.ensure_no_exception();
2457  }
2458  }
2459  else
2460  {
2461  java_data->l = jo_iface.release();
2462  }
2463  break;
2464  }
2465  default:
2466  {
2467  throw BridgeRuntimeError(
2468  "[map_to_java():" + OUString::unacquired( &type->pTypeName )
2469  + "] unsupported type!" + jni.get_stack_trace() );
2470  }
2471  }
2472 }
2473 
2474 }
2475 
2476 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
#define SAL_SEQUENCE_HEADER_SIZE
jobject m_object_Type_UNSIGNED_LONG
Definition: jni_info.h:136
jstring ustring_to_jstring(JNI_context const &jni, rtl_uString const *ustr)
Definition: jni_helper.h:67
void SAL_CALL typelib_typedescriptionreference_acquire(typelib_TypeDescriptionReference *pRef) SAL_THROW_EXTERN_C()
jobject m_object_Type_UNSIGNED_HYPER
Definition: jni_info.h:137
OUString jstring_to_oustring(JNI_context const &jni, jstring jstr)
Definition: jni_helper.h:59
void SAL_CALL uno_destructData(void *pValue, typelib_TypeDescription *pTypeDescr, uno_ReleaseFunc release) SAL_THROW_EXTERN_C()
signed char sal_Int8
jobject create_type(JNI_context const &jni, jclass clazz)
Definition: jni_helper.h:101
static std::unique_ptr< rtl_mem > seq_allocate(sal_Int32 nElements, sal_Int32 nSize)
Definition: jni_data.cxx:34
tuple args
static void append_sig(OStringBuffer *buf, typelib_TypeDescriptionReference *type, bool use_Object_for_type_XInterface=true, bool use_slashes=true)
Definition: jni_info.h:246
jobject get() const
Definition: jni_base.h:155
void SAL_CALL typelib_typedescriptionreference_assign(typelib_TypeDescriptionReference **ppDest, typelib_TypeDescriptionReference *pSource) SAL_THROW_EXTERN_C()
void SAL_CALL uno_any_construct(uno_Any *pDest, void *pSource, typelib_TypeDescription *pTypeDescr, uno_AcquireFunc acquire) SAL_THROW_EXTERN_C()
sal_uInt16 sal_Unicode
OUString get_stack_trace(jobject jo_exc=nullptr) const
Definition: jni_bridge.cxx:377
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
sal_Int32 nElements
struct _uno_Any uno_Any
Definition: msvc/except.hxx:31
typelib_TypeDescriptionReference **SAL_CALL typelib_static_type_getByTypeClass(typelib_TypeClass eTypeClass) SAL_THROW_EXTERN_C()
std::unique_ptr< jfieldID[]> m_fields
Definition: jni_info.h:100
void jstring_to_ustring(JNI_context const &jni, rtl_uString **out_ustr, jstring jstr)
Definition: jni_helper.h:33
void ensure_no_exception() const
Definition: jni_base.h:96
bool is() const
Definition: jni_base.h:157
void SAL_CALL uno_any_destruct(uno_Any *pValue, uno_ReleaseFunc release) SAL_THROW_EXTERN_C()
int i
void reset(jobject jo)
Definition: jni_base.h:184
jfieldID m_field_Type_typeName
Definition: jni_info.h:187
unsigned char sal_Bool
void SAL_CALL typelib_typedescriptionreference_release(typelib_TypeDescriptionReference *pRef) SAL_THROW_EXTERN_C()
struct _typelib_TypeDescription typelib_TypeDescription
Definition: msvc/except.hxx:52
JNI_type_info const * get_type_info(JNI_context const &jni, typelib_TypeDescription *type) const
Definition: jni_info.cxx:390
void SAL_CALL uno_type_destructData(void *pValue, typelib_TypeDescriptionReference *pType, uno_ReleaseFunc release) SAL_THROW_EXTERN_C()
exports com.sun.star.chart2. data
::com::sun::star::uno::TypeDescription m_td
Definition: jni_info.h:67
::com::sun::star::uno::Type const & m_RuntimeException_type
Definition: jni_info.h:203
typelib_TypeDescription * get() const
Definition: jni_base.h:239
void * p
void map_to_java(JNI_context const &jni, jvalue *java_data, void const *uno_data, typelib_TypeDescriptionReference *type, JNI_type_info const *info, bool in_param, bool out_param, bool special_wrapped_integral_types=false) const
Definition: jni_data.cxx:1155
jobject m_object_Type_UNSIGNED_SHORT
Definition: jni_info.h:135
bool type_equals(typelib_TypeDescriptionReference *type1, typelib_TypeDescriptionReference *type2)
Definition: jni_info.h:43
bool is_XInterface(typelib_TypeDescriptionReference *type)
Definition: jni_info.h:56
static rtl_mem * allocate(std::size_t bytes)
Definition: jni_base.h:218
void map_to_uno(JNI_context const &jni, void *uno_data, jvalue java_data, typelib_TypeDescriptionReference *type, JNI_type_info const *info, bool assign, bool out_param, bool special_wrapped_integral_types=false) const
Definition: jni_data.cxx:211
JNI_info const * getJniInfo() const
Definition: jni_bridge.cxx:271
JNI_type_info const * m_base
Definition: jni_info.h:96
sal_uInt16 nPos
jclass find_class(JNI_context const &jni, char const *class_name, bool inException=false)
Definition: jni_helper.h:78
char const * name