blob: dbdfa6acb1581cbe1f8de1e43bc2b481775b5b79 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_bridges.hxx"
#include "jni_bridge.h"
#include "rtl/strbuf.hxx"
#include "rtl/ustrbuf.hxx"
#include "uno/sequence2.h"
using namespace ::std;
using namespace ::rtl;
namespace jni_uno
{
//------------------------------------------------------------------------------
inline rtl_mem * seq_allocate( sal_Int32 nElements, sal_Int32 nSize )
{
auto_ptr< rtl_mem > seq(
rtl_mem::allocate( SAL_SEQUENCE_HEADER_SIZE + (nElements * nSize) ) );
uno_Sequence * p = (uno_Sequence *)seq.get();
p->nRefCount = 1;
p->nElements = nElements;
return seq.release();
}
//______________________________________________________________________________
namespace {
void createDefaultUnoValue(
JNI_context const & jni, void * uno_data,
typelib_TypeDescriptionReference * type,
JNI_type_info const * info /* maybe 0 */, bool assign)
{
switch (type->eTypeClass) {
case typelib_TypeClass_BOOLEAN:
*static_cast< sal_Bool * >(uno_data) = false;
break;
case typelib_TypeClass_BYTE:
*static_cast< sal_Int8 * >(uno_data) = 0;
break;
case typelib_TypeClass_SHORT:
*static_cast< sal_Int16 * >(uno_data) = 0;
break;
case typelib_TypeClass_UNSIGNED_SHORT:
*static_cast< sal_uInt16 * >(uno_data) = 0;
break;
case typelib_TypeClass_LONG:
*static_cast< sal_Int32 * >(uno_data) = 0;
break;
case typelib_TypeClass_UNSIGNED_LONG:
*static_cast< sal_uInt32 * >(uno_data) = 0;
break;
case typelib_TypeClass_HYPER:
*static_cast< sal_Int64 * >(uno_data) = 0;
break;
case typelib_TypeClass_UNSIGNED_HYPER:
*static_cast< sal_uInt64 * >(uno_data) = 0;
break;
case typelib_TypeClass_FLOAT:
*static_cast< float * >(uno_data) = 0;
break;
case typelib_TypeClass_DOUBLE:
*static_cast< double * >(uno_data) = 0;
break;
case typelib_TypeClass_CHAR:
*static_cast< sal_Unicode * >(uno_data) = 0;
break;
case typelib_TypeClass_STRING:
if (!assign) {
*static_cast< rtl_uString ** >(uno_data) = 0;
}
rtl_uString_new(static_cast< rtl_uString ** >(uno_data));
break;
case typelib_TypeClass_TYPE:
if (assign) {
typelib_typedescriptionreference_release(
*static_cast< typelib_TypeDescriptionReference ** >(uno_data));
}
*static_cast< typelib_TypeDescriptionReference ** >(uno_data)
= *typelib_static_type_getByTypeClass(typelib_TypeClass_VOID);
OSL_ASSERT(
*static_cast< typelib_TypeDescriptionReference ** >(uno_data) != 0);
typelib_typedescriptionreference_acquire(
*static_cast< typelib_TypeDescriptionReference ** >(uno_data));
break;
case typelib_TypeClass_ANY:
if (assign) {
uno_any_destruct(static_cast< uno_Any * >(uno_data), 0);
}
uno_any_construct(
static_cast< uno_Any * >(uno_data), 0,
jni.get_info()->m_XInterface_type_info->m_td.get(), 0);
break;
case typelib_TypeClass_SEQUENCE:
{
auto_ptr< rtl_mem > seq(seq_allocate(0, 0));
if (assign) {
uno_type_destructData(uno_data, type, 0);
}
*static_cast< uno_Sequence ** >(uno_data)
= reinterpret_cast< uno_Sequence * >(seq.release());
break;
}
case typelib_TypeClass_ENUM:
{
typelib_TypeDescription * td = 0;
TYPELIB_DANGER_GET(&td, type);
*static_cast< sal_Int32 * >(uno_data)
= (reinterpret_cast< typelib_EnumTypeDescription * >(td)->
nDefaultEnumValue);
TYPELIB_DANGER_RELEASE(td);
break;
}
case typelib_TypeClass_STRUCT:
{
if (info == 0) {
info = jni.get_info()->get_type_info(jni, type);
}
JNI_compound_type_info const * comp_info
= static_cast< JNI_compound_type_info const * >(info);
typelib_CompoundTypeDescription * comp_td
= reinterpret_cast< typelib_CompoundTypeDescription * >(
comp_info->m_td.get());
sal_Int32 nPos = 0;
sal_Int32 nMembers = comp_td->nMembers;
try {
if (comp_td->pBaseTypeDescription != 0) {
createDefaultUnoValue(
jni, uno_data,
comp_td->pBaseTypeDescription->aBase.pWeakRef,
comp_info->m_base, assign);
}
for (; nPos < nMembers; ++nPos) {
createDefaultUnoValue(
jni,
(static_cast< char * >(uno_data)
+ comp_td->pMemberOffsets[nPos]),
comp_td->ppTypeRefs[nPos], 0, assign);
}
} catch (...) {
if (!assign) {
for (sal_Int32 i = 0; i < nPos; ++i) {
uno_type_destructData(
(static_cast< char * >(uno_data)
+ comp_td->pMemberOffsets[i]),
comp_td->ppTypeRefs[i], 0);
}
if (comp_td->pBaseTypeDescription != 0) {
uno_destructData(
uno_data, &comp_td->pBaseTypeDescription->aBase, 0);
}
}
throw;
}
}
break;
case typelib_TypeClass_INTERFACE:
if (assign) {
uno_Interface * p = *static_cast< uno_Interface ** >(uno_data);
if (p != 0) {
(*p->release)(p);
}
}
*static_cast< uno_Interface ** >(uno_data) = 0;
break;
default:
OSL_ASSERT(false);
break;
}
}
}
void Bridge::map_to_uno(
JNI_context const & jni,
void * uno_data, jvalue java_data,
typelib_TypeDescriptionReference * type,
JNI_type_info const * info /* maybe 0 */,
bool assign, bool out_param,
bool special_wrapped_integral_types ) const
{
OSL_ASSERT(
!out_param ||
(1 == jni->GetArrayLength( (jarray) java_data.l )) );
switch (type->eTypeClass)
{
case typelib_TypeClass_CHAR:
if (out_param)
{
jni->GetCharArrayRegion(
(jcharArray) java_data.l, 0, 1, (jchar *) uno_data );
jni.ensure_no_exception();
}
else if (special_wrapped_integral_types)
{
*(jchar *) uno_data = jni->CallCharMethodA(
java_data.l, m_jni_info->m_method_Character_charValue, 0 );
jni.ensure_no_exception();
}
else
{
*(jchar *) uno_data = java_data.c;
}
break;
case typelib_TypeClass_BOOLEAN:
if (out_param)
{
jni->GetBooleanArrayRegion(
(jbooleanArray) java_data.l, 0, 1, (jboolean *) uno_data );
jni.ensure_no_exception();
}
else if (special_wrapped_integral_types)
{
*(jboolean *) uno_data = jni->CallBooleanMethodA(
java_data.l, m_jni_info->m_method_Boolean_booleanValue, 0 );
jni.ensure_no_exception();
}
else
{
*(jboolean *) uno_data = java_data.z;
}
break;
case typelib_TypeClass_BYTE:
if (out_param)
{
jni->GetByteArrayRegion(
(jbyteArray) java_data.l, 0, 1, (jbyte *) uno_data );
jni.ensure_no_exception();
}
else if (special_wrapped_integral_types)
{
*(jbyte *) uno_data = jni->CallByteMethodA(
java_data.l, m_jni_info->m_method_Byte_byteValue, 0 );
jni.ensure_no_exception();
}
else
{
*(jbyte *) uno_data = java_data.b;
}
break;
case typelib_TypeClass_SHORT:
case typelib_TypeClass_UNSIGNED_SHORT:
if (out_param)
{
jni->GetShortArrayRegion(
(jshortArray) java_data.l, 0, 1, (jshort *) uno_data );
jni.ensure_no_exception();
}
else if (special_wrapped_integral_types)
{
*(jshort *) uno_data = jni->CallShortMethodA(
java_data.l, m_jni_info->m_method_Short_shortValue, 0 );
jni.ensure_no_exception();
}
else
{
*(jshort *) uno_data = java_data.s;
}
break;
case typelib_TypeClass_LONG:
case typelib_TypeClass_UNSIGNED_LONG:
if (out_param)
{
jni->GetIntArrayRegion(
(jintArray) java_data.l, 0, 1, (jint *) uno_data );
jni.ensure_no_exception();
}
else if (special_wrapped_integral_types)
{
*(jint *) uno_data = jni->CallIntMethodA(
java_data.l, m_jni_info->m_method_Integer_intValue, 0 );
jni.ensure_no_exception();
}
else
{
*(jint *) uno_data = java_data.i;
}
break;
case typelib_TypeClass_HYPER:
case typelib_TypeClass_UNSIGNED_HYPER:
if (out_param)
{
jni->GetLongArrayRegion(
(jlongArray) java_data.l, 0, 1, (jlong *) uno_data );
jni.ensure_no_exception();
}
else if (special_wrapped_integral_types)
{
*(jlong *) uno_data = jni->CallLongMethodA(
java_data.l, m_jni_info->m_method_Long_longValue, 0 );
jni.ensure_no_exception();
}
else
{
*(jlong *) uno_data = java_data.j;
}
break;
case typelib_TypeClass_FLOAT:
if (out_param)
{
jni->GetFloatArrayRegion(
(jfloatArray) java_data.l, 0, 1, (jfloat *) uno_data );
jni.ensure_no_exception();
}
else if (special_wrapped_integral_types)
{
*(jfloat *) uno_data = jni->CallFloatMethodA(
java_data.l, m_jni_info->m_method_Float_floatValue, 0 );
jni.ensure_no_exception();
}
else
{
*(jfloat *) uno_data = java_data.f;
}
break;
case typelib_TypeClass_DOUBLE:
if (out_param)
{
jni->GetDoubleArrayRegion(
(jdoubleArray) java_data.l, 0, 1, (jdouble *) uno_data );
jni.ensure_no_exception();
}
else if (special_wrapped_integral_types)
{
*(jdouble *) uno_data = jni->CallDoubleMethodA(
java_data.l, m_jni_info->m_method_Double_doubleValue, 0 );
jni.ensure_no_exception();
}
else
{
*(jdouble *) uno_data = java_data.d;
}
break;
case typelib_TypeClass_STRING:
{
JLocalAutoRef jo_out_holder( jni );
if (out_param)
{
jo_out_holder.reset(
jni->GetObjectArrayElement( (jobjectArray) java_data.l, 0 ) );
jni.ensure_no_exception();
java_data.l = jo_out_holder.get();
}
if (0 == java_data.l)
{
OUStringBuffer buf( 128 );
buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
buf.append( OUString::unacquired( &type->pTypeName ) );
buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] null-ref given!") );
buf.append( jni.get_stack_trace() );
throw BridgeRuntimeError( buf.makeStringAndClear() );
}
if (! assign)
*(rtl_uString **)uno_data = 0;
jstring_to_ustring(
jni, (rtl_uString **)uno_data, (jstring) java_data.l );
break;
}
case typelib_TypeClass_TYPE:
{
JLocalAutoRef jo_out_holder( jni );
if (out_param)
{
jo_out_holder.reset(
jni->GetObjectArrayElement( (jobjectArray) java_data.l, 0 ) );
jni.ensure_no_exception();
java_data.l = jo_out_holder.get();
}
if (0 == java_data.l)
{
OUStringBuffer buf( 128 );
buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
buf.append( OUString::unacquired( &type->pTypeName ) );
buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] null-ref given!") );
buf.append( jni.get_stack_trace() );
throw BridgeRuntimeError( buf.makeStringAndClear() );
}
// type name
JLocalAutoRef jo_type_name(
jni, jni->GetObjectField(
java_data.l, m_jni_info->m_field_Type__typeName ) );
if (! jo_type_name.is())
{
OUStringBuffer buf( 128 );
buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
buf.append( OUString::unacquired( &type->pTypeName ) );
buf.appendAscii(
RTL_CONSTASCII_STRINGPARAM("] incomplete type object: "
"no type name!") );
buf.append( jni.get_stack_trace() );
throw BridgeRuntimeError( buf.makeStringAndClear() );
}
OUString type_name(
jstring_to_oustring( jni, (jstring) jo_type_name.get() ) );
::com::sun::star::uno::TypeDescription td( type_name );
if (! td.is())
{
OUStringBuffer buf( 128 );
buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
buf.append( OUString::unacquired( &type->pTypeName ) );
buf.appendAscii(
RTL_CONSTASCII_STRINGPARAM("] UNO type not found: ") );
buf.append( type_name );
buf.append( jni.get_stack_trace() );
throw BridgeRuntimeError( buf.makeStringAndClear() );
}
typelib_typedescriptionreference_acquire( td.get()->pWeakRef );
if (assign)
{
typelib_typedescriptionreference_release(
*(typelib_TypeDescriptionReference **)uno_data );
}
*(typelib_TypeDescriptionReference **)uno_data = td.get()->pWeakRef;
break;
}
case typelib_TypeClass_ANY:
{
JLocalAutoRef jo_out_holder( jni );
if (out_param)
{
jo_out_holder.reset(
jni->GetObjectArrayElement( (jobjectArray) java_data.l, 0 ) );
jni.ensure_no_exception();
java_data.l = jo_out_holder.get();
}
uno_Any * pAny = (uno_Any *)uno_data;
if (0 == java_data.l) // null-ref maps to XInterface null-ref
{
if (assign)
uno_any_destruct( pAny, 0 );
uno_any_construct(
pAny, 0, m_jni_info->m_XInterface_type_info->m_td.get(), 0 );
break;
}
JLocalAutoRef jo_type( jni );
JLocalAutoRef jo_wrapped_holder( jni );
if (JNI_FALSE != jni->IsInstanceOf(
java_data.l, m_jni_info->m_class_Any ))
{
// boxed any
jo_type.reset( jni->GetObjectField(
java_data.l, m_jni_info->m_field_Any__type ) );
if (! jo_type.is())
{
OUStringBuffer buf( 128 );
buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
buf.append( OUString::unacquired( &type->pTypeName ) );
buf.appendAscii(
RTL_CONSTASCII_STRINGPARAM("] no type set at "
"com.sun.star.uno.Any!") );
buf.append( jni.get_stack_trace() );
throw BridgeRuntimeError( buf.makeStringAndClear() );
}
// wrapped value
jo_wrapped_holder.reset(
jni->GetObjectField(
java_data.l, m_jni_info->m_field_Any__object ) );
java_data.l = jo_wrapped_holder.get();
}
else
{
// create type out of class
JLocalAutoRef jo_class( jni, jni->GetObjectClass( java_data.l ) );
jo_type.reset( create_type( jni, (jclass) jo_class.get() ) );
#if OSL_DEBUG_LEVEL > 1
{
JLocalAutoRef jo_toString(
jni, jni->CallObjectMethodA(
java_data.l, m_jni_info->m_method_Object_toString, 0 ) );
jni.ensure_no_exception();
OUString toString(
jstring_to_oustring( jni, (jstring) jo_toString.get() ) );
}
#endif
}
// get type name
JLocalAutoRef jo_type_name(
jni, jni->GetObjectField(
jo_type.get(), m_jni_info->m_field_Type__typeName ) );
jni.ensure_no_exception();
OUString type_name(
jstring_to_oustring( jni, (jstring) jo_type_name.get() ) );
::com::sun::star::uno::TypeDescription value_td( type_name );
if (! value_td.is())
{
OUStringBuffer buf( 128 );
buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
buf.append( OUString::unacquired( &type->pTypeName ) );
buf.appendAscii(
RTL_CONSTASCII_STRINGPARAM("] UNO type not found: ") );
buf.append( type_name );
buf.append( jni.get_stack_trace() );
throw BridgeRuntimeError( buf.makeStringAndClear() );
}
typelib_TypeClass type_class = value_td.get()->eTypeClass;
if (assign)
{
uno_any_destruct( pAny, 0 );
}
try
{
switch (type_class)
{
case typelib_TypeClass_VOID:
pAny->pData = &pAny->pReserved;
break;
case typelib_TypeClass_CHAR:
*(jchar *) &pAny->pReserved = jni->CallCharMethodA(
java_data.l, m_jni_info->m_method_Character_charValue, 0 );
jni.ensure_no_exception();
pAny->pData = &pAny->pReserved;
break;
case typelib_TypeClass_BOOLEAN:
*(jboolean *) &pAny->pReserved = jni->CallBooleanMethodA(
java_data.l, m_jni_info->m_method_Boolean_booleanValue, 0 );
jni.ensure_no_exception();
pAny->pData = &pAny->pReserved;
break;
case typelib_TypeClass_BYTE:
*(jbyte *) &pAny->pReserved = jni->CallByteMethodA(
java_data.l, m_jni_info->m_method_Byte_byteValue, 0 );
jni.ensure_no_exception();
pAny->pData = &pAny->pReserved;
break;
case typelib_TypeClass_SHORT:
case typelib_TypeClass_UNSIGNED_SHORT:
*(jshort *) &pAny->pReserved = jni->CallShortMethodA(
java_data.l, m_jni_info->m_method_Short_shortValue, 0 );
jni.ensure_no_exception();
pAny->pData = &pAny->pReserved;
break;
case typelib_TypeClass_LONG:
case typelib_TypeClass_UNSIGNED_LONG:
*(jint *) &pAny->pReserved = jni->CallIntMethodA(
java_data.l, m_jni_info->m_method_Integer_intValue, 0 );
jni.ensure_no_exception();
pAny->pData = &pAny->pReserved;
break;
case typelib_TypeClass_HYPER:
case typelib_TypeClass_UNSIGNED_HYPER:
if (sizeof (sal_Int64) <= sizeof (void *))
{
*(jlong *) &pAny->pReserved = jni->CallLongMethodA(
java_data.l, m_jni_info->m_method_Long_longValue, 0 );
jni.ensure_no_exception();
pAny->pData = &pAny->pReserved;
}
else
{
auto_ptr< rtl_mem > mem(
rtl_mem::allocate( sizeof (sal_Int64) ) );
*(jlong *) mem.get() = jni->CallLongMethodA(
java_data.l, m_jni_info->m_method_Long_longValue, 0 );
jni.ensure_no_exception();
pAny->pData = mem.release();
}
break;
case typelib_TypeClass_FLOAT:
if (sizeof (float) <= sizeof (void *))
{
*(jfloat *) &pAny->pReserved = jni->CallFloatMethodA(
java_data.l, m_jni_info->m_method_Float_floatValue, 0 );
jni.ensure_no_exception();
pAny->pData = &pAny->pReserved;
}
else
{
auto_ptr< rtl_mem > mem(
rtl_mem::allocate( sizeof (float) ) );
*(jfloat *) mem.get() = jni->CallFloatMethodA(
java_data.l, m_jni_info->m_method_Float_floatValue, 0 );
jni.ensure_no_exception();
pAny->pData = mem.release();
}
break;
case typelib_TypeClass_DOUBLE:
if (sizeof (double) <= sizeof (void *))
{
*(jdouble *) &pAny->pReserved =
jni->CallDoubleMethodA(
java_data.l,
m_jni_info->m_method_Double_doubleValue, 0 );
jni.ensure_no_exception();
pAny->pData = &pAny->pReserved;
}
else
{
auto_ptr< rtl_mem > mem(
rtl_mem::allocate( sizeof (double) ) );
*(jdouble *) mem.get() =
jni->CallDoubleMethodA(
java_data.l,
m_jni_info->m_method_Double_doubleValue, 0 );
jni.ensure_no_exception();
pAny->pData = mem.release();
}
break;
case typelib_TypeClass_STRING:
// opt: anies often contain strings; copy string directly
pAny->pReserved = 0;
jstring_to_ustring(
jni, (rtl_uString **)&pAny->pReserved,
(jstring) java_data.l );
pAny->pData = &pAny->pReserved;
break;
case typelib_TypeClass_TYPE:
case typelib_TypeClass_ENUM:
case typelib_TypeClass_SEQUENCE:
case typelib_TypeClass_INTERFACE:
map_to_uno(
jni, &pAny->pReserved, java_data,
value_td.get()->pWeakRef, 0,
false /* no assign */, false /* no out param */ );
pAny->pData = &pAny->pReserved;
break;
case typelib_TypeClass_STRUCT:
case typelib_TypeClass_EXCEPTION:
{
auto_ptr< rtl_mem > mem(
rtl_mem::allocate( value_td.get()->nSize ) );
map_to_uno(
jni, mem.get(), java_data, value_td.get()->pWeakRef, 0,
false /* no assign */, false /* no out param */ );
pAny->pData = mem.release();
break;
}
default:
{
OUStringBuffer buf( 128 );
buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
buf.append( type_name );
buf.appendAscii(
RTL_CONSTASCII_STRINGPARAM("] unsupported value type "
"of any!") );
buf.append( jni.get_stack_trace() );
throw BridgeRuntimeError( buf.makeStringAndClear() );
}
}
}
catch (...)
{
if (assign)
{
// restore to valid any
uno_any_construct( pAny, 0, 0, 0 );
}
throw;
}
typelib_typedescriptionreference_acquire( value_td.get()->pWeakRef );
pAny->pType = value_td.get()->pWeakRef;
break;
}
case typelib_TypeClass_ENUM:
{
JLocalAutoRef jo_out_holder( jni );
if (out_param)
{
jo_out_holder.reset(
jni->GetObjectArrayElement( (jobjectArray) java_data.l, 0 ) );
jni.ensure_no_exception();
java_data.l = jo_out_holder.get();
}
if (0 == java_data.l)
{
OUStringBuffer buf( 128 );
buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
buf.append( OUString::unacquired( &type->pTypeName ) );
buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] null-ref given!") );
buf.append( jni.get_stack_trace() );
throw BridgeRuntimeError( buf.makeStringAndClear() );
}
*(jint *) uno_data = jni->GetIntField(
java_data.l, m_jni_info->m_field_Enum_m_value );
break;
}
case typelib_TypeClass_STRUCT:
case typelib_TypeClass_EXCEPTION:
{
JLocalAutoRef jo_out_holder( jni );
if (out_param)
{
jo_out_holder.reset(
jni->GetObjectArrayElement( (jobjectArray) java_data.l, 0 ) );
jni.ensure_no_exception();
java_data.l = jo_out_holder.get();
}
if (0 == java_data.l)
{
OUStringBuffer buf( 128 );
buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
buf.append( OUString::unacquired( &type->pTypeName ) );
buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] null-ref given!") );
buf.append( jni.get_stack_trace() );
throw BridgeRuntimeError( buf.makeStringAndClear() );
}
if (0 == info)
info = m_jni_info->get_type_info( jni, type );
JNI_compound_type_info const * comp_info =
static_cast< JNI_compound_type_info const * >( info );
typelib_CompoundTypeDescription * comp_td =
(typelib_CompoundTypeDescription *)comp_info->m_td.get();
bool polymorphic
= comp_td->aBase.eTypeClass == typelib_TypeClass_STRUCT
&& reinterpret_cast< typelib_StructTypeDescription * >(
comp_td)->pParameterizedTypes != 0;
sal_Int32 nPos = 0;
sal_Int32 nMembers = comp_td->nMembers;
try
{
if (0 != comp_td->pBaseTypeDescription)
{
map_to_uno(
jni, uno_data, java_data,
((typelib_TypeDescription *) comp_td->pBaseTypeDescription)
->pWeakRef,
comp_info->m_base,
assign, false /* no out param */ );
}
for ( ; nPos < nMembers; ++nPos )
{
void * p = (char *)uno_data + comp_td->pMemberOffsets[ nPos ];
typelib_TypeDescriptionReference * member_type =
comp_td->ppTypeRefs[ nPos ];
jfieldID field_id = comp_info->m_fields[ nPos ];
bool parameterizedType = polymorphic
&& reinterpret_cast< typelib_StructTypeDescription * >(
comp_td)->pParameterizedTypes[nPos];
switch (member_type->eTypeClass)
{
case typelib_TypeClass_CHAR:
if (parameterizedType) {
JLocalAutoRef jo(
jni, jni->GetObjectField( java_data.l, field_id ) );
if ( jo.get() == 0 ) {
*(jchar *) p = 0;
} else {
jvalue val;
val.l = jo.get();
map_to_uno(
jni, p, val, member_type, 0, assign, false,
true );
}
} else {
*(jchar *) p = jni->GetCharField(
java_data.l, field_id );
}
break;
case typelib_TypeClass_BOOLEAN:
if (parameterizedType) {
JLocalAutoRef jo(
jni, jni->GetObjectField( java_data.l, field_id ) );
if ( jo.get() == 0 ) {
*(jboolean *) p = false;
} else {
jvalue val;
val.l = jo.get();
map_to_uno(
jni, p, val, member_type, 0, assign, false,
true );
}
} else {
*(jboolean *) p = jni->GetBooleanField(
java_data.l, field_id );
}
break;
case typelib_TypeClass_BYTE:
if (parameterizedType) {
JLocalAutoRef jo(
jni, jni->GetObjectField( java_data.l, field_id ) );
if ( jo.get() == 0 ) {
*(jbyte *) p = 0;
} else {
jvalue val;
val.l = jo.get();
map_to_uno(
jni, p, val, member_type, 0, assign, false,
true );
}
} else {
*(jbyte *) p = jni->GetByteField(
java_data.l, field_id );
}
break;
case typelib_TypeClass_SHORT:
case typelib_TypeClass_UNSIGNED_SHORT:
if (parameterizedType) {
JLocalAutoRef jo(
jni, jni->GetObjectField( java_data.l, field_id ) );
if ( jo.get() == 0 ) {
*(jshort *) p = 0;
} else {
jvalue val;
val.l = jo.get();
map_to_uno(
jni, p, val, member_type, 0, assign, false,
true );
}
} else {
*(jshort *) p = jni->GetShortField(
java_data.l, field_id );
}
break;
case typelib_TypeClass_LONG:
case typelib_TypeClass_UNSIGNED_LONG:
if (parameterizedType) {
JLocalAutoRef jo(
jni, jni->GetObjectField( java_data.l, field_id ) );
if ( jo.get() == 0 ) {
*(jint *) p = 0;
} else {
jvalue val;
val.l = jo.get();
map_to_uno(
jni, p, val, member_type, 0, assign, false,
true );
}
} else {
*(jint *) p = jni->GetIntField( java_data.l, field_id );
}
break;
case typelib_TypeClass_HYPER:
case typelib_TypeClass_UNSIGNED_HYPER:
if (parameterizedType) {
JLocalAutoRef jo(
jni, jni->GetObjectField( java_data.l, field_id ) );
if ( jo.get() == 0 ) {
*(jlong *) p = 0;
} else {
jvalue val;
val.l = jo.get();
map_to_uno(
jni, p, val, member_type, 0, assign, false,
true );
}
} else {
*(jlong *) p = jni->GetLongField(
java_data.l, field_id );
}
break;
case typelib_TypeClass_FLOAT:
if (parameterizedType) {
JLocalAutoRef jo(
jni, jni->GetObjectField( java_data.l, field_id ) );
if ( jo.get() == 0 ) {
*(jfloat *) p = 0;
} else {
jvalue val;
val.l = jo.get();
map_to_uno(
jni, p, val, member_type, 0, assign, false,
true );
}
} else {
*(jfloat *) p = jni->GetFloatField(
java_data.l, field_id );
}
break;
case typelib_TypeClass_DOUBLE:
if (parameterizedType) {
JLocalAutoRef jo(
jni, jni->GetObjectField( java_data.l, field_id ) );
if ( jo.get() == 0 ) {
*(jdouble *) p = 0;
} else {
jvalue val;
val.l = jo.get();
map_to_uno(
jni, p, val, member_type, 0, assign, false,
true );
}
} else {
*(jdouble *) p = jni->GetDoubleField(
java_data.l, field_id );
}
break;
default:
{
JLocalAutoRef jo_field( jni );
bool checkNull;
if (0 == field_id)
{
// special for Message: call Throwable.getMessage()
OSL_ASSERT(
type_equals(
type,
m_jni_info->m_Exception_type.getTypeLibType() )
|| type_equals(
type,
m_jni_info->m_RuntimeException_type.
getTypeLibType() ) );
OSL_ASSERT( 0 == nPos ); // first member
// call getMessage()
jo_field.reset(
jni->CallObjectMethodA(
java_data.l,
m_jni_info->m_method_Throwable_getMessage, 0 )
);
jni.ensure_no_exception();
checkNull = true;
}
else
{
jo_field.reset(
jni->GetObjectField( java_data.l, field_id ) );
checkNull = parameterizedType;
}
if (checkNull && !jo_field.is()) {
createDefaultUnoValue(jni, p, member_type, 0, assign);
} else {
jvalue val;
val.l = jo_field.get();
map_to_uno(
jni, p, val, member_type, 0,
assign, false /* no out param */ );
}
break;
}
}
}
}
catch (...)
{
if (! assign)
{
// cleanup
for ( sal_Int32 nCleanup = 0; nCleanup < nPos; ++nCleanup )
{
void * p =
(char *)uno_data + comp_td->pMemberOffsets[ nCleanup ];
uno_type_destructData(
p, comp_td->ppTypeRefs[ nCleanup ], 0 );
}
if (0 != comp_td->pBaseTypeDescription)
{
uno_destructData(
uno_data,
(typelib_TypeDescription *) comp_td
->pBaseTypeDescription, 0 );
}
}
throw;
}
break;
}
case typelib_TypeClass_SEQUENCE:
{
JLocalAutoRef jo_out_holder( jni );
if (out_param)
{
jo_out_holder.reset(
jni->GetObjectArrayElement( (jobjectArray) java_data.l, 0 ) );
jni.ensure_no_exception();
java_data.l = jo_out_holder.get();
}
if (0 == java_data.l)
{
OUStringBuffer buf( 128 );
buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
buf.append( OUString::unacquired( &type->pTypeName ) );
buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] null-ref given!") );
buf.append( jni.get_stack_trace() );
throw BridgeRuntimeError( buf.makeStringAndClear() );
}
TypeDescr td( type );
typelib_TypeDescriptionReference * element_type =
((typelib_IndirectTypeDescription *)td.get())->pType;
auto_ptr< rtl_mem > seq;
sal_Int32 nElements = jni->GetArrayLength( (jarray) java_data.l );
switch (element_type->eTypeClass)
{
case typelib_TypeClass_CHAR:
seq.reset( seq_allocate( nElements, sizeof (sal_Unicode) ) );
jni->GetCharArrayRegion(
(jcharArray) java_data.l, 0, nElements,
(jchar *) ((uno_Sequence *) seq.get())->elements );
jni.ensure_no_exception();
break;
case typelib_TypeClass_BOOLEAN:
seq.reset( seq_allocate( nElements, sizeof (sal_Bool) ) );
jni->GetBooleanArrayRegion(
(jbooleanArray) java_data.l, 0, nElements,
(jboolean *) ((uno_Sequence *) seq.get())->elements );
jni.ensure_no_exception();
break;
case typelib_TypeClass_BYTE:
seq.reset( seq_allocate( nElements, sizeof (sal_Int8) ) );
jni->GetByteArrayRegion(
(jbyteArray) java_data.l, 0, nElements,
(jbyte *) ((uno_Sequence *) seq.get())->elements );
jni.ensure_no_exception();
break;
case typelib_TypeClass_SHORT:
case typelib_TypeClass_UNSIGNED_SHORT:
seq.reset( seq_allocate( nElements, sizeof (sal_Int16) ) );
jni->GetShortArrayRegion(
(jshortArray) java_data.l, 0, nElements,
(jshort *) ((uno_Sequence *) seq.get())->elements );
jni.ensure_no_exception();
break;
case typelib_TypeClass_LONG:
case typelib_TypeClass_UNSIGNED_LONG:
seq.reset( seq_allocate( nElements, sizeof (sal_Int32) ) );
jni->GetIntArrayRegion(
(jintArray) java_data.l, 0, nElements,
(jint *) ((uno_Sequence *) seq.get())->elements );
jni.ensure_no_exception();
break;
case typelib_TypeClass_HYPER:
case typelib_TypeClass_UNSIGNED_HYPER:
seq.reset( seq_allocate( nElements, sizeof (sal_Int64) ) );
jni->GetLongArrayRegion(
(jlongArray) java_data.l, 0, nElements,
(jlong *) ((uno_Sequence *) seq.get())->elements );
jni.ensure_no_exception();
break;
case typelib_TypeClass_FLOAT:
seq.reset( seq_allocate( nElements, sizeof (float) ) );
jni->GetFloatArrayRegion(
(jfloatArray) java_data.l, 0, nElements,
(jfloat *)((uno_Sequence *)seq.get())->elements );
jni.ensure_no_exception();
break;
case typelib_TypeClass_DOUBLE:
seq.reset( seq_allocate( nElements, sizeof (double) ) );
jni->GetDoubleArrayRegion(
(jdoubleArray) java_data.l, 0, nElements,
(jdouble *) ((uno_Sequence *) seq.get())->elements );
jni.ensure_no_exception();
break;
case typelib_TypeClass_STRING:
case typelib_TypeClass_TYPE:
case typelib_TypeClass_ANY:
case typelib_TypeClass_ENUM:
case typelib_TypeClass_STRUCT:
case typelib_TypeClass_EXCEPTION:
case typelib_TypeClass_SEQUENCE:
case typelib_TypeClass_INTERFACE:
{
TypeDescr element_td( element_type );
seq.reset( seq_allocate( nElements, element_td.get()->nSize ) );
JNI_type_info const * element_info;
if (typelib_TypeClass_STRUCT == element_type->eTypeClass ||
typelib_TypeClass_EXCEPTION == element_type->eTypeClass ||
typelib_TypeClass_INTERFACE == element_type->eTypeClass)
{
element_info =
m_jni_info->get_type_info( jni, element_td.get() );
}
else
{
element_info = 0;
}
for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
{
try
{
JLocalAutoRef jo(
jni, jni->GetObjectArrayElement(
(jobjectArray) java_data.l, nPos ) );
jni.ensure_no_exception();
jvalue val;
val.l = jo.get();
void * p =
((uno_Sequence *)seq.get())->elements +
(nPos * element_td.get()->nSize);
map_to_uno(
jni, p, val, element_td.get()->pWeakRef, element_info,
false /* no assign */, false /* no out param */ );
}
catch (...)
{
// cleanup
for ( sal_Int32 nCleanPos = 0;
nCleanPos < nPos; ++nCleanPos )
{
void * p =
((uno_Sequence *)seq.get())->elements +
(nCleanPos * element_td.get()->nSize);
uno_destructData( p, element_td.get(), 0 );
}
throw;
}
}
break;
}
default:
{
OUStringBuffer buf( 128 );
buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
buf.append( OUString::unacquired( &type->pTypeName ) );
buf.appendAscii(
RTL_CONSTASCII_STRINGPARAM("] unsupported sequence element"
" type: ") );
buf.append( OUString::unacquired( &element_type->pTypeName ) );
buf.append( jni.get_stack_trace() );
throw BridgeRuntimeError( buf.makeStringAndClear() );
}
}
if (assign)
uno_destructData( uno_data, td.get(), 0 );
*(uno_Sequence **)uno_data = (uno_Sequence *)seq.release();
break;
}
case typelib_TypeClass_INTERFACE:
{
JLocalAutoRef jo_out_holder( jni );
if (out_param)
{
jo_out_holder.reset(
jni->GetObjectArrayElement( (jobjectArray) java_data.l, 0 ) );
jni.ensure_no_exception();
java_data.l = jo_out_holder.get();
}
if (0 == java_data.l) // null-ref
{
if (assign)
{
uno_Interface * p = *(uno_Interface **)uno_data;
if (0 != p)
(*p->release)( p );
}
*(uno_Interface **)uno_data = 0;
}
else
{
if (0 == info)
info = m_jni_info->get_type_info( jni, type );
JNI_interface_type_info const * iface_info =
static_cast< JNI_interface_type_info const * >( info );
uno_Interface * pUnoI = map_to_uno( jni, java_data.l, iface_info );
if (assign)
{
uno_Interface * p = *(uno_Interface **)uno_data;
if (0 != p)
(*p->release)( p );
}
*(uno_Interface **)uno_data = pUnoI;
}
break;
}
default:
{
OUStringBuffer buf( 128 );
buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
buf.append( OUString::unacquired( &type->pTypeName ) );
buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] unsupported type!") );
buf.append( jni.get_stack_trace() );
throw BridgeRuntimeError( buf.makeStringAndClear() );
}
}
}
//##############################################################################
//______________________________________________________________________________
void Bridge::map_to_java(
JNI_context const & jni,
jvalue * java_data, void const * uno_data,
typelib_TypeDescriptionReference * type,
JNI_type_info const * info /* maybe 0 */,
bool in_param, bool out_param,
bool special_wrapped_integral_types ) const
{
switch (type->eTypeClass)
{
case typelib_TypeClass_CHAR:
if (out_param)
{
if (0 == java_data->l)
{
JLocalAutoRef jo_ar( jni, jni->NewCharArray( 1 ) );
jni.ensure_no_exception();
if (in_param)
{
jni->SetCharArrayRegion(
(jcharArray) jo_ar.get(), 0, 1, (jchar *) uno_data );
jni.ensure_no_exception();
}
java_data->l = jo_ar.release();
}
else
{
if (in_param)
{
jni->SetCharArrayRegion(
(jcharArray) java_data->l, 0, 1, (jchar *) uno_data );
jni.ensure_no_exception();
}
}
}
else if (special_wrapped_integral_types)
{
jvalue arg;
arg.c = *(jchar const *) uno_data;
java_data->l = jni->NewObjectA(
m_jni_info->m_class_Character,
m_jni_info->m_ctor_Character_with_char, &arg );
jni.ensure_no_exception();
}
else
{
java_data->c = *(jchar const *) uno_data;
}
break;
case typelib_TypeClass_BOOLEAN:
if (out_param)
{
if (0 == java_data->l)
{
JLocalAutoRef jo_ar( jni, jni->NewBooleanArray( 1 ) );
jni.ensure_no_exception();
if (in_param)
{
jni->SetBooleanArrayRegion(
(jbooleanArray) jo_ar.get(),
0, 1, (jboolean *) uno_data );
jni.ensure_no_exception();
}
java_data->l = jo_ar.release();
}
else
{
if (in_param)
{
jni->SetBooleanArrayRegion(
(jbooleanArray) java_data->l,
0, 1, (jboolean *) uno_data );
jni.ensure_no_exception();
}
}
}
else if (special_wrapped_integral_types)
{
jvalue arg;
arg.z = *(jboolean const *) uno_data;
java_data->l = jni->NewObjectA(
m_jni_info->m_class_Boolean,
m_jni_info->m_ctor_Boolean_with_boolean, &arg );
jni.ensure_no_exception();
}
else
{
java_data->z = *(jboolean const *) uno_data;
}
break;
case typelib_TypeClass_BYTE:
if (out_param)
{
if (0 == java_data->l)
{
JLocalAutoRef jo_ar( jni, jni->NewByteArray( 1 ) );
jni.ensure_no_exception();
if (in_param)
{
jni->SetByteArrayRegion(
(jbyteArray) jo_ar.get(), 0, 1, (jbyte *) uno_data );
jni.ensure_no_exception();
}
java_data->l = jo_ar.release();
}
else
{
if (in_param)
{
jni->SetByteArrayRegion(
(jbyteArray) java_data->l, 0, 1, (jbyte *) uno_data );
jni.ensure_no_exception();
}
}
}
else if (special_wrapped_integral_types)
{
jvalue arg;
arg.b = *(jbyte const *) uno_data;
java_data->l = jni->NewObjectA(
m_jni_info->m_class_Byte,
m_jni_info->m_ctor_Byte_with_byte, &arg );
jni.ensure_no_exception();
}
else
{
java_data->b = *(jbyte const *) uno_data;
}
break;
case typelib_TypeClass_SHORT:
case typelib_TypeClass_UNSIGNED_SHORT:
if (out_param)
{
if (0 == java_data->l)
{
JLocalAutoRef jo_ar( jni, jni->NewShortArray( 1 ) );
jni.ensure_no_exception();
if (in_param)
{
jni->SetShortArrayRegion(
(jshortArray) jo_ar.get(), 0, 1, (jshort *) uno_data );
jni.ensure_no_exception();
}
java_data->l = jo_ar.release();
}
else
{
if (in_param)
{
jni->SetShortArrayRegion(
(jshortArray) java_data->l, 0, 1, (jshort *) uno_data );
jni.ensure_no_exception();
}
}
}
else if (special_wrapped_integral_types)
{
jvalue arg;
arg.s = *(jshort const *) uno_data;
java_data->l = jni->NewObjectA(
m_jni_info->m_class_Short,
m_jni_info->m_ctor_Short_with_short, &arg );
jni.ensure_no_exception();
}
else
{
java_data->s = *(jshort const *) uno_data;
}
break;
case typelib_TypeClass_LONG:
case typelib_TypeClass_UNSIGNED_LONG:
if (out_param)
{
if (0 == java_data->l)
{
JLocalAutoRef jo_ar( jni, jni->NewIntArray( 1 ) );
jni.ensure_no_exception();
if (in_param)
{
jni->SetIntArrayRegion(
(jintArray) jo_ar.get(), 0, 1, (jint *) uno_data );
jni.ensure_no_exception();
}
java_data->l = jo_ar.release();
}
else
{
if (in_param)
{
jni->SetIntArrayRegion(
(jintArray) java_data->l, 0, 1, (jint *) uno_data );
jni.ensure_no_exception();
}
}
}
else if (special_wrapped_integral_types)
{
jvalue arg;
arg.i = *(jint const *) uno_data;
java_data->l = jni->NewObjectA(
m_jni_info->m_class_Integer,
m_jni_info->m_ctor_Integer_with_int, &arg );
jni.ensure_no_exception();
}
else
{
java_data->i = *(jint const *) uno_data;
}
break;
case typelib_TypeClass_HYPER:
case typelib_TypeClass_UNSIGNED_HYPER:
if (out_param)
{
if (0 == java_data->l)
{
JLocalAutoRef jo_ar( jni, jni->NewLongArray( 1 ) );
jni.ensure_no_exception();
if (in_param)
{
jni->SetLongArrayRegion(
(jlongArray)jo_ar.get(), 0, 1, (jlong *) uno_data );
jni.ensure_no_exception();
}
java_data->l = jo_ar.release();
}
else
{
if (in_param)
{
jni->SetLongArrayRegion(
(jlongArray)java_data->l, 0, 1, (jlong *) uno_data );
jni.ensure_no_exception();
}
}
}
else if (special_wrapped_integral_types)
{
jvalue arg;
arg.j = *(jlong const *) uno_data;
java_data->l = jni->NewObjectA(
m_jni_info->m_class_Long,
m_jni_info->m_ctor_Long_with_long, &arg );
jni.ensure_no_exception();
}
else
{
java_data->j = *(jlong const *) uno_data;
}
break;
case typelib_TypeClass_FLOAT:
if (out_param)
{
if (0 == java_data->l)
{
JLocalAutoRef jo_ar( jni, jni->NewFloatArray( 1 ) );
jni.ensure_no_exception();
if (in_param)
{
jni->SetFloatArrayRegion(
(jfloatArray) jo_ar.get(), 0, 1, (jfloat *) uno_data );
jni.ensure_no_exception();
}
java_data->l = jo_ar.release();
}
else
{
if (in_param)
{
jni->SetFloatArrayRegion(
(jfloatArray) java_data->l, 0, 1, (jfloat *) uno_data );
jni.ensure_no_exception();
}
}
}
else if (special_wrapped_integral_types)
{
jvalue arg;
arg.f = *(jfloat const *) uno_data;
java_data->l = jni->NewObjectA(
m_jni_info->m_class_Float,
m_jni_info->m_ctor_Float_with_float, &arg );
jni.ensure_no_exception();
}
else
{
java_data->f = *(jfloat const *) uno_data;
}
break;
case typelib_TypeClass_DOUBLE:
if (out_param)
{
if (0 == java_data->l)
{
JLocalAutoRef jo_ar( jni, jni->NewDoubleArray( 1 ) );
jni.ensure_no_exception();
if (in_param)
{
jni->SetDoubleArrayRegion(
(jdoubleArray) jo_ar.get(),
0, 1, (jdouble *) uno_data );
jni.ensure_no_exception();
}
java_data->l = jo_ar.release();
}
else
{
if (in_param)
{
jni->SetDoubleArrayRegion(
(jdoubleArray) java_data->l,
0, 1, (jdouble *) uno_data );
jni.ensure_no_exception();
}
}
}
else if (special_wrapped_integral_types)
{
jvalue arg;
arg.d = *(double const *)uno_data;
java_data->l = jni->NewObjectA(
m_jni_info->m_class_Double,
m_jni_info->m_ctor_Double_with_double, &arg );
jni.ensure_no_exception();
}
else
{
java_data->d = *(jdouble const *) uno_data;
}
break;
case typelib_TypeClass_STRING:
{
if (out_param)
{
JLocalAutoRef jo_in( jni );
if (in_param)
{
jo_in.reset(
ustring_to_jstring(
jni, *(rtl_uString * const *) uno_data ) );
}
if (0 == java_data->l)
{
java_data->l = jni->NewObjectArray(
1, m_jni_info->m_class_String, jo_in.get() );
jni.ensure_no_exception();
}
else
{
jni->SetObjectArrayElement(
(jobjectArray) java_data->l, 0, jo_in.get() );
jni.ensure_no_exception();
}
}
else
{
OSL_ASSERT( in_param );
java_data->l =
ustring_to_jstring( jni, *(rtl_uString * const *) uno_data );
}
break;
}
case typelib_TypeClass_TYPE:
{
if (out_param)
{
JLocalAutoRef jo_in( jni );
if (in_param)
{
jo_in.reset(
create_type(
jni,
*(typelib_TypeDescriptionReference * const *) uno_data )
);
}
if (0 == java_data->l)
{
java_data->l = jni->NewObjectArray(
1, m_jni_info->m_class_Type, jo_in.get() );
jni.ensure_no_exception();
}
else
{
jni->SetObjectArrayElement(
(jobjectArray) java_data->l, 0, jo_in.get() );
jni.ensure_no_exception();
}
}
else
{
OSL_ASSERT( in_param );
java_data->l =
create_type(
jni,
*(typelib_TypeDescriptionReference * const *) uno_data );
}
break;
}
case typelib_TypeClass_ANY:
{
JLocalAutoRef jo_any( jni );
if (in_param)
{
uno_Any const * pAny = (uno_Any const *)uno_data;
#if defined BRIDGES_JNI_UNO_FORCE_BOXED_ANY
if (typelib_TypeClass_VOID == pAny->pType->eTypeClass)
{
jo_any.reset(
jni->NewLocalRef( m_jni_info->m_object_Any_VOID ) );
}
else
{
jvalue args[ 2 ];
map_to_java(
jni, &args[ 1 ], pAny->pData, pAny->pType, 0,
true /* in */, false /* no out */,
true /* create integral wrappers */ );
jo_any.reset( args[ 1 ].l );
// build up com.sun.star.uno.Any
JLocalAutoRef jo_type( jni, create_type( jni, pAny->pType ) );
args[ 0 ].l = jo_type.get();
jo_any.reset(
jni->NewObjectA(
m_jni_info->m_class_Any,
m_jni_info->m_ctor_Any_with_Type_Object, args ) );
jni.ensure_no_exception();
}
#else
switch (pAny->pType->eTypeClass)
{
case typelib_TypeClass_VOID:
jo_any.reset(
jni->NewLocalRef( m_jni_info->m_object_Any_VOID ) );
break;
case typelib_TypeClass_UNSIGNED_SHORT:
{
jvalue args[ 2 ];
args[ 0 ].s = *(jshort const *) &pAny->pReserved;
JLocalAutoRef jo_val(
jni, jni->NewObjectA(
m_jni_info->m_class_Short,
m_jni_info->m_ctor_Short_with_short, args ) );
jni.ensure_no_exception();
// box up in com.sun.star.uno.Any
args[ 0 ].l = m_jni_info->m_object_Type_UNSIGNED_SHORT;
args[ 1 ].l = jo_val.get();
jo_any.reset(
jni->NewObjectA(
m_jni_info->m_class_Any,
m_jni_info->m_ctor_Any_with_Type_Object, args ) );
jni.ensure_no_exception();
break;
}
case typelib_TypeClass_UNSIGNED_LONG:
{
jvalue args[ 2 ];
args[ 0 ].i = *(jint const *) &pAny->pReserved;
JLocalAutoRef jo_val(
jni, jni->NewObjectA(
m_jni_info->m_class_Integer,
m_jni_info->m_ctor_Integer_with_int, args ) );
jni.ensure_no_exception();
// box up in com.sun.star.uno.Any
args[ 0 ].l = m_jni_info->m_object_Type_UNSIGNED_LONG;
args[ 1 ].l = jo_val.get();
jo_any.reset(
jni->NewObjectA(
m_jni_info->m_class_Any,
m_jni_info->m_ctor_Any_with_Type_Object, args ) );
jni.ensure_no_exception();
break;
}
case typelib_TypeClass_UNSIGNED_HYPER:
{
jvalue args[ 2 ];
args[ 0 ].j = *(jlong const *) pAny->pData;
JLocalAutoRef jo_val(
jni, jni->NewObjectA(
m_jni_info->m_class_Long,
m_jni_info->m_ctor_Long_with_long, args ) );
jni.ensure_no_exception();
// box up in com.sun.star.uno.Any
args[ 0 ].l = m_jni_info->m_object_Type_UNSIGNED_HYPER;
args[ 1 ].l = jo_val.get();
jo_any.reset(
jni->NewObjectA(
m_jni_info->m_class_Any,
m_jni_info->m_ctor_Any_with_Type_Object, args ) );
jni.ensure_no_exception();
break;
}
case typelib_TypeClass_STRING: // opt strings
jo_any.reset( ustring_to_jstring(
jni, (rtl_uString *) pAny->pReserved ) );
break;
case typelib_TypeClass_SEQUENCE:
{
jvalue java_data2;
// prefetch sequence td
TypeDescr seq_td( pAny->pType );
map_to_java(
jni, &java_data2, pAny->pData, seq_td.get()->pWeakRef, 0,
true /* in */, false /* no out */,
true /* create integral wrappers */ );
jo_any.reset( java_data2.l );
// determine inner element type
::com::sun::star::uno::Type element_type(
((typelib_IndirectTypeDescription *)seq_td.get())->pType );
while (typelib_TypeClass_SEQUENCE ==
element_type.getTypeLibType()->eTypeClass)
{
TypeDescr element_td( element_type.getTypeLibType() );
typelib_typedescriptionreference_assign(
reinterpret_cast< typelib_TypeDescriptionReference ** >(
&element_type ),
((typelib_IndirectTypeDescription *)element_td.get())
->pType );
}
// box up only if unsigned element type
switch (element_type.getTypeLibType()->eTypeClass)
{
case typelib_TypeClass_UNSIGNED_SHORT:
case typelib_TypeClass_UNSIGNED_LONG:
case typelib_TypeClass_UNSIGNED_HYPER:
{
jvalue args[ 2 ];
JLocalAutoRef jo_type(
jni, create_type( jni, seq_td.get()->pWeakRef ) );
args[ 0 ].l = jo_type.get();
args[ 1 ].l = jo_any.get();
jo_any.reset(
jni->NewObjectA(
m_jni_info->m_class_Any,
m_jni_info->m_ctor_Any_with_Type_Object, args ) );
jni.ensure_no_exception();
break;
}
default:
break;
}
break;
}
case typelib_TypeClass_INTERFACE:
{
uno_Interface * pUnoI = (uno_Interface *)pAny->pReserved;
if (is_XInterface( pAny->pType ))
{
if (0 != pUnoI)
{
jo_any.reset(
map_to_java(
jni, pUnoI,
m_jni_info->m_XInterface_type_info ) );
}
// else: empty XInterface ref maps to null-ref
}
else
{
JNI_interface_type_info const * iface_info =
static_cast< JNI_interface_type_info const * >(
m_jni_info->get_type_info( jni, pAny->pType ) );
if (0 != pUnoI)
{
jo_any.reset( map_to_java( jni, pUnoI, iface_info ) );
}
// box up in com.sun.star.uno.Any
jvalue args[ 2 ];
args[ 0 ].l = iface_info->m_type;
args[ 1 ].l = jo_any.get();
jo_any.reset(
jni->NewObjectA(
m_jni_info->m_class_Any,
m_jni_info->m_ctor_Any_with_Type_Object, args ) );
jni.ensure_no_exception();
}
break;
}
case typelib_TypeClass_STRUCT:
{
// Do not lose information about type arguments of instantiated
// polymorphic struct types:
rtl::OUString const & name = rtl::OUString::unacquired(
&pAny->pType->pTypeName);
OSL_ASSERT(!name.isEmpty());
if (name[name.getLength() - 1] == '>')
{
// Box up in com.sun.star.uno.Any:
JLocalAutoRef jo_type(jni, create_type(jni, pAny->pType));
jvalue java_data2;
map_to_java(
jni, &java_data2, pAny->pData, pAny->pType, 0, true,
false);
jo_any.reset(java_data2.l);
jvalue args[2];
args[0].l = jo_type.get();
args[1].l = jo_any.get();
jo_any.reset(
jni->NewObjectA(
m_jni_info->m_class_Any,
m_jni_info->m_ctor_Any_with_Type_Object, args));
jni.ensure_no_exception();
break;
}
// fall through
}
default:
{
jvalue java_data2;
map_to_java(
jni, &java_data2, pAny->pData, pAny->pType, 0,
true /* in */, false /* no out */,
true /* create integral wrappers */ );
jo_any.reset( java_data2.l );
break;
}
}
#endif
}
if (out_param)
{
if (0 == java_data->l)
{
java_data->l = jni->NewObjectArray(
1, m_jni_info->m_class_Object, jo_any.get() );
jni.ensure_no_exception();
}
else
{
jni->SetObjectArrayElement(
(jobjectArray) java_data->l, 0, jo_any.get() );
jni.ensure_no_exception();
}
}
else
{
java_data->l = jo_any.release();
}
break;
}
case typelib_TypeClass_ENUM:
{
OUString const & type_name = OUString::unacquired( &type->pTypeName );
OString class_name(
OUStringToOString( type_name, RTL_TEXTENCODING_JAVA_UTF8 ) );
JLocalAutoRef jo_enum_class(
jni, find_class( jni, class_name.getStr() ) );
JLocalAutoRef jo_enum( jni );
if (in_param)
{
// call static <enum_class>.fromInt( int )
OStringBuffer sig_buf( 5 + class_name.getLength() );
sig_buf.append( RTL_CONSTASCII_STRINGPARAM("(I)L") );
sig_buf.append( class_name.replace( '.', '/' ) );
sig_buf.append( ';' );
OString sig( sig_buf.makeStringAndClear() );
jmethodID method_id = jni->GetStaticMethodID(
(jclass) jo_enum_class.get(), "fromInt", sig.getStr() );
jni.ensure_no_exception();
OSL_ASSERT( 0 != method_id );
jvalue arg;
arg.i = *(jint const *) uno_data;
jo_enum.reset(
jni->CallStaticObjectMethodA(
(jclass) jo_enum_class.get(), method_id, &arg ) );
jni.ensure_no_exception();
}
if (out_param)
{
if (0 == java_data->l)
{
java_data->l = jni->NewObjectArray(
1, (jclass) jo_enum_class.get(), jo_enum.get() );
jni.ensure_no_exception();
}
else
{
jni->SetObjectArrayElement(
(jobjectArray) java_data->l, 0, jo_enum.get() );
jni.ensure_no_exception();
}
}
else
{
java_data->l = jo_enum.release();
}
break;
}
case typelib_TypeClass_STRUCT:
case typelib_TypeClass_EXCEPTION:
{
if (0 == info)
info = m_jni_info->get_type_info( jni, type );
JNI_compound_type_info const * comp_info =
static_cast< JNI_compound_type_info const * >( info );
JLocalAutoRef jo_comp( jni );
if (in_param)
{
if (typelib_TypeClass_EXCEPTION == type->eTypeClass)
{
JLocalAutoRef jo_message(
jni, ustring_to_jstring( jni, *(rtl_uString **)uno_data ) );
jvalue arg;
arg.l = jo_message.get();
jo_comp.reset(
jni->NewObjectA(
comp_info->m_class, comp_info->m_exc_ctor, &arg ) );
jni.ensure_no_exception();
}
else
{
jo_comp.reset( jni->AllocObject( comp_info->m_class ) );
jni.ensure_no_exception();
}
for ( JNI_compound_type_info const * linfo = comp_info;
0 != linfo;
linfo = static_cast< JNI_compound_type_info const * >(
linfo->m_base ) )
{
typelib_CompoundTypeDescription * comp_td =
(typelib_CompoundTypeDescription *)linfo->m_td.get();
typelib_TypeDescriptionReference ** ppMemberTypeRefs =
comp_td->ppTypeRefs;
sal_Int32 * pMemberOffsets = comp_td->pMemberOffsets;
bool polymorphic
= comp_td->aBase.eTypeClass == typelib_TypeClass_STRUCT
&& reinterpret_cast< typelib_StructTypeDescription * >(
comp_td)->pParameterizedTypes != 0;
for ( sal_Int32 nPos = comp_td->nMembers; nPos--; )
{
jfieldID field_id = linfo->m_fields[ nPos ];
if (0 != field_id)
{
void const * p =
(char const *)uno_data + pMemberOffsets[ nPos ];
typelib_TypeDescriptionReference * member_type =
ppMemberTypeRefs[ nPos ];
bool parameterizedType = polymorphic
&& (reinterpret_cast<
typelib_StructTypeDescription * >(comp_td)->
pParameterizedTypes[nPos]);
switch (member_type->eTypeClass)
{
case typelib_TypeClass_CHAR:
if (parameterizedType) {
jvalue arg;
arg.c = *(jchar const *) p;
JLocalAutoRef jo(
jni,
jni->NewObjectA(
m_jni_info->m_class_Character,
m_jni_info->m_ctor_Character_with_char,
&arg ) );
jni.ensure_no_exception();
jni->SetObjectField(
jo_comp.get(), field_id, jo.get() );
} else {
jni->SetCharField(
jo_comp.get(),
field_id, *(jchar const *) p );
}
break;
case typelib_TypeClass_BOOLEAN:
if (parameterizedType) {
jvalue arg;
arg.z = *(jboolean const *) p;
JLocalAutoRef jo(
jni,
jni->NewObjectA(
m_jni_info->m_class_Boolean,
m_jni_info->m_ctor_Boolean_with_boolean,
&arg ) );
jni.ensure_no_exception();
jni->SetObjectField(
jo_comp.get(), field_id, jo.get() );
} else {
jni->SetBooleanField(
jo_comp.get(),
field_id, *(jboolean const *) p );
}
break;
case typelib_TypeClass_BYTE:
if (parameterizedType) {
jvalue arg;
arg.b = *(jbyte const *) p;
JLocalAutoRef jo(
jni,
jni->NewObjectA(
m_jni_info->m_class_Byte,
m_jni_info->m_ctor_Byte_with_byte,
&arg ) );
jni.ensure_no_exception();
jni->SetObjectField(
jo_comp.get(), field_id, jo.get() );
} else {
jni->SetByteField(
jo_comp.get(),
field_id, *(jbyte const *) p );
}
break;
case typelib_TypeClass_SHORT:
case typelib_TypeClass_UNSIGNED_SHORT:
if (parameterizedType) {
jvalue arg;
arg.s = *(jshort const *) p;
JLocalAutoRef jo(
jni,
jni->NewObjectA(
m_jni_info->m_class_Short,
m_jni_info->m_ctor_Short_with_short,
&arg ) );
jni.ensure_no_exception();
jni->SetObjectField(
jo_comp.get(), field_id, jo.get() );
} else {
jni->SetShortField(
jo_comp.get(),
field_id, *(jshort const *) p );
}
break;
case typelib_TypeClass_LONG:
case typelib_TypeClass_UNSIGNED_LONG:
if (parameterizedType) {
jvalue arg;
arg.i = *(jint const *) p;
JLocalAutoRef jo(
jni,
jni->NewObjectA(
m_jni_info->m_class_Integer,
m_jni_info->m_ctor_Integer_with_int,
&arg ) );
jni.ensure_no_exception();
jni->SetObjectField(
jo_comp.get(), field_id, jo.get() );
} else {
jni->SetIntField(
jo_comp.get(),
field_id, *(jint const *) p );
}
break;
case typelib_TypeClass_HYPER:
case typelib_TypeClass_UNSIGNED_HYPER:
if (parameterizedType) {
jvalue arg;
arg.j = *(jlong const *) p;
JLocalAutoRef jo(
jni,
jni->NewObjectA(
m_jni_info->m_class_Long,
m_jni_info->m_ctor_Long_with_long,
&arg ) );
jni.ensure_no_exception();
jni->SetObjectField(
jo_comp.get(), field_id, jo.get() );
} else {
jni->SetLongField(
jo_comp.get(),
field_id, *(jlong const *) p );
}
break;
case typelib_TypeClass_FLOAT:
if (parameterizedType) {
jvalue arg;
arg.f = *(jfloat const *) p;
JLocalAutoRef jo(
jni,
jni->NewObjectA(
m_jni_info->m_class_Float,
m_jni_info->m_ctor_Float_with_float,
&arg ) );
jni.ensure_no_exception();
jni->SetObjectField(
jo_comp.get(), field_id, jo.get() );
} else {
jni->SetFloatField(
jo_comp.get(),
field_id, *(jfloat const *) p );
}
break;
case typelib_TypeClass_DOUBLE:
if (parameterizedType) {
jvalue arg;
arg.d = *(jdouble const *) p;
JLocalAutoRef jo(
jni,
jni->NewObjectA(
m_jni_info->m_class_Double,
m_jni_info->m_ctor_Double_with_double,
&arg ) );
jni.ensure_no_exception();
jni->SetObjectField(
jo_comp.get(), field_id, jo.get() );
} else {
jni->SetDoubleField(
jo_comp.get(),
field_id, *(jdouble const *) p );
}
break;
case typelib_TypeClass_STRING: // string opt here
{
JLocalAutoRef jo_string(
jni, ustring_to_jstring(
jni, *(rtl_uString * const *) p ) );
jni->SetObjectField(
jo_comp.get(), field_id, jo_string.get() );
break;
}
default:
{
jvalue java_data2;
map_to_java(
jni, &java_data2, p, member_type, 0,
true /* in */, false /* no out */ );
JLocalAutoRef jo_obj( jni, java_data2.l );
jni->SetObjectField(
jo_comp.get(), field_id, jo_obj.get() );
break;
}
}
}
}
}
}
if (out_param)
{
if (0 == java_data->l)
{
java_data->l =
jni->NewObjectArray( 1, comp_info->m_class, jo_comp.get() );
jni.ensure_no_exception();
}
else
{
jni->SetObjectArrayElement(
(jobjectArray) java_data->l, 0, jo_comp.get() );
jni.ensure_no_exception();
}
}
else
{
java_data->l = jo_comp.release();
}
break;
}
case typelib_TypeClass_SEQUENCE:
{
// xxx todo: possible opt for pure out sequences
JLocalAutoRef jo_ar( jni );
sal_Int32 nElements;
uno_Sequence const * seq = 0;
if (in_param)
{
seq = *(uno_Sequence * const *)uno_data;
nElements = seq->nElements;
}
else
{
nElements = 0;
}
TypeDescr td( type );
typelib_TypeDescriptionReference * element_type =
((typelib_IndirectTypeDescription *)td.get())->pType;
switch (element_type->eTypeClass)
{
case typelib_TypeClass_CHAR:
jo_ar.reset( jni->NewCharArray( nElements ) );
jni.ensure_no_exception();
if (0 < nElements)
{
jni->SetCharArrayRegion(
(jcharArray) jo_ar.get(),
0, nElements, (jchar *) seq->elements );
jni.ensure_no_exception();
}
break;
case typelib_TypeClass_BOOLEAN:
jo_ar.reset( jni->NewBooleanArray( nElements ) );
jni.ensure_no_exception();
if (0 < nElements)
{
jni->SetBooleanArrayRegion(
(jbooleanArray) jo_ar.get(),
0, nElements, (jboolean *) seq->elements );
jni.ensure_no_exception();
}
break;
case typelib_TypeClass_BYTE:
jo_ar.reset( jni->NewByteArray( nElements ) );
jni.ensure_no_exception();
if (0 < nElements)
{
jni->SetByteArrayRegion(
(jbyteArray) jo_ar.get(),
0, nElements, (jbyte *) seq->elements );
jni.ensure_no_exception();
}
break;
case typelib_TypeClass_SHORT:
case typelib_TypeClass_UNSIGNED_SHORT:
jo_ar.reset( jni->NewShortArray( nElements ) );
jni.ensure_no_exception();
if (0 < nElements)
{
jni->SetShortArrayRegion(
(jshortArray) jo_ar.get(),
0, nElements, (jshort *) seq->elements );
jni.ensure_no_exception();
}
break;
case typelib_TypeClass_LONG:
case typelib_TypeClass_UNSIGNED_LONG:
jo_ar.reset( jni->NewIntArray( nElements ) );
jni.ensure_no_exception();
if (0 < nElements)
{
jni->SetIntArrayRegion(
(jintArray) jo_ar.get(),
0, nElements, (jint *) seq->elements );
jni.ensure_no_exception();
}
break;
case typelib_TypeClass_HYPER:
case typelib_TypeClass_UNSIGNED_HYPER:
jo_ar.reset( jni->NewLongArray( nElements ) );
jni.ensure_no_exception();
if (0 < nElements)
{
jni->SetLongArrayRegion(
(jlongArray) jo_ar.get(),
0, nElements, (jlong *) seq->elements );
jni.ensure_no_exception();
}
break;
case typelib_TypeClass_FLOAT:
jo_ar.reset( jni->NewFloatArray( nElements ) );
jni.ensure_no_exception();
if (0 < nElements)
{
jni->SetFloatArrayRegion(
(jfloatArray) jo_ar.get(),
0, nElements, (jfloat *) seq->elements );
jni.ensure_no_exception();
}
break;
case typelib_TypeClass_DOUBLE:
jo_ar.reset( jni->NewDoubleArray( nElements ) );
jni.ensure_no_exception();
if (0 < nElements)
{
jni->SetDoubleArrayRegion(
(jdoubleArray) jo_ar.get(),
0, nElements, (jdouble *) seq->elements );
jni.ensure_no_exception();
}
break;
case typelib_TypeClass_STRING:
jo_ar.reset(
jni->NewObjectArray(
nElements, m_jni_info->m_class_String, 0 ) );
jni.ensure_no_exception();
if (in_param)
{
rtl_uString * const * pp =
(rtl_uString * const *) seq->elements;
for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
{
JLocalAutoRef jo_string(
jni, ustring_to_jstring( jni, pp[ nPos ] ) );
jni->SetObjectArrayElement(
(jobjectArray) jo_ar.get(), nPos, jo_string.get() );
jni.ensure_no_exception();
}
}
break;
case typelib_TypeClass_TYPE:
jo_ar.reset(
jni->NewObjectArray( nElements, m_jni_info->m_class_Type, 0 ) );
jni.ensure_no_exception();
if (in_param)
{
typelib_TypeDescriptionReference * const * pp =
(typelib_TypeDescriptionReference * const *)seq->elements;
for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
{
jvalue val;
map_to_java(
jni, &val, &pp[ nPos ], element_type, 0,
true /* in */, false /* no out */ );
JLocalAutoRef jo_element( jni, val.l );
jni->SetObjectArrayElement(
(jobjectArray) jo_ar.get(), nPos, jo_element.get() );
jni.ensure_no_exception();
}
}
break;
case typelib_TypeClass_ANY:
jo_ar.reset(
jni->NewObjectArray(
nElements, m_jni_info->m_class_Object, 0 ) );
jni.ensure_no_exception();
if (in_param)
{
uno_Any const * p = (uno_Any const *)seq->elements;
for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
{
jvalue val;
map_to_java(
jni, &val, &p[ nPos ], element_type, 0,
true /* in */, false /* no out */ );
JLocalAutoRef jo_element( jni, val.l );
jni->SetObjectArrayElement(
(jobjectArray) jo_ar.get(), nPos, jo_element.get() );
jni.ensure_no_exception();
}
}
break;
case typelib_TypeClass_ENUM:
{
OUString const & element_type_name =
OUString::unacquired( &element_type->pTypeName );
OString class_name(
OUStringToOString(
element_type_name, RTL_TEXTENCODING_JAVA_UTF8 ) );
JLocalAutoRef jo_enum_class(
jni, find_class( jni, class_name.getStr() ) );
jo_ar.reset(
jni->NewObjectArray(
nElements, (jclass) jo_enum_class.get(), 0 ) );
jni.ensure_no_exception();
if (0 < nElements)
{
// call static <enum_class>.fromInt( int )
OStringBuffer sig_buf( 5 + class_name.getLength() );
sig_buf.append( RTL_CONSTASCII_STRINGPARAM("(I)L") );
sig_buf.append( class_name.replace( '.', '/' ) );
sig_buf.append( ';' );
OString sig( sig_buf.makeStringAndClear() );
jmethodID method_id = jni->GetStaticMethodID(
(jclass) jo_enum_class.get(), "fromInt", sig.getStr() );
jni.ensure_no_exception();
OSL_ASSERT( 0 != method_id );
sal_Int32 const * p = (sal_Int32 const *)seq->elements;
for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
{
jvalue arg;
arg.i = p[ nPos ];
JLocalAutoRef jo_enum(
jni, jni->CallStaticObjectMethodA(
(jclass) jo_enum_class.get(), method_id, &arg ) );
jni.ensure_no_exception();
jni->SetObjectArrayElement(
(jobjectArray) jo_ar.get(), nPos, jo_enum.get() );
jni.ensure_no_exception();
}
}
break;
}
case typelib_TypeClass_STRUCT:
case typelib_TypeClass_EXCEPTION:
{
JNI_type_info const * element_info =
m_jni_info->get_type_info( jni, element_type );
jo_ar.reset(
jni->NewObjectArray( nElements, element_info->m_class, 0 ) );
jni.ensure_no_exception();
if (0 < nElements)
{
char * p = (char *)seq->elements;
sal_Int32 nSize = element_info->m_td.get()->nSize;
for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
{
jvalue val;
map_to_java(
jni, &val, p + (nSize * nPos),
element_type, element_info,
true /* in */, false /* no out */ );
JLocalAutoRef jo_element( jni, val.l );
jni->SetObjectArrayElement(
(jobjectArray) jo_ar.get(), nPos, jo_element.get() );
jni.ensure_no_exception();
}
}
break;
}
case typelib_TypeClass_SEQUENCE:
{
OStringBuffer buf( 64 );
JNI_info::append_sig(
&buf, element_type, false /* use class XInterface */,
false /* '.' instead of '/' */ );
OString class_name( buf.makeStringAndClear() );
JLocalAutoRef jo_seq_class(
jni, find_class( jni, class_name.getStr() ) );
jo_ar.reset(
jni->NewObjectArray(
nElements, (jclass) jo_seq_class.get(), 0 ) );
jni.ensure_no_exception();
if (0 < nElements)
{
TypeDescr element_td( element_type );
uno_Sequence ** elements = (uno_Sequence **) seq->elements;
for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
{
jvalue java_data2;
map_to_java(
jni, &java_data2, elements + nPos, element_type, 0,
true /* in */, false /* no out */ );
JLocalAutoRef jo_seq( jni, java_data2.l );
jni->SetObjectArrayElement(
(jobjectArray) jo_ar.get(), nPos, jo_seq.get() );
jni.ensure_no_exception();
}
}
break;
}
case typelib_TypeClass_INTERFACE:
{
JNI_interface_type_info const * iface_info =
static_cast< JNI_interface_type_info const * >(
m_jni_info->get_type_info( jni, element_type ) );
jo_ar.reset(
jni->NewObjectArray( nElements, iface_info->m_class, 0 ) );
jni.ensure_no_exception();
if (0 < nElements)
{
uno_Interface ** pp = (uno_Interface **)seq->elements;
for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
{
uno_Interface * pUnoI = pp[ nPos ];
if (0 != pUnoI)
{
JLocalAutoRef jo_element(
jni, map_to_java( jni, pUnoI, iface_info ) );
jni->SetObjectArrayElement(
(jobjectArray) jo_ar.get(),
nPos, jo_element.get() );
jni.ensure_no_exception();
}
}
}
break;
}
default:
{
OUStringBuffer buf( 128 );
buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_java():") );
buf.append( OUString::unacquired( &type->pTypeName ) );
buf.appendAscii(
RTL_CONSTASCII_STRINGPARAM("] unsupported element type: ") );
buf.append( OUString::unacquired( &element_type->pTypeName ) );
buf.append( jni.get_stack_trace() );
throw BridgeRuntimeError( buf.makeStringAndClear() );
}
}
if (out_param)
{
if (0 == java_data->l)
{
JLocalAutoRef jo_element_class(
jni, jni->GetObjectClass( jo_ar.get() ) );
if (in_param)
{
java_data->l = jni->NewObjectArray(
1, (jclass) jo_element_class.get(), jo_ar.get() );
}
else
{
java_data->l = jni->NewObjectArray(
1, (jclass) jo_element_class.get(), 0 );
}
jni.ensure_no_exception();
}
else
{
jni->SetObjectArrayElement(
(jobjectArray) java_data->l, 0, jo_ar.get() );
jni.ensure_no_exception();
}
}
else
{
java_data->l = jo_ar.release();
}
break;
}
case typelib_TypeClass_INTERFACE:
{
JLocalAutoRef jo_iface( jni );
if (in_param)
{
uno_Interface * pUnoI = *(uno_Interface * const *)uno_data;
if (0 != pUnoI)
{
if (0 == info)
info = m_jni_info->get_type_info( jni, type );
JNI_interface_type_info const * iface_info =
static_cast< JNI_interface_type_info const * >( info );
jo_iface.reset( map_to_java( jni, pUnoI, iface_info ) );
}
}
if (out_param)
{
if (0 == java_data->l)
{
if (0 == info)
info = m_jni_info->get_type_info( jni, type );
java_data->l =
jni->NewObjectArray( 1, info->m_class, jo_iface.get() );
jni.ensure_no_exception();
}
else
{
jni->SetObjectArrayElement(
(jobjectArray) java_data->l, 0, jo_iface.get() );
jni.ensure_no_exception();
}
}
else
{
java_data->l = jo_iface.release();
}
break;
}
default:
{
OUStringBuffer buf( 128 );
buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_java():") );
buf.append( OUString::unacquired( &type->pTypeName ) );
buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] unsupported type!") );
buf.append( jni.get_stack_trace() );
throw BridgeRuntimeError( buf.makeStringAndClear() );
}
}
}
}