| /************************************************************** |
| * |
| * 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() ); |
| } |
| } |
| } |
| |
| } |