INTEGRATION: CWS bunoexttm (1.1.2.2.2); FILE ADDED
2007/02/08 10:13:36 kr 1.1.2.2.2.2: fixed: linkage 2007/01/25 13:30:15 kr 1.1.2.2.2.1: fixed: license, warning; adapted: EnvDcp nsp
This commit is contained in:
349
cppu/source/uno/cascade_mapping.cxx
Normal file
349
cppu/source/uno/cascade_mapping.cxx
Normal file
@@ -0,0 +1,349 @@
|
||||
/*************************************************************************
|
||||
*
|
||||
* OpenOffice.org - a multi-platform office productivity suite
|
||||
*
|
||||
* $RCSfile: cascade_mapping.cxx,v $
|
||||
*
|
||||
* $Revision: 1.2 $
|
||||
*
|
||||
* last change: $Author: kz $ $Date: 2007-05-09 13:38:28 $
|
||||
*
|
||||
* The Contents of this file are made available subject to
|
||||
* the terms of GNU Lesser General Public License Version 2.1.
|
||||
*
|
||||
*
|
||||
* GNU Lesser General Public License Version 2.1
|
||||
* =============================================
|
||||
* Copyright 2005 by Sun Microsystems, Inc.
|
||||
* 901 San Antonio Road, Palo Alto, CA 94303, USA
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License version 2.1, as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*
|
||||
************************************************************************/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "osl/interlck.h"
|
||||
#include "rtl/ustring.hxx"
|
||||
#include "uno/environment.hxx"
|
||||
#include "uno/mapping.hxx"
|
||||
#include "uno/dispatcher.h"
|
||||
|
||||
//#include "cascade_mappping.hxx"
|
||||
#include "cppu/EnvDcp.hxx"
|
||||
|
||||
|
||||
//#define LOG_CALLING_named_purpose_getMapping
|
||||
|
||||
//#define LOG_LIFECYLE_MediatorMapping
|
||||
#ifdef LOG_LIFECYLE_MediatorMapping
|
||||
# define LOG_LIFECYLE_MediatorMapping_emit(x) x
|
||||
|
||||
#else
|
||||
# define LOG_LIFECYLE_MediatorMapping_emit(x)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
using namespace com::sun::star;
|
||||
|
||||
class MediatorMapping : public uno_Mapping
|
||||
{
|
||||
oslInterlockedCount m_refCount;
|
||||
|
||||
uno::Mapping m_from2uno;
|
||||
uno::Mapping m_uno2to;
|
||||
|
||||
uno::Environment m_from;
|
||||
uno::Environment m_interm;
|
||||
uno::Environment m_to;
|
||||
|
||||
public:
|
||||
void acquire(void);
|
||||
void release(void);
|
||||
|
||||
void mapInterface(void ** ppOut,
|
||||
void * pInterface,
|
||||
typelib_InterfaceTypeDescription * pInterfaceTypeDescr);
|
||||
MediatorMapping(uno_Environment * pFrom,
|
||||
uno_Environment * pInterm,
|
||||
uno_Environment * pTo);
|
||||
~MediatorMapping();
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
static void SAL_CALL s_acquire(uno_Mapping * mapping)
|
||||
{
|
||||
MediatorMapping * pMediatorMapping = static_cast<MediatorMapping *>(mapping);
|
||||
pMediatorMapping->acquire();
|
||||
}
|
||||
|
||||
static void SAL_CALL s_release(uno_Mapping * mapping)
|
||||
{
|
||||
MediatorMapping * pMediatorMapping = static_cast<MediatorMapping *>(mapping);
|
||||
pMediatorMapping->release();
|
||||
}
|
||||
|
||||
static void SAL_CALL s_mapInterface(
|
||||
uno_Mapping * mapping,
|
||||
void ** ppOut,
|
||||
void * pInterface,
|
||||
typelib_InterfaceTypeDescription * pInterfaceTypeDescr)
|
||||
{
|
||||
MediatorMapping * pMediatorMapping = static_cast<MediatorMapping *>(mapping);
|
||||
pMediatorMapping->mapInterface(ppOut, pInterface, pInterfaceTypeDescr);
|
||||
}
|
||||
}
|
||||
|
||||
MediatorMapping::MediatorMapping(uno_Environment * pFrom,
|
||||
uno_Environment * pInterm,
|
||||
uno_Environment * pTo)
|
||||
: m_refCount(0),
|
||||
m_from2uno(pFrom, pInterm),
|
||||
m_uno2to (pInterm, pTo),
|
||||
m_from (pFrom),
|
||||
m_interm (pInterm),
|
||||
m_to (pTo)
|
||||
{
|
||||
LOG_LIFECYLE_MediatorMapping_emit(std::cerr << __FUNCTION__ << std::endl);
|
||||
|
||||
if (!m_from2uno.get() || !m_uno2to.get())
|
||||
abort();
|
||||
|
||||
uno_Mapping::acquire = s_acquire;
|
||||
uno_Mapping::release = s_release;
|
||||
uno_Mapping::mapInterface = s_mapInterface;
|
||||
}
|
||||
|
||||
MediatorMapping::~MediatorMapping()
|
||||
{
|
||||
LOG_LIFECYLE_MediatorMapping_emit(std::cerr << __FUNCTION__ << std::endl);
|
||||
}
|
||||
|
||||
void MediatorMapping::acquire(void)
|
||||
{
|
||||
LOG_LIFECYLE_MediatorMapping_emit(std::cerr << __FUNCTION__ << std::endl);
|
||||
|
||||
osl_incrementInterlockedCount(&m_refCount);
|
||||
}
|
||||
|
||||
void MediatorMapping::release(void)
|
||||
{
|
||||
LOG_LIFECYLE_MediatorMapping_emit(std::cerr << __FUNCTION__ << std::endl);
|
||||
|
||||
if (osl_decrementInterlockedCount(&m_refCount) == 0)
|
||||
{
|
||||
::uno_revokeMapping(this);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" { static void s_mapInterface_v(va_list param)
|
||||
{
|
||||
void ** ppOut = va_arg(param, void **);
|
||||
void * pInterface = va_arg(param, void *);
|
||||
typelib_InterfaceTypeDescription * pInterfaceTypeDescr = va_arg(param, typelib_InterfaceTypeDescription *);
|
||||
uno_Mapping * pMapping = va_arg(param, uno_Mapping *);
|
||||
|
||||
pMapping->mapInterface(pMapping, ppOut, pInterface, pInterfaceTypeDescr);
|
||||
}}
|
||||
|
||||
void MediatorMapping::mapInterface(
|
||||
void ** ppOut,
|
||||
void * pInterface,
|
||||
typelib_InterfaceTypeDescription * pInterfaceTypeDescr)
|
||||
{
|
||||
if (*ppOut != 0)
|
||||
{
|
||||
uno_ExtEnvironment * env = m_to.get()->pExtEnv;
|
||||
OSL_ASSERT( env != 0 );
|
||||
env->releaseInterface( env, *ppOut );
|
||||
*ppOut = NULL;
|
||||
}
|
||||
|
||||
void * ret = 0;
|
||||
uno_Interface * pUnoI = 0;
|
||||
|
||||
m_from.invoke(s_mapInterface_v, &pUnoI, pInterface, pInterfaceTypeDescr, m_from2uno.get());
|
||||
|
||||
m_uno2to.mapInterface(&ret, pUnoI, pInterfaceTypeDescr);
|
||||
|
||||
if (pUnoI)
|
||||
m_interm.get()->pExtEnv->releaseInterface(m_interm.get()->pExtEnv, pUnoI);
|
||||
|
||||
*ppOut = ret;
|
||||
}
|
||||
|
||||
extern "C" { static void SAL_CALL s_MediatorMapping_free(uno_Mapping * pMapping)
|
||||
SAL_THROW_EXTERN_C()
|
||||
{
|
||||
delete static_cast<MediatorMapping *>(pMapping);
|
||||
}}
|
||||
|
||||
|
||||
|
||||
static rtl::OUString getPrefix(rtl::OUString const & str1, rtl::OUString const & str2)
|
||||
{
|
||||
sal_Int32 nIndex1 = 0;
|
||||
sal_Int32 nIndex2 = 0;
|
||||
sal_Int32 sim = 0;
|
||||
|
||||
rtl::OUString token1;
|
||||
rtl::OUString token2;
|
||||
|
||||
do
|
||||
{
|
||||
token1 = str1.getToken(0, ':', nIndex1);
|
||||
token2 = str2.getToken(0, ':', nIndex2);
|
||||
|
||||
if (token1.equals(token2))
|
||||
sim += token1.getLength() + 1;
|
||||
}
|
||||
while(nIndex1 == nIndex2 && nIndex1 >= 0 && token1.equals(token2));
|
||||
|
||||
rtl::OUString result;
|
||||
|
||||
if (sim)
|
||||
result = str1.copy(0, sim - 1);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// rtl::OUString str1(RTL_CONSTASCII_USTRINGPARAM("abc:def:ghi"));
|
||||
// rtl::OUString str2(RTL_CONSTASCII_USTRINGPARAM("abc:def"));
|
||||
// rtl::OUString str3(RTL_CONSTASCII_USTRINGPARAM("abc"));
|
||||
// rtl::OUString str4(RTL_CONSTASCII_USTRINGPARAM(""));
|
||||
|
||||
// rtl::OUString pref;
|
||||
|
||||
// pref = getPrefix(str1, str1);
|
||||
// pref = getPrefix(str1, str2);
|
||||
// pref = getPrefix(str1, str3);
|
||||
// pref = getPrefix(str1, str4);
|
||||
|
||||
// pref = getPrefix(str2, str1);
|
||||
// pref = getPrefix(str3, str1);
|
||||
// pref = getPrefix(str4, str1);
|
||||
|
||||
|
||||
void getCascadeMapping(uno_Mapping ** ppMapping,
|
||||
uno_Environment * pFrom,
|
||||
uno_Environment * pTo,
|
||||
rtl_uString * pAddPurpose)
|
||||
{
|
||||
if (pAddPurpose && pAddPurpose->length)
|
||||
return;
|
||||
|
||||
rtl::OUString uno_envType(RTL_CONSTASCII_USTRINGPARAM(UNO_LB_UNO));
|
||||
|
||||
rtl::OUString from_envType = cppu::EnvDcp::getTypeName(pFrom->pTypeName);
|
||||
rtl::OUString to_envType = cppu::EnvDcp::getTypeName(pTo->pTypeName);
|
||||
rtl::OUString from_envPurpose = cppu::EnvDcp::getPurpose(pFrom->pTypeName);
|
||||
rtl::OUString to_envPurpose = cppu::EnvDcp::getPurpose(pTo->pTypeName);
|
||||
|
||||
#ifdef LOG_CALLING_named_purpose_getMapping
|
||||
rtl::OString s_from_name = rtl::OUStringToOString(pFrom->pTypeName, RTL_TEXTENCODING_ASCII_US);
|
||||
rtl::OString s_to_name = rtl::OUStringToOString(pTo->pTypeName, RTL_TEXTENCODING_ASCII_US);
|
||||
|
||||
std::cerr << __FUNCTION__ << " - creating mediation ";
|
||||
std::cerr << "pFrom: " << s_from_name.getStr();
|
||||
std::cerr <<" pTo: " << s_to_name.getStr() << std::endl;
|
||||
#endif
|
||||
|
||||
if (from_envPurpose == to_envPurpose) // gcc:bla => uno:bla
|
||||
return;
|
||||
|
||||
// reaching this point means, we need a mediated mapping!!!
|
||||
// we generall mediate via uno[:free]
|
||||
uno_Environment * pInterm = NULL;
|
||||
|
||||
// chained uno -> uno
|
||||
if (from_envType == uno_envType && to_envType == uno_envType)
|
||||
{
|
||||
rtl::OUString purpose = getPrefix(from_envPurpose, to_envPurpose);
|
||||
|
||||
rtl::OUString uno_envDcp = uno_envType;
|
||||
uno_envDcp += purpose;
|
||||
|
||||
// direct mapping possible?
|
||||
// uno:bla-->uno:bla:blubb
|
||||
if (from_envPurpose.equals(purpose))
|
||||
{
|
||||
rtl::OUString rest = to_envPurpose.copy(purpose.getLength());
|
||||
|
||||
sal_Int32 index = rest.indexOf(':', 1);
|
||||
if (index == -1)
|
||||
{
|
||||
uno_getMapping(ppMapping, pFrom, pTo, rest.copy(1).pData);
|
||||
return;
|
||||
}
|
||||
|
||||
uno_envDcp += rest.copy(0, index);
|
||||
}
|
||||
else if (to_envPurpose.equals(purpose))
|
||||
{
|
||||
rtl::OUString rest = from_envPurpose.copy(purpose.getLength());
|
||||
|
||||
sal_Int32 index = rest.indexOf(':', 1);
|
||||
if (index == -1)
|
||||
{
|
||||
uno_getMapping(ppMapping, pFrom, pTo, rest.copy(1).pData);
|
||||
return;
|
||||
}
|
||||
|
||||
uno_envDcp += rest.copy(0, index);
|
||||
}
|
||||
|
||||
uno_getEnvironment(&pInterm, uno_envDcp.pData, NULL);
|
||||
}
|
||||
else if (from_envType != uno_envType && to_envType == uno_envType) // <ANY> -> UNO ?
|
||||
// mediate via uno:purpose(fromEnv)
|
||||
{
|
||||
rtl::OUString envDcp = uno_envType;
|
||||
|
||||
envDcp += from_envPurpose;
|
||||
uno_getEnvironment(&pInterm, envDcp.pData, NULL);
|
||||
}
|
||||
else if (from_envType == uno_envType && to_envType != uno_envType) // UNO -> <ANY>?
|
||||
// mediate via uno(context)
|
||||
{
|
||||
rtl::OUString envDcp = uno_envType;
|
||||
|
||||
envDcp += to_envPurpose;
|
||||
uno_getEnvironment(&pInterm, envDcp.pData, NULL);
|
||||
}
|
||||
else // everything else
|
||||
// mediate via uno:purpose
|
||||
{
|
||||
rtl::OUString purpose = getPrefix(from_envPurpose, to_envPurpose);
|
||||
|
||||
rtl::OUString uno_envDcp = uno_envType;
|
||||
uno_envDcp += purpose;
|
||||
|
||||
uno_getEnvironment(&pInterm, uno_envDcp.pData, NULL);
|
||||
}
|
||||
|
||||
uno_Mapping * pMapping = new MediatorMapping(pFrom, pInterm, pTo);
|
||||
pInterm->release(pInterm);
|
||||
|
||||
|
||||
pMapping->acquire(pMapping);
|
||||
|
||||
::uno_registerMapping(&pMapping, s_MediatorMapping_free, pFrom, pTo, pAddPurpose);
|
||||
|
||||
if (*ppMapping)
|
||||
(*ppMapping)->release(*ppMapping);
|
||||
|
||||
*ppMapping = pMapping;
|
||||
}
|
Reference in New Issue
Block a user