Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quellcode-Bibliothek jni_data.cxx   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   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 .
 */


#include <sal/config.h>

#include <cassert>
#include <memory>

#include "jni_bridge.h"
#include "jni_helper.h"

#include <rtl/strbuf.hxx>
#include <uno/sequence2.h>

namespace jni_uno
{


static std::unique_ptr<rtl_mem> seq_allocate(
    sal_Int32 nElements, sal_Int32 nSize )
{
    std::unique_ptr< rtl_mem > seq(
        rtl_mem::allocate( SAL_SEQUENCE_HEADER_SIZE + (nElements * nSize) ) );
    uno_Sequence * p = reinterpret_cast<uno_Sequence *>(seq.get());
    p->nRefCount = 1;
    p->nElements = nElements;
    return seq;
}


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_castfloat * >(uno_data) = 0;
        break;

    case typelib_TypeClass_DOUBLE:
        *static_castdouble * >(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) = nullptr;
        }
        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);
        assert(
            *static_cast< typelib_TypeDescriptionReference ** >(uno_data) != nullptr);
        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), nullptr);
        }
        uno_any_construct(
            static_cast< uno_Any * >(uno_data), nullptr,
            jni.get_info()->m_XInterface_type_info->m_td.get(), nullptr);
        break;

    case typelib_TypeClass_SEQUENCE:
        {
            std::unique_ptr< rtl_mem > seq(seq_allocate(0, 0));
            if (assign) {
                uno_type_destructData(uno_data, type, nullptr);
            }
            *static_cast< uno_Sequence ** >(uno_data)
                = reinterpret_cast< uno_Sequence * >(seq.release());
            break;
        }

    case typelib_TypeClass_ENUM:
        {
            typelib_TypeDescription * td = nullptr;
            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 == nullptr) {
                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 != nullptr) {
                    createDefaultUnoValue(
                        jni, uno_data,
                        comp_td->pBaseTypeDescription->aBase.pWeakRef,
                        comp_info->m_base, assign);
                }
                for (; nPos < nMembers; ++nPos) {
                    createDefaultUnoValue(
                        jni,
                        (static_castchar * >(uno_data)
                         + comp_td->pMemberOffsets[nPos]),
                        comp_td->ppTypeRefs[nPos], nullptr, assign);
                }
            } catch (...) {
                if (!assign) {
                    for (sal_Int32 i = 0; i < nPos; ++i) {
                        uno_type_destructData(
                            (static_castchar * >(uno_data)
                             + comp_td->pMemberOffsets[i]),
                            comp_td->ppTypeRefs[i], nullptr);
                    }
                    if (comp_td->pBaseTypeDescription != nullptr) {
                        uno_destructData(
                            uno_data, &comp_td->pBaseTypeDescription->aBase, nullptr);
                    }
                }
                throw;
            }
        }
        break;

    case typelib_TypeClass_INTERFACE:
        if (assign) {
            uno_Interface * p = *static_cast< uno_Interface ** >(uno_data);
            if (p != nullptr) {
                (*p->release)(p);
            }
        }
        *static_cast< uno_Interface ** >(uno_data) = nullptr;
        break;

    default:
        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
{
    assert(
        !out_param ||
        (jni->GetArrayLength( static_cast<jarray>(java_data.l) ) == 1) );

    switch (type->eTypeClass)
    {
    case typelib_TypeClass_CHAR:
        if (out_param)
        {
            jni->GetCharArrayRegion(
                static_cast<jcharArray>(java_data.l), 0, 1, static_cast<jchar *>(uno_data) );
            jni.ensure_no_exception();
        }
        else if (special_wrapped_integral_types)
        {
            *static_cast<jchar *>(uno_data) = jni->CallCharMethodA(
                java_data.l, getJniInfo()->m_method_Character_charValue, nullptr );
            jni.ensure_no_exception();
        }
        else
        {
            *static_cast<jchar *>(uno_data) = java_data.c;
        }
        break;
    case typelib_TypeClass_BOOLEAN:
        if (out_param)
        {
            jni->GetBooleanArrayRegion(
                static_cast<jbooleanArray>(java_data.l), 0, 1, static_cast<jboolean *>(uno_data) );
            jni.ensure_no_exception();
        }
        else if (special_wrapped_integral_types)
        {
            *static_cast<jboolean *>(uno_data) = jni->CallBooleanMethodA(
                java_data.l, getJniInfo()->m_method_Boolean_booleanValue, nullptr );
            jni.ensure_no_exception();
        }
        else
        {
            *static_cast<jboolean *>(uno_data) = java_data.z;
        }
        break;
    case typelib_TypeClass_BYTE:
        if (out_param)
        {
            jni->GetByteArrayRegion(
                static_cast<jbyteArray>(java_data.l), 0, 1, static_cast<jbyte *>(uno_data) );
            jni.ensure_no_exception();
        }
        else if (special_wrapped_integral_types)
        {
            *static_cast<jbyte *>(uno_data) = jni->CallByteMethodA(
                java_data.l, getJniInfo()->m_method_Byte_byteValue, nullptr );
            jni.ensure_no_exception();
        }
        else
        {
            *static_cast<jbyte *>(uno_data) = java_data.b;
        }
        break;
    case typelib_TypeClass_SHORT:
    case typelib_TypeClass_UNSIGNED_SHORT:
        if (out_param)
        {
            jni->GetShortArrayRegion(
                static_cast<jshortArray>(java_data.l), 0, 1, static_cast<jshort *>(uno_data) );
            jni.ensure_no_exception();
        }
        else if (special_wrapped_integral_types)
        {
            *static_cast<jshort *>(uno_data) = jni->CallShortMethodA(
                java_data.l, getJniInfo()->m_method_Short_shortValue, nullptr );
            jni.ensure_no_exception();
        }
        else
        {
            *static_cast<jshort *>(uno_data) = java_data.s;
        }
        break;
    case typelib_TypeClass_LONG:
    case typelib_TypeClass_UNSIGNED_LONG:
        if (out_param)
        {
            jni->GetIntArrayRegion(
                static_cast<jintArray>(java_data.l), 0, 1, static_cast<jint *>(uno_data) );
            jni.ensure_no_exception();
        }
        else if (special_wrapped_integral_types)
        {
            *static_cast<jint *>(uno_data) = jni->CallIntMethodA(
                java_data.l, getJniInfo()->m_method_Integer_intValue, nullptr );
            jni.ensure_no_exception();
        }
        else
        {
            *static_cast<jint *>(uno_data) = java_data.i;
        }
        break;
    case typelib_TypeClass_HYPER:
    case typelib_TypeClass_UNSIGNED_HYPER:
        if (out_param)
        {
            jni->GetLongArrayRegion(
                static_cast<jlongArray>(java_data.l), 0, 1, static_cast<jlong *>(uno_data) );
            jni.ensure_no_exception();
        }
        else if (special_wrapped_integral_types)
        {
            *static_cast<jlong *>(uno_data) = jni->CallLongMethodA(
                java_data.l, getJniInfo()->m_method_Long_longValue, nullptr );
            jni.ensure_no_exception();
        }
        else
        {
            *static_cast<jlong *>(uno_data) = java_data.j;
        }
        break;
    case typelib_TypeClass_FLOAT:
        if (out_param)
        {
            jni->GetFloatArrayRegion(
                static_cast<jfloatArray>(java_data.l), 0, 1, static_cast<jfloat *>(uno_data) );
            jni.ensure_no_exception();
        }
        else if (special_wrapped_integral_types)
        {
            *static_cast<jfloat *>(uno_data) = jni->CallFloatMethodA(
                java_data.l, getJniInfo()->m_method_Float_floatValue, nullptr );
            jni.ensure_no_exception();
        }
        else
        {
            *static_cast<jfloat *>(uno_data) = java_data.f;
        }
        break;
    case typelib_TypeClass_DOUBLE:
        if (out_param)
        {
            jni->GetDoubleArrayRegion(
                static_cast<jdoubleArray>(java_data.l), 0, 1, static_cast<jdouble *>(uno_data) );
            jni.ensure_no_exception();
        }
        else if (special_wrapped_integral_types)
        {
            *static_cast<jdouble *>(uno_data) = jni->CallDoubleMethodA(
                java_data.l, getJniInfo()->m_method_Double_doubleValue, nullptr );
            jni.ensure_no_exception();
        }
        else
        {
            *static_cast<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( static_cast<jobjectArray>(java_data.l), 0 ) );
            jni.ensure_no_exception();
            java_data.l = jo_out_holder.get();
        }
        if (java_data.l == nullptr)
        {
            throw BridgeRuntimeError(
                "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
                + "] null-ref given!" + jni.get_stack_trace() );
        }
        if (! assign)
            *static_cast<rtl_uString **>(uno_data) = nullptr;
        jstring_to_ustring(
            jni, static_cast<rtl_uString **>(uno_data), static_cast<jstring>(java_data.l) );
        break;
    }
    case typelib_TypeClass_TYPE:
    {
        JLocalAutoRef jo_out_holder( jni );
        if (out_param)
        {
            jo_out_holder.reset(
                jni->GetObjectArrayElement( static_cast<jobjectArray>(java_data.l), 0 ) );
            jni.ensure_no_exception();
            java_data.l = jo_out_holder.get();
        }
        if (java_data.l == nullptr)
        {
            throw BridgeRuntimeError(
                "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
                + "] null-ref given!" + jni.get_stack_trace() );
        }

        // type name
        JLocalAutoRef jo_type_name(
            jni, jni->GetObjectField(
                java_data.l, getJniInfo()->m_field_Type_typeName ) );
        if (! jo_type_name.is())
        {
            throw BridgeRuntimeError(
                "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
                + "] incomplete type object: no type name!"
                + jni.get_stack_trace() );
        }
        OUString type_name(
            jstring_to_oustring( jni, static_cast<jstring>(jo_type_name.get()) ) );
        ::com::sun::star::uno::TypeDescription td( type_name );
        if (! td.is())
        {
            throw BridgeRuntimeError(
                "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
                + "] UNO type not found: " + type_name
                + jni.get_stack_trace() );
        }
        typelib_typedescriptionreference_acquire( td.get()->pWeakRef );
        if (assign)
        {
            typelib_typedescriptionreference_release(
                *static_cast<typelib_TypeDescriptionReference **>(uno_data) );
        }
        *static_cast<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( static_cast<jobjectArray>(java_data.l), 0 ) );
            jni.ensure_no_exception();
            java_data.l = jo_out_holder.get();
        }

        uno_Any * pAny = static_cast<uno_Any *>(uno_data);
        if (java_data.l == nullptr) // null-ref maps to XInterface null-ref
        {
            if (assign)
                uno_any_destruct( pAny, nullptr );
            uno_any_construct(
                pAny, nullptr, getJniInfo()->m_XInterface_type_info->m_td.get(), nullptr );
            break;
        }

        JLocalAutoRef jo_type( jni );
        JLocalAutoRef jo_wrapped_holder( jni );

        if (jni->IsInstanceOf( java_data.l, getJniInfo()->m_class_Any ))
        {
            // boxed any
            jo_type.reset( jni->GetObjectField(
                               java_data.l, getJniInfo()->m_field_Any_type ) );
            if (! jo_type.is())
            {
                throw BridgeRuntimeError(
                    "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
                    + "] no type set at com.sun.star.uno.Any!"
                    + jni.get_stack_trace() );
            }
            // wrapped value
            jo_wrapped_holder.reset(
                jni->GetObjectField(
                    java_data.l, getJniInfo()->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, static_cast<jclass>(jo_class.get()) ) );
        }

        // get type name
        JLocalAutoRef jo_type_name(
            jni, jni->GetObjectField(
                jo_type.get(), getJniInfo()->m_field_Type_typeName ) );
        jni.ensure_no_exception();
        OUString type_name(
            jstring_to_oustring( jni, static_cast<jstring>(jo_type_name.get()) ) );

        ::com::sun::star::uno::TypeDescription value_td( type_name );
        if (! value_td.is())
        {
            throw BridgeRuntimeError(
                "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
                + "] UNO type not found: " + type_name
                + jni.get_stack_trace() );
        }
        typelib_TypeClass type_class = value_td.get()->eTypeClass;

        if (assign)
        {
            uno_any_destruct( pAny, nullptr );
        }
        try
        {
            switch (type_class)
            {
            case typelib_TypeClass_VOID:
                pAny->pData = &pAny->pReserved;
                break;
            case typelib_TypeClass_CHAR:
                pAny->pData = &pAny->pReserved;
                *static_cast<jchar *>(pAny->pData) = jni->CallCharMethodA(
                    java_data.l, getJniInfo()->m_method_Character_charValue, nullptr );
                jni.ensure_no_exception();
                break;
            case typelib_TypeClass_BOOLEAN:
                pAny->pData = &pAny->pReserved;
                *static_cast<jboolean *>(pAny->pData) = jni->CallBooleanMethodA(
                    java_data.l, getJniInfo()->m_method_Boolean_booleanValue, nullptr );
                jni.ensure_no_exception();
                break;
            case typelib_TypeClass_BYTE:
                pAny->pData = &pAny->pReserved;
                *static_cast<jbyte *>(pAny->pData) = jni->CallByteMethodA(
                    java_data.l, getJniInfo()->m_method_Byte_byteValue, nullptr );
                jni.ensure_no_exception();
                break;
            case typelib_TypeClass_SHORT:
            case typelib_TypeClass_UNSIGNED_SHORT:
                pAny->pData = &pAny->pReserved;
                *static_cast<jshort *>(pAny->pData) = jni->CallShortMethodA(
                    java_data.l, getJniInfo()->m_method_Short_shortValue, nullptr );
                jni.ensure_no_exception();
                break;
            case typelib_TypeClass_LONG:
            case typelib_TypeClass_UNSIGNED_LONG:
                pAny->pData = &pAny->pReserved;
                *static_cast<jint *>(pAny->pData) = jni->CallIntMethodA(
                    java_data.l, getJniInfo()->m_method_Integer_intValue, nullptr );
                jni.ensure_no_exception();
                break;
            case typelib_TypeClass_HYPER:
            case typelib_TypeClass_UNSIGNED_HYPER:
                if (sizeof (sal_Int64) <= sizeof (void *))
                {
                    pAny->pData = &pAny->pReserved;
                    *static_cast<jlong *>(pAny->pData) = jni->CallLongMethodA(
                        java_data.l, getJniInfo()->m_method_Long_longValue, nullptr );
                    jni.ensure_no_exception();
                }
                else
                {
                    std::unique_ptr< rtl_mem > mem(
                        rtl_mem::allocate( sizeof (sal_Int64) ) );
                    *reinterpret_cast<jlong *>(mem.get()) = jni->CallLongMethodA(
                        java_data.l, getJniInfo()->m_method_Long_longValue, nullptr );
                    jni.ensure_no_exception();
                    pAny->pData = mem.release();
                }
                break;
            case typelib_TypeClass_FLOAT:
                if (sizeof (float) <= sizeof (void *))
                {
                    pAny->pData = &pAny->pReserved;
                    *static_cast<jfloat *>(pAny->pData) = jni->CallFloatMethodA(
                        java_data.l, getJniInfo()->m_method_Float_floatValue, nullptr );
                    jni.ensure_no_exception();
                }
                else
                {
                    std::unique_ptr< rtl_mem > mem(
                        rtl_mem::allocate( sizeof (float) ) );
                    *reinterpret_cast<jfloat *>(mem.get()) = jni->CallFloatMethodA(
                        java_data.l, getJniInfo()->m_method_Float_floatValue, nullptr );
                    jni.ensure_no_exception();
                    pAny->pData = mem.release();
                }
                break;
            case typelib_TypeClass_DOUBLE:
                if (sizeof (double) <= sizeof (void *))
                {
                    pAny->pData = &pAny->pReserved;
                    *static_cast<jdouble *>(pAny->pData) =
                        jni->CallDoubleMethodA(
                            java_data.l,
                            getJniInfo()->m_method_Double_doubleValue, nullptr );
                    jni.ensure_no_exception();
                }
                else
                {
                    std::unique_ptr< rtl_mem > mem(
                        rtl_mem::allocate( sizeof (double) ) );
                    *reinterpret_cast<jdouble *>(mem.get()) =
                        jni->CallDoubleMethodA(
                            java_data.l,
                            getJniInfo()->m_method_Double_doubleValue, nullptr );
                    jni.ensure_no_exception();
                    pAny->pData = mem.release();
                }
                break;
            case typelib_TypeClass_STRING:
                // opt: anies often contain strings; copy string directly
                pAny->pReserved = nullptr;
                pAny->pData = &pAny->pReserved;
                jstring_to_ustring(
                    jni, static_cast<rtl_uString **>(pAny->pData),
                    static_cast<jstring>(java_data.l) );
                break;
            case typelib_TypeClass_TYPE:
            case typelib_TypeClass_ENUM:
            case typelib_TypeClass_SEQUENCE:
            case typelib_TypeClass_INTERFACE:
                pAny->pData = &pAny->pReserved;
                map_to_uno(
                    jni, pAny->pData, java_data,
                    value_td.get()->pWeakRef, nullptr,
                    false /* no assign */, false /* no out param */ );
                break;
            case typelib_TypeClass_STRUCT:
            case typelib_TypeClass_EXCEPTION:
            {
                std::unique_ptr< rtl_mem > mem(
                    rtl_mem::allocate( value_td.get()->nSize ) );
                map_to_uno(
                    jni, mem.get(), java_data, value_td.get()->pWeakRef, nullptr,
                    false /* no assign */, false /* no out param */ );
                pAny->pData = mem.release();
                break;
            }
            default:
            {
                throw BridgeRuntimeError(
                    "[map_to_uno():" + type_name
                    + "] unsupported value type of any!"
                    + jni.get_stack_trace() );
            }
            }
        }
        catch (...)
        {
            if (assign)
            {
                // restore to valid any
                uno_any_construct( pAny, nullptr, nullptr, nullptr );
            }
            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( static_cast<jobjectArray>(java_data.l), 0 ) );
            jni.ensure_no_exception();
            java_data.l = jo_out_holder.get();
        }
        if (java_data.l == nullptr)
        {
            throw BridgeRuntimeError(
                "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
                + "] null-ref given!" + jni.get_stack_trace() );
        }

        *static_cast<jint *>(uno_data) = jni->GetIntField(
            java_data.l, getJniInfo()->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( static_cast<jobjectArray>(java_data.l), 0 ) );
            jni.ensure_no_exception();
            java_data.l = jo_out_holder.get();
        }
        if (java_data.l == nullptr)
        {
            throw BridgeRuntimeError(
                "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
                + "] null-ref given!" + jni.get_stack_trace() );
        }

        if (info == nullptr)
            info = getJniInfo()->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());
        bool polymorphic
            = comp_td->aBase.eTypeClass == typelib_TypeClass_STRUCT
            && reinterpret_cast< typelib_StructTypeDescription * >(
                comp_td)->pParameterizedTypes != nullptr;

        sal_Int32 nPos = 0;
        sal_Int32 nMembers = comp_td->nMembers;
        try
        {
            if (comp_td->pBaseTypeDescription != nullptr)
            {
                map_to_uno(
                    jni, uno_data, java_data,
                    comp_td->pBaseTypeDescription->aBase.pWeakRef,
                    comp_info->m_base,
                    assign, false /* no out param */ );
            }

            for ( ; nPos < nMembers; ++nPos )
            {
                void * p = static_cast<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() == nullptr ) {
                            *static_cast<jchar *>(p) = 0;
                        } else {
                            jvalue val;
                            val.l = jo.get();
                            map_to_uno(
                                jni, p, val, member_type, nullptr, assign, false,
                                true );
                        }
                    } else {
                        *static_cast<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() == nullptr ) {
                            *static_cast<jboolean *>(p) = false;
                        } else {
                            jvalue val;
                            val.l = jo.get();
                            map_to_uno(
                                jni, p, val, member_type, nullptr, assign, false,
                                true );
                        }
                    } else {
                        *static_cast<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() == nullptr ) {
                            *static_cast<jbyte *>(p) = 0;
                        } else {
                            jvalue val;
                            val.l = jo.get();
                            map_to_uno(
                                jni, p, val, member_type, nullptr, assign, false,
                                true );
                        }
                    } else {
                        *static_cast<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() == nullptr ) {
                            *static_cast<jshort *>(p) = 0;
                        } else {
                            jvalue val;
                            val.l = jo.get();
                            map_to_uno(
                                jni, p, val, member_type, nullptr, assign, false,
                                true );
                        }
                    } else {
                        *static_cast<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() == nullptr ) {
                            *static_cast<jint *>(p) = 0;
                        } else {
                            jvalue val;
                            val.l = jo.get();
                            map_to_uno(
                                jni, p, val, member_type, nullptr, assign, false,
                                true );
                        }
                    } else {
                        *static_cast<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() == nullptr ) {
                            *static_cast<jlong *>(p) = 0;
                        } else {
                            jvalue val;
                            val.l = jo.get();
                            map_to_uno(
                                jni, p, val, member_type, nullptr, assign, false,
                                true );
                        }
                    } else {
                        *static_cast<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() == nullptr ) {
                            *static_cast<jfloat *>(p) = 0;
                        } else {
                            jvalue val;
                            val.l = jo.get();
                            map_to_uno(
                                jni, p, val, member_type, nullptr, assign, false,
                                true );
                        }
                    } else {
                        *static_cast<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() == nullptr ) {
                            *static_cast<jdouble *>(p) = 0;
                        } else {
                            jvalue val;
                            val.l = jo.get();
                            map_to_uno(
                                jni, p, val, member_type, nullptr, assign, false,
                                true );
                        }
                    } else {
                        *static_cast<jdouble *>(p) = jni->GetDoubleField(
                            java_data.l, field_id );
                    }
                    break;
                default:
                {
                    JLocalAutoRef jo_field( jni );
                    bool checkNull;
                    if (field_id == nullptr)
                    {
                        // special for Message: call Throwable.getMessage()
                        assert(
                            type_equals(
                                type,
                                getJniInfo()->m_Exception_type.getTypeLibType() )
                            || type_equals(
                                type,
                                getJniInfo()->m_RuntimeException_type.
                                getTypeLibType() ) );
                        assert( nPos == 0 ); // first member
                        // call getMessage()
                        jo_field.reset(
                            jni->CallObjectMethodA(
                                java_data.l,
                                getJniInfo()->m_method_Throwable_getMessage, nullptr )
                            );
                        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, nullptr, assign);
                    } else {
                        jvalue val;
                        val.l = jo_field.get();
                        map_to_uno(
                            jni, p, val, member_type, nullptr,
                            assign, false /* no out param */ );
                    }
                    break;
                }
                }
            }
        }
        catch (...)
        {
            if (! assign)
            {
                // cleanup
                for ( sal_Int32 nCleanup = 0; nCleanup < nPos; ++nCleanup )
                {
                    void * p =
                        static_cast<char *>(uno_data) + comp_td->pMemberOffsets[ nCleanup ];
                    uno_type_destructData(
                        p, comp_td->ppTypeRefs[ nCleanup ], nullptr );
                }
                if (comp_td->pBaseTypeDescription != nullptr)
                {
                    uno_destructData(
                        uno_data, &comp_td->pBaseTypeDescription->aBase, nullptr );
                }
            }
            throw;
        }
        break;
    }
    case typelib_TypeClass_SEQUENCE:
    {
        JLocalAutoRef jo_out_holder( jni );
        if (out_param)
        {
            jo_out_holder.reset(
                jni->GetObjectArrayElement( static_cast<jobjectArray>(java_data.l), 0 ) );
            jni.ensure_no_exception();
            java_data.l = jo_out_holder.get();
        }
        if (java_data.l == nullptr)
        {
            throw BridgeRuntimeError(
                "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
                + "] null-ref given!" + jni.get_stack_trace() );
        }

        TypeDescr td( type );
        typelib_TypeDescriptionReference * element_type =
            reinterpret_cast<typelib_IndirectTypeDescription *>(td.get())->pType;

        std::unique_ptr< rtl_mem > seq;
        sal_Int32 nElements = jni->GetArrayLength( static_cast<jarray>(java_data.l) );

        switch (element_type->eTypeClass)
        {
        case typelib_TypeClass_CHAR:
            seq = seq_allocate( nElements, sizeof (sal_Unicode) );
            jni->GetCharArrayRegion(
                static_cast<jcharArray>(java_data.l), 0, nElements,
                reinterpret_cast<jchar *>(reinterpret_cast<uno_Sequence *>(seq.get())->elements) );
            jni.ensure_no_exception();
            break;
        case typelib_TypeClass_BOOLEAN:
            seq = seq_allocate( nElements, sizeof (sal_Bool) );
            jni->GetBooleanArrayRegion(
                static_cast<jbooleanArray>(java_data.l), 0, nElements,
                reinterpret_cast<jboolean *>(reinterpret_cast<uno_Sequence *>(seq.get())->elements) );
            jni.ensure_no_exception();
            break;
        case typelib_TypeClass_BYTE:
            seq = seq_allocate( nElements, sizeof (sal_Int8) );
            jni->GetByteArrayRegion(
                static_cast<jbyteArray>(java_data.l), 0, nElements,
                reinterpret_cast<jbyte *>(reinterpret_cast<uno_Sequence *>(seq.get())->elements) );
            jni.ensure_no_exception();
            break;
        case typelib_TypeClass_SHORT:
        case typelib_TypeClass_UNSIGNED_SHORT:
            seq = seq_allocate( nElements, sizeof (sal_Int16) );
            jni->GetShortArrayRegion(
                static_cast<jshortArray>(java_data.l), 0, nElements,
                reinterpret_cast<jshort *>(reinterpret_cast<uno_Sequence *>(seq.get())->elements) );
            jni.ensure_no_exception();
            break;
        case typelib_TypeClass_LONG:
        case typelib_TypeClass_UNSIGNED_LONG:
            seq = seq_allocate( nElements, sizeof (sal_Int32) );
            jni->GetIntArrayRegion(
                static_cast<jintArray>(java_data.l), 0, nElements,
                reinterpret_cast<jint *>(reinterpret_cast<uno_Sequence *>(seq.get())->elements) );
            jni.ensure_no_exception();
            break;
        case typelib_TypeClass_HYPER:
        case typelib_TypeClass_UNSIGNED_HYPER:
            seq = seq_allocate( nElements, sizeof (sal_Int64) );
            jni->GetLongArrayRegion(
                static_cast<jlongArray>(java_data.l), 0, nElements,
                reinterpret_cast<jlong *>(reinterpret_cast<uno_Sequence *>(seq.get())->elements) );
            jni.ensure_no_exception();
            break;
        case typelib_TypeClass_FLOAT:
            seq = seq_allocate( nElements, sizeof (float) );
            jni->GetFloatArrayRegion(
                static_cast<jfloatArray>(java_data.l), 0, nElements,
                reinterpret_cast<jfloat *>(reinterpret_cast<uno_Sequence *>(seq.get())->elements) );
            jni.ensure_no_exception();
            break;
        case typelib_TypeClass_DOUBLE:
            seq = seq_allocate( nElements, sizeof (double) );
            jni->GetDoubleArrayRegion(
                static_cast<jdoubleArray>(java_data.l), 0, nElements,
                reinterpret_cast<jdouble *>(reinterpret_cast<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 = seq_allocate( nElements, element_td.get()->nSize );

            JNI_type_info const * element_info;
            if (element_type->eTypeClass == typelib_TypeClass_STRUCT ||
                element_type->eTypeClass == typelib_TypeClass_EXCEPTION ||
                element_type->eTypeClass == typelib_TypeClass_INTERFACE)
            {
                element_info =
                    getJniInfo()->get_type_info( jni, element_td.get() );
            }
            else
            {
                element_info = nullptr;
            }

            for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
            {
                try
                {
                    JLocalAutoRef jo(
                        jni, jni->GetObjectArrayElement(
                            static_cast<jobjectArray>(java_data.l), nPos ) );
                    jni.ensure_no_exception();
                    jvalue val;
                    val.l = jo.get();
                    void * p =
                        reinterpret_cast<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 =
                            reinterpret_cast<uno_Sequence *>(seq.get())->elements +
                            (nCleanPos * element_td.get()->nSize);
                        uno_destructData( p, element_td.get(), nullptr );
                    }
                    throw;
                }
            }
            break;
        }
        default:
        {
            throw BridgeRuntimeError(
                "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
                + "] unsupported sequence element type: "
                + OUString::unacquired( &element_type->pTypeName )
                + jni.get_stack_trace() );
        }
        }

        if (assign)
            uno_destructData( uno_data, td.get(), nullptr );
        *static_cast<uno_Sequence **>(uno_data) = reinterpret_cast<uno_Sequence *>(seq.release());
        break;
    }
    case typelib_TypeClass_INTERFACE:
    {
        JLocalAutoRef jo_out_holder( jni );
        if (out_param)
        {
            jo_out_holder.reset(
                jni->GetObjectArrayElement( static_cast<jobjectArray>(java_data.l), 0 ) );
            jni.ensure_no_exception();
            java_data.l = jo_out_holder.get();
        }

        if (java_data.l == nullptr) // null-ref
        {
            if (assign)
            {
                uno_Interface * p = *static_cast<uno_Interface **>(uno_data);
                if (p != nullptr)
                    (*p->release)( p );
            }
            *static_cast<uno_Interface **>(uno_data) = nullptr;
        }
        else
        {
            if (info == nullptr)
                info = getJniInfo()->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 = *static_cast<uno_Interface **>(uno_data);
                if (p != nullptr)
                    (*p->release)( p );
            }
            *static_cast<uno_Interface **>(uno_data) = pUnoI;
        }
        break;
    }
    default:
    {
        throw BridgeRuntimeError(
            "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
            + "] unsupported type!" + jni.get_stack_trace() );
    }
    }
}


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
{
    // 4th param of Set*ArrayRegion changed from pointer to non-const to pointer
    // to const between <http://docs.oracle.com/javase/6/docs/technotes/guides/
    // jni/spec/functions.html#wp22933> and <http://docs.oracle.com/javase/7/
    // docs/technotes/guides/jni/spec/functions.html#wp22933>; work around that
    // difference in a way that doesn't trigger loplugin:redundantcast:
    void * data = const_cast<void *>(uno_data);

    switch (type->eTypeClass)
    {
    case typelib_TypeClass_CHAR:
        if (out_param)
        {
            if (java_data->l == nullptr)
            {
                JLocalAutoRef jo_ar( jni, jni->NewCharArray( 1 ) );
                jni.ensure_no_exception();
                if (in_param)
                {
                    jni->SetCharArrayRegion(
                        static_cast<jcharArray>(jo_ar.get()), 0, 1, static_cast<jchar *>(data) );
                    jni.ensure_no_exception();
                }
                java_data->l = jo_ar.release();
            }
            else
            {
                if (in_param)
                {
                    jni->SetCharArrayRegion(
                        static_cast<jcharArray>(java_data->l), 0, 1, static_cast<jchar *>(data) );
                    jni.ensure_no_exception();
                }
            }
        }
        else if (special_wrapped_integral_types)
        {
            jvalue arg;
            arg.c = *static_cast<jchar const *>(uno_data);
            java_data->l = jni->NewObjectA(
                getJniInfo()->m_class_Character,
                getJniInfo()->m_ctor_Character_with_char, &arg );
            jni.ensure_no_exception();
        }
        else
        {
            java_data->c = *static_cast<jchar const *>(uno_data);
        }
        break;
    case typelib_TypeClass_BOOLEAN:
        if (out_param)
        {
            if (java_data->l == nullptr)
            {
                JLocalAutoRef jo_ar( jni, jni->NewBooleanArray( 1 ) );
                jni.ensure_no_exception();
                if (in_param)
                {
                    jni->SetBooleanArrayRegion(
                        static_cast<jbooleanArray>(jo_ar.get()),
                        0, 1, static_cast<jboolean *>(data) );
                    jni.ensure_no_exception();
                }
                java_data->l = jo_ar.release();
            }
            else
            {
                if (in_param)
                {
                    jni->SetBooleanArrayRegion(
                        static_cast<jbooleanArray>(java_data->l),
                        0, 1, static_cast<jboolean *>(data) );
                    jni.ensure_no_exception();
                }
            }
        }
        else if (special_wrapped_integral_types)
        {
            jvalue arg;
            arg.z = *static_cast<jboolean const *>(uno_data);
            java_data->l = jni->NewObjectA(
                getJniInfo()->m_class_Boolean,
                getJniInfo()->m_ctor_Boolean_with_boolean, &arg );
            jni.ensure_no_exception();
        }
        else
        {
            java_data->z = *static_cast<jboolean const *>(uno_data);
        }
        break;
    case typelib_TypeClass_BYTE:
        if (out_param)
        {
            if (java_data->l == nullptr)
            {
                JLocalAutoRef jo_ar( jni, jni->NewByteArray( 1 ) );
                jni.ensure_no_exception();
                if (in_param)
                {
                    jni->SetByteArrayRegion(
                        static_cast<jbyteArray>(jo_ar.get()), 0, 1, static_cast<jbyte *>(data) );
                    jni.ensure_no_exception();
                }
                java_data->l = jo_ar.release();
            }
            else
            {
                if (in_param)
                {
                    jni->SetByteArrayRegion(
                        static_cast<jbyteArray>(java_data->l), 0, 1, static_cast<jbyte *>(data) );
                    jni.ensure_no_exception();
                }
            }
        }
        else if (special_wrapped_integral_types)
        {
            jvalue arg;
            arg.b = *static_cast<jbyte const *>(uno_data);
            java_data->l = jni->NewObjectA(
                getJniInfo()->m_class_Byte,
                getJniInfo()->m_ctor_Byte_with_byte, &arg );
            jni.ensure_no_exception();
        }
        else
        {
            java_data->b = *static_cast<jbyte const *>(uno_data);
        }
        break;
    case typelib_TypeClass_SHORT:
    case typelib_TypeClass_UNSIGNED_SHORT:
        if (out_param)
        {
            if (java_data->l == nullptr)
            {
                JLocalAutoRef jo_ar( jni, jni->NewShortArray( 1 ) );
                jni.ensure_no_exception();
                if (in_param)
                {
                    jni->SetShortArrayRegion(
                        static_cast<jshortArray>(jo_ar.get()), 0, 1, static_cast<jshort *>(data) );
                    jni.ensure_no_exception();
                }
                java_data->l = jo_ar.release();
            }
            else
            {
                if (in_param)
                {
                    jni->SetShortArrayRegion(
                        static_cast<jshortArray>(java_data->l), 0, 1, static_cast<jshort *>(data) );
                    jni.ensure_no_exception();
                }
            }
        }
        else if (special_wrapped_integral_types)
        {
            jvalue arg;
            arg.s = *static_cast<jshort const *>(uno_data);
            java_data->l = jni->NewObjectA(
                getJniInfo()->m_class_Short,
                getJniInfo()->m_ctor_Short_with_short, &arg );
            jni.ensure_no_exception();
        }
        else
        {
            java_data->s = *static_cast<jshort const *>(uno_data);
        }
        break;
    case typelib_TypeClass_LONG:
    case typelib_TypeClass_UNSIGNED_LONG:
        if (out_param)
        {
            if (java_data->l == nullptr)
            {
                JLocalAutoRef jo_ar( jni, jni->NewIntArray( 1 ) );
                jni.ensure_no_exception();
                if (in_param)
                {
                    jni->SetIntArrayRegion(
                        static_cast<jintArray>(jo_ar.get()), 0, 1, static_cast<jint *>(data) );
                    jni.ensure_no_exception();
                }
                java_data->l = jo_ar.release();
            }
            else
            {
                if (in_param)
                {
                    jni->SetIntArrayRegion(
                        static_cast<jintArray>(java_data->l), 0, 1, static_cast<jint *>(data) );
                    jni.ensure_no_exception();
                }
            }
        }
        else if (special_wrapped_integral_types)
        {
            jvalue arg;
            arg.i = *static_cast<jint const *>(uno_data);
            java_data->l = jni->NewObjectA(
                getJniInfo()->m_class_Integer,
                getJniInfo()->m_ctor_Integer_with_int, &arg );
            jni.ensure_no_exception();
        }
        else
        {
            java_data->i = *static_cast<jint const *>(uno_data);
        }
        break;
    case typelib_TypeClass_HYPER:
    case typelib_TypeClass_UNSIGNED_HYPER:
        if (out_param)
        {
            if (java_data->l == nullptr)
            {
                JLocalAutoRef jo_ar( jni, jni->NewLongArray( 1 ) );
                jni.ensure_no_exception();
                if (in_param)
                {
                    jni->SetLongArrayRegion(
                        static_cast<jlongArray>(jo_ar.get()), 0, 1, static_cast<jlong *>(data) );
                    jni.ensure_no_exception();
                }
                java_data->l = jo_ar.release();
            }
            else
            {
                if (in_param)
                {
                    jni->SetLongArrayRegion(
                        static_cast<jlongArray>(java_data->l), 0, 1, static_cast<jlong *>(data) );
                    jni.ensure_no_exception();
                }
            }
        }
        else if (special_wrapped_integral_types)
        {
            jvalue arg;
            arg.j = *static_cast<jlong const *>(uno_data);
            java_data->l = jni->NewObjectA(
                getJniInfo()->m_class_Long,
                getJniInfo()->m_ctor_Long_with_long, &arg );
            jni.ensure_no_exception();
        }
        else
        {
            java_data->j = *static_cast<jlong const *>(uno_data);
        }
        break;
    case typelib_TypeClass_FLOAT:
        if (out_param)
        {
            if (java_data->l == nullptr)
            {
                JLocalAutoRef jo_ar( jni, jni->NewFloatArray( 1 ) );
                jni.ensure_no_exception();
                if (in_param)
                {
                    jni->SetFloatArrayRegion(
                        static_cast<jfloatArray>(jo_ar.get()), 0, 1, static_cast<jfloat *>(data) );
                    jni.ensure_no_exception();
                }
                java_data->l = jo_ar.release();
            }
            else
            {
                if (in_param)
                {
                    jni->SetFloatArrayRegion(
                        static_cast<jfloatArray>(java_data->l), 0, 1, static_cast<jfloat *>(data) );
                    jni.ensure_no_exception();
                }
            }
        }
        else if (special_wrapped_integral_types)
        {
            jvalue arg;
            arg.f = *static_cast<jfloat const *>(uno_data);
            java_data->l = jni->NewObjectA(
                getJniInfo()->m_class_Float,
                getJniInfo()->m_ctor_Float_with_float, &arg );
            jni.ensure_no_exception();
        }
        else
        {
            java_data->f = *static_cast<jfloat const *>(uno_data);
        }
        break;
    case typelib_TypeClass_DOUBLE:
        if (out_param)
        {
            if (java_data->l == nullptr)
            {
                JLocalAutoRef jo_ar( jni, jni->NewDoubleArray( 1 ) );
                jni.ensure_no_exception();
                if (in_param)
                {
                    jni->SetDoubleArrayRegion(
                        static_cast<jdoubleArray>(jo_ar.get()),
                        0, 1, static_cast<jdouble *>(data) );
                    jni.ensure_no_exception();
                }
                java_data->l = jo_ar.release();
            }
            else
            {
                if (in_param)
                {
                    jni->SetDoubleArrayRegion(
                        static_cast<jdoubleArray>(java_data->l),
                        0, 1, static_cast<jdouble *>(data) );
                    jni.ensure_no_exception();
                }
            }
        }
        else if (special_wrapped_integral_types)
        {
            jvalue arg;
            arg.d = *static_cast<double const *>(uno_data);
            java_data->l = jni->NewObjectA(
                getJniInfo()->m_class_Double,
                getJniInfo()->m_ctor_Double_with_double, &arg );
            jni.ensure_no_exception();
        }
        else
        {
            java_data->d = *static_cast<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, *static_cast<rtl_uString * const *>(uno_data) ) );
            }
            if (java_data->l == nullptr)
            {
                java_data->l = jni->NewObjectArray(
                    1, getJniInfo()->m_class_String, jo_in.get() );
                jni.ensure_no_exception();
            }
            else
            {
                jni->SetObjectArrayElement(
                    static_cast<jobjectArray>(java_data->l), 0, jo_in.get() );
                jni.ensure_no_exception();
            }
        }
        else
        {
            assert( in_param );
            java_data->l =
                ustring_to_jstring( jni, *static_cast<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,
                        *static_cast<typelib_TypeDescriptionReference * const *>(uno_data) )
                    );
            }
            if (java_data->l == nullptr)
            {
                java_data->l = jni->NewObjectArray(
                    1, getJniInfo()->m_class_Type, jo_in.get() );
                jni.ensure_no_exception();
            }
            else
            {
                jni->SetObjectArrayElement(
                    static_cast<jobjectArray>(java_data->l), 0, jo_in.get() );
                jni.ensure_no_exception();
            }
        }
        else
        {
            assert( in_param );
            java_data->l =
                create_type(
                    jni,
                    *static_cast<typelib_TypeDescriptionReference * const *>(uno_data) );
        }
        break;
    }
    case typelib_TypeClass_ANY:
    {
        JLocalAutoRef jo_any( jni );
        if (in_param)
        {
            uno_Any const * pAny = static_cast<uno_Any const *>(uno_data);
            switch (pAny->pType->eTypeClass)
            {
            case typelib_TypeClass_VOID:
                jo_any.reset(
                    jni->NewLocalRef( getJniInfo()->m_object_Any_VOID ) );
                break;
            case typelib_TypeClass_UNSIGNED_SHORT:
            {
                jvalue args[ 2 ];
                args[ 0 ].s = *static_cast<jshort const *>(pAny->pData);
                JLocalAutoRef jo_val(
                    jni, jni->NewObjectA(
                        getJniInfo()->m_class_Short,
                        getJniInfo()->m_ctor_Short_with_short, args ) );
                jni.ensure_no_exception();
                // box up in com.sun.star.uno.Any
                args[ 0 ].l = getJniInfo()->m_object_Type_UNSIGNED_SHORT;
                args[ 1 ].l = jo_val.get();
                jo_any.reset(
                    jni->NewObjectA(
                        getJniInfo()->m_class_Any,
                        getJniInfo()->m_ctor_Any_with_Type_Object, args ) );
                jni.ensure_no_exception();
                break;
            }
            case typelib_TypeClass_UNSIGNED_LONG:
            {
                jvalue args[ 2 ];
                args[ 0 ].i = *static_cast<jint const *>(pAny->pData);
                JLocalAutoRef jo_val(
                    jni, jni->NewObjectA(
                        getJniInfo()->m_class_Integer,
                        getJniInfo()->m_ctor_Integer_with_int, args ) );
                jni.ensure_no_exception();
                // box up in com.sun.star.uno.Any
                args[ 0 ].l = getJniInfo()->m_object_Type_UNSIGNED_LONG;
                args[ 1 ].l = jo_val.get();
                jo_any.reset(
                    jni->NewObjectA(
                        getJniInfo()->m_class_Any,
                        getJniInfo()->m_ctor_Any_with_Type_Object, args ) );
                jni.ensure_no_exception();
                break;
            }
            case typelib_TypeClass_UNSIGNED_HYPER:
            {
                jvalue args[ 2 ];
                args[ 0 ].j = *static_cast<jlong const *>(pAny->pData);
                JLocalAutoRef jo_val(
                    jni, jni->NewObjectA(
                        getJniInfo()->m_class_Long,
                        getJniInfo()->m_ctor_Long_with_long, args ) );
                jni.ensure_no_exception();
                // box up in com.sun.star.uno.Any
                args[ 0 ].l = getJniInfo()->m_object_Type_UNSIGNED_HYPER;
                args[ 1 ].l = jo_val.get();
                jo_any.reset(
                    jni->NewObjectA(
                        getJniInfo()->m_class_Any,
                        getJniInfo()->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, static_cast<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, nullptr,
                    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(
                    reinterpret_cast<typelib_IndirectTypeDescription *>(seq_td.get())->pType );
                while (element_type.getTypeLibType()->eTypeClass ==
                         typelib_TypeClass_SEQUENCE)
                {
                    TypeDescr element_td( element_type.getTypeLibType() );
                    typelib_typedescriptionreference_assign(
                        reinterpret_cast< typelib_TypeDescriptionReference ** >(
                            &element_type ),
                        reinterpret_cast<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(
                            getJniInfo()->m_class_Any,
                            getJniInfo()->m_ctor_Any_with_Type_Object, args ) );
                    jni.ensure_no_exception();
                    break;
                }
                default:
                    break;
                }
                break;
            }
            case typelib_TypeClass_INTERFACE:
            {
                uno_Interface * pUnoI = static_cast<uno_Interface *>(pAny->pReserved);
                if (is_XInterface( pAny->pType ))
                {
                    if (pUnoI != nullptr)
                    {
                        jo_any.reset(
                            map_to_java(
                                jni, pUnoI,
                                getJniInfo()->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 * >(
                            getJniInfo()->get_type_info( jni, pAny->pType ) );
                    if (pUnoI != nullptr)
                    {
                        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(
                            getJniInfo()->m_class_Any,
                            getJniInfo()->m_ctor_Any_with_Type_Object, args ) );
                    jni.ensure_no_exception();
                }
                break;
            }
            case typelib_TypeClass_STRUCT:
            {
--> --------------------

--> maximum size reached

--> --------------------

Messung V0.5
C=96 H=96 G=95

¤ Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.0.20Bemerkung:  ¤

*Bot Zugriff






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge