summaryrefslogtreecommitdiff
path: root/cppu/source
diff options
context:
space:
mode:
Diffstat (limited to 'cppu/source')
-rw-r--r--cppu/source/AffineBridge/AffineBridge.cxx364
-rw-r--r--cppu/source/AffineBridge/makefile.mk44
-rwxr-xr-xcppu/source/LogBridge/LogBridge.cxx277
-rwxr-xr-xcppu/source/LogBridge/makefile.mk44
-rw-r--r--cppu/source/UnsafeBridge/UnsafeBridge.cxx163
-rw-r--r--cppu/source/UnsafeBridge/makefile.mk44
-rw-r--r--cppu/source/cppu/cppu_opt.cxx81
-rw-r--r--cppu/source/cppu/makefile.mk45
-rw-r--r--cppu/source/helper/purpenv/Proxy.hxx89
-rw-r--r--cppu/source/helper/purpenv/export.mk19
-rw-r--r--cppu/source/helper/purpenv/helper_purpenv_Environment.cxx537
-rw-r--r--cppu/source/helper/purpenv/helper_purpenv_Mapping.cxx233
-rw-r--r--cppu/source/helper/purpenv/helper_purpenv_Proxy.cxx530
-rw-r--r--cppu/source/helper/purpenv/makefile.mk46
-rw-r--r--cppu/source/threadpool/current.cxx299
-rw-r--r--cppu/source/threadpool/current.hxx48
-rw-r--r--cppu/source/threadpool/jobqueue.cxx191
-rw-r--r--cppu/source/threadpool/jobqueue.hxx79
-rw-r--r--cppu/source/threadpool/makefile.mk49
-rw-r--r--cppu/source/threadpool/thread.cxx217
-rw-r--r--cppu/source/threadpool/thread.hxx88
-rw-r--r--cppu/source/threadpool/threadident.cxx135
-rw-r--r--cppu/source/threadpool/threadpool.cxx502
-rw-r--r--cppu/source/threadpool/threadpool.hxx129
-rw-r--r--cppu/source/typelib/makefile.mk45
-rw-r--r--cppu/source/typelib/static_types.cxx673
-rw-r--r--cppu/source/typelib/typelib.cxx2671
-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
49 files changed, 15611 insertions, 0 deletions
diff --git a/cppu/source/AffineBridge/AffineBridge.cxx b/cppu/source/AffineBridge/AffineBridge.cxx
new file mode 100644
index 000000000000..59f8213274a6
--- /dev/null
+++ b/cppu/source/AffineBridge/AffineBridge.cxx
@@ -0,0 +1,364 @@
+/*************************************************************************
+ *
+ * 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 "osl/thread.hxx"
+#include "osl/conditn.hxx"
+#include "osl/mutex.hxx"
+
+#include "cppu/helper/purpenv/Environment.hxx"
+#include "cppu/helper/purpenv/Mapping.hxx"
+
+
+#ifdef debug
+# define LOG_LIFECYCLE_AffineBridge
+#endif
+
+#ifdef LOG_LIFECYCLE_AffineBridge
+# include <iostream>
+# define LOG_LIFECYCLE_AffineBridge_emit(x) x
+
+#else
+# define LOG_LIFECYCLE_AffineBridge_emit(x)
+
+#endif
+
+class InnerThread;
+class OuterThread;
+
+class SAL_DLLPRIVATE AffineBridge : public cppu::Enterable
+{
+public:
+ enum Msg
+ {
+ CB_DONE,
+ CB_FPOINTER
+ };
+
+ Msg m_message;
+ uno_EnvCallee * m_pCallee;
+ va_list * m_pParam;
+
+ osl::Mutex m_innerMutex;
+ oslThreadIdentifier m_innerThreadId;
+ InnerThread * m_pInnerThread;
+ osl::Condition m_innerCondition;
+ sal_Int32 m_enterCount;
+
+ osl::Mutex m_outerMutex;
+ oslThreadIdentifier m_outerThreadId;
+ osl::Condition m_outerCondition;
+ OuterThread * m_pOuterThread;
+
+ explicit AffineBridge(void);
+ virtual ~AffineBridge(void);
+
+ virtual void v_callInto_v(uno_EnvCallee * pCallee, va_list * pParam);
+ virtual void v_callOut_v (uno_EnvCallee * pCallee, va_list * pParam);
+
+ virtual void v_enter(void);
+ virtual void v_leave(void);
+
+ virtual int v_isValid(rtl::OUString * pReason);
+
+ void innerDispatch(void);
+ void outerDispatch(int loop);
+};
+
+class SAL_DLLPRIVATE InnerThread : public osl::Thread
+{
+ virtual void SAL_CALL run(void);
+
+ AffineBridge * m_pAffineBridge;
+
+public:
+ InnerThread(AffineBridge * threadEnvironment)
+ : m_pAffineBridge(threadEnvironment)
+ {
+ create();
+ }
+};
+
+void InnerThread::run(void)
+{
+ m_pAffineBridge->enter();
+ m_pAffineBridge->innerDispatch();
+ m_pAffineBridge->leave();
+}
+
+class SAL_DLLPRIVATE OuterThread : public osl::Thread
+{
+ virtual void SAL_CALL run(void);
+
+ AffineBridge * m_pAffineBridge;
+
+public:
+ OuterThread(AffineBridge * threadEnvironment);
+};
+
+OuterThread::OuterThread(AffineBridge * threadEnvironment)
+ : m_pAffineBridge(threadEnvironment)
+{
+ create();
+}
+
+void OuterThread::run(void)
+{
+ osl::MutexGuard guard(m_pAffineBridge->m_outerMutex);
+
+ m_pAffineBridge->m_outerThreadId = getIdentifier();
+ m_pAffineBridge->outerDispatch(0);
+ m_pAffineBridge->m_outerThreadId = 0;
+
+ m_pAffineBridge->m_pOuterThread = NULL;
+ m_pAffineBridge = NULL;
+}
+
+
+AffineBridge::AffineBridge(void)
+ : m_innerThreadId(0),
+ m_pInnerThread (NULL),
+ m_enterCount (0),
+ m_outerThreadId(0),
+ m_pOuterThread (NULL)
+{
+ LOG_LIFECYCLE_AffineBridge_emit(fprintf(stderr, "LIFE: %s -> %p\n", "AffineBridge::AffineBridge(uno_Environment * pEnv)", this));
+}
+
+AffineBridge::~AffineBridge(void)
+{
+ LOG_LIFECYCLE_AffineBridge_emit(fprintf(stderr, "LIFE: %s -> %p\n", "AffineBridge::~AffineBridge(void)", this));
+
+ if (m_pInnerThread && osl_getThreadIdentifier(NULL) != m_innerThreadId)
+ {
+ m_message = CB_DONE;
+ m_innerCondition.set();
+
+ m_pInnerThread->join();
+ }
+
+ delete m_pInnerThread;
+
+ if (m_pOuterThread)
+ {
+ m_pOuterThread->join();
+ delete m_pOuterThread;
+ }
+}
+
+
+void AffineBridge::outerDispatch(int loop)
+{
+ OSL_ASSERT(m_outerThreadId == osl_getThreadIdentifier(NULL));
+ OSL_ASSERT(m_innerThreadId != m_outerThreadId);
+
+ Msg mm;
+
+ do
+ {
+ // FIXME: created outer thread must not wait
+ // in case of no message
+ // note: no message can happen in case newly created
+ // outer thread acquire outerMutex after a real outer
+ // thread enters outerDispatch!
+ m_outerCondition.wait();
+ m_outerCondition.reset();
+
+ mm = m_message;
+
+ switch(mm)
+ {
+ case CB_DONE:
+ break;
+
+ case CB_FPOINTER:
+ {
+ m_pCallee(m_pParam);
+
+ m_message = CB_DONE;
+ m_innerCondition.set();
+ break;
+ }
+ default:
+ abort();
+ }
+ }
+ while(mm != CB_DONE && loop);
+}
+
+void AffineBridge::innerDispatch(void)
+{
+ OSL_ASSERT(m_innerThreadId == osl_getThreadIdentifier(NULL));
+ OSL_ASSERT(m_innerThreadId != m_outerThreadId);
+
+ Msg mm;
+
+ do
+ {
+ m_innerCondition.wait();
+ m_innerCondition.reset();
+
+ mm = m_message;
+
+ switch(mm)
+ {
+ case CB_DONE:
+ break;
+
+ case CB_FPOINTER:
+ {
+ m_pCallee(m_pParam);
+
+ m_message = CB_DONE;
+ m_outerCondition.set();
+ break;
+ }
+ default:
+ abort();
+ }
+ }
+ while(mm != CB_DONE);
+}
+
+void AffineBridge::v_callInto_v(uno_EnvCallee * pCallee, va_list * pParam)
+{
+ osl::MutexGuard guard(m_outerMutex); // only one thread at a time can call into
+
+ if (m_innerThreadId == 0) // no inner thread yet
+ {
+ m_pInnerThread = new InnerThread(this);
+ m_pInnerThread->resume();
+ }
+
+ bool resetId = false;
+ if (!m_outerThreadId)
+ {
+ m_outerThreadId = osl_getThreadIdentifier(NULL);
+ resetId = true;
+ }
+
+ m_message = CB_FPOINTER;
+ m_pCallee = pCallee;
+ m_pParam = pParam;
+ m_innerCondition.set();
+
+ outerDispatch(1);
+
+ if (resetId)
+ m_outerThreadId = 0;
+}
+
+void AffineBridge::v_callOut_v(uno_EnvCallee * pCallee, va_list * pParam)
+{
+ OSL_ASSERT(m_innerThreadId);
+
+ osl::MutexGuard guard(m_innerMutex);
+
+ if (m_outerThreadId == 0) // no outer thread yet
+ {
+ osl::MutexGuard guard_m_outerMutex(m_outerMutex);
+
+ if (m_outerThreadId == 0)
+ {
+ if (m_pOuterThread)
+ {
+ m_pOuterThread->join();
+ delete m_pOuterThread;
+ }
+
+ m_pOuterThread = new OuterThread(this);
+ }
+ }
+
+ m_message = CB_FPOINTER;
+ m_pCallee = pCallee;
+ m_pParam = pParam;
+ m_outerCondition.set();
+
+ innerDispatch();
+}
+
+void AffineBridge::v_enter(void)
+{
+ m_innerMutex.acquire();
+
+ if (!m_enterCount)
+ m_innerThreadId = osl_getThreadIdentifier(NULL);
+
+ OSL_ASSERT(m_innerThreadId == osl_getThreadIdentifier(NULL));
+
+ ++ m_enterCount;
+}
+
+void AffineBridge::v_leave(void)
+{
+ OSL_ASSERT(m_innerThreadId == osl_getThreadIdentifier(NULL));
+
+ -- m_enterCount;
+ if (!m_enterCount)
+ m_innerThreadId = 0;
+
+ m_innerMutex.release();
+}
+
+int AffineBridge::v_isValid(rtl::OUString * pReason)
+{
+ int result = 1;
+
+ result = m_enterCount > 0;
+ if (!result)
+ *pReason = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("not entered"));
+
+ else
+ {
+ result = m_innerThreadId == osl_getThreadIdentifier(NULL);
+
+ if (!result)
+ *pReason = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("wrong thread"));
+ }
+
+ if (result)
+ *pReason = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("OK"));
+
+ return result;
+}
+
+extern "C" void SAL_DLLPUBLIC_EXPORT SAL_CALL uno_initEnvironment(uno_Environment * pEnv)
+ SAL_THROW_EXTERN_C()
+{
+ cppu::helper::purpenv::Environment_initWithEnterable(pEnv, new AffineBridge());
+}
+
+extern "C" void SAL_DLLPUBLIC_EXPORT SAL_CALL uno_ext_getMapping(uno_Mapping ** ppMapping,
+ uno_Environment * pFrom,
+ uno_Environment * pTo )
+{
+ cppu::helper::purpenv::createMapping(ppMapping, pFrom, pTo);
+}
+
diff --git a/cppu/source/AffineBridge/makefile.mk b/cppu/source/AffineBridge/makefile.mk
new file mode 100644
index 000000000000..c25062c15194
--- /dev/null
+++ b/cppu/source/AffineBridge/makefile.mk
@@ -0,0 +1,44 @@
+#*************************************************************************
+#
+# 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 := AffineBridge
+
+ENABLE_EXCEPTIONS := TRUE
+NO_BSYMBOLIC := TRUE
+USE_DEFFILE := FALSE
+
+
+.INCLUDE: settings.mk
+
+
+SLOFILES := $(SLO)$/AffineBridge.obj
+
+
+.INCLUDE: target.mk
+
diff --git a/cppu/source/LogBridge/LogBridge.cxx b/cppu/source/LogBridge/LogBridge.cxx
new file mode 100755
index 000000000000..b57cd405c82b
--- /dev/null
+++ b/cppu/source/LogBridge/LogBridge.cxx
@@ -0,0 +1,277 @@
+/*************************************************************************
+ *
+ * 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 "osl/mutex.hxx"
+#include "osl/thread.h"
+#include "uno/dispatcher.h"
+#include "typelib/typedescription.hxx"
+#include "cppu/helper/purpenv/Environment.hxx"
+#include "cppu/helper/purpenv/Mapping.hxx"
+#include "cppu/EnvDcp.hxx"
+#include "rtl/logfile.hxx"
+#include "uno/environment.hxx"
+#include <com/sun/star/uno/Type.hxx>
+#include <hash_map>
+#include <memory>
+
+namespace
+{
+class LogBridge : public cppu::Enterable
+{
+ osl::Mutex m_mutex;
+ sal_Int32 m_count;
+ oslThreadIdentifier m_threadId;
+
+ virtual ~LogBridge(void);
+
+public:
+ explicit LogBridge(void);
+
+ virtual void v_callInto_v(uno_EnvCallee * pCallee, va_list * pParam);
+ virtual void v_callOut_v (uno_EnvCallee * pCallee, va_list * pParam);
+
+ virtual void v_enter(void);
+ virtual void v_leave(void);
+
+ virtual int v_isValid(rtl::OUString * pReason);
+};
+
+LogBridge::LogBridge(void)
+ : m_count (0)
+ ,m_threadId(0)
+{
+}
+
+LogBridge::~LogBridge(void)
+{
+ OSL_ASSERT(m_count >= 0);
+}
+
+void LogBridge::v_callInto_v(uno_EnvCallee * pCallee, va_list * pParam)
+{
+ enter();
+ pCallee(pParam);
+ leave();
+}
+
+void LogBridge::v_callOut_v(uno_EnvCallee * pCallee, va_list * pParam)
+{
+ OSL_ASSERT(m_count > 0);
+
+ -- m_count;
+ pCallee(pParam);
+ ++ m_count;
+
+ if (!m_threadId)
+ m_threadId = osl_getThreadIdentifier(NULL);
+}
+
+void LogBridge::v_enter(void)
+{
+ m_mutex.acquire();
+
+ OSL_ASSERT(m_count >= 0);
+
+ if (m_count == 0)
+ m_threadId = osl_getThreadIdentifier(NULL);
+
+ ++ m_count;
+}
+
+void LogBridge::v_leave(void)
+{
+ OSL_ASSERT(m_count > 0);
+
+ -- m_count;
+ if (!m_count)
+ m_threadId = 0;
+
+
+ m_mutex.release();
+}
+
+int LogBridge::v_isValid(rtl::OUString * pReason)
+{
+ int result = 1;
+
+ result = m_count > 0;
+ if (!result)
+ *pReason = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("not entered"));
+
+ else
+ {
+ result = m_threadId == osl_getThreadIdentifier(NULL);
+
+ if (!result)
+ *pReason = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("wrong thread"));
+ }
+
+ if (result)
+ *pReason = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("OK"));
+
+ return result;
+}
+
+ void traceValue(typelib_TypeDescriptionReference* _pTypeRef,void* pArg)
+ {
+ switch(_pTypeRef->eTypeClass)
+ {
+ case typelib_TypeClass_STRING:
+ {
+ const ::rtl::OString sValue( ::rtl::OUStringToOString(*static_cast< ::rtl::OUString*>(pArg),osl_getThreadTextEncoding()));
+ rtl_logfile_trace( "%s", sValue.getStr());
+ }
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ rtl_logfile_trace( "%d", *static_cast<sal_Bool*>(pArg));
+ break;
+ case typelib_TypeClass_BYTE:
+ rtl_logfile_trace( "%d", *static_cast<sal_Int8*>(pArg));
+ break;
+ case typelib_TypeClass_CHAR:
+ rtl_logfile_trace( "%c", *static_cast<sal_Char*>(pArg));
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ rtl_logfile_trace( "%d", *static_cast<sal_Int16*>(pArg));
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ rtl_logfile_trace( "%d", *static_cast<sal_Int32*>(pArg));
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ rtl_logfile_trace( "%d", *static_cast<sal_Int64*>(pArg));
+ break;
+ case typelib_TypeClass_FLOAT:
+ rtl_logfile_trace( "%f", *static_cast<float*>(pArg));
+ break;
+ case typelib_TypeClass_DOUBLE:
+ rtl_logfile_trace( "%f", *static_cast<double*>(pArg));
+ break;
+ case typelib_TypeClass_TYPE:
+ {
+ const ::rtl::OString sValue( ::rtl::OUStringToOString(((com::sun::star::uno::Type*)pArg)->getTypeName(),osl_getThreadTextEncoding()));
+ rtl_logfile_trace( "%s", sValue.getStr());
+ }
+ break;
+ case typelib_TypeClass_ANY:
+ if ( static_cast<uno_Any*>(pArg)->pData )
+ traceValue(static_cast<uno_Any*>(pArg)->pType,static_cast<uno_Any*>(pArg)->pData);
+ else
+ rtl_logfile_trace( "void");
+ break;
+ case typelib_TypeClass_EXCEPTION:
+ rtl_logfile_trace( "exception");
+ break;
+ case typelib_TypeClass_INTERFACE:
+ {
+ const ::rtl::OString sValue( ::rtl::OUStringToOString(_pTypeRef->pTypeName,osl_getThreadTextEncoding()));
+ rtl_logfile_trace( "%s 0x%p", sValue.getStr(),pArg);
+ }
+ break;
+ case typelib_TypeClass_VOID:
+ rtl_logfile_trace( "void");
+ break;
+ default:
+ rtl_logfile_trace( "0x%p", pArg);
+ break;
+ } // switch(pParams[i].pTypeRef->eTypeClass)
+ }
+}
+
+void LogProbe(
+ bool pre,
+ void * /*pThis*/,
+ void * /*pContext*/,
+ typelib_TypeDescriptionReference * pReturnTypeRef,
+ typelib_MethodParameter * pParams,
+ sal_Int32 nParams,
+ typelib_TypeDescription const * pMemberType,
+ void * pReturn,
+ void * pArgs[],
+ uno_Any ** ppException )
+{
+ static ::std::auto_ptr< ::rtl::Logfile> pLogger;
+ ::rtl::OString sTemp;
+ if ( pMemberType && pMemberType->pTypeName )
+ sTemp = ::rtl::OUStringToOString(pMemberType->pTypeName,RTL_TEXTENCODING_ASCII_US);
+ if ( pre )
+ {
+ rtl_logfile_longTrace( "{ LogBridge () %s", sTemp.getStr() );
+ if ( nParams )
+ {
+ rtl_logfile_trace( "\n| : ( LogBridge ");
+ for(sal_Int32 i = 0;i < nParams;++i)
+ {
+ if ( i > 0 )
+ rtl_logfile_trace( ",");
+ traceValue(pParams[i].pTypeRef,pArgs[i]);
+
+ }
+ rtl_logfile_trace( ")");
+ } // if ( nParams )
+ rtl_logfile_trace( "\n");
+ }
+ else if ( !pre )
+ {
+ rtl_logfile_longTrace( "} LogBridge () %s",sTemp.getStr());
+ if ( ppException && *ppException )
+ {
+ rtl_logfile_trace( " excption occured : ");
+ typelib_TypeDescription * pElementTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pElementTypeDescr, (*ppException)->pType );
+ const ::rtl::OString sValue( ::rtl::OUStringToOString(pElementTypeDescr->pTypeName,osl_getThreadTextEncoding()));
+ rtl_logfile_trace( "%s", sValue.getStr());
+ TYPELIB_DANGER_RELEASE( pElementTypeDescr );
+ }
+ else if ( pReturnTypeRef )
+ {
+ rtl_logfile_trace( " return : ");
+ traceValue(pReturnTypeRef,pReturn);
+ } // if ( pReturn && pReturnTypeRef )
+
+ rtl_logfile_trace( "\n");
+ }
+}
+
+extern "C" void SAL_DLLPUBLIC_EXPORT SAL_CALL uno_initEnvironment(uno_Environment * pEnv)
+ SAL_THROW_EXTERN_C()
+{
+ cppu::helper::purpenv::Environment_initWithEnterable(pEnv, new LogBridge());
+}
+
+extern "C" void SAL_DLLPUBLIC_EXPORT SAL_CALL uno_ext_getMapping(uno_Mapping ** ppMapping,
+ uno_Environment * pFrom,
+ uno_Environment * pTo )
+{
+ cppu::helper::purpenv::createMapping(ppMapping, pFrom, pTo,LogProbe);
+}
diff --git a/cppu/source/LogBridge/makefile.mk b/cppu/source/LogBridge/makefile.mk
new file mode 100755
index 000000000000..2759c3ddfcb3
--- /dev/null
+++ b/cppu/source/LogBridge/makefile.mk
@@ -0,0 +1,44 @@
+#*************************************************************************
+#
+# 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 := LogBridge
+
+ENABLE_EXCEPTIONS := TRUE
+NO_BSYMBOLIC := TRUE
+USE_DEFFILE := FALSE
+
+
+.INCLUDE: settings.mk
+
+
+SLOFILES := $(SLO)$/LogBridge.obj
+
+
+.INCLUDE: target.mk
+
diff --git a/cppu/source/UnsafeBridge/UnsafeBridge.cxx b/cppu/source/UnsafeBridge/UnsafeBridge.cxx
new file mode 100644
index 000000000000..5a531de47182
--- /dev/null
+++ b/cppu/source/UnsafeBridge/UnsafeBridge.cxx
@@ -0,0 +1,163 @@
+/*************************************************************************
+ *
+ * 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 "osl/mutex.hxx"
+#include "osl/thread.h"
+
+#include "cppu/helper/purpenv/Environment.hxx"
+#include "cppu/helper/purpenv/Mapping.hxx"
+
+
+#ifdef debug
+# define LOG_LIFECYCLE_UnsafeBridge
+#endif
+
+#ifdef LOG_LIFECYCLE_UnsafeBridge
+# include <iostream>
+# define LOG_LIFECYCLE_UnsafeBridge_emit(x) x
+
+#else
+# define LOG_LIFECYCLE_UnsafeBridge_emit(x)
+
+#endif
+
+
+class SAL_DLLPRIVATE UnsafeBridge : public cppu::Enterable
+{
+ osl::Mutex m_mutex;
+ sal_Int32 m_count;
+ oslThreadIdentifier m_threadId;
+
+ virtual ~UnsafeBridge(void);
+
+public:
+ explicit UnsafeBridge(void);
+
+ virtual void v_callInto_v(uno_EnvCallee * pCallee, va_list * pParam);
+ virtual void v_callOut_v (uno_EnvCallee * pCallee, va_list * pParam);
+
+ virtual void v_enter(void);
+ virtual void v_leave(void);
+
+ virtual int v_isValid(rtl::OUString * pReason);
+};
+
+UnsafeBridge::UnsafeBridge(void)
+ : m_count (0),
+ m_threadId(0)
+{
+ LOG_LIFECYCLE_UnsafeBridge_emit(fprintf(stderr, "LIFE: %s -> %p\n", "UnsafeBridge::UnsafeBridge(uno_Environment * pEnv)", this));
+}
+
+UnsafeBridge::~UnsafeBridge(void)
+{
+ LOG_LIFECYCLE_UnsafeBridge_emit(fprintf(stderr, "LIFE: %s -> %p\n", "UnsafeBridge::~UnsafeBridge(void)", this));
+
+ OSL_ASSERT(m_count >= 0);
+}
+
+void UnsafeBridge::v_callInto_v(uno_EnvCallee * pCallee, va_list * pParam)
+{
+ enter();
+ pCallee(pParam);
+ leave();
+}
+
+void UnsafeBridge::v_callOut_v(uno_EnvCallee * pCallee, va_list * pParam)
+{
+ OSL_ASSERT(m_count > 0);
+
+ -- m_count;
+ pCallee(pParam);
+ ++ m_count;
+
+ if (!m_threadId)
+ m_threadId = osl_getThreadIdentifier(NULL);
+}
+
+void UnsafeBridge::v_enter(void)
+{
+ m_mutex.acquire();
+
+ OSL_ASSERT(m_count >= 0);
+
+ if (m_count == 0)
+ m_threadId = osl_getThreadIdentifier(NULL);
+
+ ++ m_count;
+}
+
+void UnsafeBridge::v_leave(void)
+{
+ OSL_ASSERT(m_count > 0);
+
+ -- m_count;
+ if (!m_count)
+ m_threadId = 0;
+
+
+ m_mutex.release();
+}
+
+int UnsafeBridge::v_isValid(rtl::OUString * pReason)
+{
+ int result = 1;
+
+ result = m_count > 0;
+ if (!result)
+ *pReason = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("not entered"));
+
+ else
+ {
+ result = m_threadId == osl_getThreadIdentifier(NULL);
+
+ if (!result)
+ *pReason = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("wrong thread"));
+ }
+
+ if (result)
+ *pReason = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("OK"));
+
+ return result;
+}
+
+extern "C" void SAL_DLLPUBLIC_EXPORT SAL_CALL uno_initEnvironment(uno_Environment * pEnv)
+ SAL_THROW_EXTERN_C()
+{
+ cppu::helper::purpenv::Environment_initWithEnterable(pEnv, new UnsafeBridge());
+}
+
+extern "C" void SAL_DLLPUBLIC_EXPORT SAL_CALL uno_ext_getMapping(uno_Mapping ** ppMapping,
+ uno_Environment * pFrom,
+ uno_Environment * pTo )
+{
+ cppu::helper::purpenv::createMapping(ppMapping, pFrom, pTo);
+}
+
diff --git a/cppu/source/UnsafeBridge/makefile.mk b/cppu/source/UnsafeBridge/makefile.mk
new file mode 100644
index 000000000000..0c1c4a988c83
--- /dev/null
+++ b/cppu/source/UnsafeBridge/makefile.mk
@@ -0,0 +1,44 @@
+#*************************************************************************
+#
+# 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 := UnsafeBridge
+
+ENABLE_EXCEPTIONS := TRUE
+NO_BSYMBOLIC := TRUE
+USE_DEFFILE := FALSE
+
+
+.INCLUDE: settings.mk
+
+
+SLOFILES := $(SLO)$/UnsafeBridge.obj
+
+
+.INCLUDE: target.mk
+
diff --git a/cppu/source/cppu/cppu_opt.cxx b/cppu/source/cppu/cppu_opt.cxx
new file mode 100644
index 000000000000..a4640fd6f945
--- /dev/null
+++ b/cppu/source/cppu/cppu_opt.cxx
@@ -0,0 +1,81 @@
+/*************************************************************************
+ *
+ * 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 "typelib/typedescription.h"
+#include "uno/any2.h"
+#include "rtl/ustrbuf.hxx"
+
+
+using namespace ::rtl;
+
+//##################################################################################################
+extern "C" rtl_uString * SAL_CALL cppu_unsatisfied_iquery_msg(
+ typelib_TypeDescriptionReference * pType )
+ SAL_THROW_EXTERN_C()
+{
+ OUStringBuffer buf( 64 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("unsatisfied query for interface of type ") );
+ buf.append( OUString::unacquired( &pType->pTypeName ) );
+ buf.append( (sal_Unicode) '!' );
+ OUString ret( buf.makeStringAndClear() );
+ rtl_uString_acquire( ret.pData );
+ return ret.pData;
+}
+
+//##################################################################################################
+extern "C" rtl_uString * SAL_CALL cppu_unsatisfied_iset_msg(
+ typelib_TypeDescriptionReference * pType )
+ SAL_THROW_EXTERN_C()
+{
+ OUStringBuffer buf( 64 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("invalid attempt to assign an empty interface of type ") );
+ buf.append( OUString::unacquired( &pType->pTypeName ) );
+ buf.append( (sal_Unicode) '!' );
+ OUString ret( buf.makeStringAndClear() );
+ rtl_uString_acquire( ret.pData );
+ return ret.pData;
+}
+
+//##############################################################################
+extern "C" rtl_uString * SAL_CALL cppu_Any_extraction_failure_msg(
+ uno_Any * pAny, typelib_TypeDescriptionReference * pType )
+ SAL_THROW_EXTERN_C()
+{
+ OUStringBuffer buf;
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
+ "Cannot extract an Any(") );
+ buf.append( OUString::unacquired(&pAny->pType->pTypeName) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(") to ") );
+ buf.append( OUString::unacquired(&pType->pTypeName) );
+ buf.append( static_cast<sal_Unicode>('!') );
+ const OUString ret( buf.makeStringAndClear() );
+ rtl_uString_acquire( ret.pData );
+ return ret.pData;
+}
diff --git a/cppu/source/cppu/makefile.mk b/cppu/source/cppu/makefile.mk
new file mode 100644
index 000000000000..5a42ec3113c2
--- /dev/null
+++ b/cppu/source/cppu/makefile.mk
@@ -0,0 +1,45 @@
+#*************************************************************************
+#
+# 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_cppu
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : ..$/..$/util$/makefile.pmk
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES= \
+ $(SLO)$/cppu_opt.obj
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : ..$/..$/util$/target.pmk
+.INCLUDE : target.mk
diff --git a/cppu/source/helper/purpenv/Proxy.hxx b/cppu/source/helper/purpenv/Proxy.hxx
new file mode 100644
index 000000000000..570d7291b177
--- /dev/null
+++ b/cppu/source/helper/purpenv/Proxy.hxx
@@ -0,0 +1,89 @@
+/*************************************************************************
+ *
+ * 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_Proxy_hxx
+#define INCLUDED_Proxy_hxx
+
+#include "osl/interlck.h"
+
+#include "uno/environment.hxx"
+#include "uno/mapping.hxx"
+#include "uno/dispatcher.h"
+
+#include "cppu/helper/purpenv/Mapping.hxx"
+
+
+namespace cssu = com::sun::star::uno;
+
+
+class SAL_DLLPRIVATE Proxy : public uno_Interface
+{
+ oslInterlockedCount m_nRef;
+
+ cssu::Environment m_from;
+ cssu::Environment m_to;
+
+ cssu::Mapping m_from_to;
+ cssu::Mapping m_to_from;
+
+ // mapping information
+ uno_Interface * m_pUnoI; // wrapped interface
+ typelib_InterfaceTypeDescription * m_pTypeDescr;
+ rtl::OUString m_aOId;
+
+ cppu::helper::purpenv::ProbeFun * m_probeFun;
+ void * m_pProbeContext;
+
+public:
+ explicit Proxy(cssu::Mapping const & to_from,
+ uno_Environment * pTo,
+ uno_Environment * pFrom,
+ uno_Interface * pUnoI,
+ typelib_InterfaceTypeDescription * pTypeDescr,
+ rtl::OUString const & rOId,
+ cppu::helper::purpenv::ProbeFun * probeFun,
+ void * pProbeContext)
+ SAL_THROW( () );
+ ~Proxy(void);
+
+ void acquire(void);
+ void release(void);
+
+ void dispatch(
+ typelib_TypeDescriptionReference * pReturnTypeRef,
+ typelib_MethodParameter * pParams,
+ sal_Int32 nParams,
+ typelib_TypeDescription const * pMemberType,
+ void * pReturn,
+ void * pArgs[],
+ uno_Any ** ppException );
+
+};
+
+extern "C" SAL_DLLPRIVATE void SAL_CALL Proxy_free(uno_ExtEnvironment * pEnv, void * pProxy) SAL_THROW_EXTERN_C();
+
+#endif
diff --git a/cppu/source/helper/purpenv/export.mk b/cppu/source/helper/purpenv/export.mk
new file mode 100644
index 000000000000..7e5e9d04d1d2
--- /dev/null
+++ b/cppu/source/helper/purpenv/export.mk
@@ -0,0 +1,19 @@
+
+.IF "$(GUI)"=="UNX" || "$(GUI)"=="MAC"
+NAMEpurpenv_helper := uno_purpenvhelper$(COMID)
+
+purpenv_helper_LIB := -l$(NAMEpurpenv_helper)
+
+.ELIF "$(GUI)"=="OS2"
+NAMEpurpenv_helper := purpeh$(UDK_MAJOR)
+purpenv_helper_LIB := i$(NAMEpurpenv_helper)
+
+.ELSE
+NAMEpurpenv_helper := purpenvhelper$(UDK_MAJOR)$(COMID)
+.IF "$(COM)"=="GCC"
+purpenv_helper_LIB := -l$(NAMEpurpenv_helper)
+.ELSE
+purpenv_helper_LIB := $(LIBPRE) i$(NAMEpurpenv_helper).lib
+.ENDIF
+
+.ENDIF
diff --git a/cppu/source/helper/purpenv/helper_purpenv_Environment.cxx b/cppu/source/helper/purpenv/helper_purpenv_Environment.cxx
new file mode 100644
index 000000000000..0fbed6739951
--- /dev/null
+++ b/cppu/source/helper/purpenv/helper_purpenv_Environment.cxx
@@ -0,0 +1,537 @@
+/*************************************************************************
+ *
+ * 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/helper/purpenv/Environment.hxx"
+
+#include "osl/diagnose.h"
+#include "uno/lbnames.h"
+
+#include "typelib/typedescription.h"
+#include "osl/interlck.h"
+
+#ifdef debug
+# define LOG_LIFECYCLE_cppu_helper_purpenv_Base
+#endif
+
+#ifdef LOG_LIFECYCLE_cppu_helper_purpenv_Base
+# include <iostream>
+# define LOG_LIFECYCLE_cppu_helper_purpenv_Base_emit(x) x
+
+#else
+# define LOG_LIFECYCLE_cppu_helper_purpenv_Base_emit(x)
+
+#endif
+
+
+extern "C" {
+typedef void SAL_CALL EnvFun_P (uno_Environment *);
+typedef void SAL_CALL EnvFun_PP_P(uno_Environment ** ppHardEnv, uno_Environment *);
+typedef void SAL_CALL ExtEnv_registerProxyInterface (uno_ExtEnvironment *,
+ void ** ppProxy,
+ uno_freeProxyFunc freeProxy,
+ rtl_uString * pOId,
+ typelib_InterfaceTypeDescription * pTypeDescr);
+typedef void SAL_CALL ExtEnv_revokeInterface (uno_ExtEnvironment *,
+ void * pInterface);
+typedef void SAL_CALL ExtEnv_getObjectIdentifier (uno_ExtEnvironment *,
+ rtl_uString **,
+ void *);
+typedef void SAL_CALL ExtEnv_getRegisteredInterface (uno_ExtEnvironment *,
+ void **,
+ rtl_uString *,
+ typelib_InterfaceTypeDescription *);
+typedef void SAL_CALL ExtEnv_getRegisteredInterfaces(uno_ExtEnvironment *,
+ void *** pppInterfaces,
+ sal_Int32 * pnLen,
+ uno_memAlloc memAlloc);
+typedef void SAL_CALL ExtEnv_computeObjectIdentifier(uno_ExtEnvironment *,
+ rtl_uString ** ppOId,
+ void * pInterface);
+typedef void SAL_CALL ExtEnv_acquireInterface (uno_ExtEnvironment *,
+ void * pInterface);
+typedef void SAL_CALL ExtEnv_releaseInterface (uno_ExtEnvironment *,
+ void * pInterface);
+}
+
+class Base : public cppu::Enterable
+{
+public:
+ explicit Base(uno_Environment * pEnv, cppu::Enterable * pEnterable);
+
+ void acquireWeak(void);
+ void releaseWeak(void);
+ void harden (uno_Environment ** ppHardEnv);
+ void acquire (void);
+ void release (void);
+
+ void registerProxyInterface (void ** ppProxy,
+ uno_freeProxyFunc freeProxy,
+ rtl::OUString const & oid,
+ typelib_InterfaceTypeDescription * pTypeDescr);
+ void revokeInterface (void * pInterface);
+ void getObjectIdentifier (void * pInterface,
+ rtl::OUString * pOid);
+ void getRegisteredInterface (void **,
+ rtl::OUString const & oid,
+ typelib_InterfaceTypeDescription *);
+ void getRegisteredInterfaces(void ***,
+ sal_Int32 * pnLen,
+ uno_memAlloc memAlloc);
+ void computeObjectIdentifier(void * pInterface,
+ rtl::OUString * pOid);
+ void acquireInterface (void * pInterface);
+ void releaseInterface (void * pInterface);
+
+ virtual void v_enter (void);
+ virtual void v_leave (void);
+ virtual void v_callInto_v(uno_EnvCallee * pCallee, va_list * pParam);
+ virtual void v_callOut_v (uno_EnvCallee * pCallee, va_list * pParam);
+ virtual int v_isValid (rtl::OUString * pReason);
+
+protected:
+ oslInterlockedCount m_nRef;
+ uno_Environment * m_pEnv;
+ cppu::Enterable * m_pEnterable;
+
+ EnvFun_P * m_env_acquire;
+ EnvFun_P * m_env_release;
+ EnvFun_PP_P * m_env_harden;
+ EnvFun_P * m_env_acquireWeak;
+ EnvFun_P * m_env_releaseWeak;
+
+ ExtEnv_registerProxyInterface * m_env_registerProxyInterface;
+ ExtEnv_revokeInterface * m_env_revokeInterface;
+ ExtEnv_getObjectIdentifier * m_env_getObjectIdentifier;
+ ExtEnv_getRegisteredInterface * m_env_getRegisteredInterface;
+ ExtEnv_getRegisteredInterfaces * m_env_getRegisteredInterfaces;
+ ExtEnv_computeObjectIdentifier * m_env_computeObjectIdentifier;
+ ExtEnv_acquireInterface * m_env_acquireInterface;
+ ExtEnv_releaseInterface * m_env_releaseInterface;
+
+ virtual ~Base();
+};
+
+extern "C" {
+static void SAL_CALL s_acquire(uno_Environment * pEnv) //SAL_THROW_EXTERN_C()
+{
+ Base * pBase = static_cast<Base *>(pEnv->pReserved);
+ pBase->acquire();
+}
+
+static void SAL_CALL s_release(uno_Environment * pEnv) SAL_THROW_EXTERN_C()
+{
+ Base * pBase = static_cast<Base *>(pEnv->pReserved);
+ pBase->release();
+}
+
+static void SAL_CALL s_harden(uno_Environment ** ppHardEnv, uno_Environment * pEnv) SAL_THROW_EXTERN_C()
+{
+ Base * pBase = static_cast<Base *>(pEnv->pReserved);
+ pBase->harden(ppHardEnv);
+}
+
+static void SAL_CALL s_acquireWeak(uno_Environment * pEnv) SAL_THROW_EXTERN_C()
+{
+ Base * pBase = static_cast<Base *>(pEnv->pReserved);
+ pBase->acquireWeak();
+}
+
+static void SAL_CALL s_releaseWeak(uno_Environment * pEnv) SAL_THROW_EXTERN_C()
+{
+ Base * pBase = static_cast<Base *>(pEnv->pReserved);
+ pBase->releaseWeak();
+}
+
+
+static void SAL_CALL s_registerProxyInterface(uno_ExtEnvironment * pExtEnv,
+ void ** ppProxy,
+ uno_freeProxyFunc freeProxy,
+ rtl_uString * pOId,
+ typelib_InterfaceTypeDescription * pTypeDescr)
+{
+ Base * pBase = static_cast<Base *>(pExtEnv->aBase.pReserved);
+ pBase->registerProxyInterface(ppProxy, freeProxy, pOId, pTypeDescr);
+}
+
+static void SAL_CALL s_revokeInterface(uno_ExtEnvironment * pExtEnv, void * pInterface)
+{
+ Base * pBase = static_cast<Base *>(pExtEnv->aBase.pReserved);
+ pBase->revokeInterface(pInterface);
+}
+
+static void SAL_CALL s_getObjectIdentifier(uno_ExtEnvironment * pExtEnv,
+ rtl_uString ** ppOId,
+ void * pInterface)
+{
+ Base * pBase = static_cast<Base *>(pExtEnv->aBase.pReserved);
+ pBase->getObjectIdentifier(pInterface, reinterpret_cast<rtl::OUString *>(ppOId));
+}
+
+static void SAL_CALL s_getRegisteredInterface(uno_ExtEnvironment * pExtEnv,
+ void ** ppInterface,
+ rtl_uString * pOId,
+ typelib_InterfaceTypeDescription * pTypeDescr)
+{
+ Base * pBase = static_cast<Base *>(pExtEnv->aBase.pReserved);
+ pBase->getRegisteredInterface(ppInterface, pOId, pTypeDescr);
+}
+
+static void SAL_CALL s_getRegisteredInterfaces(uno_ExtEnvironment * pExtEnv,
+ void *** pppInterface,
+ sal_Int32 * pnLen,
+ uno_memAlloc memAlloc)
+{
+ Base * pBase = static_cast<Base *>(pExtEnv->aBase.pReserved);
+ pBase->getRegisteredInterfaces(pppInterface, pnLen, memAlloc);
+}
+
+static void SAL_CALL s_computeObjectIdentifier(uno_ExtEnvironment * pExtEnv,
+ rtl_uString ** ppOId,
+ void * pInterface)
+{
+ Base * pBase = static_cast<Base *>(pExtEnv->aBase.pReserved);
+ pBase->computeObjectIdentifier(pInterface, reinterpret_cast<rtl::OUString *>(ppOId));
+}
+
+static void SAL_CALL s_acquireInterface(uno_ExtEnvironment * pExtEnv, void * pInterface) {
+ Base * pBase = static_cast<Base *>(pExtEnv->aBase.pReserved);
+ pBase->acquireInterface(pInterface);
+}
+
+static void SAL_CALL s_releaseInterface(uno_ExtEnvironment * pExtEnv, void * pInterface) {
+ Base * pBase = static_cast<Base *>(pExtEnv->aBase.pReserved);
+ pBase->releaseInterface(pInterface);
+}
+
+}
+
+Base::Base(uno_Environment * pEnv, cppu::Enterable * pEnterable)
+ :m_nRef(1),
+ m_pEnv(pEnv),
+ m_pEnterable (pEnterable),
+ m_env_acquire (pEnv->acquire),
+ m_env_release (pEnv->release),
+ m_env_harden (pEnv->harden),
+ m_env_acquireWeak(pEnv->acquireWeak),
+ m_env_releaseWeak(pEnv->releaseWeak),
+ m_env_registerProxyInterface (pEnv->pExtEnv->registerProxyInterface),
+ m_env_revokeInterface (pEnv->pExtEnv->revokeInterface),
+ m_env_getObjectIdentifier (pEnv->pExtEnv->getObjectIdentifier),
+ m_env_getRegisteredInterface (pEnv->pExtEnv->getRegisteredInterface),
+ m_env_getRegisteredInterfaces(pEnv->pExtEnv->getRegisteredInterfaces),
+ m_env_computeObjectIdentifier(pEnv->pExtEnv->computeObjectIdentifier),
+ m_env_acquireInterface (pEnv->pExtEnv->acquireInterface),
+ m_env_releaseInterface (pEnv->pExtEnv->releaseInterface)
+{
+ LOG_LIFECYCLE_cppu_helper_purpenv_Base_emit(fprintf(stderr, "LIFE: %s -> %p\n", "cppu::helper::purpenv::Base::Base(uno_Environment * pEnv)", this));
+ OSL_ENSURE(
+ rtl_ustr_ascii_compare_WithLength(pEnv->pTypeName->buffer, rtl_str_getLength(UNO_LB_UNO), UNO_LB_UNO)
+ == 0,
+ "### wrong environment type!");
+
+ pEnv->acquire = s_acquire;
+ pEnv->release = s_release;
+ pEnv->harden = s_harden;
+ pEnv->acquireWeak = s_acquireWeak;
+ pEnv->releaseWeak = s_releaseWeak;
+
+ pEnv->pExtEnv->registerProxyInterface = s_registerProxyInterface;
+ pEnv->pExtEnv->revokeInterface = s_revokeInterface;
+ pEnv->pExtEnv->getObjectIdentifier = s_getObjectIdentifier;
+ pEnv->pExtEnv->getRegisteredInterface = s_getRegisteredInterface;
+ pEnv->pExtEnv->getRegisteredInterfaces = s_getRegisteredInterfaces;
+ pEnv->pExtEnv->computeObjectIdentifier = s_computeObjectIdentifier;
+ pEnv->pExtEnv->acquireInterface = s_acquireInterface;
+ pEnv->pExtEnv->releaseInterface = s_releaseInterface;
+
+ pEnv->pReserved = this;
+}
+
+Base::~Base()
+{
+ LOG_LIFECYCLE_cppu_helper_purpenv_Base_emit(fprintf(stderr, "LIFE: %s -> %p\n", "cppu::helper::purpenv::Base::~Base()", this));
+
+ m_pEnv->acquire = m_env_acquire;
+ m_pEnv->release = m_env_release;
+ m_pEnv->harden = m_env_harden;
+ m_pEnv->acquireWeak = m_env_acquireWeak;
+ m_pEnv->releaseWeak = m_env_releaseWeak;
+
+ m_pEnv->pReserved = NULL;
+
+ delete m_pEnterable;
+ m_pEnv->release(m_pEnv);
+}
+
+void Base::acquire(void)
+{
+ m_env_acquire(m_pEnv);
+
+ osl_incrementInterlockedCount(&m_nRef);
+}
+
+void Base::release(void)
+{
+ if (osl_decrementInterlockedCount(&m_nRef) == 0)
+ delete this;
+
+ else
+ m_env_release(m_pEnv);
+}
+
+void Base::harden(uno_Environment ** ppHardEnv)
+{
+ m_env_harden(ppHardEnv, m_pEnv);
+ osl_incrementInterlockedCount(&m_nRef);
+}
+
+void Base::acquireWeak(void)
+{
+ m_env_acquireWeak(m_pEnv);
+}
+
+void Base::releaseWeak(void)
+{
+ m_env_releaseWeak(m_pEnv);
+}
+
+
+extern "C" { static void s_registerProxyInterface_v(va_list * pParam)
+{
+ uno_ExtEnvironment * pExtEnv = va_arg(*pParam, uno_ExtEnvironment *);
+ void ** ppProxy = va_arg(*pParam, void **);
+ uno_freeProxyFunc freeProxy = va_arg(*pParam, uno_freeProxyFunc);
+ rtl_uString * pOId = va_arg(*pParam, rtl_uString *);
+ typelib_InterfaceTypeDescription * pTypeDescr = va_arg(*pParam, typelib_InterfaceTypeDescription *);
+ ExtEnv_registerProxyInterface * pRegisterProxyInterface
+ = va_arg(*pParam, ExtEnv_registerProxyInterface *);
+
+ pRegisterProxyInterface(pExtEnv, ppProxy, freeProxy, pOId, pTypeDescr);
+}}
+
+void Base::registerProxyInterface(void ** ppProxy,
+ uno_freeProxyFunc freeProxy,
+ rtl::OUString const & oid,
+ typelib_InterfaceTypeDescription * pTypeDescr)
+{
+ uno_Environment_invoke(m_pEnv,
+ s_registerProxyInterface_v,
+ m_pEnv->pExtEnv,
+ ppProxy,
+ freeProxy,
+ oid.pData,
+ pTypeDescr,
+ m_env_registerProxyInterface);
+}
+
+
+extern "C" { static void s_revokeInterface_v(va_list * pParam)
+{
+ uno_ExtEnvironment * pExtEnv = va_arg(*pParam, uno_ExtEnvironment *);
+ void * pInterface = va_arg(*pParam, void *);
+ ExtEnv_revokeInterface * pRevokeInterface = va_arg(*pParam, ExtEnv_revokeInterface *);
+
+ pRevokeInterface(pExtEnv, pInterface);
+}}
+
+void Base::revokeInterface(void * pInterface)
+{
+ uno_Environment_invoke(m_pEnv,
+ s_revokeInterface_v,
+ m_pEnv->pExtEnv,
+ pInterface,
+ m_env_revokeInterface);
+}
+
+
+extern "C" { static void s_getObjectIdentifier_v(va_list * pParam)
+{
+ uno_ExtEnvironment * pExtEnv = va_arg(*pParam, uno_ExtEnvironment *);
+ void * pInterface = va_arg(*pParam, void *);
+ rtl::OUString * pOId = va_arg(*pParam, rtl::OUString *);
+ ExtEnv_getObjectIdentifier * pGetObjectIdentifier
+ = va_arg(*pParam, ExtEnv_getObjectIdentifier *);
+
+ pGetObjectIdentifier(pExtEnv, reinterpret_cast<rtl_uString **>(pOId), pInterface);
+}}
+
+void Base::getObjectIdentifier(void * pInterface, rtl::OUString * pOid)
+{
+ uno_Environment_invoke(m_pEnv,
+ s_getObjectIdentifier_v,
+ m_pEnv->pExtEnv,
+ pInterface,
+ pOid,
+ m_env_getObjectIdentifier);
+}
+
+
+extern "C" { static void s_getRegisteredInterface_v(va_list * pParam)
+{
+ uno_ExtEnvironment * pExtEnv = va_arg(*pParam, uno_ExtEnvironment *);
+ void ** ppInterface = va_arg(*pParam, void **);
+ rtl_uString * pOId = va_arg(*pParam, rtl_uString *);
+ typelib_InterfaceTypeDescription * pTypeDescr = va_arg(*pParam, typelib_InterfaceTypeDescription *);
+ ExtEnv_getRegisteredInterface * pGetRegisteredInterface
+ = va_arg(*pParam, ExtEnv_getRegisteredInterface *);
+
+ pGetRegisteredInterface(pExtEnv, ppInterface, pOId, pTypeDescr);
+}}
+
+void Base::getRegisteredInterface(void ** ppInterface,
+ rtl::OUString const & oid,
+ typelib_InterfaceTypeDescription * pTypeDescr)
+{
+ uno_Environment_invoke(m_pEnv,
+ s_getRegisteredInterface_v,
+ m_pEnv->pExtEnv,
+ ppInterface,
+ oid.pData,
+ pTypeDescr,
+ m_env_getRegisteredInterface);
+}
+
+
+extern "C" { static void s_getRegisteredInterfaces_v(va_list * pParam)
+{
+ uno_ExtEnvironment * pExtEnv = va_arg(*pParam, uno_ExtEnvironment *);
+ void *** pppInterface = va_arg(*pParam, void ***);
+ sal_Int32 * pnLen = va_arg(*pParam, sal_Int32 *);
+ uno_memAlloc memAlloc = va_arg(*pParam, uno_memAlloc);
+ ExtEnv_getRegisteredInterfaces * pGetRegisteredInterfaces
+ = va_arg(*pParam, ExtEnv_getRegisteredInterfaces *);
+
+ pGetRegisteredInterfaces(pExtEnv, pppInterface, pnLen, memAlloc);
+}}
+
+void Base::getRegisteredInterfaces(void *** pppInterface,
+ sal_Int32 * pnLen,
+ uno_memAlloc memAlloc)
+{
+ uno_Environment_invoke(m_pEnv,
+ s_getRegisteredInterfaces_v,
+ m_pEnv->pExtEnv,
+ pppInterface,
+ pnLen,
+ memAlloc,
+ m_env_getRegisteredInterfaces);
+}
+
+
+extern "C" { static void s_computeObjectIdentifier_v(va_list * pParam)
+{
+ uno_ExtEnvironment * pExtEnv = va_arg(*pParam, uno_ExtEnvironment *);
+ void * pInterface = va_arg(*pParam, void *);
+ rtl::OUString * pOId = va_arg(*pParam, rtl::OUString *);
+ ExtEnv_computeObjectIdentifier * pComputeObjectIdentifier
+ = va_arg(*pParam, ExtEnv_computeObjectIdentifier *);
+
+ pComputeObjectIdentifier(pExtEnv, reinterpret_cast<rtl_uString **>(pOId), pInterface);
+}}
+
+void Base::computeObjectIdentifier(void * pInterface, rtl::OUString * pOid)
+{
+ uno_Environment_invoke(m_pEnv,
+ s_computeObjectIdentifier_v,
+ m_pEnv->pExtEnv,
+ pInterface,
+ pOid,
+ m_env_computeObjectIdentifier);
+}
+
+
+extern "C" { static void s_acquireInterface_v(va_list * pParam)
+{
+ uno_ExtEnvironment * pExtEnv = va_arg(*pParam, uno_ExtEnvironment *);
+ void * pInterface = va_arg(*pParam, void *);
+ ExtEnv_acquireInterface * pAcquireInterface
+ = va_arg(*pParam, ExtEnv_acquireInterface *);
+
+ pAcquireInterface(pExtEnv, pInterface);
+}}
+
+void Base::acquireInterface(void * pInterface)
+{
+ uno_Environment_invoke(m_pEnv, s_acquireInterface_v, m_pEnv->pExtEnv, pInterface, m_env_acquireInterface);
+}
+
+
+extern "C" { static void s_releaseInterface_v(va_list * pParam)
+{
+ uno_ExtEnvironment * pExtEnv = va_arg(*pParam, uno_ExtEnvironment *);
+ void * pInterface = va_arg(*pParam, void *);
+ ExtEnv_releaseInterface * pReleaseInterface
+ = va_arg(*pParam, ExtEnv_releaseInterface *);
+
+ pReleaseInterface(pExtEnv, pInterface);
+}}
+
+void Base::releaseInterface(void * pInterface)
+{
+ uno_Environment_invoke(m_pEnv,
+ s_releaseInterface_v,
+ m_pEnv->pExtEnv,
+ pInterface,
+ m_env_releaseInterface);
+}
+
+void Base::v_enter(void)
+{
+ m_pEnterable->enter();
+}
+
+void Base::v_leave(void)
+{
+ m_pEnterable->leave();
+}
+
+void Base::v_callInto_v(uno_EnvCallee * pCallee, va_list * pParam)
+{
+ m_pEnterable->callInto_v(pCallee, pParam);
+}
+
+void Base::v_callOut_v(uno_EnvCallee * pCallee, va_list * pParam)
+{
+ m_pEnterable->callOut_v(pCallee, pParam);
+}
+
+int Base::v_isValid(rtl::OUString * pReason)
+{
+ return m_pEnterable->isValid(pReason);
+}
+
+namespace cppu { namespace helper { namespace purpenv {
+
+void Environment_initWithEnterable(uno_Environment * pEnvironment, cppu::Enterable * pEnterable)
+{
+ new Base(pEnvironment, pEnterable);
+}
+
+}}}
diff --git a/cppu/source/helper/purpenv/helper_purpenv_Mapping.cxx b/cppu/source/helper/purpenv/helper_purpenv_Mapping.cxx
new file mode 100644
index 000000000000..0b4b3c9e0786
--- /dev/null
+++ b/cppu/source/helper/purpenv/helper_purpenv_Mapping.cxx
@@ -0,0 +1,233 @@
+/*************************************************************************
+ *
+ * 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/helper/purpenv/Mapping.hxx"
+
+#include "Proxy.hxx"
+
+#include "osl/interlck.h"
+#include "uno/environment.hxx"
+#include "uno/dispatcher.h"
+#include "typelib/typedescription.h"
+
+
+#ifdef debug
+# define LOG_LIFECYCLE_cppu_helper_purpenv_Mapping
+#endif
+
+#ifdef LOG_LIFECYCLE_cppu_helper_purpenv_Mapping
+# include <iostream>
+# define LOG_LIFECYCLE_cppu_helper_purpenv_Mapping_emit(x) x
+
+#else
+# define LOG_LIFECYCLE_cppu_helper_purpenv_Mapping_emit(x)
+
+#endif
+
+
+using namespace com::sun::star;
+
+
+class Mapping : public uno_Mapping
+{
+ uno::Environment m_from;
+ uno::Environment m_to;
+
+ oslInterlockedCount m_nCount;
+
+ cppu::helper::purpenv::ProbeFun * m_probeFun;
+ void * m_pContext;
+
+public:
+ explicit Mapping(uno_Environment * pFrom,
+ uno_Environment * pTo,
+ cppu::helper::purpenv::ProbeFun * probeFun,
+ void * pProbeContext);
+ virtual ~Mapping(void);
+
+ void mapInterface(
+ uno_Interface ** ppOut,
+ uno_Interface * pUnoI,
+ typelib_InterfaceTypeDescription * pTypeDescr);
+
+ void acquire(void);
+ void release(void);
+};
+
+static void SAL_CALL s_mapInterface(
+ uno_Mapping * puno_Mapping,
+ uno_Interface ** ppOut,
+ uno_Interface * pUnoI,
+ typelib_InterfaceTypeDescription * pTypeDescr )
+ SAL_THROW_EXTERN_C()
+{
+ Mapping * pMapping = static_cast<Mapping *>(puno_Mapping);
+ pMapping->mapInterface(ppOut, pUnoI, pTypeDescr);
+}
+
+extern "C" {
+static void SAL_CALL s_acquire(uno_Mapping * puno_Mapping)
+ SAL_THROW_EXTERN_C()
+{
+ Mapping * pMapping = static_cast<Mapping *>(puno_Mapping);
+ pMapping->acquire();
+}
+
+static void SAL_CALL s_release(uno_Mapping * puno_Mapping)
+ SAL_THROW_EXTERN_C()
+{
+ Mapping * pMapping = static_cast<Mapping * >(puno_Mapping);
+ pMapping->release();
+}
+
+
+static void s_getIdentifier_v(va_list * pParam)
+{
+ uno_ExtEnvironment * pEnv = va_arg(*pParam, uno_ExtEnvironment *);
+ rtl_uString ** ppOid = va_arg(*pParam, rtl_uString **);
+ uno_Interface * pUnoI = va_arg(*pParam, uno_Interface *);
+
+ pEnv->getObjectIdentifier(pEnv, ppOid, pUnoI);
+}
+
+static void SAL_CALL s_free(uno_Mapping * puno_Mapping)
+ SAL_THROW_EXTERN_C()
+{
+ Mapping * pMapping = static_cast<Mapping *>(puno_Mapping);
+ delete pMapping;
+}
+}
+
+Mapping::Mapping(uno_Environment * pFrom,
+ uno_Environment * pTo,
+ cppu::helper::purpenv::ProbeFun * probeFun,
+ void * pProbeContext
+) SAL_THROW( () )
+ : m_from (pFrom),
+ m_to (pTo),
+ m_nCount (1),
+ m_probeFun(probeFun),
+ m_pContext(pProbeContext)
+{
+ LOG_LIFECYCLE_cppu_helper_purpenv_Mapping_emit(fprintf(stderr, "LIFE: %s -> %p\n", "Mapping::Mapping(uno_Environment * pFrom, uno_Environment * pTo) SAL_THROW( () )", this));
+
+ uno_Mapping::acquire = s_acquire;
+ uno_Mapping::release = s_release;
+ uno_Mapping::mapInterface = (uno_MapInterfaceFunc)s_mapInterface;
+}
+
+Mapping::~Mapping(void)
+{
+ LOG_LIFECYCLE_cppu_helper_purpenv_Mapping_emit(fprintf(stderr, "LIFE: %s -> %p\n", "Mapping::~Mapping(void)", this));
+}
+
+
+void Mapping::mapInterface(
+ uno_Interface ** ppOut,
+ uno_Interface * pUnoI,
+ typelib_InterfaceTypeDescription * pTypeDescr)
+{
+ OSL_ASSERT(ppOut && pTypeDescr);
+ if (*ppOut)
+ {
+ (*ppOut)->release(*ppOut);
+ *ppOut = 0;
+ }
+
+ if (!pUnoI)
+ return;
+
+ // get object id of uno interface to be wrapped
+ // need to enter environment because of potential "queryInterface" call
+ rtl_uString * pOId = 0;
+ uno_Environment_invoke(m_from.get(), s_getIdentifier_v, m_from.get(), &pOId, pUnoI);
+ OSL_ASSERT(pOId);
+
+ // try to get any known interface from target environment
+ m_to.get()->pExtEnv->getRegisteredInterface(m_to.get()->pExtEnv, (void **)ppOut, pOId, pTypeDescr);
+
+ if (!*ppOut) // not yet there, register new proxy interface
+ {
+ // try to publish a new proxy (ref count initially 1)
+ uno_Interface * pProxy = new Proxy(this,
+ m_from.get(),
+ m_to.get(),
+ pUnoI,
+ pTypeDescr,
+ pOId,
+ m_probeFun,
+ m_pContext);
+
+ // proxy may be exchanged during registration
+ m_to.get()->pExtEnv->registerProxyInterface(m_to.get()->pExtEnv,
+ (void **)&pProxy,
+ Proxy_free,
+ pOId,
+ pTypeDescr);
+
+ *ppOut = pProxy;
+ }
+
+ rtl_uString_release(pOId);
+}
+
+
+void Mapping::acquire() SAL_THROW(())
+{
+ if (osl_incrementInterlockedCount(&m_nCount) == 1)
+ {
+ uno_Mapping * pMapping = this;
+
+ ::uno_registerMapping(&pMapping, s_free, m_from.get(), m_to.get(), NULL);
+ }
+}
+
+void Mapping::release() SAL_THROW(())
+{
+ if (osl_decrementInterlockedCount(&m_nCount) == 0)
+ ::uno_revokeMapping(this);
+}
+
+
+namespace cppu { namespace helper { namespace purpenv {
+
+void createMapping(uno_Mapping ** ppMapping,
+ uno_Environment * pFrom,
+ uno_Environment * pTo,
+ ProbeFun * probeFun,
+ void * pContext
+ )
+{
+ *ppMapping = new Mapping(pFrom, pTo, probeFun, pContext);
+
+ ::uno_registerMapping(ppMapping, s_free, pFrom, pTo, NULL);
+}
+
+}}}
diff --git a/cppu/source/helper/purpenv/helper_purpenv_Proxy.cxx b/cppu/source/helper/purpenv/helper_purpenv_Proxy.cxx
new file mode 100644
index 000000000000..344203e38762
--- /dev/null
+++ b/cppu/source/helper/purpenv/helper_purpenv_Proxy.cxx
@@ -0,0 +1,530 @@
+/*************************************************************************
+ *
+ * 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 "Proxy.hxx"
+
+#include "sal/alloca.h"
+#include "uno/dispatcher.h"
+#include "typelib/typedescription.hxx"
+#include "cppu/EnvDcp.hxx"
+
+
+//#define LOG_LIFECYCLE_Proxy
+#ifdef LOG_LIFECYCLE_Proxy
+# include <iostream>
+# define LOG_LIFECYCLE_Proxy_emit(x) x
+
+#else
+# define LOG_LIFECYCLE_Proxy_emit(x)
+
+#endif
+
+
+using namespace com::sun::star;
+
+
+static bool relatesToInterface(typelib_TypeDescription * pTypeDescr)
+ SAL_THROW( () )
+{
+ switch (pTypeDescr->eTypeClass)
+ {
+// case typelib_TypeClass_TYPEDEF:
+ case typelib_TypeClass_SEQUENCE:
+ {
+ switch (((typelib_IndirectTypeDescription *)pTypeDescr)->pType->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE:
+ case typelib_TypeClass_UNION: // might relate to interface
+ case typelib_TypeClass_ANY: // might relate to interface
+ return true;
+ case typelib_TypeClass_SEQUENCE:
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType );
+ bool bRel = relatesToInterface( pTD );
+ TYPELIB_DANGER_RELEASE( pTD );
+ return bRel;
+ }
+ default:
+ ;
+ }
+ return false;
+ }
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ // ...optimized... to avoid getDescription() calls!
+ typelib_CompoundTypeDescription * pComp = (typelib_CompoundTypeDescription *)pTypeDescr;
+ typelib_TypeDescriptionReference ** pTypes = pComp->ppTypeRefs;
+ for ( sal_Int32 nPos = pComp->nMembers; nPos--; )
+ {
+ switch (pTypes[nPos]->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE:
+ case typelib_TypeClass_UNION: // might relate to interface
+ case typelib_TypeClass_ANY: // might relate to interface
+ return true;
+// case typelib_TypeClass_TYPEDEF:
+ case typelib_TypeClass_SEQUENCE:
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, pTypes[nPos] );
+ bool bRel = relatesToInterface( pTD );
+ TYPELIB_DANGER_RELEASE( pTD );
+ if (bRel)
+ return true;
+ }
+ default:
+ ;
+ }
+ }
+ if (pComp->pBaseTypeDescription)
+ return relatesToInterface( (typelib_TypeDescription *)pComp->pBaseTypeDescription );
+ break;
+ }
+ case typelib_TypeClass_UNION: // might relate to interface
+ case typelib_TypeClass_ANY: // might relate to interface
+ case typelib_TypeClass_INTERFACE:
+ return true;
+
+ default:
+ ;
+ }
+ return false;
+}
+
+extern "C" { static void SAL_CALL s_Proxy_dispatch(
+ uno_Interface * pUnoI,
+ typelib_TypeDescription const * pMemberType,
+ void * pReturn,
+ void * pArgs[],
+ uno_Any ** ppException)
+ SAL_THROW_EXTERN_C()
+{
+ Proxy * pThis = static_cast<Proxy *>(pUnoI);
+
+ typelib_MethodParameter param;
+ sal_Int32 nParams = 0;
+ typelib_MethodParameter * pParams = 0;
+ typelib_TypeDescriptionReference * pReturnTypeRef = 0;
+ // sal_Int32 nOutParams = 0;
+
+ switch (pMemberType->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ if (pReturn)
+ {
+ pReturnTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)
+ pMemberType)->pAttributeTypeRef;
+ nParams = 0;
+ pParams = NULL;
+ }
+ else
+ {
+ param.pTypeRef = ((typelib_InterfaceAttributeTypeDescription *)
+ pMemberType)->pAttributeTypeRef;
+ param.bIn = sal_True;
+ param.bOut = sal_False;
+ nParams = 1;
+ pParams = &param;
+ }
+ break;
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ typelib_InterfaceMethodTypeDescription * method_td =
+ (typelib_InterfaceMethodTypeDescription *) pMemberType;
+ pReturnTypeRef = method_td->pReturnTypeRef;
+ nParams = method_td->nParams;
+ pParams = method_td->pParams;
+ break;
+ }
+ default:
+ OSL_ENSURE( sal_False, "### illegal member typeclass!" );
+ abort();
+ }
+
+ pThis->dispatch( pReturnTypeRef,
+ pParams,
+ nParams,
+ pMemberType,
+ pReturn,
+ pArgs,
+ ppException );
+}}
+
+extern "C" void SAL_CALL Proxy_free(uno_ExtEnvironment * /*pEnv*/, void * pProxy) SAL_THROW_EXTERN_C()
+{
+ Proxy * pThis = static_cast<Proxy * >(reinterpret_cast<uno_Interface *>(pProxy));
+ delete pThis;
+}
+
+extern "C" {
+static void SAL_CALL s_Proxy_acquire(uno_Interface * pUnoI) SAL_THROW_EXTERN_C()
+{
+ Proxy * pProxy = static_cast<Proxy *>(pUnoI);
+ pProxy->acquire();
+}
+
+static void SAL_CALL s_Proxy_release(uno_Interface * pUnoI) SAL_THROW_EXTERN_C()
+{
+ Proxy * pProxy = static_cast<Proxy *>(pUnoI);
+ pProxy->release();
+}
+
+static void s_acquireAndRegister_v(va_list * pParam)
+{
+ uno_Interface * pUnoI = va_arg(*pParam, uno_Interface *);
+ rtl_uString * pOid = va_arg(*pParam, rtl_uString *);
+ typelib_InterfaceTypeDescription * pTypeDescr = va_arg(*pParam, typelib_InterfaceTypeDescription *);
+ uno_ExtEnvironment * pEnv = va_arg(*pParam, uno_ExtEnvironment *);
+
+ pUnoI->acquire(pUnoI);
+ pEnv->registerInterface(pEnv, reinterpret_cast<void **>(&pUnoI), pOid, pTypeDescr);
+}
+}
+
+Proxy::Proxy(uno::Mapping const & to_from,
+ uno_Environment * pTo,
+ uno_Environment * pFrom,
+ uno_Interface * pUnoI,
+ typelib_InterfaceTypeDescription * pTypeDescr,
+ rtl::OUString const & rOId,
+ cppu::helper::purpenv::ProbeFun * probeFun,
+ void * pProbeContext
+)
+ SAL_THROW(())
+ : m_nRef (1),
+ m_from (pFrom),
+ m_to (pTo),
+ m_from_to (pFrom, pTo),
+ m_to_from (to_from),
+ m_pUnoI (pUnoI),
+ m_pTypeDescr (pTypeDescr),
+ m_aOId (rOId),
+ m_probeFun (probeFun),
+ m_pProbeContext(pProbeContext)
+{
+ LOG_LIFECYCLE_Proxy_emit(fprintf(stderr, "LIFE: %s -> %p\n", "Proxy::Proxy(<>)", this));
+
+ typelib_typedescription_acquire((typelib_TypeDescription *)m_pTypeDescr);
+ if (!((typelib_TypeDescription *)m_pTypeDescr)->bComplete)
+ typelib_typedescription_complete((typelib_TypeDescription **)&m_pTypeDescr);
+
+ OSL_ENSURE(((typelib_TypeDescription *)m_pTypeDescr)->bComplete, "### type is incomplete!");
+
+ uno_Environment_invoke(m_to.get(), s_acquireAndRegister_v, m_pUnoI, rOId.pData, pTypeDescr, m_to.get());
+
+ // uno_Interface
+ uno_Interface::acquire = s_Proxy_acquire;
+ uno_Interface::release = s_Proxy_release;
+ uno_Interface::pDispatcher = s_Proxy_dispatch;
+}
+
+extern "C" { static void s_releaseAndRevoke_v(va_list * pParam)
+{
+ uno_ExtEnvironment * pEnv = va_arg(*pParam, uno_ExtEnvironment *);
+ uno_Interface * pUnoI = va_arg(*pParam, uno_Interface *);
+
+ pEnv->revokeInterface(pEnv, reinterpret_cast<void *>(pUnoI));
+ pUnoI->release(pUnoI);
+}}
+
+Proxy::~Proxy()
+{
+ LOG_LIFECYCLE_Proxy_emit(fprintf(stderr, "LIFE: %s -> %p\n", "Proxy::~Proxy()", this));
+
+ uno_Environment_invoke(m_to.get(), s_releaseAndRevoke_v, m_to.get(), m_pUnoI);
+
+ typelib_typedescription_release((typelib_TypeDescription *)m_pTypeDescr);
+}
+
+static uno::TypeDescription getAcquireMethod(void)
+{
+ typelib_TypeDescriptionReference * type_XInterface =
+ * typelib_static_type_getByTypeClass(typelib_TypeClass_INTERFACE);
+
+ typelib_TypeDescription * pTXInterfaceDescr = 0;
+ TYPELIB_DANGER_GET (&pTXInterfaceDescr, type_XInterface);
+ uno::TypeDescription acquire(
+ reinterpret_cast< typelib_InterfaceTypeDescription * >(
+ pTXInterfaceDescr)->ppAllMembers[1]);
+ TYPELIB_DANGER_RELEASE(pTXInterfaceDescr);
+
+ return acquire;
+}
+
+static uno::TypeDescription getReleaseMethod(void)
+{
+ typelib_TypeDescriptionReference * type_XInterface =
+ * typelib_static_type_getByTypeClass(typelib_TypeClass_INTERFACE);
+
+ typelib_TypeDescription * pTXInterfaceDescr = 0;
+ TYPELIB_DANGER_GET (&pTXInterfaceDescr, type_XInterface);
+ uno::TypeDescription release(
+ reinterpret_cast< typelib_InterfaceTypeDescription * >(
+ pTXInterfaceDescr)->ppAllMembers[2]);
+ TYPELIB_DANGER_RELEASE(pTXInterfaceDescr);
+
+ return release;
+}
+
+static uno::TypeDescription s_acquireMethod(getAcquireMethod());
+static uno::TypeDescription s_releaseMethod(getReleaseMethod());
+
+void Proxy::acquire(void)
+{
+ if (m_probeFun)
+ m_probeFun(true,
+ this,
+ m_pProbeContext,
+ *typelib_static_type_getByTypeClass(typelib_TypeClass_VOID),
+ NULL,
+ 0,
+ s_acquireMethod.get(),
+ NULL,
+ NULL,
+ NULL);
+
+ if (osl_incrementInterlockedCount(&m_nRef) == 1)
+ {
+ // rebirth of proxy zombie
+ void * pThis = this;
+ m_from.get()->pExtEnv->registerProxyInterface(m_from.get()->pExtEnv,
+ &pThis,
+ Proxy_free,
+ m_aOId.pData,
+ m_pTypeDescr);
+ OSL_ASSERT(pThis == this);
+ }
+
+ if (m_probeFun)
+ m_probeFun(false,
+ this,
+ m_pProbeContext,
+ *typelib_static_type_getByTypeClass(typelib_TypeClass_VOID),
+ NULL,
+ 0,
+ s_acquireMethod.get(),
+ NULL,
+ NULL,
+ NULL);
+
+}
+
+void Proxy::release(void)
+{
+ cppu::helper::purpenv::ProbeFun * probeFun = m_probeFun;
+ void * pProbeContext = m_pProbeContext;
+
+ if (m_probeFun)
+ m_probeFun(true,
+ this,
+ m_pProbeContext,
+ *typelib_static_type_getByTypeClass(typelib_TypeClass_VOID),
+ NULL,
+ 0,
+ s_releaseMethod.get(),
+ NULL,
+ NULL,
+ NULL);
+
+ if (osl_decrementInterlockedCount(&m_nRef) == 0)
+ m_from.get()->pExtEnv->revokeInterface(m_from.get()->pExtEnv, this);
+
+ if (probeFun)
+ probeFun(false,
+ this,
+ pProbeContext,
+ *typelib_static_type_getByTypeClass(typelib_TypeClass_VOID),
+ NULL,
+ 0,
+ s_releaseMethod.get(),
+ NULL,
+ NULL,
+ NULL);
+
+}
+
+
+extern "C" {
+static void s_type_destructData_v(va_list * pParam)
+{
+ void * ret = va_arg(*pParam, void *);
+ typelib_TypeDescriptionReference * pReturnTypeRef = va_arg(*pParam, typelib_TypeDescriptionReference *);
+
+ uno_type_destructData(ret, pReturnTypeRef, 0);
+}
+
+static void s_dispatcher_v(va_list * pParam)
+{
+ uno_Interface * pUnoI = va_arg(*pParam, uno_Interface *);
+ typelib_TypeDescription const * pMemberType = va_arg(*pParam, typelib_TypeDescription const *);
+ void * pReturn = va_arg(*pParam, void *);
+ void ** pArgs = va_arg(*pParam, void **);
+ uno_Any ** ppException = va_arg(*pParam, uno_Any **);
+
+ pUnoI->pDispatcher(pUnoI, pMemberType, pReturn, pArgs, ppException);
+}
+}
+
+void Proxy::dispatch(typelib_TypeDescriptionReference * pReturnTypeRef,
+ typelib_MethodParameter * pParams,
+ sal_Int32 nParams,
+ typelib_TypeDescription const * pMemberType,
+ void * pReturn,
+ void * pArgs[],
+ uno_Any ** ppException)
+{
+ if (m_probeFun)
+ m_probeFun(true,
+ this,
+ m_pProbeContext,
+ pReturnTypeRef,
+ pParams,
+ nParams,
+ pMemberType,
+ pReturn,
+ pArgs,
+ ppException);
+
+ void ** args = (void **) alloca( sizeof (void *) * nParams );
+
+ typelib_TypeDescription * return_td = 0;
+ void * ret = pReturn;
+ if (pReturnTypeRef)
+ {
+ TYPELIB_DANGER_GET(&return_td, pReturnTypeRef);
+
+ if (relatesToInterface(return_td))
+ ret = alloca(return_td->nSize);
+
+ TYPELIB_DANGER_RELEASE(return_td);
+ }
+
+ for (sal_Int32 nPos = 0; nPos < nParams; ++ nPos)
+ {
+ typelib_MethodParameter const & param = pParams[nPos];
+ typelib_TypeDescription * td = 0;
+ TYPELIB_DANGER_GET( &td, param.pTypeRef );
+ if (relatesToInterface(td))
+ {
+ args[nPos] = alloca(td->nSize);
+ if (param.bIn)
+ {
+ uno_copyAndConvertData(args[nPos], pArgs[nPos], td, m_from_to.get());
+ }
+ }
+ else
+ {
+ args[nPos] = pArgs[nPos];
+ }
+ TYPELIB_DANGER_RELEASE( td );
+ }
+
+ uno_Any exc_data;
+ uno_Any * exc = &exc_data;
+
+ // do the UNO call...
+ uno_Environment_invoke(m_to.get(), s_dispatcher_v, m_pUnoI, pMemberType, ret, args, &exc);
+
+ if (exc == 0)
+ {
+ for (sal_Int32 nPos = 0; nPos < nParams; ++ nPos)
+ {
+ if (args[nPos] != pArgs[nPos])
+ {
+ typelib_MethodParameter const & param = pParams[nPos];
+ if (param.bOut)
+ {
+ if (param.bIn) // is inout
+ {
+ uno_type_destructData(pArgs[nPos], param.pTypeRef, 0);
+ }
+ uno_type_copyAndConvertData(pArgs[ nPos ],
+ args[ nPos ],
+ param.pTypeRef,
+ m_to_from.get());
+ }
+ uno_Environment_invoke(m_to.get(), s_type_destructData_v, args[nPos], param.pTypeRef, 0);
+ }
+ }
+ if (ret != pReturn)
+ {
+ uno_type_copyAndConvertData(pReturn,
+ ret,
+ pReturnTypeRef,
+ m_to_from.get());
+
+ uno_Environment_invoke(m_to.get(), s_type_destructData_v, ret, pReturnTypeRef, 0);
+ }
+
+ *ppException = 0;
+ }
+ else // exception occured
+ {
+ for (sal_Int32 nPos = 0; nPos < nParams; ++ nPos)
+ {
+ if (args[nPos] != pArgs[nPos])
+ {
+ typelib_MethodParameter const & param = pParams[nPos];
+ if (param.bIn)
+ {
+ uno_Environment_invoke(m_to.get(), s_type_destructData_v, args[nPos], param.pTypeRef, 0);
+ }
+ }
+ }
+
+ uno_type_any_constructAndConvert(*ppException,
+ exc->pData,
+ exc->pType,
+ m_to_from.get());
+
+ // FIXME: need to destruct in m_to
+ uno_any_destruct(exc, 0);
+ }
+
+ if (m_probeFun)
+ m_probeFun(false,
+ this,
+ m_pProbeContext,
+ pReturnTypeRef,
+ pParams,
+ nParams,
+ pMemberType,
+ pReturn,
+ pArgs,
+ ppException);
+}
+
diff --git a/cppu/source/helper/purpenv/makefile.mk b/cppu/source/helper/purpenv/makefile.mk
new file mode 100644
index 000000000000..0517a95579cc
--- /dev/null
+++ b/cppu/source/helper/purpenv/makefile.mk
@@ -0,0 +1,46 @@
+#*************************************************************************
+#
+# 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 := helper_purpenv
+
+
+ENABLE_EXCEPTIONS := TRUE
+NO_BSYMBOLIC := TRUE
+USE_DEFFILE := TRUE
+
+
+.INCLUDE : settings.mk
+
+SLOFILES := \
+ $(SLO)$/helper_purpenv_Environment.obj \
+ $(SLO)$/helper_purpenv_Mapping.obj \
+ $(SLO)$/helper_purpenv_Proxy.obj
+
+
+.INCLUDE : target.mk
diff --git a/cppu/source/threadpool/current.cxx b/cppu/source/threadpool/current.cxx
new file mode 100644
index 000000000000..db814a50991b
--- /dev/null
+++ b/cppu/source/threadpool/current.cxx
@@ -0,0 +1,299 @@
+/*************************************************************************
+ *
+ * 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/uuid.h"
+#include "osl/thread.h"
+#include "osl/mutex.hxx"
+
+#include "uno/environment.hxx"
+#include "uno/mapping.hxx"
+#include "uno/lbnames.h"
+#include "typelib/typedescription.h"
+
+#include "current.hxx"
+
+
+using namespace ::osl;
+using namespace ::rtl;
+using namespace ::cppu;
+using namespace ::com::sun::star::uno;
+
+namespace cppu
+{
+
+//--------------------------------------------------------------------------------------------------
+class SAL_NO_VTABLE XInterface
+{
+public:
+ virtual void SAL_CALL slot_queryInterface() = 0;
+ virtual void SAL_CALL acquire() throw () = 0;
+ virtual void SAL_CALL release() throw () = 0;
+};
+//--------------------------------------------------------------------------------------------------
+static typelib_InterfaceTypeDescription * get_type_XCurrentContext()
+{
+ static typelib_InterfaceTypeDescription * s_type_XCurrentContext = 0;
+ if (0 == s_type_XCurrentContext)
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if (0 == s_type_XCurrentContext)
+ {
+ OUString sTypeName( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XCurrentContext") );
+ typelib_InterfaceTypeDescription * pTD = 0;
+ typelib_TypeDescriptionReference * pMembers[1] = { 0 };
+ OUString sMethodName0(
+ RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XCurrentContext::getValueByName") );
+ typelib_typedescriptionreference_new(
+ &pMembers[0],
+ typelib_TypeClass_INTERFACE_METHOD,
+ sMethodName0.pData );
+ typelib_typedescription_newInterface(
+ &pTD,
+ sTypeName.pData, 0x00000000, 0x0000, 0x0000, 0x00000000, 0x00000000,
+ * typelib_static_type_getByTypeClass( typelib_TypeClass_INTERFACE ),
+ 1,
+ pMembers );
+
+ typelib_typedescription_register( (typelib_TypeDescription**)&pTD );
+ typelib_typedescriptionreference_release( pMembers[0] );
+
+ typelib_InterfaceMethodTypeDescription * pMethod = 0;
+ typelib_Parameter_Init aParameters[1];
+ OUString sParamName0( RTL_CONSTASCII_USTRINGPARAM("Name") );
+ OUString sParamType0( RTL_CONSTASCII_USTRINGPARAM("string") );
+ aParameters[0].pParamName = sParamName0.pData;
+ aParameters[0].eTypeClass = typelib_TypeClass_STRING;
+ aParameters[0].pTypeName = sParamType0.pData;
+ aParameters[0].bIn = sal_True;
+ aParameters[0].bOut = sal_False;
+ rtl_uString * pExceptions[1];
+ OUString sExceptionName0(
+ RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.RuntimeException") );
+ pExceptions[0] = sExceptionName0.pData;
+ OUString sReturnType0( RTL_CONSTASCII_USTRINGPARAM("any") );
+ typelib_typedescription_newInterfaceMethod(
+ &pMethod,
+ 3, sal_False,
+ sMethodName0.pData,
+ typelib_TypeClass_ANY, sReturnType0.pData,
+ 1, aParameters, 1, pExceptions );
+ typelib_typedescription_register( (typelib_TypeDescription**)&pMethod );
+ typelib_typedescription_release( (typelib_TypeDescription*)pMethod );
+#if ! defined CPPU_LEAK_STATIC_DATA
+ // another static ref
+ ++reinterpret_cast< typelib_TypeDescription * >( pTD )->
+ nStaticRefCount;
+#endif
+ s_type_XCurrentContext = pTD;
+ }
+ }
+ return s_type_XCurrentContext;
+}
+
+//##################################################################################################
+
+//==================================================================================================
+class ThreadKey
+{
+ sal_Bool _bInit;
+ oslThreadKey _hThreadKey;
+ oslThreadKeyCallbackFunction _pCallback;
+
+public:
+ inline oslThreadKey getThreadKey() SAL_THROW( () );
+
+ inline ThreadKey( oslThreadKeyCallbackFunction pCallback ) SAL_THROW( () );
+ inline ~ThreadKey() SAL_THROW( () );
+};
+//__________________________________________________________________________________________________
+inline ThreadKey::ThreadKey( oslThreadKeyCallbackFunction pCallback ) SAL_THROW( () )
+ : _bInit( sal_False )
+ , _pCallback( pCallback )
+{
+}
+//__________________________________________________________________________________________________
+inline ThreadKey::~ThreadKey() SAL_THROW( () )
+{
+ if (_bInit)
+ {
+ ::osl_destroyThreadKey( _hThreadKey );
+ }
+}
+//__________________________________________________________________________________________________
+inline oslThreadKey ThreadKey::getThreadKey() SAL_THROW( () )
+{
+ if (! _bInit)
+ {
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ if (! _bInit)
+ {
+ _hThreadKey = ::osl_createThreadKey( _pCallback );
+ _bInit = sal_True;
+ }
+ }
+ return _hThreadKey;
+}
+
+//==================================================================================================
+extern "C" void SAL_CALL delete_IdContainer( void * p )
+{
+ if (p)
+ {
+ IdContainer * pId = reinterpret_cast< IdContainer * >( p );
+ if (pId->pCurrentContext)
+ {
+ (*pId->pCurrentContextEnv->releaseInterface)(
+ pId->pCurrentContextEnv, pId->pCurrentContext );
+ (*((uno_Environment *)pId->pCurrentContextEnv)->release)(
+ (uno_Environment *)pId->pCurrentContextEnv );
+ }
+ if (pId->bInit)
+ {
+ ::rtl_byte_sequence_release( pId->pLocalThreadId );
+ ::rtl_byte_sequence_release( pId->pCurrentId );
+ }
+ delete pId;
+ }
+}
+//==================================================================================================
+IdContainer * getIdContainer() SAL_THROW( () )
+{
+ static ThreadKey s_key( delete_IdContainer );
+ oslThreadKey aKey = s_key.getThreadKey();
+
+ IdContainer * pId = reinterpret_cast< IdContainer * >( ::osl_getThreadKeyData( aKey ) );
+ if (! pId)
+ {
+ pId = new IdContainer();
+ pId->pCurrentContext = 0;
+ pId->pCurrentContextEnv = 0;
+ pId->bInit = sal_False;
+ ::osl_setThreadKeyData( aKey, pId );
+ }
+ return pId;
+}
+
+}
+
+//##################################################################################################
+extern "C" sal_Bool SAL_CALL uno_setCurrentContext(
+ void * pCurrentContext,
+ rtl_uString * pEnvTypeName, void * pEnvContext )
+ SAL_THROW_EXTERN_C()
+{
+ IdContainer * pId = getIdContainer();
+ OSL_ASSERT( pId );
+
+ // free old one
+ if (pId->pCurrentContext)
+ {
+ (*pId->pCurrentContextEnv->releaseInterface)(
+ pId->pCurrentContextEnv, pId->pCurrentContext );
+ (*((uno_Environment *)pId->pCurrentContextEnv)->release)(
+ (uno_Environment *)pId->pCurrentContextEnv );
+ pId->pCurrentContextEnv = 0;
+
+ pId->pCurrentContext = 0;
+ }
+
+ if (pCurrentContext)
+ {
+ uno_Environment * pEnv = 0;
+ ::uno_getEnvironment( &pEnv, pEnvTypeName, pEnvContext );
+ OSL_ASSERT( pEnv && pEnv->pExtEnv );
+ if (pEnv)
+ {
+ if (pEnv->pExtEnv)
+ {
+ pId->pCurrentContextEnv = pEnv->pExtEnv;
+ (*pId->pCurrentContextEnv->acquireInterface)(
+ pId->pCurrentContextEnv, pCurrentContext );
+ pId->pCurrentContext = pCurrentContext;
+ }
+ else
+ {
+ (*pEnv->release)( pEnv );
+ return sal_False;
+ }
+ }
+ else
+ {
+ return sal_False;
+ }
+ }
+ return sal_True;
+}
+//##################################################################################################
+extern "C" sal_Bool SAL_CALL uno_getCurrentContext(
+ void ** ppCurrentContext, rtl_uString * pEnvTypeName, void * pEnvContext )
+ SAL_THROW_EXTERN_C()
+{
+ IdContainer * pId = getIdContainer();
+ OSL_ASSERT( pId );
+
+ Environment target_env;
+
+ // release inout parameter
+ if (*ppCurrentContext)
+ {
+ target_env = Environment(rtl::OUString(pEnvTypeName), pEnvContext);
+ OSL_ASSERT( target_env.is() );
+ if (! target_env.is())
+ return sal_False;
+ uno_ExtEnvironment * pEnv = target_env.get()->pExtEnv;
+ OSL_ASSERT( 0 != pEnv );
+ if (0 == pEnv)
+ return sal_False;
+ (*pEnv->releaseInterface)( pEnv, *ppCurrentContext );
+
+ *ppCurrentContext = 0;
+ }
+
+ // case: null-ref
+ if (0 == pId->pCurrentContext)
+ return sal_True;
+
+ if (! target_env.is())
+ {
+ target_env = Environment(rtl::OUString(pEnvTypeName), pEnvContext);
+ OSL_ASSERT( target_env.is() );
+ if (! target_env.is())
+ return sal_False;
+ }
+
+ Mapping mapping((uno_Environment *) pId->pCurrentContextEnv, target_env.get());
+ OSL_ASSERT( mapping.is() );
+ if (! mapping.is())
+ return sal_False;
+
+ mapping.mapInterface(ppCurrentContext, pId->pCurrentContext, ::cppu::get_type_XCurrentContext() );
+
+ return sal_True;
+}
diff --git a/cppu/source/threadpool/current.hxx b/cppu/source/threadpool/current.hxx
new file mode 100644
index 000000000000..fbe0531cf178
--- /dev/null
+++ b/cppu/source/threadpool/current.hxx
@@ -0,0 +1,48 @@
+/*************************************************************************
+ *
+ * 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/byteseq.h"
+
+typedef struct _uno_ExtEnvironment uno_ExtEnvironment;
+
+namespace cppu
+{
+struct CurrentContext;
+
+struct IdContainer
+{
+ void * pCurrentContext;
+ uno_ExtEnvironment * pCurrentContextEnv;
+ //
+ sal_Bool bInit;
+ sal_Sequence * pLocalThreadId;
+ sal_Int32 nRefCountOfCurrentId;
+ sal_Sequence * pCurrentId;
+};
+
+IdContainer * getIdContainer() SAL_THROW( () );
+}
diff --git a/cppu/source/threadpool/jobqueue.cxx b/cppu/source/threadpool/jobqueue.cxx
new file mode 100644
index 000000000000..2604af98dee4
--- /dev/null
+++ b/cppu/source/threadpool/jobqueue.cxx
@@ -0,0 +1,191 @@
+/*************************************************************************
+ *
+ * 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 "jobqueue.hxx"
+#include "threadpool.hxx"
+
+#include <osl/diagnose.h>
+
+using namespace ::osl;
+
+namespace cppu_threadpool {
+
+ JobQueue::JobQueue() :
+ m_nToDo( 0 ),
+ m_bSuspended( sal_False ),
+ m_cndWait( osl_createCondition() )
+ {
+ osl_resetCondition( m_cndWait );
+ }
+
+ JobQueue::~JobQueue()
+ {
+ osl_destroyCondition( m_cndWait );
+ }
+
+
+ void JobQueue::add( void *pThreadSpecificData, RequestFun * doRequest )
+ {
+ MutexGuard guard( m_mutex );
+ Job job = { pThreadSpecificData , doRequest };
+ m_lstJob.push_back( job );
+ if( ! m_bSuspended )
+ {
+ osl_setCondition( m_cndWait );
+ }
+ m_nToDo ++;
+ }
+
+ void *JobQueue::enter( sal_Int64 nDisposeId , sal_Bool bReturnWhenNoJob )
+ {
+ void *pReturn = 0;
+ {
+ // synchronize with the dispose calls
+ MutexGuard guard( m_mutex );
+ if( DisposedCallerAdmin::getInstance()->isDisposed( nDisposeId ) )
+ {
+ return 0;
+ }
+ m_lstCallstack.push_front( nDisposeId );
+ }
+
+
+ while( sal_True )
+ {
+ if( bReturnWhenNoJob )
+ {
+ MutexGuard guard( m_mutex );
+ if( m_lstJob.empty() )
+ {
+ break;
+ }
+ }
+
+ osl_waitCondition( m_cndWait , 0 );
+
+ struct Job job={0,0};
+ {
+ // synchronize with add and dispose calls
+ MutexGuard guard( m_mutex );
+
+ if( 0 == m_lstCallstack.front() )
+ {
+ // disposed !
+ break;
+ }
+
+ OSL_ASSERT( ! m_lstJob.empty() );
+ if( ! m_lstJob.empty() )
+ {
+ job = m_lstJob.front();
+ m_lstJob.pop_front();
+ }
+ if( m_lstJob.empty() )
+ {
+ osl_resetCondition( m_cndWait );
+ }
+ }
+
+ if( job.doRequest )
+ {
+ job.doRequest( job.pThreadSpecificData );
+ m_nToDo --;
+ }
+ else
+ {
+ m_nToDo --;
+ pReturn = job.pThreadSpecificData;
+ break;
+ }
+ }
+
+ {
+ // synchronize with the dispose calls
+ MutexGuard guard( m_mutex );
+ m_lstCallstack.pop_front();
+ }
+
+ return pReturn;
+ }
+
+ void JobQueue::dispose( sal_Int64 nDisposeId )
+ {
+ MutexGuard guard( m_mutex );
+ for( CallStackList::iterator ii = m_lstCallstack.begin() ;
+ ii != m_lstCallstack.end() ;
+ ++ii )
+ {
+ if( (*ii) == nDisposeId )
+ {
+ (*ii) = 0;
+ }
+ }
+
+ if( !m_lstCallstack.empty() && ! m_lstCallstack.front() )
+ {
+ // The thread is waiting for a disposed pCallerId, let it go
+ osl_setCondition( m_cndWait );
+ }
+ }
+
+ void JobQueue::suspend()
+ {
+ MutexGuard guard( m_mutex );
+ m_bSuspended = sal_True;
+ }
+
+ void JobQueue::resume()
+ {
+ MutexGuard guard( m_mutex );
+ m_bSuspended = sal_False;
+ if( ! m_lstJob.empty() )
+ {
+ osl_setCondition( m_cndWait );
+ }
+ }
+
+ sal_Bool JobQueue::isEmpty()
+ {
+ MutexGuard guard( m_mutex );
+ return m_lstJob.empty();
+ }
+
+ sal_Bool JobQueue::isCallstackEmpty()
+ {
+ MutexGuard guard( m_mutex );
+ return m_lstCallstack.empty();
+ }
+
+ sal_Bool JobQueue::isBusy()
+ {
+ return m_nToDo > 0;
+ }
+
+
+}
diff --git a/cppu/source/threadpool/jobqueue.hxx b/cppu/source/threadpool/jobqueue.hxx
new file mode 100644
index 000000000000..5f610b4a2fce
--- /dev/null
+++ b/cppu/source/threadpool/jobqueue.hxx
@@ -0,0 +1,79 @@
+/*************************************************************************
+ *
+ * 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 _CPPU_THREADPOOL_JOBQUEUE_HXX_
+#define _CPPU_THREADPOOL_JOBQUEUE_HXX_
+
+#include <list>
+#include <sal/types.h>
+
+#include <osl/conditn.h>
+#include <osl/mutex.hxx>
+
+namespace cppu_threadpool
+{
+ extern "C" typedef void (SAL_CALL RequestFun)(void *);
+
+ struct Job
+ {
+ void *pThreadSpecificData;
+ RequestFun * doRequest;
+ };
+
+ typedef ::std::list < struct Job > JobList;
+
+ typedef ::std::list < sal_Int64 > CallStackList;
+
+ class JobQueue
+ {
+ public:
+ JobQueue();
+ ~JobQueue();
+
+ void add( void *pThreadSpecificData, RequestFun * doRequest );
+
+ void *enter( sal_Int64 nDisposeId , sal_Bool bReturnWhenNoJob = sal_False );
+ void dispose( sal_Int64 nDisposeId );
+
+ void suspend();
+ void resume();
+
+ sal_Bool isEmpty();
+ sal_Bool isCallstackEmpty();
+ sal_Bool isBusy();
+
+ private:
+ ::osl::Mutex m_mutex;
+ JobList m_lstJob;
+ CallStackList m_lstCallstack;
+ sal_Int32 m_nToDo;
+ sal_Bool m_bSuspended;
+ oslCondition m_cndWait;
+ };
+}
+
+#endif
diff --git a/cppu/source/threadpool/makefile.mk b/cppu/source/threadpool/makefile.mk
new file mode 100644
index 000000000000..ea5e146b9cf6
--- /dev/null
+++ b/cppu/source/threadpool/makefile.mk
@@ -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.
+#
+#*************************************************************************
+PRJ=..$/..
+
+PRJNAME=cppu
+TARGET=cppu_threadpool
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : ..$/..$/util$/makefile.pmk
+.INCLUDE : settings.mk
+
+# ------------------------------------------------------------------
+
+SLOFILES=\
+ $(SLO)$/threadpool.obj\
+ $(SLO)$/jobqueue.obj\
+ $(SLO)$/thread.obj\
+ $(SLO)$/threadident.obj\
+ $(SLO)$/current.obj
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : ..$/..$/util$/target.pmk
+.INCLUDE : target.mk
diff --git a/cppu/source/threadpool/thread.cxx b/cppu/source/threadpool/thread.cxx
new file mode 100644
index 000000000000..b043dd4e907a
--- /dev/null
+++ b/cppu/source/threadpool/thread.cxx
@@ -0,0 +1,217 @@
+/*************************************************************************
+ *
+ * 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 <stdio.h>
+#include <osl/diagnose.h>
+#include <uno/threadpool.h>
+
+#include "thread.hxx"
+#include "jobqueue.hxx"
+#include "threadpool.hxx"
+
+
+using namespace osl;
+extern "C" {
+
+void SAL_CALL cppu_requestThreadWorker( void *pVoid )
+{
+ ::cppu_threadpool::ORequestThread *pThread = ( ::cppu_threadpool::ORequestThread * ) pVoid;
+
+ pThread->run();
+ pThread->onTerminated();
+}
+
+}
+
+namespace cppu_threadpool {
+
+// ----------------------------------------------------------------------------------
+ ThreadAdmin::~ThreadAdmin()
+ {
+#if OSL_DEBUG_LEVEL > 1
+ if( m_lst.size() )
+ {
+ fprintf( stderr, "%lu Threads left\n" , static_cast<unsigned long>(m_lst.size()) );
+ }
+#endif
+ }
+
+ void ThreadAdmin::add( ORequestThread *p )
+ {
+ MutexGuard aGuard( m_mutex );
+ m_lst.push_back( p );
+ }
+
+ void ThreadAdmin::remove( ORequestThread * p )
+ {
+ MutexGuard aGuard( m_mutex );
+ ::std::list< ORequestThread * >::iterator ii = ::std::find( m_lst.begin(), m_lst.end(), p );
+ OSL_ASSERT( ii != m_lst.end() );
+ m_lst.erase( ii );
+ }
+
+ void ThreadAdmin::join()
+ {
+ ORequestThread *pCurrent;
+ do
+ {
+ pCurrent = 0;
+ {
+ MutexGuard aGuard( m_mutex );
+ if( ! m_lst.empty() )
+ {
+ pCurrent = m_lst.front();
+ pCurrent->setDeleteSelf( sal_False );
+ }
+ }
+ if ( pCurrent )
+ {
+ pCurrent->join();
+ delete pCurrent;
+ }
+ } while( pCurrent );
+ }
+
+ ThreadAdmin* ThreadAdmin::getInstance()
+ {
+ static ThreadAdmin *pThreadAdmin = 0;
+ if( ! pThreadAdmin )
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if( ! pThreadAdmin )
+ {
+ static ThreadAdmin admin;
+ pThreadAdmin = &admin;
+ }
+ }
+ return pThreadAdmin;
+
+ }
+
+// ----------------------------------------------------------------------------------
+ ORequestThread::ORequestThread( JobQueue *pQueue,
+ const ByteSequence &aThreadId,
+ sal_Bool bAsynchron )
+ : m_thread( 0 )
+ , m_pQueue( pQueue )
+ , m_aThreadId( aThreadId )
+ , m_bAsynchron( bAsynchron )
+ , m_bDeleteSelf( sal_True )
+ {
+ ThreadAdmin::getInstance()->add( this );
+ }
+
+
+ ORequestThread::~ORequestThread()
+ {
+ if (m_thread != 0)
+ {
+ osl_destroyThread(m_thread);
+ }
+ }
+
+
+ void ORequestThread::setTask( JobQueue *pQueue,
+ const ByteSequence &aThreadId,
+ sal_Bool bAsynchron )
+ {
+ m_pQueue = pQueue;
+ m_aThreadId = aThreadId;
+ m_bAsynchron = bAsynchron;
+ }
+
+ sal_Bool ORequestThread::create()
+ {
+ OSL_ASSERT(m_thread == 0); // only one running thread per instance
+
+ m_thread = osl_createSuspendedThread( cppu_requestThreadWorker, (void*)this);
+ if ( m_thread )
+ {
+ osl_resumeThread( m_thread );
+ }
+
+ return m_thread != 0;
+ }
+
+ void ORequestThread::join()
+ {
+ osl_joinWithThread( m_thread );
+ }
+
+ void ORequestThread::onTerminated()
+ {
+ ThreadAdmin::getInstance()->remove( this );
+ if( m_bDeleteSelf )
+ {
+ delete this;
+ }
+ }
+
+ void ORequestThread::run()
+ {
+ while ( m_pQueue )
+ {
+ if( ! m_bAsynchron )
+ {
+ if ( !uno_bindIdToCurrentThread( m_aThreadId.getHandle() ) )
+ {
+ OSL_ASSERT( false );
+ }
+ }
+
+ while( ! m_pQueue->isEmpty() )
+ {
+ // Note : Oneways should not get a disposable disposeid,
+ // It does not make sense to dispose a call in this state.
+ // That's way we put it an disposeid, that can't be used otherwise.
+ m_pQueue->enter(
+ sal::static_int_cast< sal_Int64 >(
+ reinterpret_cast< sal_IntPtr >(this)),
+ sal_True );
+
+ if( m_pQueue->isEmpty() )
+ {
+ ThreadPool::getInstance()->revokeQueue( m_aThreadId , m_bAsynchron );
+ // Note : revokeQueue might have failed because m_pQueue.isEmpty()
+ // may be false (race).
+ }
+ }
+
+ delete m_pQueue;
+ m_pQueue = 0;
+
+ if( ! m_bAsynchron )
+ {
+ uno_releaseIdFromCurrentThread();
+ }
+
+ cppu_threadpool::ThreadPool::getInstance()->waitInPool( this );
+ }
+ }
+}
diff --git a/cppu/source/threadpool/thread.hxx b/cppu/source/threadpool/thread.hxx
new file mode 100644
index 000000000000..639f26c5339b
--- /dev/null
+++ b/cppu/source/threadpool/thread.hxx
@@ -0,0 +1,88 @@
+/*************************************************************************
+ *
+ * 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 _CPPU_THREADPOOL_THREAD_HXX
+#define _CPPU_THREADPOOL_THREAD_HXX
+
+#include <list>
+#include <sal/types.h>
+
+#include <osl/thread.h>
+
+#include "jobqueue.hxx"
+
+namespace cppu_threadpool {
+
+ class JobQueue;
+
+ //-----------------------------------------
+ // private thread class for the threadpool
+ // independent from vos
+ //-----------------------------------------
+ class ORequestThread
+ {
+ public:
+ ORequestThread( JobQueue * ,
+ const ::rtl::ByteSequence &aThreadId,
+ sal_Bool bAsynchron );
+ ~ORequestThread();
+
+ void setTask( JobQueue * , const ::rtl::ByteSequence & aThreadId , sal_Bool bAsynchron );
+
+ sal_Bool create();
+ void join();
+ void onTerminated();
+ void run();
+ inline void setDeleteSelf( sal_Bool b )
+ { m_bDeleteSelf = b; }
+
+ private:
+ oslThread m_thread;
+ JobQueue *m_pQueue;
+ ::rtl::ByteSequence m_aThreadId;
+ sal_Bool m_bAsynchron;
+ sal_Bool m_bDeleteSelf;
+ };
+
+ class ThreadAdmin
+ {
+ public:
+ ~ThreadAdmin ();
+ static ThreadAdmin *getInstance();
+ void add( ORequestThread * );
+ void remove( ORequestThread * );
+ void join();
+
+ private:
+ ::osl::Mutex m_mutex;
+ ::std::list< ORequestThread * > m_lst;
+ };
+
+} // end cppu_threadpool
+
+
+#endif
+
diff --git a/cppu/source/threadpool/threadident.cxx b/cppu/source/threadpool/threadident.cxx
new file mode 100644
index 000000000000..0fb6c1196185
--- /dev/null
+++ b/cppu/source/threadpool/threadident.cxx
@@ -0,0 +1,135 @@
+/*************************************************************************
+ *
+ * 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 <stdio.h>
+
+#include <list>
+
+#include <osl/mutex.hxx>
+#include <osl/thread.h>
+#include <osl/diagnose.h>
+
+#include <rtl/process.h>
+#include <rtl/byteseq.hxx>
+
+#include <uno/threadpool.h>
+
+#include "current.hxx"
+
+
+using namespace ::std;
+using namespace ::osl;
+using namespace ::rtl;
+using namespace ::cppu;
+
+
+static inline void createLocalId( sal_Sequence **ppThreadId )
+{
+ rtl_byte_sequence_constructNoDefault( ppThreadId , 4 + 16 );
+ *((sal_Int32*) ((*ppThreadId)->elements)) = osl_getThreadIdentifier(0);
+
+ rtl_getGlobalProcessId( (sal_uInt8 * ) &( (*ppThreadId)->elements[4]) );
+}
+
+
+extern "C" void SAL_CALL
+uno_getIdOfCurrentThread( sal_Sequence **ppThreadId )
+ SAL_THROW_EXTERN_C()
+{
+ IdContainer * p = getIdContainer();
+ if( ! p->bInit )
+ {
+ // first time, that the thread enters the bridge
+ createLocalId( ppThreadId );
+
+ // TODO
+ // note : this is a leak !
+ p->pLocalThreadId = *ppThreadId;
+ p->pCurrentId = *ppThreadId;
+ p->nRefCountOfCurrentId = 1;
+ rtl_byte_sequence_acquire( p->pLocalThreadId );
+ rtl_byte_sequence_acquire( p->pCurrentId );
+ p->bInit = sal_True;
+ }
+ else
+ {
+ p->nRefCountOfCurrentId ++;
+ if( *ppThreadId )
+ {
+ rtl_byte_sequence_release( *ppThreadId );
+ }
+ *ppThreadId = p->pCurrentId;
+ rtl_byte_sequence_acquire( *ppThreadId );
+ }
+}
+
+
+extern "C" void SAL_CALL uno_releaseIdFromCurrentThread()
+ SAL_THROW_EXTERN_C()
+{
+ IdContainer *p = getIdContainer();
+ OSL_ASSERT( p );
+ OSL_ASSERT( p->nRefCountOfCurrentId );
+
+ p->nRefCountOfCurrentId --;
+ if( ! p->nRefCountOfCurrentId && (p->pLocalThreadId != p->pCurrentId) )
+ {
+ rtl_byte_sequence_assign( &(p->pCurrentId) , p->pLocalThreadId );
+ }
+}
+
+extern "C" sal_Bool SAL_CALL uno_bindIdToCurrentThread( sal_Sequence *pThreadId )
+ SAL_THROW_EXTERN_C()
+{
+ IdContainer *p = getIdContainer();
+ if( ! p->bInit )
+ {
+ p->pLocalThreadId = 0;
+ createLocalId( &(p->pLocalThreadId) );
+ p->nRefCountOfCurrentId = 1;
+ p->pCurrentId = pThreadId;
+ rtl_byte_sequence_acquire( p->pCurrentId );
+ p->bInit = sal_True;
+ }
+ else
+ {
+ OSL_ASSERT( 0 == p->nRefCountOfCurrentId );
+ if( 0 == p->nRefCountOfCurrentId )
+ {
+ rtl_byte_sequence_assign(&( p->pCurrentId ), pThreadId );
+ p->nRefCountOfCurrentId ++;
+ }
+ else
+ {
+ return sal_False;
+ }
+
+ }
+ return sal_True;
+}
diff --git a/cppu/source/threadpool/threadpool.cxx b/cppu/source/threadpool/threadpool.cxx
new file mode 100644
index 000000000000..accf585957f8
--- /dev/null
+++ b/cppu/source/threadpool/threadpool.cxx
@@ -0,0 +1,502 @@
+/*************************************************************************
+ *
+ * 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 <hash_set>
+#include <stdio.h>
+
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+#include <osl/thread.h>
+
+#include <uno/threadpool.h>
+
+#include "threadpool.hxx"
+#include "thread.hxx"
+
+using namespace ::std;
+using namespace ::osl;
+
+namespace cppu_threadpool
+{
+ DisposedCallerAdmin *DisposedCallerAdmin::getInstance()
+ {
+ static DisposedCallerAdmin *pDisposedCallerAdmin = 0;
+ if( ! pDisposedCallerAdmin )
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if( ! pDisposedCallerAdmin )
+ {
+ static DisposedCallerAdmin admin;
+ pDisposedCallerAdmin = &admin;
+ }
+ }
+ return pDisposedCallerAdmin;
+ }
+
+ DisposedCallerAdmin::~DisposedCallerAdmin()
+ {
+#if OSL_DEBUG_LEVEL > 1
+ if( !m_lst.empty() )
+ {
+ printf( "DisposedCallerList : %lu left\n" , static_cast<unsigned long>(m_lst.size( )));
+ }
+#endif
+ }
+
+ void DisposedCallerAdmin::dispose( sal_Int64 nDisposeId )
+ {
+ MutexGuard guard( m_mutex );
+ m_lst.push_back( nDisposeId );
+ }
+
+ void DisposedCallerAdmin::stopDisposing( sal_Int64 nDisposeId )
+ {
+ MutexGuard guard( m_mutex );
+ for( DisposedCallerList::iterator ii = m_lst.begin() ;
+ ii != m_lst.end() ;
+ ++ ii )
+ {
+ if( (*ii) == nDisposeId )
+ {
+ m_lst.erase( ii );
+ break;
+ }
+ }
+ }
+
+ sal_Bool DisposedCallerAdmin::isDisposed( sal_Int64 nDisposeId )
+ {
+ MutexGuard guard( m_mutex );
+ for( DisposedCallerList::iterator ii = m_lst.begin() ;
+ ii != m_lst.end() ;
+ ++ ii )
+ {
+ if( (*ii) == nDisposeId )
+ {
+ return sal_True;
+ }
+ }
+ return sal_False;
+ }
+
+
+ //-------------------------------------------------------------------------------
+ ThreadPool::~ThreadPool()
+ {
+#if OSL_DEBUG_LEVEL > 1
+ if( m_mapQueue.size() )
+ {
+ printf( "ThreadIdHashMap : %lu left\n" , static_cast<unsigned long>(m_mapQueue.size()) );
+ }
+#endif
+ }
+ ThreadPool *ThreadPool::getInstance()
+ {
+ static ThreadPool *pThreadPool = 0;
+ if( ! pThreadPool )
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if( ! pThreadPool )
+ {
+ static ThreadPool pool;
+ pThreadPool = &pool;
+ }
+ }
+ return pThreadPool;
+ }
+
+
+ void ThreadPool::dispose( sal_Int64 nDisposeId )
+ {
+ if( nDisposeId )
+ {
+ DisposedCallerAdmin::getInstance()->dispose( nDisposeId );
+
+ MutexGuard guard( m_mutex );
+ for( ThreadIdHashMap::iterator ii = m_mapQueue.begin() ;
+ ii != m_mapQueue.end();
+ ++ii)
+ {
+ if( (*ii).second.first )
+ {
+ (*ii).second.first->dispose( nDisposeId );
+ }
+ if( (*ii).second.second )
+ {
+ (*ii).second.second->dispose( nDisposeId );
+ }
+ }
+ }
+ else
+ {
+ {
+ MutexGuard guard( m_mutexWaitingThreadList );
+ for( WaitingThreadList::iterator ii = m_lstThreads.begin() ;
+ ii != m_lstThreads.end() ;
+ ++ ii )
+ {
+ // wake the threads up
+ osl_setCondition( (*ii)->condition );
+ }
+ }
+ ThreadAdmin::getInstance()->join();
+ }
+ }
+
+ void ThreadPool::stopDisposing( sal_Int64 nDisposeId )
+ {
+ DisposedCallerAdmin::getInstance()->stopDisposing( nDisposeId );
+ }
+
+ /******************
+ * This methods lets the thread wait a certain amount of time. If within this timespan
+ * a new request comes in, this thread is reused. This is done only to improve performance,
+ * it is not required for threadpool functionality.
+ ******************/
+ void ThreadPool::waitInPool( ORequestThread * pThread )
+ {
+ struct WaitingThread waitingThread;
+ waitingThread.condition = osl_createCondition();
+ waitingThread.thread = pThread;
+ {
+ MutexGuard guard( m_mutexWaitingThreadList );
+ m_lstThreads.push_front( &waitingThread );
+ }
+
+ // let the thread wait 2 seconds
+ TimeValue time = { 2 , 0 };
+ osl_waitCondition( waitingThread.condition , &time );
+
+ {
+ MutexGuard guard ( m_mutexWaitingThreadList );
+ if( waitingThread.thread )
+ {
+ // thread wasn't reused, remove it from the list
+ WaitingThreadList::iterator ii = find(
+ m_lstThreads.begin(), m_lstThreads.end(), &waitingThread );
+ OSL_ASSERT( ii != m_lstThreads.end() );
+ m_lstThreads.erase( ii );
+ }
+ }
+
+ osl_destroyCondition( waitingThread.condition );
+ }
+
+ void ThreadPool::createThread( JobQueue *pQueue ,
+ const ByteSequence &aThreadId,
+ sal_Bool bAsynchron )
+ {
+ sal_Bool bCreate = sal_True;
+ {
+ // Can a thread be reused ?
+ MutexGuard guard( m_mutexWaitingThreadList );
+ if( ! m_lstThreads.empty() )
+ {
+ // inform the thread and let it go
+ struct WaitingThread *pWaitingThread = m_lstThreads.back();
+ pWaitingThread->thread->setTask( pQueue , aThreadId , bAsynchron );
+ pWaitingThread->thread = 0;
+
+ // remove from list
+ m_lstThreads.pop_back();
+
+ // let the thread go
+ osl_setCondition( pWaitingThread->condition );
+ bCreate = sal_False;
+ }
+ }
+
+ if( bCreate )
+ {
+ ORequestThread *pThread =
+ new ORequestThread( pQueue , aThreadId, bAsynchron);
+ // deletes itself !
+ pThread->create();
+ }
+ }
+
+ sal_Bool ThreadPool::revokeQueue( const ByteSequence &aThreadId, sal_Bool bAsynchron )
+ {
+ MutexGuard guard( m_mutex );
+
+ ThreadIdHashMap::iterator ii = m_mapQueue.find( aThreadId );
+ OSL_ASSERT( ii != m_mapQueue.end() );
+
+ if( bAsynchron )
+ {
+ if( ! (*ii).second.second->isEmpty() )
+ {
+ // another thread has put something into the queue
+ return sal_False;
+ }
+
+ (*ii).second.second = 0;
+ if( (*ii).second.first )
+ {
+ // all oneway request have been processed, now
+ // synchronus requests may go on
+ (*ii).second.first->resume();
+ }
+ }
+ else
+ {
+ if( ! (*ii).second.first->isEmpty() )
+ {
+ // another thread has put something into the queue
+ return sal_False;
+ }
+ (*ii).second.first = 0;
+ }
+
+ if( 0 == (*ii).second.first && 0 == (*ii).second.second )
+ {
+ m_mapQueue.erase( ii );
+ }
+
+ return sal_True;
+ }
+
+
+ void ThreadPool::addJob(
+ const ByteSequence &aThreadId ,
+ sal_Bool bAsynchron,
+ void *pThreadSpecificData,
+ RequestFun * doRequest )
+ {
+ sal_Bool bCreateThread = sal_False;
+ JobQueue *pQueue = 0;
+ {
+ MutexGuard guard( m_mutex );
+
+ ThreadIdHashMap::iterator ii = m_mapQueue.find( aThreadId );
+
+ if( ii == m_mapQueue.end() )
+ {
+ m_mapQueue[ aThreadId ] = pair < JobQueue * , JobQueue * > ( 0 , 0 );
+ ii = m_mapQueue.find( aThreadId );
+ OSL_ASSERT( ii != m_mapQueue.end() );
+ }
+
+ if( bAsynchron )
+ {
+ if( ! (*ii).second.second )
+ {
+ (*ii).second.second = new JobQueue();
+ bCreateThread = sal_True;
+ }
+ pQueue = (*ii).second.second;
+ }
+ else
+ {
+ if( ! (*ii).second.first )
+ {
+ (*ii).second.first = new JobQueue();
+ bCreateThread = sal_True;
+ }
+ pQueue = (*ii).second.first;
+
+ if( (*ii).second.second && ( (*ii).second.second->isBusy() ) )
+ {
+ pQueue->suspend();
+ }
+ }
+ pQueue->add( pThreadSpecificData , doRequest );
+ }
+
+ if( bCreateThread )
+ {
+ createThread( pQueue , aThreadId , bAsynchron);
+ }
+ }
+
+ void ThreadPool::prepare( const ByteSequence &aThreadId )
+ {
+ MutexGuard guard( m_mutex );
+
+ ThreadIdHashMap::iterator ii = m_mapQueue.find( aThreadId );
+
+ if( ii == m_mapQueue.end() )
+ {
+ JobQueue *p = new JobQueue();
+ m_mapQueue[ aThreadId ] = pair< JobQueue * , JobQueue * > ( p , 0 );
+ }
+ else if( 0 == (*ii).second.first )
+ {
+ (*ii).second.first = new JobQueue();
+ }
+ }
+
+ void * ThreadPool::enter( const ByteSequence & aThreadId , sal_Int64 nDisposeId )
+ {
+ JobQueue *pQueue = 0;
+ {
+ MutexGuard guard( m_mutex );
+
+ ThreadIdHashMap::iterator ii = m_mapQueue.find( aThreadId );
+
+ OSL_ASSERT( ii != m_mapQueue.end() );
+ pQueue = (*ii).second.first;
+ }
+
+ OSL_ASSERT( pQueue );
+ void *pReturn = pQueue->enter( nDisposeId );
+
+ if( pQueue->isCallstackEmpty() )
+ {
+ if( revokeQueue( aThreadId , sal_False) )
+ {
+ // remove queue
+ delete pQueue;
+ }
+ }
+ return pReturn;
+ }
+}
+
+
+using namespace cppu_threadpool;
+
+struct uno_ThreadPool_Equal
+{
+ sal_Bool operator () ( const uno_ThreadPool &a , const uno_ThreadPool &b ) const
+ {
+ return a == b;
+ }
+};
+
+struct uno_ThreadPool_Hash
+{
+ sal_Size operator () ( const uno_ThreadPool &a ) const
+ {
+ return (sal_Size) a;
+ }
+};
+
+
+
+typedef ::std::hash_set< uno_ThreadPool, uno_ThreadPool_Hash, uno_ThreadPool_Equal > ThreadpoolHashSet;
+
+static ThreadpoolHashSet *g_pThreadpoolHashSet;
+
+struct _uno_ThreadPool
+{
+ sal_Int32 dummy;
+};
+
+extern "C" uno_ThreadPool SAL_CALL
+uno_threadpool_create() SAL_THROW_EXTERN_C()
+{
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if( ! g_pThreadpoolHashSet )
+ {
+ g_pThreadpoolHashSet = new ThreadpoolHashSet();
+ }
+
+ // Just ensure that the handle is unique in the process (via heap)
+ uno_ThreadPool h = new struct _uno_ThreadPool;
+ g_pThreadpoolHashSet->insert( h );
+ return h;
+}
+
+extern "C" void SAL_CALL
+uno_threadpool_attach( uno_ThreadPool ) SAL_THROW_EXTERN_C()
+{
+ sal_Sequence *pThreadId = 0;
+ uno_getIdOfCurrentThread( &pThreadId );
+ ThreadPool::getInstance()->prepare( pThreadId );
+ rtl_byte_sequence_release( pThreadId );
+ uno_releaseIdFromCurrentThread();
+}
+
+extern "C" void SAL_CALL
+uno_threadpool_enter( uno_ThreadPool hPool , void **ppJob )
+ SAL_THROW_EXTERN_C()
+{
+ sal_Sequence *pThreadId = 0;
+ uno_getIdOfCurrentThread( &pThreadId );
+ *ppJob =
+ ThreadPool::getInstance()->enter(
+ pThreadId,
+ sal::static_int_cast< sal_Int64 >(
+ reinterpret_cast< sal_IntPtr >(hPool)) );
+ rtl_byte_sequence_release( pThreadId );
+ uno_releaseIdFromCurrentThread();
+}
+
+extern "C" void SAL_CALL
+uno_threadpool_detach( uno_ThreadPool ) SAL_THROW_EXTERN_C()
+{
+ // we might do here some tiding up in case a thread called attach but never detach
+}
+
+extern "C" void SAL_CALL
+uno_threadpool_putJob(
+ uno_ThreadPool,
+ sal_Sequence *pThreadId,
+ void *pJob,
+ void ( SAL_CALL * doRequest ) ( void *pThreadSpecificData ),
+ sal_Bool bIsOneway ) SAL_THROW_EXTERN_C()
+{
+ ThreadPool::getInstance()->addJob( pThreadId, bIsOneway, pJob ,doRequest );
+}
+
+extern "C" void SAL_CALL
+uno_threadpool_dispose( uno_ThreadPool hPool ) SAL_THROW_EXTERN_C()
+{
+ ThreadPool::getInstance()->dispose(
+ sal::static_int_cast< sal_Int64 >(
+ reinterpret_cast< sal_IntPtr >(hPool)) );
+}
+
+extern "C" void SAL_CALL
+uno_threadpool_destroy( uno_ThreadPool hPool ) SAL_THROW_EXTERN_C()
+{
+ ThreadPool::getInstance()->stopDisposing(
+ sal::static_int_cast< sal_Int64 >(
+ reinterpret_cast< sal_IntPtr >(hPool)) );
+
+ if( hPool )
+ {
+ // special treatment for 0 !
+ OSL_ASSERT( g_pThreadpoolHashSet );
+
+ MutexGuard guard( Mutex::getGlobalMutex() );
+
+ ThreadpoolHashSet::iterator ii = g_pThreadpoolHashSet->find( hPool );
+ OSL_ASSERT( ii != g_pThreadpoolHashSet->end() );
+ g_pThreadpoolHashSet->erase( ii );
+ delete hPool;
+
+ if( g_pThreadpoolHashSet->empty() )
+ {
+ delete g_pThreadpoolHashSet;
+ g_pThreadpoolHashSet = 0;
+ }
+ }
+}
diff --git a/cppu/source/threadpool/threadpool.hxx b/cppu/source/threadpool/threadpool.hxx
new file mode 100644
index 000000000000..cb580eaf92a2
--- /dev/null
+++ b/cppu/source/threadpool/threadpool.hxx
@@ -0,0 +1,129 @@
+/*************************************************************************
+ *
+ * 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 <hash_map>
+
+#include <osl/conditn.h>
+
+#include <rtl/byteseq.hxx>
+
+#include "jobqueue.hxx"
+
+
+using namespace ::rtl;
+namespace cppu_threadpool {
+ class ORequestThread;
+
+ struct EqualThreadId
+ {
+ sal_Int32 operator () ( const ::rtl::ByteSequence &a , const ::rtl::ByteSequence &b ) const
+ {
+ return a == b;
+ }
+ };
+
+ struct HashThreadId
+ {
+ sal_Int32 operator () ( const ::rtl::ByteSequence &a ) const
+ {
+ if( a.getLength() >= 4 )
+ {
+ return *(sal_Int32 *)a.getConstArray();
+ }
+ return 0;
+ }
+ };
+
+ typedef ::std::hash_map
+ <
+ ByteSequence, // ThreadID
+ ::std::pair < JobQueue * , JobQueue * >,
+ HashThreadId,
+ EqualThreadId
+ > ThreadIdHashMap;
+
+ typedef ::std::list < sal_Int64 > DisposedCallerList;
+
+
+ struct WaitingThread
+ {
+ oslCondition condition;
+ ORequestThread *thread;
+ };
+
+ typedef ::std::list < struct ::cppu_threadpool::WaitingThread * > WaitingThreadList;
+
+ class DisposedCallerAdmin
+ {
+ public:
+ ~DisposedCallerAdmin();
+
+ static DisposedCallerAdmin *getInstance();
+
+ void dispose( sal_Int64 nDisposeId );
+ void stopDisposing( sal_Int64 nDisposeId );
+ sal_Bool isDisposed( sal_Int64 nDisposeId );
+
+ private:
+ ::osl::Mutex m_mutex;
+ DisposedCallerList m_lst;
+ };
+
+ class ThreadPool
+ {
+ public:
+ ~ThreadPool();
+ static ThreadPool *getInstance();
+
+ void dispose( sal_Int64 nDisposeId );
+ void stopDisposing( sal_Int64 nDisposeId );
+
+ void addJob( const ByteSequence &aThreadId,
+ sal_Bool bAsynchron,
+ void *pThreadSpecificData,
+ RequestFun * doRequest );
+
+ void prepare( const ByteSequence &aThreadId );
+ void * enter( const ByteSequence &aThreadId, sal_Int64 nDisposeId );
+
+ /********
+ * @return true, if queue could be succesfully revoked.
+ ********/
+ sal_Bool revokeQueue( const ByteSequence & aThreadId , sal_Bool bAsynchron );
+
+ void waitInPool( ORequestThread *pThread );
+ private:
+ void createThread( JobQueue *pQueue, const ByteSequence &aThreadId, sal_Bool bAsynchron);
+
+
+ ThreadIdHashMap m_mapQueue;
+ ::osl::Mutex m_mutex;
+
+ ::osl::Mutex m_mutexWaitingThreadList;
+ WaitingThreadList m_lstThreads;
+ };
+
+} // end namespace cppu_threadpool
diff --git a/cppu/source/typelib/makefile.mk b/cppu/source/typelib/makefile.mk
new file mode 100644
index 000000000000..5a09459fed54
--- /dev/null
+++ b/cppu/source/typelib/makefile.mk
@@ -0,0 +1,45 @@
+#*************************************************************************
+#
+# 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_typelib
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : ..$/..$/util$/makefile.pmk
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES= \
+ $(SLO)$/typelib.obj \
+ $(SLO)$/static_types.obj
+
+.INCLUDE : ..$/..$/util$/target.pmk
+.INCLUDE : target.mk
+
diff --git a/cppu/source/typelib/static_types.cxx b/cppu/source/typelib/static_types.cxx
new file mode 100644
index 000000000000..5f1bbaad514a
--- /dev/null
+++ b/cppu/source/typelib/static_types.cxx
@@ -0,0 +1,673 @@
+/*************************************************************************
+ *
+ * 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 <stdarg.h>
+#include <algorithm>
+
+#include <osl/mutex.hxx>
+#include <osl/interlck.h>
+#include <rtl/ustring.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/memory.h>
+#include <rtl/instance.hxx>
+
+#include <typelib/typedescription.h>
+
+
+using namespace osl;
+using namespace rtl;
+
+extern "C"
+{
+
+//------------------------------------------------------------------------
+sal_Int32 SAL_CALL typelib_typedescription_getAlignedUnoSize(
+ const typelib_TypeDescription * pTypeDescription,
+ sal_Int32 nOffset,
+ sal_Int32 & rMaxIntegralTypeSize )
+ SAL_THROW_EXTERN_C();
+//------------------------------------------------------------------------
+void SAL_CALL typelib_typedescription_newEmpty(
+ typelib_TypeDescription ** ppRet,
+ typelib_TypeClass eTypeClass,
+ rtl_uString * pTypeName )
+ SAL_THROW_EXTERN_C();
+//-----------------------------------------------------------------------------
+void SAL_CALL typelib_typedescriptionreference_getByName(
+ typelib_TypeDescriptionReference ** ppRet,
+ rtl_uString * pName )
+ SAL_THROW_EXTERN_C();
+
+#ifdef SAL_W32
+#pragma pack(push, 8)
+#elif defined(SAL_OS2)
+#pragma pack(8)
+#endif
+
+/**
+ * The double member determin the alignment.
+ * Under Os2 and MS-Windows the Alignment is min( 8, sizeof( type ) ).
+ * The aligment of a strukture is min( 8, sizeof( max basic type ) ), the greatest basic type
+ * determine the aligment.
+ */
+struct AlignSize_Impl
+{
+ sal_Int16 nInt16;
+ double dDouble;
+};
+
+#ifdef SAL_W32
+#pragma pack(pop)
+#elif defined(SAL_OS2)
+#pragma pack()
+#endif
+
+// the value of the maximal alignment
+static sal_Int32 nMaxAlignment = (sal_Int32)( (sal_Size)(&((AlignSize_Impl *) 16)->dDouble) - 16);
+
+static inline sal_Int32 adjustAlignment( sal_Int32 nRequestedAlignment )
+ SAL_THROW( () )
+{
+ if( nRequestedAlignment > nMaxAlignment )
+ nRequestedAlignment = nMaxAlignment;
+ return nRequestedAlignment;
+}
+
+/**
+ * Calculate the new size of the struktur.
+ */
+static inline sal_Int32 newAlignedSize(
+ sal_Int32 OldSize, sal_Int32 ElementSize, sal_Int32 NeededAlignment )
+ SAL_THROW( () )
+{
+ NeededAlignment = adjustAlignment( NeededAlignment );
+ return (OldSize + NeededAlignment -1) / NeededAlignment * NeededAlignment + ElementSize;
+}
+
+//--------------------------------------------------------------------------------------------------
+
+namespace
+{
+ struct typelib_StaticInitMutex : public rtl::Static< Mutex, typelib_StaticInitMutex > {};
+}
+
+// !for NOT REALLY WEAK TYPES only!
+static inline typelib_TypeDescriptionReference * igetTypeByName( rtl_uString * pTypeName )
+ SAL_THROW( () )
+{
+ typelib_TypeDescriptionReference * pRef = 0;
+ ::typelib_typedescriptionreference_getByName( &pRef, pTypeName );
+ if (pRef && pRef->pType && pRef->pType->pWeakRef) // found initialized td
+ {
+ return pRef;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+extern "C"
+{
+//##################################################################################################
+typelib_TypeDescriptionReference ** SAL_CALL typelib_static_type_getByTypeClass(
+ typelib_TypeClass eTypeClass )
+ SAL_THROW_EXTERN_C()
+{
+ static typelib_TypeDescriptionReference * s_aTypes[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0 };
+
+ if (! s_aTypes[eTypeClass])
+ {
+ MutexGuard aGuard( typelib_StaticInitMutex::get() );
+ if (! s_aTypes[eTypeClass])
+ {
+ static const char * s_aTypeNames[] = {
+ "void", "char", "boolean", "byte",
+ "short", "unsigned short", "long", "unsigned long",
+ "hyper", "unsigned hyper", "float", "double",
+ "string", "type", "any" };
+
+ switch (eTypeClass)
+ {
+ case typelib_TypeClass_EXCEPTION:
+ case typelib_TypeClass_INTERFACE:
+ {
+ // type
+ if (! s_aTypes[typelib_TypeClass_TYPE])
+ {
+ OUString sTypeName( RTL_CONSTASCII_USTRINGPARAM("type") );
+ ::typelib_typedescriptionreference_new(
+ &s_aTypes[typelib_TypeClass_TYPE], typelib_TypeClass_TYPE, sTypeName.pData );
+#ifndef CPPU_LEAK_STATIC_DATA
+ // another static ref
+ ++s_aTypes[typelib_TypeClass_TYPE]->nStaticRefCount;
+#endif
+ }
+ // any
+ if (! s_aTypes[typelib_TypeClass_ANY])
+ {
+ OUString sTypeName( RTL_CONSTASCII_USTRINGPARAM("any") );
+ ::typelib_typedescriptionreference_new(
+ &s_aTypes[typelib_TypeClass_ANY], typelib_TypeClass_ANY, sTypeName.pData );
+#ifndef CPPU_LEAK_STATIC_DATA
+ // another static ref
+ ++s_aTypes[typelib_TypeClass_ANY]->nStaticRefCount;
+#endif
+ }
+ // string
+ if (! s_aTypes[typelib_TypeClass_STRING])
+ {
+ OUString sTypeName( RTL_CONSTASCII_USTRINGPARAM("string") );
+ ::typelib_typedescriptionreference_new(
+ &s_aTypes[typelib_TypeClass_STRING], typelib_TypeClass_STRING, sTypeName.pData );
+#ifndef CPPU_LEAK_STATIC_DATA
+ // another static ref
+ ++s_aTypes[typelib_TypeClass_STRING]->nStaticRefCount;
+#endif
+ }
+ // XInterface
+ if (! s_aTypes[typelib_TypeClass_INTERFACE])
+ {
+ OUString sTypeName( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XInterface") );
+
+ typelib_InterfaceTypeDescription * pTD = 0;
+
+ typelib_TypeDescriptionReference * pMembers[3] = { 0,0,0 };
+ OUString sMethodName0( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XInterface::queryInterface") );
+ ::typelib_typedescriptionreference_new(
+ &pMembers[0], typelib_TypeClass_INTERFACE_METHOD, sMethodName0.pData );
+ OUString sMethodName1( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XInterface::acquire") );
+ ::typelib_typedescriptionreference_new(
+ &pMembers[1], typelib_TypeClass_INTERFACE_METHOD, sMethodName1.pData );
+ OUString sMethodName2( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XInterface::release") );
+ ::typelib_typedescriptionreference_new(
+ &pMembers[2], typelib_TypeClass_INTERFACE_METHOD, sMethodName2.pData );
+
+ ::typelib_typedescription_newInterface(
+ &pTD, sTypeName.pData, 0xe227a391, 0x33d6, 0x11d1, 0xaabe00a0, 0x249d5590,
+ 0, 3, pMembers );
+
+ ::typelib_typedescription_register( (typelib_TypeDescription **)&pTD );
+ ::typelib_typedescriptionreference_acquire(
+ s_aTypes[typelib_TypeClass_INTERFACE] = ((typelib_TypeDescription *)pTD)->pWeakRef );
+#ifndef CPPU_LEAK_STATIC_DATA
+ // another static ref
+ ++s_aTypes[typelib_TypeClass_INTERFACE]->nStaticRefCount;
+#endif
+ ::typelib_typedescription_release( (typelib_TypeDescription*)pTD );
+
+ ::typelib_typedescriptionreference_release( pMembers[0] );
+ ::typelib_typedescriptionreference_release( pMembers[1] );
+ ::typelib_typedescriptionreference_release( pMembers[2] );
+ // Exception
+ OSL_ASSERT( ! s_aTypes[typelib_TypeClass_EXCEPTION] );
+ {
+ typelib_TypeDescription * pTD1 = 0;
+ OUString sTypeName1( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.Exception") );
+
+ typelib_CompoundMember_Init aMembers[2];
+ OUString sMemberType0( RTL_CONSTASCII_USTRINGPARAM("string") );
+ OUString sMemberName0( RTL_CONSTASCII_USTRINGPARAM("Message") );
+ aMembers[0].eTypeClass = typelib_TypeClass_STRING;
+ aMembers[0].pTypeName = sMemberType0.pData;
+ aMembers[0].pMemberName = sMemberName0.pData;
+ OUString sMemberType1( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XInterface") );
+ OUString sMemberName1( RTL_CONSTASCII_USTRINGPARAM("Context") );
+ aMembers[1].eTypeClass = typelib_TypeClass_INTERFACE;
+ aMembers[1].pTypeName = sMemberType1.pData;
+ aMembers[1].pMemberName = sMemberName1.pData;
+
+ ::typelib_typedescription_new(
+ &pTD1, typelib_TypeClass_EXCEPTION, sTypeName1.pData, 0, 2, aMembers );
+ typelib_typedescription_register( &pTD1 );
+ typelib_typedescriptionreference_acquire(
+ s_aTypes[typelib_TypeClass_EXCEPTION] = pTD1->pWeakRef );
+#ifndef CPPU_LEAK_STATIC_DATA
+ // another static ref
+ ++s_aTypes[typelib_TypeClass_EXCEPTION]->nStaticRefCount;
+#endif
+ // RuntimeException
+ OUString sTypeName2( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.RuntimeException") );
+ ::typelib_typedescription_new(
+ &pTD1, typelib_TypeClass_EXCEPTION, sTypeName2.pData, s_aTypes[typelib_TypeClass_EXCEPTION], 0, 0 );
+ ::typelib_typedescription_register( &pTD1 );
+ ::typelib_typedescription_release( pTD1 );
+ }
+ // XInterface members
+ typelib_InterfaceMethodTypeDescription * pMethod = 0;
+ typelib_Parameter_Init aParameters[1];
+ OUString sParamName0( RTL_CONSTASCII_USTRINGPARAM("aType") );
+ OUString sParamType0( RTL_CONSTASCII_USTRINGPARAM("type") );
+ aParameters[0].pParamName = sParamName0.pData;
+ aParameters[0].eTypeClass = typelib_TypeClass_TYPE;
+ aParameters[0].pTypeName = sParamType0.pData;
+ aParameters[0].bIn = sal_True;
+ aParameters[0].bOut = sal_False;
+ rtl_uString * pExceptions[1];
+ OUString sExceptionName0( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.RuntimeException") );
+ pExceptions[0] = sExceptionName0.pData;
+ OUString sReturnType0( RTL_CONSTASCII_USTRINGPARAM("any") );
+ typelib_typedescription_newInterfaceMethod(
+ &pMethod, 0, sal_False, sMethodName0.pData,
+ typelib_TypeClass_ANY, sReturnType0.pData,
+ 1, aParameters, 1, pExceptions );
+ ::typelib_typedescription_register( (typelib_TypeDescription**)&pMethod );
+
+ OUString sReturnType1( RTL_CONSTASCII_USTRINGPARAM("void") );
+ ::typelib_typedescription_newInterfaceMethod(
+ &pMethod, 1, sal_True, sMethodName1.pData,
+ typelib_TypeClass_VOID, sReturnType1.pData, 0, 0, 0, 0 );
+ ::typelib_typedescription_register( (typelib_TypeDescription**)&pMethod );
+
+ ::typelib_typedescription_newInterfaceMethod(
+ &pMethod, 2, sal_True, sMethodName2.pData,
+ typelib_TypeClass_VOID, sReturnType1.pData,
+ 0, 0, 0, 0 );
+ ::typelib_typedescription_register( (typelib_TypeDescription**)&pMethod );
+ ::typelib_typedescription_release( (typelib_TypeDescription*)pMethod );
+ }
+ break;
+ }
+ default:
+ {
+ OUString aTypeName( OUString::createFromAscii( s_aTypeNames[eTypeClass] ) );
+ ::typelib_typedescriptionreference_new( &s_aTypes[eTypeClass], eTypeClass, aTypeName.pData );
+#ifndef CPPU_LEAK_STATIC_DATA
+ // another static ref
+ ++s_aTypes[eTypeClass]->nStaticRefCount;
+#endif
+ }
+ }
+ }
+ }
+ return &s_aTypes[eTypeClass];
+}
+
+//##################################################################################################
+void SAL_CALL typelib_static_type_init(
+ typelib_TypeDescriptionReference ** ppRef,
+ typelib_TypeClass eTypeClass, const sal_Char * pTypeName )
+ SAL_THROW_EXTERN_C()
+{
+ if (! *ppRef)
+ {
+ MutexGuard aGuard( typelib_StaticInitMutex::get() );
+ if (! *ppRef)
+ {
+ OUString aTypeName( OUString::createFromAscii( pTypeName ) );
+ ::typelib_typedescriptionreference_new( ppRef, eTypeClass, aTypeName.pData );
+
+#ifndef CPPU_LEAK_STATIC_DATA
+ // another static ref
+ ++((*ppRef)->nStaticRefCount);
+#endif
+ }
+ }
+}
+
+//##################################################################################################
+void SAL_CALL typelib_static_sequence_type_init(
+ typelib_TypeDescriptionReference ** ppRef,
+ typelib_TypeDescriptionReference * pElementType )
+ SAL_THROW_EXTERN_C()
+{
+ if (! *ppRef)
+ {
+ MutexGuard aGuard( typelib_StaticInitMutex::get() );
+ if (! *ppRef)
+ {
+ OUStringBuffer aBuf( 32 );
+ aBuf.appendAscii( "[]" );
+ aBuf.append( pElementType->pTypeName );
+ OUString aTypeName( aBuf.makeStringAndClear() );
+
+ OSL_ASSERT( ! TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK(typelib_TypeClass_SEQUENCE) );
+ *ppRef = igetTypeByName( aTypeName.pData );
+ if (!*ppRef)
+ {
+ typelib_TypeDescription * pReg = 0;
+ ::typelib_typedescription_new(
+ &pReg, typelib_TypeClass_SEQUENCE,
+ aTypeName.pData, pElementType, 0, 0 );
+
+ ::typelib_typedescription_register( &pReg );
+ *ppRef = (typelib_TypeDescriptionReference *)pReg;
+ OSL_ASSERT( *ppRef == pReg->pWeakRef );
+ }
+#ifndef CPPU_LEAK_STATIC_DATA
+ // another static ref
+ ++((*ppRef)->nStaticRefCount);
+#endif
+ }
+ }
+}
+
+//##################################################################################################
+namespace {
+
+void init(
+ typelib_TypeDescriptionReference ** ppRef,
+ typelib_TypeClass eTypeClass, const sal_Char * pTypeName,
+ typelib_TypeDescriptionReference * pBaseType,
+ sal_Int32 nMembers, typelib_TypeDescriptionReference ** ppMembers,
+ sal_Bool const * pParameterizedTypes)
+{
+ OSL_ENSURE( typelib_TypeClass_STRUCT == eTypeClass ||
+ typelib_TypeClass_EXCEPTION == eTypeClass, "### unexpected type class!" );
+
+ if (! *ppRef)
+ {
+ MutexGuard aGuard( typelib_StaticInitMutex::get() );
+ if (! *ppRef)
+ {
+ OSL_ASSERT( ! TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK(eTypeClass) );
+ OUString aTypeName( OUString::createFromAscii( pTypeName ) );
+ *ppRef = igetTypeByName( aTypeName.pData );
+ if (!*ppRef)
+ {
+ typelib_CompoundTypeDescription * pComp = 0;
+ ::typelib_typedescription_newEmpty(
+ (typelib_TypeDescription **)&pComp, eTypeClass, aTypeName.pData );
+
+ sal_Int32 nOffset = 0;
+ if (pBaseType)
+ {
+ ::typelib_typedescriptionreference_getDescription(
+ (typelib_TypeDescription **)&pComp->pBaseTypeDescription, pBaseType );
+ OSL_ASSERT( pComp->pBaseTypeDescription );
+ nOffset = ((typelib_TypeDescription *)pComp->pBaseTypeDescription)->nSize;
+ OSL_ENSURE( newAlignedSize( 0, ((typelib_TypeDescription *)pComp->pBaseTypeDescription)->nSize, ((typelib_TypeDescription *)pComp->pBaseTypeDescription)->nAlignment ) == ((typelib_TypeDescription *)pComp->pBaseTypeDescription)->nSize, "### unexpected offset!" );
+ }
+
+ if (nMembers)
+ {
+ pComp->nMembers = nMembers;
+ pComp->pMemberOffsets = new sal_Int32[ nMembers ];
+ pComp->ppTypeRefs = new typelib_TypeDescriptionReference *[ nMembers ];
+ if (pParameterizedTypes != 0) {
+ reinterpret_cast< typelib_StructTypeDescription * >(
+ pComp)->pParameterizedTypes
+ = new sal_Bool[nMembers];
+ }
+ for ( sal_Int32 i = 0 ; i < nMembers; ++i )
+ {
+ ::typelib_typedescriptionreference_acquire(
+ pComp->ppTypeRefs[i] = ppMembers[i] );
+ // write offset
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, pComp->ppTypeRefs[i] );
+ OSL_ENSURE( pTD->nSize, "### void member?" );
+ nOffset = newAlignedSize( nOffset, pTD->nSize, pTD->nAlignment );
+ pComp->pMemberOffsets[i] = nOffset - pTD->nSize;
+ TYPELIB_DANGER_RELEASE( pTD );
+
+ if (pParameterizedTypes != 0) {
+ reinterpret_cast< typelib_StructTypeDescription * >(
+ pComp)->pParameterizedTypes[i]
+ = pParameterizedTypes[i];
+ }
+ }
+ }
+
+ typelib_TypeDescription * pReg = (typelib_TypeDescription *)pComp;
+ pReg->pWeakRef = (typelib_TypeDescriptionReference *)pReg;
+ // sizeof( void ) not allowed
+ pReg->nSize = ::typelib_typedescription_getAlignedUnoSize( pReg, 0, pReg->nAlignment );
+ pReg->nAlignment = adjustAlignment( pReg->nAlignment );
+ pReg->bComplete = sal_False;
+
+ ::typelib_typedescription_register( &pReg );
+ *ppRef = (typelib_TypeDescriptionReference *)pReg;
+ OSL_ASSERT( *ppRef == pReg->pWeakRef );
+ }
+#ifndef CPPU_LEAK_STATIC_DATA
+ // another static ref
+ ++((*ppRef)->nStaticRefCount);
+#endif
+ }
+ }
+}
+
+}
+
+void SAL_CALL typelib_static_compound_type_init(
+ typelib_TypeDescriptionReference ** ppRef,
+ typelib_TypeClass eTypeClass, const sal_Char * pTypeName,
+ typelib_TypeDescriptionReference * pBaseType,
+ sal_Int32 nMembers, typelib_TypeDescriptionReference ** ppMembers )
+ SAL_THROW_EXTERN_C()
+{
+ init(ppRef, eTypeClass, pTypeName, pBaseType, nMembers, ppMembers, 0);
+}
+
+void SAL_CALL typelib_static_struct_type_init(
+ typelib_TypeDescriptionReference ** ppRef, const sal_Char * pTypeName,
+ typelib_TypeDescriptionReference * pBaseType,
+ sal_Int32 nMembers, typelib_TypeDescriptionReference ** ppMembers,
+ sal_Bool const * pParameterizedTypes )
+ SAL_THROW_EXTERN_C()
+{
+ init(
+ ppRef, typelib_TypeClass_STRUCT, pTypeName, pBaseType, nMembers,
+ ppMembers, pParameterizedTypes);
+}
+
+//##################################################################################################
+void SAL_CALL typelib_static_interface_type_init(
+ typelib_TypeDescriptionReference ** ppRef,
+ const sal_Char * pTypeName,
+ typelib_TypeDescriptionReference * pBaseType )
+ SAL_THROW_EXTERN_C()
+{
+ typelib_static_mi_interface_type_init(
+ ppRef, pTypeName, pBaseType == 0 ? 0 : 1, &pBaseType);
+}
+
+//##################################################################################################
+void SAL_CALL typelib_static_mi_interface_type_init(
+ typelib_TypeDescriptionReference ** ppRef,
+ const sal_Char * pTypeName,
+ sal_Int32 nBaseTypes,
+ typelib_TypeDescriptionReference ** ppBaseTypes )
+ SAL_THROW_EXTERN_C()
+{
+ if (! *ppRef)
+ {
+ MutexGuard aGuard( typelib_StaticInitMutex::get() );
+ if (! *ppRef)
+ {
+ OSL_ASSERT( ! TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK(typelib_TypeClass_INTERFACE) );
+ OUString aTypeName( OUString::createFromAscii( pTypeName ) );
+ *ppRef = igetTypeByName( aTypeName.pData );
+ if (!*ppRef)
+ {
+ typelib_InterfaceTypeDescription * pIface = 0;
+ ::typelib_typedescription_newEmpty(
+ (typelib_TypeDescription **)&pIface, typelib_TypeClass_INTERFACE, aTypeName.pData );
+
+ pIface->nBaseTypes = std::max< sal_Int32 >(nBaseTypes, 1);
+ pIface->ppBaseTypes = new typelib_InterfaceTypeDescription *[
+ pIface->nBaseTypes];
+ if (nBaseTypes > 0)
+ {
+ for (sal_Int32 i = 0; i < nBaseTypes; ++i) {
+ pIface->ppBaseTypes[i] = 0;
+ ::typelib_typedescriptionreference_getDescription(
+ (typelib_TypeDescription **)&pIface->ppBaseTypes[i], ppBaseTypes[i] );
+ OSL_ASSERT( pIface->ppBaseTypes[i] );
+ }
+ }
+ else
+ {
+ pIface->ppBaseTypes[0] = 0;
+ ::typelib_typedescriptionreference_getDescription(
+ (typelib_TypeDescription **)&pIface->ppBaseTypes[0],
+ * ::typelib_static_type_getByTypeClass( typelib_TypeClass_INTERFACE ) );
+ OSL_ASSERT( pIface->ppBaseTypes[0] );
+ }
+ pIface->pBaseTypeDescription = pIface->ppBaseTypes[0];
+ typelib_typedescription_acquire(
+ &pIface->pBaseTypeDescription->aBase);
+
+ typelib_TypeDescription * pReg = (typelib_TypeDescription *)pIface;
+ pReg->pWeakRef = (typelib_TypeDescriptionReference *)pReg;
+ // sizeof( void ) not allowed
+ pReg->nSize = ::typelib_typedescription_getAlignedUnoSize( pReg, 0, pReg->nAlignment );
+
+ pReg->nAlignment = adjustAlignment( pReg->nAlignment );
+ pReg->bComplete = sal_False;
+
+ ::typelib_typedescription_register( &pReg );
+ *ppRef = (typelib_TypeDescriptionReference *)pReg;
+ OSL_ASSERT( *ppRef == pReg->pWeakRef );
+ }
+#ifndef CPPU_LEAK_STATIC_DATA
+ // another static ref
+ ++((*ppRef)->nStaticRefCount);
+#endif
+ }
+ }
+}
+
+//##################################################################################################
+void SAL_CALL typelib_static_enum_type_init(
+ typelib_TypeDescriptionReference ** ppRef,
+ const sal_Char * pTypeName,
+ sal_Int32 nDefaultValue )
+ SAL_THROW_EXTERN_C()
+{
+ if (! *ppRef)
+ {
+ MutexGuard aGuard( typelib_StaticInitMutex::get() );
+ if (! *ppRef)
+ {
+ OSL_ASSERT( ! TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK(typelib_TypeClass_ENUM) );
+ OUString aTypeName( OUString::createFromAscii( pTypeName ) );
+ *ppRef = igetTypeByName( aTypeName.pData );
+ if (!*ppRef)
+ {
+ typelib_TypeDescription * pReg = 0;
+ ::typelib_typedescription_newEmpty(
+ &pReg, typelib_TypeClass_ENUM, aTypeName.pData );
+ typelib_EnumTypeDescription * pEnum = (typelib_EnumTypeDescription *)pReg;
+
+ pEnum->nDefaultEnumValue = nDefaultValue;
+
+ pReg->pWeakRef = (typelib_TypeDescriptionReference *)pReg;
+ // sizeof( void ) not allowed
+ pReg->nSize = ::typelib_typedescription_getAlignedUnoSize( pReg, 0, pReg->nAlignment );
+ pReg->nAlignment = ::adjustAlignment( pReg->nAlignment );
+ pReg->bComplete = sal_False;
+
+ ::typelib_typedescription_register( &pReg );
+ *ppRef = (typelib_TypeDescriptionReference *)pReg;
+ OSL_ASSERT( *ppRef == pReg->pWeakRef );
+ }
+#ifndef CPPU_LEAK_STATIC_DATA
+ // another static ref
+ ++(*(sal_Int32 *)&(*ppRef)->pReserved);
+#endif
+ }
+ }
+}
+
+//##################################################################################################
+void SAL_CALL typelib_static_array_type_init(
+ typelib_TypeDescriptionReference ** ppRef,
+ typelib_TypeDescriptionReference * pElementTypeRef,
+ sal_Int32 nDimensions, ... )
+ SAL_THROW_EXTERN_C()
+{
+ if (! *ppRef)
+ {
+ MutexGuard aGuard( typelib_StaticInitMutex::get() );
+ if (! *ppRef)
+ {
+ OUStringBuffer aBuf( 32 );
+ aBuf.append( pElementTypeRef->pTypeName );
+
+ va_list dimArgs;
+ va_start( dimArgs, nDimensions );
+ sal_Int32 dim = 0;
+ sal_Int32 nElements = 1;
+ sal_Int32* pDimensions = new sal_Int32[nDimensions];
+ for (sal_Int32 i=0; i < nDimensions; i++)
+ {
+ dim = va_arg( dimArgs, int);
+ pDimensions[i] = dim;
+ aBuf.appendAscii("[");
+ aBuf.append(dim);
+ aBuf.appendAscii("]");
+ nElements *= dim;
+ }
+ va_end( dimArgs );
+ OUString aTypeName( aBuf.makeStringAndClear() );
+
+ OSL_ASSERT( ! TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK(typelib_TypeClass_ARRAY) );
+ *ppRef = igetTypeByName( aTypeName.pData );
+ if (!*ppRef)
+ {
+ typelib_TypeDescription * pReg = 0;
+ ::typelib_typedescription_newEmpty(
+ &pReg, typelib_TypeClass_ARRAY, aTypeName.pData );
+ typelib_ArrayTypeDescription * pArray = (typelib_ArrayTypeDescription *)pReg;
+
+ pArray->nDimensions = nDimensions;
+ pArray->nTotalElements = nElements;
+ pArray->pDimensions = pDimensions;
+
+ typelib_typedescriptionreference_acquire(pElementTypeRef);
+ ((typelib_IndirectTypeDescription*)pArray)->pType = pElementTypeRef;
+
+ pReg->pWeakRef = (typelib_TypeDescriptionReference *)pReg;
+ // sizeof( void ) not allowed
+ pReg->nSize = ::typelib_typedescription_getAlignedUnoSize( pReg, 0, pReg->nAlignment );
+ pReg->nAlignment = ::adjustAlignment( pReg->nAlignment );
+ pReg->bComplete = sal_True;
+
+ ::typelib_typedescription_register( &pReg );
+ *ppRef = (typelib_TypeDescriptionReference *)pReg;
+ OSL_ASSERT( *ppRef == pReg->pWeakRef );
+ } else
+ delete [] pDimensions;
+#ifndef CPPU_LEAK_STATIC_DATA
+ // another static ref
+ ++((*ppRef)->nStaticRefCount);
+#endif
+ }
+ }
+}
+
+} // extern "C"
+
+}
diff --git a/cppu/source/typelib/typelib.cxx b/cppu/source/typelib/typelib.cxx
new file mode 100644
index 000000000000..7f85d691cce5
--- /dev/null
+++ b/cppu/source/typelib/typelib.cxx
@@ -0,0 +1,2671 @@
+/*************************************************************************
+ *
+ * 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 <hash_map>
+#include <list>
+#include <set>
+#include <vector>
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sal/alloca.h>
+#include <new>
+#include <osl/interlck.h>
+#include <osl/mutex.hxx>
+#include <rtl/ustring.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/alloc.h>
+#include <rtl/instance.hxx>
+#include <osl/diagnose.h>
+#include <typelib/typedescription.h>
+#include <uno/any2.h>
+
+using namespace rtl;
+using namespace std;
+using namespace osl;
+
+
+//------------------------------------------------------------------------
+//------------------------------------------------------------------------
+#ifdef SAL_W32
+#pragma pack(push, 8)
+#elif defined(SAL_OS2)
+#pragma pack(8)
+#endif
+
+/**
+ * The double member determin the alignment.
+ * Under Os2 and MS-Windows the Alignment is min( 8, sizeof( type ) ).
+ * The aligment of a strukture is min( 8, sizeof( max basic type ) ), the greatest basic type
+ * determine the aligment.
+ */
+struct AlignSize_Impl
+{
+ sal_Int16 nInt16;
+ double dDouble;
+};
+
+#ifdef SAL_W32
+#pragma pack(pop)
+#elif defined(SAL_OS2)
+#pragma pack()
+#endif
+
+// the value of the maximal alignment
+static sal_Int32 nMaxAlignment = (sal_Int32)( (sal_Size)(&((AlignSize_Impl *) 16)->dDouble) - 16);
+
+static inline sal_Int32 adjustAlignment( sal_Int32 nRequestedAlignment )
+ SAL_THROW( () )
+{
+ if( nRequestedAlignment > nMaxAlignment )
+ nRequestedAlignment = nMaxAlignment;
+ return nRequestedAlignment;
+}
+
+/**
+ * Calculate the new size of the struktur.
+ */
+static inline sal_Int32 newAlignedSize(
+ sal_Int32 OldSize, sal_Int32 ElementSize, sal_Int32 NeededAlignment )
+ SAL_THROW( () )
+{
+ NeededAlignment = adjustAlignment( NeededAlignment );
+ return (OldSize + NeededAlignment -1) / NeededAlignment * NeededAlignment + ElementSize;
+}
+
+static inline sal_Bool reallyWeak( typelib_TypeClass eTypeClass )
+ SAL_THROW( () )
+{
+ return TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( eTypeClass );
+}
+
+static inline sal_Int32 getDescriptionSize( typelib_TypeClass eTypeClass )
+ SAL_THROW( () )
+{
+ OSL_ASSERT( typelib_TypeClass_TYPEDEF != eTypeClass );
+
+ sal_Int32 nSize;
+ // The reference is the description
+ // if the description is empty, than it must be filled with
+ // the new description
+ switch( eTypeClass )
+ {
+ case typelib_TypeClass_ARRAY:
+ nSize = (sal_Int32)sizeof( typelib_ArrayTypeDescription );
+ break;
+
+ case typelib_TypeClass_SEQUENCE:
+ nSize = (sal_Int32)sizeof( typelib_IndirectTypeDescription );
+ break;
+
+ case typelib_TypeClass_UNION:
+ nSize = (sal_Int32)sizeof( typelib_UnionTypeDescription );
+ break;
+
+ case typelib_TypeClass_STRUCT:
+ nSize = (sal_Int32)sizeof( typelib_StructTypeDescription );
+ break;
+
+ case typelib_TypeClass_EXCEPTION:
+ nSize = (sal_Int32)sizeof( typelib_CompoundTypeDescription );
+ break;
+
+ case typelib_TypeClass_ENUM:
+ nSize = (sal_Int32)sizeof( typelib_EnumTypeDescription );
+ break;
+
+ case typelib_TypeClass_INTERFACE:
+ nSize = (sal_Int32)sizeof( typelib_InterfaceTypeDescription );
+ break;
+
+ case typelib_TypeClass_INTERFACE_METHOD:
+ nSize = (sal_Int32)sizeof( typelib_InterfaceMethodTypeDescription );
+ break;
+
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ nSize = (sal_Int32)sizeof( typelib_InterfaceAttributeTypeDescription );
+ break;
+
+ default:
+ nSize = (sal_Int32)sizeof( typelib_TypeDescription );
+ }
+ return nSize;
+}
+
+
+//-----------------------------------------------------------------------------
+extern "C" void SAL_CALL typelib_typedescriptionreference_getByName(
+ typelib_TypeDescriptionReference ** ppRet, rtl_uString * pName )
+ SAL_THROW_EXTERN_C();
+
+//-----------------------------------------------------------------------------
+struct equalStr_Impl
+{
+ sal_Bool operator()(const sal_Unicode * const & s1, const sal_Unicode * const & s2) const SAL_THROW( () )
+ { return 0 == rtl_ustr_compare( s1, s2 ); }
+};
+
+//-----------------------------------------------------------------------------
+struct hashStr_Impl
+{
+ size_t operator()(const sal_Unicode * const & s) const SAL_THROW( () )
+ { return rtl_ustr_hashCode( s ); }
+};
+
+
+//-----------------------------------------------------------------------------
+// Heavy hack, the const sal_Unicode * is hold by the typedescription reference
+typedef hash_map< const sal_Unicode *, typelib_TypeDescriptionReference *,
+ hashStr_Impl, equalStr_Impl > WeakMap_Impl;
+
+typedef pair< void *, typelib_typedescription_Callback > CallbackEntry;
+typedef list< CallbackEntry > CallbackSet_Impl;
+typedef list< typelib_TypeDescription * > TypeDescriptionList_Impl;
+
+// # of cached elements
+static sal_Int32 nCacheSize = 256;
+
+//-----------------------------------------------------------------------------
+/**
+ * All members must set initial to 0 and no constructor is needed. So it
+ * doesn't care, when this class is static initialized.<BR>
+ */
+struct TypeDescriptor_Init_Impl
+{
+ //sal_Bool bDesctructorCalled;
+ // all type description references
+ WeakMap_Impl * pWeakMap;
+ // all type description callbacks
+ CallbackSet_Impl * pCallbacks;
+ // A cache to hold descriptions
+ TypeDescriptionList_Impl * pCache;
+ // The mutex to guard all type library accesses
+ Mutex * pMutex;
+
+ inline Mutex & getMutex() SAL_THROW( () );
+
+ inline void callChain( typelib_TypeDescription ** ppRet, rtl_uString * pName ) SAL_THROW( () );
+
+#if OSL_DEBUG_LEVEL > 1
+ // only for debugging
+ sal_Int32 nTypeDescriptionCount;
+ sal_Int32 nCompoundTypeDescriptionCount;
+ sal_Int32 nUnionTypeDescriptionCount;
+ sal_Int32 nIndirectTypeDescriptionCount;
+ sal_Int32 nArrayTypeDescriptionCount;
+ sal_Int32 nEnumTypeDescriptionCount;
+ sal_Int32 nInterfaceMethodTypeDescriptionCount;
+ sal_Int32 nInterfaceAttributeTypeDescriptionCount;
+ sal_Int32 nInterfaceTypeDescriptionCount;
+ sal_Int32 nTypeDescriptionReferenceCount;
+#endif
+ ~TypeDescriptor_Init_Impl() SAL_THROW( () );
+};
+//__________________________________________________________________________________________________
+inline Mutex & TypeDescriptor_Init_Impl::getMutex() SAL_THROW( () )
+{
+ if( !pMutex )
+ {
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ if( !pMutex )
+ pMutex = new Mutex();
+ }
+ return * pMutex;
+}
+//__________________________________________________________________________________________________
+inline void TypeDescriptor_Init_Impl::callChain(
+ typelib_TypeDescription ** ppRet, rtl_uString * pName )
+ SAL_THROW( () )
+{
+ if (pCallbacks)
+ {
+ CallbackSet_Impl::const_iterator aIt = pCallbacks->begin();
+ while( aIt != pCallbacks->end() )
+ {
+ const CallbackEntry & rEntry = *aIt;
+ (*rEntry.second)( rEntry.first, ppRet, pName );
+ if( *ppRet )
+ return;
+ ++aIt;
+ }
+ }
+ if (*ppRet)
+ {
+ typelib_typedescription_release( *ppRet );
+ *ppRet = 0;
+ }
+}
+
+// never called
+#if defined(CPPU_LEAK_STATIC_DATA) && defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)
+static void dumb_sunpro5_must_have_dtor_stl_hashmap_code_if_compiled_with_minus_g() SAL_THROW( () )
+{
+ delete (WeakMap_Impl *)0xbeef1e;
+}
+#endif
+//__________________________________________________________________________________________________
+TypeDescriptor_Init_Impl::~TypeDescriptor_Init_Impl() SAL_THROW( () )
+{
+#ifndef CPPU_LEAK_STATIC_DATA
+ if( pCache )
+ {
+ TypeDescriptionList_Impl::const_iterator aIt = pCache->begin();
+ while( aIt != pCache->end() )
+ {
+ typelib_typedescription_release( (*aIt) );
+ aIt++;
+ }
+ delete pCache;
+ pCache = 0;
+ }
+
+ if( pWeakMap )
+ {
+ sal_Int32 nSize = pWeakMap->size();
+ typelib_TypeDescriptionReference ** ppTDR = new typelib_TypeDescriptionReference *[ nSize ];
+ // save al weak references
+ WeakMap_Impl::const_iterator aIt = pWeakMap->begin();
+ sal_Int32 i = 0;
+ while( aIt != pWeakMap->end() )
+ {
+ typelib_typedescriptionreference_acquire( ppTDR[i++] = (*aIt).second );
+ ++aIt;
+ }
+
+ for( i = 0; i < nSize; i++ )
+ {
+ typelib_TypeDescriptionReference * pTDR = ppTDR[i];
+ sal_Int32 nStaticCounts = pTDR->nStaticRefCount;
+ OSL_ASSERT( pTDR->nRefCount > pTDR->nStaticRefCount );
+ pTDR->nRefCount -= pTDR->nStaticRefCount;
+
+ if( pTDR->pType && !pTDR->pType->bOnDemand )
+ {
+ pTDR->pType->bOnDemand = sal_True;
+ typelib_typedescription_release( pTDR->pType );
+ }
+ typelib_typedescriptionreference_release( pTDR );
+ }
+
+ delete [] ppTDR;
+
+#if OSL_DEBUG_LEVEL > 1
+ aIt = pWeakMap->begin();
+ while( aIt != pWeakMap->end() )
+ {
+ typelib_TypeDescriptionReference * pTDR = (*aIt).second;
+ if (pTDR)
+ {
+ OString aTypeName( OUStringToOString( pTDR->pTypeName, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE(
+ "### remaining type: %s; ref count = %d", aTypeName.getStr(), pTDR->nRefCount );
+ }
+ else
+ {
+ OSL_TRACE( "### remaining null type entry!?" );
+ }
+ ++aIt;
+ }
+#endif
+
+ delete pWeakMap;
+ pWeakMap = 0;
+ }
+#if OSL_DEBUG_LEVEL > 1
+ OSL_ASSERT( nTypeDescriptionCount == 0 );
+ OSL_ASSERT( nCompoundTypeDescriptionCount == 0 );
+ OSL_ASSERT( nUnionTypeDescriptionCount == 0 );
+ OSL_ASSERT( nIndirectTypeDescriptionCount == 0 );
+ OSL_ASSERT( nArrayTypeDescriptionCount == 0 );
+ OSL_ASSERT( nEnumTypeDescriptionCount == 0 );
+ OSL_ASSERT( nInterfaceMethodTypeDescriptionCount == 0 );
+ OSL_ASSERT( nInterfaceAttributeTypeDescriptionCount == 0 );
+ OSL_ASSERT( nInterfaceTypeDescriptionCount == 0 );
+ OSL_ASSERT( nTypeDescriptionReferenceCount == 0 );
+
+ OSL_ASSERT( !pCallbacks || pCallbacks->empty() );
+#endif
+ delete pCallbacks;
+ pCallbacks = 0;
+#endif // CPPU_LEAK_STATIC_DATA
+
+ // todo: maybe into leak block
+ if( pMutex )
+ {
+ delete pMutex;
+ pMutex = 0;
+ }
+};
+
+namespace { struct Init : public rtl::Static< TypeDescriptor_Init_Impl, Init > {}; }
+
+//------------------------------------------------------------------------
+//------------------------------------------------------------------------
+//------------------------------------------------------------------------
+//------------------------------------------------------------------------
+extern "C" void SAL_CALL typelib_typedescription_registerCallback(
+ void * pContext, typelib_typedescription_Callback pCallback )
+ SAL_THROW_EXTERN_C()
+{
+ // todo mt safe: guard is no solution, can not acquire while calling callback!
+ TypeDescriptor_Init_Impl &rInit = Init::get();
+// OslGuard aGuard( rInit.getMutex() );
+ if( !rInit.pCallbacks )
+ rInit.pCallbacks = new CallbackSet_Impl;
+ rInit.pCallbacks->push_back( CallbackEntry( pContext, pCallback ) );
+}
+
+//------------------------------------------------------------------------
+extern "C" void SAL_CALL typelib_typedescription_revokeCallback(
+ void * pContext, typelib_typedescription_Callback pCallback )
+ SAL_THROW_EXTERN_C()
+{
+ TypeDescriptor_Init_Impl &rInit = Init::get();
+ if( rInit.pCallbacks )
+ {
+ // todo mt safe: guard is no solution, can not acquire while calling callback!
+// OslGuard aGuard( rInit.getMutex() );
+ CallbackEntry aEntry( pContext, pCallback );
+ CallbackSet_Impl::iterator iPos( rInit.pCallbacks->begin() );
+ while (!(iPos == rInit.pCallbacks->end()))
+ {
+ if (*iPos == aEntry)
+ {
+ rInit.pCallbacks->erase( iPos );
+ iPos = rInit.pCallbacks->begin();
+ }
+ else
+ {
+ ++iPos;
+ }
+ }
+ }
+}
+
+
+//------------------------------------------------------------------------
+//------------------------------------------------------------------------
+//------------------------------------------------------------------------
+extern "C" sal_Int32 SAL_CALL typelib_typedescription_getAlignedUnoSize(
+ const typelib_TypeDescription * pTypeDescription,
+ sal_Int32 nOffset, sal_Int32 & rMaxIntegralTypeSize )
+ SAL_THROW_EXTERN_C();
+
+//------------------------------------------------------------------------
+static inline void typelib_typedescription_initTables(
+ typelib_TypeDescription * pTD )
+ SAL_THROW( () )
+{
+ typelib_InterfaceTypeDescription * pITD = (typelib_InterfaceTypeDescription *)pTD;
+
+ sal_Bool * pReadWriteAttributes = (sal_Bool *)alloca( pITD->nAllMembers );
+ for ( sal_Int32 i = pITD->nAllMembers; i--; )
+ {
+ pReadWriteAttributes[i] = sal_False;
+ if( typelib_TypeClass_INTERFACE_ATTRIBUTE == pITD->ppAllMembers[i]->eTypeClass )
+ {
+ typelib_TypeDescription * pM = 0;
+ TYPELIB_DANGER_GET( &pM, pITD->ppAllMembers[i] );
+ OSL_ASSERT( pM );
+ if (pM)
+ {
+ pReadWriteAttributes[i] = !((typelib_InterfaceAttributeTypeDescription *)pM)->bReadOnly;
+ TYPELIB_DANGER_RELEASE( pM );
+ }
+#if OSL_DEBUG_LEVEL > 1
+ else
+ {
+ OString aStr( OUStringToOString( pITD->ppAllMembers[i]->pTypeName, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( "\n### cannot get attribute type description: %s", aStr.getStr() );
+ }
+#endif
+ }
+ }
+
+ MutexGuard aGuard( Init::get().getMutex() );
+ if( !pTD->bComplete )
+ {
+ // create the index table from member to function table
+ pITD->pMapMemberIndexToFunctionIndex = new sal_Int32[ pITD->nAllMembers ];
+ sal_Int32 nAdditionalOffset = 0; // +1 for read/write attributes
+ sal_Int32 i;
+ for( i = 0; i < pITD->nAllMembers; i++ )
+ {
+ // index to the get method of the attribute
+ pITD->pMapMemberIndexToFunctionIndex[i] = i + nAdditionalOffset;
+ // extra offset if it is a read/write attribute?
+ if( pReadWriteAttributes[i] )
+ {
+ // a read/write attribute
+ nAdditionalOffset++;
+ }
+ }
+
+ // create the index table from function to member table
+ pITD->pMapFunctionIndexToMemberIndex = new sal_Int32[ pITD->nAllMembers + nAdditionalOffset ];
+ nAdditionalOffset = 0; // +1 for read/write attributes
+ for( i = 0; i < pITD->nAllMembers; i++ )
+ {
+ // index to the get method of the attribute
+ pITD->pMapFunctionIndexToMemberIndex[i + nAdditionalOffset] = i;
+ // extra offset if it is a read/write attribute?
+ if( pReadWriteAttributes[i] )
+ {
+ // a read/write attribute
+ pITD->pMapFunctionIndexToMemberIndex[i + ++nAdditionalOffset] = i;
+ }
+ }
+ // must be the last action after all initialization is done
+ pITD->nMapFunctionIndexToMemberIndex = pITD->nAllMembers + nAdditionalOffset;
+ pTD->bComplete = sal_True;
+ }
+}
+
+namespace {
+
+// In some situations (notably typelib_typedescription_newInterfaceMethod and
+// typelib_typedescription_newInterfaceAttribute), only the members nMembers,
+// ppMembers, nAllMembers, and ppAllMembers of an incomplete interface type
+// description are necessary, but not the additional
+// pMapMemberIndexToFunctionIndex, nMapFunctionIndexToMemberIndex, and
+// pMapFunctionIndexToMemberIndex (which are computed by
+// typelib_typedescription_initTables). Furthermore, in those situations, it
+// might be illegal to compute those tables, as the creation of the interface
+// member type descriptions would recursively require a complete interface type
+// description. The parameter initTables controls whether or not to call
+// typelib_typedescription_initTables in those situations.
+bool complete(typelib_TypeDescription ** ppTypeDescr, bool initTables) {
+ if (! (*ppTypeDescr)->bComplete)
+ {
+ OSL_ASSERT( (typelib_TypeClass_STRUCT == (*ppTypeDescr)->eTypeClass ||
+ typelib_TypeClass_EXCEPTION == (*ppTypeDescr)->eTypeClass ||
+ typelib_TypeClass_UNION == (*ppTypeDescr)->eTypeClass ||
+ typelib_TypeClass_ENUM == (*ppTypeDescr)->eTypeClass ||
+ typelib_TypeClass_INTERFACE == (*ppTypeDescr)->eTypeClass) &&
+ !reallyWeak( (*ppTypeDescr)->eTypeClass ) );
+
+ if (typelib_TypeClass_INTERFACE == (*ppTypeDescr)->eTypeClass &&
+ ((typelib_InterfaceTypeDescription *)*ppTypeDescr)->ppAllMembers)
+ {
+ if (initTables) {
+ typelib_typedescription_initTables( *ppTypeDescr );
+ }
+ return true;
+ }
+
+ typelib_TypeDescription * pTD = 0;
+ // on demand access of complete td
+ TypeDescriptor_Init_Impl &rInit = Init::get();
+ rInit.callChain( &pTD, (*ppTypeDescr)->pTypeName );
+ if (pTD)
+ {
+ if (typelib_TypeClass_TYPEDEF == pTD->eTypeClass)
+ {
+ typelib_typedescriptionreference_getDescription(
+ &pTD, ((typelib_IndirectTypeDescription *)pTD)->pType );
+ OSL_ASSERT( pTD );
+ if (! pTD)
+ return false;
+ }
+
+ OSL_ASSERT( typelib_TypeClass_TYPEDEF != pTD->eTypeClass );
+ // typedescription found
+ // set to on demand
+ pTD->bOnDemand = sal_True;
+
+ if (pTD->eTypeClass == typelib_TypeClass_INTERFACE
+ && !pTD->bComplete && initTables)
+ {
+ // mandatory info from callback chain
+ OSL_ASSERT( ((typelib_InterfaceTypeDescription *)pTD)->ppAllMembers );
+ // complete except of tables init
+ typelib_typedescription_initTables( pTD );
+ pTD->bComplete = sal_True;
+ }
+
+ // The type description is hold by the reference until
+ // on demand is activated.
+ ::typelib_typedescription_register( &pTD ); // replaces incomplete one
+ OSL_ASSERT( pTD == *ppTypeDescr ); // has to merge into existing one
+
+ // insert into the chache
+ MutexGuard aGuard( rInit.getMutex() );
+ if( !rInit.pCache )
+ rInit.pCache = new TypeDescriptionList_Impl;
+ if( (sal_Int32)rInit.pCache->size() >= nCacheSize )
+ {
+ typelib_typedescription_release( rInit.pCache->front() );
+ rInit.pCache->pop_front();
+ }
+ // descriptions in the cache must be acquired!
+ typelib_typedescription_acquire( pTD );
+ rInit.pCache->push_back( pTD );
+
+ OSL_ASSERT(
+ pTD->bComplete
+ || (pTD->eTypeClass == typelib_TypeClass_INTERFACE
+ && !initTables));
+
+ ::typelib_typedescription_release( *ppTypeDescr );
+ *ppTypeDescr = pTD;
+ }
+ else
+ {
+#if OSL_DEBUG_LEVEL > 1
+ OString aStr(
+ OUStringToOString( (*ppTypeDescr)->pTypeName, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( "\n### type cannot be completed: %s", aStr.getStr() );
+#endif
+ return false;
+ }
+ }
+ return true;
+}
+
+}
+
+//------------------------------------------------------------------------
+extern "C" void SAL_CALL typelib_typedescription_newEmpty(
+ typelib_TypeDescription ** ppRet,
+ typelib_TypeClass eTypeClass, rtl_uString * pTypeName )
+ SAL_THROW_EXTERN_C()
+{
+ if( *ppRet )
+ {
+ typelib_typedescription_release( *ppRet );
+ *ppRet = 0;
+ }
+
+ OSL_ASSERT( typelib_TypeClass_TYPEDEF != eTypeClass );
+
+ typelib_TypeDescription * pRet;
+ switch( eTypeClass )
+ {
+ case typelib_TypeClass_ARRAY:
+ {
+ typelib_ArrayTypeDescription * pTmp = new typelib_ArrayTypeDescription();
+ typelib_IndirectTypeDescription * pIndirect = (typelib_IndirectTypeDescription *)pTmp;
+ pRet = (typelib_TypeDescription *)pTmp;
+#if OSL_DEBUG_LEVEL > 1
+ osl_incrementInterlockedCount(
+ &Init::get().nArrayTypeDescriptionCount );
+#endif
+ pIndirect->pType = 0;
+ pTmp->nDimensions = 0;
+ pTmp->nTotalElements = 0;
+ pTmp->pDimensions = 0;
+ }
+ break;
+
+ case typelib_TypeClass_SEQUENCE:
+ {
+ typelib_IndirectTypeDescription * pTmp = new typelib_IndirectTypeDescription();
+ pRet = (typelib_TypeDescription *)pTmp;
+#if OSL_DEBUG_LEVEL > 1
+ osl_incrementInterlockedCount(
+ &Init::get().nIndirectTypeDescriptionCount );
+#endif
+ pTmp->pType = 0;
+ }
+ break;
+
+ case typelib_TypeClass_UNION:
+ {
+ typelib_UnionTypeDescription * pTmp;
+ pTmp = new typelib_UnionTypeDescription();
+ pRet = (typelib_TypeDescription *)pTmp;
+#if OSL_DEBUG_LEVEL > 1
+ osl_incrementInterlockedCount(
+ &Init::get().nUnionTypeDescriptionCount );
+#endif
+ pTmp->nMembers = 0;
+ pTmp->pDiscriminantTypeRef = 0;
+ pTmp->pDiscriminants = 0;
+ pTmp->ppTypeRefs = 0;
+ pTmp->ppMemberNames = 0;
+ pTmp->pDefaultTypeRef = 0;
+ }
+ break;
+
+ case typelib_TypeClass_STRUCT:
+ {
+ // FEATURE_EMPTYCLASS
+ typelib_StructTypeDescription * pTmp;
+ pTmp = new typelib_StructTypeDescription();
+ pRet = (typelib_TypeDescription *)pTmp;
+#if OSL_DEBUG_LEVEL > 1
+ osl_incrementInterlockedCount(
+ &Init::get().nCompoundTypeDescriptionCount );
+#endif
+ pTmp->aBase.pBaseTypeDescription = 0;
+ pTmp->aBase.nMembers = 0;
+ pTmp->aBase.pMemberOffsets = 0;
+ pTmp->aBase.ppTypeRefs = 0;
+ pTmp->aBase.ppMemberNames = 0;
+ pTmp->pParameterizedTypes = 0;
+ }
+ break;
+
+ case typelib_TypeClass_EXCEPTION:
+ {
+ // FEATURE_EMPTYCLASS
+ typelib_CompoundTypeDescription * pTmp;
+ pTmp = new typelib_CompoundTypeDescription();
+ pRet = (typelib_TypeDescription *)pTmp;
+#if OSL_DEBUG_LEVEL > 1
+ osl_incrementInterlockedCount(
+ &Init::get().nCompoundTypeDescriptionCount );
+#endif
+ pTmp->pBaseTypeDescription = 0;
+ pTmp->nMembers = 0;
+ pTmp->pMemberOffsets = 0;
+ pTmp->ppTypeRefs = 0;
+ pTmp->ppMemberNames = 0;
+ }
+ break;
+
+ case typelib_TypeClass_ENUM:
+ {
+ typelib_EnumTypeDescription * pTmp = new typelib_EnumTypeDescription();
+ pRet = (typelib_TypeDescription *)pTmp;
+#if OSL_DEBUG_LEVEL > 1
+ osl_incrementInterlockedCount(
+ &Init::get().nEnumTypeDescriptionCount );
+#endif
+ pTmp->nDefaultEnumValue = 0;
+ pTmp->nEnumValues = 0;
+ pTmp->ppEnumNames = 0;
+ pTmp->pEnumValues = 0;
+ }
+ break;
+
+ case typelib_TypeClass_INTERFACE:
+ {
+ typelib_InterfaceTypeDescription * pTmp = new typelib_InterfaceTypeDescription();
+ pRet = (typelib_TypeDescription *)pTmp;
+#if OSL_DEBUG_LEVEL > 1
+ osl_incrementInterlockedCount(
+ &Init::get().nInterfaceTypeDescriptionCount );
+#endif
+ pTmp->pBaseTypeDescription = 0;
+ pTmp->nMembers = 0;
+ pTmp->ppMembers = 0;
+ pTmp->nAllMembers = 0;
+ pTmp->ppAllMembers = 0;
+ pTmp->nMapFunctionIndexToMemberIndex = 0;
+ pTmp->pMapFunctionIndexToMemberIndex = 0;
+ pTmp->pMapMemberIndexToFunctionIndex= 0;
+ pTmp->nBaseTypes = 0;
+ pTmp->ppBaseTypes = 0;
+ }
+ break;
+
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ typelib_InterfaceMethodTypeDescription * pTmp = new typelib_InterfaceMethodTypeDescription();
+ pRet = (typelib_TypeDescription *)pTmp;
+#if OSL_DEBUG_LEVEL > 1
+ osl_incrementInterlockedCount(
+ &Init::get().nInterfaceMethodTypeDescriptionCount );
+#endif
+ pTmp->aBase.pMemberName = 0;
+ pTmp->pReturnTypeRef = 0;
+ pTmp->nParams = 0;
+ pTmp->pParams = 0;
+ pTmp->nExceptions = 0;
+ pTmp->ppExceptions = 0;
+ pTmp->pInterface = 0;
+ pTmp->pBaseRef = 0;
+ pTmp->nIndex = 0;
+ }
+ break;
+
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ typelib_InterfaceAttributeTypeDescription * pTmp = new typelib_InterfaceAttributeTypeDescription();
+ pRet = (typelib_TypeDescription *)pTmp;
+#if OSL_DEBUG_LEVEL > 1
+ osl_incrementInterlockedCount(
+ &Init::get().nInterfaceAttributeTypeDescriptionCount );
+#endif
+ pTmp->aBase.pMemberName = 0;
+ pTmp->pAttributeTypeRef = 0;
+ pTmp->pInterface = 0;
+ pTmp->pBaseRef = 0;
+ pTmp->nIndex = 0;
+ pTmp->nGetExceptions = 0;
+ pTmp->ppGetExceptions = 0;
+ pTmp->nSetExceptions = 0;
+ pTmp->ppSetExceptions = 0;
+ }
+ break;
+
+ default:
+ {
+ pRet = new typelib_TypeDescription();
+#if OSL_DEBUG_LEVEL > 1
+ osl_incrementInterlockedCount( &Init::get().nTypeDescriptionCount );
+#endif
+ }
+ }
+
+ pRet->nRefCount = 1; // reference count is initially 1
+ pRet->nStaticRefCount = 0;
+ pRet->eTypeClass = eTypeClass;
+ pRet->pTypeName = 0;
+ pRet->pUniqueIdentifier = 0;
+ pRet->pReserved = 0;
+ rtl_uString_acquire( pRet->pTypeName = pTypeName );
+ pRet->pSelf = pRet;
+ pRet->bComplete = sal_True;
+ pRet->nSize = 0;
+ pRet->nAlignment = 0;
+ pRet->pWeakRef = 0;
+ pRet->bOnDemand = sal_False;
+ *ppRet = pRet;
+}
+
+//------------------------------------------------------------------------
+namespace {
+
+void newTypeDescription(
+ typelib_TypeDescription ** ppRet, typelib_TypeClass eTypeClass,
+ rtl_uString * pTypeName, typelib_TypeDescriptionReference * pType,
+ sal_Int32 nMembers, typelib_CompoundMember_Init * pCompoundMembers,
+ typelib_StructMember_Init * pStructMembers)
+{
+ OSL_ASSERT(
+ (pCompoundMembers == 0 || pStructMembers == 0)
+ && (pStructMembers == 0 || eTypeClass == typelib_TypeClass_STRUCT));
+ if (typelib_TypeClass_TYPEDEF == eTypeClass)
+ {
+ OSL_TRACE( "### unexpected typedef!" );
+ typelib_typedescriptionreference_getDescription( ppRet, pType );
+ return;
+ }
+
+ typelib_typedescription_newEmpty( ppRet, eTypeClass, pTypeName );
+
+ switch( eTypeClass )
+ {
+ case typelib_TypeClass_SEQUENCE:
+ {
+ OSL_ASSERT( nMembers == 0 );
+ typelib_typedescriptionreference_acquire( pType );
+ ((typelib_IndirectTypeDescription *)*ppRet)->pType = pType;
+ }
+ break;
+
+ case typelib_TypeClass_EXCEPTION:
+ case typelib_TypeClass_STRUCT:
+ {
+ // FEATURE_EMPTYCLASS
+ typelib_CompoundTypeDescription * pTmp = (typelib_CompoundTypeDescription*)*ppRet;
+
+ sal_Int32 nOffset = 0;
+ if( pType )
+ {
+ typelib_typedescriptionreference_getDescription(
+ (typelib_TypeDescription **)&pTmp->pBaseTypeDescription, pType );
+ nOffset = ((typelib_TypeDescription *)pTmp->pBaseTypeDescription)->nSize;
+ OSL_ENSURE( newAlignedSize( 0, ((typelib_TypeDescription *)pTmp->pBaseTypeDescription)->nSize, ((typelib_TypeDescription *)pTmp->pBaseTypeDescription)->nAlignment ) == ((typelib_TypeDescription *)pTmp->pBaseTypeDescription)->nSize, "### unexpected offset!" );
+ }
+ if( nMembers )
+ {
+ pTmp->nMembers = nMembers;
+ pTmp->pMemberOffsets = new sal_Int32[ nMembers ];
+ pTmp->ppTypeRefs = new typelib_TypeDescriptionReference *[ nMembers ];
+ pTmp->ppMemberNames = new rtl_uString *[ nMembers ];
+ bool polymorphic = eTypeClass == typelib_TypeClass_STRUCT
+ && rtl::OUString::unacquired(&pTypeName).indexOf('<') >= 0;
+ OSL_ASSERT(!polymorphic || pStructMembers != 0);
+ if (polymorphic) {
+ reinterpret_cast< typelib_StructTypeDescription * >(pTmp)->
+ pParameterizedTypes = new sal_Bool[nMembers];
+ }
+ for( sal_Int32 i = 0 ; i < nMembers; i++ )
+ {
+ // read the type and member names
+ pTmp->ppTypeRefs[i] = 0;
+ if (pCompoundMembers != 0) {
+ typelib_typedescriptionreference_new(
+ pTmp->ppTypeRefs +i, pCompoundMembers[i].eTypeClass,
+ pCompoundMembers[i].pTypeName );
+ rtl_uString_acquire(
+ pTmp->ppMemberNames[i]
+ = pCompoundMembers[i].pMemberName );
+ } else {
+ typelib_typedescriptionreference_new(
+ pTmp->ppTypeRefs +i,
+ pStructMembers[i].aBase.eTypeClass,
+ pStructMembers[i].aBase.pTypeName );
+ rtl_uString_acquire(
+ pTmp->ppMemberNames[i]
+ = pStructMembers[i].aBase.pMemberName );
+ }
+ // write offset
+ sal_Int32 size;
+ sal_Int32 alignment;
+ if (pTmp->ppTypeRefs[i]->eTypeClass ==
+ typelib_TypeClass_SEQUENCE)
+ {
+ // Take care of recursion like
+ // struct S { sequence<S> x; };
+ size = sizeof(void *);
+ alignment = adjustAlignment(size);
+ } else {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, pTmp->ppTypeRefs[i] );
+ OSL_ENSURE( pTD->nSize, "### void member?" );
+ size = pTD->nSize;
+ alignment = pTD->nAlignment;
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ nOffset = newAlignedSize( nOffset, size, alignment );
+ pTmp->pMemberOffsets[i] = nOffset - size;
+
+ if (polymorphic) {
+ reinterpret_cast< typelib_StructTypeDescription * >(
+ pTmp)->pParameterizedTypes[i]
+ = pStructMembers[i].bParameterizedType;
+ }
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if( !reallyWeak( eTypeClass ) )
+ (*ppRet)->pWeakRef = (typelib_TypeDescriptionReference *)*ppRet;
+ if( eTypeClass != typelib_TypeClass_VOID )
+ {
+ // sizeof( void ) not allowed
+ (*ppRet)->nSize = typelib_typedescription_getAlignedUnoSize( (*ppRet), 0, (*ppRet)->nAlignment );
+ (*ppRet)->nAlignment = adjustAlignment( (*ppRet)->nAlignment );
+ }
+}
+
+}
+
+extern "C" void SAL_CALL typelib_typedescription_new(
+ typelib_TypeDescription ** ppRet,
+ typelib_TypeClass eTypeClass,
+ rtl_uString * pTypeName,
+ typelib_TypeDescriptionReference * pType,
+ sal_Int32 nMembers,
+ typelib_CompoundMember_Init * pMembers )
+ SAL_THROW_EXTERN_C()
+{
+ newTypeDescription(
+ ppRet, eTypeClass, pTypeName, pType, nMembers, pMembers, 0);
+}
+
+extern "C" void SAL_CALL typelib_typedescription_newStruct(
+ typelib_TypeDescription ** ppRet,
+ rtl_uString * pTypeName,
+ typelib_TypeDescriptionReference * pType,
+ sal_Int32 nMembers,
+ typelib_StructMember_Init * pMembers )
+ SAL_THROW_EXTERN_C()
+{
+ newTypeDescription(
+ ppRet, typelib_TypeClass_STRUCT, pTypeName, pType, nMembers, 0,
+ pMembers);
+}
+
+//------------------------------------------------------------------------
+extern "C" void SAL_CALL typelib_typedescription_newUnion(
+ typelib_TypeDescription ** ppRet,
+ rtl_uString * pTypeName,
+ typelib_TypeDescriptionReference * pDiscriminantTypeRef,
+ sal_Int64 nDefaultDiscriminant,
+ typelib_TypeDescriptionReference * pDefaultTypeRef,
+ sal_Int32 nMembers,
+ typelib_Union_Init * pMembers )
+ SAL_THROW_EXTERN_C()
+{
+ typelib_typedescription_newEmpty( ppRet, typelib_TypeClass_UNION, pTypeName );
+ // discriminant type
+ typelib_UnionTypeDescription * pTmp = (typelib_UnionTypeDescription *)*ppRet;
+ typelib_typedescriptionreference_acquire( pTmp->pDiscriminantTypeRef = pDiscriminantTypeRef );
+
+ sal_Int32 nPos;
+
+ pTmp->nMembers = nMembers;
+ // default discriminant
+ if (nMembers)
+ {
+ pTmp->pDiscriminants = new sal_Int64[ nMembers ];
+ for ( nPos = nMembers; nPos--; )
+ {
+ pTmp->pDiscriminants[nPos] = pMembers[nPos].nDiscriminant;
+ }
+ }
+ // default default discriminant
+ pTmp->nDefaultDiscriminant = nDefaultDiscriminant;
+
+ // union member types
+ pTmp->ppTypeRefs = new typelib_TypeDescriptionReference *[ nMembers ];
+ for ( nPos = nMembers; nPos--; )
+ {
+ typelib_typedescriptionreference_acquire( pTmp->ppTypeRefs[nPos] = pMembers[nPos].pTypeRef );
+ }
+ // union member names
+ pTmp->ppMemberNames = new rtl_uString *[ nMembers ];
+ for ( nPos = nMembers; nPos--; )
+ {
+ rtl_uString_acquire( pTmp->ppMemberNames[nPos] = pMembers[nPos].pMemberName );
+ }
+
+ // default union type
+ typelib_typedescriptionreference_acquire( pTmp->pDefaultTypeRef = pDefaultTypeRef );
+
+ if (! reallyWeak( typelib_TypeClass_UNION ))
+ (*ppRet)->pWeakRef = (typelib_TypeDescriptionReference *)*ppRet;
+ (*ppRet)->nSize = typelib_typedescription_getAlignedUnoSize( (*ppRet), 0, (*ppRet)->nAlignment );
+ (*ppRet)->nAlignment = adjustAlignment( (*ppRet)->nAlignment );
+}
+
+//------------------------------------------------------------------------
+extern "C" void SAL_CALL typelib_typedescription_newEnum(
+ typelib_TypeDescription ** ppRet,
+ rtl_uString * pTypeName,
+ sal_Int32 nDefaultValue,
+ sal_Int32 nEnumValues,
+ rtl_uString ** ppEnumNames,
+ sal_Int32 * pEnumValues )
+ SAL_THROW_EXTERN_C()
+{
+ typelib_typedescription_newEmpty( ppRet, typelib_TypeClass_ENUM, pTypeName );
+ typelib_EnumTypeDescription * pEnum = (typelib_EnumTypeDescription *)*ppRet;
+
+ pEnum->nDefaultEnumValue = nDefaultValue;
+ pEnum->nEnumValues = nEnumValues;
+ pEnum->ppEnumNames = new rtl_uString * [ nEnumValues ];
+ for ( sal_Int32 nPos = nEnumValues; nPos--; )
+ {
+ rtl_uString_acquire( pEnum->ppEnumNames[nPos] = ppEnumNames[nPos] );
+ }
+ pEnum->pEnumValues = new sal_Int32[ nEnumValues ];
+ ::memcpy( pEnum->pEnumValues, pEnumValues, nEnumValues * sizeof(sal_Int32) );
+
+ (*ppRet)->pWeakRef = (typelib_TypeDescriptionReference *)*ppRet;
+ // sizeof( void ) not allowed
+ (*ppRet)->nSize = typelib_typedescription_getAlignedUnoSize( (*ppRet), 0, (*ppRet)->nAlignment );
+ (*ppRet)->nAlignment = adjustAlignment( (*ppRet)->nAlignment );
+}
+
+//------------------------------------------------------------------------
+extern "C" void SAL_CALL typelib_typedescription_newArray(
+ typelib_TypeDescription ** ppRet,
+ typelib_TypeDescriptionReference * pElementTypeRef,
+ sal_Int32 nDimensions,
+ sal_Int32 * pDimensions )
+ SAL_THROW_EXTERN_C ()
+{
+ OUStringBuffer aBuf( 32 );
+ aBuf.append( pElementTypeRef->pTypeName );
+ sal_Int32 nElements = 1;
+ for (sal_Int32 i=0; i < nDimensions; i++)
+ {
+ aBuf.appendAscii("[");
+ aBuf.append(pDimensions[i]);
+ aBuf.appendAscii("]");
+ nElements *= pDimensions[i];
+ }
+ OUString aTypeName( aBuf.makeStringAndClear() );
+
+
+ typelib_typedescription_newEmpty( ppRet, typelib_TypeClass_ARRAY, aTypeName.pData );
+ typelib_ArrayTypeDescription * pArray = (typelib_ArrayTypeDescription *)*ppRet;
+
+ pArray->nDimensions = nDimensions;
+ pArray->nTotalElements = nElements;
+ pArray->pDimensions = new sal_Int32[ nDimensions ];
+ ::memcpy( pArray->pDimensions, pDimensions, nDimensions * sizeof(sal_Int32) );
+
+ typelib_typedescriptionreference_acquire(pElementTypeRef);
+ ((typelib_IndirectTypeDescription*)pArray)->pType = pElementTypeRef;
+
+ (*ppRet)->pWeakRef = (typelib_TypeDescriptionReference *)*ppRet;
+ // sizeof( void ) not allowed
+ (*ppRet)->nSize = typelib_typedescription_getAlignedUnoSize( *ppRet, 0, (*ppRet)->nAlignment );
+ (*ppRet)->nAlignment = adjustAlignment( (*ppRet)->nAlignment );
+}
+
+//------------------------------------------------------------------------
+extern "C" void SAL_CALL typelib_typedescription_newInterface(
+ typelib_InterfaceTypeDescription ** ppRet,
+ rtl_uString * pTypeName,
+ sal_uInt32 nUik1, sal_uInt16 nUik2, sal_uInt16 nUik3, sal_uInt32 nUik4, sal_uInt32 nUik5,
+ typelib_TypeDescriptionReference * pBaseInterface,
+ sal_Int32 nMembers,
+ typelib_TypeDescriptionReference ** ppMembers )
+ SAL_THROW_EXTERN_C()
+{
+ typelib_typedescription_newMIInterface(
+ ppRet, pTypeName, nUik1, nUik2, nUik3, nUik4, nUik5,
+ pBaseInterface == 0 ? 0 : 1, &pBaseInterface, nMembers, ppMembers);
+}
+
+//------------------------------------------------------------------------
+
+namespace {
+
+class BaseList {
+public:
+ struct Entry {
+ sal_Int32 memberOffset;
+ sal_Int32 directBaseIndex;
+ sal_Int32 directBaseMemberOffset;
+ typelib_InterfaceTypeDescription const * base;
+ };
+
+ typedef std::vector< Entry > List;
+
+ BaseList(typelib_InterfaceTypeDescription const * desc);
+
+ List const & getList() const { return list; }
+
+ sal_Int32 getBaseMembers() const { return members; }
+
+private:
+ typedef std::set< rtl::OUString > Set;
+
+ void calculate(
+ sal_Int32 directBaseIndex, Set & directBaseSet,
+ sal_Int32 * directBaseMembers,
+ typelib_InterfaceTypeDescription const * desc);
+
+ Set set;
+ List list;
+ sal_Int32 members;
+};
+
+BaseList::BaseList(typelib_InterfaceTypeDescription const * desc) {
+ members = 0;
+ for (sal_Int32 i = 0; i < desc->nBaseTypes; ++i) {
+ Set directBaseSet;
+ sal_Int32 directBaseMembers = 0;
+ calculate(i, directBaseSet, &directBaseMembers, desc->ppBaseTypes[i]);
+ }
+}
+
+void BaseList::calculate(
+ sal_Int32 directBaseIndex, Set & directBaseSet,
+ sal_Int32 * directBaseMembers,
+ typelib_InterfaceTypeDescription const * desc)
+{
+ for (sal_Int32 i = 0; i < desc->nBaseTypes; ++i) {
+ calculate(
+ directBaseIndex, directBaseSet, directBaseMembers,
+ desc->ppBaseTypes[i]);
+ }
+ if (set.insert(desc->aBase.pTypeName).second) {
+ Entry e;
+ e.memberOffset = members;
+ e.directBaseIndex = directBaseIndex;
+ e.directBaseMemberOffset = *directBaseMembers;
+ e.base = desc;
+ list.push_back(e);
+ OSL_ASSERT(desc->ppAllMembers != 0);
+ members += desc->nMembers;
+ }
+ if (directBaseSet.insert(desc->aBase.pTypeName).second) {
+ OSL_ASSERT(desc->ppAllMembers != 0);
+ *directBaseMembers += desc->nMembers;
+ }
+}
+
+}
+
+extern "C" void SAL_CALL typelib_typedescription_newMIInterface(
+ typelib_InterfaceTypeDescription ** ppRet,
+ rtl_uString * pTypeName,
+ sal_uInt32 nUik1, sal_uInt16 nUik2, sal_uInt16 nUik3, sal_uInt32 nUik4, sal_uInt32 nUik5,
+ sal_Int32 nBaseInterfaces,
+ typelib_TypeDescriptionReference ** ppBaseInterfaces,
+ sal_Int32 nMembers,
+ typelib_TypeDescriptionReference ** ppMembers )
+ SAL_THROW_EXTERN_C()
+{
+ if (*ppRet != 0) {
+ typelib_typedescription_release(&(*ppRet)->aBase);
+ *ppRet = 0;
+ }
+
+ typelib_InterfaceTypeDescription * pITD = 0;
+ typelib_typedescription_newEmpty(
+ (typelib_TypeDescription **)&pITD, typelib_TypeClass_INTERFACE, pTypeName );
+
+ pITD->nBaseTypes = nBaseInterfaces;
+ pITD->ppBaseTypes = new typelib_InterfaceTypeDescription *[nBaseInterfaces];
+ for (sal_Int32 i = 0; i < nBaseInterfaces; ++i) {
+ pITD->ppBaseTypes[i] = 0;
+ typelib_typedescriptionreference_getDescription(
+ reinterpret_cast< typelib_TypeDescription ** >(
+ &pITD->ppBaseTypes[i]),
+ ppBaseInterfaces[i]);
+ if (pITD->ppBaseTypes[i] == 0
+ || !complete(
+ reinterpret_cast< typelib_TypeDescription ** >(
+ &pITD->ppBaseTypes[i]),
+ false))
+ {
+ OSL_ASSERT(false);
+ return;
+ }
+ OSL_ASSERT(pITD->ppBaseTypes[i] != 0);
+ }
+ if (nBaseInterfaces > 0) {
+ pITD->pBaseTypeDescription = pITD->ppBaseTypes[0];
+ }
+ // set the
+ pITD->aUik.m_Data1 = nUik1;
+ pITD->aUik.m_Data2 = nUik2;
+ pITD->aUik.m_Data3 = nUik3;
+ pITD->aUik.m_Data4 = nUik4;
+ pITD->aUik.m_Data5 = nUik5;
+
+ BaseList aBaseList(pITD);
+ pITD->nAllMembers = nMembers + aBaseList.getBaseMembers();
+ pITD->nMembers = nMembers;
+
+ if( pITD->nAllMembers )
+ {
+ // at minimum one member exist, allocate the memory
+ pITD->ppAllMembers = new typelib_TypeDescriptionReference *[ pITD->nAllMembers ];
+ sal_Int32 n = 0;
+
+ BaseList::List const & rList = aBaseList.getList();
+ {for (BaseList::List::const_iterator i(rList.begin()); i != rList.end();
+ ++i)
+ {
+ typelib_InterfaceTypeDescription const * pBase = i->base;
+ typelib_InterfaceTypeDescription const * pDirectBase
+ = pITD->ppBaseTypes[i->directBaseIndex];
+ OSL_ASSERT(pBase->ppAllMembers != 0);
+ for (sal_Int32 j = 0; j < pBase->nMembers; ++j) {
+ typelib_TypeDescriptionReference const * pDirectBaseMember
+ = pDirectBase->ppAllMembers[i->directBaseMemberOffset + j];
+ rtl::OUStringBuffer aBuf(pDirectBaseMember->pTypeName);
+ aBuf.appendAscii(RTL_CONSTASCII_STRINGPARAM(":@"));
+ aBuf.append(i->directBaseIndex);
+ aBuf.append(static_cast< sal_Unicode >(','));
+ aBuf.append(i->memberOffset + j);
+ aBuf.append(static_cast< sal_Unicode >(':'));
+ aBuf.append(pITD->aBase.pTypeName);
+ rtl::OUString aName(aBuf.makeStringAndClear());
+ typelib_TypeDescriptionReference * pDerivedMember = 0;
+ typelib_typedescriptionreference_new(
+ &pDerivedMember, pDirectBaseMember->eTypeClass,
+ aName.pData);
+ pITD->ppAllMembers[n++] = pDerivedMember;
+ }
+ }}
+
+ if( nMembers )
+ {
+ pITD->ppMembers = pITD->ppAllMembers + aBaseList.getBaseMembers();
+ }
+
+ // add own members
+ {for( sal_Int32 i = 0; i < nMembers; i++ )
+ {
+ typelib_typedescriptionreference_acquire( ppMembers[i] );
+ pITD->ppAllMembers[n++] = ppMembers[i];
+ }}
+ }
+
+ typelib_TypeDescription * pTmp = (typelib_TypeDescription *)pITD;
+ if( !reallyWeak( typelib_TypeClass_INTERFACE ) )
+ pTmp->pWeakRef = (typelib_TypeDescriptionReference *)pTmp;
+ pTmp->nSize = typelib_typedescription_getAlignedUnoSize( pTmp, 0, pTmp->nAlignment );
+ pTmp->nAlignment = adjustAlignment( pTmp->nAlignment );
+ pTmp->bComplete = sal_False;
+
+ *ppRet = pITD;
+}
+
+//------------------------------------------------------------------------
+
+namespace {
+
+typelib_TypeDescriptionReference ** copyExceptions(
+ sal_Int32 count, rtl_uString ** typeNames)
+{
+ OSL_ASSERT(count >= 0);
+ if (count == 0) {
+ return 0;
+ }
+ typelib_TypeDescriptionReference ** p
+ = new typelib_TypeDescriptionReference *[count];
+ for (sal_Int32 i = 0; i < count; ++i) {
+ p[i] = 0;
+ typelib_typedescriptionreference_new(
+ p + i, typelib_TypeClass_EXCEPTION, typeNames[i]);
+ }
+ return p;
+}
+
+}
+
+extern "C" void SAL_CALL typelib_typedescription_newInterfaceMethod(
+ typelib_InterfaceMethodTypeDescription ** ppRet,
+ sal_Int32 nAbsolutePosition,
+ sal_Bool bOneWay,
+ rtl_uString * pTypeName,
+ typelib_TypeClass eReturnTypeClass,
+ rtl_uString * pReturnTypeName,
+ sal_Int32 nParams,
+ typelib_Parameter_Init * pParams,
+ sal_Int32 nExceptions,
+ rtl_uString ** ppExceptionNames )
+ SAL_THROW_EXTERN_C()
+{
+ if (*ppRet != 0) {
+ typelib_typedescription_release(&(*ppRet)->aBase.aBase);
+ *ppRet = 0;
+ }
+ sal_Int32 nOffset = rtl_ustr_lastIndexOfChar_WithLength(
+ pTypeName->buffer, pTypeName->length, ':');
+ if (nOffset <= 0 || pTypeName->buffer[nOffset - 1] != ':') {
+ OSL_ENSURE(false, "Bad interface method type name");
+ return;
+ }
+ rtl::OUString aInterfaceTypeName(pTypeName->buffer, nOffset - 1);
+ typelib_InterfaceTypeDescription * pInterface = 0;
+ typelib_typedescription_getByName(
+ reinterpret_cast< typelib_TypeDescription ** >(&pInterface),
+ aInterfaceTypeName.pData);
+ if (pInterface == 0
+ || pInterface->aBase.eTypeClass != typelib_TypeClass_INTERFACE
+ || !complete(
+ reinterpret_cast< typelib_TypeDescription ** >(&pInterface), false))
+ {
+ OSL_ENSURE(false, "No interface corresponding to interface method");
+ return;
+ }
+
+ typelib_typedescription_newEmpty(
+ (typelib_TypeDescription **)ppRet, typelib_TypeClass_INTERFACE_METHOD, pTypeName );
+ typelib_TypeDescription * pTmp = (typelib_TypeDescription *)*ppRet;
+
+ rtl_uString_newFromStr_WithLength( &(*ppRet)->aBase.pMemberName,
+ pTypeName->buffer + nOffset +1,
+ pTypeName->length - nOffset -1 );
+ (*ppRet)->aBase.nPosition = nAbsolutePosition;
+ (*ppRet)->bOneWay = bOneWay;
+ typelib_typedescriptionreference_new( &(*ppRet)->pReturnTypeRef, eReturnTypeClass, pReturnTypeName );
+ (*ppRet)->nParams = nParams;
+ if( nParams )
+ {
+ (*ppRet)->pParams = new typelib_MethodParameter[ nParams ];
+
+ for( sal_Int32 i = 0; i < nParams; i++ )
+ {
+ // get the name of the parameter
+ (*ppRet)->pParams[ i ].pName = 0;
+ rtl_uString_acquire( (*ppRet)->pParams[ i ].pName = pParams[i].pParamName );
+ (*ppRet)->pParams[ i ].pTypeRef = 0;
+ // get the type name of the parameter and create the weak reference
+ typelib_typedescriptionreference_new(
+ &(*ppRet)->pParams[ i ].pTypeRef, pParams[i].eTypeClass, pParams[i].pTypeName );
+ (*ppRet)->pParams[ i ].bIn = pParams[i].bIn;
+ (*ppRet)->pParams[ i ].bOut = pParams[i].bOut;
+ }
+ }
+ (*ppRet)->nExceptions = nExceptions;
+ (*ppRet)->ppExceptions = copyExceptions(nExceptions, ppExceptionNames);
+ (*ppRet)->pInterface = pInterface;
+ (*ppRet)->pBaseRef = 0;
+ OSL_ASSERT(
+ (nAbsolutePosition >= pInterface->nAllMembers - pInterface->nMembers)
+ && nAbsolutePosition < pInterface->nAllMembers);
+ (*ppRet)->nIndex = nAbsolutePosition
+ - (pInterface->nAllMembers - pInterface->nMembers);
+ if( !reallyWeak( typelib_TypeClass_INTERFACE_METHOD ) )
+ pTmp->pWeakRef = (typelib_TypeDescriptionReference *)pTmp;
+}
+
+
+//------------------------------------------------------------------------
+extern "C" void SAL_CALL typelib_typedescription_newInterfaceAttribute(
+ typelib_InterfaceAttributeTypeDescription ** ppRet,
+ sal_Int32 nAbsolutePosition,
+ rtl_uString * pTypeName,
+ typelib_TypeClass eAttributeTypeClass,
+ rtl_uString * pAttributeTypeName,
+ sal_Bool bReadOnly )
+ SAL_THROW_EXTERN_C()
+{
+ typelib_typedescription_newExtendedInterfaceAttribute(
+ ppRet, nAbsolutePosition, pTypeName, eAttributeTypeClass,
+ pAttributeTypeName, bReadOnly, 0, 0, 0, 0);
+}
+
+//------------------------------------------------------------------------
+extern "C" void SAL_CALL typelib_typedescription_newExtendedInterfaceAttribute(
+ typelib_InterfaceAttributeTypeDescription ** ppRet,
+ sal_Int32 nAbsolutePosition,
+ rtl_uString * pTypeName,
+ typelib_TypeClass eAttributeTypeClass,
+ rtl_uString * pAttributeTypeName,
+ sal_Bool bReadOnly,
+ sal_Int32 nGetExceptions, rtl_uString ** ppGetExceptionNames,
+ sal_Int32 nSetExceptions, rtl_uString ** ppSetExceptionNames )
+ SAL_THROW_EXTERN_C()
+{
+ if (*ppRet != 0) {
+ typelib_typedescription_release(&(*ppRet)->aBase.aBase);
+ *ppRet = 0;
+ }
+ sal_Int32 nOffset = rtl_ustr_lastIndexOfChar_WithLength(
+ pTypeName->buffer, pTypeName->length, ':');
+ if (nOffset <= 0 || pTypeName->buffer[nOffset - 1] != ':') {
+ OSL_ENSURE(false, "Bad interface attribute type name");
+ return;
+ }
+ rtl::OUString aInterfaceTypeName(pTypeName->buffer, nOffset - 1);
+ typelib_InterfaceTypeDescription * pInterface = 0;
+ typelib_typedescription_getByName(
+ reinterpret_cast< typelib_TypeDescription ** >(&pInterface),
+ aInterfaceTypeName.pData);
+ if (pInterface == 0
+ || pInterface->aBase.eTypeClass != typelib_TypeClass_INTERFACE
+ || !complete(
+ reinterpret_cast< typelib_TypeDescription ** >(&pInterface), false))
+ {
+ OSL_ENSURE(false, "No interface corresponding to interface attribute");
+ return;
+ }
+
+ typelib_typedescription_newEmpty(
+ (typelib_TypeDescription **)ppRet, typelib_TypeClass_INTERFACE_ATTRIBUTE, pTypeName );
+ typelib_TypeDescription * pTmp = (typelib_TypeDescription *)*ppRet;
+
+ rtl_uString_newFromStr_WithLength( &(*ppRet)->aBase.pMemberName,
+ pTypeName->buffer + nOffset +1,
+ pTypeName->length - nOffset -1 );
+ (*ppRet)->aBase.nPosition = nAbsolutePosition;
+ typelib_typedescriptionreference_new( &(*ppRet)->pAttributeTypeRef, eAttributeTypeClass, pAttributeTypeName );
+ (*ppRet)->bReadOnly = bReadOnly;
+ (*ppRet)->pInterface = pInterface;
+ (*ppRet)->pBaseRef = 0;
+ OSL_ASSERT(
+ (nAbsolutePosition >= pInterface->nAllMembers - pInterface->nMembers)
+ && nAbsolutePosition < pInterface->nAllMembers);
+ (*ppRet)->nIndex = nAbsolutePosition
+ - (pInterface->nAllMembers - pInterface->nMembers);
+ (*ppRet)->nGetExceptions = nGetExceptions;
+ (*ppRet)->ppGetExceptions = copyExceptions(
+ nGetExceptions, ppGetExceptionNames);
+ (*ppRet)->nSetExceptions = nSetExceptions;
+ (*ppRet)->ppSetExceptions = copyExceptions(
+ nSetExceptions, ppSetExceptionNames);
+ if( !reallyWeak( typelib_TypeClass_INTERFACE_ATTRIBUTE ) )
+ pTmp->pWeakRef = (typelib_TypeDescriptionReference *)pTmp;
+}
+
+//------------------------------------------------------------------------
+extern "C" void SAL_CALL typelib_typedescription_acquire(
+ typelib_TypeDescription * pTypeDescription )
+ SAL_THROW_EXTERN_C()
+{
+ ::osl_incrementInterlockedCount( &pTypeDescription->nRefCount );
+}
+
+//------------------------------------------------------------------------
+
+namespace {
+
+void deleteExceptions(
+ sal_Int32 count, typelib_TypeDescriptionReference ** exceptions)
+{
+ for (sal_Int32 i = 0; i < count; ++i) {
+ typelib_typedescriptionreference_release(exceptions[i]);
+ }
+ delete[] exceptions;
+}
+
+}
+
+// frees anything except typelib_TypeDescription base!
+static inline void typelib_typedescription_destructExtendedMembers(
+ typelib_TypeDescription * pTD )
+ SAL_THROW( () )
+{
+ OSL_ASSERT( typelib_TypeClass_TYPEDEF != pTD->eTypeClass );
+
+ switch( pTD->eTypeClass )
+ {
+ case typelib_TypeClass_ARRAY:
+ if( ((typelib_IndirectTypeDescription*)pTD)->pType )
+ typelib_typedescriptionreference_release( ((typelib_IndirectTypeDescription*)pTD)->pType );
+ delete [] ((typelib_ArrayTypeDescription *)pTD)->pDimensions;
+ break;
+ case typelib_TypeClass_SEQUENCE:
+ if( ((typelib_IndirectTypeDescription*)pTD)->pType )
+ typelib_typedescriptionreference_release( ((typelib_IndirectTypeDescription*)pTD)->pType );
+ break;
+ case typelib_TypeClass_UNION:
+ {
+ typelib_UnionTypeDescription * pUnionTD = (typelib_UnionTypeDescription *)pTD;
+ typelib_typedescriptionreference_release( pUnionTD->pDiscriminantTypeRef );
+ typelib_typedescriptionreference_release( pUnionTD->pDefaultTypeRef );
+
+ sal_Int32 nPos;
+ typelib_TypeDescriptionReference ** ppTypeRefs = pUnionTD->ppTypeRefs;
+ for ( nPos = pUnionTD->nMembers; nPos--; )
+ {
+ typelib_typedescriptionreference_release( ppTypeRefs[nPos] );
+ }
+
+ rtl_uString ** ppMemberNames = pUnionTD->ppMemberNames;
+ for ( nPos = pUnionTD->nMembers; nPos--; )
+ {
+ rtl_uString_release( ppMemberNames[nPos] );
+ }
+ delete [] pUnionTD->ppMemberNames;
+ delete [] pUnionTD->pDiscriminants;
+ delete [] pUnionTD->ppTypeRefs;
+ }
+ break;
+ case typelib_TypeClass_STRUCT:
+ delete[] reinterpret_cast< typelib_StructTypeDescription * >(pTD)->
+ pParameterizedTypes;
+ case typelib_TypeClass_EXCEPTION:
+ {
+ typelib_CompoundTypeDescription * pCTD = (typelib_CompoundTypeDescription*)pTD;
+ if( pCTD->pBaseTypeDescription )
+ typelib_typedescription_release( (typelib_TypeDescription *)pCTD->pBaseTypeDescription );
+ sal_Int32 i;
+ for( i = 0; i < pCTD->nMembers; i++ )
+ {
+ typelib_typedescriptionreference_release( pCTD->ppTypeRefs[i] );
+ }
+ if (pCTD->ppMemberNames)
+ {
+ for ( i = 0; i < pCTD->nMembers; i++ )
+ {
+ rtl_uString_release( pCTD->ppMemberNames[i] );
+ }
+ delete [] pCTD->ppMemberNames;
+ }
+ delete [] pCTD->ppTypeRefs;
+ delete [] pCTD->pMemberOffsets;
+ }
+ break;
+ case typelib_TypeClass_INTERFACE:
+ {
+ typelib_InterfaceTypeDescription * pITD = (typelib_InterfaceTypeDescription*)pTD;
+ {for( sal_Int32 i = 0; i < pITD->nAllMembers; i++ )
+ {
+ typelib_typedescriptionreference_release( pITD->ppAllMembers[i] );
+ }}
+ delete [] pITD->ppAllMembers;
+ delete [] pITD->pMapMemberIndexToFunctionIndex;
+ delete [] pITD->pMapFunctionIndexToMemberIndex;
+ {for (sal_Int32 i = 0; i < pITD->nBaseTypes; ++i) {
+ typelib_typedescription_release(
+ reinterpret_cast< typelib_TypeDescription * >(
+ pITD->ppBaseTypes[i]));
+ }}
+ delete[] pITD->ppBaseTypes;
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ typelib_InterfaceMethodTypeDescription * pIMTD = (typelib_InterfaceMethodTypeDescription*)pTD;
+ if( pIMTD->pReturnTypeRef )
+ typelib_typedescriptionreference_release( pIMTD->pReturnTypeRef );
+ for( sal_Int32 i = 0; i < pIMTD->nParams; i++ )
+ {
+ rtl_uString_release( pIMTD->pParams[ i ].pName );
+ typelib_typedescriptionreference_release( pIMTD->pParams[ i ].pTypeRef );
+ }
+ delete [] pIMTD->pParams;
+ deleteExceptions(pIMTD->nExceptions, pIMTD->ppExceptions);
+ rtl_uString_release( pIMTD->aBase.pMemberName );
+ typelib_typedescription_release(&pIMTD->pInterface->aBase);
+ if (pIMTD->pBaseRef != 0) {
+ typelib_typedescriptionreference_release(pIMTD->pBaseRef);
+ }
+ }
+ break;
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ typelib_InterfaceAttributeTypeDescription * pIATD = (typelib_InterfaceAttributeTypeDescription*)pTD;
+ deleteExceptions(pIATD->nGetExceptions, pIATD->ppGetExceptions);
+ deleteExceptions(pIATD->nSetExceptions, pIATD->ppSetExceptions);
+ if( pIATD->pAttributeTypeRef )
+ typelib_typedescriptionreference_release( pIATD->pAttributeTypeRef );
+ if( pIATD->aBase.pMemberName )
+ rtl_uString_release( pIATD->aBase.pMemberName );
+ typelib_typedescription_release(&pIATD->pInterface->aBase);
+ if (pIATD->pBaseRef != 0) {
+ typelib_typedescriptionreference_release(pIATD->pBaseRef);
+ }
+ }
+ break;
+ case typelib_TypeClass_ENUM:
+ {
+ typelib_EnumTypeDescription * pEnum = (typelib_EnumTypeDescription *)pTD;
+ for ( sal_Int32 nPos = pEnum->nEnumValues; nPos--; )
+ {
+ rtl_uString_release( pEnum->ppEnumNames[nPos] );
+ }
+ delete [] pEnum->ppEnumNames;
+ delete [] pEnum->pEnumValues;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+//------------------------------------------------------------------------
+extern "C" void SAL_CALL typelib_typedescription_release(
+ typelib_TypeDescription * pTD )
+ SAL_THROW_EXTERN_C()
+{
+ sal_Int32 ref = ::osl_decrementInterlockedCount( &pTD->nRefCount );
+ OSL_ASSERT(ref >= 0);
+ if (0 == ref)
+ {
+ TypeDescriptor_Init_Impl &rInit = Init::get();
+ if( reallyWeak( pTD->eTypeClass ) )
+ {
+ if( pTD->pWeakRef )
+ {
+ {
+ MutexGuard aGuard( rInit.getMutex() );
+ // remove this description from the weak reference
+ pTD->pWeakRef->pType = 0;
+ }
+ typelib_typedescriptionreference_release( pTD->pWeakRef );
+ }
+ }
+ else
+ {
+ // this description is a reference too, so remove it from the hash table
+ if( rInit.pWeakMap )
+ {
+ MutexGuard aGuard( rInit.getMutex() );
+ WeakMap_Impl::iterator aIt = rInit.pWeakMap->find( (sal_Unicode*)pTD->pTypeName->buffer );
+ if( aIt != rInit.pWeakMap->end() && (void *)(*aIt).second == (void *)pTD )
+ {
+ // remove only if it contains the same object
+ rInit.pWeakMap->erase( aIt );
+ }
+ }
+ }
+
+ typelib_typedescription_destructExtendedMembers( pTD );
+ rtl_uString_release( pTD->pTypeName );
+
+#if OSL_DEBUG_LEVEL > 1
+ switch( pTD->eTypeClass )
+ {
+ case typelib_TypeClass_ARRAY:
+ osl_decrementInterlockedCount( &rInit.nArrayTypeDescriptionCount );
+ break;
+ case typelib_TypeClass_SEQUENCE:
+ osl_decrementInterlockedCount( &rInit.nIndirectTypeDescriptionCount );
+ break;
+ case typelib_TypeClass_UNION:
+ osl_decrementInterlockedCount( &rInit.nUnionTypeDescriptionCount );
+ break;
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ osl_decrementInterlockedCount( &rInit.nCompoundTypeDescriptionCount );
+ break;
+ case typelib_TypeClass_INTERFACE:
+ osl_decrementInterlockedCount( &rInit.nInterfaceTypeDescriptionCount );
+ break;
+ case typelib_TypeClass_INTERFACE_METHOD:
+ osl_decrementInterlockedCount( &rInit.nInterfaceMethodTypeDescriptionCount );
+ break;
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ osl_decrementInterlockedCount( &rInit.nInterfaceAttributeTypeDescriptionCount );
+ break;
+ case typelib_TypeClass_ENUM:
+ osl_decrementInterlockedCount( &rInit.nEnumTypeDescriptionCount );
+ break;
+ default:
+ osl_decrementInterlockedCount( &rInit.nTypeDescriptionCount );
+ }
+#endif
+
+ delete pTD;
+ }
+}
+
+//------------------------------------------------------------------------
+extern "C" void SAL_CALL typelib_typedescription_register(
+ typelib_TypeDescription ** ppNewDescription )
+ SAL_THROW_EXTERN_C()
+{
+ // connect the description with the weak reference
+ TypeDescriptor_Init_Impl &rInit = Init::get();
+ ClearableMutexGuard aGuard( rInit.getMutex() );
+
+ typelib_TypeDescriptionReference * pTDR = 0;
+ typelib_typedescriptionreference_getByName( &pTDR, (*ppNewDescription)->pTypeName );
+
+ OSL_ASSERT( (*ppNewDescription)->pWeakRef || reallyWeak( (*ppNewDescription)->eTypeClass ) );
+ if( pTDR )
+ {
+ OSL_ASSERT( (*ppNewDescription)->eTypeClass == pTDR->eTypeClass );
+ if( pTDR->pType )
+ {
+ if (reallyWeak( pTDR->eTypeClass ))
+ {
+ // pRef->pType->pWeakRef == 0 means that the description is empty
+ if (pTDR->pType->pWeakRef)
+ {
+ if (osl_incrementInterlockedCount( &pTDR->pType->nRefCount ) > 1)
+ {
+ // The refence is incremented. The object cannot be destroyed.
+ // Release the guard at the earliest point.
+ aGuard.clear();
+ ::typelib_typedescription_release( *ppNewDescription );
+ *ppNewDescription = pTDR->pType;
+ ::typelib_typedescriptionreference_release( pTDR );
+ return;
+ }
+ else
+ {
+ // destruction of this type in progress (another thread!)
+ osl_decrementInterlockedCount( &pTDR->pType->nRefCount );
+ }
+ }
+ // take new descr
+ pTDR->pType = *ppNewDescription;
+ OSL_ASSERT( ! (*ppNewDescription)->pWeakRef );
+ (*ppNewDescription)->pWeakRef = pTDR;
+ return;
+ }
+ // !reallyWeak
+
+ if (((void *)pTDR != (void *)*ppNewDescription) && // if different
+ (!pTDR->pType->pWeakRef || // uninit: ref data only set
+ // new one is complete:
+ (!pTDR->pType->bComplete && (*ppNewDescription)->bComplete) ||
+ // new one may be partly initialized interface (except of tables):
+ (typelib_TypeClass_INTERFACE == pTDR->pType->eTypeClass &&
+ !((typelib_InterfaceTypeDescription *)pTDR->pType)->ppAllMembers &&
+ (*(typelib_InterfaceTypeDescription **)ppNewDescription)->ppAllMembers)))
+ {
+ // uninitialized or incomplete
+
+ if (pTDR->pType->pWeakRef) // if init
+ {
+ typelib_typedescription_destructExtendedMembers( pTDR->pType );
+ }
+
+ // pTDR->pType->pWeakRef == 0 means that the description is empty
+ // description is not weak and the not the same
+ sal_Int32 nSize = getDescriptionSize( (*ppNewDescription)->eTypeClass );
+
+ // copy all specific data for the descriptions
+ ::rtl_copyMemory(
+ pTDR->pType +1,
+ *ppNewDescription +1,
+ nSize - sizeof(typelib_TypeDescription) );
+
+ pTDR->pType->bComplete = (*ppNewDescription)->bComplete;
+ pTDR->pType->nSize = (*ppNewDescription)->nSize;
+ pTDR->pType->nAlignment = (*ppNewDescription)->nAlignment;
+
+ ::rtl_zeroMemory(
+ *ppNewDescription +1, nSize - sizeof( typelib_TypeDescription ) );
+
+ if( pTDR->pType->bOnDemand && !(*ppNewDescription)->bOnDemand )
+ {
+ // switch from OnDemand to !OnDemand, so the description must be acquired
+ typelib_typedescription_acquire( pTDR->pType );
+ }
+ else if( !pTDR->pType->bOnDemand && (*ppNewDescription)->bOnDemand )
+ {
+ // switch from !OnDemand to OnDemand, so the description must be relesed
+ typelib_typedescription_release( pTDR->pType );
+ }
+
+ pTDR->pType->bOnDemand = (*ppNewDescription)->bOnDemand;
+ // initialized
+ pTDR->pType->pWeakRef = pTDR;
+ }
+
+ typelib_typedescription_release( *ppNewDescription );
+ // pTDR was acquired by getByName(), so it must not be acquired again
+ *ppNewDescription = pTDR->pType;
+ return;
+ }
+ }
+ else if( reallyWeak( (*ppNewDescription)->eTypeClass) )
+ {
+ typelib_typedescriptionreference_new(
+ &pTDR, (*ppNewDescription)->eTypeClass, (*ppNewDescription)->pTypeName );
+ }
+ else
+ {
+ pTDR = (typelib_TypeDescriptionReference *)*ppNewDescription;
+ if( !rInit.pWeakMap )
+ rInit.pWeakMap = new WeakMap_Impl;
+
+ // description is the weak itself, so register it
+ (*rInit.pWeakMap)[pTDR->pTypeName->buffer] = pTDR;
+ OSL_ASSERT( (void *)*ppNewDescription == (void *)pTDR );
+ }
+
+ // By default this reference is not really weak. The reference hold the description
+ // and the description hold the reference.
+ if( !(*ppNewDescription)->bOnDemand )
+ {
+ // nor OnDemand so the description must be acquired if registered
+ typelib_typedescription_acquire( *ppNewDescription );
+ }
+
+ pTDR->pType = *ppNewDescription;
+ (*ppNewDescription)->pWeakRef = pTDR;
+ OSL_ASSERT( rtl_ustr_compare( pTDR->pTypeName->buffer, (*ppNewDescription)->pTypeName->buffer ) == 0 );
+ OSL_ASSERT( pTDR->eTypeClass == (*ppNewDescription)->eTypeClass );
+}
+
+//------------------------------------------------------------------------
+static inline sal_Bool type_equals(
+ typelib_TypeDescriptionReference * p1, typelib_TypeDescriptionReference * p2 )
+ SAL_THROW( () )
+{
+ return (p1 == p2 ||
+ (p1->eTypeClass == p2->eTypeClass &&
+ p1->pTypeName->length == p2->pTypeName->length &&
+ rtl_ustr_compare( p1->pTypeName->buffer, p2->pTypeName->buffer ) == 0));
+}
+extern "C" sal_Bool SAL_CALL typelib_typedescription_equals(
+ const typelib_TypeDescription * p1, const typelib_TypeDescription * p2 )
+ SAL_THROW_EXTERN_C()
+{
+ return type_equals(
+ (typelib_TypeDescriptionReference *)p1, (typelib_TypeDescriptionReference *)p2 );
+}
+
+//------------------------------------------------------------------------
+extern "C" sal_Int32 SAL_CALL typelib_typedescription_getAlignedUnoSize(
+ const typelib_TypeDescription * pTypeDescription,
+ sal_Int32 nOffset, sal_Int32 & rMaxIntegralTypeSize )
+ SAL_THROW_EXTERN_C()
+{
+ sal_Int32 nSize;
+ if( pTypeDescription->nSize )
+ {
+ // size and alignment are set
+ rMaxIntegralTypeSize = pTypeDescription->nAlignment;
+ nSize = pTypeDescription->nSize;
+ }
+ else
+ {
+ nSize = 0;
+ rMaxIntegralTypeSize = 1;
+
+ OSL_ASSERT( typelib_TypeClass_TYPEDEF != pTypeDescription->eTypeClass );
+
+ switch( pTypeDescription->eTypeClass )
+ {
+ case typelib_TypeClass_INTERFACE:
+ // FEATURE_INTERFACE
+ nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( void * ));
+ break;
+ case typelib_TypeClass_UNION:
+ {
+ nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof(sal_Int64));
+ for ( sal_Int32 nPos = ((typelib_UnionTypeDescription *)pTypeDescription)->nMembers; nPos--; )
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, ((typelib_UnionTypeDescription *)pTypeDescription)->ppTypeRefs[nPos] );
+ sal_Int32 nMaxIntegralTypeSize;
+ sal_Int32 nMemberSize = typelib_typedescription_getAlignedUnoSize( pTD, (sal_Int32)(sizeof(sal_Int64)), nMaxIntegralTypeSize );
+ TYPELIB_DANGER_RELEASE( pTD );
+ if (nSize < nMemberSize)
+ nSize = nMemberSize;
+ if (rMaxIntegralTypeSize < nMaxIntegralTypeSize)
+ rMaxIntegralTypeSize = nMaxIntegralTypeSize;
+ }
+ ((typelib_UnionTypeDescription *)pTypeDescription)->nValueOffset = rMaxIntegralTypeSize;
+ }
+ break;
+ case typelib_TypeClass_ENUM:
+ nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( typelib_TypeClass ));
+ break;
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ // FEATURE_EMPTYCLASS
+ {
+ typelib_CompoundTypeDescription * pTmp = (typelib_CompoundTypeDescription *)pTypeDescription;
+ sal_Int32 nStructSize = 0;
+ if( pTmp->pBaseTypeDescription )
+ {
+ // inherit structs extends the base struct.
+ nStructSize = pTmp->pBaseTypeDescription->aBase.nSize;
+ rMaxIntegralTypeSize = pTmp->pBaseTypeDescription->aBase.nAlignment;
+ }
+ for( sal_Int32 i = 0; i < pTmp->nMembers; i++ )
+ {
+ typelib_TypeDescription * pMemberType = 0;
+ typelib_TypeDescriptionReference * pMemberRef = pTmp->ppTypeRefs[i];
+
+ sal_Int32 nMaxIntegral;
+ if (pMemberRef->eTypeClass == typelib_TypeClass_INTERFACE
+ || pMemberRef->eTypeClass == typelib_TypeClass_SEQUENCE)
+ {
+ nMaxIntegral = (sal_Int32)(sizeof(void *));
+ nStructSize = newAlignedSize( nStructSize, nMaxIntegral, nMaxIntegral );
+ }
+ else
+ {
+ TYPELIB_DANGER_GET( &pMemberType, pMemberRef );
+ nStructSize = typelib_typedescription_getAlignedUnoSize(
+ pMemberType, nStructSize, nMaxIntegral );
+ TYPELIB_DANGER_RELEASE( pMemberType );
+ }
+ if( nMaxIntegral > rMaxIntegralTypeSize )
+ rMaxIntegralTypeSize = nMaxIntegral;
+ }
+#ifdef __m68k__
+ // Anything that is at least 16 bits wide is aligned on a 16-bit
+ // boundary on the m68k default abi
+ sal_Int32 nMaxAlign = (rMaxIntegralTypeSize > 2) ? 2 : rMaxIntegralTypeSize;
+ nStructSize = (nStructSize + nMaxAlign -1) / nMaxAlign * nMaxAlign;
+#else
+ // Example: A { double; int; } structure has a size of 16 instead of 10. The
+ // compiler must follow this rule if it is possible to access members in arrays through:
+ // (Element *)((char *)pArray + sizeof( Element ) * ElementPos)
+ nStructSize = (nStructSize + rMaxIntegralTypeSize -1)
+ / rMaxIntegralTypeSize * rMaxIntegralTypeSize;
+#endif
+ nSize += nStructSize;
+ }
+ break;
+ case typelib_TypeClass_ARRAY:
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, ((typelib_IndirectTypeDescription *)pTypeDescription)->pType );
+ rMaxIntegralTypeSize = pTD->nSize;
+ TYPELIB_DANGER_RELEASE( pTD );
+ nSize = ((typelib_ArrayTypeDescription *)pTypeDescription)->nTotalElements * rMaxIntegralTypeSize;
+ }
+ break;
+ case typelib_TypeClass_SEQUENCE:
+ nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( void * ));
+ break;
+ case typelib_TypeClass_ANY:
+ // FEATURE_ANY
+ nSize = (sal_Int32)(sizeof( uno_Any ));
+ rMaxIntegralTypeSize = (sal_Int32)(sizeof( void * ));
+ break;
+ case typelib_TypeClass_TYPE:
+ nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( typelib_TypeDescriptionReference * ));
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Bool ));
+ break;
+ case typelib_TypeClass_CHAR:
+ nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Unicode ));
+ break;
+ case typelib_TypeClass_STRING:
+ // FEATURE_STRING
+ nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( rtl_uString * ));
+ break;
+ case typelib_TypeClass_FLOAT:
+ nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( float ));
+ break;
+ case typelib_TypeClass_DOUBLE:
+ nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( double ));
+ break;
+ case typelib_TypeClass_BYTE:
+ nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Int8 ));
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Int16 ));
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Int32 ));
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Int64 ));
+ break;
+ case typelib_TypeClass_UNKNOWN:
+ case typelib_TypeClass_SERVICE:
+ case typelib_TypeClass_MODULE:
+ default:
+ OSL_ENSURE( sal_False, "not convertable type" );
+ };
+ }
+
+ return newAlignedSize( nOffset, nSize, rMaxIntegralTypeSize );
+}
+
+//------------------------------------------------------------------------
+
+namespace {
+
+typelib_TypeDescriptionReference ** copyExceptions(
+ sal_Int32 count, typelib_TypeDescriptionReference ** source)
+{
+ typelib_TypeDescriptionReference ** p
+ = new typelib_TypeDescriptionReference *[count];
+ for (sal_Int32 i = 0; i < count; ++i) {
+ typelib_typedescriptionreference_acquire(p[i] = source[i]);
+ }
+ return p;
+}
+
+bool createDerivedInterfaceMemberDescription(
+ typelib_TypeDescription ** result, rtl::OUString const & name,
+ typelib_TypeDescriptionReference * baseRef,
+ typelib_TypeDescription const * base, typelib_TypeDescription * interface,
+ sal_Int32 index, sal_Int32 position)
+{
+ if (baseRef != 0 && base != 0 && interface != 0) {
+ switch (base->eTypeClass) {
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ typelib_typedescription_newEmpty(
+ result, typelib_TypeClass_INTERFACE_METHOD, name.pData);
+ typelib_InterfaceMethodTypeDescription const * baseMethod
+ = reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription const * >(base);
+ typelib_InterfaceMethodTypeDescription * newMethod
+ = reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription * >(*result);
+ newMethod->aBase.nPosition = position;
+ rtl_uString_acquire(
+ newMethod->aBase.pMemberName
+ = baseMethod->aBase.pMemberName);
+ typelib_typedescriptionreference_acquire(
+ newMethod->pReturnTypeRef = baseMethod->pReturnTypeRef);
+ newMethod->nParams = baseMethod->nParams;
+ newMethod->pParams = new typelib_MethodParameter[
+ newMethod->nParams];
+ for (sal_Int32 i = 0; i < newMethod->nParams; ++i) {
+ rtl_uString_acquire(
+ newMethod->pParams[i].pName
+ = baseMethod->pParams[i].pName);
+ typelib_typedescriptionreference_acquire(
+ newMethod->pParams[i].pTypeRef
+ = baseMethod->pParams[i].pTypeRef);
+ newMethod->pParams[i].bIn = baseMethod->pParams[i].bIn;
+ newMethod->pParams[i].bOut = baseMethod->pParams[i].bOut;
+ }
+ newMethod->nExceptions = baseMethod->nExceptions;
+ newMethod->ppExceptions = copyExceptions(
+ baseMethod->nExceptions, baseMethod->ppExceptions);
+ newMethod->bOneWay = baseMethod->bOneWay;
+ newMethod->pInterface
+ = reinterpret_cast< typelib_InterfaceTypeDescription * >(
+ interface);
+ newMethod->pBaseRef = baseRef;
+ newMethod->nIndex = index;
+ return true;
+ }
+
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ typelib_typedescription_newEmpty(
+ result, typelib_TypeClass_INTERFACE_ATTRIBUTE, name.pData);
+ typelib_InterfaceAttributeTypeDescription const * baseAttribute
+ = reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription const * >(base);
+ typelib_InterfaceAttributeTypeDescription * newAttribute
+ = reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(*result);
+ newAttribute->aBase.nPosition = position;
+ rtl_uString_acquire(
+ newAttribute->aBase.pMemberName
+ = baseAttribute->aBase.pMemberName);
+ newAttribute->bReadOnly = baseAttribute->bReadOnly;
+ typelib_typedescriptionreference_acquire(
+ newAttribute->pAttributeTypeRef
+ = baseAttribute->pAttributeTypeRef);
+ newAttribute->pInterface
+ = reinterpret_cast< typelib_InterfaceTypeDescription * >(
+ interface);
+ newAttribute->pBaseRef = baseRef;
+ newAttribute->nIndex = index;
+ newAttribute->nGetExceptions = baseAttribute->nGetExceptions;
+ newAttribute->ppGetExceptions = copyExceptions(
+ baseAttribute->nGetExceptions,
+ baseAttribute->ppGetExceptions);
+ newAttribute->nSetExceptions = baseAttribute->nSetExceptions;
+ newAttribute->ppSetExceptions = copyExceptions(
+ baseAttribute->nSetExceptions,
+ baseAttribute->ppSetExceptions);
+ return true;
+ }
+
+ default:
+ break;
+ }
+ }
+ return false;
+}
+
+}
+
+extern "C" void SAL_CALL typelib_typedescription_getByName(
+ typelib_TypeDescription ** ppRet, rtl_uString * pName )
+ SAL_THROW_EXTERN_C()
+{
+ if( *ppRet )
+ {
+ typelib_typedescription_release( (*ppRet) );
+ *ppRet = 0;
+ }
+
+ static sal_Bool bInited = sal_False;
+ TypeDescriptor_Init_Impl &rInit = Init::get();
+
+ if( !bInited )
+ {
+ // guard against multi thread access
+ MutexGuard aGuard( rInit.getMutex() );
+ if( !bInited )
+ {
+ // avoid recursion during the next ...new calls
+ bInited = sal_True;
+
+ rtl_uString * pTypeName = 0;
+ typelib_TypeDescription * pType = 0;
+ rtl_uString_newFromAscii( &pTypeName, "type" );
+ typelib_typedescription_new( &pType, typelib_TypeClass_TYPE, pTypeName, 0, 0, 0 );
+ typelib_typedescription_register( &pType );
+ rtl_uString_newFromAscii( &pTypeName, "void" );
+ typelib_typedescription_new( &pType, typelib_TypeClass_VOID, pTypeName, 0, 0, 0 );
+ typelib_typedescription_register( &pType );
+ rtl_uString_newFromAscii( &pTypeName, "boolean" );
+ typelib_typedescription_new( &pType, typelib_TypeClass_BOOLEAN, pTypeName, 0, 0, 0 );
+ typelib_typedescription_register( &pType );
+ rtl_uString_newFromAscii( &pTypeName, "char" );
+ typelib_typedescription_new( &pType, typelib_TypeClass_CHAR, pTypeName, 0, 0, 0 );
+ typelib_typedescription_register( &pType );
+ rtl_uString_newFromAscii( &pTypeName, "byte" );
+ typelib_typedescription_new( &pType, typelib_TypeClass_BYTE, pTypeName, 0, 0, 0 );
+ typelib_typedescription_register( &pType );
+ rtl_uString_newFromAscii( &pTypeName, "string" );
+ typelib_typedescription_new( &pType, typelib_TypeClass_STRING, pTypeName, 0, 0, 0 );
+ typelib_typedescription_register( &pType );
+ rtl_uString_newFromAscii( &pTypeName, "short" );
+ typelib_typedescription_new( &pType, typelib_TypeClass_SHORT, pTypeName, 0, 0, 0 );
+ typelib_typedescription_register( &pType );
+ rtl_uString_newFromAscii( &pTypeName, "unsigned short" );
+ typelib_typedescription_new( &pType, typelib_TypeClass_UNSIGNED_SHORT, pTypeName, 0, 0, 0 );
+ typelib_typedescription_register( &pType );
+ rtl_uString_newFromAscii( &pTypeName, "long" );
+ typelib_typedescription_new( &pType, typelib_TypeClass_LONG, pTypeName, 0, 0, 0 );
+ typelib_typedescription_register( &pType );
+ rtl_uString_newFromAscii( &pTypeName, "unsigned long" );
+ typelib_typedescription_new( &pType, typelib_TypeClass_UNSIGNED_LONG, pTypeName, 0, 0, 0 );
+ typelib_typedescription_register( &pType );
+ rtl_uString_newFromAscii( &pTypeName, "hyper" );
+ typelib_typedescription_new( &pType, typelib_TypeClass_HYPER, pTypeName, 0, 0, 0 );
+ typelib_typedescription_register( &pType );
+ rtl_uString_newFromAscii( &pTypeName, "unsigned hyper" );
+ typelib_typedescription_new( &pType, typelib_TypeClass_UNSIGNED_HYPER, pTypeName, 0, 0, 0 );
+ typelib_typedescription_register( &pType );
+ rtl_uString_newFromAscii( &pTypeName, "float" );
+ typelib_typedescription_new( &pType, typelib_TypeClass_FLOAT, pTypeName, 0, 0, 0 );
+ typelib_typedescription_register( &pType );
+ rtl_uString_newFromAscii( &pTypeName, "double" );
+ typelib_typedescription_new( &pType, typelib_TypeClass_DOUBLE, pTypeName, 0, 0, 0 );
+ typelib_typedescription_register( &pType );
+ rtl_uString_newFromAscii( &pTypeName, "any" );
+ typelib_typedescription_new( &pType, typelib_TypeClass_ANY, pTypeName, 0, 0, 0 );
+ typelib_typedescription_register( &pType );
+ typelib_typedescription_release( pType );
+ rtl_uString_release( pTypeName );
+ }
+ }
+
+ typelib_TypeDescriptionReference * pTDR = 0;
+ typelib_typedescriptionreference_getByName( &pTDR, pName );
+ if( pTDR )
+ {
+ {
+ // guard against multi thread access
+ MutexGuard aGuard( rInit.getMutex() );
+ // pTDR->pType->pWeakRef == 0 means that the description is empty
+ if( pTDR->pType && pTDR->pType->pWeakRef )
+ {
+ typelib_typedescription_acquire( pTDR->pType );
+ *ppRet = pTDR->pType;
+ }
+ }
+ typelib_typedescriptionreference_release( pTDR );
+ }
+
+ if (0 == *ppRet)
+ {
+ // check for sequence
+ OUString const & name = *reinterpret_cast< OUString const * >( &pName );
+ if (2 < name.getLength() && '[' == name[ 0 ])
+ {
+ OUString element_name( name.copy( 2 ) );
+ typelib_TypeDescription * element_td = 0;
+ typelib_typedescription_getByName( &element_td, element_name.pData );
+ if (0 != element_td)
+ {
+ typelib_typedescription_new(
+ ppRet, typelib_TypeClass_SEQUENCE, pName, element_td->pWeakRef, 0, 0 );
+ // register?
+ typelib_typedescription_release( element_td );
+ }
+ }
+ if (0 == *ppRet)
+ {
+ // Check for derived interface member type:
+ sal_Int32 i1 = name.lastIndexOf(
+ rtl::OUString::createFromAscii(":@"));
+ if (i1 >= 0) {
+ sal_Int32 i2 = i1 + RTL_CONSTASCII_LENGTH(":@");
+ sal_Int32 i3 = name.indexOf(',', i2);
+ if (i3 >= 0) {
+ sal_Int32 i4 = name.indexOf(':', i3);
+ if (i4 >= 0) {
+ typelib_TypeDescriptionReference * pBaseRef = 0;
+ typelib_TypeDescription * pBase = 0;
+ typelib_TypeDescription * pInterface = 0;
+ typelib_typedescriptionreference_getByName(
+ &pBaseRef, name.copy(0, i1).pData);
+ if (pBaseRef != 0) {
+ typelib_typedescriptionreference_getDescription(
+ &pBase, pBaseRef);
+ }
+ typelib_typedescription_getByName(
+ &pInterface, name.copy(i4 + 1).pData);
+ if (!createDerivedInterfaceMemberDescription(
+ ppRet, name, pBaseRef, pBase, pInterface,
+ name.copy(i2, i3 - i2).toInt32(),
+ name.copy(i3 + 1, i4 - i3 - 1).toInt32()))
+ {
+ if (pInterface != 0) {
+ typelib_typedescription_release(pInterface);
+ }
+ if (pBase != 0) {
+ typelib_typedescription_release(pBase);
+ }
+ if (pBaseRef != 0) {
+ typelib_typedescriptionreference_release(
+ pBaseRef);
+ }
+ }
+ }
+ }
+ }
+ }
+ if (0 == *ppRet)
+ {
+ // on demand access
+ rInit.callChain( ppRet, pName );
+ }
+
+ if( *ppRet )
+ {
+ // typedescription found
+ if (typelib_TypeClass_TYPEDEF == (*ppRet)->eTypeClass)
+ {
+ typelib_TypeDescription * pTD = 0;
+ typelib_typedescriptionreference_getDescription(
+ &pTD, ((typelib_IndirectTypeDescription *)*ppRet)->pType );
+ typelib_typedescription_release( *ppRet );
+ *ppRet = pTD;
+ }
+ else
+ {
+ // set to on demand
+ (*ppRet)->bOnDemand = sal_True;
+ // The type description is hold by the reference until
+ // on demand is activated.
+ typelib_typedescription_register( ppRet );
+
+ // insert into the chache
+ MutexGuard aGuard( rInit.getMutex() );
+ if( !rInit.pCache )
+ rInit.pCache = new TypeDescriptionList_Impl;
+ if( (sal_Int32)rInit.pCache->size() >= nCacheSize )
+ {
+ typelib_typedescription_release( rInit.pCache->front() );
+ rInit.pCache->pop_front();
+ }
+ // descriptions in the cache must be acquired!
+ typelib_typedescription_acquire( *ppRet );
+ rInit.pCache->push_back( *ppRet );
+ }
+ }
+ }
+}
+
+
+//------------------------------------------------------------------------
+//------------------------------------------------------------------------
+//------------------------------------------------------------------------
+extern "C" void SAL_CALL typelib_typedescriptionreference_newByAsciiName(
+ typelib_TypeDescriptionReference ** ppTDR,
+ typelib_TypeClass eTypeClass,
+ const sal_Char * pTypeName )
+ SAL_THROW_EXTERN_C()
+{
+ OUString aTypeName( OUString::createFromAscii( pTypeName ) );
+ typelib_typedescriptionreference_new( ppTDR, eTypeClass, aTypeName.pData );
+}
+//------------------------------------------------------------------------
+extern "C" void SAL_CALL typelib_typedescriptionreference_new(
+ typelib_TypeDescriptionReference ** ppTDR,
+ typelib_TypeClass eTypeClass, rtl_uString * pTypeName )
+ SAL_THROW_EXTERN_C()
+{
+ TypeDescriptor_Init_Impl &rInit = Init::get();
+ if( eTypeClass == typelib_TypeClass_TYPEDEF )
+ {
+ // on demand access
+ typelib_TypeDescription * pRet = 0;
+ rInit.callChain( &pRet, pTypeName );
+ if( pRet )
+ {
+ // typedescription found
+ if (typelib_TypeClass_TYPEDEF == pRet->eTypeClass)
+ {
+ typelib_typedescriptionreference_acquire(
+ ((typelib_IndirectTypeDescription *)pRet)->pType );
+ if (*ppTDR)
+ typelib_typedescriptionreference_release( *ppTDR );
+ *ppTDR = ((typelib_IndirectTypeDescription *)pRet)->pType;
+ typelib_typedescription_release( pRet );
+ }
+ else
+ {
+ // set to on demand
+ pRet->bOnDemand = sal_True;
+ // The type description is hold by the reference until
+ // on demand is activated.
+ typelib_typedescription_register( &pRet );
+
+ // insert into the chache
+ MutexGuard aGuard( rInit.getMutex() );
+ if( !rInit.pCache )
+ rInit.pCache = new TypeDescriptionList_Impl;
+ if( (sal_Int32)rInit.pCache->size() >= nCacheSize )
+ {
+ typelib_typedescription_release( rInit.pCache->front() );
+ rInit.pCache->pop_front();
+ }
+ rInit.pCache->push_back( pRet );
+ // pRet kept acquired for cache
+
+ typelib_typedescriptionreference_acquire( pRet->pWeakRef );
+ if (*ppTDR)
+ typelib_typedescriptionreference_release( *ppTDR );
+ *ppTDR = pRet->pWeakRef;
+ }
+ }
+ else if (*ppTDR)
+ {
+#if OSL_DEBUG_LEVEL > 1
+ OString aStr( OUStringToOString( pTypeName, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( !"### typedef not found: ", aStr.getStr() );
+#endif
+ typelib_typedescriptionreference_release( *ppTDR );
+ *ppTDR = 0;
+ }
+ return;
+ }
+
+ MutexGuard aGuard( rInit.getMutex() );
+ typelib_typedescriptionreference_getByName( ppTDR, pTypeName );
+ if( *ppTDR )
+ return;
+
+ if( reallyWeak( eTypeClass ) )
+ {
+ typelib_TypeDescriptionReference * pTDR = new typelib_TypeDescriptionReference();
+#if OSL_DEBUG_LEVEL > 1
+ osl_incrementInterlockedCount( &rInit.nTypeDescriptionReferenceCount );
+#endif
+ pTDR->nRefCount = 1;
+ pTDR->nStaticRefCount = 0;
+ pTDR->eTypeClass = eTypeClass;
+ pTDR->pUniqueIdentifier = 0;
+ pTDR->pReserved = 0;
+ rtl_uString_acquire( pTDR->pTypeName = pTypeName );
+ pTDR->pType = 0;
+ *ppTDR = pTDR;
+ }
+ else
+ {
+ typelib_typedescription_newEmpty( (typelib_TypeDescription ** )ppTDR, eTypeClass, pTypeName );
+ // description will be registered but not acquired
+ (*(typelib_TypeDescription ** )ppTDR)->bOnDemand = sal_True;
+ (*(typelib_TypeDescription ** )ppTDR)->bComplete = sal_False;
+ }
+
+ if( !rInit.pWeakMap )
+ rInit.pWeakMap = new WeakMap_Impl;
+ // Heavy hack, the const sal_Unicode * is hold by the typedescription reference
+ // not registered
+ rInit.pWeakMap->operator[]( (*ppTDR)->pTypeName->buffer ) = *ppTDR;
+}
+
+//------------------------------------------------------------------------
+extern "C" void SAL_CALL typelib_typedescriptionreference_acquire(
+ typelib_TypeDescriptionReference * pRef )
+ SAL_THROW_EXTERN_C()
+{
+ ::osl_incrementInterlockedCount( &pRef->nRefCount );
+}
+
+//------------------------------------------------------------------------
+extern "C" void SAL_CALL typelib_typedescriptionreference_release(
+ typelib_TypeDescriptionReference * pRef )
+ SAL_THROW_EXTERN_C()
+{
+ // Is it a type description?
+ if( reallyWeak( pRef->eTypeClass ) )
+ {
+ if( ! ::osl_decrementInterlockedCount( &pRef->nRefCount ) )
+ {
+ TypeDescriptor_Init_Impl &rInit = Init::get();
+ if( rInit.pWeakMap )
+ {
+ MutexGuard aGuard( rInit.getMutex() );
+ WeakMap_Impl::iterator aIt = rInit.pWeakMap->find( (sal_Unicode*)pRef->pTypeName->buffer );
+ if( !(aIt == rInit.pWeakMap->end()) && (*aIt).second == pRef )
+ {
+ // remove only if it contains the same object
+ rInit.pWeakMap->erase( aIt );
+ }
+ }
+
+ rtl_uString_release( pRef->pTypeName );
+ OSL_ASSERT( pRef->pType == 0 );
+#if OSL_DEBUG_LEVEL > 1
+ osl_decrementInterlockedCount( &rInit.nTypeDescriptionReferenceCount );
+#endif
+ delete pRef;
+ }
+ }
+ else
+ {
+ typelib_typedescription_release( (typelib_TypeDescription *)pRef );
+ }
+}
+
+//------------------------------------------------------------------------
+extern "C" void SAL_CALL typelib_typedescriptionreference_getDescription(
+ typelib_TypeDescription ** ppRet, typelib_TypeDescriptionReference * pRef )
+ SAL_THROW_EXTERN_C()
+{
+ if( *ppRet )
+ {
+ typelib_typedescription_release( *ppRet );
+ *ppRet = 0;
+ }
+
+ if( !reallyWeak( pRef->eTypeClass ) && pRef->pType && pRef->pType->pWeakRef )
+ {
+ // reference is a description and initialized
+ osl_incrementInterlockedCount( &((typelib_TypeDescription *)pRef)->nRefCount );
+ *ppRet = (typelib_TypeDescription *)pRef;
+ return;
+ }
+
+ {
+ MutexGuard aGuard( Init::get().getMutex() );
+ // pRef->pType->pWeakRef == 0 means that the description is empty
+ if( pRef->pType && pRef->pType->pWeakRef )
+ {
+ sal_Int32 n = ::osl_incrementInterlockedCount( &pRef->pType->nRefCount );
+ if( n > 1 )
+ {
+ // The refence is incremented. The object cannot be destroyed.
+ // Release the guard at the earliest point.
+ *ppRet = pRef->pType;
+ return;
+ }
+ else
+ {
+ ::osl_decrementInterlockedCount( &pRef->pType->nRefCount );
+ // detruction of this type in progress (another thread!)
+ // no acces through this weak reference
+ pRef->pType = 0;
+ }
+ }
+ }
+
+ typelib_typedescription_getByName( ppRet, pRef->pTypeName );
+ OSL_ASSERT( !*ppRet || rtl_ustr_compare( pRef->pTypeName->buffer, (*ppRet)->pTypeName->buffer ) == 0 );
+ OSL_ASSERT( !*ppRet || pRef->eTypeClass == (*ppRet)->eTypeClass );
+ OSL_ASSERT( !*ppRet || pRef == (*ppRet)->pWeakRef );
+ pRef->pType = *ppRet;
+}
+
+//------------------------------------------------------------------------
+extern "C" void SAL_CALL typelib_typedescriptionreference_getByName(
+ typelib_TypeDescriptionReference ** ppRet, rtl_uString * pName )
+ SAL_THROW_EXTERN_C()
+{
+ if( *ppRet )
+ {
+ typelib_typedescriptionreference_release( *ppRet );
+ *ppRet = 0;
+ }
+ TypeDescriptor_Init_Impl &rInit = Init::get();
+ if( rInit.pWeakMap )
+ {
+ MutexGuard aGuard( rInit.getMutex() );
+ WeakMap_Impl::const_iterator aIt = rInit.pWeakMap->find( (sal_Unicode*)pName->buffer );
+ if( !(aIt == rInit.pWeakMap->end()) ) // != failed on msc4.2
+ {
+ sal_Int32 n = ::osl_incrementInterlockedCount( &(*aIt).second->nRefCount );
+ if( n > 1 )
+ {
+ // The refence is incremented. The object cannot be destroyed.
+ // Release the guard at the earliest point.
+ *ppRet = (*aIt).second;
+ }
+ else
+ {
+ // detruction of this type in progress (another thread!)
+ // no acces through this weak reference
+ ::osl_decrementInterlockedCount( &(*aIt).second->nRefCount );
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+extern "C" sal_Bool SAL_CALL typelib_typedescriptionreference_equals(
+ const typelib_TypeDescriptionReference * p1,
+ const typelib_TypeDescriptionReference * p2 )
+ SAL_THROW_EXTERN_C()
+{
+ return (p1 == p2 ||
+ (p1->eTypeClass == p2->eTypeClass &&
+ p1->pTypeName->length == p2->pTypeName->length &&
+ rtl_ustr_compare( p1->pTypeName->buffer, p2->pTypeName->buffer ) == 0));
+}
+
+//##################################################################################################
+extern "C" void SAL_CALL typelib_typedescriptionreference_assign(
+ typelib_TypeDescriptionReference ** ppDest,
+ typelib_TypeDescriptionReference * pSource )
+ SAL_THROW_EXTERN_C()
+{
+ if (*ppDest != pSource)
+ {
+ ::typelib_typedescriptionreference_acquire( pSource );
+ ::typelib_typedescriptionreference_release( *ppDest );
+ *ppDest = pSource;
+ }
+}
+
+//##################################################################################################
+extern "C" void SAL_CALL typelib_setCacheSize( sal_Int32 nNewSize )
+ SAL_THROW_EXTERN_C()
+{
+ OSL_ENSURE( nNewSize >= 0, "### illegal cache size given!" );
+ if (nNewSize >= 0)
+ {
+ TypeDescriptor_Init_Impl &rInit = Init::get();
+ MutexGuard aGuard( rInit.getMutex() );
+ if ((nNewSize < nCacheSize) && rInit.pCache)
+ {
+ while ((sal_Int32)rInit.pCache->size() != nNewSize)
+ {
+ typelib_typedescription_release( rInit.pCache->front() );
+ rInit.pCache->pop_front();
+ }
+ }
+ nCacheSize = nNewSize;
+ }
+}
+
+
+static sal_Bool s_aAssignableFromTab[11][11] =
+{
+ /* from CH,BO,BY,SH,US,LO,UL,HY,UH,FL,DO */
+/* TypeClass_CHAR */ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+/* TypeClass_BOOLEAN */ { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+/* TypeClass_BYTE */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
+/* TypeClass_SHORT */ { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0 },
+/* TypeClass_UNSIGNED_SHORT */ { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0 },
+/* TypeClass_LONG */ { 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
+/* TypeClass_UNSIGNED_LONG */ { 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
+/* TypeClass_HYPER */ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
+/* TypeClass_UNSIGNED_HYPER */ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
+/* TypeClass_FLOAT */ { 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0 },
+/* TypeClass_DOUBLE */ { 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1 }
+};
+
+//##################################################################################################
+extern "C" sal_Bool SAL_CALL typelib_typedescriptionreference_isAssignableFrom(
+ typelib_TypeDescriptionReference * pAssignable,
+ typelib_TypeDescriptionReference * pFrom )
+ SAL_THROW_EXTERN_C()
+{
+ if (pAssignable && pFrom)
+ {
+ typelib_TypeClass eAssignable = pAssignable->eTypeClass;
+ typelib_TypeClass eFrom = pFrom->eTypeClass;
+
+ if (eAssignable == typelib_TypeClass_ANY) // anything can be assigned to an any .)
+ return sal_True;
+ if (eAssignable == eFrom)
+ {
+ if (type_equals( pAssignable, pFrom )) // first shot
+ {
+ return sal_True;
+ }
+ else
+ {
+ switch (eAssignable)
+ {
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ typelib_TypeDescription * pFromDescr = 0;
+ TYPELIB_DANGER_GET( &pFromDescr, pFrom );
+ if (! ((typelib_CompoundTypeDescription *)pFromDescr)->pBaseTypeDescription)
+ {
+ TYPELIB_DANGER_RELEASE( pFromDescr );
+ return sal_False;
+ }
+ sal_Bool bRet = typelib_typedescriptionreference_isAssignableFrom(
+ pAssignable,
+ ((typelib_TypeDescription *)((typelib_CompoundTypeDescription *)pFromDescr)->pBaseTypeDescription)->pWeakRef );
+ TYPELIB_DANGER_RELEASE( pFromDescr );
+ return bRet;
+ }
+ case typelib_TypeClass_INTERFACE:
+ {
+ typelib_TypeDescription * pFromDescr = 0;
+ TYPELIB_DANGER_GET( &pFromDescr, pFrom );
+ typelib_InterfaceTypeDescription * pFromIfc
+ = reinterpret_cast<
+ typelib_InterfaceTypeDescription * >(pFromDescr);
+ bool bRet = false;
+ for (sal_Int32 i = 0; i < pFromIfc->nBaseTypes; ++i) {
+ if (typelib_typedescriptionreference_isAssignableFrom(
+ pAssignable,
+ pFromIfc->ppBaseTypes[i]->aBase.pWeakRef))
+ {
+ bRet = true;
+ break;
+ }
+ }
+ TYPELIB_DANGER_RELEASE( pFromDescr );
+ return bRet;
+ }
+ default:
+ {
+ return sal_False;
+ }
+ }
+ }
+ }
+ return (eAssignable >= typelib_TypeClass_CHAR && eAssignable <= typelib_TypeClass_DOUBLE &&
+ eFrom >= typelib_TypeClass_CHAR && eFrom <= typelib_TypeClass_DOUBLE &&
+ s_aAssignableFromTab[eAssignable-1][eFrom-1]);
+ }
+ return sal_False;
+}
+//##################################################################################################
+extern "C" sal_Bool SAL_CALL typelib_typedescription_isAssignableFrom(
+ typelib_TypeDescription * pAssignable,
+ typelib_TypeDescription * pFrom )
+ SAL_THROW_EXTERN_C()
+{
+ return typelib_typedescriptionreference_isAssignableFrom(
+ pAssignable->pWeakRef, pFrom->pWeakRef );
+}
+
+//##################################################################################################
+extern "C" sal_Bool SAL_CALL typelib_typedescription_complete(
+ typelib_TypeDescription ** ppTypeDescr )
+ SAL_THROW_EXTERN_C()
+{
+ return complete(ppTypeDescr, true);
+}
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;
+ }
+}
+
+}