summaryrefslogtreecommitdiff
path: root/cppu/source/uno
diff options
context:
space:
mode:
Diffstat (limited to 'cppu/source/uno')
-rw-r--r--cppu/source/uno/EnvDcp.c49
-rw-r--r--cppu/source/uno/EnvStack.cxx380
-rw-r--r--cppu/source/uno/IdentityMapping.cxx106
-rw-r--r--cppu/source/uno/IdentityMapping.hxx39
-rw-r--r--cppu/source/uno/any.cxx150
-rw-r--r--cppu/source/uno/assign.hxx635
-rw-r--r--cppu/source/uno/cascade_mapping.cxx341
-rw-r--r--cppu/source/uno/cascade_mapping.hxx41
-rw-r--r--cppu/source/uno/constr.hxx267
-rw-r--r--cppu/source/uno/copy.hxx886
-rw-r--r--cppu/source/uno/data.cxx617
-rw-r--r--cppu/source/uno/destr.hxx438
-rw-r--r--cppu/source/uno/env_subst.cxx54
-rw-r--r--cppu/source/uno/env_subst.hxx41
-rw-r--r--cppu/source/uno/eq.hxx668
-rw-r--r--cppu/source/uno/lbenv.cxx1182
-rw-r--r--cppu/source/uno/lbmap.cxx692
-rw-r--r--cppu/source/uno/loadmodule.cxx55
-rw-r--r--cppu/source/uno/loadmodule.hxx51
-rw-r--r--cppu/source/uno/makefile.mk55
-rw-r--r--cppu/source/uno/prim.hxx206
-rw-r--r--cppu/source/uno/sequence.cxx1016
22 files changed, 7969 insertions, 0 deletions
diff --git a/cppu/source/uno/EnvDcp.c b/cppu/source/uno/EnvDcp.c
new file mode 100644
index 000000000000..7fb9a0e0ee68
--- /dev/null
+++ b/cppu/source/uno/EnvDcp.c
@@ -0,0 +1,49 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "uno/EnvDcp.h"
+
+
+void uno_EnvDcp_getTypeName(rtl_uString const * pEnvDcp, rtl_uString ** ppEnvTypeName)
+{
+ sal_Int32 colIdx = rtl_ustr_indexOfChar_WithLength(pEnvDcp->buffer, pEnvDcp->length, ':');
+ if (colIdx >= 0)
+ rtl_uString_newFromStr_WithLength(ppEnvTypeName, pEnvDcp->buffer, colIdx);
+
+ else
+ rtl_uString_newFromStr(ppEnvTypeName, pEnvDcp->buffer);
+}
+
+void uno_EnvDcp_getPurpose(rtl_uString const * pEnvDcp, rtl_uString ** ppEnvPurpose)
+{
+ sal_Int32 colIdx = rtl_ustr_indexOfChar_WithLength(pEnvDcp->buffer, pEnvDcp->length, ':');
+ if (colIdx >= 0)
+ rtl_uString_newFromStr_WithLength(ppEnvPurpose, pEnvDcp->buffer + colIdx, pEnvDcp->length - colIdx);
+
+ else
+ rtl_uString_new(ppEnvPurpose);
+}
diff --git a/cppu/source/uno/EnvStack.cxx b/cppu/source/uno/EnvStack.cxx
new file mode 100644
index 000000000000..b7cefd42b4da
--- /dev/null
+++ b/cppu/source/uno/EnvStack.cxx
@@ -0,0 +1,380 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "uno/environment.hxx"
+
+#include "cppu/EnvDcp.hxx"
+#include "cppu/Enterable.hxx"
+
+#include "osl/thread.h"
+#include "osl/mutex.hxx"
+
+#include <hash_map>
+
+
+using namespace com::sun::star;
+
+
+struct SAL_DLLPRIVATE oslThreadIdentifier_equal
+{
+ bool operator()(oslThreadIdentifier s1, oslThreadIdentifier s2) const;
+};
+
+bool oslThreadIdentifier_equal::operator()(oslThreadIdentifier s1, oslThreadIdentifier s2) const
+{
+ bool result = s1 == s2;
+
+ return result;
+}
+
+
+struct SAL_DLLPRIVATE oslThreadIdentifier_hash
+{
+ size_t operator()(oslThreadIdentifier s1) const;
+};
+
+size_t oslThreadIdentifier_hash::operator()(oslThreadIdentifier s1) const
+{
+ return s1;
+}
+
+typedef ::std::hash_map<oslThreadIdentifier,
+ uno_Environment *,
+ oslThreadIdentifier_hash,
+ oslThreadIdentifier_equal> ThreadMap;
+
+static osl::Mutex s_threadMap_mutex;
+static ThreadMap s_threadMap;
+
+
+static rtl::OUString s_uno_envDcp(RTL_CONSTASCII_USTRINGPARAM(UNO_LB_UNO));
+
+static void s_setCurrent(uno_Environment * pEnv)
+{
+ oslThreadIdentifier threadId = osl_getThreadIdentifier(NULL);
+
+ osl::MutexGuard guard(s_threadMap_mutex);
+ if (pEnv)
+ s_threadMap[threadId] = pEnv;
+
+ else
+ {
+ ThreadMap::iterator iEnv = s_threadMap.find(threadId);
+ s_threadMap.erase(iEnv);
+ }
+}
+
+static uno_Environment * s_getCurrent(void)
+{
+ uno_Environment * pEnv = NULL;
+
+ oslThreadIdentifier threadId = osl_getThreadIdentifier(NULL);
+
+ osl::MutexGuard guard(s_threadMap_mutex);
+ ThreadMap::iterator iEnv = s_threadMap.find(threadId);
+ if(iEnv != s_threadMap.end())
+ pEnv = iEnv->second;
+
+ return pEnv;
+}
+
+
+extern "C" void SAL_CALL uno_getCurrentEnvironment(uno_Environment ** ppEnv, rtl_uString * pTypeName)
+ SAL_THROW_EXTERN_C()
+{
+ if (*ppEnv)
+ {
+ (*ppEnv)->release(*ppEnv);
+ *ppEnv = NULL;
+ }
+
+ rtl::OUString currPurpose;
+
+ uno_Environment * pCurrEnv = s_getCurrent();
+ if (pCurrEnv) // no environment means no purpose
+ currPurpose = cppu::EnvDcp::getPurpose(pCurrEnv->pTypeName);
+
+ if (pTypeName && rtl_uString_getLength(pTypeName))
+ {
+ rtl::OUString envDcp(pTypeName);
+ envDcp += currPurpose;
+
+ uno_getEnvironment(ppEnv, envDcp.pData, NULL);
+ }
+ else
+ {
+ if (pCurrEnv)
+ {
+ *ppEnv = pCurrEnv;
+ (*ppEnv)->acquire(*ppEnv);
+ }
+ else
+ uno_getEnvironment(ppEnv, s_uno_envDcp.pData, NULL);
+
+ }
+}
+
+static rtl::OUString s_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;
+}
+
+static int s_getNextEnv(uno_Environment ** ppEnv, uno_Environment * pCurrEnv, uno_Environment * pTargetEnv)
+{
+ int res = 0;
+
+ rtl::OUString nextPurpose;
+
+ rtl::OUString currPurpose;
+ if (pCurrEnv)
+ currPurpose = cppu::EnvDcp::getPurpose(pCurrEnv->pTypeName);
+
+ rtl::OUString targetPurpose;
+ if (pTargetEnv)
+ targetPurpose = cppu::EnvDcp::getPurpose(pTargetEnv->pTypeName);
+
+ rtl::OUString intermPurpose(s_getPrefix(currPurpose, targetPurpose));
+ if (currPurpose.getLength() > intermPurpose.getLength())
+ {
+ sal_Int32 idx = currPurpose.lastIndexOf(':');
+ nextPurpose = currPurpose.copy(0, idx);
+
+ res = -1;
+ }
+ else if (intermPurpose.getLength() < targetPurpose.getLength())
+ {
+ sal_Int32 idx = targetPurpose.indexOf(':', intermPurpose.getLength() + 1);
+ if (idx == -1)
+ nextPurpose = targetPurpose;
+
+ else
+ nextPurpose = targetPurpose.copy(0, idx);
+
+ res = 1;
+ }
+
+ if (nextPurpose.getLength())
+ {
+ rtl::OUString next_envDcp(s_uno_envDcp);
+ next_envDcp += nextPurpose;
+
+ uno_getEnvironment(ppEnv, next_envDcp.pData, NULL);
+ }
+ else
+ {
+ if (*ppEnv)
+ (*ppEnv)->release(*ppEnv);
+
+ *ppEnv = NULL;
+ }
+
+ return res;
+}
+
+extern "C" { static void s_pull(va_list * pParam)
+{
+ uno_EnvCallee * pCallee = va_arg(*pParam, uno_EnvCallee *);
+ va_list * pXparam = va_arg(*pParam, va_list *);
+
+ pCallee(pXparam);
+}}
+
+static void s_callInto_v(uno_Environment * pEnv, uno_EnvCallee * pCallee, va_list * pParam)
+{
+ cppu::Enterable * pEnterable = reinterpret_cast<cppu::Enterable *>(pEnv->pReserved);
+ if (pEnterable)
+ pEnterable->callInto(s_pull, pCallee, pParam);
+
+ else
+ pCallee(pParam);
+}
+
+static void s_callInto(uno_Environment * pEnv, uno_EnvCallee * pCallee, ...)
+{
+ va_list param;
+
+ va_start(param, pCallee);
+ s_callInto_v(pEnv, pCallee, &param);
+ va_end(param);
+}
+
+static void s_callOut_v(uno_Environment * pEnv, uno_EnvCallee * pCallee, va_list * pParam)
+{
+ cppu::Enterable * pEnterable = reinterpret_cast<cppu::Enterable *>(pEnv->pReserved);
+ if (pEnterable)
+ pEnterable->callOut_v(pCallee, pParam);
+
+ else
+ pCallee(pParam);
+}
+
+static void s_callOut(uno_Environment * pEnv, uno_EnvCallee * pCallee, ...)
+{
+ va_list param;
+
+ va_start(param, pCallee);
+ s_callOut_v(pEnv, pCallee, &param);
+ va_end(param);
+}
+
+static void s_environment_invoke_v(uno_Environment *, uno_Environment *, uno_EnvCallee *, va_list *);
+
+extern "C" { static void s_environment_invoke_vv(va_list * pParam)
+{
+ uno_Environment * pCurrEnv = va_arg(*pParam, uno_Environment *);
+ uno_Environment * pTargetEnv = va_arg(*pParam, uno_Environment *);
+ uno_EnvCallee * pCallee = va_arg(*pParam, uno_EnvCallee *);
+ va_list * pXparam = va_arg(*pParam, va_list *);
+
+ s_environment_invoke_v(pCurrEnv, pTargetEnv, pCallee, pXparam);
+}}
+
+static void s_environment_invoke_v(uno_Environment * pCurrEnv, uno_Environment * pTargetEnv, uno_EnvCallee * pCallee, va_list * pParam)
+{
+ uno_Environment * pNextEnv = NULL;
+ switch(s_getNextEnv(&pNextEnv, pCurrEnv, pTargetEnv))
+ {
+ case -1:
+ s_setCurrent(pNextEnv);
+ s_callOut(pCurrEnv, s_environment_invoke_vv, pNextEnv, pTargetEnv, pCallee, pParam);
+ s_setCurrent(pCurrEnv);
+ break;
+
+ case 0: {
+ uno_Environment * hld = s_getCurrent();
+ s_setCurrent(pCurrEnv);
+ pCallee(pParam);
+ s_setCurrent(hld);
+ }
+ break;
+
+ case 1:
+ s_setCurrent(pNextEnv);
+ s_callInto(pNextEnv, s_environment_invoke_vv, pNextEnv, pTargetEnv, pCallee, pParam);
+ s_setCurrent(pCurrEnv);
+ break;
+ }
+
+ if (pNextEnv)
+ pNextEnv->release(pNextEnv);
+}
+
+extern "C" void SAL_CALL uno_Environment_invoke_v(uno_Environment * pTargetEnv, uno_EnvCallee * pCallee, va_list * pParam)
+ SAL_THROW_EXTERN_C()
+{
+ s_environment_invoke_v(s_getCurrent(), pTargetEnv, pCallee, pParam);
+}
+
+extern "C" void SAL_CALL uno_Environment_invoke(uno_Environment * pEnv, uno_EnvCallee * pCallee, ...)
+ SAL_THROW_EXTERN_C()
+{
+ va_list param;
+
+ va_start(param, pCallee);
+ uno_Environment_invoke_v(pEnv, pCallee, &param);
+ va_end(param);
+}
+
+extern "C" void SAL_CALL uno_Environment_enter(uno_Environment * pTargetEnv)
+ SAL_THROW_EXTERN_C()
+{
+ uno_Environment * pNextEnv = NULL;
+ uno_Environment * pCurrEnv = s_getCurrent();
+
+ int res;
+ while ( (res = s_getNextEnv(&pNextEnv, pCurrEnv, pTargetEnv)) != 0)
+ {
+ cppu::Enterable * pEnterable;
+
+ switch(res)
+ {
+ case -1:
+ pEnterable = reinterpret_cast<cppu::Enterable *>(pCurrEnv->pReserved);
+ if (pEnterable)
+ pEnterable->leave();
+ pCurrEnv->release(pCurrEnv);
+ break;
+
+ case 1:
+ pNextEnv->acquire(pNextEnv);
+ pEnterable = reinterpret_cast<cppu::Enterable *>(pNextEnv->pReserved);
+ if (pEnterable)
+ pEnterable->enter();
+ break;
+ }
+
+ s_setCurrent(pNextEnv);
+ pCurrEnv = pNextEnv;
+ }
+}
+
+int SAL_CALL uno_Environment_isValid(uno_Environment * pEnv, rtl_uString ** pReason)
+ SAL_THROW_EXTERN_C()
+{
+ int result = 1;
+
+ rtl::OUString typeName(cppu::EnvDcp::getTypeName(pEnv->pTypeName));
+ if (typeName.equals(s_uno_envDcp))
+ {
+ cppu::Enterable * pEnterable = reinterpret_cast<cppu::Enterable *>(pEnv->pReserved);
+ if (pEnterable)
+ result = pEnterable->isValid((rtl::OUString *)pReason);
+ }
+ else
+ {
+ rtl::OUString envDcp(s_uno_envDcp);
+ envDcp += cppu::EnvDcp::getPurpose(pEnv->pTypeName);
+
+ uno::Environment env(envDcp);
+
+ result = env.isValid((rtl::OUString *)pReason);
+ }
+
+ return result;
+}
diff --git a/cppu/source/uno/IdentityMapping.cxx b/cppu/source/uno/IdentityMapping.cxx
new file mode 100644
index 000000000000..64721e2993ca
--- /dev/null
+++ b/cppu/source/uno/IdentityMapping.cxx
@@ -0,0 +1,106 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "IdentityMapping.hxx"
+
+#include "uno/mapping.h"
+#include "uno/environment.hxx"
+
+#include "osl/interlck.h"
+
+
+using namespace ::com::sun::star;
+
+struct IdentityMapping : public uno_Mapping
+{
+ sal_Int32 m_nRef;
+ uno::Environment m_env;
+
+ IdentityMapping(uno::Environment const & rEnv);
+};
+
+extern "C"
+{
+
+static void SAL_CALL s_free(uno_Mapping * pMapping) SAL_THROW(())
+{
+ delete static_cast<IdentityMapping *>(pMapping);
+}
+
+static void SAL_CALL s_acquire(uno_Mapping * pMapping) SAL_THROW(())
+{
+ static rtl::OUString s_purpose;
+
+ if (1 == ::osl_incrementInterlockedCount(&static_cast<IdentityMapping *>(pMapping)->m_nRef))
+ {
+ uno_registerMapping(
+ &pMapping,
+ s_free,
+ static_cast<IdentityMapping *>(pMapping)->m_env.get(),
+ static_cast<IdentityMapping *>(pMapping)->m_env.get(),
+ s_purpose.pData);
+ }
+}
+
+static void SAL_CALL s_release(uno_Mapping * pMapping) SAL_THROW(())
+{
+ if (!::osl_decrementInterlockedCount(&static_cast<IdentityMapping *>(pMapping )->m_nRef))
+ uno_revokeMapping(pMapping);
+}
+
+static void SAL_CALL s_mapInterface(uno_Mapping * pMapping,
+ void ** ppOut,
+ void * pInterface,
+ struct _typelib_InterfaceTypeDescription * /*pInterfaceTypeDescr*/)
+ SAL_THROW(())
+{
+ *ppOut = pInterface;
+
+ if (pInterface)
+ {
+ IdentityMapping * that = static_cast<IdentityMapping *>(pMapping);
+
+ (that->m_env.get()->pExtEnv->acquireInterface)(that->m_env.get()->pExtEnv, pInterface);
+ }
+}
+}
+
+
+IdentityMapping::IdentityMapping(uno::Environment const & rEnv)
+ : m_nRef(0),
+ m_env(rEnv)
+{
+ uno_Mapping::acquire = s_acquire;
+ uno_Mapping::release = s_release;
+ uno_Mapping::mapInterface = s_mapInterface;
+}
+
+
+uno_Mapping * createIdentityMapping(uno::Environment const & rEnv) SAL_THROW(())
+{
+ return new IdentityMapping(rEnv);
+}
diff --git a/cppu/source/uno/IdentityMapping.hxx b/cppu/source/uno/IdentityMapping.hxx
new file mode 100644
index 000000000000..cf95a30b203c
--- /dev/null
+++ b/cppu/source/uno/IdentityMapping.hxx
@@ -0,0 +1,39 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_IdentityMapping_hxx
+#define INCLUDED_IdentityMapping_hxx
+
+#include "uno/mapping.h"
+
+namespace com { namespace sun { namespace star { namespace uno {
+class Environment;
+}}}}
+
+uno_Mapping * createIdentityMapping(const ::com::sun::star::uno::Environment & rEnv);
+
+#endif
diff --git a/cppu/source/uno/any.cxx b/cppu/source/uno/any.cxx
new file mode 100644
index 000000000000..29be833dfb86
--- /dev/null
+++ b/cppu/source/uno/any.cxx
@@ -0,0 +1,150 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_cppu.hxx"
+
+#include "copy.hxx"
+#include "destr.hxx"
+
+using namespace cppu;
+
+
+extern "C"
+{
+//##################################################################################################
+void SAL_CALL uno_type_any_assign(
+ uno_Any * pDest, void * pSource,
+ typelib_TypeDescriptionReference * pType,
+ uno_AcquireFunc acquire, uno_ReleaseFunc release )
+ SAL_THROW_EXTERN_C()
+{
+ _destructAny( pDest, release );
+ if (pType)
+ {
+ _copyConstructAny( pDest, pSource, pType, 0, acquire, 0 );
+ }
+ else
+ {
+ CONSTRUCT_EMPTY_ANY( pDest );
+ }
+}
+//##################################################################################################
+void SAL_CALL uno_any_assign(
+ uno_Any * pDest, void * pSource,
+ typelib_TypeDescription * pTypeDescr,
+ uno_AcquireFunc acquire, uno_ReleaseFunc release )
+ SAL_THROW_EXTERN_C()
+{
+ _destructAny( pDest, release );
+ if (pTypeDescr)
+ {
+ _copyConstructAny( pDest, pSource, pTypeDescr->pWeakRef, pTypeDescr, acquire, 0 );
+ }
+ else
+ {
+ CONSTRUCT_EMPTY_ANY( pDest );
+ }
+}
+//##################################################################################################
+void SAL_CALL uno_type_any_construct(
+ uno_Any * pDest, void * pSource,
+ typelib_TypeDescriptionReference * pType,
+ uno_AcquireFunc acquire )
+ SAL_THROW_EXTERN_C()
+{
+ if (pType)
+ {
+ _copyConstructAny( pDest, pSource, pType, 0, acquire, 0 );
+ }
+ else
+ {
+ CONSTRUCT_EMPTY_ANY( pDest );
+ }
+}
+//##################################################################################################
+void SAL_CALL uno_any_construct(
+ uno_Any * pDest, void * pSource,
+ typelib_TypeDescription * pTypeDescr,
+ uno_AcquireFunc acquire )
+ SAL_THROW_EXTERN_C()
+{
+ if (pTypeDescr)
+ {
+ _copyConstructAny( pDest, pSource, pTypeDescr->pWeakRef, pTypeDescr, acquire, 0 );
+ }
+ else
+ {
+ CONSTRUCT_EMPTY_ANY( pDest );
+ }
+}
+//##################################################################################################
+void SAL_CALL uno_type_any_constructAndConvert(
+ uno_Any * pDest, void * pSource,
+ typelib_TypeDescriptionReference * pType,
+ uno_Mapping * mapping )
+ SAL_THROW_EXTERN_C()
+{
+ if (pType)
+ {
+ _copyConstructAny( pDest, pSource, pType, 0, 0, mapping );
+ }
+ else
+ {
+ CONSTRUCT_EMPTY_ANY( pDest );
+ }
+}
+//##################################################################################################
+void SAL_CALL uno_any_constructAndConvert(
+ uno_Any * pDest, void * pSource,
+ typelib_TypeDescription * pTypeDescr,
+ uno_Mapping * mapping )
+ SAL_THROW_EXTERN_C()
+{
+ if (pTypeDescr)
+ {
+ _copyConstructAny( pDest, pSource, pTypeDescr->pWeakRef, pTypeDescr, 0, mapping );
+ }
+ else
+ {
+ CONSTRUCT_EMPTY_ANY( pDest );
+ }
+}
+//##################################################################################################
+void SAL_CALL uno_any_destruct( uno_Any * pValue, uno_ReleaseFunc release )
+ SAL_THROW_EXTERN_C()
+{
+ _destructAny( pValue, release );
+}
+//##################################################################################################
+void SAL_CALL uno_any_clear( uno_Any * pValue, uno_ReleaseFunc release )
+ SAL_THROW_EXTERN_C()
+{
+ _destructAny( pValue, release );
+ CONSTRUCT_EMPTY_ANY( pValue );
+}
+}
diff --git a/cppu/source/uno/assign.hxx b/cppu/source/uno/assign.hxx
new file mode 100644
index 000000000000..256bb31565db
--- /dev/null
+++ b/cppu/source/uno/assign.hxx
@@ -0,0 +1,635 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef ASSIGN_HXX
+#define ASSIGN_HXX
+
+#include "prim.hxx"
+#include "destr.hxx"
+#include "constr.hxx"
+#include "copy.hxx"
+
+
+namespace cppu
+{
+
+//##################################################################################################
+//#### assignment ##################################################################################
+//##################################################################################################
+
+
+//--------------------------------------------------------------------------------------------------
+inline void _assignInterface(
+ void ** ppDest, void * pSource,
+ uno_AcquireFunc acquire, uno_ReleaseFunc release )
+ SAL_THROW( () )
+{
+ _acquire( pSource, acquire );
+ void * const pToBeReleased = *ppDest;
+ *ppDest = pSource;
+ _release( pToBeReleased, release );
+}
+//--------------------------------------------------------------------------------------------------
+inline void * _queryInterface(
+ void * pSource,
+ typelib_TypeDescriptionReference * pDestType,
+ uno_QueryInterfaceFunc queryInterface )
+ SAL_THROW( () )
+{
+ if (pSource)
+ {
+ if (0 == queryInterface)
+ queryInterface = binuno_queryInterface;
+ pSource = (*queryInterface)( pSource, pDestType );
+ }
+ return pSource;
+}
+//==================================================================================================
+sal_Bool assignStruct(
+ void * pDest, void * pSource,
+ typelib_CompoundTypeDescription * pTypeDescr,
+ uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release )
+ SAL_THROW( () );
+//--------------------------------------------------------------------------------------------------
+inline sal_Bool _assignStruct(
+ void * pDest, void * pSource,
+ typelib_CompoundTypeDescription * pTypeDescr,
+ uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release )
+ SAL_THROW( () )
+{
+ if (pTypeDescr->pBaseTypeDescription)
+ {
+ // copy base value
+ if (! assignStruct( pDest, pSource, pTypeDescr->pBaseTypeDescription,
+ queryInterface, acquire, release ))
+ {
+ return sal_False;
+ }
+ }
+ // then copy members
+ typelib_TypeDescriptionReference ** ppTypeRefs = pTypeDescr->ppTypeRefs;
+ sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets;
+ sal_Int32 nDescr = pTypeDescr->nMembers;
+ while (nDescr--)
+ {
+ if (! ::uno_type_assignData( (char *)pDest + pMemberOffsets[nDescr],
+ ppTypeRefs[nDescr],
+ (char *)pSource + pMemberOffsets[nDescr],
+ ppTypeRefs[nDescr],
+ queryInterface, acquire, release ))
+ {
+ return sal_False;
+ }
+ }
+ return sal_True;
+}
+//--------------------------------------------------------------------------------------------------
+inline sal_Bool _assignArray(
+ void * pDest, void * pSource,
+ typelib_ArrayTypeDescription * pTypeDescr,
+ uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release )
+{
+ typelib_TypeDescriptionReference * pElementTypeRef =
+ ((typelib_IndirectTypeDescription *)pTypeDescr)->pType;
+ typelib_TypeDescription * pElementTypeDescr = NULL;
+ TYPELIB_DANGER_GET( &pElementTypeDescr, pElementTypeRef );
+ sal_Int32 nTotalElements = pTypeDescr->nTotalElements;
+ sal_Int32 nElementSize = pElementTypeDescr->nSize;
+ sal_Int32 i;
+ sal_Bool bRet = sal_False;
+
+ switch ( pElementTypeRef->eTypeClass )
+ {
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_FLOAT:
+ case typelib_TypeClass_DOUBLE:
+ for (i=0; i < nTotalElements; i++)
+ {
+ ::rtl_copyMemory((sal_Char *)pDest + i * nElementSize,
+ (sal_Char *)pSource + i * nElementSize,
+ nElementSize);
+ }
+ bRet = sal_True;
+ break;
+ case typelib_TypeClass_STRING:
+ for (i=0; i < nTotalElements; i++)
+ {
+ ::rtl_uString_assign( (rtl_uString **)pDest + i,
+ ((rtl_uString **)pSource)[i] );
+ }
+ bRet = sal_True;
+ break;
+ case typelib_TypeClass_TYPE:
+ for (i=0; i < nTotalElements; i++)
+ {
+ typelib_TypeDescriptionReference ** pp = (typelib_TypeDescriptionReference **)pDest + i;
+ ::typelib_typedescriptionreference_release( *pp );
+ *pp = *((typelib_TypeDescriptionReference **)pSource + i);
+ TYPE_ACQUIRE( *pp );
+ }
+ bRet = sal_True;
+ break;
+ case typelib_TypeClass_ANY:
+ for (i=0; i < nTotalElements; i++)
+ {
+ _destructAny( (uno_Any *)pDest + i, release );
+ _copyConstructAny( (uno_Any *)pDest + i, (uno_Any *)pSource + i,
+ pElementTypeRef, pElementTypeDescr, acquire, 0 );
+ }
+ bRet = sal_True;
+ break;
+ case typelib_TypeClass_ENUM:
+ for (i=0; i < nTotalElements; i++)
+ {
+ *((sal_Int32 *)pDest + i) = *((sal_Int32 *)pSource + i);
+ }
+ bRet = sal_True;
+ break;
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ for (i=0; i < nTotalElements; i++)
+ {
+ bRet = _assignStruct( (sal_Char *)pDest + i * nElementSize,
+ (sal_Char *)pSource + i * nElementSize,
+ (typelib_CompoundTypeDescription *)pElementTypeDescr,
+ queryInterface, acquire, release );
+ if (! bRet)
+ break;
+ }
+ bRet = sal_True;
+ break;
+ case typelib_TypeClass_UNION:
+ for (i=0; i < nTotalElements; i++)
+ {
+ _destructUnion( (sal_Char*)pDest + i * nElementSize, pElementTypeDescr, release );
+ _copyConstructUnion( (sal_Char*)pDest + i * nElementSize,
+ (sal_Char*)pSource + i * nElementSize,
+ pElementTypeDescr, acquire, 0 );
+ }
+ bRet = sal_True;
+ break;
+ case typelib_TypeClass_SEQUENCE:
+ for (i=0; i < nTotalElements; i++)
+ {
+ ::osl_incrementInterlockedCount(
+ &(*((uno_Sequence **)pSource + i))->nRefCount );
+ idestructSequence(
+ *((uno_Sequence **)pDest + i),
+ pElementTypeRef, pElementTypeDescr, release );
+ *((uno_Sequence **)pDest + i) = *((uno_Sequence **)pSource + i);
+ }
+ bRet = sal_True;
+ break;
+ case typelib_TypeClass_INTERFACE:
+ for (i=0; i < nTotalElements; i++)
+ {
+ _assignInterface(
+ (void **)((sal_Char*)pDest + i * nElementSize),
+ *(void **)((sal_Char*)pSource + i * nElementSize),
+ acquire, release );
+ }
+ bRet = sal_True;
+ break;
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+
+ TYPELIB_DANGER_RELEASE( pElementTypeDescr );
+ return bRet;
+}
+//--------------------------------------------------------------------------------------------------
+inline sal_Bool _assignData(
+ void * pDest,
+ typelib_TypeDescriptionReference * pDestType, typelib_TypeDescription * pDestTypeDescr,
+ void * pSource,
+ typelib_TypeDescriptionReference * pSourceType, typelib_TypeDescription * pSourceTypeDescr,
+ uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release )
+ SAL_THROW( () )
+{
+ if (pDest == pSource)
+ return _type_equals( pDestType, pSourceType );
+
+ if (! pSource)
+ {
+ _destructData( pDest, pDestType, pDestTypeDescr, release );
+ _defaultConstructData( pDest, pDestType, pDestTypeDescr );
+ return sal_True;
+ }
+ while (typelib_TypeClass_ANY == pSourceType->eTypeClass)
+ {
+ pSourceTypeDescr = 0;
+ pSourceType = ((uno_Any *)pSource)->pType;
+ pSource = ((uno_Any *)pSource)->pData;
+ if (pDest == pSource)
+ return sal_True;
+ }
+
+ switch (pDestType->eTypeClass)
+ {
+ case typelib_TypeClass_VOID:
+ return pSourceType->eTypeClass == typelib_TypeClass_VOID;
+ case typelib_TypeClass_CHAR:
+ switch (pSourceType->eTypeClass)
+ {
+ case typelib_TypeClass_CHAR:
+ *(sal_Unicode *)pDest = *(sal_Unicode *)pSource;
+ return sal_True;
+ default:
+ return sal_False;
+ }
+ case typelib_TypeClass_BOOLEAN:
+ switch (pSourceType->eTypeClass)
+ {
+ case typelib_TypeClass_BOOLEAN:
+ *(sal_Bool *)pDest = (*(sal_Bool *)pSource != sal_False);
+ return sal_True;
+ default:
+ return sal_False;
+ }
+ case typelib_TypeClass_BYTE:
+ switch (pSourceType->eTypeClass)
+ {
+ case typelib_TypeClass_BYTE:
+ *(sal_Int8 *)pDest = *(sal_Int8 *)pSource;
+ return sal_True;
+ default:
+ return sal_False;
+ }
+ case typelib_TypeClass_SHORT:
+ switch (pSourceType->eTypeClass)
+ {
+ case typelib_TypeClass_BYTE:
+ *(sal_Int16 *)pDest = *(sal_Int8 *)pSource;
+ return sal_True;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *(sal_Int16 *)pDest = *(sal_Int16 *)pSource;
+ return sal_True;
+ default:
+ return sal_False;
+ }
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ switch (pSourceType->eTypeClass)
+ {
+ case typelib_TypeClass_BYTE:
+ *(sal_uInt16 *)pDest = *(sal_Int8 *)pSource;
+ return sal_True;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *(sal_uInt16 *)pDest = *(sal_uInt16 *)pSource;
+ return sal_True;
+ default:
+ return sal_False;
+ }
+ case typelib_TypeClass_LONG:
+ switch (pSourceType->eTypeClass)
+ {
+ case typelib_TypeClass_BYTE:
+ *(sal_Int32 *)pDest = *(sal_Int8 *)pSource;
+ return sal_True;
+ case typelib_TypeClass_SHORT:
+ *(sal_Int32 *)pDest = *(sal_Int16 *)pSource;
+ return sal_True;
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *(sal_Int32 *)pDest = *(sal_uInt16 *)pSource;
+ return sal_True;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ *(sal_Int32 *)pDest = *(sal_Int32 *)pSource;
+ return sal_True;
+ default:
+ return sal_False;
+ }
+ case typelib_TypeClass_UNSIGNED_LONG:
+ switch (pSourceType->eTypeClass)
+ {
+ case typelib_TypeClass_BYTE:
+ *(sal_uInt32 *)pDest = *(sal_Int8 *)pSource;
+ return sal_True;
+ case typelib_TypeClass_SHORT:
+ *(sal_uInt32 *)pDest = *(sal_Int16 *)pSource;
+ return sal_True;
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *(sal_uInt32 *)pDest = *(sal_uInt16 *)pSource;
+ return sal_True;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ *(sal_uInt32 *)pDest = *(sal_uInt32 *)pSource;
+ return sal_True;
+ default:
+ return sal_False;
+ }
+ case typelib_TypeClass_HYPER:
+ switch (pSourceType->eTypeClass)
+ {
+ case typelib_TypeClass_BYTE:
+ *(sal_Int64 *)pDest = *(sal_Int8 *)pSource;
+ return sal_True;
+ case typelib_TypeClass_SHORT:
+ *(sal_Int64 *)pDest = *(sal_Int16 *)pSource;
+ return sal_True;
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *(sal_Int64 *)pDest = *(sal_uInt16 *)pSource;
+ return sal_True;
+ case typelib_TypeClass_LONG:
+ *(sal_Int64 *)pDest = *(sal_Int32 *)pSource;
+ return sal_True;
+ case typelib_TypeClass_UNSIGNED_LONG:
+ *(sal_Int64 *)pDest = *(sal_uInt32 *)pSource;
+ return sal_True;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ *(sal_Int64 *)pDest = *(sal_Int64 *)pSource;
+ return sal_True;
+ default:
+ return sal_False;
+ }
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ switch (pSourceType->eTypeClass)
+ {
+ case typelib_TypeClass_BYTE:
+ *(sal_uInt64 *)pDest = *(sal_Int8 *)pSource;
+ return sal_True;
+ case typelib_TypeClass_SHORT:
+ *(sal_uInt64 *)pDest = *(sal_Int16 *)pSource;
+ return sal_True;
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *(sal_uInt64 *)pDest = *(sal_uInt16 *)pSource;
+ return sal_True;
+ case typelib_TypeClass_LONG:
+ *(sal_uInt64 *)pDest = *(sal_Int32 *)pSource;
+ return sal_True;
+ case typelib_TypeClass_UNSIGNED_LONG:
+ *(sal_uInt64 *)pDest = *(sal_uInt32 *)pSource;
+ return sal_True;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ *(sal_uInt64 *)pDest = *(sal_uInt64 *)pSource;
+ return sal_True;
+ default:
+ return sal_False;
+ }
+ case typelib_TypeClass_FLOAT:
+ switch (pSourceType->eTypeClass)
+ {
+ case typelib_TypeClass_BYTE:
+ *(float *)pDest = *(sal_Int8 *)pSource;
+ return sal_True;
+ case typelib_TypeClass_SHORT:
+ *(float *)pDest = *(sal_Int16 *)pSource;
+ return sal_True;
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *(float *)pDest = *(sal_uInt16 *)pSource;
+ return sal_True;
+ case typelib_TypeClass_FLOAT:
+ *(float *)pDest = *(float *)pSource;
+ return sal_True;
+ default:
+ return sal_False;
+ }
+ case typelib_TypeClass_DOUBLE:
+ switch (pSourceType->eTypeClass)
+ {
+ case typelib_TypeClass_BYTE:
+ *(double *)pDest = *(sal_Int8 *)pSource;
+ return sal_True;
+ case typelib_TypeClass_SHORT:
+ *(double *)pDest = *(sal_Int16 *)pSource;
+ return sal_True;
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *(double *)pDest = *(sal_uInt16 *)pSource;
+ return sal_True;
+ case typelib_TypeClass_LONG:
+ *(double *)pDest = *(sal_Int32 *)pSource;
+ return sal_True;
+ case typelib_TypeClass_UNSIGNED_LONG:
+ *(double *)pDest = *(sal_uInt32 *)pSource;
+ return sal_True;
+ case typelib_TypeClass_FLOAT:
+ *(double *)pDest = *(float *)pSource;
+ return sal_True;
+ case typelib_TypeClass_DOUBLE:
+ *(double *)pDest = *(double *)pSource;
+ return sal_True;
+ default:
+ return sal_False;
+ }
+ case typelib_TypeClass_STRING:
+ switch (pSourceType->eTypeClass)
+ {
+ case typelib_TypeClass_STRING:
+ ::rtl_uString_assign( (rtl_uString **)pDest, *(rtl_uString **)pSource );
+ return sal_True;
+ default:
+ return sal_False;
+ }
+ case typelib_TypeClass_TYPE:
+ switch (pSourceType->eTypeClass)
+ {
+ case typelib_TypeClass_TYPE:
+ {
+ typelib_TypeDescriptionReference ** pp = (typelib_TypeDescriptionReference **)pDest;
+ ::typelib_typedescriptionreference_release( *pp );
+ *pp = *(typelib_TypeDescriptionReference **)pSource;
+ TYPE_ACQUIRE( *pp );
+ return sal_True;
+ }
+ default:
+ return sal_False;
+ }
+ case typelib_TypeClass_ANY:
+ _destructAny( (uno_Any *)pDest, release );
+ _copyConstructAny( (uno_Any *)pDest, pSource, pSourceType, pSourceTypeDescr, acquire, 0 );
+ return sal_True;
+ case typelib_TypeClass_ENUM:
+ if (_type_equals( pDestType, pSourceType ))
+ {
+ *(sal_Int32 *)pDest = *(sal_Int32 *)pSource;
+ return sal_True;
+ }
+ return sal_False;
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ if (typelib_TypeClass_STRUCT == pSourceType->eTypeClass ||
+ typelib_TypeClass_EXCEPTION == pSourceType->eTypeClass)
+ {
+ sal_Bool bRet = sal_False;
+ if (pSourceTypeDescr)
+ {
+ typelib_CompoundTypeDescription * pTypeDescr =
+ (typelib_CompoundTypeDescription *)pSourceTypeDescr;
+ while (pTypeDescr &&
+ !_type_equals(
+ ((typelib_TypeDescription *)pTypeDescr)->pWeakRef, pDestType ))
+ {
+ pTypeDescr = pTypeDescr->pBaseTypeDescription;
+ }
+ if (pTypeDescr)
+ {
+ bRet = _assignStruct(
+ pDest, pSource, pTypeDescr, queryInterface, acquire, release );
+ }
+ }
+ else
+ {
+ TYPELIB_DANGER_GET( &pSourceTypeDescr, pSourceType );
+ typelib_CompoundTypeDescription * pTypeDescr =
+ (typelib_CompoundTypeDescription *)pSourceTypeDescr;
+ while (pTypeDescr &&
+ !_type_equals(
+ ((typelib_TypeDescription *)pTypeDescr)->pWeakRef, pDestType ))
+ {
+ pTypeDescr = pTypeDescr->pBaseTypeDescription;
+ }
+ if (pTypeDescr)
+ {
+ bRet = _assignStruct(
+ pDest, pSource, pTypeDescr, queryInterface, acquire, release );
+ }
+ TYPELIB_DANGER_RELEASE( pSourceTypeDescr );
+ }
+ return bRet;
+ }
+ return sal_False;
+ case typelib_TypeClass_ARRAY:
+ {
+ sal_Bool bRet = sal_False;
+ if (pSourceTypeDescr)
+ {
+ typelib_ArrayTypeDescription * pTypeDescr =
+ (typelib_ArrayTypeDescription *)pSourceTypeDescr;
+ bRet = _assignArray( pDest, pSource, pTypeDescr, queryInterface, acquire, release );
+ }
+ else
+ {
+ TYPELIB_DANGER_GET( &pSourceTypeDescr, pSourceType );
+ typelib_ArrayTypeDescription * pTypeDescr =
+ (typelib_ArrayTypeDescription *)pSourceTypeDescr;
+ if ( pTypeDescr )
+ {
+ bRet = _assignArray(
+ pDest, pSource, pTypeDescr, queryInterface, acquire, release );
+ }
+ TYPELIB_DANGER_RELEASE( pSourceTypeDescr );
+ }
+ return bRet;
+ }
+ case typelib_TypeClass_UNION:
+ if (_type_equals( pDestType, pSourceType ))
+ {
+ if (pDestTypeDescr)
+ {
+ _destructUnion( pDest, pDestTypeDescr, release );
+ _copyConstructUnion( pDest, pSource, pDestTypeDescr, acquire, 0 );
+ }
+ else
+ {
+ TYPELIB_DANGER_GET( &pDestTypeDescr, pDestType );
+ _destructUnion( pDest, pDestTypeDescr, release );
+ _copyConstructUnion( pDest, pSource, pDestTypeDescr, acquire, 0 );
+ TYPELIB_DANGER_RELEASE( pDestTypeDescr );
+ }
+ return sal_True;
+ }
+ return sal_False;
+ case typelib_TypeClass_SEQUENCE:
+ if (typelib_TypeClass_SEQUENCE != pSourceType->eTypeClass)
+ return sal_False;
+ // self assignment:
+ if (*(uno_Sequence **)pSource == *(uno_Sequence **)pDest)
+ return sal_True;
+ if (_type_equals( pDestType, pSourceType ))
+ {
+ ::osl_incrementInterlockedCount(
+ &(*(uno_Sequence **)pSource)->nRefCount );
+ idestructSequence(
+ *(uno_Sequence **)pDest, pDestType, pDestTypeDescr, release );
+ *(uno_Sequence **)pDest = *(uno_Sequence **)pSource;
+ return sal_True;
+ }
+ return sal_False;
+ case typelib_TypeClass_INTERFACE:
+ if (typelib_TypeClass_INTERFACE != pSourceType->eTypeClass)
+ return sal_False;
+ if (_type_equals( pDestType, pSourceType ))
+ {
+ _assignInterface( (void **)pDest, *(void **)pSource, acquire, release );
+ return sal_True;
+ }
+ else if (*static_cast< void ** >(pSource) == 0)
+ {
+ // A null reference of any interface type can be converted to a null
+ // reference of any other interface type:
+ void * const pToBeReleased = *static_cast< void ** >(pDest);
+ *static_cast< void ** >(pDest) = 0;
+ _release( pToBeReleased, release );
+ return true;
+ }
+ else
+ {
+ if (pSourceTypeDescr)
+ {
+ typelib_TypeDescription * pTD = pSourceTypeDescr;
+ while (pTD && !_type_equals( pTD->pWeakRef, pDestType ))
+ {
+ pTD = (typelib_TypeDescription *)
+ ((typelib_InterfaceTypeDescription *)pTD)->pBaseTypeDescription;
+ }
+ if (pTD) // is base of dest
+ {
+ _assignInterface( (void **)pDest, *(void **)pSource, acquire, release );
+ return true;
+ }
+ }
+
+ // query for interface:
+ void * pQueried = _queryInterface( *static_cast<void **>(pSource),
+ pDestType, queryInterface );
+ if (pQueried != 0) {
+ void * const pToBeReleased = *static_cast<void **>(pDest);
+ *static_cast<void **>(pDest) = pQueried;
+ _release( pToBeReleased, release );
+ }
+ return (pQueried != 0);
+ }
+ default:
+ OSL_ASSERT(false);
+ return sal_False;
+ }
+}
+
+}
+
+#endif
diff --git a/cppu/source/uno/cascade_mapping.cxx b/cppu/source/uno/cascade_mapping.cxx
new file mode 100644
index 000000000000..ee870a52e286
--- /dev/null
+++ b/cppu/source/uno/cascade_mapping.cxx
@@ -0,0 +1,341 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#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 * pParam)
+{
+ void ** ppOut = va_arg(*pParam, void **);
+ void * pInterface = va_arg(*pParam, void *);
+ typelib_InterfaceTypeDescription * pInterfaceTypeDescr = va_arg(*pParam, typelib_InterfaceTypeDescription *);
+ uno_Mapping * pMapping = va_arg(*pParam, 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;
+}
diff --git a/cppu/source/uno/cascade_mapping.hxx b/cppu/source/uno/cascade_mapping.hxx
new file mode 100644
index 000000000000..3b63e17198fb
--- /dev/null
+++ b/cppu/source/uno/cascade_mapping.hxx
@@ -0,0 +1,41 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_cascade_mapping_hxx
+#define INCLUDED_cascade_mapping_hxx
+
+#include "uno/environment.h"
+#include "uno/mapping.h"
+#include "rtl/ustring.h"
+
+
+void getCascadeMapping(uno_Mapping ** ppMapping,
+ uno_Environment * pFrom,
+ uno_Environment * pTo,
+ rtl_uString * pAddPurpose );
+
+#endif
diff --git a/cppu/source/uno/constr.hxx b/cppu/source/uno/constr.hxx
new file mode 100644
index 000000000000..8e6d35e9db64
--- /dev/null
+++ b/cppu/source/uno/constr.hxx
@@ -0,0 +1,267 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef CONSTR_HXX
+#define CONSTR_HXX
+
+#include "prim.hxx"
+
+
+namespace cppu
+{
+
+//##################################################################################################
+//#### construction ################################################################################
+//##################################################################################################
+
+//--------------------------------------------------------------------------------------------------
+inline void _defaultConstructUnion(
+ void * pMem,
+ typelib_TypeDescription * pTypeDescr )
+ SAL_THROW( () )
+{
+ ::uno_type_constructData(
+ (char *)pMem + ((typelib_UnionTypeDescription *)pTypeDescr)->nValueOffset,
+ ((typelib_UnionTypeDescription *)pTypeDescr)->pDefaultTypeRef );
+ *(sal_Int64 *)pMem = ((typelib_UnionTypeDescription *)pTypeDescr)->nDefaultDiscriminant;
+}
+//==================================================================================================
+void defaultConstructStruct(
+ void * pMem,
+ typelib_CompoundTypeDescription * pCompType )
+ SAL_THROW( () );
+//--------------------------------------------------------------------------------------------------
+inline void _defaultConstructStruct(
+ void * pMem,
+ typelib_CompoundTypeDescription * pTypeDescr )
+ SAL_THROW( () )
+{
+ if (pTypeDescr->pBaseTypeDescription)
+ {
+ defaultConstructStruct( pMem, pTypeDescr->pBaseTypeDescription );
+ }
+
+ typelib_TypeDescriptionReference ** ppTypeRefs = (pTypeDescr)->ppTypeRefs;
+ sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets;
+ sal_Int32 nDescr = pTypeDescr->nMembers;
+
+ while (nDescr--)
+ {
+ ::uno_type_constructData( (char *)pMem + pMemberOffsets[nDescr], ppTypeRefs[nDescr] );
+ }
+}
+
+//--------------------------------------------------------------------------------------------------
+inline void _defaultConstructArray(
+ void * pMem,
+ typelib_ArrayTypeDescription * pTypeDescr )
+{
+ typelib_TypeDescription * pElementType = NULL;
+ TYPELIB_DANGER_GET( &pElementType, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType );
+ sal_Int32 nTotalElements = pTypeDescr->nTotalElements;
+ sal_Int32 nElementSize = pElementType->nSize;
+ sal_Int32 i;
+ switch ( pElementType->eTypeClass )
+ {
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_FLOAT:
+ case typelib_TypeClass_DOUBLE:
+ case typelib_TypeClass_INTERFACE:
+ ::rtl_zeroMemory(pMem, nElementSize * nTotalElements);
+ break;
+
+ case typelib_TypeClass_STRING:
+ for (i=0; i < nTotalElements; i++)
+ {
+ rtl_uString** ppElement = (rtl_uString **)pMem + i;
+ *ppElement = 0;
+ rtl_uString_new( ppElement);
+ }
+ break;
+ case typelib_TypeClass_TYPE:
+ for (i=0; i < nTotalElements; i++)
+ {
+ typelib_TypeDescriptionReference** ppElement = (typelib_TypeDescriptionReference **)pMem + i;
+ *ppElement = _getVoidType();
+ }
+ break;
+ case typelib_TypeClass_ANY:
+ for (i=0; i < nTotalElements; i++)
+ {
+ CONSTRUCT_EMPTY_ANY( (uno_Any *)pMem + i );
+ }
+ break;
+ case typelib_TypeClass_ENUM:
+ for (i=0; i < nTotalElements; i++)
+ {
+ *((sal_Int32 *)pMem + i) = ((typelib_EnumTypeDescription *)pElementType)->nDefaultEnumValue;
+ }
+ break;
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ for (i=0; i < nTotalElements; i++)
+ {
+ _defaultConstructStruct( (sal_Char*)pMem + i * nElementSize, (typelib_CompoundTypeDescription *)pElementType );
+ }
+ break;
+ case typelib_TypeClass_UNION:
+ for (i=0; i < nTotalElements; i++)
+ {
+ _defaultConstructUnion( (sal_Char*)pMem + i * nElementSize, pElementType );
+ }
+ break;
+ case typelib_TypeClass_SEQUENCE:
+ for (i=0; i < nTotalElements; i++)
+ {
+ uno_Sequence** ppElement = (uno_Sequence **)pMem + i;
+ *ppElement = createEmptySequence();
+ }
+ break;
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pElementType );
+}
+
+//--------------------------------------------------------------------------------------------------
+inline void _defaultConstructData(
+ void * pMem,
+ typelib_TypeDescriptionReference * pType,
+ typelib_TypeDescription * pTypeDescr )
+ SAL_THROW( () )
+{
+ switch (pType->eTypeClass)
+ {
+ case typelib_TypeClass_CHAR:
+ *(sal_Unicode *)pMem = '\0';
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ *(sal_Bool *)pMem = sal_False;
+ break;
+ case typelib_TypeClass_BYTE:
+ *(sal_Int8 *)pMem = 0;
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *(sal_Int16 *)pMem = 0;
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ *(sal_Int32 *)pMem = 0;
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ *(sal_Int64 *)pMem = 0;
+ break;
+ case typelib_TypeClass_FLOAT:
+ *(float *)pMem = 0.0;
+ break;
+ case typelib_TypeClass_DOUBLE:
+ *(double *)pMem = 0.0;
+ break;
+ case typelib_TypeClass_STRING:
+ *(rtl_uString **)pMem = 0;
+ ::rtl_uString_new( (rtl_uString **)pMem );
+ break;
+ case typelib_TypeClass_TYPE:
+ *(typelib_TypeDescriptionReference **)pMem = _getVoidType();
+ break;
+ case typelib_TypeClass_ANY:
+ CONSTRUCT_EMPTY_ANY( (uno_Any *)pMem );
+ break;
+ case typelib_TypeClass_ENUM:
+ if (pTypeDescr)
+ {
+ *(sal_Int32 *)pMem = ((typelib_EnumTypeDescription *)pTypeDescr)->nDefaultEnumValue;
+ }
+ else
+ {
+ TYPELIB_DANGER_GET( &pTypeDescr, pType );
+ *(sal_Int32 *)pMem = ((typelib_EnumTypeDescription *)pTypeDescr)->nDefaultEnumValue;
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ }
+ break;
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ if (pTypeDescr)
+ {
+ _defaultConstructStruct( pMem, (typelib_CompoundTypeDescription *)pTypeDescr );
+ }
+ else
+ {
+ TYPELIB_DANGER_GET( &pTypeDescr, pType );
+ _defaultConstructStruct( pMem, (typelib_CompoundTypeDescription *)pTypeDescr );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ }
+ break;
+ case typelib_TypeClass_ARRAY:
+ if (pTypeDescr)
+ {
+ _defaultConstructArray( pMem, (typelib_ArrayTypeDescription *)pTypeDescr );
+ }
+ else
+ {
+ TYPELIB_DANGER_GET( &pTypeDescr, pType );
+ _defaultConstructArray( pMem, (typelib_ArrayTypeDescription *)pTypeDescr );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ }
+ break;
+ case typelib_TypeClass_UNION:
+ if (pTypeDescr)
+ {
+ _defaultConstructUnion( pMem, pTypeDescr );
+ }
+ else
+ {
+ TYPELIB_DANGER_GET( &pTypeDescr, pType );
+ _defaultConstructUnion( pMem, pTypeDescr );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ }
+ break;
+ case typelib_TypeClass_SEQUENCE:
+ *(uno_Sequence **)pMem = createEmptySequence();
+ break;
+ case typelib_TypeClass_INTERFACE:
+ *(void **)pMem = 0; // either cpp or c-uno interface
+ break;
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+}
+
+}
+
+#endif
diff --git a/cppu/source/uno/copy.hxx b/cppu/source/uno/copy.hxx
new file mode 100644
index 000000000000..7999b5ae0d2b
--- /dev/null
+++ b/cppu/source/uno/copy.hxx
@@ -0,0 +1,886 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef COPY_HXX
+#define COPY_HXX
+
+#include "prim.hxx"
+#include "constr.hxx"
+
+
+namespace cppu
+{
+
+//##################################################################################################
+//#### copy construction ###########################################################################
+//##################################################################################################
+
+//------------------------------------------------------------------------------
+inline uno_Sequence * allocSeq(
+ sal_Int32 nElementSize, sal_Int32 nElements )
+{
+ OSL_ASSERT( nElements >= 0 && nElementSize >= 0 );
+ uno_Sequence * pSeq = 0;
+ sal_uInt32 nSize = calcSeqMemSize( nElementSize, nElements );
+ if (nSize > 0)
+ {
+ pSeq = (uno_Sequence *) rtl_allocateMemory( nSize );
+ if (pSeq != 0)
+ {
+ // header init
+ pSeq->nRefCount = 1;
+ pSeq->nElements = nElements;
+ }
+ }
+ return pSeq;
+}
+
+//--------------------------------------------------------------------------------------------------
+void copyConstructStruct(
+ void * pDest, void * pSource,
+ typelib_CompoundTypeDescription * pTypeDescr,
+ uno_AcquireFunc acquire, uno_Mapping * mapping )
+ SAL_THROW ( () );
+//--------------------------------------------------------------------------------------------------
+inline void _copyConstructStruct(
+ void * pDest, void * pSource,
+ typelib_CompoundTypeDescription * pTypeDescr,
+ uno_AcquireFunc acquire, uno_Mapping * mapping )
+ SAL_THROW ( () )
+{
+ if (pTypeDescr->pBaseTypeDescription)
+ {
+ // copy base value
+ copyConstructStruct( pDest, pSource, pTypeDescr->pBaseTypeDescription, acquire, mapping );
+ }
+
+ // then copy members
+ typelib_TypeDescriptionReference ** ppTypeRefs = pTypeDescr->ppTypeRefs;
+ sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets;
+ sal_Int32 nDescr = pTypeDescr->nMembers;
+
+ if (mapping)
+ {
+ while (nDescr--)
+ {
+ ::uno_type_copyAndConvertData(
+ (char *)pDest + pMemberOffsets[nDescr],
+ (char *)pSource + pMemberOffsets[nDescr],
+ ppTypeRefs[nDescr], mapping );
+ }
+ }
+ else
+ {
+ while (nDescr--)
+ {
+ ::uno_type_copyData(
+ (char *)pDest + pMemberOffsets[nDescr],
+ (char *)pSource + pMemberOffsets[nDescr],
+ ppTypeRefs[nDescr], acquire );
+ }
+ }
+}
+//--------------------------------------------------------------------------------------------------
+inline void _copyConstructArray(
+ void * pDest, void * pSource,
+ typelib_ArrayTypeDescription * pTypeDescr,
+ uno_AcquireFunc acquire, uno_Mapping * mapping )
+{
+ typelib_TypeDescriptionReference * pElementTypeRef = ((typelib_IndirectTypeDescription *)pTypeDescr)->pType;
+ typelib_TypeDescription * pElementTypeDescr = NULL;
+ TYPELIB_DANGER_GET( &pElementTypeDescr, pElementTypeRef );
+ sal_Int32 nElementSize = ((typelib_TypeDescription*)pElementTypeDescr)->nSize;
+ TYPELIB_DANGER_RELEASE( pElementTypeDescr );
+ sal_Int32 nTotalElements = pTypeDescr->nTotalElements;
+
+ if (mapping)
+ {
+ for(sal_Int32 i = 0; i < nTotalElements; i++)
+ {
+ ::uno_type_copyAndConvertData(
+ (sal_Char *)pDest + i * nElementSize,
+ (sal_Char *)pSource + i * nElementSize,
+ pElementTypeRef, mapping );
+ }
+ }
+ else
+ {
+ for(sal_Int32 i = 0; i < nTotalElements; i++)
+ {
+ ::uno_type_copyData(
+ (sal_Char *)pDest + (i * nElementSize),
+ (sal_Char *)pSource + (i * nElementSize),
+ pElementTypeRef, acquire );
+ }
+ }
+}
+//--------------------------------------------------------------------------------------------------
+inline void _copyConstructUnion(
+ void * pDest, void * pSource,
+ typelib_TypeDescription * pTypeDescr,
+ uno_AcquireFunc acquire, uno_Mapping * mapping )
+ SAL_THROW ( () )
+{
+ typelib_TypeDescriptionReference * pSetType = _unionGetSetType( pSource, pTypeDescr );
+ if (mapping)
+ {
+ ::uno_type_copyAndConvertData(
+ (char *)pDest + ((typelib_UnionTypeDescription *)pTypeDescr)->nValueOffset,
+ (char *)pSource + ((typelib_UnionTypeDescription *)pTypeDescr)->nValueOffset,
+ pSetType, mapping );
+ }
+ else
+ {
+ ::uno_type_copyData(
+ (char *)pDest + ((typelib_UnionTypeDescription *)pTypeDescr)->nValueOffset,
+ (char *)pSource + ((typelib_UnionTypeDescription *)pTypeDescr)->nValueOffset,
+ pSetType, acquire );
+ }
+ *(sal_Int64 *)pDest = *(sal_Int64 *)pSource;
+ typelib_typedescriptionreference_release( pSetType );
+}
+
+//------------------------------------------------------------------------------
+uno_Sequence * copyConstructSequence(
+ uno_Sequence * pSource,
+ typelib_TypeDescriptionReference * pElementType,
+ uno_AcquireFunc acquire, uno_Mapping * mapping );
+
+//--------------------------------------------------------------------------------------------------
+inline void _copyConstructAnyFromData(
+ uno_Any * pDestAny, void * pSource,
+ typelib_TypeDescriptionReference * pType, typelib_TypeDescription * pTypeDescr,
+ uno_AcquireFunc acquire, uno_Mapping * mapping )
+ SAL_THROW ( () )
+{
+ TYPE_ACQUIRE( pType );
+ pDestAny->pType = pType;
+
+ switch (pType->eTypeClass)
+ {
+ case typelib_TypeClass_CHAR:
+ pDestAny->pData = &pDestAny->pReserved;
+ *(sal_Unicode *)&pDestAny->pReserved = *(sal_Unicode *)pSource;
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ pDestAny->pData = &pDestAny->pReserved;
+ *(sal_Bool *)&pDestAny->pReserved = (*(sal_Bool *)pSource != sal_False);
+ break;
+ case typelib_TypeClass_BYTE:
+ pDestAny->pData = &pDestAny->pReserved;
+ *(sal_Int8 *)&pDestAny->pReserved = *(sal_Int8 *)pSource;
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ pDestAny->pData = &pDestAny->pReserved;
+ *(sal_Int16 *)&pDestAny->pReserved = *(sal_Int16 *)pSource;
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ pDestAny->pData = &pDestAny->pReserved;
+ *(sal_Int32 *)&pDestAny->pReserved = *(sal_Int32 *)pSource;
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ if (sizeof(void *) >= sizeof(sal_Int64))
+ {
+ pDestAny->pData = &pDestAny->pReserved;
+ *(sal_Int64 *)&pDestAny->pReserved = *(sal_Int64 *)pSource;
+ }
+ else
+ {
+ pDestAny->pData = ::rtl_allocateMemory( sizeof(sal_Int64) );
+ *(sal_Int64 *)pDestAny->pData = *(sal_Int64 *)pSource;
+ }
+ break;
+ case typelib_TypeClass_FLOAT:
+ if (sizeof(void *) >= sizeof(float))
+ {
+ pDestAny->pData = &pDestAny->pReserved;
+ *(float *)&pDestAny->pReserved = *(float *)pSource;
+ }
+ else
+ {
+ pDestAny->pData = ::rtl_allocateMemory( sizeof(float) );
+ *(float *)pDestAny->pData = *(float *)pSource;
+ }
+ break;
+ case typelib_TypeClass_DOUBLE:
+ if (sizeof(void *) >= sizeof(double))
+ {
+ pDestAny->pData = &pDestAny->pReserved;
+ *(double *)&pDestAny->pReserved = *(double *)pSource;
+ }
+ else
+ {
+ pDestAny->pData = ::rtl_allocateMemory( sizeof(double) );
+ *(double *)pDestAny->pData = *(double *)pSource;
+ }
+ break;
+ case typelib_TypeClass_STRING:
+ ::rtl_uString_acquire( *(rtl_uString **)pSource );
+ pDestAny->pData = &pDestAny->pReserved;
+ *(rtl_uString **)&pDestAny->pReserved = *(rtl_uString **)pSource;
+ break;
+ case typelib_TypeClass_TYPE:
+ TYPE_ACQUIRE( *(typelib_TypeDescriptionReference **)pSource );
+ pDestAny->pData = &pDestAny->pReserved;
+ *(typelib_TypeDescriptionReference **)&pDestAny->pReserved = *(typelib_TypeDescriptionReference **)pSource;
+ break;
+ case typelib_TypeClass_ANY:
+ OSL_ENSURE( 0, "### unexpected nested any!" );
+ break;
+ case typelib_TypeClass_ENUM:
+ pDestAny->pData = &pDestAny->pReserved;
+ // enum is forced to 32bit long
+ *(sal_Int32 *)&pDestAny->pReserved = *(sal_Int32 *)pSource;
+ break;
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ if (pTypeDescr)
+ {
+ pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize );
+ _copyConstructStruct(
+ pDestAny->pData, pSource,
+ (typelib_CompoundTypeDescription *)pTypeDescr,
+ acquire, mapping );
+ }
+ else
+ {
+ TYPELIB_DANGER_GET( &pTypeDescr, pType );
+ pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize );
+ _copyConstructStruct(
+ pDestAny->pData, pSource,
+ (typelib_CompoundTypeDescription *)pTypeDescr,
+ acquire, mapping );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ }
+ break;
+ case typelib_TypeClass_ARRAY:
+ if (pTypeDescr)
+ {
+ pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize );
+ _copyConstructArray(
+ pDestAny->pData, pSource,
+ (typelib_ArrayTypeDescription *)pTypeDescr,
+ acquire, mapping );
+ }
+ else
+ {
+ TYPELIB_DANGER_GET( &pTypeDescr, pType );
+ pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize );
+ _copyConstructArray(
+ pDestAny->pData, pSource,
+ (typelib_ArrayTypeDescription *)pTypeDescr,
+ acquire, mapping );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ }
+ break;
+ case typelib_TypeClass_UNION:
+ if (pTypeDescr)
+ {
+ pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize );
+ _copyConstructUnion( pDestAny->pData, pSource, pTypeDescr, acquire, mapping );
+ }
+ else
+ {
+ TYPELIB_DANGER_GET( &pTypeDescr, pType );
+ pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize );
+ _copyConstructUnion( pDestAny->pData, pSource, pTypeDescr, acquire, mapping );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ }
+ break;
+ case typelib_TypeClass_SEQUENCE:
+ pDestAny->pData = &pDestAny->pReserved;
+ if (pTypeDescr)
+ {
+ *(uno_Sequence **)&pDestAny->pReserved = copyConstructSequence(
+ *(uno_Sequence **)pSource,
+ ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
+ acquire, mapping );
+ }
+ else
+ {
+ TYPELIB_DANGER_GET( &pTypeDescr, pType );
+ *(uno_Sequence **)&pDestAny->pReserved = copyConstructSequence(
+ *(uno_Sequence **)pSource,
+ ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
+ acquire, mapping );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ }
+ break;
+ case typelib_TypeClass_INTERFACE:
+ pDestAny->pData = &pDestAny->pReserved;
+ if (mapping)
+ {
+ pDestAny->pReserved = _map( *(void **)pSource, pType, pTypeDescr, mapping );
+ }
+ else
+ {
+ _acquire( pDestAny->pReserved = *(void **)pSource, acquire );
+ }
+ break;
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+}
+//--------------------------------------------------------------------------------------------------
+inline void _copyConstructAny(
+ uno_Any * pDestAny, void * pSource,
+ typelib_TypeDescriptionReference * pType, typelib_TypeDescription * pTypeDescr,
+ uno_AcquireFunc acquire, uno_Mapping * mapping )
+ SAL_THROW ( () )
+{
+ if (typelib_TypeClass_VOID == pType->eTypeClass)
+ {
+ CONSTRUCT_EMPTY_ANY( pDestAny );
+ }
+ else
+ {
+ if (typelib_TypeClass_ANY == pType->eTypeClass)
+ {
+ if (pSource)
+ {
+ pType = ((uno_Any *)pSource)->pType;
+ if (typelib_TypeClass_VOID == pType->eTypeClass)
+ {
+ CONSTRUCT_EMPTY_ANY( pDestAny );
+ return;
+ }
+ pTypeDescr = 0;
+ pSource = ((uno_Any *)pSource)->pData;
+ }
+ else
+ {
+ CONSTRUCT_EMPTY_ANY( pDestAny );
+ return;
+ }
+ }
+ if (pSource)
+ {
+ _copyConstructAnyFromData( pDestAny, pSource, pType, pTypeDescr, acquire, mapping );
+ }
+ else // default construct
+ {
+ TYPE_ACQUIRE( pType );
+ pDestAny->pType = pType;
+ switch (pType->eTypeClass)
+ {
+ case typelib_TypeClass_CHAR:
+ pDestAny->pData = &pDestAny->pReserved;
+ *(sal_Unicode *)&pDestAny->pReserved = '\0';
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ pDestAny->pData = &pDestAny->pReserved;
+ *(sal_Bool *)&pDestAny->pReserved = sal_False;
+ break;
+ case typelib_TypeClass_BYTE:
+ pDestAny->pData = &pDestAny->pReserved;
+ *(sal_Int8 *)&pDestAny->pReserved = 0;
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ pDestAny->pData = &pDestAny->pReserved;
+ *(sal_Int16 *)&pDestAny->pReserved = 0;
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ pDestAny->pData = &pDestAny->pReserved;
+ *(sal_Int32 *)&pDestAny->pReserved = 0;
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ if (sizeof(void *) >= sizeof(sal_Int64))
+ {
+ pDestAny->pData = &pDestAny->pReserved;
+ *(sal_Int64 *)&pDestAny->pReserved = 0;
+ }
+ else
+ {
+ pDestAny->pData = ::rtl_allocateMemory( sizeof(sal_Int64) );
+ *(sal_Int64 *)pDestAny->pData = 0;
+ }
+ break;
+ case typelib_TypeClass_FLOAT:
+ if (sizeof(void *) >= sizeof(float))
+ {
+ pDestAny->pData = &pDestAny->pReserved;
+ *(float *)&pDestAny->pReserved = 0.0;
+ }
+ else
+ {
+ pDestAny->pData = ::rtl_allocateMemory( sizeof(float) );
+ *(float *)pDestAny->pData = 0.0;
+ }
+ break;
+ case typelib_TypeClass_DOUBLE:
+ if (sizeof(void *) >= sizeof(double))
+ {
+ pDestAny->pData = &pDestAny->pReserved;
+ *(double *)&pDestAny->pReserved = 0.0;
+ }
+ else
+ {
+ pDestAny->pData = ::rtl_allocateMemory( sizeof(double) );
+ *(double *)pDestAny->pData = 0.0;
+ }
+ break;
+ case typelib_TypeClass_STRING:
+ pDestAny->pData = &pDestAny->pReserved;
+ *(rtl_uString **)&pDestAny->pReserved = 0;
+ ::rtl_uString_new( (rtl_uString **)&pDestAny->pReserved );
+ break;
+ case typelib_TypeClass_TYPE:
+ pDestAny->pData = &pDestAny->pReserved;
+ *(typelib_TypeDescriptionReference **)&pDestAny->pReserved = _getVoidType();
+ break;
+ case typelib_TypeClass_ENUM:
+ pDestAny->pData = &pDestAny->pReserved;
+ if (pTypeDescr)
+ {
+ *(sal_Int32 *)&pDestAny->pReserved = ((typelib_EnumTypeDescription *)pTypeDescr)->nDefaultEnumValue;
+ }
+ else
+ {
+ TYPELIB_DANGER_GET( &pTypeDescr, pType );
+ *(sal_Int32 *)&pDestAny->pReserved = ((typelib_EnumTypeDescription *)pTypeDescr)->nDefaultEnumValue;
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ }
+ break;
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ if (pTypeDescr)
+ {
+ pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize );
+ _defaultConstructStruct(
+ pDestAny->pData, (typelib_CompoundTypeDescription *)pTypeDescr );
+ }
+ else
+ {
+ TYPELIB_DANGER_GET( &pTypeDescr, pType );
+ pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize );
+ _defaultConstructStruct(
+ pDestAny->pData, (typelib_CompoundTypeDescription *)pTypeDescr );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ }
+ break;
+ case typelib_TypeClass_ARRAY:
+ if (pTypeDescr)
+ {
+ pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize );
+ _defaultConstructArray(
+ pDestAny->pData, (typelib_ArrayTypeDescription *)pTypeDescr );
+ }
+ else
+ {
+ TYPELIB_DANGER_GET( &pTypeDescr, pType );
+ pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize );
+ _defaultConstructArray(
+ pDestAny->pData, (typelib_ArrayTypeDescription *)pTypeDescr );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ }
+ break;
+ case typelib_TypeClass_UNION:
+ if (pTypeDescr)
+ {
+ pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize );
+ _defaultConstructUnion( pDestAny->pData, pTypeDescr );
+ }
+ else
+ {
+ TYPELIB_DANGER_GET( &pTypeDescr, pType );
+ pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize );
+ _defaultConstructUnion( pDestAny->pData, pTypeDescr );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ }
+ break;
+ case typelib_TypeClass_SEQUENCE:
+ pDestAny->pData = &pDestAny->pReserved;
+ *(uno_Sequence **)&pDestAny->pReserved = createEmptySequence();
+ break;
+ case typelib_TypeClass_INTERFACE:
+ pDestAny->pData = &pDestAny->pReserved;
+ pDestAny->pReserved = 0; // either cpp or c-uno interface
+ break;
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ }
+ }
+}
+//------------------------------------------------------------------------------
+inline uno_Sequence * icopyConstructSequence(
+ uno_Sequence * pSource,
+ typelib_TypeDescriptionReference * pElementType,
+ uno_AcquireFunc acquire, uno_Mapping * mapping )
+{
+ typelib_TypeClass eTypeClass = pElementType->eTypeClass;
+ if (!mapping ||
+ (eTypeClass <= typelib_TypeClass_ENUM &&
+ eTypeClass != typelib_TypeClass_ANY))
+ {
+ ::osl_incrementInterlockedCount( &pSource->nRefCount );
+ return pSource;
+ }
+ else // create new sequence
+ {
+ uno_Sequence * pDest;
+ sal_Int32 nElements = pSource->nElements;
+ if (nElements)
+ {
+ switch (eTypeClass)
+ {
+ case typelib_TypeClass_ANY:
+ {
+ pDest = allocSeq( sizeof (uno_Any), nElements );
+ if (pDest != 0)
+ {
+ uno_Any * pDestElements = (uno_Any *)pDest->elements;
+ uno_Any * pSourceElements = (uno_Any *)pSource->elements;
+ for ( sal_Int32 nPos = nElements; nPos--; )
+ {
+ typelib_TypeDescriptionReference * pType =
+ pSourceElements[nPos].pType;
+ if (typelib_TypeClass_VOID == pType->eTypeClass)
+ {
+ CONSTRUCT_EMPTY_ANY( &pDestElements[nPos] );
+ }
+ else
+ {
+ _copyConstructAnyFromData(
+ &pDestElements[nPos],
+ pSourceElements[nPos].pData,
+ pType, 0,
+ acquire, mapping );
+ }
+ }
+ }
+ break;
+ }
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ typelib_TypeDescription * pElementTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
+ sal_Int32 nElementSize = pElementTypeDescr->nSize;
+ char * pSourceElements = pSource->elements;
+ pDest = allocSeq( nElementSize, nElements );
+ if (pDest != 0)
+ {
+ char * pElements = pDest->elements;
+ for ( sal_Int32 nPos = nElements; nPos--; )
+ {
+ _copyConstructStruct(
+ pElements + (nPos * nElementSize),
+ pSourceElements + (nPos * nElementSize),
+ (typelib_CompoundTypeDescription *)
+ pElementTypeDescr,
+ acquire, mapping );
+ }
+ }
+ TYPELIB_DANGER_RELEASE( pElementTypeDescr );
+ break;
+ }
+ case typelib_TypeClass_ARRAY:
+ {
+ typelib_TypeDescription * pElementTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
+ sal_Int32 nElementSize = pElementTypeDescr->nSize;
+ char * pSourceElements = pSource->elements;
+ pDest = allocSeq( nElementSize, nElements );
+ if (pDest != 0)
+ {
+ char * pElements = pDest->elements;
+ for ( sal_Int32 nPos = nElements; nPos--; )
+ {
+ _copyConstructArray(
+ pElements + (nPos * nElementSize),
+ pSourceElements + (nPos * nElementSize),
+ (typelib_ArrayTypeDescription *)pElementTypeDescr,
+ acquire, mapping );
+ }
+ }
+ TYPELIB_DANGER_RELEASE( pElementTypeDescr );
+ break;
+ }
+ case typelib_TypeClass_UNION:
+ {
+ typelib_TypeDescription * pElementTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
+ sal_Int32 nElementSize = pElementTypeDescr->nSize;
+ sal_Int32 nValueOffset =
+ ((typelib_UnionTypeDescription *)
+ pElementTypeDescr)->nValueOffset;
+ pDest = allocSeq( nElementSize, nElements );
+ if (pDest != 0)
+ {
+ char * pElements = pDest->elements;
+ char * pSourceElements = pSource->elements;
+ for ( sal_Int32 nPos = nElements; nPos--; )
+ {
+ char * pDest2 =
+ pElements + (nPos * nElementSize);
+ char * pSource2 =
+ pSourceElements + (nPos * nElementSize);
+
+ typelib_TypeDescriptionReference * pSetType =
+ _unionGetSetType( pSource2, pElementTypeDescr );
+ ::uno_type_copyAndConvertData(
+ pDest2 + nValueOffset, pSource2 + nValueOffset,
+ pSetType, mapping );
+ *(sal_Int64 *)pDest2 = *(sal_Int64 *)pSource2;
+ ::typelib_typedescriptionreference_release( pSetType );
+ }
+ }
+ TYPELIB_DANGER_RELEASE( pElementTypeDescr );
+ break;
+ }
+ case typelib_TypeClass_SEQUENCE: // sequence of sequence
+ {
+ pDest = allocSeq( sizeof (uno_Sequence *), nElements );
+ if (pDest != 0)
+ {
+ typelib_TypeDescription * pElementTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
+ typelib_TypeDescriptionReference * pSeqElementType =
+ ((typelib_IndirectTypeDescription *)
+ pElementTypeDescr)->pType;
+
+ uno_Sequence ** pDestElements =
+ (uno_Sequence **) pDest->elements;
+ uno_Sequence ** pSourceElements =
+ (uno_Sequence **) pSource->elements;
+ for ( sal_Int32 nPos = nElements; nPos--; )
+ {
+ uno_Sequence * pNew = copyConstructSequence(
+ pSourceElements[nPos],
+ pSeqElementType,
+ acquire, mapping );
+ OSL_ASSERT( pNew != 0 );
+ // ought never be a memory allocation problem,
+ // because of reference counted sequence handles
+ pDestElements[ nPos ] = pNew;
+ }
+
+ TYPELIB_DANGER_RELEASE( pElementTypeDescr );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE:
+ {
+ pDest = allocSeq( sizeof (void *), nElements );
+ if (pDest != 0)
+ {
+ char * pElements = pDest->elements;
+ void ** pSourceElements = (void **)pSource->elements;
+ if (mapping)
+ {
+ typelib_TypeDescription * pElementTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
+ for ( sal_Int32 nPos = nElements; nPos--; )
+ {
+ ((void **)pElements)[nPos] = 0;
+ if (((void **)pSourceElements)[nPos])
+ {
+ (*mapping->mapInterface)(
+ mapping, (void **)pElements + nPos,
+ pSourceElements[nPos],
+ (typelib_InterfaceTypeDescription *)
+ pElementTypeDescr );
+ }
+ }
+ TYPELIB_DANGER_RELEASE( pElementTypeDescr );
+ }
+ else
+ {
+ for ( sal_Int32 nPos = nElements; nPos--; )
+ {
+ ((void **)pElements)[nPos] = pSourceElements[nPos];
+ _acquire( ((void **)pElements)[nPos], acquire );
+ }
+ }
+ }
+ break;
+ }
+ default:
+ OSL_ENSURE( 0, "### unexepcted sequence element type!" );
+ pDest = 0;
+ break;
+ }
+ }
+ else // empty sequence
+ {
+ pDest = allocSeq( 0, 0 );
+ }
+
+ return pDest;
+ }
+}
+
+//--------------------------------------------------------------------------------------------------
+inline void _copyConstructData(
+ void * pDest, void * pSource,
+ typelib_TypeDescriptionReference * pType, typelib_TypeDescription * pTypeDescr,
+ uno_AcquireFunc acquire, uno_Mapping * mapping )
+ SAL_THROW ( () )
+{
+ switch (pType->eTypeClass)
+ {
+ case typelib_TypeClass_CHAR:
+ *(sal_Unicode *)pDest = *(sal_Unicode *)pSource;
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ *(sal_Bool *)pDest = (*(sal_Bool *)pSource != sal_False);
+ break;
+ case typelib_TypeClass_BYTE:
+ *(sal_Int8 *)pDest = *(sal_Int8 *)pSource;
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *(sal_Int16 *)pDest = *(sal_Int16 *)pSource;
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ *(sal_Int32 *)pDest = *(sal_Int32 *)pSource;
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ *(sal_Int64 *)pDest = *(sal_Int64 *)pSource;
+ break;
+ case typelib_TypeClass_FLOAT:
+ *(float *)pDest = *(float *)pSource;
+ break;
+ case typelib_TypeClass_DOUBLE:
+ *(double *)pDest = *(double *)pSource;
+ break;
+ case typelib_TypeClass_STRING:
+ ::rtl_uString_acquire( *(rtl_uString **)pSource );
+ *(rtl_uString **)pDest = *(rtl_uString **)pSource;
+ break;
+ case typelib_TypeClass_TYPE:
+ TYPE_ACQUIRE( *(typelib_TypeDescriptionReference **)pSource );
+ *(typelib_TypeDescriptionReference **)pDest = *(typelib_TypeDescriptionReference **)pSource;
+ break;
+ case typelib_TypeClass_ANY:
+ _copyConstructAny(
+ (uno_Any *)pDest, ((uno_Any *)pSource)->pData,
+ ((uno_Any *)pSource)->pType, 0,
+ acquire, mapping );
+ break;
+ case typelib_TypeClass_ENUM:
+ *(sal_Int32 *)pDest = *(sal_Int32 *)pSource;
+ break;
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ if (pTypeDescr)
+ {
+ _copyConstructStruct(
+ pDest, pSource,
+ (typelib_CompoundTypeDescription *)pTypeDescr,
+ acquire, mapping );
+ }
+ else
+ {
+ TYPELIB_DANGER_GET( &pTypeDescr, pType );
+ _copyConstructStruct(
+ pDest, pSource,
+ (typelib_CompoundTypeDescription *)pTypeDescr,
+ acquire, mapping );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ }
+ break;
+ case typelib_TypeClass_ARRAY:
+ if (pTypeDescr)
+ {
+ _copyConstructArray(
+ pDest, pSource,
+ (typelib_ArrayTypeDescription *)pTypeDescr,
+ acquire, mapping );
+ }
+ else
+ {
+ TYPELIB_DANGER_GET( &pTypeDescr, pType );
+ _copyConstructArray(
+ pDest, pSource,
+ (typelib_ArrayTypeDescription *)pTypeDescr,
+ acquire, mapping );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ }
+ break;
+ case typelib_TypeClass_UNION:
+ if (pTypeDescr)
+ {
+ _copyConstructUnion( pDest, pSource, pTypeDescr, acquire, mapping );
+ }
+ else
+ {
+ TYPELIB_DANGER_GET( &pTypeDescr, pType );
+ _copyConstructUnion( pDest, pSource, pTypeDescr, acquire, mapping );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ }
+ break;
+ case typelib_TypeClass_SEQUENCE:
+ if (mapping)
+ {
+ if (pTypeDescr)
+ {
+ *(uno_Sequence **)pDest = icopyConstructSequence(
+ *(uno_Sequence **)pSource,
+ ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
+ acquire, mapping );
+ }
+ else
+ {
+ TYPELIB_DANGER_GET( &pTypeDescr, pType );
+ *(uno_Sequence **)pDest = icopyConstructSequence(
+ *(uno_Sequence **)pSource,
+ ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
+ acquire, mapping );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ }
+ }
+ else
+ {
+ ::osl_incrementInterlockedCount( &(*(uno_Sequence **)pSource)->nRefCount );
+ *(uno_Sequence **)pDest = *(uno_Sequence **)pSource;
+ }
+ break;
+ case typelib_TypeClass_INTERFACE:
+ if (mapping)
+ *(void **)pDest = _map( *(void **)pSource, pType, pTypeDescr, mapping );
+ else
+ _acquire( *(void **)pDest = *(void **)pSource, acquire );
+ break;
+ default:
+ break;
+ }
+}
+
+}
+
+#endif
diff --git a/cppu/source/uno/data.cxx b/cppu/source/uno/data.cxx
new file mode 100644
index 000000000000..5b29637b581b
--- /dev/null
+++ b/cppu/source/uno/data.cxx
@@ -0,0 +1,617 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_cppu.hxx"
+
+#include "cppu/macros.hxx"
+
+#include "osl/mutex.hxx"
+
+#include "constr.hxx"
+#include "destr.hxx"
+#include "copy.hxx"
+#include "assign.hxx"
+#include "eq.hxx"
+
+#include "boost/static_assert.hpp"
+
+
+using namespace ::cppu;
+using namespace ::rtl;
+using namespace ::osl;
+
+
+namespace cppu
+{
+
+// Sequence<>() (default ctor) relies on this being static:
+uno_Sequence g_emptySeq = { 1, 0, { 0 } };
+typelib_TypeDescriptionReference * g_pVoidType = 0;
+
+//--------------------------------------------------------------------------------------------------
+void * binuno_queryInterface( void * pUnoI, typelib_TypeDescriptionReference * pDestType )
+{
+ // init queryInterface() td
+ static typelib_TypeDescription * g_pQITD = 0;
+ if (0 == g_pQITD)
+ {
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ if (0 == g_pQITD)
+ {
+ typelib_TypeDescriptionReference * type_XInterface =
+ * typelib_static_type_getByTypeClass( typelib_TypeClass_INTERFACE );
+ typelib_InterfaceTypeDescription * pTXInterfaceDescr = 0;
+ TYPELIB_DANGER_GET( (typelib_TypeDescription **) &pTXInterfaceDescr, type_XInterface );
+ OSL_ASSERT( pTXInterfaceDescr->ppAllMembers );
+ typelib_typedescriptionreference_getDescription(
+ &g_pQITD, pTXInterfaceDescr->ppAllMembers[ 0 ] );
+ TYPELIB_DANGER_RELEASE( (typelib_TypeDescription *) pTXInterfaceDescr );
+ }
+ }
+
+ uno_Any aRet, aExc;
+ uno_Any * pExc = &aExc;
+ void * aArgs[ 1 ];
+ aArgs[ 0 ] = &pDestType;
+ (*((uno_Interface *) pUnoI)->pDispatcher)(
+ (uno_Interface *) pUnoI, g_pQITD, &aRet, aArgs, &pExc );
+
+ uno_Interface * ret = 0;
+ if (0 == pExc)
+ {
+ typelib_TypeDescriptionReference * ret_type = aRet.pType;
+ switch (ret_type->eTypeClass)
+ {
+ case typelib_TypeClass_VOID: // common case
+ typelib_typedescriptionreference_release( ret_type );
+ break;
+ case typelib_TypeClass_INTERFACE:
+ // tweaky... avoiding acquire/ release pair
+ typelib_typedescriptionreference_release( ret_type );
+ ret = (uno_Interface *) aRet.pReserved; // serving acquired interface
+ break;
+ default:
+ _destructAny( &aRet, 0 );
+ break;
+ }
+ }
+ else
+ {
+#if OSL_DEBUG_LEVEL > 1
+ OUStringBuffer buf( 128 );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("### exception occured querying for interface ") );
+ buf.append( * reinterpret_cast< OUString const * >( &pDestType->pTypeName ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(": [") );
+ buf.append( * reinterpret_cast< OUString const * >( &pExc->pType->pTypeName ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] ") );
+ // Message is very first member
+ buf.append( * reinterpret_cast< OUString const * >( pExc->pData ) );
+ OString cstr(
+ OUStringToOString( buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr.getStr() );
+#endif
+ uno_any_destruct( pExc, 0 );
+ }
+ return ret;
+}
+
+//==================================================================================================
+void defaultConstructStruct(
+ void * pMem,
+ typelib_CompoundTypeDescription * pCompType )
+ SAL_THROW( () )
+{
+ _defaultConstructStruct( pMem, pCompType );
+}
+//==================================================================================================
+void copyConstructStruct(
+ void * pDest, void * pSource,
+ typelib_CompoundTypeDescription * pTypeDescr,
+ uno_AcquireFunc acquire, uno_Mapping * mapping )
+ SAL_THROW( () )
+{
+ _copyConstructStruct( pDest, pSource, pTypeDescr, acquire, mapping );
+}
+//==================================================================================================
+void destructStruct(
+ void * pValue,
+ typelib_CompoundTypeDescription * pTypeDescr,
+ uno_ReleaseFunc release )
+ SAL_THROW( () )
+{
+ _destructStruct( pValue, pTypeDescr, release );
+}
+//==================================================================================================
+sal_Bool equalStruct(
+ void * pDest, void *pSource,
+ typelib_CompoundTypeDescription * pTypeDescr,
+ uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release )
+ SAL_THROW( () )
+{
+ return _equalStruct( pDest, pSource, pTypeDescr, queryInterface, release );
+}
+//==================================================================================================
+sal_Bool assignStruct(
+ void * pDest, void * pSource,
+ typelib_CompoundTypeDescription * pTypeDescr,
+ uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release )
+ SAL_THROW( () )
+{
+ return _assignStruct( pDest, pSource, pTypeDescr, queryInterface, acquire, release );
+}
+
+//==============================================================================
+uno_Sequence * copyConstructSequence(
+ uno_Sequence * pSource,
+ typelib_TypeDescriptionReference * pElementType,
+ uno_AcquireFunc acquire, uno_Mapping * mapping )
+{
+ return icopyConstructSequence( pSource, pElementType, acquire, mapping );
+}
+
+//==============================================================================
+void destructSequence(
+ uno_Sequence * pSequence,
+ typelib_TypeDescriptionReference * pType,
+ typelib_TypeDescription * pTypeDescr,
+ uno_ReleaseFunc release )
+{
+ idestructSequence( pSequence, pType, pTypeDescr, release );
+}
+
+//==================================================================================================
+sal_Bool equalSequence(
+ uno_Sequence * pDest, uno_Sequence * pSource,
+ typelib_TypeDescriptionReference * pElementType,
+ uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release )
+ SAL_THROW( () )
+{
+ return _equalSequence( pDest, pSource, pElementType, queryInterface, release );
+}
+
+extern "C"
+{
+//##################################################################################################
+void SAL_CALL uno_type_constructData(
+ void * pMem, typelib_TypeDescriptionReference * pType )
+ SAL_THROW_EXTERN_C()
+{
+ _defaultConstructData( pMem, pType, 0 );
+}
+//##################################################################################################
+void SAL_CALL uno_constructData(
+ void * pMem, typelib_TypeDescription * pTypeDescr )
+ SAL_THROW_EXTERN_C()
+{
+ _defaultConstructData( pMem, pTypeDescr->pWeakRef, pTypeDescr );
+}
+//##################################################################################################
+void SAL_CALL uno_type_destructData(
+ void * pValue, typelib_TypeDescriptionReference * pType,
+ uno_ReleaseFunc release )
+ SAL_THROW_EXTERN_C()
+{
+ _destructData( pValue, pType, 0, release );
+}
+//##################################################################################################
+void SAL_CALL uno_destructData(
+ void * pValue,
+ typelib_TypeDescription * pTypeDescr,
+ uno_ReleaseFunc release )
+ SAL_THROW_EXTERN_C()
+{
+ _destructData( pValue, pTypeDescr->pWeakRef, pTypeDescr, release );
+}
+//##################################################################################################
+void SAL_CALL uno_type_copyData(
+ void * pDest, void * pSource,
+ typelib_TypeDescriptionReference * pType,
+ uno_AcquireFunc acquire )
+ SAL_THROW_EXTERN_C()
+{
+ _copyConstructData( pDest, pSource, pType, 0, acquire, 0 );
+}
+//##################################################################################################
+void SAL_CALL uno_copyData(
+ void * pDest, void * pSource,
+ typelib_TypeDescription * pTypeDescr,
+ uno_AcquireFunc acquire )
+ SAL_THROW_EXTERN_C()
+{
+ _copyConstructData( pDest, pSource, pTypeDescr->pWeakRef, pTypeDescr, acquire, 0 );
+}
+//##################################################################################################
+void SAL_CALL uno_type_copyAndConvertData(
+ void * pDest, void * pSource,
+ typelib_TypeDescriptionReference * pType,
+ uno_Mapping * mapping )
+ SAL_THROW_EXTERN_C()
+{
+ _copyConstructData( pDest, pSource, pType, 0, 0, mapping );
+}
+//##################################################################################################
+void SAL_CALL uno_copyAndConvertData(
+ void * pDest, void * pSource,
+ typelib_TypeDescription * pTypeDescr,
+ uno_Mapping * mapping )
+ SAL_THROW_EXTERN_C()
+{
+ _copyConstructData( pDest, pSource, pTypeDescr->pWeakRef, pTypeDescr, 0, mapping );
+}
+//##################################################################################################
+sal_Bool SAL_CALL uno_type_equalData(
+ void * pVal1, typelib_TypeDescriptionReference * pVal1Type,
+ void * pVal2, typelib_TypeDescriptionReference * pVal2Type,
+ uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release )
+ SAL_THROW_EXTERN_C()
+{
+ return _equalData(
+ pVal1, pVal1Type, 0,
+ pVal2, pVal2Type, 0,
+ queryInterface, release );
+}
+//##################################################################################################
+sal_Bool SAL_CALL uno_equalData(
+ void * pVal1, typelib_TypeDescription * pVal1TD,
+ void * pVal2, typelib_TypeDescription * pVal2TD,
+ uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release )
+ SAL_THROW_EXTERN_C()
+{
+ return _equalData(
+ pVal1, pVal1TD->pWeakRef, pVal1TD,
+ pVal2, pVal2TD->pWeakRef, pVal2TD,
+ queryInterface, release );
+}
+//##################################################################################################
+sal_Bool SAL_CALL uno_type_assignData(
+ void * pDest, typelib_TypeDescriptionReference * pDestType,
+ void * pSource, typelib_TypeDescriptionReference * pSourceType,
+ uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release )
+ SAL_THROW_EXTERN_C()
+{
+ return _assignData(
+ pDest, pDestType, 0,
+ pSource, pSourceType, 0,
+ queryInterface, acquire, release );
+}
+//##################################################################################################
+sal_Bool SAL_CALL uno_assignData(
+ void * pDest, typelib_TypeDescription * pDestTD,
+ void * pSource, typelib_TypeDescription * pSourceTD,
+ uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release )
+ SAL_THROW_EXTERN_C()
+{
+ return _assignData(
+ pDest, pDestTD->pWeakRef, pDestTD,
+ pSource, pSourceTD->pWeakRef, pSourceTD,
+ queryInterface, acquire, release );
+}
+//##################################################################################################
+sal_Bool SAL_CALL uno_type_isAssignableFromData(
+ typelib_TypeDescriptionReference * pAssignable,
+ void * pFrom, typelib_TypeDescriptionReference * pFromType,
+ uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release )
+ SAL_THROW_EXTERN_C()
+{
+ if (::typelib_typedescriptionreference_isAssignableFrom( pAssignable, pFromType ))
+ return sal_True;
+ if (typelib_TypeClass_INTERFACE != pFromType->eTypeClass ||
+ typelib_TypeClass_INTERFACE != pAssignable->eTypeClass)
+ {
+ return sal_False;
+ }
+
+ // query
+ if (0 == pFrom)
+ return sal_False;
+ void * pInterface = *(void **)pFrom;
+ if (0 == pInterface)
+ return sal_False;
+
+ if (0 == queryInterface)
+ queryInterface = binuno_queryInterface;
+ void * p = (*queryInterface)( pInterface, pAssignable );
+ _release( p, release );
+ return (0 != p);
+}
+}
+
+
+//##################################################################################################
+//##################################################################################################
+//##################################################################################################
+
+
+#if OSL_DEBUG_LEVEL > 1
+
+#include <stdio.h>
+
+#if defined( SAL_W32)
+#pragma pack(push, 8)
+#elif defined(SAL_OS2)
+#pragma pack(push, 4)
+#endif
+
+#if defined(INTEL) \
+ && (defined(__GNUC__) && (defined(LINUX) || defined(FREEBSD) || defined(OS2)) || defined(MACOSX) \
+ || defined(__SUNPRO_CC) && defined(SOLARIS))
+#define MAX_ALIGNMENT_4
+#endif
+
+#define OFFSET_OF( s, m ) ((sal_Size)((char *)&((s *)16)->m -16))
+
+#define BINTEST_VERIFY( c ) \
+ if (! (c)) { fprintf( stderr, "### binary compatibility test failed: " #c " [line %d]!!!\n", __LINE__ ); abort(); }
+#define BINTEST_VERIFYOFFSET( s, m, n ) \
+ if (OFFSET_OF(s, m) != n) { fprintf( stderr, "### OFFSET_OF(" #s ", " #m ") = %d instead of expected %d!!!\n", OFFSET_OF(s, m), n ); abort(); }
+
+#if OSL_DEBUG_LEVEL > 1
+#if defined(__GNUC__) && (defined(LINUX) || defined(FREEBSD)) && (defined(INTEL) || defined(POWERPC) || defined(X86_64) || defined(S390))
+#define BINTEST_VERIFYSIZE( s, n ) \
+ fprintf( stderr, "> sizeof(" #s ") = %d; __alignof__ (" #s ") = %d\n", sizeof(s), __alignof__ (s) ); \
+ if (sizeof(s) != n) { fprintf( stderr, "### sizeof(" #s ") = %d instead of expected %d!!!\n", sizeof(s), n ); abort(); }
+#else // ! GNUC
+#define BINTEST_VERIFYSIZE( s, n ) \
+ fprintf( stderr, "> sizeof(" #s ") = %d\n", sizeof(s) ); \
+ if (sizeof(s) != n) { fprintf( stderr, "### sizeof(" #s ") = %d instead of expected %d!!!\n", sizeof(s), n ); abort(); }
+#endif
+#else // ! OSL_DEBUG_LEVEL
+#define BINTEST_VERIFYSIZE( s, n ) \
+ if (sizeof(s) != n) { fprintf( stderr, "### sizeof(" #s ") = %d instead of expected %d!!!\n", sizeof(s), n ); abort(); }
+#endif
+
+struct C1
+{
+ sal_Int16 n1;
+};
+struct C2 : public C1
+{
+ sal_Int32 n2 CPPU_GCC3_ALIGN( C1 );
+};
+struct C3 : public C2
+{
+ double d3;
+ sal_Int32 n3;
+};
+struct C4 : public C3
+{
+ sal_Int32 n4 CPPU_GCC3_ALIGN( C3 );
+ double d4;
+};
+struct C5 : public C4
+{
+ sal_Int64 n5;
+ sal_Bool b5;
+};
+struct C6 : public C1
+{
+ C5 c6 CPPU_GCC3_ALIGN( C1 );
+ sal_Bool b6;
+};
+
+struct D
+{
+ sal_Int16 d;
+ sal_Int32 e;
+};
+struct E
+{
+ sal_Bool a;
+ sal_Bool b;
+ sal_Bool c;
+ sal_Int16 d;
+ sal_Int32 e;
+};
+
+struct M
+{
+ sal_Int32 n;
+ sal_Int16 o;
+};
+
+struct N : public M
+{
+ sal_Int16 p CPPU_GCC3_ALIGN( M );
+};
+struct N2
+{
+ M m;
+ sal_Int16 p;
+};
+
+struct O : public M
+{
+ double p;
+ sal_Int16 q;
+};
+struct O2 : public O
+{
+ sal_Int16 p2 CPPU_GCC3_ALIGN( O );
+};
+
+struct P : public N
+{
+ double p2;
+};
+
+struct empty
+{
+};
+struct second : public empty
+{
+ int a;
+};
+
+struct AlignSize_Impl
+{
+ sal_Int16 nInt16;
+ double dDouble;
+};
+
+struct Char1
+{
+ char c1;
+};
+struct Char2 : public Char1
+{
+ char c2 CPPU_GCC3_ALIGN( Char1 );
+};
+struct Char3 : public Char2
+{
+ char c3 CPPU_GCC3_ALIGN( Char2 );
+};
+struct Char4
+{
+ Char3 chars;
+ char c;
+};
+class Ref
+{
+ void * p;
+};
+enum Enum
+{
+ v = SAL_MAX_ENUM
+};
+
+
+class BinaryCompatible_Impl
+{
+public:
+ BinaryCompatible_Impl();
+};
+BinaryCompatible_Impl::BinaryCompatible_Impl()
+{
+ BOOST_STATIC_ASSERT( ((sal_Bool) true) == sal_True &&
+ (1 != 0) == sal_True );
+ BOOST_STATIC_ASSERT( ((sal_Bool) false) == sal_False &&
+ (1 == 0) == sal_False );
+#ifdef MAX_ALIGNMENT_4
+ // max alignment is 4
+ BINTEST_VERIFYOFFSET( AlignSize_Impl, dDouble, 4 );
+ BINTEST_VERIFYSIZE( AlignSize_Impl, 12 );
+#else
+ // max alignment is 8
+ BINTEST_VERIFYOFFSET( AlignSize_Impl, dDouble, 8 );
+ BINTEST_VERIFYSIZE( AlignSize_Impl, 16 );
+#endif
+
+ // sequence
+ BINTEST_VERIFY( (SAL_SEQUENCE_HEADER_SIZE % 8) == 0 );
+ // enum
+ BINTEST_VERIFY( sizeof( Enum ) == sizeof( sal_Int32 ) );
+ // any
+ BINTEST_VERIFY( sizeof(void *) >= sizeof(sal_Int32) );
+ BINTEST_VERIFY( sizeof( uno_Any ) == sizeof( void * ) * 3 );
+ BINTEST_VERIFYOFFSET( uno_Any, pType, 0 );
+ BINTEST_VERIFYOFFSET( uno_Any, pData, 1 * sizeof (void *) );
+ BINTEST_VERIFYOFFSET( uno_Any, pReserved, 2 * sizeof (void *) );
+ // interface
+ BINTEST_VERIFY( sizeof( Ref ) == sizeof( void * ) );
+ // string
+ BINTEST_VERIFY( sizeof( OUString ) == sizeof( rtl_uString * ) );
+ // struct
+ BINTEST_VERIFYSIZE( M, 8 );
+ BINTEST_VERIFYOFFSET( M, o, 4 );
+ BINTEST_VERIFYSIZE( N, 12 );
+ BINTEST_VERIFYOFFSET( N, p, 8 );
+ BINTEST_VERIFYSIZE( N2, 12 );
+ BINTEST_VERIFYOFFSET( N2, p, 8 );
+#ifdef MAX_ALIGNMENT_4
+ BINTEST_VERIFYSIZE( O, 20 );
+#else
+ BINTEST_VERIFYSIZE( O, 24 );
+#endif
+ BINTEST_VERIFYSIZE( D, 8 );
+ BINTEST_VERIFYOFFSET( D, e, 4 );
+ BINTEST_VERIFYOFFSET( E, d, 4 );
+ BINTEST_VERIFYOFFSET( E, e, 8 );
+
+ BINTEST_VERIFYSIZE( C1, 2 );
+ BINTEST_VERIFYSIZE( C2, 8 );
+ BINTEST_VERIFYOFFSET( C2, n2, 4 );
+
+#ifdef MAX_ALIGNMENT_4
+ BINTEST_VERIFYSIZE( C3, 20 );
+ BINTEST_VERIFYOFFSET( C3, d3, 8 );
+ BINTEST_VERIFYOFFSET( C3, n3, 16 );
+ BINTEST_VERIFYSIZE( C4, 32 );
+ BINTEST_VERIFYOFFSET( C4, n4, 20 );
+ BINTEST_VERIFYOFFSET( C4, d4, 24 );
+ BINTEST_VERIFYSIZE( C5, 44 );
+ BINTEST_VERIFYOFFSET( C5, n5, 32 );
+ BINTEST_VERIFYOFFSET( C5, b5, 40 );
+ BINTEST_VERIFYSIZE( C6, 52 );
+ BINTEST_VERIFYOFFSET( C6, c6, 4 );
+ BINTEST_VERIFYOFFSET( C6, b6, 48 );
+
+ BINTEST_VERIFYSIZE( O2, 24 );
+ BINTEST_VERIFYOFFSET( O2, p2, 20 );
+#else
+ BINTEST_VERIFYSIZE( C3, 24 );
+ BINTEST_VERIFYOFFSET( C3, d3, 8 );
+ BINTEST_VERIFYOFFSET( C3, n3, 16 );
+ BINTEST_VERIFYSIZE( C4, 40 );
+ BINTEST_VERIFYOFFSET( C4, n4, 24 );
+ BINTEST_VERIFYOFFSET( C4, d4, 32 );
+ BINTEST_VERIFYSIZE( C5, 56 );
+ BINTEST_VERIFYOFFSET( C5, n5, 40 );
+ BINTEST_VERIFYOFFSET( C5, b5, 48 );
+ BINTEST_VERIFYSIZE( C6, 72 );
+ BINTEST_VERIFYOFFSET( C6, c6, 8 );
+ BINTEST_VERIFYOFFSET( C6, b6, 64 );
+
+ BINTEST_VERIFYSIZE( O2, 32 );
+ BINTEST_VERIFYOFFSET( O2, p2, 24 );
+#endif
+
+ BINTEST_VERIFYSIZE( Char3, 3 );
+ BINTEST_VERIFYOFFSET( Char4, c, 3 );
+
+#ifdef MAX_ALIGNMENT_4
+ // max alignment is 4
+ BINTEST_VERIFYSIZE( P, 20 );
+#else
+ // alignment of P is 8, because of P[] ...
+ BINTEST_VERIFYSIZE( P, 24 );
+ BINTEST_VERIFYSIZE( second, sizeof( int ) );
+#endif
+}
+
+#ifdef SAL_W32
+# pragma pack(pop)
+#elif defined(SAL_OS2)
+# pragma pack()
+#endif
+
+static BinaryCompatible_Impl aTest;
+
+#endif
+
+}
diff --git a/cppu/source/uno/destr.hxx b/cppu/source/uno/destr.hxx
new file mode 100644
index 000000000000..8f156038ade5
--- /dev/null
+++ b/cppu/source/uno/destr.hxx
@@ -0,0 +1,438 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef DESTR_HXX
+#define DESTR_HXX
+
+#include "prim.hxx"
+
+
+namespace cppu
+{
+
+//##################################################################################################
+//#### destruction #################################################################################
+//##################################################################################################
+
+//--------------------------------------------------------------------------------------------------
+inline void _destructUnion(
+ void * pValue,
+ typelib_TypeDescription * pTypeDescr,
+ uno_ReleaseFunc release )
+ SAL_THROW( () )
+{
+ typelib_TypeDescriptionReference * pType = _unionGetSetType( pValue, pTypeDescr );
+ ::uno_type_destructData(
+ (char *)pValue + ((typelib_UnionTypeDescription *)pTypeDescr)->nValueOffset,
+ pType, release );
+ ::typelib_typedescriptionreference_release( pType );
+}
+//==================================================================================================
+void destructStruct(
+ void * pValue,
+ typelib_CompoundTypeDescription * pTypeDescr,
+ uno_ReleaseFunc release )
+ SAL_THROW( () );
+//--------------------------------------------------------------------------------------------------
+inline void _destructStruct(
+ void * pValue,
+ typelib_CompoundTypeDescription * pTypeDescr,
+ uno_ReleaseFunc release )
+ SAL_THROW( () )
+{
+ if (pTypeDescr->pBaseTypeDescription)
+ {
+ destructStruct( pValue, pTypeDescr->pBaseTypeDescription, release );
+ }
+
+ typelib_TypeDescriptionReference ** ppTypeRefs = pTypeDescr->ppTypeRefs;
+ sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets;
+ sal_Int32 nDescr = pTypeDescr->nMembers;
+ while (nDescr--)
+ {
+ ::uno_type_destructData(
+ (char *)pValue + pMemberOffsets[nDescr],
+ ppTypeRefs[nDescr], release );
+ }
+}
+
+//--------------------------------------------------------------------------------------------------
+inline void _destructArray(
+ void * pValue,
+ typelib_ArrayTypeDescription * pTypeDescr,
+ uno_ReleaseFunc release )
+ throw ()
+{
+ typelib_TypeDescription * pElementType = NULL;
+ TYPELIB_DANGER_GET( &pElementType, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType );
+ sal_Int32 nElementSize = pElementType->nSize;
+ TYPELIB_DANGER_RELEASE( pElementType );
+
+ sal_Int32 nTotalElements = pTypeDescr->nTotalElements;
+ for(sal_Int32 i=0; i < nTotalElements; i++)
+ {
+ ::uno_type_destructData(
+ (sal_Char *)pValue + i * nElementSize,
+ ((typelib_IndirectTypeDescription *)pTypeDescr)->pType, release );
+ }
+
+ typelib_typedescriptionreference_release(((typelib_IndirectTypeDescription *)pTypeDescr)->pType);
+}
+
+//==============================================================================
+void destructSequence(
+ uno_Sequence * pSequence,
+ typelib_TypeDescriptionReference * pType,
+ typelib_TypeDescription * pTypeDescr,
+ uno_ReleaseFunc release );
+
+//--------------------------------------------------------------------------------------------------
+inline void _destructAny(
+ uno_Any * pAny,
+ uno_ReleaseFunc release )
+ SAL_THROW( () )
+{
+ typelib_TypeDescriptionReference * pType = pAny->pType;
+
+ switch (pType->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ if (sizeof(void *) < sizeof(sal_Int64))
+ {
+ ::rtl_freeMemory( pAny->pData );
+ }
+ break;
+ case typelib_TypeClass_FLOAT:
+ if (sizeof(void *) < sizeof(float))
+ {
+ ::rtl_freeMemory( pAny->pData );
+ }
+ break;
+ case typelib_TypeClass_DOUBLE:
+ if (sizeof(void *) < sizeof(double))
+ {
+ ::rtl_freeMemory( pAny->pData );
+ }
+ break;
+ case typelib_TypeClass_STRING:
+ ::rtl_uString_release( (rtl_uString *)pAny->pReserved );
+ break;
+ case typelib_TypeClass_TYPE:
+ ::typelib_typedescriptionreference_release(
+ (typelib_TypeDescriptionReference *)pAny->pReserved );
+ break;
+ case typelib_TypeClass_ANY:
+ OSL_ENSURE( sal_False, "### unexpected nested any!" );
+ ::uno_any_destruct( (uno_Any *)pAny->pData, release );
+ ::rtl_freeMemory( pAny->pData );
+ break;
+ case typelib_TypeClass_TYPEDEF:
+ OSL_ENSURE( 0, "### unexpected typedef!" );
+ break;
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pType );
+ _destructStruct( pAny->pData, (typelib_CompoundTypeDescription *)pTypeDescr, release );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ ::rtl_freeMemory( pAny->pData );
+ break;
+ }
+ case typelib_TypeClass_UNION:
+ {
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pType );
+ _destructUnion( pAny->pData, pTypeDescr, release );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ ::rtl_freeMemory( pAny->pData );
+ break;
+ }
+ case typelib_TypeClass_SEQUENCE:
+ {
+ destructSequence(
+ *(uno_Sequence **) &pAny->pReserved, pType, 0, release );
+ break;
+ }
+ case typelib_TypeClass_INTERFACE:
+ _release( pAny->pReserved, release );
+ break;
+ default:
+ break;
+ }
+#if OSL_DEBUG_LEVEL > 0
+ pAny->pData = (void *)0xdeadbeef;
+#endif
+
+ ::typelib_typedescriptionreference_release( pType );
+}
+//--------------------------------------------------------------------------------------------------
+inline sal_Int32 idestructElements(
+ void * pElements, typelib_TypeDescriptionReference * pElementType,
+ sal_Int32 nStartIndex, sal_Int32 nStopIndex,
+ uno_ReleaseFunc release )
+ SAL_THROW( () )
+{
+ switch (pElementType->eTypeClass)
+ {
+ case typelib_TypeClass_CHAR:
+ return (sal_Int32)(sizeof(sal_Unicode));
+ case typelib_TypeClass_BOOLEAN:
+ return (sal_Int32)(sizeof(sal_Bool));
+ case typelib_TypeClass_BYTE:
+ return (sal_Int32)(sizeof(sal_Int8));
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ return (sal_Int32)(sizeof(sal_Int16));
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ return (sal_Int32)(sizeof(sal_Int32));
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ return (sal_Int32)(sizeof(sal_Int64));
+ case typelib_TypeClass_FLOAT:
+ return (sal_Int32)(sizeof(float));
+ case typelib_TypeClass_DOUBLE:
+ return (sal_Int32)(sizeof(double));
+
+ case typelib_TypeClass_STRING:
+ {
+ rtl_uString ** pDest = (rtl_uString **)pElements;
+ for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
+ {
+ ::rtl_uString_release( pDest[nPos] );
+ }
+ return (sal_Int32)(sizeof(rtl_uString *));
+ }
+ case typelib_TypeClass_TYPE:
+ {
+ typelib_TypeDescriptionReference ** pDest = (typelib_TypeDescriptionReference **)pElements;
+ for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
+ {
+ ::typelib_typedescriptionreference_release( pDest[nPos] );
+ }
+ return (sal_Int32)(sizeof(typelib_TypeDescriptionReference *));
+ }
+ case typelib_TypeClass_ANY:
+ {
+ uno_Any * pDest = (uno_Any *)pElements;
+ for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
+ {
+ _destructAny( &pDest[nPos], release );
+ }
+ return (sal_Int32)(sizeof(uno_Any));
+ }
+ case typelib_TypeClass_ENUM:
+ return (sal_Int32)(sizeof(sal_Int32));
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ typelib_TypeDescription * pElementTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
+ sal_Int32 nElementSize = pElementTypeDescr->nSize;
+ for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
+ {
+ _destructStruct(
+ (char *)pElements + (nElementSize * nPos),
+ (typelib_CompoundTypeDescription *)pElementTypeDescr,
+ release );
+ }
+ sal_Int32 nSize = pElementTypeDescr->nSize;
+ TYPELIB_DANGER_RELEASE( pElementTypeDescr );
+ return nSize;
+ }
+ case typelib_TypeClass_UNION:
+ {
+ typelib_TypeDescription * pElementTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
+ sal_Int32 nElementSize = pElementTypeDescr->nSize;
+ for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
+ {
+ _destructUnion(
+ (char *)pElements + (nElementSize * nPos),
+ pElementTypeDescr,
+ release );
+ }
+ sal_Int32 nSize = pElementTypeDescr->nSize;
+ TYPELIB_DANGER_RELEASE( pElementTypeDescr );
+ return nSize;
+ }
+ case typelib_TypeClass_SEQUENCE:
+ {
+ typelib_TypeDescription * pElementTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
+ uno_Sequence ** pDest = (uno_Sequence **)pElements;
+ for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
+ {
+ destructSequence(
+ pDest[nPos],
+ pElementTypeDescr->pWeakRef, pElementTypeDescr,
+ release );
+ }
+ TYPELIB_DANGER_RELEASE( pElementTypeDescr );
+ return (sal_Int32)(sizeof(uno_Sequence *));
+ }
+ case typelib_TypeClass_INTERFACE:
+ {
+ if (release)
+ {
+ for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
+ {
+ void * p = ((void **)pElements)[nPos];
+ if (p)
+ {
+ (*release)( p );
+ }
+ }
+ }
+ else
+ {
+ for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
+ {
+ uno_Interface * p = ((uno_Interface **)pElements)[nPos];
+ if (p)
+ {
+ (*p->release)( p );
+ }
+ }
+ }
+ return (sal_Int32)(sizeof(void *));
+ }
+ default:
+ OSL_ASSERT(false);
+ return 0;
+ }
+}
+
+//------------------------------------------------------------------------------
+inline void idestructSequence(
+ uno_Sequence * pSeq,
+ typelib_TypeDescriptionReference * pType,
+ typelib_TypeDescription * pTypeDescr,
+ uno_ReleaseFunc release )
+{
+ if (::osl_decrementInterlockedCount( &pSeq->nRefCount ) == 0)
+ {
+ if (pSeq->nElements > 0)
+ {
+ if (pTypeDescr)
+ {
+ idestructElements(
+ pSeq->elements,
+ ((typelib_IndirectTypeDescription *) pTypeDescr)->pType, 0,
+ pSeq->nElements, release );
+ }
+ else
+ {
+ TYPELIB_DANGER_GET( &pTypeDescr, pType );
+ idestructElements(
+ pSeq->elements,
+ ((typelib_IndirectTypeDescription *) pTypeDescr)->pType, 0,
+ pSeq->nElements, release );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ }
+ }
+ ::rtl_freeMemory( pSeq );
+ }
+}
+
+//--------------------------------------------------------------------------------------------------
+inline void _destructData(
+ void * pValue,
+ typelib_TypeDescriptionReference * pType,
+ typelib_TypeDescription * pTypeDescr,
+ uno_ReleaseFunc release )
+ SAL_THROW( () )
+{
+ switch (pType->eTypeClass)
+ {
+ case typelib_TypeClass_STRING:
+ ::rtl_uString_release( *(rtl_uString **)pValue );
+ break;
+ case typelib_TypeClass_TYPE:
+ ::typelib_typedescriptionreference_release( *(typelib_TypeDescriptionReference **)pValue );
+ break;
+ case typelib_TypeClass_ANY:
+ _destructAny( (uno_Any *)pValue, release );
+ break;
+ case typelib_TypeClass_TYPEDEF:
+ OSL_ENSURE( 0, "### unexpected typedef!" );
+ break;
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ if (pTypeDescr)
+ {
+ _destructStruct( pValue, (typelib_CompoundTypeDescription *)pTypeDescr, release );
+ }
+ else
+ {
+ TYPELIB_DANGER_GET( &pTypeDescr, pType );
+ _destructStruct( pValue, (typelib_CompoundTypeDescription *)pTypeDescr, release );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ }
+ break;
+ case typelib_TypeClass_ARRAY:
+ if (pTypeDescr)
+ {
+ _destructArray( pValue, (typelib_ArrayTypeDescription *)pTypeDescr, release );
+ }
+ else
+ {
+ TYPELIB_DANGER_GET( &pTypeDescr, pType );
+ _destructArray( pValue, (typelib_ArrayTypeDescription *)pTypeDescr, release );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ }
+ break;
+ case typelib_TypeClass_UNION:
+ if (pTypeDescr)
+ {
+ _destructUnion( pValue, pTypeDescr, release );
+ }
+ else
+ {
+ TYPELIB_DANGER_GET( &pTypeDescr, pType );
+ _destructUnion( pValue, pTypeDescr, release );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ }
+ break;
+ case typelib_TypeClass_SEQUENCE:
+ {
+ idestructSequence(
+ *(uno_Sequence **)pValue, pType, pTypeDescr, release );
+ break;
+ }
+ case typelib_TypeClass_INTERFACE:
+ _release( *(void **)pValue, release );
+ break;
+ default:
+ break;
+ }
+}
+
+}
+
+#endif
diff --git a/cppu/source/uno/env_subst.cxx b/cppu/source/uno/env_subst.cxx
new file mode 100644
index 000000000000..4465a9e1815e
--- /dev/null
+++ b/cppu/source/uno/env_subst.cxx
@@ -0,0 +1,54 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "rtl/ustring.hxx"
+#include "uno/environment.h"
+#include "env_subst.hxx"
+
+
+void SAL_CALL uno_getEnvironment(uno_Environment ** ppEnv,
+ rtl_uString * pEnvDcp,
+ void * pContext)
+ SAL_THROW_EXTERN_C()
+{
+ rtl::OUString envDcp(pEnvDcp);
+
+ rtl::OString a_envName("UNO_ENV_SUBST:");
+ a_envName += rtl::OUStringToOString(envDcp, RTL_TEXTENCODING_ASCII_US);
+ char * c_value = getenv(a_envName.getStr());
+ if (c_value && rtl_str_getLength(c_value))
+ {
+ rtl::OString a_envDcp(a_envName.copy(a_envName.indexOf(':') + 1));
+
+ OSL_TRACE("UNO_ENV_SUBST \"%s\" -> \"%s\"", a_envDcp.getStr(), c_value);
+ rtl::OUString value(c_value, rtl_str_getLength(c_value), RTL_TEXTENCODING_ASCII_US);
+
+ envDcp = value;
+ }
+
+ uno_direct_getEnvironment(ppEnv, envDcp.pData, pContext);
+}
diff --git a/cppu/source/uno/env_subst.hxx b/cppu/source/uno/env_subst.hxx
new file mode 100644
index 000000000000..8ee8631ced84
--- /dev/null
+++ b/cppu/source/uno/env_subst.hxx
@@ -0,0 +1,41 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_env_substs_hxx
+#define INCLUDED_env_substs_hxx
+
+#include "rtl/ustring.hxx"
+#include "uno/environment.h"
+
+
+extern "C" void SAL_CALL uno_direct_getEnvironment(uno_Environment ** ppEnv,
+ rtl_uString * pEnvDcp,
+ void * pContext)
+ SAL_THROW_EXTERN_C();
+
+
+#endif
diff --git a/cppu/source/uno/eq.hxx b/cppu/source/uno/eq.hxx
new file mode 100644
index 000000000000..45bc0e79cfaa
--- /dev/null
+++ b/cppu/source/uno/eq.hxx
@@ -0,0 +1,668 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef EQ_HXX
+#define EQ_HXX
+
+#include <math.h>
+#include <rtl/memory.h>
+
+#include "prim.hxx"
+#include "destr.hxx"
+
+
+namespace cppu
+{
+
+//##################################################################################################
+//#### equality ####################################################################################
+//##################################################################################################
+
+//--------------------------------------------------------------------------------------------------
+inline sal_Bool _equalObject(
+ void * pI1, void * pI2,
+ uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release )
+ SAL_THROW( () )
+{
+ if (pI1 == pI2)
+ return sal_True;
+ if ((0 == pI1) || (0 == pI2))
+ return sal_False;
+ sal_Bool bRet = sal_False;
+
+ typelib_TypeDescriptionReference * type_XInterface =
+ * typelib_static_type_getByTypeClass( typelib_TypeClass_INTERFACE );
+ if (0 == queryInterface)
+ queryInterface = binuno_queryInterface;
+ pI1 = (*queryInterface)( pI1, type_XInterface );
+ if (0 != pI1)
+ {
+ pI2 = (*queryInterface)( pI2, type_XInterface );
+ if (0 != pI2)
+ {
+ bRet = (pI1 == pI2);
+ _release( pI2, release );
+ }
+ _release( pI1, release );
+ }
+ return bRet;
+}
+
+//==================================================================================================
+sal_Bool equalStruct(
+ void * pDest, void *pSource,
+ typelib_CompoundTypeDescription * pTypeDescr,
+ uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release )
+ SAL_THROW( () );
+//--------------------------------------------------------------------------------------------------
+inline sal_Bool _equalStruct(
+ void * pDest, void *pSource,
+ typelib_CompoundTypeDescription * pTypeDescr,
+ uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release )
+ SAL_THROW( () )
+{
+ if (pTypeDescr->pBaseTypeDescription &&
+ !equalStruct( pDest, pSource, pTypeDescr->pBaseTypeDescription, queryInterface, release ))
+ {
+ return sal_False;
+ }
+
+ typelib_TypeDescriptionReference ** ppTypeRefs = pTypeDescr->ppTypeRefs;
+ sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets;
+ sal_Int32 nDescr = pTypeDescr->nMembers;
+
+ while (nDescr--)
+ {
+ sal_Int32 nOffset = pMemberOffsets[nDescr];
+ if (! ::uno_type_equalData( (char *)pDest + nOffset,
+ ppTypeRefs[nDescr],
+ (char *)pSource + nOffset,
+ ppTypeRefs[nDescr],
+ queryInterface, release ))
+ {
+ return sal_False;
+ }
+ }
+ return sal_True;
+}
+//==================================================================================================
+sal_Bool equalSequence(
+ uno_Sequence * pDest, uno_Sequence * pSource,
+ typelib_TypeDescriptionReference * pElementType,
+ uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release )
+ SAL_THROW( () );
+//--------------------------------------------------------------------------------------------------
+inline sal_Bool _equalSequence(
+ uno_Sequence * pDest, uno_Sequence * pSource,
+ typelib_TypeDescriptionReference * pElementType,
+ uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release )
+ SAL_THROW( () )
+{
+ if (pDest == pSource)
+ return sal_True;
+ sal_Int32 nElements = pDest->nElements;
+ if (nElements != pSource->nElements)
+ return sal_False;
+ if (! nElements)
+ return sal_True;
+
+ void * pDestElements = pDest->elements;
+ void * pSourceElements = pSource->elements;
+
+ switch (pElementType->eTypeClass)
+ {
+ case typelib_TypeClass_CHAR:
+ return (0 == ::rtl_compareMemory( pDestElements, pSourceElements, sizeof(sal_Unicode) * nElements ));
+ case typelib_TypeClass_BOOLEAN:
+ {
+ for ( sal_Int32 nPos = nElements; nPos--; )
+ {
+ if ((((sal_Bool *)pDestElements)[nPos] != sal_False) !=
+ (((sal_Bool *)pSourceElements)[nPos] != sal_False))
+ {
+ return sal_False;
+ }
+ }
+ return sal_True;
+ }
+ case typelib_TypeClass_BYTE:
+ return (0 == ::rtl_compareMemory( pDestElements, pSourceElements, sizeof(sal_Int8) * nElements ));
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ return (0 == ::rtl_compareMemory( pDestElements, pSourceElements, sizeof(sal_Int16) * nElements ));
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ return (0 == ::rtl_compareMemory( pDestElements, pSourceElements, sizeof(sal_Int32) * nElements ));
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ return (0 == ::rtl_compareMemory( pDestElements, pSourceElements, sizeof(sal_Int64) * nElements ));
+ case typelib_TypeClass_FLOAT:
+ {
+ for ( sal_Int32 nPos = nElements; nPos--; )
+ {
+ if (((float *)pDestElements)[nPos] != ((float *)pSourceElements)[nPos])
+ return sal_False;
+ }
+ return sal_True;
+ }
+ case typelib_TypeClass_DOUBLE:
+ {
+ for ( sal_Int32 nPos = nElements; nPos--; )
+ {
+ if (((double *)pDestElements)[nPos] != ((double *)pSourceElements)[nPos])
+ return sal_False;
+ }
+ return sal_True;
+ }
+ case typelib_TypeClass_STRING:
+ {
+ for ( sal_Int32 nPos = nElements; nPos--; )
+ {
+ if (! ((::rtl::OUString *)pDestElements +nPos)->equals( ((const ::rtl::OUString *)pSourceElements)[nPos] ))
+ return sal_False;
+ }
+ return sal_True;
+ }
+ case typelib_TypeClass_TYPE:
+ {
+ for ( sal_Int32 nPos = nElements; nPos--; )
+ {
+ if (! _type_equals( ((typelib_TypeDescriptionReference **)pDestElements)[nPos],
+ ((typelib_TypeDescriptionReference **)pSourceElements)[nPos] ))
+ {
+ return sal_False;
+ }
+ }
+ return sal_True;
+ }
+ case typelib_TypeClass_ANY:
+ {
+ for ( sal_Int32 nPos = nElements; nPos--; )
+ {
+ uno_Any * pDest2 = (uno_Any *)pDestElements + nPos;
+ uno_Any * pSource2 = (uno_Any *)pSourceElements + nPos;
+ if (! ::uno_type_equalData( pDest2->pData, pDest2->pType,
+ pSource2->pData, pSource2->pType,
+ queryInterface, release ))
+ {
+ return sal_False;
+ }
+ }
+ return sal_True;
+ }
+ case typelib_TypeClass_ENUM:
+ return (0 == ::rtl_compareMemory( pDestElements, pSourceElements, sizeof(sal_Int32) * nElements ));
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ typelib_TypeDescription * pElementTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
+ sal_Int32 nElementSize = pElementTypeDescr->nSize;
+ for ( sal_Int32 nPos = nElements; nPos--; )
+ {
+ if (! _equalStruct( (char *)pDestElements + (nPos * nElementSize),
+ (char *)pSourceElements + (nPos * nElementSize),
+ (typelib_CompoundTypeDescription *)pElementTypeDescr,
+ queryInterface, release ))
+ {
+ TYPELIB_DANGER_RELEASE( pElementTypeDescr );
+ return sal_False;
+ }
+ }
+ TYPELIB_DANGER_RELEASE( pElementTypeDescr );
+ return sal_True;
+ }
+ case typelib_TypeClass_UNION:
+ {
+ typelib_TypeDescription * pElementTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
+ sal_Int32 nElementSize = pElementTypeDescr->nSize;
+ sal_Int32 nValueOffset = ((typelib_UnionTypeDescription *)pElementTypeDescr)->nValueOffset;
+ for ( sal_Int32 nPos = nElements; nPos--; )
+ {
+ char * pDest2 = (char *)pDestElements + (nPos * nElementSize);
+ char * pSource2 = (char *)pSourceElements + (nPos * nElementSize);
+ typelib_TypeDescriptionReference * pSetType = _unionGetSetType(
+ pDest2, pElementTypeDescr );
+ sal_Bool bRet = ::uno_type_equalData(
+ pDest2 + nValueOffset, pSetType,
+ pSource2 + nValueOffset, pSetType,
+ queryInterface, release );
+ ::typelib_typedescriptionreference_release( pSetType );
+ if (! bRet)
+ {
+ TYPELIB_DANGER_RELEASE( pElementTypeDescr );
+ return sal_False;
+ }
+ }
+ TYPELIB_DANGER_RELEASE( pElementTypeDescr );
+ return sal_True;
+ }
+ case typelib_TypeClass_SEQUENCE: // sequence of sequence
+ {
+ typelib_TypeDescription * pElementTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
+ typelib_TypeDescriptionReference * pSeqElementType =
+ ((typelib_IndirectTypeDescription *)pElementTypeDescr)->pType;
+ for ( sal_Int32 nPos = nElements; nPos--; )
+ {
+ if (! equalSequence( ((uno_Sequence **)pDestElements)[nPos],
+ ((uno_Sequence **)pSourceElements)[nPos],
+ pSeqElementType, queryInterface, release ))
+ {
+ TYPELIB_DANGER_RELEASE( pElementTypeDescr );
+ return sal_False;
+ }
+ }
+ TYPELIB_DANGER_RELEASE( pElementTypeDescr );
+ return sal_True;
+ }
+ case typelib_TypeClass_INTERFACE:
+ {
+ for ( sal_Int32 nPos = nElements; nPos--; )
+ {
+ if (! _equalObject( ((void **)pDestElements)[nPos], ((void **)pSourceElements)[nPos],
+ queryInterface, release ))
+ {
+ return sal_False;
+ }
+ }
+ return sal_True;
+ }
+ default:
+ OSL_ASSERT(false);
+ return sal_False;
+ }
+}
+//--------------------------------------------------------------------------------------------------
+inline sal_Bool _equalData(
+ void * pDest,
+ typelib_TypeDescriptionReference * pDestType, typelib_TypeDescription * pDestTypeDescr,
+ void * pSource,
+ typelib_TypeDescriptionReference * pSourceType, typelib_TypeDescription * pSourceTypeDescr,
+ uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release )
+ SAL_THROW( () )
+{
+ typelib_TypeClass eSourceTypeClass, eDestTypeClass;
+ while (typelib_TypeClass_ANY == (eDestTypeClass = pDestType->eTypeClass))
+ {
+ pDestTypeDescr = 0;
+ pDestType = ((uno_Any *)pDest)->pType;
+ pDest = ((uno_Any *)pDest)->pData;
+ }
+ while (typelib_TypeClass_ANY == (eSourceTypeClass = pSourceType->eTypeClass))
+ {
+ pSourceTypeDescr = 0;
+ pSourceType = ((uno_Any *)pSource)->pType;
+ pSource = ((uno_Any *)pSource)->pData;
+ }
+
+ switch (eDestTypeClass)
+ {
+ case typelib_TypeClass_VOID:
+ return eSourceTypeClass == typelib_TypeClass_VOID;
+ case typelib_TypeClass_CHAR:
+ return eSourceTypeClass == typelib_TypeClass_CHAR
+ && *(sal_Unicode *)pDest == *(sal_Unicode *)pSource;
+ case typelib_TypeClass_BOOLEAN:
+ return eSourceTypeClass == typelib_TypeClass_BOOLEAN
+ && ((*(sal_Bool *)pDest != sal_False)
+ == (*(sal_Bool *)pSource != sal_False));
+ case typelib_TypeClass_BYTE:
+ switch (eSourceTypeClass)
+ {
+ case typelib_TypeClass_BYTE:
+ return (*(sal_Int8 *)pDest == *(sal_Int8 *)pSource);
+ case typelib_TypeClass_SHORT:
+ return ((sal_Int16)*(sal_Int8 *)pDest == *(sal_Int16 *)pSource);
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ return ((sal_Int32)*(sal_Int8 *)pDest == (sal_Int32)*(sal_uInt16 *)pSource);
+ case typelib_TypeClass_LONG:
+ return ((sal_Int32)*(sal_Int8 *)pDest == *(sal_Int32 *)pSource);
+ case typelib_TypeClass_UNSIGNED_LONG:
+ return ((sal_Int64)*(sal_Int8 *)pDest == (sal_Int64)*(sal_uInt32 *)pSource);
+ case typelib_TypeClass_HYPER:
+ return ((sal_Int64)*(sal_Int8 *)pDest == *(sal_Int64 *)pSource);
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ return (*(sal_Int8 *)pDest >= 0 &&
+ (sal_Int64)*(sal_Int8 *)pDest == *(sal_Int64 *)pSource); // same size
+ case typelib_TypeClass_FLOAT:
+ return ((float)*(sal_Int8 *)pDest == *(float *)pSource);
+ case typelib_TypeClass_DOUBLE:
+ return ((double)*(sal_Int8 *)pDest == *(double *)pSource);
+ default:
+ return sal_False;
+ }
+ case typelib_TypeClass_SHORT:
+ switch (eSourceTypeClass)
+ {
+ case typelib_TypeClass_BYTE:
+ return (*(sal_Int16 *)pDest == (sal_Int16)*(sal_Int8 *)pSource);
+ case typelib_TypeClass_SHORT:
+ return (*(sal_Int16 *)pDest == *(sal_Int16 *)pSource);
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ return ((sal_Int32)*(sal_Int16 *)pDest == (sal_Int32)*(sal_uInt16 *)pSource);
+ case typelib_TypeClass_LONG:
+ return ((sal_Int32)*(sal_Int16 *)pDest == *(sal_Int32 *)pSource);
+ case typelib_TypeClass_UNSIGNED_LONG:
+ return ((sal_Int64)*(sal_Int16 *)pDest == (sal_Int64)*(sal_uInt32 *)pSource);
+ case typelib_TypeClass_HYPER:
+ return ((sal_Int64)*(sal_Int16 *)pDest == *(sal_Int64 *)pSource);
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ return (*(sal_Int16 *)pDest >= 0 &&
+ (sal_Int64)*(sal_Int16 *)pDest == *(sal_Int64 *)pSource); // same size
+ case typelib_TypeClass_FLOAT:
+ return ((float)*(sal_Int16 *)pDest == *(float *)pSource);
+ case typelib_TypeClass_DOUBLE:
+ return ((double)*(sal_Int16 *)pDest == *(double *)pSource);
+ default:
+ return sal_False;
+ }
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ switch (eSourceTypeClass)
+ {
+ case typelib_TypeClass_BYTE:
+ return ((sal_Int32)*(sal_uInt16 *)pDest == (sal_Int32)*(sal_Int8 *)pSource);
+ case typelib_TypeClass_SHORT:
+ return ((sal_Int32)*(sal_uInt16 *)pDest == (sal_Int32)*(sal_Int16 *)pSource);
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ return (*(sal_uInt16 *)pDest == *(sal_uInt16 *)pSource);
+ case typelib_TypeClass_LONG:
+ return ((sal_Int32)*(sal_uInt16 *)pDest == *(sal_Int32 *)pSource);
+ case typelib_TypeClass_UNSIGNED_LONG:
+ return ((sal_uInt32)*(sal_uInt16 *)pDest == *(sal_uInt32 *)pSource);
+ case typelib_TypeClass_HYPER:
+ return ((sal_Int64)*(sal_uInt16 *)pDest == *(sal_Int64 *)pSource);
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ return ((sal_uInt64)*(sal_uInt16 *)pDest == *(sal_uInt64 *)pSource);
+ case typelib_TypeClass_FLOAT:
+ return ((float)*(sal_uInt16 *)pDest == *(float *)pSource);
+ case typelib_TypeClass_DOUBLE:
+ return ((double)*(sal_uInt16 *)pDest == *(double *)pSource);
+ default:
+ return sal_False;
+ }
+ case typelib_TypeClass_LONG:
+ switch (eSourceTypeClass)
+ {
+ case typelib_TypeClass_BYTE:
+ return (*(sal_Int32 *)pDest == (sal_Int32)*(sal_Int8 *)pSource);
+ case typelib_TypeClass_SHORT:
+ return (*(sal_Int32 *)pDest == (sal_Int32)*(sal_Int16 *)pSource);
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ return (*(sal_Int32 *)pDest == (sal_Int32)*(sal_uInt16 *)pSource);
+ case typelib_TypeClass_LONG:
+ return (*(sal_Int32 *)pDest == *(sal_Int32 *)pSource);
+ case typelib_TypeClass_UNSIGNED_LONG:
+ return ((sal_Int64)*(sal_Int32 *)pDest == (sal_Int64)*(sal_uInt32 *)pSource);
+ case typelib_TypeClass_HYPER:
+ return ((sal_Int64)*(sal_Int32 *)pDest == *(sal_Int64 *)pSource);
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ return (*(sal_Int32 *)pDest >= 0 &&
+ (sal_Int64)*(sal_Int32 *)pDest == *(sal_Int64 *)pSource); // same size
+ case typelib_TypeClass_FLOAT:
+ return ((float)*(sal_Int32 *)pDest == *(float *)pSource);
+ case typelib_TypeClass_DOUBLE:
+ return ((double)*(sal_Int32 *)pDest == *(double *)pSource);
+ default:
+ return sal_False;
+ }
+ case typelib_TypeClass_UNSIGNED_LONG:
+ switch (eSourceTypeClass)
+ {
+ case typelib_TypeClass_BYTE:
+ return ((sal_Int64)*(sal_uInt32 *)pDest == (sal_Int64)*(sal_Int8 *)pSource);
+ case typelib_TypeClass_SHORT:
+ return ((sal_Int64)*(sal_uInt32 *)pDest == (sal_Int64)*(sal_Int16 *)pSource);
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ return (*(sal_uInt32 *)pDest == (sal_uInt32)*(sal_uInt16 *)pSource);
+ case typelib_TypeClass_LONG:
+ return ((sal_Int64)*(sal_uInt32 *)pDest == (sal_Int64)*(sal_Int32 *)pSource);
+ case typelib_TypeClass_UNSIGNED_LONG:
+ return (*(sal_uInt32 *)pDest == *(sal_uInt32 *)pSource);
+ case typelib_TypeClass_HYPER:
+ return ((sal_Int64)*(sal_uInt32 *)pDest == *(sal_Int64 *)pSource);
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ return ((sal_uInt64)*(sal_uInt32 *)pDest == *(sal_uInt64 *)pSource);
+ case typelib_TypeClass_FLOAT:
+ return ((float)*(sal_uInt32 *)pDest == *(float *)pSource);
+ case typelib_TypeClass_DOUBLE:
+ return ((double)*(sal_uInt32 *)pDest == *(double *)pSource);
+ default:
+ return sal_False;
+ }
+ case typelib_TypeClass_HYPER:
+ switch (eSourceTypeClass)
+ {
+ case typelib_TypeClass_BYTE:
+ return (*(sal_Int64 *)pDest == (sal_Int64)*(sal_Int8 *)pSource);
+ case typelib_TypeClass_SHORT:
+ return (*(sal_Int64 *)pDest == (sal_Int64)*(sal_Int16 *)pSource);
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ return (*(sal_Int64 *)pDest == (sal_Int64)*(sal_uInt16 *)pSource);
+ case typelib_TypeClass_LONG:
+ return (*(sal_Int64 *)pDest == (sal_Int64)*(sal_Int32 *)pSource);
+ case typelib_TypeClass_UNSIGNED_LONG:
+ return (*(sal_Int64 *)pDest == (sal_Int64)*(sal_uInt32 *)pSource);
+ case typelib_TypeClass_HYPER:
+ return (*(sal_Int64 *)pDest == *(sal_Int64 *)pSource);
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ return (*(sal_Int64 *)pDest >= 0 &&
+ *(sal_Int64 *)pDest == *(sal_Int64 *)pSource); // same size
+ case typelib_TypeClass_FLOAT:
+ return ((float)*(sal_Int64 *)pDest == *(float *)pSource);
+ case typelib_TypeClass_DOUBLE:
+ return ((double)*(sal_Int64 *)pDest == *(double *)pSource);
+ default:
+ return sal_False;
+ }
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ switch (eSourceTypeClass)
+ {
+ case typelib_TypeClass_BYTE:
+ return (*(sal_Int8 *)pSource >= 0 &&
+ *(sal_uInt64 *)pDest == (sal_uInt64)*(sal_Int8 *)pSource);
+ case typelib_TypeClass_SHORT:
+ return (*(sal_Int16 *)pSource >= 0 &&
+ *(sal_uInt64 *)pDest == (sal_uInt64)*(sal_Int16 *)pSource);
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ return (*(sal_uInt64 *)pDest == (sal_uInt64)*(sal_uInt16 *)pSource);
+ case typelib_TypeClass_LONG:
+ return (*(sal_Int32 *)pSource >= 0 &&
+ *(sal_uInt64 *)pDest == (sal_uInt64)*(sal_Int32 *)pSource);
+ case typelib_TypeClass_UNSIGNED_LONG:
+ return (*(sal_uInt64 *)pDest == (sal_uInt64)*(sal_uInt32 *)pSource);
+ case typelib_TypeClass_HYPER:
+ return (*(sal_Int64 *)pSource >= 0 &&
+ *(sal_uInt64 *)pDest == (sal_uInt64)*(sal_Int64 *)pSource);
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ return (*(sal_uInt64 *)pDest == *(sal_uInt64 *)pSource);
+ case typelib_TypeClass_FLOAT:
+ if (::floor( *(float *)pSource ) != *(float *)pSource || *(float *)pSource < 0)
+ return sal_False;
+ return (*(sal_uInt64 *)pDest == (sal_uInt64)*(float *)pSource);
+ case typelib_TypeClass_DOUBLE:
+ if (::floor( *(double *)pSource ) != *(double *)pSource || *(double *)pSource < 0)
+ return sal_False;
+ return (*(sal_uInt64 *)pDest == (sal_uInt64)*(double *)pSource);
+ default:
+ return sal_False;
+ }
+ case typelib_TypeClass_FLOAT:
+ switch (eSourceTypeClass)
+ {
+ case typelib_TypeClass_BYTE:
+ return (*(float *)pDest == (float)*(sal_Int8 *)pSource);
+ case typelib_TypeClass_SHORT:
+ return (*(float *)pDest == (float)*(sal_Int16 *)pSource);
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ return (*(float *)pDest == (float)*(sal_uInt16 *)pSource);
+ case typelib_TypeClass_LONG:
+ return (*(float *)pDest == (float)*(sal_Int32 *)pSource);
+ case typelib_TypeClass_UNSIGNED_LONG:
+ return (*(float *)pDest == (float)*(sal_uInt32 *)pSource);
+ case typelib_TypeClass_HYPER:
+ return (*(float *)pDest == (float)*(sal_Int64 *)pSource);
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ if (::floor( *(float *)pDest ) != *(float *)pDest || *(float *)pDest < 0)
+ return sal_False;
+ return ((sal_uInt64)*(float *)pDest == *(sal_uInt64 *)pSource);
+ case typelib_TypeClass_FLOAT:
+ return (*(float *)pDest == *(float *)pSource);
+ case typelib_TypeClass_DOUBLE:
+ return ((double)*(float *)pDest == *(double *)pSource);
+ default:
+ return sal_False;
+ }
+ case typelib_TypeClass_DOUBLE:
+ switch (eSourceTypeClass)
+ {
+ case typelib_TypeClass_BYTE:
+ return (*(double *)pDest == (double)*(sal_Int8 *)pSource);
+ case typelib_TypeClass_SHORT:
+ return (*(double *)pDest == (double)*(sal_Int16 *)pSource);
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ return (*(double *)pDest == (double)*(sal_uInt16 *)pSource);
+ case typelib_TypeClass_LONG:
+ return (*(double *)pDest == (double)*(sal_Int32 *)pSource);
+ case typelib_TypeClass_UNSIGNED_LONG:
+ return (*(double *)pDest == (double)*(sal_uInt32 *)pSource);
+ case typelib_TypeClass_HYPER:
+ return (*(double *)pDest == (double)*(sal_Int64 *)pSource);
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ if (::floor( *(double *)pDest ) != *(double *)pDest || *(double *)pDest < 0)
+ return sal_False;
+ return ((sal_uInt64)*(double *)pDest == *(sal_uInt64 *)pSource);
+ case typelib_TypeClass_FLOAT:
+ return (*(double *)pDest == (double)*(float *)pSource);
+ case typelib_TypeClass_DOUBLE:
+ return (*(double *)pDest == *(double *)pSource);
+ default:
+ return sal_False;
+ }
+ case typelib_TypeClass_STRING:
+ return eSourceTypeClass == typelib_TypeClass_STRING
+ && ((::rtl::OUString *)pDest)->equals(
+ *(::rtl::OUString const *)pSource );
+ case typelib_TypeClass_TYPE:
+ return eSourceTypeClass == typelib_TypeClass_TYPE
+ && _type_equals(
+ *(typelib_TypeDescriptionReference **)pDest,
+ *(typelib_TypeDescriptionReference **)pSource );
+ case typelib_TypeClass_ENUM:
+ return (_type_equals( pDestType, pSourceType ) &&
+ *(sal_Int32 *)pDest == *(sal_Int32 *)pSource);
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ if (! _type_equals( pDestType, pSourceType ))
+ return sal_False;
+ if (pDestTypeDescr)
+ {
+ return _equalStruct(
+ pDest, pSource,
+ (typelib_CompoundTypeDescription *)pDestTypeDescr,
+ queryInterface, release );
+ }
+ else
+ {
+ TYPELIB_DANGER_GET( &pDestTypeDescr, pDestType );
+ sal_Bool bRet = _equalStruct(
+ pDest, pSource,
+ (typelib_CompoundTypeDescription *)pDestTypeDescr,
+ queryInterface, release );
+ TYPELIB_DANGER_RELEASE( pDestTypeDescr );
+ return bRet;
+ }
+ case typelib_TypeClass_UNION:
+ if (_type_equals( pDestType, pSourceType ) &&
+ *(sal_Int64 *)pDest == *(sal_Int64 *)pSource) // same discriminant
+ {
+ sal_Bool bRet;
+ if (pDestTypeDescr)
+ {
+ typelib_TypeDescriptionReference * pSetType = _unionGetSetType(
+ pDest, pDestTypeDescr );
+ bRet = ::uno_type_equalData(
+ (char *)pDest + ((typelib_UnionTypeDescription *)pDestTypeDescr)->nValueOffset,
+ pSetType,
+ (char *)pSource + ((typelib_UnionTypeDescription *)pDestTypeDescr)->nValueOffset,
+ pSetType,
+ queryInterface, release );
+ typelib_typedescriptionreference_release( pSetType );
+ }
+ else
+ {
+ TYPELIB_DANGER_GET( &pDestTypeDescr, pDestType );
+ typelib_TypeDescriptionReference * pSetType = _unionGetSetType(
+ pDest, pDestTypeDescr );
+ bRet = ::uno_type_equalData(
+ (char *)pDest + ((typelib_UnionTypeDescription *)pDestTypeDescr)->nValueOffset,
+ pSetType,
+ (char *)pSource + ((typelib_UnionTypeDescription *)pDestTypeDescr)->nValueOffset,
+ pSetType,
+ queryInterface, release );
+ typelib_typedescriptionreference_release( pSetType );
+ TYPELIB_DANGER_RELEASE( pDestTypeDescr );
+ }
+ return bRet;
+ }
+ return sal_False;
+ case typelib_TypeClass_SEQUENCE:
+ if (_type_equals( pDestType, pSourceType ))
+ {
+ if (pDestTypeDescr)
+ {
+ return _equalSequence(
+ *(uno_Sequence **)pDest, *(uno_Sequence **)pSource,
+ ((typelib_IndirectTypeDescription *)pDestTypeDescr)->pType,
+ queryInterface, release );
+ }
+ else
+ {
+ TYPELIB_DANGER_GET( &pDestTypeDescr, pDestType );
+ sal_Bool bRet = _equalSequence(
+ *(uno_Sequence **)pDest, *(uno_Sequence **)pSource,
+ ((typelib_IndirectTypeDescription *)pDestTypeDescr)->pType,
+ queryInterface, release );
+ TYPELIB_DANGER_RELEASE( pDestTypeDescr );
+ return bRet;
+ }
+ }
+ return sal_False;
+ case typelib_TypeClass_INTERFACE:
+ if (typelib_TypeClass_INTERFACE == eSourceTypeClass)
+ return _equalObject( *(void **)pDest, *(void **)pSource, queryInterface, release );
+ break;
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ return sal_False;
+}
+
+}
+
+#endif
diff --git a/cppu/source/uno/lbenv.cxx b/cppu/source/uno/lbenv.cxx
new file mode 100644
index 000000000000..21d16c5b9148
--- /dev/null
+++ b/cppu/source/uno/lbenv.cxx
@@ -0,0 +1,1182 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_cppu.hxx"
+
+#include "cppu/EnvDcp.hxx"
+
+#include "sal/alloca.h"
+#include "osl/diagnose.h"
+#include "osl/interlck.h"
+#include "osl/mutex.hxx"
+#include "osl/module.h"
+#include "osl/process.h"
+#include "rtl/process.h"
+#include "rtl/unload.h"
+#include "rtl/string.hxx"
+#include "rtl/ustring.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/instance.hxx"
+#include "typelib/typedescription.h"
+#include "uno/dispatcher.h"
+#include "uno/environment.h"
+#include "uno/lbnames.h"
+#include "prim.hxx"
+#include "destr.hxx"
+#include "loadmodule.hxx"
+
+#include <hash_map>
+#include <vector>
+#include <stdio.h>
+
+
+using ::rtl::OUString;
+
+namespace
+{
+
+//------------------------------------------------------------------------------
+inline static bool td_equals( typelib_InterfaceTypeDescription * pTD1,
+ typelib_InterfaceTypeDescription * pTD2 )
+{
+ return (pTD1 == pTD2 ||
+ (((typelib_TypeDescription *)pTD1)->pTypeName->length ==
+ ((typelib_TypeDescription *)pTD2)->pTypeName->length &&
+ ::rtl_ustr_compare(
+ ((typelib_TypeDescription *) pTD1)->pTypeName->buffer,
+ ((typelib_TypeDescription *) pTD2)->pTypeName->buffer ) == 0));
+}
+
+struct ObjectEntry;
+struct uno_DefaultEnvironment;
+
+//------------------------------------------------------------------------------
+struct InterfaceEntry
+{
+ sal_Int32 refCount;
+ void * pInterface;
+ uno_freeProxyFunc fpFreeProxy;
+ typelib_InterfaceTypeDescription * pTypeDescr;
+};
+
+struct ObjectEntry
+{
+ OUString oid;
+ sal_Int32 nRef;
+ ::std::vector< InterfaceEntry > aInterfaces;
+ bool mixedObject;
+
+ inline ObjectEntry( const OUString & rOId_ );
+
+ inline void append(
+ uno_DefaultEnvironment * pEnv,
+ void * pInterface, typelib_InterfaceTypeDescription * pTypeDescr,
+ uno_freeProxyFunc fpFreeProxy );
+ inline InterfaceEntry * find(
+ typelib_InterfaceTypeDescription * pTypeDescr );
+ inline sal_Int32 find( void * iface_ptr, ::std::size_t pos );
+};
+
+//------------------------------------------------------------------------------
+struct FctPtrHash :
+ public ::std::unary_function< const void *, ::std::size_t >
+{
+ ::std::size_t operator () ( const void * pKey ) const
+ { return (::std::size_t) pKey; }
+};
+
+//------------------------------------------------------------------------------
+struct FctOUStringHash :
+ public ::std::unary_function< const OUString &, ::std::size_t >
+{
+ ::std::size_t operator () ( const OUString & rKey ) const
+ { return rKey.hashCode(); }
+};
+
+// mapping from environment name to environment
+typedef ::std::hash_map<
+ OUString, uno_Environment *, FctOUStringHash,
+ ::std::equal_to< OUString > > OUString2EnvironmentMap;
+
+// mapping from ptr to object entry
+typedef ::std::hash_map<
+ void *, ObjectEntry *, FctPtrHash,
+ ::std::equal_to< void * > > Ptr2ObjectMap;
+// mapping from oid to object entry
+typedef ::std::hash_map<
+ OUString, ObjectEntry *, FctOUStringHash,
+ ::std::equal_to< OUString > > OId2ObjectMap;
+
+
+//==============================================================================
+struct EnvironmentsData
+{
+ ::osl::Mutex mutex;
+ OUString2EnvironmentMap aName2EnvMap;
+
+ ~EnvironmentsData();
+
+ inline void getEnvironment(
+ uno_Environment ** ppEnv, const OUString & rEnvDcp, void * pContext );
+ inline void registerEnvironment( uno_Environment ** ppEnv );
+ inline void getRegisteredEnvironments(
+ uno_Environment *** pppEnvs, sal_Int32 * pnLen,
+ uno_memAlloc memAlloc, const OUString & rEnvDcp );
+};
+
+namespace
+{
+ struct theEnvironmentsData : public rtl::Static< EnvironmentsData, theEnvironmentsData > {};
+}
+
+//==============================================================================
+struct uno_DefaultEnvironment : public uno_ExtEnvironment
+{
+ sal_Int32 nRef;
+ sal_Int32 nWeakRef;
+
+ ::osl::Mutex mutex;
+ Ptr2ObjectMap aPtr2ObjectMap;
+ OId2ObjectMap aOId2ObjectMap;
+
+ uno_DefaultEnvironment(
+ const OUString & rEnvDcp_, void * pContext_ );
+ ~uno_DefaultEnvironment();
+};
+
+//______________________________________________________________________________
+inline ObjectEntry::ObjectEntry( OUString const & rOId_ )
+ : oid( rOId_ ),
+ nRef( 0 ),
+ mixedObject( false )
+{
+ aInterfaces.reserve( 2 );
+}
+
+//______________________________________________________________________________
+inline void ObjectEntry::append(
+ uno_DefaultEnvironment * pEnv,
+ void * pInterface, typelib_InterfaceTypeDescription * pTypeDescr,
+ uno_freeProxyFunc fpFreeProxy )
+{
+ InterfaceEntry aNewEntry;
+ if (! fpFreeProxy)
+ (*pEnv->acquireInterface)( pEnv, pInterface );
+ aNewEntry.refCount = 1;
+ aNewEntry.pInterface = pInterface;
+ aNewEntry.fpFreeProxy = fpFreeProxy;
+ typelib_typedescription_acquire( (typelib_TypeDescription *) pTypeDescr );
+ aNewEntry.pTypeDescr = pTypeDescr;
+
+ ::std::pair< Ptr2ObjectMap::iterator, bool > insertion(
+ pEnv->aPtr2ObjectMap.insert( Ptr2ObjectMap::value_type(
+ pInterface, this ) ) );
+ OSL_ASSERT( insertion.second ||
+ (find( pInterface, 0 ) >= 0 &&
+ // points to the same object entry:
+ insertion.first->second == this) );
+ aInterfaces.push_back( aNewEntry );
+}
+
+//______________________________________________________________________________
+inline InterfaceEntry * ObjectEntry::find(
+ typelib_InterfaceTypeDescription * pTypeDescr_ )
+{
+ OSL_ASSERT( ! aInterfaces.empty() );
+ if (aInterfaces.empty())
+ return 0;
+
+ // shortcut common case:
+ OUString const & type_name =
+ OUString::unacquired(
+ &((typelib_TypeDescription *) pTypeDescr_)->pTypeName );
+ if (type_name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("com.sun.star.uno.XInterface") ))
+ {
+ return &aInterfaces[ 0 ];
+ }
+
+ ::std::size_t nSize = aInterfaces.size();
+ for ( ::std::size_t nPos = 0; nPos < nSize; ++nPos )
+ {
+ typelib_InterfaceTypeDescription * pITD =
+ aInterfaces[ nPos ].pTypeDescr;
+ while (pITD)
+ {
+ if (td_equals( pITD, pTypeDescr_ ))
+ return &aInterfaces[ nPos ];
+ pITD = pITD->pBaseTypeDescription;
+ }
+ }
+ return 0;
+}
+
+//______________________________________________________________________________
+inline sal_Int32 ObjectEntry::find(
+ void * iface_ptr, ::std::size_t pos )
+{
+ ::std::size_t size = aInterfaces.size();
+ for ( ; pos < size; ++pos )
+ {
+ if (aInterfaces[ pos ].pInterface == iface_ptr)
+ return pos;
+ }
+ return -1;
+}
+
+extern "C"
+{
+
+//------------------------------------------------------------------------------
+static void SAL_CALL defenv_registerInterface(
+ uno_ExtEnvironment * pEnv, void ** ppInterface,
+ rtl_uString * pOId, typelib_InterfaceTypeDescription * pTypeDescr )
+{
+ OSL_ENSURE( pEnv && ppInterface && pOId && pTypeDescr, "### null ptr!" );
+ OUString const & rOId = OUString::unacquired( &pOId );
+
+ uno_DefaultEnvironment * that =
+ static_cast< uno_DefaultEnvironment * >( pEnv );
+ ::osl::ClearableMutexGuard guard( that->mutex );
+
+ // try to insert dummy 0:
+ std::pair<OId2ObjectMap::iterator, bool> const insertion(
+ that->aOId2ObjectMap.insert( OId2ObjectMap::value_type( rOId, 0 ) ) );
+ if (insertion.second)
+ {
+ ObjectEntry * pOEntry = new ObjectEntry( rOId );
+ insertion.first->second = pOEntry;
+ ++pOEntry->nRef; // another register call on object
+ pOEntry->append( that, *ppInterface, pTypeDescr, 0 );
+ }
+ else // object entry exists
+ {
+ ObjectEntry * pOEntry = insertion.first->second;
+ ++pOEntry->nRef; // another register call on object
+ InterfaceEntry * pIEntry = pOEntry->find( pTypeDescr );
+
+ if (pIEntry) // type entry exists
+ {
+ ++pIEntry->refCount;
+ if (pIEntry->pInterface != *ppInterface)
+ {
+ void * pInterface = pIEntry->pInterface;
+ (*pEnv->acquireInterface)( pEnv, pInterface );
+ guard.clear();
+ (*pEnv->releaseInterface)( pEnv, *ppInterface );
+ *ppInterface = pInterface;
+ }
+ }
+ else
+ {
+ pOEntry->append( that, *ppInterface, pTypeDescr, 0 );
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+static void SAL_CALL defenv_registerProxyInterface(
+ uno_ExtEnvironment * pEnv, void ** ppInterface, uno_freeProxyFunc freeProxy,
+ rtl_uString * pOId, typelib_InterfaceTypeDescription * pTypeDescr )
+{
+ OSL_ENSURE( pEnv && ppInterface && pOId && pTypeDescr && freeProxy,
+ "### null ptr!" );
+ OUString const & rOId = OUString::unacquired( &pOId );
+
+ uno_DefaultEnvironment * that =
+ static_cast< uno_DefaultEnvironment * >( pEnv );
+ ::osl::ClearableMutexGuard guard( that->mutex );
+
+ // try to insert dummy 0:
+ std::pair<OId2ObjectMap::iterator, bool> const insertion(
+ that->aOId2ObjectMap.insert( OId2ObjectMap::value_type( rOId, 0 ) ) );
+ if (insertion.second)
+ {
+ ObjectEntry * pOEntry = new ObjectEntry( rOId );
+ insertion.first->second = pOEntry;
+ ++pOEntry->nRef; // another register call on object
+ pOEntry->append( that, *ppInterface, pTypeDescr, freeProxy );
+ }
+ else // object entry exists
+ {
+ ObjectEntry * pOEntry = insertion.first->second;
+
+ // first registration was an original, then registerProxyInterface():
+ pOEntry->mixedObject |=
+ (!pOEntry->aInterfaces.empty() &&
+ pOEntry->aInterfaces[ 0 ].fpFreeProxy == 0);
+
+ ++pOEntry->nRef; // another register call on object
+ InterfaceEntry * pIEntry = pOEntry->find( pTypeDescr );
+
+ if (pIEntry) // type entry exists
+ {
+ if (pIEntry->pInterface == *ppInterface)
+ {
+ ++pIEntry->refCount;
+ }
+ else
+ {
+ void * pInterface = pIEntry->pInterface;
+ (*pEnv->acquireInterface)( pEnv, pInterface );
+ --pOEntry->nRef; // manual revoke of proxy to be freed
+ guard.clear();
+ (*freeProxy)( pEnv, *ppInterface );
+ *ppInterface = pInterface;
+ }
+ }
+ else
+ {
+ pOEntry->append( that, *ppInterface, pTypeDescr, freeProxy );
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+static void SAL_CALL s_stub_defenv_revokeInterface(va_list * pParam)
+{
+ uno_ExtEnvironment * pEnv = va_arg(*pParam, uno_ExtEnvironment *);
+ void * pInterface = va_arg(*pParam, void *);
+
+ OSL_ENSURE( pEnv && pInterface, "### null ptr!" );
+ uno_DefaultEnvironment * that =
+ static_cast< uno_DefaultEnvironment * >( pEnv );
+ ::osl::ClearableMutexGuard guard( that->mutex );
+
+ Ptr2ObjectMap::const_iterator const iFind(
+ that->aPtr2ObjectMap.find( pInterface ) );
+ OSL_ASSERT( iFind != that->aPtr2ObjectMap.end() );
+ ObjectEntry * pOEntry = iFind->second;
+ if (! --pOEntry->nRef)
+ {
+ // cleanup maps
+ that->aOId2ObjectMap.erase( pOEntry->oid );
+ sal_Int32 nPos;
+ for ( nPos = pOEntry->aInterfaces.size(); nPos--; )
+ {
+ that->aPtr2ObjectMap.erase( pOEntry->aInterfaces[nPos].pInterface );
+ }
+
+ // the last proxy interface of the environment might kill this
+ // environment, because of releasing its language binding!!!
+ guard.clear();
+
+ // release interfaces
+ for ( nPos = pOEntry->aInterfaces.size(); nPos--; )
+ {
+ InterfaceEntry const & rEntry = pOEntry->aInterfaces[nPos];
+ typelib_typedescription_release(
+ (typelib_TypeDescription *) rEntry.pTypeDescr );
+ if (rEntry.fpFreeProxy) // is proxy or used interface?
+ {
+ (*rEntry.fpFreeProxy)( pEnv, rEntry.pInterface );
+ }
+ else
+ {
+ (*pEnv->releaseInterface)( pEnv, rEntry.pInterface );
+ }
+ }
+
+ delete pOEntry;
+ }
+ else if (pOEntry->mixedObject)
+ {
+ OSL_ASSERT( !pOEntry->aInterfaces.empty() &&
+ pOEntry->aInterfaces[ 0 ].fpFreeProxy == 0 );
+
+ sal_Int32 index = pOEntry->find( pInterface, 1 );
+ OSL_ASSERT( index > 0 );
+ if (index > 0)
+ {
+ InterfaceEntry & entry = pOEntry->aInterfaces[ index ];
+ OSL_ASSERT( entry.pInterface == pInterface );
+ if (entry.fpFreeProxy != 0)
+ {
+ --entry.refCount;
+ if (entry.refCount == 0)
+ {
+ uno_freeProxyFunc fpFreeProxy = entry.fpFreeProxy;
+ typelib_TypeDescription * pTypeDescr =
+ reinterpret_cast< typelib_TypeDescription * >(
+ entry.pTypeDescr );
+
+ pOEntry->aInterfaces.erase(
+ pOEntry->aInterfaces.begin() + index );
+ if (pOEntry->find( pInterface, index ) < 0)
+ {
+ // proxy ptr not registered for another interface:
+ // remove from ptr map
+#if OSL_DEBUG_LEVEL > 0
+ ::std::size_t erased =
+#endif
+ that->aPtr2ObjectMap.erase( pInterface );
+ OSL_ASSERT( erased == 1 );
+ }
+
+ guard.clear();
+
+ typelib_typedescription_release( pTypeDescr );
+ (*fpFreeProxy)( pEnv, pInterface );
+ }
+ }
+ }
+ }
+}
+
+static void SAL_CALL defenv_revokeInterface(uno_ExtEnvironment * pEnv, void * pInterface)
+{
+ uno_Environment_invoke(&pEnv->aBase, s_stub_defenv_revokeInterface, pEnv, pInterface);
+}
+
+//------------------------------------------------------------------------------
+static void SAL_CALL defenv_getObjectIdentifier(
+ uno_ExtEnvironment * pEnv, rtl_uString ** ppOId, void * pInterface )
+{
+ OSL_ENSURE( pEnv && ppOId && pInterface, "### null ptr!" );
+ if (*ppOId)
+ {
+ ::rtl_uString_release( *ppOId );
+ *ppOId = 0;
+ }
+
+ uno_DefaultEnvironment * that =
+ static_cast< uno_DefaultEnvironment * >( pEnv );
+ ::osl::ClearableMutexGuard guard( that->mutex );
+
+ Ptr2ObjectMap::const_iterator const iFind(
+ that->aPtr2ObjectMap.find( pInterface ) );
+ if (iFind == that->aPtr2ObjectMap.end())
+ {
+ guard.clear();
+ (*pEnv->computeObjectIdentifier)( pEnv, ppOId, pInterface );
+ }
+ else
+ {
+ rtl_uString * hstr = iFind->second->oid.pData;
+ rtl_uString_acquire( hstr );
+ *ppOId = hstr;
+ }
+}
+
+//------------------------------------------------------------------------------
+static void SAL_CALL defenv_getRegisteredInterface(
+ uno_ExtEnvironment * pEnv, void ** ppInterface,
+ rtl_uString * pOId, typelib_InterfaceTypeDescription * pTypeDescr )
+{
+ OSL_ENSURE( pEnv && ppInterface && pOId && pTypeDescr, "### null ptr!" );
+ if (*ppInterface)
+ {
+ (*pEnv->releaseInterface)( pEnv, *ppInterface );
+ *ppInterface = 0;
+ }
+
+ OUString const & rOId = OUString::unacquired( &pOId );
+ uno_DefaultEnvironment * that =
+ static_cast< uno_DefaultEnvironment * >( pEnv );
+ ::osl::MutexGuard guard( that->mutex );
+
+ OId2ObjectMap::const_iterator const iFind
+ ( that->aOId2ObjectMap.find( rOId ) );
+ if (iFind != that->aOId2ObjectMap.end())
+ {
+ InterfaceEntry const * pIEntry = iFind->second->find( pTypeDescr );
+ if (pIEntry)
+ {
+ (*pEnv->acquireInterface)( pEnv, pIEntry->pInterface );
+ *ppInterface = pIEntry->pInterface;
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+static void SAL_CALL defenv_getRegisteredInterfaces(
+ uno_ExtEnvironment * pEnv, void *** pppInterfaces, sal_Int32 * pnLen,
+ uno_memAlloc memAlloc )
+{
+ OSL_ENSURE( pEnv && pppInterfaces && pnLen && memAlloc, "### null ptr!" );
+ uno_DefaultEnvironment * that =
+ static_cast< uno_DefaultEnvironment * >( pEnv );
+ ::osl::MutexGuard guard( that->mutex );
+
+ sal_Int32 nLen = that->aPtr2ObjectMap.size();
+ sal_Int32 nPos = 0;
+ void ** ppInterfaces = (void **) (*memAlloc)( nLen * sizeof (void *) );
+
+ Ptr2ObjectMap::const_iterator iPos( that->aPtr2ObjectMap.begin() );
+ Ptr2ObjectMap::const_iterator const iEnd( that->aPtr2ObjectMap.end() );
+ while (iPos != iEnd)
+ {
+ (*pEnv->acquireInterface)( pEnv, ppInterfaces[nPos++] = (*iPos).first );
+ ++iPos;
+ }
+
+ *pppInterfaces = ppInterfaces;
+ *pnLen = nLen;
+}
+
+//------------------------------------------------------------------------------
+static void SAL_CALL defenv_acquire( uno_Environment * pEnv )
+{
+ uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv;
+ ::osl_incrementInterlockedCount( &that->nWeakRef );
+ ::osl_incrementInterlockedCount( &that->nRef );
+}
+
+//------------------------------------------------------------------------------
+static void SAL_CALL defenv_release( uno_Environment * pEnv )
+{
+ uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv;
+ if (! ::osl_decrementInterlockedCount( &that->nRef ))
+ {
+ // invoke dispose callback
+ if (pEnv->environmentDisposing)
+ {
+ (*pEnv->environmentDisposing)( pEnv );
+ }
+
+ OSL_ENSURE( that->aOId2ObjectMap.empty(), "### object entries left!" );
+ }
+ // free memory if no weak refs left
+ if (! ::osl_decrementInterlockedCount( &that->nWeakRef ))
+ {
+ delete that;
+ }
+}
+
+//------------------------------------------------------------------------------
+static void SAL_CALL defenv_acquireWeak( uno_Environment * pEnv )
+{
+ uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv;
+ ::osl_incrementInterlockedCount( &that->nWeakRef );
+}
+
+//------------------------------------------------------------------------------
+static void SAL_CALL defenv_releaseWeak( uno_Environment * pEnv )
+{
+ uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv;
+ if (! ::osl_decrementInterlockedCount( &that->nWeakRef ))
+ {
+ delete that;
+ }
+}
+
+//------------------------------------------------------------------------------
+static void SAL_CALL defenv_harden(
+ uno_Environment ** ppHardEnv, uno_Environment * pEnv )
+{
+ if (*ppHardEnv)
+ {
+ (*(*ppHardEnv)->release)( *ppHardEnv );
+ *ppHardEnv = 0;
+ }
+
+ uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv;
+ {
+ ::osl::MutexGuard guard( theEnvironmentsData::get().mutex );
+ if (1 == ::osl_incrementInterlockedCount( &that->nRef )) // is dead
+ {
+ that->nRef = 0;
+ return;
+ }
+ }
+ ::osl_incrementInterlockedCount( &that->nWeakRef );
+ *ppHardEnv = pEnv;
+}
+
+//------------------------------------------------------------------------------
+static void SAL_CALL defenv_dispose( uno_Environment * )
+{
+}
+}
+
+//______________________________________________________________________________
+uno_DefaultEnvironment::uno_DefaultEnvironment(
+ const OUString & rEnvDcp_, void * pContext_ )
+ : nRef( 0 ),
+ nWeakRef( 0 )
+{
+ uno_Environment * that = reinterpret_cast< uno_Environment * >(this);
+ that->pReserved = 0;
+ // functions
+ that->acquire = defenv_acquire;
+ that->release = defenv_release;
+ that->acquireWeak = defenv_acquireWeak;
+ that->releaseWeak = defenv_releaseWeak;
+ that->harden = defenv_harden;
+ that->dispose = defenv_dispose;
+ that->pExtEnv = this;
+ // identifier
+ ::rtl_uString_acquire( rEnvDcp_.pData );
+ that->pTypeName = rEnvDcp_.pData;
+ that->pContext = pContext_;
+
+ // will be late initialized
+ that->environmentDisposing = 0;
+
+ uno_ExtEnvironment::registerInterface = defenv_registerInterface;
+ uno_ExtEnvironment::registerProxyInterface = defenv_registerProxyInterface;
+ uno_ExtEnvironment::revokeInterface = defenv_revokeInterface;
+ uno_ExtEnvironment::getObjectIdentifier = defenv_getObjectIdentifier;
+ uno_ExtEnvironment::getRegisteredInterface = defenv_getRegisteredInterface;
+ uno_ExtEnvironment::getRegisteredInterfaces =
+ defenv_getRegisteredInterfaces;
+
+}
+
+//______________________________________________________________________________
+uno_DefaultEnvironment::~uno_DefaultEnvironment()
+{
+ ::rtl_uString_release( ((uno_Environment *) this)->pTypeName );
+}
+
+//==============================================================================
+static void writeLine(
+ void * stream, const sal_Char * pLine, const sal_Char * pFilter )
+{
+ if (pFilter && *pFilter)
+ {
+ // lookup pFilter in pLine
+ while (*pLine)
+ {
+ if (*pLine == *pFilter)
+ {
+ sal_Int32 nPos = 1;
+ while (pLine[nPos] && pFilter[nPos] == pLine[nPos])
+ {
+ ++nPos;
+ }
+ if (! pFilter[nPos])
+ {
+ if (stream)
+ {
+ fprintf( (FILE *) stream, "%s\n", pLine );
+ }
+ else
+ {
+ OSL_TRACE( pLine );
+ OSL_TRACE( "\n" );
+ }
+ }
+ }
+ ++pLine;
+ }
+ }
+ else
+ {
+ if (stream)
+ {
+ fprintf( (FILE *) stream, "%s\n", pLine );
+ }
+ else
+ {
+ fprintf( stderr, "%s\n", pLine );
+ }
+ }
+}
+
+//==============================================================================
+static void writeLine(
+ void * stream, const OUString & rLine, const sal_Char * pFilter )
+{
+ ::rtl::OString aLine( ::rtl::OUStringToOString(
+ rLine, RTL_TEXTENCODING_ASCII_US ) );
+ writeLine( stream, aLine.getStr(), pFilter );
+}
+
+//##############################################################################
+extern "C" void SAL_CALL uno_dumpEnvironment(
+ void * stream, uno_Environment * pEnv, const sal_Char * pFilter )
+ SAL_THROW_EXTERN_C()
+{
+ OSL_ENSURE( pEnv, "### null ptr!" );
+ ::rtl::OUStringBuffer buf;
+
+ if (! pEnv->pExtEnv)
+ {
+ writeLine( stream, "###################################"
+ "###########################################", pFilter );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("environment: ") );
+ buf.append( pEnv->pTypeName );
+ writeLine( stream, buf.makeStringAndClear(), pFilter );
+ writeLine( stream, "NO INTERFACE INFORMATION AVAILABLE!", pFilter );
+ return;
+ }
+
+ writeLine( stream, "########################################"
+ "######################################", pFilter );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("environment dump: ") );
+ buf.append( pEnv->pTypeName );
+ writeLine( stream, buf.makeStringAndClear(), pFilter );
+
+ uno_DefaultEnvironment * that =
+ reinterpret_cast< uno_DefaultEnvironment * >(pEnv);
+ ::osl::MutexGuard guard( that->mutex );
+
+ Ptr2ObjectMap ptr2obj( that->aPtr2ObjectMap );
+ OId2ObjectMap::const_iterator iPos( that->aOId2ObjectMap.begin() );
+ while (iPos != that->aOId2ObjectMap.end())
+ {
+ ObjectEntry * pOEntry = iPos->second;
+
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("+ ") );
+ if (pOEntry->mixedObject)
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("mixed ") );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("object entry: nRef=") );
+ buf.append( pOEntry->nRef, 10 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("; oid=\"") );
+ buf.append( pOEntry->oid );
+ buf.append( (sal_Unicode) '\"' );
+ writeLine( stream, buf.makeStringAndClear(), pFilter );
+
+ for ( ::std::size_t nPos = 0;
+ nPos < pOEntry->aInterfaces.size(); ++nPos )
+ {
+ const InterfaceEntry & rIEntry = pOEntry->aInterfaces[nPos];
+
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" - ") );
+ buf.append(
+ ((typelib_TypeDescription *) rIEntry.pTypeDescr)->pTypeName );
+ if (rIEntry.fpFreeProxy)
+ {
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("; proxy free=0x") );
+ buf.append(
+ reinterpret_cast< sal_IntPtr >(rIEntry.fpFreeProxy), 16 );
+ }
+ else
+ {
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("; original") );
+ }
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("; ptr=0x") );
+ buf.append(
+ reinterpret_cast< sal_IntPtr >(rIEntry.pInterface), 16 );
+
+ if (pOEntry->find( rIEntry.pInterface, nPos + 1 ) < 0)
+ {
+ ::std::size_t erased = ptr2obj.erase( rIEntry.pInterface );
+ if (erased != 1)
+ {
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
+ " (ptr not found in map!)") );
+ }
+ }
+ writeLine( stream, buf.makeStringAndClear(), pFilter );
+ }
+ ++iPos;
+ }
+ if (! ptr2obj.empty())
+ writeLine( stream, "ptr map inconsistency!!!", pFilter );
+ writeLine( stream, "#####################################"
+ "#########################################", pFilter );
+}
+
+//##############################################################################
+extern "C" void SAL_CALL uno_dumpEnvironmentByName(
+ void * stream, rtl_uString * pEnvDcp, const sal_Char * pFilter )
+ SAL_THROW_EXTERN_C()
+{
+ uno_Environment * pEnv = 0;
+ uno_getEnvironment( &pEnv, pEnvDcp, 0 );
+ if (pEnv)
+ {
+ ::uno_dumpEnvironment( stream, pEnv, pFilter );
+ (*pEnv->release)( pEnv );
+ }
+ else
+ {
+ ::rtl::OUStringBuffer buf( 32 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("environment \"") );
+ buf.append( pEnvDcp );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" does not exist!") );
+ writeLine( stream, buf.makeStringAndClear(), pFilter );
+ }
+}
+
+//------------------------------------------------------------------------------
+inline static const OUString & unoenv_getStaticOIdPart()
+{
+ static OUString * s_pStaticOidPart = 0;
+ if (! s_pStaticOidPart)
+ {
+ ::osl::MutexGuard guard( ::osl::Mutex::getGlobalMutex() );
+ if (! s_pStaticOidPart)
+ {
+ ::rtl::OUStringBuffer aRet( 64 );
+ aRet.appendAscii( RTL_CONSTASCII_STRINGPARAM("];") );
+ // pid
+ oslProcessInfo info;
+ info.Size = sizeof(oslProcessInfo);
+ if (::osl_getProcessInfo( 0, osl_Process_IDENTIFIER, &info ) ==
+ osl_Process_E_None)
+ {
+ aRet.append( (sal_Int64)info.Ident, 16 );
+ }
+ else
+ {
+ aRet.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("unknown process id") );
+ }
+ // good guid
+ sal_uInt8 ar[16];
+ ::rtl_getGlobalProcessId( ar );
+ aRet.append( (sal_Unicode)';' );
+ for ( sal_Int32 i = 0; i < 16; ++i )
+ aRet.append( (sal_Int32)ar[i], 16 );
+
+ static OUString s_aStaticOidPart( aRet.makeStringAndClear() );
+ s_pStaticOidPart = &s_aStaticOidPart;
+ }
+ }
+ return *s_pStaticOidPart;
+}
+
+extern "C"
+{
+
+//------------------------------------------------------------------------------
+static void SAL_CALL unoenv_computeObjectIdentifier(
+ uno_ExtEnvironment * pEnv, rtl_uString ** ppOId, void * pInterface )
+{
+ OSL_ENSURE( pEnv && ppOId && pInterface, "### null ptr!" );
+ if (*ppOId)
+ {
+ ::rtl_uString_release( *ppOId );
+ *ppOId = 0;
+ }
+
+ uno_Interface * pUnoI = (uno_Interface *)
+ ::cppu::binuno_queryInterface(
+ pInterface, *typelib_static_type_getByTypeClass(
+ typelib_TypeClass_INTERFACE ) );
+ if (0 != pUnoI)
+ {
+ (*pUnoI->release)( pUnoI );
+ // interface
+ ::rtl::OUStringBuffer oid( 64 );
+ oid.append( reinterpret_cast< sal_Int64 >(pUnoI), 16 );
+ oid.append( static_cast< sal_Unicode >(';') );
+ // environment[context]
+ oid.append( ((uno_Environment *) pEnv)->pTypeName );
+ oid.append( static_cast< sal_Unicode >('[') );
+ oid.append( reinterpret_cast< sal_Int64 >(
+ reinterpret_cast<
+ uno_Environment * >(pEnv)->pContext ), 16 );
+ // process;good guid
+ oid.append( unoenv_getStaticOIdPart() );
+ OUString aStr( oid.makeStringAndClear() );
+ ::rtl_uString_acquire( *ppOId = aStr.pData );
+ }
+}
+
+//==============================================================================
+static void SAL_CALL unoenv_acquireInterface(
+ uno_ExtEnvironment *, void * pUnoI_ )
+{
+ uno_Interface * pUnoI = reinterpret_cast< uno_Interface * >(pUnoI_);
+ (*pUnoI->acquire)( pUnoI );
+}
+
+//==============================================================================
+static void SAL_CALL unoenv_releaseInterface(
+ uno_ExtEnvironment *, void * pUnoI_ )
+{
+ uno_Interface * pUnoI = reinterpret_cast< uno_Interface * >(pUnoI_);
+ (*pUnoI->release)( pUnoI );
+}
+}
+
+//______________________________________________________________________________
+EnvironmentsData::~EnvironmentsData()
+{
+ ::osl::MutexGuard guard( mutex );
+
+ for ( OUString2EnvironmentMap::const_iterator iPos( aName2EnvMap.begin() );
+ iPos != aName2EnvMap.end(); ++iPos )
+ {
+ uno_Environment * pWeak = iPos->second;
+ uno_Environment * pHard = 0;
+ (*pWeak->harden)( &pHard, pWeak );
+ (*pWeak->releaseWeak)( pWeak );
+
+ if (pHard)
+ {
+#if OSL_DEBUG_LEVEL > 1
+ ::uno_dumpEnvironment( 0, pHard, 0 );
+#endif
+#if defined CPPU_LEAK_STATIC_DATA
+ pHard->environmentDisposing = 0; // set to null => wont be called
+#else
+ (*pHard->dispose)( pHard ); // send explicit dispose
+#endif
+ (*pHard->release)( pHard );
+ }
+ }
+}
+
+//______________________________________________________________________________
+inline void EnvironmentsData::getEnvironment(
+ uno_Environment ** ppEnv, const OUString & rEnvDcp, void * pContext )
+{
+ if (*ppEnv)
+ {
+ (*(*ppEnv)->release)( *ppEnv );
+ *ppEnv = 0;
+ }
+
+ OUString aKey(
+ OUString::valueOf( reinterpret_cast< sal_IntPtr >(pContext) ) );
+ aKey += rEnvDcp;
+
+ // try to find registered mapping
+ OUString2EnvironmentMap::const_iterator const iFind(
+ aName2EnvMap.find( aKey ) );
+ if (iFind != aName2EnvMap.end())
+ {
+ uno_Environment * pWeak = iFind->second;
+ (*pWeak->harden)( ppEnv, pWeak );
+ }
+}
+
+//______________________________________________________________________________
+inline void EnvironmentsData::registerEnvironment( uno_Environment ** ppEnv )
+{
+ OSL_ENSURE( ppEnv, "### null ptr!" );
+ uno_Environment * pEnv = *ppEnv;
+
+ OUString aKey(
+ OUString::valueOf( reinterpret_cast< sal_IntPtr >(pEnv->pContext) ) );
+ aKey += pEnv->pTypeName;
+
+ // try to find registered environment
+ OUString2EnvironmentMap::const_iterator const iFind(
+ aName2EnvMap.find( aKey ) );
+ if (iFind == aName2EnvMap.end())
+ {
+ (*pEnv->acquireWeak)( pEnv );
+ ::std::pair< OUString2EnvironmentMap::iterator, bool > insertion(
+ aName2EnvMap.insert(
+ OUString2EnvironmentMap::value_type( aKey, pEnv ) ) );
+ OSL_ENSURE(
+ insertion.second, "### insertion of env into map failed?!" );
+ }
+ else
+ {
+ uno_Environment * pHard = 0;
+ uno_Environment * pWeak = iFind->second;
+ (*pWeak->harden)( &pHard, pWeak );
+ if (pHard)
+ {
+ if (pEnv)
+ (*pEnv->release)( pEnv );
+ *ppEnv = pHard;
+ }
+ else // registered one is dead
+ {
+ (*pWeak->releaseWeak)( pWeak );
+ (*pEnv->acquireWeak)( pEnv );
+ aName2EnvMap[ aKey ] = pEnv;
+ }
+ }
+}
+
+//______________________________________________________________________________
+inline void EnvironmentsData::getRegisteredEnvironments(
+ uno_Environment *** pppEnvs, sal_Int32 * pnLen, uno_memAlloc memAlloc,
+ const OUString & rEnvDcp )
+{
+ OSL_ENSURE( pppEnvs && pnLen && memAlloc, "### null ptr!" );
+
+ // max size
+ uno_Environment ** ppFound = (uno_Environment **)alloca(
+ sizeof(uno_Environment *) * aName2EnvMap.size() );
+ sal_Int32 nSize = 0;
+
+ // find matching environment
+ for ( OUString2EnvironmentMap::const_iterator iPos( aName2EnvMap.begin() );
+ iPos != aName2EnvMap.end(); ++iPos )
+ {
+ uno_Environment * pWeak = iPos->second;
+ if (!rEnvDcp.getLength() ||
+ rEnvDcp.equals( pWeak->pTypeName ))
+ {
+ ppFound[nSize] = 0;
+ (*pWeak->harden)( &ppFound[nSize], pWeak );
+ if (ppFound[nSize])
+ ++nSize;
+ }
+ }
+
+ *pnLen = nSize;
+ if (nSize)
+ {
+ *pppEnvs = (uno_Environment **) (*memAlloc)(
+ sizeof (uno_Environment *) * nSize );
+ OSL_ASSERT( *pppEnvs );
+ while (nSize--)
+ {
+ (*pppEnvs)[nSize] = ppFound[nSize];
+ }
+ }
+ else
+ {
+ *pppEnvs = 0;
+ }
+}
+
+static bool loadEnv(OUString const & cLibStem,
+ uno_Environment * pEnv,
+ void * /*pContext*/)
+{
+ // late init with some code from matching uno language binding
+ // will be unloaded by environment
+ oslModule hMod = cppu::detail::loadModule( cLibStem );
+
+ if (!hMod)
+ return false;
+
+ OUString aSymbolName(RTL_CONSTASCII_USTRINGPARAM(UNO_INIT_ENVIRONMENT));
+ uno_initEnvironmentFunc fpInit = (uno_initEnvironmentFunc)
+ ::osl_getFunctionSymbol( hMod, aSymbolName.pData );
+ if (!fpInit)
+ {
+ ::osl_unloadModule( hMod );
+ return false;
+ }
+
+ (*fpInit)( pEnv ); // init of environment
+ ::rtl_registerModuleForUnloading( hMod );
+
+ return true;
+}
+
+
+extern "C"
+{
+
+//------------------------------------------------------------------------------
+static uno_Environment * initDefaultEnvironment(
+ const OUString & rEnvDcp, void * pContext )
+{
+ uno_Environment * pEnv = &(new uno_DefaultEnvironment( rEnvDcp, pContext ))->aBase;
+ (*pEnv->acquire)( pEnv );
+
+ OUString envTypeName = cppu::EnvDcp::getTypeName(rEnvDcp);
+
+ // create default environment
+ if (envTypeName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_LB_UNO) ))
+ {
+ uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv;
+ that->computeObjectIdentifier = unoenv_computeObjectIdentifier;
+ that->acquireInterface = unoenv_acquireInterface;
+ that->releaseInterface = unoenv_releaseInterface;
+
+ OUString envPurpose = cppu::EnvDcp::getPurpose(rEnvDcp);
+ if (envPurpose.getLength())
+ {
+ rtl::OUString libStem = envPurpose.copy(envPurpose.lastIndexOf(':') + 1);
+ libStem += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("_uno_uno") );
+
+ if(!loadEnv(libStem, pEnv, pContext))
+ {
+ pEnv->release(pEnv);
+ return NULL;
+ }
+ }
+ }
+ else
+ {
+ // late init with some code from matching uno language binding
+ ::rtl::OUStringBuffer aLibName( 16 );
+ aLibName.append( envTypeName );
+ aLibName.appendAscii( RTL_CONSTASCII_STRINGPARAM("_uno" ) );
+ OUString aStr( aLibName.makeStringAndClear() );
+
+ if (!loadEnv(aStr, pEnv, pContext))
+ {
+ pEnv->release(pEnv);
+ return NULL;
+ }
+ }
+
+ return pEnv;
+}
+
+//##############################################################################
+void SAL_CALL uno_createEnvironment(
+ uno_Environment ** ppEnv, rtl_uString * pEnvDcp, void * pContext )
+ SAL_THROW_EXTERN_C()
+{
+ OSL_ENSURE( ppEnv, "### null ptr!" );
+ if (*ppEnv)
+ (*(*ppEnv)->release)( *ppEnv );
+
+ OUString const & rEnvDcp = OUString::unacquired( &pEnvDcp );
+ *ppEnv = initDefaultEnvironment( rEnvDcp, pContext );
+}
+
+//##############################################################################
+void SAL_CALL uno_direct_getEnvironment(
+ uno_Environment ** ppEnv, rtl_uString * pEnvDcp, void * pContext )
+ SAL_THROW_EXTERN_C()
+{
+ OSL_ENSURE( ppEnv, "### null ptr!" );
+ OUString const & rEnvDcp = OUString::unacquired( &pEnvDcp );
+
+ EnvironmentsData & rData = theEnvironmentsData::get();
+
+ ::osl::MutexGuard guard( rData.mutex );
+ rData.getEnvironment( ppEnv, rEnvDcp, pContext );
+ if (! *ppEnv)
+ {
+ *ppEnv = initDefaultEnvironment( rEnvDcp, pContext );
+ if (*ppEnv)
+ {
+ // register new environment:
+ rData.registerEnvironment( ppEnv );
+ }
+ }
+}
+
+//##############################################################################
+void SAL_CALL uno_getRegisteredEnvironments(
+ uno_Environment *** pppEnvs, sal_Int32 * pnLen, uno_memAlloc memAlloc,
+ rtl_uString * pEnvDcp )
+ SAL_THROW_EXTERN_C()
+{
+ EnvironmentsData & rData = theEnvironmentsData::get();
+
+ ::osl::MutexGuard guard( rData.mutex );
+ rData.getRegisteredEnvironments(
+ pppEnvs, pnLen, memAlloc,
+ (pEnvDcp ? OUString(pEnvDcp) : OUString()) );
+}
+
+} // extern "C"
+
+}
+
diff --git a/cppu/source/uno/lbmap.cxx b/cppu/source/uno/lbmap.cxx
new file mode 100644
index 000000000000..d2c4a6f60641
--- /dev/null
+++ b/cppu/source/uno/lbmap.cxx
@@ -0,0 +1,692 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_cppu.hxx"
+
+#include "IdentityMapping.hxx"
+
+#include <hash_map>
+#include <set>
+#include <algorithm>
+
+#include "rtl/unload.h"
+#include "rtl/ustring.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "osl/module.h"
+#include "osl/diagnose.h"
+#include "osl/mutex.hxx"
+#include "osl/interlck.h"
+
+#include "uno/dispatcher.h"
+#include "uno/mapping.h"
+#include "uno/lbnames.h"
+#include "uno/environment.hxx"
+
+#include "typelib/typedescription.h"
+
+#include "cppu/EnvDcp.hxx"
+#include "cascade_mapping.hxx"
+#include "IdentityMapping.hxx"
+#include "loadmodule.hxx"
+
+using namespace std;
+using namespace osl;
+using namespace rtl;
+using namespace com::sun::star::uno;
+
+
+namespace cppu
+{
+
+class Mapping
+{
+ uno_Mapping * _pMapping;
+
+public:
+ inline Mapping( uno_Mapping * pMapping = 0 ) SAL_THROW( () );
+ inline Mapping( const Mapping & rMapping ) SAL_THROW( () );
+ inline ~Mapping() SAL_THROW( () );
+ inline Mapping & SAL_CALL operator = ( uno_Mapping * pMapping ) SAL_THROW( () );
+ inline Mapping & SAL_CALL operator = ( const Mapping & rMapping ) SAL_THROW( () )
+ { return operator = ( rMapping._pMapping ); }
+ inline uno_Mapping * SAL_CALL get() const SAL_THROW( () )
+ { return _pMapping; }
+ inline sal_Bool SAL_CALL is() const SAL_THROW( () )
+ { return (_pMapping != 0); }
+};
+//__________________________________________________________________________________________________
+inline Mapping::Mapping( uno_Mapping * pMapping ) SAL_THROW( () )
+ : _pMapping( pMapping )
+{
+ if (_pMapping)
+ (*_pMapping->acquire)( _pMapping );
+}
+//__________________________________________________________________________________________________
+inline Mapping::Mapping( const Mapping & rMapping ) SAL_THROW( () )
+ : _pMapping( rMapping._pMapping )
+{
+ if (_pMapping)
+ (*_pMapping->acquire)( _pMapping );
+}
+//__________________________________________________________________________________________________
+inline Mapping::~Mapping() SAL_THROW( () )
+{
+ if (_pMapping)
+ (*_pMapping->release)( _pMapping );
+}
+//__________________________________________________________________________________________________
+inline Mapping & Mapping::operator = ( uno_Mapping * pMapping ) SAL_THROW( () )
+{
+ if (pMapping)
+ (*pMapping->acquire)( pMapping );
+ if (_pMapping)
+ (*_pMapping->release)( _pMapping );
+ _pMapping = pMapping;
+ return *this;
+}
+
+//==================================================================================================
+struct MappingEntry
+{
+ sal_Int32 nRef;
+ uno_Mapping * pMapping;
+ uno_freeMappingFunc freeMapping;
+ OUString aMappingName;
+
+ MappingEntry(
+ uno_Mapping * pMapping_, uno_freeMappingFunc freeMapping_,
+ const OUString & rMappingName_ )
+ SAL_THROW( () )
+ : nRef( 1 )
+ , pMapping( pMapping_ )
+ , freeMapping( freeMapping_ )
+ , aMappingName( rMappingName_ )
+ {}
+};
+//--------------------------------------------------------------------------------------------------
+struct FctOUStringHash : public unary_function< const OUString &, size_t >
+{
+ size_t operator()( const OUString & rKey ) const SAL_THROW( () )
+ { return (size_t)rKey.hashCode(); }
+};
+//--------------------------------------------------------------------------------------------------
+struct FctPtrHash : public unary_function< uno_Mapping *, size_t >
+{
+ size_t operator()( uno_Mapping * pKey ) const SAL_THROW( () )
+ { return (size_t)pKey; }
+};
+
+typedef hash_map<
+ OUString, MappingEntry *, FctOUStringHash, equal_to< OUString > > t_OUString2Entry;
+typedef hash_map<
+ uno_Mapping *, MappingEntry *, FctPtrHash, equal_to< uno_Mapping * > > t_Mapping2Entry;
+
+typedef set< uno_getMappingFunc > t_CallbackSet;
+typedef set< OUString > t_OUStringSet;
+
+//==================================================================================================
+struct MappingsData
+{
+ Mutex aMappingsMutex;
+ t_OUString2Entry aName2Entry;
+ t_Mapping2Entry aMapping2Entry;
+
+ Mutex aCallbacksMutex;
+ t_CallbackSet aCallbacks;
+
+ Mutex aNegativeLibsMutex;
+ t_OUStringSet aNegativeLibs;
+};
+//--------------------------------------------------------------------------------------------------
+static MappingsData & getMappingsData() SAL_THROW( () )
+{
+ static MappingsData * s_p = 0;
+ if (! s_p)
+ {
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ if (! s_p)
+ {
+ //TODO This memory is leaked; see #i63473# for when this should be
+ // changed again:
+ s_p = new MappingsData;
+ }
+ }
+ return *s_p;
+}
+
+/**
+ * This class mediates two different mapping via uno, e.g. form any language to uno,
+ * then from uno to any other language.
+ */
+struct uno_Mediate_Mapping : public uno_Mapping
+{
+ sal_Int32 nRef;
+
+ Environment aFrom;
+ Environment aTo;
+
+ Mapping aFrom2Uno;
+ Mapping aUno2To;
+
+ OUString aAddPurpose;
+
+ uno_Mediate_Mapping(
+ const Environment & rFrom_, const Environment & rTo_,
+ const Mapping & rFrom2Uno_, const Mapping & rUno2To_,
+ const OUString & rAddPurpose )
+ SAL_THROW( () );
+};
+extern "C"
+{
+//--------------------------------------------------------------------------------------------------
+static void SAL_CALL mediate_free( uno_Mapping * pMapping )
+ SAL_THROW( () )
+{
+ delete static_cast< uno_Mediate_Mapping * >( pMapping );
+}
+//--------------------------------------------------------------------------------------------------
+static void SAL_CALL mediate_acquire( uno_Mapping * pMapping )
+ SAL_THROW( () )
+{
+ if (1 == ::osl_incrementInterlockedCount(
+ & static_cast< uno_Mediate_Mapping * >( pMapping )->nRef ))
+ {
+ uno_registerMapping(
+ &pMapping, mediate_free,
+ static_cast< uno_Mediate_Mapping * >( pMapping )->aFrom.get(),
+ static_cast< uno_Mediate_Mapping * >( pMapping )->aTo.get(),
+ static_cast< uno_Mediate_Mapping * >( pMapping )->aAddPurpose.pData );
+ }
+}
+//--------------------------------------------------------------------------------------------------
+static void SAL_CALL mediate_release( uno_Mapping * pMapping )
+ SAL_THROW( () )
+{
+ if (! ::osl_decrementInterlockedCount(
+ & static_cast< uno_Mediate_Mapping * >( pMapping )->nRef ))
+ {
+ uno_revokeMapping( pMapping );
+ }
+}
+//--------------------------------------------------------------------------------------------------
+static void SAL_CALL mediate_mapInterface(
+ uno_Mapping * pMapping,
+ void ** ppOut, void * pInterface,
+ typelib_InterfaceTypeDescription * pInterfaceTypeDescr )
+ SAL_THROW( () )
+{
+ OSL_ENSURE( pMapping && ppOut, "### null ptr!" );
+ if (pMapping && ppOut)
+ {
+ uno_Mediate_Mapping * that = static_cast< uno_Mediate_Mapping * >( pMapping );
+ uno_Mapping * pFrom2Uno = that->aFrom2Uno.get();
+
+ uno_Interface * pUnoI = 0;
+ (*pFrom2Uno->mapInterface)( pFrom2Uno, (void **) &pUnoI, pInterface, pInterfaceTypeDescr );
+ if (0 == pUnoI)
+ {
+ void * pOut = *ppOut;
+ if (0 != pOut)
+ {
+ uno_ExtEnvironment * pTo = that->aTo.get()->pExtEnv;
+ OSL_ENSURE( 0 != pTo, "### cannot release out interface: leaking!" );
+ if (0 != pTo)
+ (*pTo->releaseInterface)( pTo, pOut );
+ *ppOut = 0; // set to 0 anyway, because mapping was not successfull!
+ }
+ }
+ else
+ {
+ uno_Mapping * pUno2To = that->aUno2To.get();
+ (*pUno2To->mapInterface)( pUno2To, ppOut, pUnoI, pInterfaceTypeDescr );
+ (*pUnoI->release)( pUnoI );
+ }
+ }
+}
+}
+//__________________________________________________________________________________________________
+uno_Mediate_Mapping::uno_Mediate_Mapping(
+ const Environment & rFrom_, const Environment & rTo_,
+ const Mapping & rFrom2Uno_, const Mapping & rUno2To_,
+ const OUString & rAddPurpose_ )
+ SAL_THROW( () )
+ : nRef( 1 )
+ , aFrom( rFrom_ )
+ , aTo( rTo_ )
+ , aFrom2Uno( rFrom2Uno_ )
+ , aUno2To( rUno2To_ )
+ , aAddPurpose( rAddPurpose_ )
+{
+ uno_Mapping::acquire = mediate_acquire;
+ uno_Mapping::release = mediate_release;
+ uno_Mapping::mapInterface = mediate_mapInterface;
+}
+
+//==================================================================================================
+static inline OUString getMappingName(
+ const Environment & rFrom, const Environment & rTo, const OUString & rAddPurpose )
+ SAL_THROW( () )
+{
+ OUStringBuffer aKey( 64 );
+ aKey.append( rAddPurpose );
+ aKey.append( (sal_Unicode)';' );
+ aKey.append( rFrom.getTypeName() );
+ aKey.append( (sal_Unicode)'[' );
+ aKey.append( reinterpret_cast< sal_IntPtr >(rFrom.get()), 16 );
+ aKey.appendAscii( RTL_CONSTASCII_STRINGPARAM("];") );
+ aKey.append( rTo.getTypeName() );
+ aKey.append( (sal_Unicode)'[' );
+ aKey.append( reinterpret_cast< sal_IntPtr >(rTo.get()), 16 );
+ aKey.append( (sal_Unicode)']' );
+ return aKey.makeStringAndClear();
+}
+//==================================================================================================
+static inline OUString getBridgeName(
+ const Environment & rFrom, const Environment & rTo, const OUString & rAddPurpose )
+ SAL_THROW( () )
+{
+ OUStringBuffer aBridgeName( 16 );
+ if (rAddPurpose.getLength())
+ {
+ aBridgeName.append( rAddPurpose );
+ aBridgeName.append( (sal_Unicode)'_' );
+ }
+ aBridgeName.append( EnvDcp::getTypeName(rFrom.getTypeName()) );
+ aBridgeName.append( (sal_Unicode)'_' );
+ aBridgeName.append( EnvDcp::getTypeName(rTo.getTypeName()) );
+ return aBridgeName.makeStringAndClear();
+}
+//==================================================================================================
+static inline void setNegativeBridge( const OUString & rBridgeName )
+ SAL_THROW( () )
+{
+ MappingsData & rData = getMappingsData();
+ MutexGuard aGuard( rData.aNegativeLibsMutex );
+ rData.aNegativeLibs.insert( rBridgeName );
+}
+//==================================================================================================
+static inline oslModule loadModule( const OUString & rBridgeName )
+ SAL_THROW( () )
+{
+ sal_Bool bNeg;
+ {
+ MappingsData & rData = getMappingsData();
+ MutexGuard aGuard( rData.aNegativeLibsMutex );
+ const t_OUStringSet::const_iterator iFind( rData.aNegativeLibs.find( rBridgeName ) );
+ bNeg = (iFind != rData.aNegativeLibs.end());
+ }
+
+ if (! bNeg)
+ {
+ oslModule hModule = cppu::detail::loadModule( rBridgeName );
+
+ if (hModule)
+ return hModule;
+
+ setNegativeBridge( rBridgeName ); // no load again
+ }
+ return 0;
+}
+//==================================================================================================
+static Mapping loadExternalMapping(
+ const Environment & rFrom, const Environment & rTo, const OUString & rAddPurpose )
+ SAL_THROW( () )
+{
+ OSL_ASSERT( rFrom.is() && rTo.is() );
+ if (rFrom.is() && rTo.is())
+ {
+ // find proper lib
+ oslModule hModule = 0;
+ OUString aName;
+
+ if (EnvDcp::getTypeName(rFrom.getTypeName()).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_LB_UNO) ))
+ hModule = loadModule( aName = getBridgeName( rTo, rFrom, rAddPurpose ) );
+ if (! hModule)
+ hModule = loadModule( aName = getBridgeName( rFrom, rTo, rAddPurpose ) );
+ if (! hModule)
+ hModule = loadModule( aName = getBridgeName( rTo, rFrom, rAddPurpose ) );
+
+ if (hModule)
+ {
+ OUString aSymbolName( RTL_CONSTASCII_USTRINGPARAM(UNO_EXT_GETMAPPING) );
+ uno_ext_getMappingFunc fpGetMapFunc =
+ (uno_ext_getMappingFunc)::osl_getFunctionSymbol(
+ hModule, aSymbolName.pData );
+
+ if (fpGetMapFunc)
+ {
+ Mapping aExt;
+ (*fpGetMapFunc)( (uno_Mapping **)&aExt, rFrom.get(), rTo.get() );
+ OSL_ASSERT( aExt.is() );
+ if (aExt.is())
+ {
+ ::rtl_registerModuleForUnloading( hModule );
+ return aExt;
+ }
+ }
+ ::osl_unloadModule( hModule );
+ setNegativeBridge( aName );
+ }
+ }
+ return Mapping();
+}
+
+//==================================================================================================
+static Mapping getDirectMapping(
+ const Environment & rFrom, const Environment & rTo, const OUString & rAddPurpose = OUString() )
+ SAL_THROW( () )
+{
+ OSL_ASSERT( rFrom.is() && rTo.is() );
+ if (rFrom.is() && rTo.is())
+ {
+ MappingsData & rData = getMappingsData();
+ ClearableMutexGuard aGuard( rData.aMappingsMutex );
+
+ // try to find registered mapping
+ const t_OUString2Entry::const_iterator iFind( rData.aName2Entry.find(
+ getMappingName( rFrom, rTo, rAddPurpose ) ) );
+
+ if (iFind == rData.aName2Entry.end())
+ {
+ aGuard.clear();
+ return loadExternalMapping( rFrom, rTo, rAddPurpose );
+ }
+ else
+ {
+ return Mapping( (*iFind).second->pMapping );
+ }
+ }
+ return Mapping();
+}
+
+//--------------------------------------------------------------------------------------------------
+static inline Mapping createMediateMapping(
+ const Environment & rFrom, const Environment & rTo,
+ const Mapping & rFrom2Uno, const Mapping & rUno2To,
+ const OUString & rAddPurpose )
+ SAL_THROW( () )
+{
+ uno_Mapping * pRet = new uno_Mediate_Mapping(
+ rFrom, rTo, rFrom2Uno, rUno2To, rAddPurpose ); // ref count initially 1
+ uno_registerMapping(
+ &pRet, mediate_free, rFrom.get(), rTo.get(), rAddPurpose.pData );
+ Mapping aRet( pRet );
+ (*pRet->release)( pRet );
+ return aRet;
+}
+//==================================================================================================
+static Mapping getMediateMapping(
+ const Environment & rFrom, const Environment & rTo, const OUString & rAddPurpose )
+ SAL_THROW( () )
+{
+ Environment aUno;
+ Mapping aUno2To;
+
+ // backwards: from dest to source of mapping chain
+
+ // connect to uno
+ OUString aUnoEnvTypeName( RTL_CONSTASCII_USTRINGPARAM(UNO_LB_UNO) );
+ if (rTo.getTypeName() == aUnoEnvTypeName) // to is uno
+ {
+ aUno = rTo;
+ // no Uno2To mapping necessary
+ }
+ else
+ {
+ // get registered uno env
+ ::uno_getEnvironment( (uno_Environment **)&aUno, aUnoEnvTypeName.pData, 0 );
+
+ aUno2To = getDirectMapping( aUno, rTo );
+ // : uno <-> to
+ if (! aUno2To.is())
+ return Mapping();
+ }
+
+ // connect to uno
+ if (rAddPurpose.getLength()) // insert purpose mapping between new ano_uno <-> uno
+ {
+ // create anonymous uno env
+ Environment aAnUno;
+ ::uno_createEnvironment( (uno_Environment **)&aAnUno, aUnoEnvTypeName.pData, 0 );
+
+ Mapping aAnUno2Uno( getDirectMapping( aAnUno, aUno, rAddPurpose ) );
+ if (! aAnUno2Uno.is())
+ return Mapping();
+
+ if (aUno2To.is()) // to is not uno
+ {
+ // create another purposed mediate mapping
+ aUno2To = createMediateMapping( aAnUno, rTo, aAnUno2Uno, aUno2To, rAddPurpose );
+ // : ano_uno <-> uno <-> to
+ }
+ else
+ {
+ aUno2To = aAnUno2Uno;
+ // : ano_uno <-> to (i.e., uno)
+ }
+ aUno = aAnUno;
+ }
+
+ Mapping aFrom2Uno( getDirectMapping( rFrom, aUno ) );
+ if (aFrom2Uno.is() && aUno2To.is())
+ {
+ return createMediateMapping( rFrom, rTo, aFrom2Uno, aUno2To, rAddPurpose );
+ // : from <-> some uno ...
+ }
+
+ return Mapping();
+}
+}
+
+using namespace ::cppu;
+
+extern "C"
+{
+//##################################################################################################
+void SAL_CALL uno_getMapping(
+ uno_Mapping ** ppMapping, uno_Environment * pFrom, uno_Environment * pTo,
+ rtl_uString * pAddPurpose )
+ SAL_THROW_EXTERN_C()
+{
+ OSL_ENSURE( ppMapping && pFrom && pTo, "### null ptr!" );
+ if (*ppMapping)
+ {
+ (*(*ppMapping)->release)( *ppMapping );
+ *ppMapping = 0;
+ }
+
+ Mapping aRet;
+ Environment aFrom( pFrom ), aTo( pTo );
+
+ OUString aAddPurpose;
+ if (pAddPurpose)
+ aAddPurpose = pAddPurpose;
+
+ MappingsData & rData = getMappingsData();
+
+ // try registered mapping
+ {
+ MutexGuard aGuard( rData.aMappingsMutex );
+ const t_OUString2Entry::const_iterator iFind( rData.aName2Entry.find(
+ getMappingName( aFrom, aTo, aAddPurpose ) ) );
+ if (iFind != rData.aName2Entry.end())
+ aRet = (*iFind).second->pMapping;
+ }
+
+ // See if an identity mapping does fit.
+ if (!aRet.is() && pFrom == pTo && !aAddPurpose.getLength())
+ aRet = createIdentityMapping(pFrom);
+
+ if (!aRet.is())
+ {
+ getCascadeMapping(ppMapping, pFrom, pTo, pAddPurpose);
+
+ if (*ppMapping)
+ return;
+ }
+
+ if (! aRet.is()) // try callback chain
+ {
+ MutexGuard aGuard( rData.aCallbacksMutex );
+ for ( t_CallbackSet::const_iterator iPos( rData.aCallbacks.begin() );
+ iPos != rData.aCallbacks.end(); ++iPos )
+ {
+ (**iPos)( ppMapping, pFrom, pTo, aAddPurpose.pData );
+ if (*ppMapping)
+ return;
+ }
+ }
+
+ if (! aRet.is())
+ {
+ aRet = loadExternalMapping( aFrom, aTo, aAddPurpose ); // direct try
+ if (! aRet.is())
+ aRet = getMediateMapping( aFrom, aTo, aAddPurpose ); // try via uno
+ }
+
+ if (aRet.is())
+ {
+ (*aRet.get()->acquire)( aRet.get() );
+ *ppMapping = aRet.get();
+ }
+}
+//##################################################################################################
+void SAL_CALL uno_getMappingByName(
+ uno_Mapping ** ppMapping, rtl_uString * pFrom, rtl_uString * pTo,
+ rtl_uString * pAddPurpose )
+ SAL_THROW_EXTERN_C()
+{
+ OSL_ENSURE( ppMapping && pFrom && pTo, "### null ptr!" );
+ if (*ppMapping)
+ {
+ (*(*ppMapping)->release)( *ppMapping );
+ *ppMapping = 0;
+ }
+
+ uno_Environment * pEFrom = 0;
+ uno_getEnvironment( &pEFrom, pFrom, 0 );
+ OSL_ENSURE( pEFrom, "### cannot get source environment!" );
+ if (pEFrom)
+ {
+ uno_Environment * pETo = 0;
+ uno_getEnvironment( &pETo, pTo, 0 );
+ OSL_ENSURE( pETo, "### cannot get target environment!" );
+ if (pETo)
+ {
+ ::uno_getMapping( ppMapping, pEFrom, pETo, pAddPurpose );
+ (*pETo->release)( pETo );
+ }
+ (*pEFrom->release)( pEFrom );
+ }
+}
+
+//##################################################################################################
+void SAL_CALL uno_registerMapping(
+ uno_Mapping ** ppMapping, uno_freeMappingFunc freeMapping,
+ uno_Environment * pFrom, uno_Environment * pTo, rtl_uString * pAddPurpose )
+ SAL_THROW_EXTERN_C()
+{
+ MappingsData & rData = getMappingsData();
+ ClearableMutexGuard aGuard( rData.aMappingsMutex );
+
+ const t_Mapping2Entry::const_iterator iFind( rData.aMapping2Entry.find( *ppMapping ) );
+ if (iFind == rData.aMapping2Entry.end())
+ {
+ OUString aMappingName(
+ getMappingName( pFrom, pTo, pAddPurpose ? OUString(pAddPurpose) : OUString() ) );
+#if OSL_DEBUG_LEVEL > 1
+ OString cstr( OUStringToOString( aMappingName, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( "> inserting new mapping: %s", cstr.getStr() );
+#endif
+ // count initially 1
+ MappingEntry * pEntry = new MappingEntry( *ppMapping, freeMapping, aMappingName );
+ rData.aName2Entry[ aMappingName ] = pEntry;
+ rData.aMapping2Entry[ *ppMapping ] = pEntry;
+ }
+ else
+ {
+ MappingEntry * pEntry = (*iFind).second;
+ ++pEntry->nRef;
+
+ if (pEntry->pMapping != *ppMapping) // exchange mapping to be registered
+ {
+ (*pEntry->pMapping->acquire)( pEntry->pMapping );
+ --pEntry->nRef; // correct count; kill mapping to be registered
+ aGuard.clear();
+ (*freeMapping)( *ppMapping );
+ *ppMapping = pEntry->pMapping;
+ }
+ }
+}
+//##################################################################################################
+void SAL_CALL uno_revokeMapping(
+ uno_Mapping * pMapping )
+ SAL_THROW_EXTERN_C()
+{
+ MappingsData & rData = getMappingsData();
+ ClearableMutexGuard aGuard( rData.aMappingsMutex );
+
+ const t_Mapping2Entry::const_iterator iFind( rData.aMapping2Entry.find( pMapping ) );
+ OSL_ASSERT( iFind != rData.aMapping2Entry.end() );
+ MappingEntry * pEntry = (*iFind).second;
+ if (! --pEntry->nRef)
+ {
+ rData.aMapping2Entry.erase( pEntry->pMapping );
+ rData.aName2Entry.erase( pEntry->aMappingName );
+ aGuard.clear();
+#if OSL_DEBUG_LEVEL > 1
+ OString cstr( OUStringToOString( pEntry->aMappingName, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( "> revoking mapping %s", cstr.getStr() );
+#endif
+ (*pEntry->freeMapping)( pEntry->pMapping );
+ delete pEntry;
+ }
+}
+
+//##################################################################################################
+void SAL_CALL uno_registerMappingCallback(
+ uno_getMappingFunc pCallback )
+ SAL_THROW_EXTERN_C()
+{
+ OSL_ENSURE( pCallback, "### null ptr!" );
+ MappingsData & rData = getMappingsData();
+ MutexGuard aGuard( rData.aCallbacksMutex );
+ rData.aCallbacks.insert( pCallback );
+}
+//##################################################################################################
+void SAL_CALL uno_revokeMappingCallback(
+ uno_getMappingFunc pCallback )
+ SAL_THROW_EXTERN_C()
+{
+ OSL_ENSURE( pCallback, "### null ptr!" );
+ MappingsData & rData = getMappingsData();
+ MutexGuard aGuard( rData.aCallbacksMutex );
+ rData.aCallbacks.erase( pCallback );
+}
+} // extern "C"
+
diff --git a/cppu/source/uno/loadmodule.cxx b/cppu/source/uno/loadmodule.cxx
new file mode 100644
index 000000000000..e6858d247f04
--- /dev/null
+++ b/cppu/source/uno/loadmodule.cxx
@@ -0,0 +1,55 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_cppu.hxx"
+
+#include "sal/config.h"
+
+#include "osl/module.h"
+#include "rtl/string.h"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/ustring.hxx"
+
+#include "loadmodule.hxx"
+
+namespace cppu { namespace detail {
+
+::oslModule loadModule(rtl::OUString const & name) {
+ rtl::OUStringBuffer b;
+#if defined SAL_DLLPREFIX
+ b.appendAscii(RTL_CONSTASCII_STRINGPARAM(SAL_DLLPREFIX));
+#endif
+ b.append(name);
+ b.appendAscii(RTL_CONSTASCII_STRINGPARAM(SAL_DLLEXTENSION));
+ return ::osl_loadModuleRelative(
+ reinterpret_cast< oslGenericFunction >(&loadModule),
+ b.makeStringAndClear().pData,
+ SAL_LOADMODULE_GLOBAL | SAL_LOADMODULE_LAZY);
+}
+
+} }
diff --git a/cppu/source/uno/loadmodule.hxx b/cppu/source/uno/loadmodule.hxx
new file mode 100644
index 000000000000..77a9bb8d6dc0
--- /dev/null
+++ b/cppu/source/uno/loadmodule.hxx
@@ -0,0 +1,51 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_CPPU_SOURCE_UNO_CREATEMODULENAME_HXX
+#define INCLUDED_CPPU_SOURCE_UNO_CREATEMODULENAME_HXX
+
+#include "sal/config.h"
+#include "osl/module.h"
+
+namespace rtl { class OUString; }
+
+namespace cppu { namespace detail {
+
+/** Load a module.
+
+ @param name
+ the nucleus of a module name (without any "lib...so", ".dll", etc.
+ decoration, and without a path).
+
+ @return
+ the handle returned by osl_loadModule.
+*/
+::oslModule loadModule(::rtl::OUString const & name);
+
+} }
+
+#endif
diff --git a/cppu/source/uno/makefile.mk b/cppu/source/uno/makefile.mk
new file mode 100644
index 000000000000..63bf4f0387ac
--- /dev/null
+++ b/cppu/source/uno/makefile.mk
@@ -0,0 +1,55 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+PRJ=..$/..
+
+PRJNAME=cppu
+TARGET=cppu_uno
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : ..$/..$/util$/makefile.pmk
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES= \
+ $(SLO)$/data.obj \
+ $(SLO)$/sequence.obj \
+ $(SLO)$/any.obj \
+ $(SLO)$/lbmap.obj \
+ $(SLO)$/lbenv.obj \
+ $(SLO)$/IdentityMapping.obj \
+ $(SLO)$/EnvDcp.obj \
+ $(SLO)$/cascade_mapping.obj \
+ $(SLO)$/EnvStack.obj \
+ $(SLO)$/env_subst.obj \
+ $(SLO)$/loadmodule.obj
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : ..$/..$/util$/target.pmk
+.INCLUDE : target.mk
diff --git a/cppu/source/uno/prim.hxx b/cppu/source/uno/prim.hxx
new file mode 100644
index 000000000000..4acafd125d55
--- /dev/null
+++ b/cppu/source/uno/prim.hxx
@@ -0,0 +1,206 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef PRIM_HXX
+#define PRIM_HXX
+
+#include "typelib/typedescription.h"
+#ifndef _typelib_TypeClass_H_
+#include "typelib/typeclass.h"
+#endif
+#include "uno/sequence2.h"
+#include "uno/any2.h"
+#include "uno/data.h"
+#include "uno/mapping.h"
+#include "uno/dispatcher.h"
+
+#ifndef _OSL_INTERLCK_H
+#include "osl/interlck.h"
+#endif
+#include "osl/diagnose.h"
+#ifndef _RTL_USTRING_HXX
+#include "rtl/ustring.hxx"
+#endif
+#include "rtl/alloc.h"
+
+#if OSL_DEBUG_LEVEL > 1
+#include "rtl/ustrbuf.hxx"
+#include "rtl/string.hxx"
+#endif
+
+
+namespace cppu
+{
+
+extern uno_Sequence g_emptySeq;
+extern typelib_TypeDescriptionReference * g_pVoidType;
+
+//--------------------------------------------------------------------------------------------------
+inline void * _map(
+ void * p,
+ typelib_TypeDescriptionReference * pType, typelib_TypeDescription * pTypeDescr,
+ uno_Mapping * mapping )
+ SAL_THROW( () )
+{
+ void * pRet = 0;
+ if (p)
+ {
+ if (pTypeDescr)
+ {
+ (*mapping->mapInterface)(
+ mapping, &pRet, p, (typelib_InterfaceTypeDescription *)pTypeDescr );
+ }
+ else
+ {
+ TYPELIB_DANGER_GET( &pTypeDescr, pType );
+ (*mapping->mapInterface)(
+ mapping, &pRet, p, (typelib_InterfaceTypeDescription *)pTypeDescr );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ }
+ }
+ return pRet;
+}
+//--------------------------------------------------------------------------------------------------
+inline void _acquire( void * p, uno_AcquireFunc acquire ) SAL_THROW( () )
+{
+ if (p)
+ {
+ if (acquire)
+ {
+ (*acquire)( p );
+ }
+ else
+ {
+ (*((uno_Interface *)p)->acquire)( (uno_Interface *)p );
+ }
+ }
+}
+//--------------------------------------------------------------------------------------------------
+inline void _release( void * p, uno_ReleaseFunc release ) SAL_THROW( () )
+{
+ if (p)
+ {
+ if (release)
+ {
+ (*release)( p );
+ }
+ else
+ {
+ (*((uno_Interface *)p)->release)( (uno_Interface *)p );
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+inline sal_uInt32 calcSeqMemSize(
+ sal_Int32 nElementSize, sal_Int32 nElements )
+{
+ sal_uInt64 nSize =
+ (sal_uInt64) SAL_SEQUENCE_HEADER_SIZE +
+ ((sal_uInt64) nElementSize * (sal_uInt64) nElements);
+ if (nSize > 0xffffffffU)
+ return 0;
+ else
+ return (sal_uInt32) nSize;
+}
+
+//--------------------------------------------------------------------------------------------------
+inline uno_Sequence * createEmptySequence() SAL_THROW( () )
+{
+ ::osl_incrementInterlockedCount( &g_emptySeq.nRefCount );
+ return &g_emptySeq;
+}
+//--------------------------------------------------------------------------------------------------
+inline typelib_TypeDescriptionReference * _getVoidType()
+ SAL_THROW( () )
+{
+ if (! g_pVoidType)
+ {
+ g_pVoidType = * ::typelib_static_type_getByTypeClass( typelib_TypeClass_VOID );
+ }
+ ::typelib_typedescriptionreference_acquire( g_pVoidType );
+ return g_pVoidType;
+}
+
+//--------------------------------------------------------------------------------------------------
+#if OSL_DEBUG_LEVEL > 0
+#define CONSTRUCT_EMPTY_ANY( pAny ) \
+(pAny)->pType = _getVoidType(); \
+(pAny)->pData = (void *)0xdeadbeef;
+#else
+#define CONSTRUCT_EMPTY_ANY( pAny ) \
+(pAny)->pType = _getVoidType(); \
+(pAny)->pData = (pAny);
+#endif
+
+//--------------------------------------------------------------------------------------------------
+#define TYPE_ACQUIRE( pType ) \
+ ::osl_incrementInterlockedCount( &(pType)->nRefCount );
+
+//--------------------------------------------------------------------------------------------------
+extern "C" void * binuno_queryInterface(
+ void * pUnoI, typelib_TypeDescriptionReference * pDestType );
+
+//--------------------------------------------------------------------------------------------------
+inline typelib_TypeDescriptionReference * _unionGetSetType(
+ void * pUnion, typelib_TypeDescription * pTD )
+ SAL_THROW( () )
+{
+ typelib_TypeDescriptionReference * pRet = 0;
+ sal_Int32 nPos;
+
+ sal_Int64 * pDiscr = ((typelib_UnionTypeDescription *)pTD)->pDiscriminants;
+ sal_Int64 nDiscr = *(sal_Int64 *)pUnion;
+ for ( nPos = ((typelib_UnionTypeDescription *)pTD)->nMembers; nPos--; )
+ {
+ if (pDiscr[nPos] == nDiscr)
+ {
+ pRet = ((typelib_UnionTypeDescription *)pTD)->ppTypeRefs[nPos];
+ break;
+ }
+ }
+ if (nPos >= 0)
+ {
+ // default
+ pRet = ((typelib_UnionTypeDescription *)pTD)->pDefaultTypeRef;
+ }
+ typelib_typedescriptionreference_acquire( pRet );
+ return pRet;
+}
+//--------------------------------------------------------------------------------------------------
+inline sal_Bool _type_equals(
+ typelib_TypeDescriptionReference * pType1, typelib_TypeDescriptionReference * pType2 )
+ SAL_THROW( () )
+{
+ return (pType1 == pType2 ||
+ (pType1->eTypeClass == pType2->eTypeClass &&
+ pType1->pTypeName->length == pType2->pTypeName->length &&
+ ::rtl_ustr_compare( pType1->pTypeName->buffer, pType2->pTypeName->buffer ) == 0));
+}
+
+}
+
+#endif
diff --git a/cppu/source/uno/sequence.cxx b/cppu/source/uno/sequence.cxx
new file mode 100644
index 000000000000..933d38fc6b4f
--- /dev/null
+++ b/cppu/source/uno/sequence.cxx
@@ -0,0 +1,1016 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_cppu.hxx"
+#include <rtl/memory.h>
+#include <rtl/alloc.h>
+#include <osl/diagnose.h>
+#include <osl/interlck.h>
+#include <typelib/typedescription.h>
+#include <uno/data.h>
+#include <uno/dispatcher.h>
+#include <uno/sequence2.h>
+
+#include "constr.hxx"
+#include "copy.hxx"
+#include "destr.hxx"
+
+
+using namespace cppu;
+
+namespace cppu
+{
+
+//------------------------------------------------------------------------------
+static inline uno_Sequence * reallocSeq(
+ uno_Sequence * pReallocate, sal_Size nElementSize, sal_Int32 nElements )
+{
+ OSL_ASSERT( nElements >= 0 );
+ uno_Sequence * pNew = 0;
+ sal_uInt32 nSize = calcSeqMemSize( nElementSize, nElements );
+ if (nSize > 0)
+ {
+ if (pReallocate == 0)
+ {
+ pNew = (uno_Sequence *) rtl_allocateMemory( nSize );
+ }
+ else
+ {
+ pNew = (uno_Sequence *) rtl_reallocateMemory( pReallocate, nSize );
+ }
+ if (pNew != 0)
+ {
+ // header init
+ pNew->nRefCount = 1;
+ pNew->nElements = nElements;
+ }
+ }
+ return pNew;
+}
+
+//------------------------------------------------------------------------------
+static inline bool idefaultConstructElements(
+ uno_Sequence ** ppSeq,
+ typelib_TypeDescriptionReference * pElementType,
+ sal_Int32 nStartIndex, sal_Int32 nStopIndex,
+ sal_Int32 nAlloc = -1 ) // >= 0 means (re)alloc memory for nAlloc elements
+{
+ uno_Sequence * pSeq = *ppSeq;
+ switch (pElementType->eTypeClass)
+ {
+ case typelib_TypeClass_CHAR:
+ if (nAlloc >= 0)
+ pSeq = reallocSeq( pSeq, sizeof(sal_Unicode), nAlloc );
+ if (pSeq != 0)
+ {
+ ::rtl_zeroMemory(
+ pSeq->elements + (sizeof(sal_Unicode) * nStartIndex),
+ sizeof(sal_Unicode) * (nStopIndex - nStartIndex) );
+ }
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ if (nAlloc >= 0)
+ pSeq = reallocSeq( pSeq, sizeof(sal_Bool), nAlloc );
+ if (pSeq != 0)
+ {
+ ::rtl_zeroMemory(
+ pSeq->elements + (sizeof(sal_Bool) * nStartIndex),
+ sizeof(sal_Bool) * (nStopIndex - nStartIndex) );
+ }
+ break;
+ case typelib_TypeClass_BYTE:
+ if (nAlloc >= 0)
+ pSeq = reallocSeq( pSeq, sizeof(sal_Int8), nAlloc );
+ if (pSeq != 0)
+ {
+ ::rtl_zeroMemory(
+ pSeq->elements + (sizeof(sal_Int8) * nStartIndex),
+ sizeof(sal_Int8) * (nStopIndex - nStartIndex) );
+ }
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ if (nAlloc >= 0)
+ pSeq = reallocSeq( pSeq, sizeof(sal_Int16), nAlloc );
+ if (pSeq != 0)
+ {
+ ::rtl_zeroMemory(
+ pSeq->elements + (sizeof(sal_Int16) * nStartIndex),
+ sizeof(sal_Int16) * (nStopIndex - nStartIndex) );
+ }
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ if (nAlloc >= 0)
+ pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
+ if (pSeq != 0)
+ {
+ ::rtl_zeroMemory(
+ pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
+ sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
+ }
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ if (nAlloc >= 0)
+ pSeq = reallocSeq( pSeq, sizeof(sal_Int64), nAlloc );
+ if (pSeq != 0)
+ {
+ ::rtl_zeroMemory(
+ pSeq->elements + (sizeof(sal_Int64) * nStartIndex),
+ sizeof(sal_Int64) * (nStopIndex - nStartIndex) );
+ }
+ break;
+ case typelib_TypeClass_FLOAT:
+ {
+ if (nAlloc >= 0)
+ pSeq = reallocSeq( pSeq, sizeof(float), nAlloc );
+ if (pSeq != 0)
+ {
+ float * pElements = (float *) pSeq->elements;
+ for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
+ {
+ pElements[nPos] = 0.0;
+ }
+ }
+ break;
+ }
+ case typelib_TypeClass_DOUBLE:
+ {
+ if (nAlloc >= 0)
+ pSeq = reallocSeq( pSeq, sizeof(double), nAlloc );
+ if (pSeq != 0)
+ {
+ double * pElements = (double *) pSeq->elements;
+ for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
+ {
+ pElements[nPos] = 0.0;
+ }
+ }
+ break;
+ }
+ case typelib_TypeClass_STRING:
+ {
+ if (nAlloc >= 0)
+ pSeq = reallocSeq( pSeq, sizeof(rtl_uString *), nAlloc );
+ if (pSeq != 0)
+ {
+ rtl_uString ** pElements = (rtl_uString **) pSeq->elements;
+ for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
+ {
+ pElements[nPos] = 0;
+ rtl_uString_new( &pElements[nPos] );
+ }
+ }
+ break;
+ }
+ case typelib_TypeClass_TYPE:
+ {
+ if (nAlloc >= 0)
+ {
+ pSeq = reallocSeq(
+ pSeq, sizeof(typelib_TypeDescriptionReference *), nAlloc );
+ }
+ if (pSeq != 0)
+ {
+ typelib_TypeDescriptionReference ** pElements =
+ (typelib_TypeDescriptionReference **) pSeq->elements;
+ for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
+ {
+ pElements[nPos] = _getVoidType();
+ }
+ }
+ break;
+ }
+ case typelib_TypeClass_ANY:
+ {
+ if (nAlloc >= 0)
+ pSeq = reallocSeq( pSeq, sizeof(uno_Any), nAlloc );
+ if (pSeq != 0)
+ {
+ uno_Any * pElements = (uno_Any *) pSeq->elements;
+ for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
+ {
+ CONSTRUCT_EMPTY_ANY( &pElements[nPos] );
+ }
+ }
+ break;
+ }
+ case typelib_TypeClass_ENUM:
+ {
+ if (nAlloc >= 0)
+ pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
+ if (pSeq != 0)
+ {
+ typelib_TypeDescription * pElementTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
+ sal_Int32 eEnum =
+ ((typelib_EnumTypeDescription *)
+ pElementTypeDescr)->nDefaultEnumValue;
+ TYPELIB_DANGER_RELEASE( pElementTypeDescr );
+
+ sal_Int32 * pElements = (sal_Int32 *) pSeq->elements;
+ for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
+ {
+ pElements[nPos] = eEnum;
+ }
+ }
+ break;
+ }
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ typelib_TypeDescription * pElementTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
+ sal_Int32 nElementSize = pElementTypeDescr->nSize;
+
+ if (nAlloc >= 0)
+ pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
+ if (pSeq != 0)
+ {
+ char * pElements = pSeq->elements;
+ for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
+ {
+ _defaultConstructStruct(
+ pElements + (nElementSize * nPos),
+ (typelib_CompoundTypeDescription *)pElementTypeDescr );
+ }
+ }
+
+ TYPELIB_DANGER_RELEASE( pElementTypeDescr );
+ break;
+ }
+ case typelib_TypeClass_ARRAY:
+ {
+ typelib_TypeDescription * pElementTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
+ sal_Int32 nElementSize = pElementTypeDescr->nSize;
+
+ if (nAlloc >= 0)
+ pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
+ if (pSeq != 0)
+ {
+ char * pElements = pSeq->elements;
+ for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
+ {
+ _defaultConstructArray(
+ pElements + (nElementSize * nPos),
+ (typelib_ArrayTypeDescription *)pElementTypeDescr );
+ }
+ }
+
+ TYPELIB_DANGER_RELEASE( pElementTypeDescr );
+ break;
+ }
+ case typelib_TypeClass_UNION:
+ {
+ typelib_TypeDescription * pElementTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
+ sal_Int32 nElementSize = pElementTypeDescr->nSize;
+
+ if (nAlloc >= 0)
+ pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
+ if (pSeq != 0)
+ {
+ sal_Int32 nValueOffset =
+ ((typelib_UnionTypeDescription *)
+ pElementTypeDescr)->nValueOffset;
+ sal_Int64 nDefaultDiscr =
+ ((typelib_UnionTypeDescription *)
+ pElementTypeDescr)->nDefaultDiscriminant;
+
+ typelib_TypeDescription * pDefaultTypeDescr = 0;
+ TYPELIB_DANGER_GET(
+ &pDefaultTypeDescr,
+ ((typelib_UnionTypeDescription *)
+ pElementTypeDescr)->pDefaultTypeRef );
+
+ char * pElements = pSeq->elements;
+ for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
+ {
+ char * pMem = pElements + (nElementSize * nPos);
+ ::uno_constructData(
+ (char *)pMem + nValueOffset, pDefaultTypeDescr );
+ *(sal_Int64 *)pMem = nDefaultDiscr;
+ }
+ TYPELIB_DANGER_RELEASE( pDefaultTypeDescr );
+ }
+
+ TYPELIB_DANGER_RELEASE( pElementTypeDescr );
+ break;
+ }
+ case typelib_TypeClass_SEQUENCE:
+ {
+ if (nAlloc >= 0)
+ pSeq = reallocSeq( pSeq, sizeof(uno_Sequence *), nAlloc );
+ if (pSeq != 0)
+ {
+ uno_Sequence ** pElements =
+ (uno_Sequence **) pSeq->elements;
+ for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
+ {
+ pElements[nPos] = createEmptySequence();
+ }
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE: // either C++ or C-UNO interface
+ if (nAlloc >= 0)
+ pSeq = reallocSeq( pSeq, sizeof(void *), nAlloc );
+ if (pSeq != 0)
+ {
+ ::rtl_zeroMemory(
+ pSeq->elements + (sizeof(void *) * nStartIndex),
+ sizeof(void *) * (nStopIndex - nStartIndex) );
+ }
+ break;
+ default:
+ OSL_ENSURE( 0, "### unexpected element type!" );
+ pSeq = 0;
+ break;
+ }
+
+ if (pSeq == 0)
+ {
+ OSL_ASSERT( nAlloc >= 0 ); // must have been an allocation failure
+ return false;
+ }
+ else
+ {
+ *ppSeq = pSeq;
+ return true;
+ }
+}
+
+//------------------------------------------------------------------------------
+static inline bool icopyConstructFromElements(
+ uno_Sequence ** ppSeq, void * pSourceElements,
+ typelib_TypeDescriptionReference * pElementType,
+ sal_Int32 nStartIndex, sal_Int32 nStopIndex,
+ uno_AcquireFunc acquire,
+ sal_Int32 nAlloc = -1 ) // >= 0 means (re)alloc memory for nAlloc elements
+{
+ uno_Sequence * pSeq = *ppSeq;
+ switch (pElementType->eTypeClass)
+ {
+ case typelib_TypeClass_CHAR:
+ if (nAlloc >= 0)
+ pSeq = reallocSeq( pSeq, sizeof(sal_Unicode), nAlloc );
+ if (pSeq != 0)
+ {
+ ::rtl_copyMemory(
+ pSeq->elements + (sizeof(sal_Unicode) * nStartIndex),
+ (char *)pSourceElements + (sizeof(sal_Unicode) * nStartIndex),
+ sizeof(sal_Unicode) * (nStopIndex - nStartIndex) );
+ }
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ if (nAlloc >= 0)
+ pSeq = reallocSeq( pSeq, sizeof(sal_Bool), nAlloc );
+ if (pSeq != 0)
+ {
+ ::rtl_copyMemory(
+ pSeq->elements + (sizeof(sal_Bool) * nStartIndex),
+ (char *)pSourceElements + (sizeof(sal_Bool) * nStartIndex),
+ sizeof(sal_Bool) * (nStopIndex - nStartIndex) );
+ }
+ break;
+ case typelib_TypeClass_BYTE:
+ if (nAlloc >= 0)
+ pSeq = reallocSeq( pSeq, sizeof(sal_Int8), nAlloc );
+ if (pSeq != 0)
+ {
+ ::rtl_copyMemory(
+ pSeq->elements + (sizeof(sal_Int8) * nStartIndex),
+ (char *)pSourceElements + (sizeof(sal_Int8) * nStartIndex),
+ sizeof(sal_Int8) * (nStopIndex - nStartIndex) );
+ }
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ if (nAlloc >= 0)
+ pSeq = reallocSeq( pSeq, sizeof(sal_Int16), nAlloc );
+ if (pSeq != 0)
+ {
+ ::rtl_copyMemory(
+ pSeq->elements + (sizeof(sal_Int16) * nStartIndex),
+ (char *)pSourceElements + (sizeof(sal_Int16) * nStartIndex),
+ sizeof(sal_Int16) * (nStopIndex - nStartIndex) );
+ }
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ if (nAlloc >= 0)
+ pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
+ if (pSeq != 0)
+ {
+ ::rtl_copyMemory(
+ pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
+ (char *)pSourceElements + (sizeof(sal_Int32) * nStartIndex),
+ sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
+ }
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ if (nAlloc >= 0)
+ pSeq = reallocSeq( pSeq, sizeof(sal_Int64), nAlloc );
+ if (pSeq != 0)
+ {
+ ::rtl_copyMemory(
+ pSeq->elements + (sizeof(sal_Int64) * nStartIndex),
+ (char *)pSourceElements + (sizeof(sal_Int64) * nStartIndex),
+ sizeof(sal_Int64) * (nStopIndex - nStartIndex) );
+ }
+ break;
+ case typelib_TypeClass_FLOAT:
+ if (nAlloc >= 0)
+ pSeq = reallocSeq( pSeq, sizeof(float), nAlloc );
+ if (pSeq != 0)
+ {
+ ::rtl_copyMemory(
+ pSeq->elements + (sizeof(float) * nStartIndex),
+ (char *)pSourceElements + (sizeof(float) * nStartIndex),
+ sizeof(float) * (nStopIndex - nStartIndex) );
+ }
+ break;
+ case typelib_TypeClass_DOUBLE:
+ if (nAlloc >= 0)
+ pSeq = reallocSeq( pSeq, sizeof(double), nAlloc );
+ if (pSeq != 0)
+ {
+ ::rtl_copyMemory(
+ pSeq->elements + (sizeof(double) * nStartIndex),
+ (char *)pSourceElements + (sizeof(double) * nStartIndex),
+ sizeof(double) * (nStopIndex - nStartIndex) );
+ }
+ break;
+ case typelib_TypeClass_ENUM:
+ if (nAlloc >= 0)
+ pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
+ if (pSeq != 0)
+ {
+ ::rtl_copyMemory(
+ pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
+ (char *)pSourceElements + (sizeof(sal_Int32) * nStartIndex),
+ sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
+ }
+ break;
+ case typelib_TypeClass_STRING:
+ {
+ if (nAlloc >= 0)
+ pSeq = reallocSeq( pSeq, sizeof(rtl_uString *), nAlloc );
+ if (pSeq != 0)
+ {
+ rtl_uString ** pDestElements = (rtl_uString **) pSeq->elements;
+ for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
+ {
+ ::rtl_uString_acquire(
+ ((rtl_uString **)pSourceElements)[nPos] );
+ pDestElements[nPos] = ((rtl_uString **)pSourceElements)[nPos];
+ }
+ }
+ break;
+ }
+ case typelib_TypeClass_TYPE:
+ {
+ if (nAlloc >= 0)
+ {
+ pSeq = reallocSeq(
+ pSeq, sizeof(typelib_TypeDescriptionReference *), nAlloc );
+ }
+ if (pSeq != 0)
+ {
+ typelib_TypeDescriptionReference ** pDestElements =
+ (typelib_TypeDescriptionReference **) pSeq->elements;
+ for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
+ {
+ TYPE_ACQUIRE(
+ ((typelib_TypeDescriptionReference **)
+ pSourceElements)[nPos] );
+ pDestElements[nPos] =
+ ((typelib_TypeDescriptionReference **)
+ pSourceElements)[nPos];
+ }
+ }
+ break;
+ }
+ case typelib_TypeClass_ANY:
+ {
+ if (nAlloc >= 0)
+ pSeq = reallocSeq( pSeq, sizeof(uno_Any), nAlloc );
+ if (pSeq != 0)
+ {
+ uno_Any * pDestElements = (uno_Any *) pSeq->elements;
+ for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
+ {
+ uno_Any * pSource = (uno_Any *)pSourceElements + nPos;
+ _copyConstructAny(
+ &pDestElements[nPos],
+ pSource->pData,
+ pSource->pType, 0,
+ acquire, 0 );
+ }
+ }
+ break;
+ }
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ typelib_TypeDescription * pElementTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
+ sal_Int32 nElementSize = pElementTypeDescr->nSize;
+
+ if (nAlloc >= 0)
+ pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
+ if (pSeq != 0)
+ {
+ char * pDestElements = pSeq->elements;
+
+ typelib_CompoundTypeDescription * pTypeDescr =
+ (typelib_CompoundTypeDescription *)pElementTypeDescr;
+ for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
+ {
+ char * pDest =
+ pDestElements + (nElementSize * nPos);
+ char * pSource =
+ (char *)pSourceElements + (nElementSize * nPos);
+
+ if (pTypeDescr->pBaseTypeDescription)
+ {
+ // copy base value
+ _copyConstructStruct(
+ pDest, pSource,
+ pTypeDescr->pBaseTypeDescription, acquire, 0 );
+ }
+
+ // then copy members
+ typelib_TypeDescriptionReference ** ppTypeRefs =
+ pTypeDescr->ppTypeRefs;
+ sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets;
+ sal_Int32 nDescr = pTypeDescr->nMembers;
+
+ while (nDescr--)
+ {
+ ::uno_type_copyData(
+ pDest + pMemberOffsets[nDescr],
+ pSource + pMemberOffsets[nDescr],
+ ppTypeRefs[nDescr], acquire );
+ }
+ }
+ }
+
+ TYPELIB_DANGER_RELEASE( pElementTypeDescr );
+ break;
+ }
+ case typelib_TypeClass_UNION:
+ {
+ typelib_TypeDescription * pElementTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
+ sal_Int32 nElementSize = pElementTypeDescr->nSize;
+
+ if (nAlloc >= 0)
+ pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
+ if (pSeq != 0)
+ {
+ char * pDestElements = pSeq->elements;
+
+ sal_Int32 nValueOffset =
+ ((typelib_UnionTypeDescription *)
+ pElementTypeDescr)->nValueOffset;
+ for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
+ {
+ char * pDest =
+ pDestElements + (nElementSize * nPos);
+ char * pSource =
+ (char *)pSourceElements + (nElementSize * nPos);
+
+ typelib_TypeDescriptionReference * pSetType = _unionGetSetType(
+ pSource, pElementTypeDescr );
+ ::uno_type_copyData(
+ pDest + nValueOffset,
+ pSource + nValueOffset,
+ pSetType, acquire );
+ *(sal_Int64 *)pDest = *(sal_Int64 *)pSource;
+ typelib_typedescriptionreference_release( pSetType );
+ }
+ }
+
+ TYPELIB_DANGER_RELEASE( pElementTypeDescr );
+ break;
+ }
+ case typelib_TypeClass_SEQUENCE: // sequence of sequence
+ {
+ if (nAlloc >= 0)
+ pSeq = reallocSeq( pSeq, sizeof(uno_Sequence *), nAlloc );
+ if (pSeq != 0)
+ {
+ typelib_TypeDescription * pElementTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
+ typelib_TypeDescriptionReference * pSeqElementType =
+ ((typelib_IndirectTypeDescription *) pElementTypeDescr)->pType;
+ uno_Sequence ** pDestElements = (uno_Sequence **) pSeq->elements;
+ for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
+ {
+ uno_Sequence * pNew = icopyConstructSequence(
+ ((uno_Sequence **) pSourceElements)[nPos],
+ pSeqElementType, acquire, 0 );
+ OSL_ASSERT( pNew != 0 );
+ // ought never be a memory allocation problem,
+ // because of reference counted sequence handles
+ pDestElements[ nPos ] = pNew;
+ }
+ TYPELIB_DANGER_RELEASE( pElementTypeDescr );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE:
+ {
+ if (nAlloc >= 0)
+ pSeq = reallocSeq( pSeq, sizeof(void *), nAlloc );
+ if (pSeq != 0)
+ {
+ void ** pDestElements = (void **) pSeq->elements;
+ for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
+ {
+ _acquire( pDestElements[nPos] =
+ ((void **)pSourceElements)[nPos], acquire );
+ }
+ }
+ break;
+ }
+ default:
+ OSL_ENSURE( 0, "### unexpected element type!" );
+ pSeq = 0;
+ break;
+ }
+
+ if (pSeq == 0)
+ {
+ OSL_ASSERT( nAlloc >= 0 ); // must have been an allocation failure
+ return false;
+ }
+ else
+ {
+ *ppSeq = pSeq;
+ return true;
+ }
+}
+
+//------------------------------------------------------------------------------
+static inline bool ireallocSequence(
+ uno_Sequence ** ppSequence,
+ typelib_TypeDescriptionReference * pElementType,
+ sal_Int32 nSize,
+ uno_AcquireFunc acquire, uno_ReleaseFunc release )
+{
+ bool ret = true;
+ uno_Sequence * pSeq = *ppSequence;
+ sal_Int32 nElements = pSeq->nElements;
+
+ if (pSeq->nRefCount > 1 ||
+ // not mem-copyable elements?
+ typelib_TypeClass_ANY == pElementType->eTypeClass ||
+ typelib_TypeClass_STRUCT == pElementType->eTypeClass ||
+ typelib_TypeClass_EXCEPTION == pElementType->eTypeClass)
+ {
+ // split sequence and construct new one from scratch
+ uno_Sequence * pNew = 0;
+
+ sal_Int32 nRest = nSize - nElements;
+ sal_Int32 nCopy = (nRest > 0 ? nElements : nSize);
+
+ if (nCopy >= 0)
+ {
+ ret = icopyConstructFromElements(
+ &pNew, pSeq->elements, pElementType,
+ 0, nCopy, acquire,
+ nSize ); // alloc to nSize
+ }
+ if (ret && nRest > 0)
+ {
+ ret = idefaultConstructElements(
+ &pNew, pElementType,
+ nCopy, nSize,
+ nCopy >= 0 ? -1 /* no mem allocation */ : nSize );
+ }
+
+ if (ret)
+ {
+ // destruct sequence
+ if (osl_decrementInterlockedCount( &pSeq->nRefCount ) == 0)
+ {
+ if (nElements > 0)
+ {
+ idestructElements(
+ pSeq->elements, pElementType,
+ 0, nElements, release );
+ }
+ rtl_freeMemory( pSeq );
+ }
+ *ppSequence = pNew;
+ }
+ }
+ else
+ {
+ OSL_ASSERT( pSeq->nRefCount == 1 );
+ if (nSize > nElements) // default construct the rest
+ {
+ ret = idefaultConstructElements(
+ ppSequence, pElementType,
+ nElements, nSize,
+ nSize ); // realloc to nSize
+ }
+ else // or destruct the rest and realloc mem
+ {
+ sal_Int32 nElementSize = idestructElements(
+ pSeq->elements, pElementType,
+ nSize, nElements, release );
+ // warning: it is assumed that the following will never fail,
+ // else this leads to a sequence null handle
+ *ppSequence = reallocSeq( pSeq, nElementSize, nSize );
+ OSL_ASSERT( *ppSequence != 0 );
+ ret = (*ppSequence != 0);
+ }
+ }
+
+ return ret;
+}
+
+}
+
+extern "C"
+{
+
+//##############################################################################
+sal_Bool SAL_CALL uno_type_sequence_construct(
+ uno_Sequence ** ppSequence, typelib_TypeDescriptionReference * pType,
+ void * pElements, sal_Int32 len,
+ uno_AcquireFunc acquire )
+ SAL_THROW_EXTERN_C()
+{
+ bool ret;
+ if (len)
+ {
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pType );
+
+ typelib_TypeDescriptionReference * pElementType =
+ ((typelib_IndirectTypeDescription *)pTypeDescr)->pType;
+
+ *ppSequence = 0;
+ if (pElements == 0)
+ {
+ ret = idefaultConstructElements(
+ ppSequence, pElementType,
+ 0, len,
+ len ); // alloc to len
+ }
+ else
+ {
+ ret = icopyConstructFromElements(
+ ppSequence, pElements, pElementType,
+ 0, len, acquire,
+ len ); // alloc to len
+ }
+
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ }
+ else
+ {
+ *ppSequence = createEmptySequence();
+ ret = true;
+ }
+
+ OSL_ASSERT( (*ppSequence != 0) == ret );
+ return ret;
+}
+
+//##############################################################################
+sal_Bool SAL_CALL uno_sequence_construct(
+ uno_Sequence ** ppSequence, typelib_TypeDescription * pTypeDescr,
+ void * pElements, sal_Int32 len,
+ uno_AcquireFunc acquire )
+ SAL_THROW_EXTERN_C()
+{
+ bool ret;
+ if (len > 0)
+ {
+ typelib_TypeDescriptionReference * pElementType =
+ ((typelib_IndirectTypeDescription *)pTypeDescr)->pType;
+
+ *ppSequence = 0;
+ if (pElements == 0)
+ {
+ ret = idefaultConstructElements(
+ ppSequence, pElementType,
+ 0, len,
+ len ); // alloc to len
+ }
+ else
+ {
+ ret = icopyConstructFromElements(
+ ppSequence, pElements, pElementType,
+ 0, len, acquire,
+ len ); // alloc to len
+ }
+ }
+ else
+ {
+ *ppSequence = createEmptySequence();
+ ret = true;
+ }
+
+ OSL_ASSERT( (*ppSequence != 0) == ret );
+ return ret;
+}
+
+//##############################################################################
+sal_Bool SAL_CALL uno_type_sequence_realloc(
+ uno_Sequence ** ppSequence, typelib_TypeDescriptionReference * pType,
+ sal_Int32 nSize, uno_AcquireFunc acquire, uno_ReleaseFunc release )
+ SAL_THROW_EXTERN_C()
+{
+ OSL_ENSURE( ppSequence, "### null ptr!" );
+ OSL_ENSURE( nSize >= 0, "### new size must be at least 0!" );
+
+ bool ret = true;
+ if (nSize != (*ppSequence)->nElements)
+ {
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pType );
+ ret = ireallocSequence(
+ ppSequence, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
+ nSize, acquire, release );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ }
+ return ret;
+}
+
+//##############################################################################
+sal_Bool SAL_CALL uno_sequence_realloc(
+ uno_Sequence ** ppSequence, typelib_TypeDescription * pTypeDescr,
+ sal_Int32 nSize, uno_AcquireFunc acquire, uno_ReleaseFunc release )
+ SAL_THROW_EXTERN_C()
+{
+ OSL_ENSURE( ppSequence, "### null ptr!" );
+ OSL_ENSURE( nSize >= 0, "### new size must be at least 0!" );
+
+ bool ret = true;
+ if (nSize != (*ppSequence)->nElements)
+ {
+ ret = ireallocSequence(
+ ppSequence, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
+ nSize, acquire, release );
+ }
+ return ret;
+}
+
+//##############################################################################
+sal_Bool SAL_CALL uno_type_sequence_reference2One(
+ uno_Sequence ** ppSequence,
+ typelib_TypeDescriptionReference * pType,
+ uno_AcquireFunc acquire, uno_ReleaseFunc release )
+ SAL_THROW_EXTERN_C()
+{
+ OSL_ENSURE( ppSequence, "### null ptr!" );
+ bool ret = true;
+ uno_Sequence * pSequence = *ppSequence;
+ if (pSequence->nRefCount > 1)
+ {
+ uno_Sequence * pNew = 0;
+ if (pSequence->nElements > 0)
+ {
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pType );
+
+ ret = icopyConstructFromElements(
+ &pNew, pSequence->elements,
+ ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
+ 0, pSequence->nElements, acquire,
+ pSequence->nElements ); // alloc nElements
+ if (ret)
+ {
+ idestructSequence( *ppSequence, pType, pTypeDescr, release );
+ *ppSequence = pNew;
+ }
+
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ }
+ else
+ {
+ pNew = allocSeq( 0, 0 );
+ ret = (pNew != 0);
+ if (ret)
+ {
+ // easy destruction of empty sequence:
+ if (osl_decrementInterlockedCount( &pSequence->nRefCount ) == 0)
+ rtl_freeMemory( pSequence );
+ *ppSequence = pNew;
+ }
+ }
+ }
+ return ret;
+}
+
+//##############################################################################
+sal_Bool SAL_CALL uno_sequence_reference2One(
+ uno_Sequence ** ppSequence,
+ typelib_TypeDescription * pTypeDescr,
+ uno_AcquireFunc acquire, uno_ReleaseFunc release )
+ SAL_THROW_EXTERN_C()
+{
+ OSL_ENSURE( ppSequence, "### null ptr!" );
+ bool ret = true;
+ uno_Sequence * pSequence = *ppSequence;
+ if (pSequence->nRefCount > 1)
+ {
+ uno_Sequence * pNew = 0;
+ if (pSequence->nElements > 0)
+ {
+ ret = icopyConstructFromElements(
+ &pNew, pSequence->elements,
+ ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
+ 0, pSequence->nElements, acquire,
+ pSequence->nElements ); // alloc nElements
+ if (ret)
+ {
+ idestructSequence(
+ pSequence, pTypeDescr->pWeakRef, pTypeDescr, release );
+ *ppSequence = pNew;
+ }
+ }
+ else
+ {
+ pNew = allocSeq( 0, 0 );
+ ret = (pNew != 0);
+ if (ret)
+ {
+ // easy destruction of empty sequence:
+ if (osl_decrementInterlockedCount( &pSequence->nRefCount ) == 0)
+ rtl_freeMemory( pSequence );
+ *ppSequence = pNew;
+ }
+ }
+
+ }
+ return ret;
+}
+
+//##############################################################################
+void SAL_CALL uno_sequence_assign(
+ uno_Sequence ** ppDest,
+ uno_Sequence * pSource,
+ typelib_TypeDescription * pTypeDescr,
+ uno_ReleaseFunc release )
+ SAL_THROW_EXTERN_C()
+{
+ if (*ppDest != pSource)
+ {
+ ::osl_incrementInterlockedCount( &pSource->nRefCount );
+ idestructSequence( *ppDest, pTypeDescr->pWeakRef, pTypeDescr, release );
+ *ppDest = pSource;
+ }
+}
+
+//##############################################################################
+void SAL_CALL uno_type_sequence_assign(
+ uno_Sequence ** ppDest,
+ uno_Sequence * pSource,
+ typelib_TypeDescriptionReference * pType,
+ uno_ReleaseFunc release )
+ SAL_THROW_EXTERN_C()
+{
+ if (*ppDest != pSource)
+ {
+ ::osl_incrementInterlockedCount( &pSource->nRefCount );
+ idestructSequence( *ppDest, pType, 0, release );
+ *ppDest = pSource;
+ }
+}
+
+}