summaryrefslogtreecommitdiff
path: root/bridges/source/remote
diff options
context:
space:
mode:
Diffstat (limited to 'bridges/source/remote')
-rw-r--r--bridges/source/remote/context/context.cxx487
-rw-r--r--bridges/source/remote/context/exports.dxp5
-rw-r--r--bridges/source/remote/context/makefile.mk65
-rwxr-xr-xbridges/source/remote/context/rmcxt.map10
-rw-r--r--bridges/source/remote/idl/corba.idl88
-rw-r--r--bridges/source/remote/static/helper.cxx212
-rw-r--r--bridges/source/remote/static/makefile.mk61
-rw-r--r--bridges/source/remote/static/mapping.cxx221
-rw-r--r--bridges/source/remote/static/proxy.cxx341
-rw-r--r--bridges/source/remote/static/remote.cxx164
-rw-r--r--bridges/source/remote/static/remote_types.cxx99
-rw-r--r--bridges/source/remote/static/remote_types.hxx92
-rw-r--r--bridges/source/remote/static/stub.cxx339
-rw-r--r--bridges/source/remote/urp/makefile.mk78
-rw-r--r--bridges/source/remote/urp/urp_bridgeimpl.cxx253
-rw-r--r--bridges/source/remote/urp/urp_bridgeimpl.hxx130
-rw-r--r--bridges/source/remote/urp/urp_cache.h60
-rw-r--r--bridges/source/remote/urp/urp_cache.hxx163
-rw-r--r--bridges/source/remote/urp/urp_dispatch.cxx118
-rw-r--r--bridges/source/remote/urp/urp_dispatch.hxx80
-rw-r--r--bridges/source/remote/urp/urp_environment.cxx554
-rw-r--r--bridges/source/remote/urp/urp_job.cxx941
-rw-r--r--bridges/source/remote/urp/urp_job.hxx381
-rw-r--r--bridges/source/remote/urp/urp_log.cxx150
-rw-r--r--bridges/source/remote/urp/urp_log.hxx53
-rw-r--r--bridges/source/remote/urp/urp_marshal.cxx238
-rw-r--r--bridges/source/remote/urp/urp_marshal.hxx345
-rw-r--r--bridges/source/remote/urp/urp_marshal_decl.hxx109
-rw-r--r--bridges/source/remote/urp/urp_property.hxx94
-rw-r--r--bridges/source/remote/urp/urp_propertyobject.cxx796
-rw-r--r--bridges/source/remote/urp/urp_propertyobject.hxx107
-rw-r--r--bridges/source/remote/urp/urp_reader.cxx835
-rw-r--r--bridges/source/remote/urp/urp_reader.hxx81
-rw-r--r--bridges/source/remote/urp/urp_replycontainer.hxx78
-rw-r--r--bridges/source/remote/urp/urp_threadid.cxx51
-rw-r--r--bridges/source/remote/urp/urp_threadid.hxx62
-rw-r--r--bridges/source/remote/urp/urp_unmarshal.cxx709
-rw-r--r--bridges/source/remote/urp/urp_unmarshal.hxx281
-rw-r--r--bridges/source/remote/urp/urp_writer.cxx271
-rw-r--r--bridges/source/remote/urp/urp_writer.hxx85
40 files changed, 9287 insertions, 0 deletions
diff --git a/bridges/source/remote/context/context.cxx b/bridges/source/remote/context/context.cxx
new file mode 100644
index 000000000000..75991d45f546
--- /dev/null
+++ b/bridges/source/remote/context/context.cxx
@@ -0,0 +1,487 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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_bridges.hxx"
+#include <stdio.h>
+#include <string.h>
+#include <list>
+#include <hash_map>
+#include <utility>
+
+#include <osl/diagnose.h>
+#include <osl/interlck.h>
+#include <osl/mutex.hxx>
+
+#include "rtl/ustring.hxx"
+#include "rtl/instance.hxx"
+
+#include <bridges/remote/context.h>
+#include <bridges/remote/remote.h>
+#include <bridges/remote/connection.h>
+#include <bridges/remote/counter.hxx>
+
+using namespace ::std;
+using namespace ::osl;
+using namespace ::rtl;
+
+namespace {
+
+extern "C" typedef void * (SAL_CALL * MemAlloc)(sal_Size);
+
+}
+
+namespace remote_context
+{
+
+class remote_ContextImpl :
+ public remote_Context
+{
+public:
+ remote_ContextImpl( remote_Connection *pConnection,
+ rtl_uString *pIdStr,
+ rtl_uString *pDescription,
+ rtl_uString *pProtocol,
+ remote_InstanceProvider *pProvider );
+ ~remote_ContextImpl();
+
+ static void SAL_CALL thisAcquire( uno_Context * );
+ static void SAL_CALL thisRelease( uno_Context * );
+ static void * SAL_CALL thisQuery( uno_Context * , rtl_uString * );
+ static void SAL_CALL thisAddDisposingListener( remote_Context * , remote_DisposingListener * );
+ static void SAL_CALL thisRemoveDisposingListener( remote_Context *, remote_DisposingListener *);
+ static void SAL_CALL thisDispose( remote_Context *);
+public:
+ oslInterlockedCount m_nRef;
+ sal_Bool m_bDisposed;
+ list < remote_DisposingListener * > m_lstListener;
+ Mutex m_mutex;
+};
+
+
+
+
+struct equalOUString_Impl
+{
+ sal_Bool operator()(const OUString & s1, const OUString & s2) const
+ { return s1 == s2; }
+};
+
+struct hashOUString_Impl
+{
+ size_t operator()(const OUString & rName) const
+ { return rName.hashCode(); }
+};
+
+typedef hash_map
+<
+ OUString,
+ void *,
+ hashOUString_Impl,
+ equalOUString_Impl
+>
+ContextMap;
+
+#if OSL_DEBUG_LEVEL > 1
+static MyCounter thisCounter( "DEBUG : Context" );
+#endif
+
+class ContextAdmin
+{
+public:
+ // listener administration
+ void addContextListener( remote_contextListenerFunc listener , void *pObject );
+ void removeContextListener( remote_contextListenerFunc listener , void *pObject );
+
+ void fire( sal_Int32 nRemoteContextMode,
+ rtl_uString *sName,
+ rtl_uString *sDescription );
+
+ // context administration
+ uno_Context *createAndRegisterContext(
+ remote_Connection *pConnection,
+ rtl_uString *pIdStr,
+ rtl_uString *pDescription,
+ rtl_uString *pProtocol,
+ remote_InstanceProvider *pInstanceProvider );
+
+ void revokeContext( uno_Context *pRemoteContext );
+
+ uno_Context *getContext( rtl_uString *pHost );
+
+ rtl_uString ** getConnectionList(
+ sal_Int32 *pnStringCount, MemAlloc memAlloc );
+
+private:
+ ::osl::Mutex m_mutex;
+
+ ContextMap m_mapContext;
+
+ typedef std::list< std::pair< remote_contextListenerFunc, void * > > List;
+ List m_lstListener;
+};
+
+void ContextAdmin::addContextListener( remote_contextListenerFunc listener , void *pObject )
+{
+ ::osl::MutexGuard guard( m_mutex );
+
+ m_lstListener.push_back( std::make_pair( listener, pObject ) );
+}
+
+void ContextAdmin::removeContextListener( remote_contextListenerFunc listener , void *pObject )
+{
+ ::osl::MutexGuard guard( m_mutex );
+
+ for (List::iterator ii(m_lstListener.begin()); ii != m_lstListener.end();
+ ++ii)
+ {
+ if (ii->first == listener && ii->second == pObject) {
+ m_lstListener.erase( ii );
+ break;
+ }
+ }
+}
+
+void ContextAdmin::fire(
+ sal_Int32 nRemoteContextMode,
+ rtl_uString *pName,
+ rtl_uString *sDescription )
+{
+ List lst;
+ {
+ ::osl::MutexGuard guard( m_mutex );
+ lst = m_lstListener;
+ }
+ for (List::iterator i(lst.begin()); i != lst.end(); ++i) {
+ (i->first)(i->second, nRemoteContextMode, pName, sDescription);
+ }
+}
+
+uno_Context *ContextAdmin::createAndRegisterContext( remote_Connection *pConnection,
+ rtl_uString *pIdStr,
+ rtl_uString *pDescription,
+ rtl_uString *pProtocol,
+ remote_InstanceProvider *pInstanceProvider )
+{
+ ::osl::MutexGuard guard( m_mutex );
+
+ uno_Context *pContext = getContext( pIdStr );
+ if( pContext )
+ {
+ pContext->release( pContext );
+ return 0;
+ }
+
+ remote_ContextImpl *p = new remote_ContextImpl( pConnection,
+ pIdStr,
+ pDescription,
+ pProtocol,
+ pInstanceProvider );
+
+ p->aBase.acquire( (uno_Context*) p );
+
+ m_mapContext[ OUString( pIdStr) ] = (void*) p;
+
+ fire( REMOTE_CONTEXT_CREATE , pIdStr , pDescription );
+ return ( uno_Context * )p;
+}
+
+
+void ContextAdmin::revokeContext( uno_Context *pRemoteContext )
+{
+ ::osl::MutexGuard guard( m_mutex );
+
+ remote_ContextImpl *p = ( remote_ContextImpl * ) pRemoteContext;
+
+ ContextMap::iterator ii = m_mapContext.find( p->m_pName );
+ OSL_ASSERT( ii != m_mapContext.end() );
+ m_mapContext.erase( ii );
+
+ fire( REMOTE_CONTEXT_DESTROY , p->m_pName , p->m_pDescription );
+
+}
+
+uno_Context *ContextAdmin::getContext( rtl_uString *pHost )
+{
+ ::osl::MutexGuard guard( m_mutex );
+
+ ContextMap::iterator ii = m_mapContext.find( OUString( (rtl_uString*)pHost ) );
+ if( ii == m_mapContext.end() )
+ {
+ return 0;
+ }
+
+ uno_Context *p = ( uno_Context * ) (*ii).second;
+ p->acquire( p );
+ return p;
+}
+
+
+rtl_uString ** ContextAdmin::getConnectionList(
+ sal_Int32 *pnStringCount, MemAlloc memAlloc )
+{
+ ::osl::MutexGuard guard( m_mutex );
+
+ *pnStringCount = m_mapContext.size();
+
+ if (*pnStringCount == 0)
+ return NULL;
+
+ rtl_uString **ppReturn = ( rtl_uString ** )
+ memAlloc( sizeof( rtl_uString * ) * m_mapContext.size() );
+ memset( ppReturn , 0 , sizeof( rtl_uString * ) * m_mapContext.size() );
+
+ sal_Int32 i = 0;
+ for( ContextMap::iterator ii = m_mapContext.begin() ;
+ ii != m_mapContext.end();
+ ++ii, i++ )
+ {
+ rtl_uString_assign( &( ppReturn[i] ), (*ii).first.pData );
+ }
+
+ return ppReturn;
+}
+
+
+struct theContextAdmin : public rtl::Static<ContextAdmin, theContextAdmin> {};
+
+/*****************************
+ * remote_ContextImpl implementation
+ ****************************/
+
+
+
+remote_ContextImpl::remote_ContextImpl( remote_Connection *pConnection ,
+ rtl_uString *pIdStr,
+ rtl_uString *pDescription,
+ rtl_uString *pProtocol,
+ remote_InstanceProvider *pProvider ) :
+ m_nRef( 0 ),
+ m_bDisposed( sal_False )
+{
+ m_pConnection = pConnection;
+ m_pConnection->acquire( m_pConnection );
+
+ m_pInstanceProvider = pProvider;
+ if( m_pInstanceProvider )
+ {
+ m_pInstanceProvider->acquire( pProvider );
+ }
+
+ m_pName = pIdStr;
+ rtl_uString_acquire( m_pName );
+
+ m_pDescription = pDescription;
+ rtl_uString_acquire( m_pDescription );
+
+ m_pProtocol = pProtocol;
+ rtl_uString_acquire( pProtocol );
+
+ aBase.acquire = thisAcquire;
+ aBase.release = thisRelease;
+ addDisposingListener = thisAddDisposingListener;
+ removeDisposingListener = thisRemoveDisposingListener;
+ dispose = thisDispose;
+#if OSL_DEBUG_LEVEL > 1
+ thisCounter.acquire();
+#endif
+}
+
+remote_ContextImpl::~remote_ContextImpl()
+{
+ // disposed must have been called
+ OSL_ASSERT( m_bDisposed );
+
+ rtl_uString_release( m_pName );
+ rtl_uString_release( m_pDescription );
+ rtl_uString_release( m_pProtocol );
+#if OSL_DEBUG_LEVEL > 1
+ thisCounter.release();
+#endif
+
+}
+
+
+void remote_ContextImpl::thisAddDisposingListener( remote_Context *pRemoteC ,
+ remote_DisposingListener *pListener )
+{
+ remote_ContextImpl *pImpl = (remote_ContextImpl * ) pRemoteC;
+
+ ::osl::MutexGuard guard( pImpl->m_mutex );
+
+ pListener->acquire( pListener );
+ pImpl->m_lstListener.push_back( pListener );
+}
+
+void remote_ContextImpl::thisRemoveDisposingListener( remote_Context *pRemoteC,
+ remote_DisposingListener *pListener)
+{
+ remote_ContextImpl *pImpl = (remote_ContextImpl * ) pRemoteC;
+ MutexGuard guard( pImpl->m_mutex );
+
+ for( list< remote_DisposingListener * >::iterator ii = pImpl->m_lstListener.begin() ;
+ ii != pImpl->m_lstListener.end();
+ ++ii )
+ {
+ if( (*ii) == pListener )
+ {
+ pImpl->m_lstListener.erase( ii );
+ pListener->release( pListener );
+ break;
+ }
+ }
+}
+
+void remote_ContextImpl::thisDispose( remote_Context *pRemoteC )
+{
+ remote_ContextImpl *pImpl = ( remote_ContextImpl * )pRemoteC;
+
+ MutexGuard guard( pImpl->m_mutex );
+ if( ! pImpl->m_bDisposed )
+ {
+ pImpl->m_bDisposed = sal_True;
+ theContextAdmin::get().revokeContext( (uno_Context * ) pRemoteC );
+
+ if( pImpl->m_pInstanceProvider )
+ {
+ pImpl->m_pInstanceProvider->release( pImpl->m_pInstanceProvider );
+ pImpl->m_pInstanceProvider = 0;
+ }
+
+ pImpl->m_pConnection->release( pImpl->m_pConnection );
+ pImpl->m_pConnection = 0;
+
+ list< remote_DisposingListener * > lst = pImpl->m_lstListener;
+ pImpl->m_lstListener.clear();
+
+ for( list < remote_DisposingListener * >::iterator ii = lst.begin();
+ ii != lst.end();
+ ++ii )
+ {
+ (*ii)->disposing( (*ii) , pImpl->m_pName );
+ (*ii)->release( (*ii) );
+ }
+
+ }
+}
+
+
+
+void remote_ContextImpl::thisAcquire( uno_Context *pRemoteC )
+{
+ remote_ContextImpl *p = SAL_REINTERPRET_CAST(remote_ContextImpl * ,pRemoteC );
+ osl_incrementInterlockedCount( &(p->m_nRef) );
+}
+
+void remote_ContextImpl::thisRelease( uno_Context *pRemoteC )
+{
+ remote_ContextImpl *p = SAL_REINTERPRET_CAST( remote_ContextImpl * , pRemoteC );
+ if (! osl_decrementInterlockedCount( &(p->m_nRef) ))
+ {
+ // enshure, that this piece of code is not reentered
+ osl_incrementInterlockedCount( &(p->m_nRef) );
+
+ // dispose, if necessary
+ p->dispose( p );
+
+ // restore the counter
+ osl_decrementInterlockedCount( &(p->m_nRef) );
+
+ if( 0 == p->m_nRef )
+ {
+ delete p;
+ }
+ else
+ {
+ // reanimated, but disposed !
+ }
+ }
+}
+
+void *remote_ContextImpl::thisQuery( uno_Context * , rtl_uString * )
+{
+ return 0;
+}
+
+
+} // end namespace remote_context
+
+
+using namespace remote_context;
+
+//-----------------------
+//
+// C-Interface
+//
+//-----------------------
+extern "C" remote_Context * SAL_CALL
+remote_getContext( rtl_uString *pIdString )
+{
+ return (remote_Context *) theContextAdmin::get().getContext(pIdString);
+}
+
+
+
+extern "C" remote_Context * SAL_CALL
+remote_createContext( remote_Connection *pConnection,
+ rtl_uString *pIdStr,
+ rtl_uString *pDescription,
+ rtl_uString *pProtocol,
+ remote_InstanceProvider *pProvider )
+{
+ remote_ContextImpl *p = (remote_ContextImpl * )
+ theContextAdmin::get().createAndRegisterContext(
+ pConnection ,
+ pIdStr ,
+ pDescription,
+ pProtocol,
+ pProvider );
+
+ return (remote_Context * )p;
+}
+
+
+extern "C" void SAL_CALL
+remote_addContextListener( remote_contextListenerFunc listener, void *pObject )
+{
+ theContextAdmin::get().addContextListener( listener , pObject );
+}
+
+extern "C" void SAL_CALL
+remote_removeContextListener( remote_contextListenerFunc listener , void *pObject )
+{
+ theContextAdmin::get().removeContextListener( listener , pObject );
+}
+
+extern "C" rtl_uString ** SAL_CALL
+remote_getContextList( sal_Int32 *pnStringCount, MemAlloc memAlloc )
+{
+ return theContextAdmin::get().getConnectionList( pnStringCount , memAlloc );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/context/exports.dxp b/bridges/source/remote/context/exports.dxp
new file mode 100644
index 000000000000..dcef3c369b10
--- /dev/null
+++ b/bridges/source/remote/context/exports.dxp
@@ -0,0 +1,5 @@
+remote_getContext
+remote_createContext
+remote_getContextList
+remote_removeContextListener
+remote_addContextListener \ No newline at end of file
diff --git a/bridges/source/remote/context/makefile.mk b/bridges/source/remote/context/makefile.mk
new file mode 100644
index 000000000000..cc2a52355d25
--- /dev/null
+++ b/bridges/source/remote/context/makefile.mk
@@ -0,0 +1,65 @@
+#*************************************************************************
+#
+# 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=bridges
+TARGET=rmcxt
+ENABLE_EXCEPTIONS=TRUE
+USE_DEFFILE=TRUE
+
+UNIXVERSIONNAMES=UDK
+
+# --- Settings -----------------------------------------------------
+.INCLUDE : settings.mk
+# ------------------------------------------------------------------
+
+UNOUCRDEP=$(SOLARUCRDIR)$/uce.rdb
+UNOUCRRDB=$(SOLARUCRDIR)$/uce.rdb
+
+SLOFILES= $(SLO)$/context.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1STDLIBS= \
+ $(SALLIB)
+
+SHL1DEPN=
+SHL1IMPLIB= i$(TARGET)
+SHL1LIBS= $(SLB)$/$(TARGET).lib
+SHL1DEF= $(MISC)$/$(SHL1TARGET).def
+SHL1RPATH=URELIB
+
+SHL1VERSIONMAP= $(TARGET).map
+
+DEF1NAME= $(SHL1TARGET)
+#DEF1EXPORTFILE= exports.dxp
+
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/bridges/source/remote/context/rmcxt.map b/bridges/source/remote/context/rmcxt.map
new file mode 100755
index 000000000000..182f6495ea9d
--- /dev/null
+++ b/bridges/source/remote/context/rmcxt.map
@@ -0,0 +1,10 @@
+UDK_3_0_0 {
+ global:
+ remote_getContext;
+ remote_createContext;
+ remote_getContextList;
+ remote_removeContextListener;
+ remote_addContextListener;
+ local:
+ *;
+};
diff --git a/bridges/source/remote/idl/corba.idl b/bridges/source/remote/idl/corba.idl
new file mode 100644
index 000000000000..63f93283d41e
--- /dev/null
+++ b/bridges/source/remote/idl/corba.idl
@@ -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.
+ *
+ ************************************************************************/
+module com
+{
+module sun
+{
+module star
+{
+
+module corba
+{
+
+ // CosBridging module
+ typedef unsigned long ObjectSystemID;
+ typedef sequence< byte > OpaqueData;
+
+ struct OneThreadID
+ {
+ ObjectSystemID objSysID;
+ OpaqueData threadID;
+ };
+
+ typedef sequence<OneThreadID> ThreadIDs;
+
+ struct LogicalThreadID // Service context
+ {
+ ThreadIDs IDs;
+ };
+
+ struct CorbaString8
+ {
+ string theString;
+ };
+
+ struct CorbaUnion
+ {
+ long dummy;
+ };
+
+ struct ObjectKey
+ {
+ CorbaString8 sOid;
+ CorbaString8 sType;
+ };
+
+ enum TCKind
+ {
+ tk_null, tk_void,
+ tk_short, tk_long, tk_ushort, tk_ulong,
+ tk_float, tk_double, tk_boolean, tk_char,
+ tk_octet, tk_any, tk_TypeCode, tk_Principal, tk_objref,
+ tk_struct, tk_union, tk_enum, tk_string,
+ tk_sequence, tk_array, tk_alias, tk_except,
+ tk_longlong, tk_ulonglong, tk_longdouble,
+ tk_wchar, tk_wstring, tk_fixed,
+ tk_value, tk_value_box,
+ tk_native,
+ tk_abstract_interface
+ };
+};
+
+};
+};
+};
diff --git a/bridges/source/remote/static/helper.cxx b/bridges/source/remote/static/helper.cxx
new file mode 100644
index 000000000000..d120d38b80df
--- /dev/null
+++ b/bridges/source/remote/static/helper.cxx
@@ -0,0 +1,212 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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_bridges.hxx"
+#include <rtl/alloc.h>
+#include <osl/diagnose.h>
+
+#include <bridges/remote/helper.hxx>
+
+#include <bridges/remote/stub.hxx>
+#include <bridges/remote/proxy.hxx>
+#include <bridges/remote/remote.hxx>
+
+#include <com/sun/star/uno/Sequence.hxx>
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+namespace bridges_remote
+{
+
+void SAL_CALL remote_createStub (
+ remote_Interface **ppRemoteI,
+ rtl_uString *pOid ,
+ typelib_TypeDescriptionReference *pTypeRef,
+ uno_Environment *pEnvRemote,
+ ReleaseRemoteCallbackFunc releaseRemoteCallback )
+{
+ typelib_TypeDescription *pType = 0;
+ typelib_typedescriptionreference_getDescription( &pType, pTypeRef );
+
+ (void) pEnvRemote->pExtEnv->getRegisteredInterface(
+ pEnvRemote->pExtEnv,
+ (void **)ppRemoteI,
+ pOid,
+ (typelib_InterfaceTypeDescription* )pType );
+
+ if( *ppRemoteI )
+ {
+ if( (*ppRemoteI)->acquire == acquireRemote2RemoteStub ) {
+
+ if( releaseRemoteCallback )
+ {
+ // use the callback handler, the bridge wants to send the call immeadiatly
+ releaseRemoteCallback( *ppRemoteI , pOid, pTypeRef , pEnvRemote );
+ }
+ else
+ {
+ ((::bridges_remote::Remote2RemoteStub *)*ppRemoteI)->releaseRemote();
+ }
+ }
+ else
+ {
+ // Uno2RemoteStub
+ // no release necessary
+ }
+ }
+ else
+ {
+ remote_BridgeImpl *pImpl = ((remote_Context *)pEnvRemote->pContext)->m_pBridgeImpl;
+ *ppRemoteI =
+ new ::bridges_remote::Remote2RemoteStub(
+ pOid,
+ (typelib_InterfaceTypeDescription * ) pType,
+ pEnvRemote,
+ pImpl->m_sendRequest);
+
+ // ppRemoteI may change during registration
+ pEnvRemote->pExtEnv->registerProxyInterface(
+ pEnvRemote->pExtEnv,
+ (void **) ppRemoteI,
+ freeRemote2RemoteStub,
+ pOid,
+ (typelib_InterfaceTypeDescription * ) pType );
+ }
+
+ typelib_typedescription_release( pType );
+}
+
+void SAL_CALL remote_sendQueryInterface(
+ uno_Environment *pEnvRemote,
+ remote_Interface **ppRemoteI,
+ rtl_uString *pOid ,
+ typelib_TypeDescriptionReference *pTypeRef,
+ uno_Any **ppException
+ )
+{
+ OSL_ASSERT( ppRemoteI );
+
+ typelib_InterfaceTypeDescription *pType = 0;
+ typelib_typedescriptionreference_getDescription( (typelib_TypeDescription ** )&pType, pTypeRef );
+
+ if( *ppRemoteI )
+ {
+ (*ppRemoteI)->release( *ppRemoteI );
+ (*ppRemoteI) = 0;
+ }
+
+ remote_BridgeImpl *pImpl = ((remote_Context *)pEnvRemote->pContext)->m_pBridgeImpl;
+
+ Type type = ::getCppuType( (Reference < XInterface > *)0 );
+
+ // get type for queryInterface
+ OUString sCompleteMethodName = type.getTypeName();
+ sCompleteMethodName += OUString(RTL_CONSTASCII_USTRINGPARAM("::queryInterface"));
+
+ typelib_InterfaceMemberTypeDescription *pMemberType = 0;
+ typelib_typedescription_getByName(
+ (typelib_TypeDescription **) &pMemberType,
+ sCompleteMethodName.pData );
+
+ OSL_ASSERT( pMemberType );
+
+ uno_Any anyInterface;
+ anyInterface.pType = 0;
+ anyInterface.pData = 0;
+
+ void *pReturn = &anyInterface;
+ void *ppArgs[1];
+
+ ppArgs[0] = 0;
+ typelib_TypeDescriptionReference *pRef = 0;
+ typelib_typedescriptionreference_new( &pRef ,
+ pType->aBase.eTypeClass,
+ pType->aBase.pTypeName);
+
+ ppArgs[0] = &pRef;
+
+// uno_Any anyException;
+// uno_Any *pAnyException = &anyException;
+
+ // do the queryInterface
+ pImpl->m_sendRequest(
+ pEnvRemote,
+ (typelib_TypeDescription * ) pMemberType,
+ pOid,
+ pType,
+ pReturn,
+ ppArgs,
+ ppException );
+
+
+ // now release everything
+ typelib_typedescriptionreference_release( pRef );
+ typelib_typedescription_release( (typelib_TypeDescription * ) pMemberType );
+
+ if( *ppException )
+ {
+ *ppRemoteI = 0;
+ }
+ else
+ {
+ // set out parameter
+ if( typelib_TypeClass_INTERFACE == anyInterface.pType->eTypeClass )
+ {
+ *ppRemoteI = ( remote_Interface * ) anyInterface.pReserved;
+ }
+ typelib_typedescriptionreference_release( anyInterface.pType );
+ }
+
+ typelib_typedescription_release( (typelib_TypeDescription * ) pType );
+}
+
+
+void SAL_CALL remote_retrieveOidFromProxy(
+ remote_Interface *pRemoteI,
+ rtl_uString **ppOid )
+{
+ if( pRemoteI->acquire == acquireRemote2RemoteStub )
+ {
+ // Remote2RemoteStub
+ ::bridges_remote::Remote2RemoteStub *pStub = (::bridges_remote::Remote2RemoteStub * ) pRemoteI;
+ rtl_uString_newFromString( ppOid , pStub->m_sOid.pData );
+ }
+ else
+ {
+ // Uno2RemoteStub
+ ::bridges_remote::Uno2RemoteStub *pStub = (::bridges_remote::Uno2RemoteStub * ) pRemoteI;
+ rtl_uString_newFromString( ppOid , pStub->m_sOid.pData );
+ pRemoteI->acquire( pRemoteI );
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/static/makefile.mk b/bridges/source/remote/static/makefile.mk
new file mode 100644
index 000000000000..9b3c2b795f8d
--- /dev/null
+++ b/bridges/source/remote/static/makefile.mk
@@ -0,0 +1,61 @@
+#*************************************************************************
+#
+# 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=bridges
+TARGET=bridges_remote_static
+ENABLE_EXCEPTIONS=TRUE
+USE_DEFFILE=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# ------------------------------------------------------------------
+
+SLOFILES= \
+ $(SLO)$/proxy.obj \
+ $(SLO)$/stub.obj \
+ $(SLO)$/remote.obj \
+ $(SLO)$/mapping.obj \
+ $(SLO)$/helper.obj \
+ $(SLO)$/remote_types.obj
+
+# Forte6 update 1 on Solaris Intel dies with internal compiler error
+# on stub.cxx if optimization is on. Switch it off for now.
+# To be reevaluated on compiler upgrade
+.IF "$(OS)$(CPU)"=="SOLARISI"
+NOOPTFILES=\
+ $(SLO)$/stub.obj
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+
diff --git a/bridges/source/remote/static/mapping.cxx b/bridges/source/remote/static/mapping.cxx
new file mode 100644
index 000000000000..cd0201cbb87c
--- /dev/null
+++ b/bridges/source/remote/static/mapping.cxx
@@ -0,0 +1,221 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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_bridges.hxx"
+#include <osl/diagnose.h>
+
+#include <bridges/remote/proxy.hxx>
+#include <bridges/remote/stub.hxx>
+#include <bridges/remote/counter.hxx>
+#include <bridges/remote/mapping.hxx>
+
+using namespace bridges_remote;
+
+extern "C" {
+
+static void SAL_CALL thisAcquire( uno_Mapping *pMap )
+{
+ RemoteMapping *p = SAL_REINTERPRET_CAST( RemoteMapping * , pMap );
+ if( 1 == osl_incrementInterlockedCount( &(p->m_nRef) ) )
+ {
+ if( remoteToUno == pMap->mapInterface )
+ {
+ uno_registerMapping( &pMap ,
+ freeRemoteMapping,
+ p->pEnvRemote ,
+ p->pEnvUno ,
+ p->m_sPurpose.pData );
+ }
+ else
+ {
+ uno_registerMapping( &pMap ,
+ freeRemoteMapping,
+ p->pEnvUno ,
+ p->pEnvRemote ,
+ p->m_sPurpose.pData );
+ }
+
+ }
+}
+
+static void SAL_CALL thisRelease( uno_Mapping *pMap )
+{
+ RemoteMapping *p = SAL_REINTERPRET_CAST( RemoteMapping * , pMap );
+ if (! osl_decrementInterlockedCount( &(p->m_nRef) ))
+ {
+ uno_revokeMapping( pMap );
+ }
+}
+
+}
+
+namespace bridges_remote {
+
+void remoteToUno( uno_Mapping *pMapping, void **ppUnoI, void *pRemoteI,
+ typelib_InterfaceTypeDescription *pTypeDescr )
+{
+ remote_Mapping *pRemoteMapping = ( remote_Mapping * ) pMapping;
+
+ OSL_ASSERT( ppUnoI && pTypeDescr );
+ if (*ppUnoI)
+ {
+ ((uno_Interface *)*ppUnoI)->release( (uno_Interface *)*ppUnoI );
+ *ppUnoI = 0;
+ }
+
+ if (pRemoteI && pTypeDescr)
+ {
+ // get object id of interface to be wrapped
+ rtl_uString * pOid = 0;
+ pRemoteMapping->pEnvRemote->pExtEnv->getObjectIdentifier(
+ pRemoteMapping->pEnvRemote->pExtEnv,
+ &pOid,
+ pRemoteI );
+
+ OSL_ASSERT(pOid);
+ if( ! pOid )
+ {
+ return;
+ }
+
+ // try to get any known interface from target environment
+ pRemoteMapping->pEnvUno->pExtEnv->getRegisteredInterface(
+ pRemoteMapping->pEnvUno->pExtEnv,
+ ppUnoI,
+ pOid,
+ pTypeDescr);
+
+ if ( ! *ppUnoI) // already existing interface
+ {
+ // try to publish a new proxy; proxy may be exchanged during registration
+ *ppUnoI = new Remote2UnoProxy(
+ ( remote_Interface * ) pRemoteI,
+ pOid,
+ pTypeDescr ,
+ pRemoteMapping->pEnvUno,
+ pRemoteMapping->pEnvRemote);
+
+ pRemoteMapping->pEnvUno->pExtEnv->registerProxyInterface(
+ pRemoteMapping->pEnvUno->pExtEnv,
+ ppUnoI,
+ freeRemote2UnoProxy,
+ pOid,
+ pTypeDescr );
+
+ OSL_ASSERT( *ppUnoI );
+ }
+ rtl_uString_release( pOid );
+ }
+}
+
+void unoToRemote( uno_Mapping *pMapping, void **ppRemoteI, void *pUnoI,
+ typelib_InterfaceTypeDescription *pTypeDescr )
+{
+ remote_Mapping *pRemoteMapping = ( remote_Mapping * ) pMapping;
+ OSL_ASSERT( ppRemoteI && pTypeDescr );
+ if (*ppRemoteI)
+ {
+ ((remote_Interface *)*ppRemoteI)->release( (remote_Interface *)*ppRemoteI);
+ *ppRemoteI = 0;
+ }
+ if (pUnoI && pTypeDescr)
+ {
+ // get object id of interface to be wrapped
+ rtl_uString * pOid = 0;
+ pRemoteMapping->pEnvUno->pExtEnv->getObjectIdentifier(
+ pRemoteMapping->pEnvUno->pExtEnv,
+ &pOid,
+ pUnoI );
+
+ OSL_ASSERT( pOid );
+ if( ! pOid )
+ {
+ return;
+ }
+
+ pRemoteMapping->pEnvRemote->pExtEnv->getRegisteredInterface(
+ pRemoteMapping->pEnvRemote->pExtEnv,
+ (void**)ppRemoteI,
+ pOid,
+ pTypeDescr );
+
+ if( !*ppRemoteI )
+ {
+ // try to publish a new proxy;
+ *ppRemoteI = new Uno2RemoteStub(
+ ( uno_Interface * ) pUnoI,
+ pOid,
+ pTypeDescr,
+ pRemoteMapping->pEnvUno,
+ pRemoteMapping->pEnvRemote );
+
+ // note : ppRemoteI may change during registration
+ pRemoteMapping->pEnvRemote->pExtEnv->registerProxyInterface(
+ pRemoteMapping->pEnvRemote->pExtEnv,
+ (void**) ppRemoteI,
+ freeUno2RemoteStub,
+ pOid,
+ pTypeDescr );
+ }
+
+ rtl_uString_release( pOid );
+ }
+}
+
+void freeRemoteMapping(uno_Mapping * mapping) {
+ delete reinterpret_cast< RemoteMapping * >(mapping);
+}
+
+RemoteMapping::RemoteMapping( uno_Environment *pEnvUno_ ,
+ uno_Environment *pEnvRemote_,
+ uno_MapInterfaceFunc func,
+ const ::rtl::OUString sPurpose) :
+ m_nRef( 1 ),
+ m_sPurpose( sPurpose )
+{
+ pEnvUno = pEnvUno_;
+ pEnvRemote = pEnvRemote_;
+
+ pEnvUno->acquire( pEnvUno );
+ pEnvRemote->acquire( pEnvRemote );
+
+ aBase.mapInterface = func;
+ aBase.acquire = thisAcquire;
+ aBase.release = thisRelease;
+}
+
+RemoteMapping::~RemoteMapping( )
+{
+ pEnvUno->release( pEnvUno );
+ pEnvRemote->release( pEnvRemote );
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/static/proxy.cxx b/bridges/source/remote/static/proxy.cxx
new file mode 100644
index 000000000000..bf8428264ab6
--- /dev/null
+++ b/bridges/source/remote/static/proxy.cxx
@@ -0,0 +1,341 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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_bridges.hxx"
+#include <sal/alloca.h>
+#include <bridges/remote/proxy.hxx>
+#include <bridges/remote/context.h>
+
+#include <uno/data.h>
+#include <uno/mapping.hxx>
+#include <uno/environment.h>
+
+#include <com/sun/star/uno/Any.hxx>
+
+#include <bridges/remote/bridgeimpl.hxx>
+
+#include "remote_types.hxx"
+
+#if OSL_DEBUG_LEVEL > 1
+#include <bridges/remote/counter.hxx>
+static MyCounter thisCounter( "DEBUG : Remote2UnoProxy");
+#endif
+
+using namespace ::bridges_remote;
+using namespace ::com::sun::star::uno;
+
+extern "C" {
+
+void SAL_CALL remote_release( void *pRemoteI )
+{
+ ((remote_Interface * )pRemoteI)->release( (remote_Interface * ) pRemoteI );
+}
+
+}
+
+namespace bridges_remote {
+
+void freeRemote2UnoProxy(uno_ExtEnvironment *, void * proxy) {
+ delete static_cast< Remote2UnoProxy * >(proxy);
+}
+
+void acquireRemote2UnoProxy( uno_Interface *pThis )
+{
+ Remote2UnoProxy *p = ( Remote2UnoProxy * ) pThis;
+ if( 1 == osl_incrementInterlockedCount( &(p->m_nRef) ) )
+ {
+ p->m_pEnvUno->pExtEnv->registerProxyInterface(
+ p->m_pEnvUno->pExtEnv,
+ (void**)&pThis,
+ freeRemote2UnoProxy,
+ p->m_sOid.pData,
+ p->m_pType );
+ OSL_ASSERT( (uno_Interface *)p == pThis );
+ }
+}
+
+void releaseRemote2UnoProxy( uno_Interface *pThis )
+{
+ Remote2UnoProxy *p = ( Remote2UnoProxy * ) pThis;
+ if ( 0 == osl_decrementInterlockedCount( &(p->m_nRef) ))
+ {
+ p->m_pEnvUno->pExtEnv->revokeInterface( p->m_pEnvUno->pExtEnv, p );
+ }
+}
+
+void SAL_CALL dispatchRemote2UnoProxy(
+ uno_Interface * pUnoI,
+ typelib_TypeDescription const * pType,
+ void * pReturn,
+ void * ppArgs[],
+ uno_Any ** ppException )
+{
+ Remote2UnoProxy *p = ( Remote2UnoProxy * ) pUnoI;
+ RemoteThreadCounter counter( p->m_pEnvRemote );
+
+ typelib_InterfaceMethodTypeDescription *pMethodType = 0;
+ typelib_InterfaceAttributeTypeDescription *pAttributeType = 0;
+ typelib_TypeDescription *pReturnType = 0;
+ typelib_TypeDescription **ppArgType = 0;
+ sal_Int32 nArgCount = 0;
+ sal_Bool *pbIsIn = 0;
+ sal_Bool *pbIsOut = 0;
+ sal_Bool *pbConversionNeeded = 0;
+ sal_Bool bConversionNeededForReturn = 0;
+
+ //--------------------------------
+ // Collect all needed types !
+ //--------------------------------
+ if( typelib_TypeClass_INTERFACE_ATTRIBUTE == pType->eTypeClass )
+ {
+ pAttributeType = ( typelib_InterfaceAttributeTypeDescription * ) pType;
+ if( pReturn )
+ {
+ TYPELIB_DANGER_GET( &pReturnType , pAttributeType->pAttributeTypeRef );
+ bConversionNeededForReturn = remote_relatesToInterface( pReturnType );
+ }
+ else
+ {
+ nArgCount = 1;
+ ppArgType = (typelib_TypeDescription **) alloca( sizeof( void * ) );
+ pbIsIn = ( sal_Bool * ) alloca( sizeof( sal_Bool ) );
+ pbIsOut = ( sal_Bool * ) alloca( sizeof( sal_Bool ) );
+ pbConversionNeeded = ( sal_Bool *) alloca( sizeof( sal_Bool ) );
+
+ pbIsIn[0] = sal_True;
+ pbIsOut[0] = sal_False;
+ ppArgType[0] = 0;
+ TYPELIB_DANGER_GET( &( ppArgType[0] ) , pAttributeType->pAttributeTypeRef );
+ pbConversionNeeded[0] = remote_relatesToInterface( ppArgType[0] );
+
+ }
+ }
+ if( typelib_TypeClass_INTERFACE_METHOD == pType->eTypeClass )
+ {
+ pMethodType = ( typelib_InterfaceMethodTypeDescription * ) pType;
+ TYPELIB_DANGER_GET( &pReturnType , pMethodType->pReturnTypeRef );
+ bConversionNeededForReturn = remote_relatesToInterface( pReturnType );
+ nArgCount = pMethodType->nParams;
+ ppArgType = (typelib_TypeDescription **) alloca( sizeof( void * ) * nArgCount );
+ pbIsIn = (sal_Bool * ) alloca( sizeof( sal_Bool ) * nArgCount );
+ pbIsOut = (sal_Bool * ) alloca( sizeof( sal_Bool ) * nArgCount );
+ pbConversionNeeded = ( sal_Bool *) alloca( sizeof( sal_Bool ) * nArgCount );
+ sal_Int32 i;
+ for( i = 0 ; i < nArgCount ; i ++ )
+ {
+ ppArgType[i] = 0;
+ TYPELIB_DANGER_GET( & (ppArgType[i]) , pMethodType->pParams[i].pTypeRef );
+ pbIsIn[i] = pMethodType->pParams[i].bIn;
+ pbIsOut[i] = pMethodType->pParams[i].bOut;
+ pbConversionNeeded[i] = remote_relatesToInterface( ppArgType[i] );
+ }
+ }
+
+ void *pRemoteReturn = 0;
+ if( pReturnType )
+ {
+ if( bConversionNeededForReturn )
+ {
+ pRemoteReturn = alloca( pReturnType->nSize );
+ }
+ else
+ {
+ pRemoteReturn = pReturn;
+ }
+ }
+
+ void ** ppRemoteArgs = 0;
+ if( nArgCount )
+ {
+ ppRemoteArgs = (void**) alloca( sizeof( void * ) * nArgCount );
+ }
+
+ sal_Int32 i;
+ for( i = 0 ; i < nArgCount ; i ++ )
+ {
+ if( pbConversionNeeded[i] )
+ {
+ ppRemoteArgs[i] = alloca( ppArgType[i]->nSize );
+
+ if( pbIsIn[i] ) {
+ uno_copyAndConvertData(
+ ppRemoteArgs[i],
+ ppArgs[i],
+ ppArgType[i],
+ p->m_mapUno2Remote.get() );
+ }
+ }
+ else
+ {
+ ppRemoteArgs[i] = ppArgs[i];
+ }
+ }
+
+ uno_Any any;
+ uno_Any *pAny = &any;
+
+ p->m_pRemoteI->pDispatcher( p->m_pRemoteI,
+ pType,
+ pRemoteReturn,
+ ppRemoteArgs,
+ &pAny );
+
+ if( ! pAny )
+ {
+ if( pReturn && bConversionNeededForReturn )
+ {
+ uno_copyAndConvertData(
+ pReturn ,
+ pRemoteReturn,
+ pReturnType,
+ p->m_mapRemote2Uno.get() );
+ uno_destructData( pRemoteReturn , pReturnType , remote_release );
+ }
+
+ sal_Int32 j;
+ for( j = 0 ; j < nArgCount ; j ++ )
+ {
+ if( pbConversionNeeded[j] )
+ {
+ if( pbIsIn[j] ) {
+ if( pbIsOut[j] ) {
+ uno_destructData( ppArgs[j] ,
+ ppArgType[j] ,
+ 0 );
+ uno_copyAndConvertData( ppArgs[j] ,
+ ppRemoteArgs[j],
+ ppArgType[j],
+ p->m_mapRemote2Uno.get() );
+ }
+ }
+ else // pure out
+ {
+ uno_copyAndConvertData( ppArgs[j] ,
+ ppRemoteArgs[j],
+ ppArgType[j],
+ p->m_mapRemote2Uno.get() );
+ }
+ uno_destructData( ppRemoteArgs[j],
+ ppArgType[j],
+ remote_release );
+ }
+ }
+ *ppException = 0;
+ }
+ else
+ {
+ // -----------------------
+ // an exception occured
+ // -----------------------
+ typelib_TypeDescription *pAnyType = 0;
+ getCppuType( (::com::sun::star::uno::Any*) 0 ).getDescription( &pAnyType );
+ uno_copyAndConvertData( *ppException ,
+ pAny ,
+ pAnyType,
+ p->m_mapRemote2Uno.get() );
+ uno_destructData( pAny , pAnyType , remote_release );
+ typelib_typedescription_release( pAnyType );
+
+ // destruct remote in parameters ( out parameters have not been constructed )
+ for( i = 0 ; i < nArgCount ; i ++ )
+ {
+ if( pbConversionNeeded[i] && pbIsIn[i] )
+ {
+ uno_destructData( ppRemoteArgs[i],
+ ppArgType[i],
+ remote_release );
+ }
+ }
+ }
+
+ //--------------------------
+ // release all acquired types
+ //--------------------------
+ if( pReturnType )
+ {
+ TYPELIB_DANGER_RELEASE( pReturnType );
+ }
+ for( i = 0 ; i < nArgCount ; i ++ )
+ {
+ TYPELIB_DANGER_RELEASE( ppArgType[ i] );
+ }
+
+}
+
+Remote2UnoProxy::Remote2UnoProxy( remote_Interface *pRemoteI,
+ rtl_uString *pOid,
+ typelib_InterfaceTypeDescription *pType,
+ uno_Environment *pEnvUno,
+ uno_Environment *pEnvRemote ) :
+ m_sOid( pOid ),
+ m_pType( pType ),
+ m_pRemoteI( pRemoteI ),
+ m_pEnvUno( pEnvUno ),
+ m_pEnvRemote( pEnvRemote ),
+ m_mapRemote2Uno( pEnvRemote, pEnvUno ),
+ m_mapUno2Remote( pEnvUno , pEnvRemote ),
+ m_nRef( 1 )
+{
+ typelib_typedescription_acquire( (typelib_TypeDescription * ) m_pType );
+ m_pEnvUno->acquire( m_pEnvUno );
+ m_pEnvRemote->acquire( m_pEnvRemote );
+
+ acquire = acquireRemote2UnoProxy;
+ release = releaseRemote2UnoProxy;
+ pDispatcher = dispatchRemote2UnoProxy;
+
+ m_pEnvRemote->pExtEnv->registerInterface(
+ m_pEnvRemote->pExtEnv,
+ (void**)&m_pRemoteI,
+ m_sOid.pData,
+ m_pType );
+ m_pRemoteI->acquire( m_pRemoteI );
+
+#if OSL_DEBUG_LEVEL > 1
+ thisCounter.acquire();
+#endif
+}
+
+Remote2UnoProxy::~Remote2UnoProxy()
+{
+ // revoke external ref (oid)
+ m_pEnvRemote->pExtEnv->revokeInterface( m_pEnvRemote->pExtEnv , m_pRemoteI );
+
+ typelib_typedescription_release( (typelib_TypeDescription * )m_pType );
+ m_pRemoteI->release( m_pRemoteI );
+ m_pEnvUno->release( m_pEnvUno );
+ m_pEnvRemote->release( m_pEnvRemote );
+#if OSL_DEBUG_LEVEL > 1
+ thisCounter.release();
+#endif
+}
+
+} // end namespace bridge_remote
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/static/remote.cxx b/bridges/source/remote/static/remote.cxx
new file mode 100644
index 000000000000..24e7674f8cf1
--- /dev/null
+++ b/bridges/source/remote/static/remote.cxx
@@ -0,0 +1,164 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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_bridges.hxx"
+#include <bridges/remote/remote.hxx>
+#include <bridges/remote/counter.hxx>
+
+#if OSL_DEBUG_LEVEL > 1
+static MyCounter thisCounter( "DEBUG : Remote2RemoteStub");
+#endif
+
+using namespace bridges_remote;
+
+extern "C" {
+
+static void SAL_CALL thisRelease( remote_Interface *pThis )
+{
+ Remote2RemoteStub *p = ( Remote2RemoteStub * ) pThis;
+ if (! osl_decrementInterlockedCount( &(p->m_nRef) ))
+ {
+ p->m_pEnvRemote->pExtEnv->revokeInterface( p->m_pEnvRemote->pExtEnv, pThis );
+
+ }
+}
+
+static void SAL_CALL thisDispatch(
+ remote_Interface * pRemoteI,
+ typelib_TypeDescription const * pMemberType,
+ void * pReturn,
+ void * pArgs[],
+ uno_Any ** ppException )
+{
+ Remote2RemoteStub *pThis = ( Remote2RemoteStub * ) pRemoteI;
+
+ pThis->m_dispatch( pThis->m_pEnvRemote,
+ pMemberType,
+ pThis->m_sOid.pData,
+ pThis->m_pType,
+ pReturn,
+ pArgs,
+ ppException );
+}
+
+}
+
+namespace bridges_remote {
+
+void acquireRemote2RemoteStub( remote_Interface *pThis )
+{
+ Remote2RemoteStub *p = ( Remote2RemoteStub * ) pThis;
+ if( 1 == osl_incrementInterlockedCount( &(p->m_nRef) ) )
+ {
+ p->m_pEnvRemote->pExtEnv->registerProxyInterface(
+ p->m_pEnvRemote->pExtEnv,
+ (void**)&pThis,
+ freeRemote2RemoteStub,
+ p->m_sOid.pData,
+ p->m_pType );
+ OSL_ASSERT( (remote_Interface *)p == pThis );
+ }
+}
+
+void freeRemote2RemoteStub(uno_ExtEnvironment *, void * stub) {
+ delete static_cast< Remote2RemoteStub * >(stub);
+}
+
+Remote2RemoteStub::Remote2RemoteStub( rtl_uString *pOid,
+ typelib_InterfaceTypeDescription *pType,
+ uno_Environment *pEnvRemote,
+ requestClientSideDispatcher dispatch ) :
+ m_sOid( pOid ),
+ m_pType( (typelib_InterfaceTypeDescription * ) pType ),
+ m_nRef( 1 ),
+ m_pEnvRemote( pEnvRemote ),
+ m_dispatch( dispatch ),
+ m_nReleaseRemote( 1 )
+{
+ typelib_typedescription_acquire( ( typelib_TypeDescription * ) m_pType );
+ m_pEnvRemote->acquire( m_pEnvRemote );
+
+ acquire = acquireRemote2RemoteStub;
+ release = thisRelease;
+ pDispatcher = thisDispatch;
+#if OSL_DEBUG_LEVEL > 1
+ thisCounter.acquire();
+#endif
+}
+
+Remote2RemoteStub::~Remote2RemoteStub()
+{
+
+ // send a release via the connection !
+ sal_Bool bNeedsRelease = sal_False;
+ if( ! m_pType->aBase.bComplete )
+ {
+ // m_pType may be exchanged during complete, so it needs to be acquired
+ // (MT : Another thread may use m_pType during e.g. dispatch ! ).
+ typelib_typedescription_acquire( (typelib_TypeDescription*)m_pType );
+ bNeedsRelease = sal_True;
+ typelib_typedescription_complete( (typelib_TypeDescription **) &m_pType );
+ }
+
+ uno_Any any;
+ uno_Any *pAny = &any;
+
+ typelib_TypeDescription *pReleaseMethod = 0;
+ typelib_typedescriptionreference_getDescription(
+ &pReleaseMethod ,
+ m_pType->ppAllMembers[REMOTE_RELEASE_METHOD_INDEX] );
+ for( int i = 0 ; i < m_nReleaseRemote ; i ++ )
+ {
+ thisDispatch( this,
+ pReleaseMethod,
+ 0,
+ 0,
+ &pAny );
+ }
+ typelib_typedescription_release( pReleaseMethod );
+ if( bNeedsRelease )
+ {
+ typelib_typedescription_release( (typelib_TypeDescription * ) m_pType );
+ }
+
+ typelib_typedescription_release( (typelib_TypeDescription * ) m_pType );
+ m_pEnvRemote->release( m_pEnvRemote );
+#if OSL_DEBUG_LEVEL > 1
+ thisCounter.release();
+#endif
+}
+
+void Remote2RemoteStub::releaseRemote()
+{
+ osl_incrementInterlockedCount( &m_nReleaseRemote );
+}
+
+} // end namespace bridges_remote
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/static/remote_types.cxx b/bridges/source/remote/static/remote_types.cxx
new file mode 100644
index 000000000000..95f023508ee4
--- /dev/null
+++ b/bridges/source/remote/static/remote_types.cxx
@@ -0,0 +1,99 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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_bridges.hxx"
+#include "remote_types.hxx"
+
+namespace bridges_remote {
+
+sal_Bool SAL_CALL remote_relatesToInterface2( typelib_TypeDescription * pTypeDescr )
+{
+ switch (pTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_SEQUENCE:
+ {
+ switch (((typelib_IndirectTypeDescription *)pTypeDescr)->pType->eTypeClass)
+ {
+ case typelib_TypeClass_SEQUENCE:
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType );
+ sal_Bool bRel = remote_relatesToInterface( pTD );
+ TYPELIB_DANGER_RELEASE( pTD );
+ return bRel;
+ }
+ default:
+ break;
+ }
+ }
+ 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 sal_True;
+ case typelib_TypeClass_SEQUENCE:
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, pTypes[nPos] );
+ sal_Bool bRel = remote_relatesToInterface( pTD );
+ TYPELIB_DANGER_RELEASE( pTD );
+ if (bRel)
+ return sal_True;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ if (pComp->pBaseTypeDescription)
+ return remote_relatesToInterface( (typelib_TypeDescription *)pComp->pBaseTypeDescription );
+ break;
+ }
+ default:
+ OSL_ASSERT( 0 );
+ }
+ return sal_False;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/static/remote_types.hxx b/bridges/source/remote/static/remote_types.hxx
new file mode 100644
index 000000000000..024f38037349
--- /dev/null
+++ b/bridges/source/remote/static/remote_types.hxx
@@ -0,0 +1,92 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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 _BRIDGES_REMOTE_TYPES_HXX_
+#define _BRIDGES_REMOTE_TYPES_HXX_
+
+#include <osl/diagnose.h>
+#include <sal/types.h>
+#include <typelib/typedescription.h>
+
+namespace bridges_remote
+{
+
+inline sal_Bool SAL_CALL remote_relatesToInterface( typelib_TypeDescription *pTypeDescr );
+sal_Bool SAL_CALL remote_relatesToInterface2( typelib_TypeDescription * pTypeDescr );
+
+
+/** Determines whether given type might relate or relates to an interface,
+ i.e. values of this type are interface or may contain interface(s).<br>
+ @param pTypeDescr type description of type
+ @return true if type might relate to an interface, false otherwise
+*/
+inline sal_Bool SAL_CALL remote_relatesToInterface( typelib_TypeDescription * pTypeDescr )
+{
+ switch (pTypeDescr->eTypeClass)
+ {
+ 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 sal_True;
+ case typelib_TypeClass_SEQUENCE:
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ return remote_relatesToInterface2( pTypeDescr );
+ default:
+ return sal_False;
+ }
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ return remote_relatesToInterface2( pTypeDescr );
+ case typelib_TypeClass_UNION: // might relate to interface
+ case typelib_TypeClass_ANY: // might relate to interface
+ case typelib_TypeClass_INTERFACE:
+ return sal_True;
+ default:
+ return sal_False;
+ }
+}
+
+/** Determines whether given type is a cpp simple type, e.g. int, enum.<br>
+ @param pTypeDescr type description of type
+ @return true if type is a cpp simple type, false otherwise
+*/
+inline sal_Bool SAL_CALL remote_isSimpleType( typelib_TypeDescription * pTypeDescr )
+{
+ return (pTypeDescr->eTypeClass <= typelib_TypeClass_ENUM &&
+ pTypeDescr->eTypeClass != typelib_TypeClass_STRING &&
+ pTypeDescr->eTypeClass != typelib_TypeClass_ANY &&
+ pTypeDescr->eTypeClass != typelib_TypeClass_TYPE);
+}
+
+}
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/static/stub.cxx b/bridges/source/remote/static/stub.cxx
new file mode 100644
index 000000000000..ee6d33184eca
--- /dev/null
+++ b/bridges/source/remote/static/stub.cxx
@@ -0,0 +1,339 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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_bridges.hxx"
+#include <sal/alloca.h>
+#include <osl/diagnose.h>
+
+#include <uno/data.h>
+#include <uno/mapping.hxx>
+
+#include <bridges/remote/stub.hxx>
+#include <bridges/remote/proxy.hxx>
+#include <bridges/remote/context.h>
+#include <bridges/remote/bridgeimpl.hxx>
+
+#include "remote_types.hxx"
+
+#if OSL_DEBUG_LEVEL > 1
+#include <bridges/remote/counter.hxx>
+static MyCounter thisCounter( "DEBUG : Uno2RemoteStub");
+#endif
+
+using namespace ::com::sun::star::uno;
+using namespace bridges_remote;
+
+extern "C" {
+
+void SAL_CALL thisRelease( remote_Interface *pThis )
+{
+ Uno2RemoteStub *p = ( Uno2RemoteStub * ) pThis;
+ if (! osl_decrementInterlockedCount( &(p->m_nRef) ))
+ {
+ p->m_pEnvRemote->pExtEnv->revokeInterface( p->m_pEnvRemote->pExtEnv, pThis );
+ }
+}
+
+void SAL_CALL thisDispatch(
+ remote_Interface * pRemoteI,
+ typelib_TypeDescription const * pType,
+ void * pReturn,
+ void * ppArgs[],
+ uno_Any ** ppException )
+{
+ Uno2RemoteStub *p = ( Uno2RemoteStub * ) pRemoteI;
+
+ RemoteThreadCounter counter( p->m_pEnvRemote );
+
+ typelib_InterfaceMethodTypeDescription *pMethodType = 0;
+ typelib_InterfaceAttributeTypeDescription *pAttributeType = 0;
+ typelib_TypeDescription *pReturnType = 0;
+ typelib_TypeDescription **ppArgType = 0;
+ sal_Int32 nArgCount = 0;
+ sal_Bool *pbIsIn = 0;
+ sal_Bool *pbIsOut = 0;
+ sal_Bool bConversionNeededForReturn = sal_False;
+ sal_Bool *pbConversionNeeded = 0;
+
+ sal_Int32 i;
+ //--------------------------------
+ // Collect all needed types !
+ //--------------------------------
+ if( typelib_TypeClass_INTERFACE_ATTRIBUTE == pType->eTypeClass )
+ {
+ pAttributeType = ( typelib_InterfaceAttributeTypeDescription * ) pType;
+ if( pReturn )
+ {
+ TYPELIB_DANGER_GET( &pReturnType , pAttributeType->pAttributeTypeRef );
+ bConversionNeededForReturn = remote_relatesToInterface( pReturnType );
+ }
+ else
+ {
+ nArgCount = 1;
+ ppArgType = (typelib_TypeDescription **) alloca( sizeof( void * ) );
+ pbIsIn = ( sal_Bool * ) alloca( sizeof( sal_Bool ) );
+ pbIsOut = ( sal_Bool * ) alloca( sizeof( sal_Bool ) );
+ pbConversionNeeded = ( sal_Bool * ) alloca( sizeof( sal_Bool ) );
+ pbIsIn[0] = sal_True;
+ pbIsOut[0] = sal_False;
+ ppArgType[0] = 0;
+ TYPELIB_DANGER_GET( &( ppArgType[0] ) , pAttributeType->pAttributeTypeRef );
+ pbConversionNeeded[0] = remote_relatesToInterface( ppArgType[0] );
+ }
+ }
+ if( typelib_TypeClass_INTERFACE_METHOD == pType->eTypeClass )
+ {
+ pMethodType = ( typelib_InterfaceMethodTypeDescription * ) pType;
+ TYPELIB_DANGER_GET( &pReturnType , pMethodType->pReturnTypeRef );
+ bConversionNeededForReturn = remote_relatesToInterface( pReturnType );
+ nArgCount = pMethodType->nParams;
+ ppArgType = (typelib_TypeDescription **) alloca( sizeof( void * ) * nArgCount );
+ pbIsIn = (sal_Bool * ) alloca( sizeof( sal_Bool ) * nArgCount );
+ pbIsOut = (sal_Bool * ) alloca( sizeof( sal_Bool ) * nArgCount );
+ pbConversionNeeded = ( sal_Bool * ) alloca( sizeof( sal_Bool ) * nArgCount );
+
+ for( i = 0 ; i < nArgCount ; i ++ )
+ {
+ ppArgType[i] = 0;
+ TYPELIB_DANGER_GET( & (ppArgType[i]) , pMethodType->pParams[i].pTypeRef );
+ pbIsIn[i] = pMethodType->pParams[i].bIn;
+ pbIsOut[i] = pMethodType->pParams[i].bOut;
+ pbConversionNeeded[i] = remote_relatesToInterface( ppArgType[i] );
+ }
+ }
+
+ // create Mapping
+
+ void *pUnoReturn = 0;
+ void **ppUnoArgs = 0;
+
+ if( pReturnType )
+ {
+ if( bConversionNeededForReturn )
+ {
+ pUnoReturn = alloca( pReturnType->nSize );
+ }
+ else
+ {
+ pUnoReturn = pReturn;
+ }
+ }
+
+ ppUnoArgs = (void **) alloca( nArgCount * sizeof( void * ) );
+ for( i = 0 ; i < nArgCount ; i ++ )
+ {
+ if( pbConversionNeeded[i] )
+ {
+ ppUnoArgs[i] = alloca( ppArgType[i]->nSize );
+ if( pbIsIn[i] )
+ {
+ uno_copyAndConvertData(
+ ppUnoArgs[i],
+ ppArgs[i],
+ ppArgType[i],
+ p->m_mapRemote2Uno.get()
+ );
+ }
+ }
+ else
+ {
+ ppUnoArgs[i] = ppArgs[i];
+ }
+ }
+
+ // do the call
+ uno_Any any;
+ uno_Any *pAny = &any;
+
+ p->m_pUnoI->pDispatcher( p->m_pUnoI,
+ pType,
+ pUnoReturn,
+ ppUnoArgs,
+ &pAny);
+
+ if( ! pAny )
+ {
+ // ------------------
+ // No Exception
+ // ------------------
+
+ // Map return value
+ if( pReturnType && bConversionNeededForReturn )
+ {
+ uno_copyAndConvertData(
+ pReturn ,
+ pUnoReturn,
+ pReturnType,
+ p->m_mapUno2Remote.get() );
+ uno_destructData( pUnoReturn , pReturnType, 0 );
+ }
+
+ // map arguments
+ for( i = 0 ; i < nArgCount ; i ++ )
+ {
+ if( pbConversionNeeded[i] )
+ {
+ if( pbIsIn[i] ) {
+ if( pbIsOut[i] ) {
+ uno_destructData(
+ ppArgs[i] ,
+ ppArgType[i] ,
+ remote_release );
+ uno_copyAndConvertData( ppArgs[i] ,
+ ppUnoArgs[i],
+ ppArgType[i],
+ p->m_mapUno2Remote.get() );
+ }
+ }
+ else // pure out
+ {
+ uno_copyAndConvertData( ppArgs[i] ,
+ ppUnoArgs[i],
+ ppArgType[i],
+ p->m_mapUno2Remote.get() );
+ }
+ uno_destructData( ppUnoArgs[i],
+ ppArgType[i],
+ 0 );
+ }
+ }
+ *ppException = 0;
+ }
+ else
+ {
+ // -----------------------
+ // an exception occured
+ // -----------------------
+ typelib_TypeDescription *pAnyType = 0;
+ getCppuType( (Any*) 0 ).getDescription( &pAnyType );
+ uno_copyAndConvertData( *ppException ,
+ pAny ,
+ pAnyType,
+ p->m_mapUno2Remote.get() );
+ uno_destructData( pAny , pAnyType , 0 );
+ typelib_typedescription_release( pAnyType );
+
+ // destruct uno in parameters ( out parameters have not been constructed )
+ for( i = 0 ; i < nArgCount ; i ++ )
+ {
+ if( pbConversionNeeded[i] && pbIsIn[i] )
+ {
+ uno_destructData( ppUnoArgs[i],
+ ppArgType[i],
+ 0 );
+ }
+ }
+ }
+
+ //--------------------------
+ // release all acquired types
+ //--------------------------
+ if( pReturnType )
+ {
+ TYPELIB_DANGER_RELEASE( pReturnType );
+ }
+ for( i = 0 ; i < nArgCount ; i ++ )
+ {
+ TYPELIB_DANGER_RELEASE( ppArgType[ i] );
+ }
+}
+
+}
+
+namespace bridges_remote {
+
+void acquireUno2RemoteStub( remote_Interface *pThis )
+{
+ Uno2RemoteStub *p = ( Uno2RemoteStub * ) pThis;
+ if( 1 == osl_incrementInterlockedCount( &(p->m_nRef) ) )
+ {
+
+ p->m_pEnvRemote->pExtEnv->registerProxyInterface(
+ p->m_pEnvRemote->pExtEnv,
+ (void**)&pThis,
+ freeUno2RemoteStub,
+ p->m_sOid.pData,
+ p->m_pType );
+
+ OSL_ASSERT( (remote_Interface*) p == pThis );
+ }
+}
+
+void freeUno2RemoteStub(uno_ExtEnvironment *, void * stub) {
+ delete static_cast< Uno2RemoteStub * >(stub);
+}
+
+Uno2RemoteStub::Uno2RemoteStub( uno_Interface *pUnoI,
+ rtl_uString *pOid,
+ typelib_InterfaceTypeDescription *pType,
+ uno_Environment *pEnvUno,
+ uno_Environment *pEnvRemote ) :
+ m_sOid( pOid ),
+ m_pType( pType ),
+ m_pUnoI( pUnoI ),
+ m_nRef( 1 ),
+ m_pEnvUno( pEnvUno ),
+ m_pEnvRemote( pEnvRemote ),
+ m_mapRemote2Uno( pEnvRemote, pEnvUno ),
+ m_mapUno2Remote( pEnvUno, pEnvRemote )
+{
+ typelib_typedescription_acquire( (typelib_TypeDescription * )m_pType );
+ m_pEnvUno->acquire( m_pEnvUno );
+ m_pEnvRemote->acquire( m_pEnvRemote );
+
+ acquire = acquireUno2RemoteStub;
+ release = thisRelease;
+ pDispatcher = thisDispatch;
+
+ m_pEnvUno->pExtEnv->registerInterface( m_pEnvUno->pExtEnv,
+ (void **)&m_pUnoI,
+ m_sOid.pData,
+ m_pType );
+ m_pUnoI->acquire( m_pUnoI );
+#if OSL_DEBUG_LEVEL > 1
+ thisCounter.acquire();
+#endif
+}
+
+Uno2RemoteStub::~Uno2RemoteStub()
+{
+ m_pEnvUno->pExtEnv->revokeInterface( m_pEnvUno->pExtEnv , m_pUnoI );
+
+ typelib_typedescription_release( (typelib_TypeDescription * )m_pType );
+ m_pUnoI->release( m_pUnoI );
+ m_pEnvUno->release( m_pEnvUno );
+ m_pEnvRemote->release( m_pEnvRemote );
+#if OSL_DEBUG_LEVEL > 1
+ thisCounter.release();
+#endif
+}
+
+} // end namespace bridges_remote
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/makefile.mk b/bridges/source/remote/urp/makefile.mk
new file mode 100644
index 000000000000..eaa3f3a6f146
--- /dev/null
+++ b/bridges/source/remote/urp/makefile.mk
@@ -0,0 +1,78 @@
+#*************************************************************************
+#
+# 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=bridges
+TARGET=urp_uno
+ENABLE_EXCEPTIONS=TRUE
+USE_DEFFILE=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# ------------------------------------------------------------------
+
+SLOFILES= \
+ $(SLO)$/urp_environment.obj \
+ $(SLO)$/urp_marshal.obj \
+ $(SLO)$/urp_unmarshal.obj \
+ $(SLO)$/urp_dispatch.obj \
+ $(SLO)$/urp_job.obj \
+ $(SLO)$/urp_reader.obj \
+ $(SLO)$/urp_writer.obj \
+ $(SLO)$/urp_log.obj \
+ $(SLO)$/urp_bridgeimpl.obj \
+ $(SLO)$/urp_propertyobject.obj \
+ $(SLO)$/urp_threadid.obj
+
+.IF "$(COM)"=="GCC"
+NOOPTFILES= \
+ $(SLO)$/urp_reader.obj
+.ENDIF # "$(COM)"=="GCC"
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+SHL1RPATH=URELIB
+
+SHL1STDLIBS=\
+ $(SALLIB)\
+ $(CPPULIB)
+
+SHL1LIBS=\
+ $(SLB)$/$(TARGET).lib \
+ $(SLB)$/bridges_remote_static.lib
+
+DEF1NAME= $(SHL1TARGET)
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/bridges/source/remote/urp/urp_bridgeimpl.cxx b/bridges/source/remote/urp/urp_bridgeimpl.cxx
new file mode 100644
index 000000000000..53443a0ecf63
--- /dev/null
+++ b/bridges/source/remote/urp/urp_bridgeimpl.cxx
@@ -0,0 +1,253 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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_bridges.hxx"
+#include <osl/thread.h>
+#include <bridges/remote/helper.hxx>
+
+#include <algorithm>
+
+#include "urp_bridgeimpl.hxx"
+
+using namespace ::rtl;
+using namespace ::osl;
+using namespace ::com::sun::star::uno;
+namespace bridges_urp
+{
+
+template < class t >
+inline t mymin( const t & val1, const t & val2 )
+{
+ return val1 < val2 ? val1 : val2;
+}
+
+/***********
+ * urp_BridgeImpl
+ ***********/
+urp_BridgeImpl::urp_BridgeImpl( sal_Int32 nCacheSize , sal_uInt32 nInitialMarshalerSize ) :
+ m_blockMarshaler( this , nInitialMarshalerSize , ::bridges_remote::remote_retrieveOidFromProxy),
+ m_nMarshaledMessages( 0 ),
+ m_oidCacheOut( (sal_uInt16)nCacheSize ),
+ m_tidCacheOut( (sal_uInt16)nCacheSize ),
+ m_typeCacheOut( (sal_uInt16)nCacheSize )
+{
+ m_pOidIn = new OUString[ nCacheSize ];
+ m_pTidIn = new ByteSequence[ nCacheSize ];
+ m_pTypeIn = new Type[ nCacheSize ];
+ m_nRemoteThreads = 0;
+}
+
+urp_BridgeImpl::~urp_BridgeImpl()
+{
+ delete [] m_pOidIn;
+ delete [] m_pTidIn;
+ delete [] m_pTypeIn;
+}
+
+
+void urp_BridgeImpl::applyProtocolChanges( const Properties &props )
+{
+ if( m_properties.nTypeCacheSize != props.nTypeCacheSize )
+ {
+ if( props.nTypeCacheSize == 0 )
+ {
+ delete [] m_pTypeIn;
+ m_pTypeIn = 0;
+ }
+ else
+ {
+ Type *pNew = new Type[props.nTypeCacheSize];
+ sal_Int32 i;
+ sal_Int32 iMin = mymin( m_properties.nTypeCacheSize , props.nTypeCacheSize );
+ for( i = 0; i < iMin ; i ++ )
+ {
+ pNew[i] = m_pTypeIn[i];
+ }
+ delete [] m_pTypeIn;
+ m_pTypeIn = pNew;
+ }
+ OSL_ASSERT( props.nTypeCacheSize <= 0xffff );
+ m_properties.nTypeCacheSize = props.nTypeCacheSize;
+ m_typeCacheOut.resize( (sal_uInt16)props.nTypeCacheSize );
+ }
+
+ if( m_properties.nOidCacheSize != props.nOidCacheSize )
+ {
+ if( 0 == props.nOidCacheSize )
+ {
+ delete [] m_pOidIn;
+ m_pOidIn = 0;
+ }
+ else
+ {
+ OUString *pNew = new OUString[props.nOidCacheSize];
+ sal_Int32 i;
+ sal_Int32 iMin = mymin( m_properties.nOidCacheSize , props.nOidCacheSize );
+ for( i = 0; i < iMin ; i ++ )
+ {
+ pNew[i] = m_pOidIn[i];
+ }
+ delete [] m_pOidIn;
+ m_pOidIn = pNew;
+ }
+ OSL_ASSERT( props.nOidCacheSize <= 0xffff );
+ m_oidCacheOut.resize( (sal_uInt16)props.nOidCacheSize );
+ m_properties.nOidCacheSize = props.nOidCacheSize;
+ }
+
+ if( m_properties.nTidCacheSize != props.nTidCacheSize )
+ {
+ if( 0 == props.nTidCacheSize )
+ {
+ delete [] m_pTidIn;
+ m_pTidIn = 0;
+ }
+ else
+ {
+ ByteSequence *pNew = new ByteSequence[props.nTidCacheSize];
+ sal_Int32 i;
+ sal_Int32 iMin = mymin( m_properties.nTidCacheSize , props.nTidCacheSize );
+ for( i = 0; i < iMin ; i ++ )
+ {
+ pNew[i] = m_pTidIn[i];
+ }
+ delete [] m_pTidIn;
+ m_pTidIn = pNew;
+ }
+ OSL_ASSERT( props.nTidCacheSize <= 0xffff );
+ m_tidCacheOut.resize( (sal_uInt16)props.nTidCacheSize );
+ m_properties.nTidCacheSize = props.nTidCacheSize;
+ }
+
+ if( m_properties.sVersion != props.sVersion )
+ {
+ m_properties.sVersion = props.sVersion;
+ }
+
+ if( m_properties.nFlushBlockSize != props.nFlushBlockSize )
+ {
+ m_properties.nFlushBlockSize = props.nFlushBlockSize;
+ }
+
+ if( m_properties.nOnewayTimeoutMUSEC != props.nOnewayTimeoutMUSEC )
+ {
+ m_properties.nOnewayTimeoutMUSEC = props.nOnewayTimeoutMUSEC;
+ }
+
+ if( props.bClearCache )
+ {
+ if( m_properties.nTypeCacheSize )
+ {
+ delete [] m_pTypeIn;
+ m_pTypeIn = new Type[m_properties.nTypeCacheSize];
+ m_typeCacheOut.clear();
+ }
+ m_lastInType = Type();
+ m_lastOutType = Type();
+
+ if( m_properties.nOidCacheSize )
+ {
+ delete [] m_pOidIn;
+ m_pOidIn = new OUString[ m_properties.nOidCacheSize];
+ m_oidCacheOut.clear();
+ }
+ m_lastOutOid = OUString();
+ m_lastInOid = OUString();
+
+ if( m_properties.nTidCacheSize )
+ {
+ delete [] m_pTidIn;
+ m_pTidIn = new ByteSequence[m_properties.nTidCacheSize];
+ m_tidCacheOut.clear();
+ }
+ m_lastInTid = ByteSequence();
+ m_lastOutTid = ByteSequence();
+ }
+
+ if( m_properties.bNegotiate != props.bNegotiate )
+ {
+ m_properties.bNegotiate = props.bNegotiate;
+ }
+
+ if( m_properties.bForceSynchronous != props.bForceSynchronous )
+ {
+ m_properties.bForceSynchronous = props.bForceSynchronous;
+ }
+
+ m_properties.bCurrentContext = props.bCurrentContext;
+}
+
+void urp_BridgeImpl::addError( char const *pError )
+{
+ OUString message = OUString(RTL_CONSTASCII_USTRINGPARAM("(tid=" ));
+ message += OUString::valueOf( (sal_Int32 ) osl_getThreadIdentifier( 0 ) );
+ message += OUString(RTL_CONSTASCII_USTRINGPARAM(") "));
+ message += OUString::createFromAscii( pError );
+ MutexGuard guard( m_errorListMutex );
+ m_lstErrors.push_back( message );
+}
+
+void urp_BridgeImpl::addError( const OUString & error )
+{
+ OUString message = OUString(RTL_CONSTASCII_USTRINGPARAM("(tid="));
+ message += OUString::valueOf( (sal_Int32 ) osl_getThreadIdentifier( 0 ) );
+ message += OUString(RTL_CONSTASCII_USTRINGPARAM(") "));
+ message += error;
+ MutexGuard guard( m_errorListMutex );
+ m_lstErrors.push_back( message );
+}
+
+void urp_BridgeImpl::dumpErrors( FILE * f)
+{
+ MutexGuard guard( m_errorListMutex );
+ for( ::std::list< OUString >::iterator ii = m_lstErrors.begin() ;
+ ii != m_lstErrors.end() ;
+ ++ii )
+ {
+ OString o = OUStringToOString( *ii , RTL_TEXTENCODING_UTF8 );
+ fprintf( f, "%s\n" , o.getStr() );
+ }
+}
+
+OUString urp_BridgeImpl::getErrorsAsString( )
+{
+ MutexGuard guard( m_errorListMutex );
+ OUString ret;
+ for( ::std::list< OUString >::iterator ii = m_lstErrors.begin() ;
+ ii != m_lstErrors.end() ;
+ ++ii )
+ {
+ ret += *ii;
+ }
+ return ret;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_bridgeimpl.hxx b/bridges/source/remote/urp/urp_bridgeimpl.hxx
new file mode 100644
index 000000000000..59795fac17cd
--- /dev/null
+++ b/bridges/source/remote/urp/urp_bridgeimpl.hxx
@@ -0,0 +1,130 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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 _URP_BRIDGEIMPL_HXX_
+#define _URP_BRIDGEIMPL_HXX_
+
+#include <stdio.h>
+#include <osl/mutex.hxx>
+#include <osl/conditn.hxx>
+#include <rtl/ustring.hxx>
+#include <rtl/byteseq.hxx>
+
+#include <uno/threadpool.h>
+#include <bridges/remote/bridgeimpl.hxx>
+
+#include "urp_cache.hxx"
+#include "urp_marshal_decl.hxx"
+
+#include "urp_replycontainer.hxx"
+#include "urp_property.hxx"
+
+
+namespace bridges_urp
+{
+
+class PropertyObject;
+
+struct equalOUString
+{
+ sal_Int32 operator() ( const ::rtl::OUString &s1, const ::rtl::OUString &s2 ) const
+ {
+ return s1 == s2;
+ }
+};
+
+struct equalType
+{
+ sal_Int32 operator() ( const ::com::sun::star::uno::Type &t1,
+ const ::com::sun::star::uno::Type &t2 ) const
+ {
+ return t1 == t2;
+ }
+};
+
+class OWriterThread;
+class OReaderThread;
+
+struct urp_BridgeImpl :
+ public remote_BridgeImpl
+{
+ urp_BridgeImpl( sal_Int32 nCacheSize , sal_uInt32 nInitialMarshalerSize );
+ ~urp_BridgeImpl();
+
+ void applyProtocolChanges( const Properties & );
+
+ void startBlockBridge();
+ void stopBlockBridge();
+ void addError( char const *pError );
+ void addError( const ::rtl::OUString &anError );
+ void dumpErrors( FILE *f );
+ ::rtl::OUString getErrorsAsString();
+
+ ::osl::Mutex m_marshalingMutex;
+ ::osl::Mutex m_disposingMutex;
+ ::osl::Mutex m_errorListMutex;
+ Marshal m_blockMarshaler;
+ sal_Int32 m_nMarshaledMessages;
+
+ // Caches for vars, that go from local process to the remote process
+ Cache < ::rtl::OUString , equalOUString > m_oidCacheOut;
+ Cache < ::rtl::ByteSequence , EqualThreadId > m_tidCacheOut;
+ Cache < ::com::sun::star::uno::Type , equalType > m_typeCacheOut;
+
+ ::com::sun::star::uno::Type m_lastOutType;
+ ::rtl::ByteSequence m_lastOutTid;
+ ::rtl::OUString m_lastOutOid;
+
+ // Caches for vars, that come from the remote process to the local process
+ ::rtl::OUString *m_pOidIn;
+ ::rtl::ByteSequence *m_pTidIn;
+ ::com::sun::star::uno::Type *m_pTypeIn;
+
+ ::com::sun::star::uno::Type m_lastInType;
+ ::rtl::ByteSequence m_lastInTid;
+ ::rtl::OUString m_lastInOid;
+
+ urp_ClientJobContainer m_clientJobContainer;
+
+ OWriterThread *m_pWriter;
+ OReaderThread *m_pReader;
+ ::rtl::OString m_sLogFileName;
+ FILE *m_pLogFile;
+ ::osl::Condition m_initialized;
+ ::osl::Condition m_cndWaitForThreads;
+
+ struct Properties m_properties;
+ class PropertyObject *m_pPropertyObject;
+ ::std::list< ::rtl::OUString > m_lstErrors;
+ uno_ThreadPool m_hThreadPool;
+};
+
+
+}
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_cache.h b/bridges/source/remote/urp/urp_cache.h
new file mode 100644
index 000000000000..ca3dec9c8298
--- /dev/null
+++ b/bridges/source/remote/urp/urp_cache.h
@@ -0,0 +1,60 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+
+namespace bridges_urp
+{
+ template < class t , class tequals >
+ class Cache
+ {
+ public:
+ inline Cache ( sal_uInt16 nMaxEntries );
+ inline ~Cache();
+
+ // puts the value t into the cache. Returns then entry,
+ // that is used for this value.
+ inline sal_uInt16 put( const t & );
+
+ // lookup, if there is an entry for this value
+ // returns 0xffff, when value cannot be found in the list
+ inline sal_uInt16 seek( const t & );
+
+ // resizes the cache, conserving overlapping values
+ inline void resize( sal_uInt16 nNewMaxEntries );
+
+ // empties the cache
+ inline void clear();
+ private:
+ t *m_pCache;
+ ::std::list< sal_uInt16 > m_lstLeastRecentlyUsed;
+ sal_uInt16 m_nMaxEntries;
+ sal_uInt16 m_nEntries;
+ };
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_cache.hxx b/bridges/source/remote/urp/urp_cache.hxx
new file mode 100644
index 000000000000..e8677116cb96
--- /dev/null
+++ b/bridges/source/remote/urp/urp_cache.hxx
@@ -0,0 +1,163 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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 <stdio.h>
+#include <list>
+#include <algorithm>
+#include <rtl/ustring.hxx>
+
+#include "urp_threadid.hxx"
+#include "urp_cache.h"
+
+namespace bridges_urp
+{
+
+ template < class t , class tequals >
+ inline Cache< t , tequals >::Cache( sal_uInt16 nMaxEntries ) :
+ m_pCache( new t[nMaxEntries] ),
+ m_nMaxEntries( nMaxEntries ),
+ m_nEntries( 0 )
+ {
+
+ }
+
+ template < class t , class tequals >
+ inline Cache< t , tequals >::~Cache( )
+ {
+ delete [] m_pCache;
+ }
+
+
+ template < class t , class tequals >
+ inline sal_uInt16 Cache< t , tequals >::put( const t & value )
+ {
+ if( ! m_nMaxEntries )
+ {
+ return 0xffff;
+ }
+ sal_uInt16 nEntry = 0xffff;
+ if( m_nEntries < m_nMaxEntries )
+ {
+ // cache has still empty places
+ m_pCache[m_nEntries] = value;
+ nEntry = m_nEntries;
+ m_nEntries ++;
+
+ // add it to the cache
+ m_lstLeastRecentlyUsed.push_front( nEntry );
+ }
+ else
+ {
+ // cache is full, remove an element and insert the new one
+ nEntry = m_lstLeastRecentlyUsed.back();
+ m_lstLeastRecentlyUsed.pop_back();
+ m_lstLeastRecentlyUsed.push_front( nEntry );
+
+ m_pCache[nEntry] = value;
+ }
+ return nEntry;
+ }
+
+ template < class t , class tequals >
+ inline sal_uInt16 Cache< t , tequals >::seek( const t & value )
+ {
+ for( ::std::list< sal_uInt16 >::iterator ii = m_lstLeastRecentlyUsed.begin() ;
+ ii != m_lstLeastRecentlyUsed.end() ;
+ ++ ii )
+ {
+ if( value == m_pCache[*ii] )
+ {
+ sal_uInt16 nEntry = *ii;
+ m_lstLeastRecentlyUsed.erase( ii );
+ m_lstLeastRecentlyUsed.push_front( nEntry );
+ return nEntry;
+ }
+ }
+ return 0xffff;
+ }
+
+ // helper predicate for element removal
+ template < class t >
+ struct PredicateOverMax
+ {
+ t m_;
+ inline PredicateOverMax( const t &value ) : m_(value)
+ {}
+ sal_Int32 operator () ( const t &value ) const
+ { return value >= m_; }
+ };
+
+ template < class t, class tequals >
+ inline void Cache < t , tequals >::resize( sal_uInt16 nNewMaxEntries )
+ {
+ if( 0 == nNewMaxEntries )
+ {
+ m_lstLeastRecentlyUsed.clear();
+ delete [] m_pCache;
+ m_pCache = 0;
+ m_nMaxEntries = 0;
+ }
+ else
+ {
+ // allocate
+ t *pNew = new t[nNewMaxEntries];
+ sal_Int32 nMin = nNewMaxEntries < m_nMaxEntries ? nNewMaxEntries : m_nMaxEntries;
+
+ // copy
+ for( sal_Int32 i = 0; i < nMin ; i ++ )
+ {
+ pNew[i] = m_pCache[i];
+ }
+ // delete
+ delete [] m_pCache;
+
+ // assign
+ m_pCache = pNew;
+
+ // remove overlapping lru cache entries
+ ::std::remove_if(m_lstLeastRecentlyUsed.begin(),
+ m_lstLeastRecentlyUsed.end(),
+ PredicateOverMax< sal_Int32 > ( nMin ) );
+ }
+ m_nMaxEntries = nNewMaxEntries;
+ m_nEntries = m_nEntries < m_nMaxEntries ?
+ m_nEntries : m_nMaxEntries;
+ }
+
+ template < class t, class tequals >
+ inline void Cache < t, tequals >:: clear()
+ {
+ for( sal_Int32 i = 0; i < m_nMaxEntries ; i ++ )
+ {
+ m_pCache[i] = t();
+ }
+ m_lstLeastRecentlyUsed.clear();
+ m_nEntries = 0;
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_dispatch.cxx b/bridges/source/remote/urp/urp_dispatch.cxx
new file mode 100644
index 000000000000..c8c405403938
--- /dev/null
+++ b/bridges/source/remote/urp/urp_dispatch.cxx
@@ -0,0 +1,118 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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_bridges.hxx"
+#include <sal/alloca.h>
+#include <osl/mutex.hxx>
+#include <osl/diagnose.h>
+
+#include <rtl/alloc.h>
+#include <rtl/ustrbuf.hxx>
+
+#include <uno/mapping.hxx>
+#include <uno/threadpool.h>
+
+#include <bridges/remote/remote.h>
+#include <bridges/remote/stub.hxx>
+#include <bridges/remote/proxy.hxx>
+#include <bridges/remote/remote.hxx>
+
+#include "urp_bridgeimpl.hxx"
+#include "urp_marshal.hxx"
+#include "urp_dispatch.hxx"
+#include "urp_job.hxx"
+#include "urp_writer.hxx"
+#include "urp_log.hxx"
+
+using namespace ::rtl;
+using namespace ::osl;
+using namespace ::com::sun::star::uno;
+
+namespace bridges_urp
+{
+
+void SAL_CALL urp_sendCloseConnection( uno_Environment *pEnvRemote )
+{
+ remote_Context *pContext = (remote_Context *) pEnvRemote->pContext;
+ urp_BridgeImpl *pImpl = (urp_BridgeImpl*) ( pContext->m_pBridgeImpl );
+
+ {
+ MutexGuard guard( pImpl->m_marshalingMutex );
+
+ // send immediately
+ if( ! pImpl->m_blockMarshaler.empty() )
+ {
+ pImpl->m_pWriter->touch( sal_True );
+ }
+
+ pImpl->m_pWriter->sendEmptyMessage();
+ }
+}
+extern "C" void SAL_CALL urp_sendRequest(
+ uno_Environment *pEnvRemote,
+ typelib_TypeDescription const * pMemberType,
+ rtl_uString *pOid,
+ typelib_InterfaceTypeDescription *pInterfaceType,
+ void *pReturn,
+ void *ppArgs[],
+ uno_Any **ppException )
+{
+ remote_Context *pContext = (remote_Context *) pEnvRemote->pContext;
+ urp_BridgeImpl *pImpl = (urp_BridgeImpl*) ( pContext->m_pBridgeImpl );
+ pImpl->m_initialized.wait();
+ urp_sendRequest_internal(
+ pEnvRemote, pMemberType, pOid, pInterfaceType, pReturn, ppArgs,
+ ppException );
+}
+void SAL_CALL urp_sendRequest_internal(
+ uno_Environment *pEnvRemote,
+ typelib_TypeDescription const * pMemberType,
+ rtl_uString *pOid,
+ typelib_InterfaceTypeDescription *pInterfaceType,
+ void *pReturn,
+ void *ppArgs[],
+ uno_Any **ppException )
+{
+ remote_Context *pContext = (remote_Context *) pEnvRemote->pContext;
+ urp_BridgeImpl *pImpl = (urp_BridgeImpl*) ( pContext->m_pBridgeImpl );
+
+ ClientJob job(
+ pEnvRemote, pContext, pImpl, pOid, pMemberType, pInterfaceType, pReturn,
+ ppArgs, ppException);
+
+ if( job.pack() && ! job.isOneway() )
+ {
+ job.wait();
+ }
+}
+
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_dispatch.hxx b/bridges/source/remote/urp/urp_dispatch.hxx
new file mode 100644
index 000000000000..146732d339b2
--- /dev/null
+++ b/bridges/source/remote/urp/urp_dispatch.hxx
@@ -0,0 +1,80 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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 <typelib/typedescription.h>
+
+#include <uno/any2.h>
+
+
+typedef struct _uno_Environment uno_Environment;
+struct remote_Interface;
+
+
+
+namespace bridges_urp {
+
+ const sal_uInt8 HDRFLAG_LONGHEADER = 0x80;
+ const sal_uInt8 HDRFLAG_REQUEST = 0x40;
+ const sal_uInt8 HDRFLAG_NEWTYPE = 0x20;
+ const sal_uInt8 HDRFLAG_NEWOID = 0x10;
+ const sal_uInt8 HDRFLAG_NEWTID = 0x08;
+ const sal_uInt8 HDRFLAG_LONGMETHODID = 0x04;
+ const sal_uInt8 HDRFLAG_IGNORECACHE = 0x02;
+ const sal_uInt8 HDRFLAG_MOREFLAGS = 0x01;
+ const sal_uInt8 HDRFLAG_MUSTREPLY = 0x80;
+ const sal_uInt8 HDRFLAG_SYNCHRONOUS = 0x40;
+
+ const sal_uInt8 HDRFLAG_EXCEPTION = 0x20;
+
+ void SAL_CALL urp_sendCloseConnection( uno_Environment *pEnvRemote );
+
+ extern "C" void SAL_CALL urp_sendRequest(
+ uno_Environment *pEnvRemote,
+ typelib_TypeDescription const * pMemberType,
+ rtl_uString *pOid,
+ typelib_InterfaceTypeDescription *pInterfaceType,
+ void *pReturn,
+ void *ppArgs[],
+ uno_Any **ppException
+ );
+
+ void SAL_CALL urp_sendRequest_internal(
+ uno_Environment *pEnvRemote,
+ typelib_TypeDescription const * pMemberType,
+ rtl_uString *pOid,
+ typelib_InterfaceTypeDescription *pInterfaceType,
+ void *pReturn,
+ void *ppArgs[],
+ uno_Any **ppException
+ );
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_environment.cxx b/bridges/source/remote/urp/urp_environment.cxx
new file mode 100644
index 000000000000..9f13e60c35e4
--- /dev/null
+++ b/bridges/source/remote/urp/urp_environment.cxx
@@ -0,0 +1,554 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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_bridges.hxx"
+
+#include <stdio.h>
+
+#include <osl/interlck.h>
+#include <osl/diagnose.h>
+#include <osl/conditn.h>
+#include <osl/mutex.hxx>
+#include <osl/process.h>
+
+#include <rtl/alloc.h>
+#include <rtl/uuid.h>
+#include <rtl/unload.h>
+
+#include <uno/environment.h>
+#include <uno/lbnames.h>
+#include <uno/mapping.hxx>
+#include <uno/threadpool.h>
+
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <bridges/remote/proxy.hxx>
+#include <bridges/remote/stub.hxx>
+#include <bridges/remote/context.h>
+#include <bridges/remote/mapping.hxx>
+#include <bridges/remote/counter.hxx>
+#include <bridges/remote/bridgeimpl.hxx>
+#include <bridges/remote/helper.hxx>
+
+#include "urp_bridgeimpl.hxx"
+#include "urp_writer.hxx"
+#include "urp_reader.hxx"
+#include "urp_dispatch.hxx"
+#include "urp_log.hxx"
+#include "urp_propertyobject.hxx"
+
+using namespace ::rtl;
+using namespace ::osl;
+using namespace ::com::sun::star::uno;
+
+namespace bridges_urp
+{
+rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT;
+
+// static void dumpProperties( struct Properties *p )
+// {
+// fprintf( stderr , "FlushBlockSize : %d\n" , p->nFlushBlockSize );
+// fprintf( stderr , "OnewayTimeoutMUSEC : %d\n" , p->nOnewayTimeoutMUSEC );
+// fprintf( stderr , "OidCacheSize : %d\n" , p->nOidCacheSize );
+// fprintf( stderr , "TypeCacheSize : %d\n" , p->nTypeCacheSize );
+// fprintf( stderr , "TidCacheSize : %d\n" , p->nTidCacheSize );
+// OString o = OUStringToOString( p->sSupportedVersions , RTL_TEXTENCODING_ASCII_US );
+// fprintf( stderr , "SupportedVersions : %s\n" , o.pData->buffer );
+// o = OUStringToOString( p->sVersion , RTL_TEXTENCODING_ASCII_US );
+// fprintf( stderr , "Version : %s\n" , o.pData->buffer );
+// fprintf( stderr , "SupportsMultipleSynchronous : %d\n" , p->bSupportsMultipleSynchronous );
+// fprintf( stderr , "SupportsMustReply : %d\n" , p->bSupportsMustReply );
+// fprintf( stderr , "SupportsSynchronous : %d\n" , p->bSupportsSynchronous );
+// }
+
+// PropertySetterThread
+//------------------------------------
+class PropertySetterThread : public ::osl::Thread
+{
+ urp_BridgeImpl *m_pImpl;
+ ::rtl::OUString m_sProps;
+ uno_Environment *m_pEnvRemote;
+public:
+ PropertySetterThread( uno_Environment *pEnvRemote,
+ urp_BridgeImpl *pImpl,
+ const ::rtl::OUString & props )
+ : m_pImpl( pImpl )
+ , m_sProps( props )
+ , m_pEnvRemote( pEnvRemote )
+ {
+ if (m_sProps.getLength() > 0) {
+ m_sProps += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(","));
+ }
+ m_sProps += rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("CurrentContext="));
+ // hold the environment in case all references are released before this
+ // thread terminates
+ m_pEnvRemote->acquire( pEnvRemote );
+ }
+ ~PropertySetterThread()
+ {
+ m_pEnvRemote->release( m_pEnvRemote );
+ }
+
+ virtual void SAL_CALL run()
+ {
+ for (;;)
+ {
+ switch ( m_pImpl->m_pPropertyObject->localRequestChange( ) )
+ {
+ case 1:
+ sal_Bool bExceptionThrown;
+ m_pImpl->m_pPropertyObject->localCommitChange( m_sProps , &bExceptionThrown );
+ OSL_ENSURE( !bExceptionThrown, "properties were not set\n" );
+ goto done;
+ case 0:
+ OSL_TRACE( "urp-bridge : remote-counterpart won the changing-the-protocol-race\n" );
+ goto done;
+ }
+ }
+ done:
+ m_pImpl->m_initialized.set();
+ }
+ virtual void SAL_CALL onTerminated()
+ {
+ delete this;
+ }
+};
+//------------------------------------
+
+
+void test_cache()
+{
+ OUString a = OUString( RTL_CONSTASCII_USTRINGPARAM( "a" ) );
+ OUString b = OUString( RTL_CONSTASCII_USTRINGPARAM( "b" ) );
+ OUString c = OUString( RTL_CONSTASCII_USTRINGPARAM( "c" ) );
+ Cache < OUString , equalOUString > cache ( 2 );
+
+ sal_Int32 n = cache.put( a );
+ if (cache.seek( a ) != n)
+ {
+ OSL_ASSERT( false );
+ }
+ OSL_ASSERT( 0 == n );
+
+ n = cache.put( b );
+ OSL_ASSERT( 1 == n );
+
+ cache.put( c );
+
+ OSL_ASSERT( 0xffff == cache.seek( a ) );
+ OSL_ASSERT( 1 == cache.seek( b ) );
+ OSL_ASSERT( 0 == cache.seek( c ) );
+
+ OSL_ASSERT( 1 == cache.put( a ) );
+ OSL_ASSERT( 0xffff == cache.seek( b) );
+ OSL_ASSERT( 1 == cache.seek( a ) );
+ OSL_ASSERT( 0 == cache.seek( c ) );
+}
+
+/*******************
+ * Are we within thread, that calls destructors of static objects ?
+ *******************/
+sal_Bool g_bStaticDestructorsCalled = sal_False;
+struct StaticSingleton
+{
+ ~StaticSingleton()
+ {
+ ::osl::MutexGuard guard( ::osl::Mutex::getGlobalMutex() );
+ g_bStaticDestructorsCalled = sal_True;
+ }
+};
+StaticSingleton singleton;
+
+#if OSL_DEBUG_LEVEL > 1
+static MyCounter thisCounter( "Remote Environment" );
+#endif
+
+void SAL_CALL allThreadsAreGone( uno_Environment * pEnvRemote )
+{
+ remote_Context *pContext = (remote_Context *) pEnvRemote->pContext;
+ urp_BridgeImpl *pImpl = ( urp_BridgeImpl *) pContext->m_pBridgeImpl;
+
+ // if the current thread is not the writer thread, the writer thread
+ // object is not destroyed up to now, though it may already have run out.
+ // In both cases, it must be safe to cal pImpl->m_pWriter->getIdentifier()
+ OSL_ASSERT( pImpl->m_pWriter );
+ if( pImpl->m_pWriter->getIdentifier() == osl_getThreadIdentifier(0) )
+ {
+ // This is the writer thread. It has done some release calls,
+ // and is now the last one, that was active. Because the writer
+ // thread holds the environment weakly, there may also be a thread within
+ // the dispose of the bridge ( because the enviroment may have a refcount == 0 ).
+ // However, this thread MUST wait for the writer thread, so it is perfectly ok,
+ // not to set m_cndWaitForThreads. ( The check for m_nRemoteThreads is done
+ // after the join of the writer thread ).
+ }
+ else
+ {
+ pImpl->m_cndWaitForThreads.set();
+ }
+
+}
+
+void SAL_CALL releaseStubs( uno_Environment *pEnvRemote )
+{
+
+ ((remote_Context * ) pEnvRemote->pContext )->m_pBridgeImpl->m_bReleaseStubsCalled = sal_True;
+
+ remote_Interface **ppInterfaces = 0;
+ sal_Int32 nCount;
+ pEnvRemote->pExtEnv->getRegisteredInterfaces( pEnvRemote->pExtEnv,
+ (void***)&ppInterfaces,
+ &nCount,
+ rtl_allocateMemory );
+
+ sal_Int32 i;
+ for( i = 0 ; i < nCount ; i ++ )
+ {
+ if( ppInterfaces[i]->acquire == bridges_remote::acquireUno2RemoteStub )
+ {
+ // these are freed by the environment, so no release necessary
+ pEnvRemote->pExtEnv->revokeInterface( pEnvRemote->pExtEnv, ppInterfaces[i] );
+ }
+ else
+ {
+ ppInterfaces[i]->release( ppInterfaces[i] );
+ }
+ }
+
+ rtl_freeMemory( (void*) ppInterfaces );
+}
+
+} // end namespace bridges_urp
+
+using namespace bridges_urp;
+
+extern "C" {
+
+static void SAL_CALL RemoteEnvironment_thisDispose( uno_Environment *pEnvRemote )
+{
+ remote_Context *pContext = (remote_Context *) pEnvRemote->pContext;
+ urp_BridgeImpl *pImpl = ( urp_BridgeImpl *) pContext->m_pBridgeImpl;
+
+ ::osl::ClearableMutexGuard guard( pImpl->m_disposingMutex );
+ if( pContext->m_pBridgeImpl->m_bDisposed &&
+ ( ! pImpl->m_pReader ||
+ osl_getThreadIdentifier(0) ==
+ (oslThreadIdentifier) pImpl->m_pReader->getIdentifier() ) )
+ {
+ return;
+ }
+ // in case, that the static destructors already have been called, no
+ // tiding up is done.
+ bool tidyUp;
+ {
+ ::osl::MutexGuard guard2( ::osl::Mutex::getGlobalMutex() );
+ tidyUp = ! g_bStaticDestructorsCalled &&
+ ! pContext->m_pBridgeImpl->m_bDisposed;
+ }
+ if( tidyUp )
+ {
+ // TODO : not threadsafe
+ // synchronization with dispatch methods needed !
+
+ pImpl->m_bDisposed = sal_True;
+
+
+ // close the connection
+ uno_threadpool_dispose( pImpl->m_hThreadPool );
+ pImpl->m_pWriter->abortThread();
+ pContext->m_pConnection->close( pContext->m_pConnection );
+
+ if( osl_getThreadIdentifier(0) ==
+ (oslThreadIdentifier) pImpl->m_pReader->getIdentifier() )
+ {
+ // This is the reader thread. Let the thread destroy itself
+ // the reader thread object must also release the connection at this stage !
+ pImpl->m_pReader->destroyYourself();
+ pImpl->m_pReader = 0;
+ }
+ else
+ {
+ // wait for the reader thread
+ // the reader thread object must also release the connection,
+ // when terminating !!!!
+ pImpl->m_pReader->join();
+ }
+
+ // wait for the writer thread
+ pImpl->m_pWriter->join();
+
+ // now let the context go !
+ pContext->dispose( pContext );
+
+ if( 0 != pImpl->m_nRemoteThreads )
+ {
+ // Wait for all threads
+ guard.clear();
+ pImpl->m_cndWaitForThreads.wait();
+ OSL_ASSERT( ! pImpl->m_nRemoteThreads );
+ }
+ else
+ {
+ guard.clear();
+ }
+#ifdef BRIDGES_URP_PROT
+ if( pImpl->m_pLogFile )
+ {
+ fclose( pImpl->m_pLogFile );
+ pImpl->m_pLogFile = 0;
+ }
+#endif
+#if OSL_DEBUG_LEVEL > 1
+ pImpl->dumpErrors( stderr );
+#endif
+
+ // destroy the threads
+ delete pImpl->m_pWriter;
+ pImpl->m_pWriter = 0;
+
+ if( pImpl->m_pReader != 0 )
+ {
+ // This is not the reader thread, so the thread object is deleted
+ delete pImpl->m_pReader;
+ pImpl->m_pReader = 0;
+ }
+
+ bool bReleaseStubs = false;
+ {
+ ::osl::MutexGuard guard2( ::osl::Mutex::getGlobalMutex() );
+ bReleaseStubs = !g_bStaticDestructorsCalled;
+ }
+ if( bReleaseStubs )
+ {
+ releaseStubs( pEnvRemote );
+ }
+ }
+}
+
+static void SAL_CALL RemoteEnvironment_thisDisposing(
+ uno_Environment *pEnvRemote )
+{
+ remote_Context *pContext = (remote_Context * )pEnvRemote->pContext;
+ urp_BridgeImpl *pImpl = ((urp_BridgeImpl*) pContext->m_pBridgeImpl);
+
+ {
+ ::osl::ClearableMutexGuard guard( pImpl->m_disposingMutex );
+ if( ! pImpl->m_bDisposed )
+ {
+ guard.clear();
+ urp_sendCloseConnection( pEnvRemote );
+ RemoteEnvironment_thisDispose( pEnvRemote );
+ }
+ }
+ pImpl->m_pPropertyObject->thisRelease();
+ pImpl->m_pPropertyObject = 0;
+
+ uno_threadpool_destroy( pImpl->m_hThreadPool );
+
+ delete pImpl;
+ pContext->aBase.release( (uno_Context * ) pContext );
+ g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
+#if OSL_DEBUG_LEVEL > 1
+ thisCounter.release();
+#endif
+}
+
+static void SAL_CALL RemoteEnvironment_thisComputeObjectIdentifier(
+ uno_ExtEnvironment *, rtl_uString **, void *)
+{
+ OSL_ENSURE( 0, "RemoteEnvironment_thisComputeObjectIdentifier should never be called" );
+}
+
+static void SAL_CALL RemoteEnvironment_thisAcquireInterface(
+ uno_ExtEnvironment *, void *pInterface )
+{
+ ((remote_Interface *)pInterface)->acquire( ( remote_Interface *) pInterface );
+}
+
+static void SAL_CALL RemoteEnvironment_thisReleaseInterface(
+ uno_ExtEnvironment *, void *pInterface )
+{
+ ((remote_Interface *)pInterface)->release( ( remote_Interface *) pInterface );
+}
+
+//##################################################################################################
+void SAL_CALL uno_initEnvironment( uno_Environment * pEnvRemote )
+{
+ g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
+ // set C-virtual methods
+ pEnvRemote->environmentDisposing = RemoteEnvironment_thisDisposing;
+ pEnvRemote->pExtEnv->computeObjectIdentifier = RemoteEnvironment_thisComputeObjectIdentifier;
+ pEnvRemote->pExtEnv->acquireInterface = RemoteEnvironment_thisAcquireInterface;
+ pEnvRemote->pExtEnv->releaseInterface = RemoteEnvironment_thisReleaseInterface;
+ pEnvRemote->dispose = RemoteEnvironment_thisDispose;
+
+ remote_Context *pContext = ( remote_Context * ) pEnvRemote->pContext;
+ pContext->aBase.acquire( ( uno_Context * ) pContext );
+ pContext->getRemoteInstance = ::bridges_remote::remote_sendQueryInterface;
+
+ // Initialize impl struct urp_BridgeImpl
+ urp_BridgeImpl *pImpl = new ::bridges_urp::urp_BridgeImpl( 256, 8192 );
+ pContext->m_pBridgeImpl = pImpl;
+
+ // Initialize threadpool
+ pImpl->m_hThreadPool = uno_threadpool_create();
+
+ // take the bridgepointer as id
+ pImpl->m_properties.seqBridgeID = ByteSequence( (sal_Int8*)&pEnvRemote , sizeof( pEnvRemote ) );
+
+ pImpl->m_allThreadsAreGone = allThreadsAreGone;
+ pImpl->m_sendRequest = urp_sendRequest;
+ pImpl->m_nRemoteThreads = 0;
+ pImpl->m_bDisposed = sal_False;
+ pImpl->m_bReleaseStubsCalled = sal_False;
+
+ pImpl->m_pPropertyObject = new PropertyObject( &(pImpl->m_properties ), pEnvRemote, pImpl );
+ pImpl->m_pPropertyObject->thisAcquire();
+
+ OUString sProtocolProperties;
+ if( pContext->m_pProtocol->length > 3 )
+ {
+ sProtocolProperties = OUString( pContext->m_pProtocol ).copy( 4, pContext->m_pProtocol->length-4);
+ }
+ if( sProtocolProperties.getLength() )
+ {
+ struct Properties props = pImpl->m_properties;
+ assignFromStringToStruct( sProtocolProperties , &props );
+ if( ! props.bNegotiate )
+ {
+ // no negotiation takes place, the creator of the bridge knows the parameter
+ // of the other side !
+ pImpl->applyProtocolChanges( props );
+ sProtocolProperties = OUString();
+ }
+ }
+
+#ifdef BRIDGES_URP_PROT
+ char *p = getenv( "PROT_REMOTE" );
+ pImpl->m_pLogFile = 0;
+ if( p )
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ static int counter;
+ oslProcessInfo data;
+ data.Size = sizeof( data );
+ osl_getProcessInfo( 0 , osl_Process_HEAPUSAGE | osl_Process_IDENTIFIER , &data );
+ OString s(p);
+ s += "_pid";
+ s += OString::valueOf( (sal_Int32) data.Ident );
+ s += "_";
+ s += OString::valueOf( (sal_Int32) counter );
+ pImpl->m_sLogFileName = s;
+ // clear the file
+ FILE *f = fopen( s.getStr() , "w" );
+ OSL_ASSERT( f );
+ if( getenv( "PROT_REMOTE_FAST") )
+ {
+ pImpl->m_pLogFile = f;
+ }
+ else
+ {
+ fclose( f );
+ }
+ counter++;
+ }
+#endif
+
+ // start reader and writer threads
+ pImpl->m_pWriter = new ::bridges_urp::OWriterThread( pContext->m_pConnection , pImpl,
+ pEnvRemote);
+ pImpl->m_pWriter->create();
+
+ pImpl->m_pReader = new ::bridges_urp::OReaderThread( pContext->m_pConnection ,
+ pEnvRemote,
+ pImpl->m_pWriter );
+ pImpl->m_pReader->create();
+
+ PropertySetterThread *pPropsSetterThread =
+ new PropertySetterThread( pEnvRemote, pImpl , sProtocolProperties );
+ pPropsSetterThread->create();
+#if OSL_DEBUG_LEVEL > 1
+ thisCounter.acquire();
+#endif
+}
+
+
+//##################################################################################################
+void SAL_CALL uno_ext_getMapping(
+ uno_Mapping ** ppMapping,
+ uno_Environment * pFrom,
+ uno_Environment * pTo )
+{
+ OSL_ASSERT( ppMapping && pFrom && pTo );
+ if (ppMapping && pFrom && pTo)
+ {
+ if (*ppMapping)
+ ((*ppMapping)->release)( *ppMapping );
+ bridges_remote::RemoteMapping * pMapping = 0;
+
+ ::rtl::OUString sFromName = pFrom->pTypeName;
+ ::rtl::OUString sToName = pTo->pTypeName;
+ ::rtl::OUString sUno(RTL_CONSTASCII_USTRINGPARAM(UNO_LB_UNO));
+ ::rtl::OUString sRemote(RTL_CONSTASCII_USTRINGPARAM("urp"));
+ if ( sFromName.equalsIgnoreAsciiCase( sRemote ) &&
+ sToName.equalsIgnoreAsciiCase( sUno ) )
+ {
+ pMapping = new bridges_remote::RemoteMapping( pTo, /* Uno */
+ pFrom, /*remote*/
+ bridges_remote::remoteToUno,
+ OUString() );
+ }
+ else if ( sFromName.equalsIgnoreAsciiCase( sUno ) &&
+ sToName.equalsIgnoreAsciiCase( sRemote ) )
+ {
+ pMapping = new bridges_remote::RemoteMapping( pFrom ,
+ pTo ,
+ bridges_remote::unoToRemote,
+ OUString() );
+ }
+
+ *ppMapping = (uno_Mapping * )pMapping;
+ OUString dummy;
+ uno_registerMapping( ppMapping ,
+ bridges_remote::freeRemoteMapping,
+ pFrom ,
+ pTo ,
+ dummy.pData );
+ }
+}
+
+sal_Bool SAL_CALL component_canUnload( TimeValue *pTime )
+{
+ return g_moduleCount.canUnload( &g_moduleCount , pTime );
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_job.cxx b/bridges/source/remote/urp/urp_job.cxx
new file mode 100644
index 000000000000..62d43863276d
--- /dev/null
+++ b/bridges/source/remote/urp/urp_job.cxx
@@ -0,0 +1,941 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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_bridges.hxx"
+#include <string.h>
+#include <stdio.h>
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+
+#include <rtl/alloc.h>
+#include <rtl/ustrbuf.hxx>
+
+#include <uno/current_context.h>
+#include <uno/current_context.hxx>
+#include <uno/threadpool.h>
+
+#include <bridges/cpp_uno/type_misc.hxx>
+#include <bridges/remote/proxy.hxx>
+
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/XCurrentContext.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+
+#include "urp_job.hxx"
+#include "urp_bridgeimpl.hxx"
+#include "urp_writer.hxx"
+#include "urp_dispatch.hxx"
+#include "urp_log.hxx"
+#include "urp_marshal.hxx"
+#include "urp_propertyobject.hxx"
+#include "urp_reader.hxx"
+
+using namespace ::std;
+using namespace ::rtl;
+using namespace ::osl;
+using namespace ::com::sun::star::uno;
+
+using namespace bridges_urp;
+
+extern "C" {
+
+static void SAL_CALL doit(void * job) {
+ ServerMultiJob * p = static_cast< ServerMultiJob * >(job);
+ p->execute();
+ delete p;
+}
+
+}
+
+namespace bridges_urp
+{
+ static sal_Bool isDisposedExceptionDescriptionAvail( const Type &type )
+ {
+ static sal_Bool bInit;
+ static sal_Bool bReturn;
+ // we don't care for thread safety here, as both threads must come
+ // to the same result
+ if( ! bInit )
+ {
+ typelib_TypeDescription *pTD = 0;
+ typelib_typedescriptionreference_getDescription( & pTD, type.getTypeLibType() );
+ if( pTD )
+ {
+ bReturn = sal_True;
+ typelib_typedescription_release( pTD );
+ }
+ else
+ {
+ bReturn = sal_False;
+ }
+ bInit = sal_True;
+ }
+ return bReturn;
+ }
+
+ //--------------------------------------------------------------------------------------
+ static void prepareRuntimeExceptionClientSide( uno_Any **ppException , const OUString &s)
+ {
+ com::sun::star::lang::DisposedException exception( s , Reference< XInterface > () );
+ Type type = ::getCppuType( &exception );
+ if( !isDisposedExceptionDescriptionAvail( type ) )
+ {
+ // if it is not available (probably missing type library),
+ // then we are satisfied with throwing a normal runtime exception,
+ // for which cppu provides a static description
+ type = getCppuType( ( RuntimeException * ) 0 );
+ }
+ uno_type_any_construct( *ppException , &exception , type.getTypeLibType() , 0 );
+ }
+
+
+ Job::Job( uno_Environment *pEnvRemote,
+ remote_Context *pContext,
+ sal_Sequence *pTid,
+ struct urp_BridgeImpl *pBridgeImpl,
+ Unmarshal *pUnmarshal )
+ : m_pContext( pContext )
+ , m_pUnmarshal( pUnmarshal )
+ , m_pBridgeImpl( pBridgeImpl )
+ , m_pTid( pTid )
+ , m_counter( pEnvRemote )
+ {
+ if ( m_pContext )
+ {
+ m_pContext->aBase.acquire( &m_pContext->aBase );
+ }
+ if( m_pTid )
+ rtl_byte_sequence_acquire( pTid );
+ }
+
+ Job::~Job()
+ {
+ if( m_pTid )
+ rtl_byte_sequence_release( m_pTid );
+ if ( m_pContext )
+ {
+ m_pContext->aBase.release( &m_pContext->aBase );
+ }
+ }
+
+
+
+
+ //--------------------------------------------------------------------------------------
+ sal_Bool ClientJob::extract( )
+ {
+ sal_Bool bReturn = sal_True;
+ //-------------------------------
+ // Handle the reply, unpack data
+ //-------------------------------
+ if( m_bExceptionOccured )
+ {
+ bReturn = m_pUnmarshal->unpackAny( *m_ppException );
+ }
+ else
+ {
+ //---------------------------------
+ // alles ist gut
+ //---------------------------------
+ if( m_pMethodType )
+ {
+ if( m_pMethodType->pReturnTypeRef->eTypeClass != typelib_TypeClass_VOID )
+ {
+ typelib_TypeDescription *pType = 0;
+ TYPELIB_DANGER_GET( &pType , m_pMethodType->pReturnTypeRef );
+ bReturn = m_pUnmarshal->unpack( m_pReturn , pType ) && bReturn;
+ TYPELIB_DANGER_RELEASE( pType );
+ }
+
+ // out parameters
+ sal_Int32 i;
+ for( i = 0 ; i < m_pMethodType->nParams ; i ++ )
+ {
+ if( m_pMethodType->pParams[i].bOut )
+ {
+ typelib_TypeDescription *pType = 0;
+ TYPELIB_DANGER_GET( &pType , m_pMethodType->pParams[i].pTypeRef );
+ if( m_pMethodType->pParams[i].bIn )
+ {
+ uno_destructData( m_ppArgs[i] , pType , ::bridges_remote::remote_release );
+ }
+ bReturn = m_pUnmarshal->unpack( m_ppArgs[i] , pType ) && bReturn;
+ TYPELIB_DANGER_RELEASE( pType );
+ }
+ }
+ }
+ else if( m_pAttributeType && m_pReturn )
+ {
+ typelib_TypeDescription *pType = 0;
+ TYPELIB_DANGER_GET( &pType , m_pAttributeType->pAttributeTypeRef );
+ bReturn = m_pUnmarshal->unpack( m_pReturn , pType ) && bReturn;
+ TYPELIB_DANGER_RELEASE( pType );
+ }
+ else if( m_pAttributeType && m_ppArgs )
+ {
+ // nothing to do
+ }
+ else
+ {
+ OSL_ASSERT( 0 );
+ }
+ }
+ return bReturn;
+ }
+
+ //-------------------------------------------------------------------------------------------
+ void ClientJob::initiate()
+ {
+ uno_threadpool_putJob( m_pBridgeImpl->m_hThreadPool, m_pTid , this, 0, sal_False);
+ }
+
+ //--------------------------------------------------------------------------------------------
+ sal_Bool ClientJob::pack()
+ {
+ sal_Bool bSuccess = sal_True;
+ MutexGuard guard( m_pBridgeImpl->m_marshalingMutex );
+
+ if( m_pMethodType &&
+ REMOTE_RELEASE_METHOD_INDEX == m_pMethodType->aBase.nPosition &&
+ ! m_pBridgeImpl->m_bDisposed &&
+ m_pBridgeImpl->m_pWriter->getIdentifier() != ::osl::Thread::getCurrentIdentifier() )
+ {
+ // all release calls are delegated to the writer thread to avoid
+ // multiple synchron calls with the same thread id and reentrant
+ // marshaling (in case during destruction of parameters a release is
+ // invoked ).
+ m_pBridgeImpl->m_pWriter->insertReleaseRemoteCall(
+ m_pOid, m_pInterfaceType->aBase.pWeakRef );
+
+ // No waiting, please
+ return sal_False;
+ }
+ else if ( m_pMethodType &&
+ REMOTE_RELEASE_METHOD_INDEX == m_pMethodType->aBase.nPosition &&
+ m_pBridgeImpl->m_bDisposed )
+ {
+ // no exception for release calls !
+ return sal_False;
+ }
+ else if( m_pBridgeImpl->m_bDisposed )
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "URP-Bridge: disposed" ) );
+ buf.append( m_pBridgeImpl->getErrorsAsString() );
+ prepareRuntimeExceptionClientSide( m_ppException , buf.makeStringAndClear() );
+ return sal_False;
+ }
+
+ // build up the flag byte
+ sal_Bool bType = sal_False, bOid = sal_False, bTid = sal_False;
+ sal_uInt8 nFlags = 0;
+ if( m_pBridgeImpl->m_lastOutType.getTypeLibType() != m_pInterfaceType->aBase.pWeakRef &&
+ ! typelib_typedescriptionreference_equals(
+ m_pBridgeImpl->m_lastOutType.getTypeLibType(), m_pInterfaceType->aBase.pWeakRef ) )
+ {
+ //new type
+ nFlags = nFlags | HDRFLAG_NEWTYPE;
+ bType = sal_True;
+ }
+ if( m_pBridgeImpl->m_lastOutOid.pData != m_pOid &&
+ rtl_ustr_compare_WithLength( m_pBridgeImpl->m_lastOutOid.pData->buffer,
+ m_pBridgeImpl->m_lastOutOid.pData->length,
+ m_pOid->buffer,
+ m_pOid->length ) )
+ {
+ //new object id
+ nFlags = nFlags | HDRFLAG_NEWOID;
+ bOid = sal_True;
+ }
+ if( m_pBridgeImpl->m_lastOutTid.getHandle() != m_pTid &&
+ !(m_pBridgeImpl->m_lastOutTid == *(ByteSequence*) &(m_pTid) ) )
+ {
+ // new threadid
+ nFlags = nFlags | HDRFLAG_NEWTID;
+ bTid = sal_True;
+ }
+
+ if( m_bCallingConventionForced )
+ {
+ nFlags = nFlags | HDRFLAG_MOREFLAGS;
+ }
+#ifdef BRIDGES_URP_PROT
+ sal_Int32 nLogStart = m_pBridgeImpl->m_blockMarshaler.getPos();
+#endif
+ // Short request headers can only handle 14-bit method IDs, so
+ // unconditionally use a long header for method IDs that are too large:
+ if( nFlags || m_nMethodIndex >= 0xC000 )
+ {
+ // the flag byte is needed + request
+ nFlags = nFlags | HDRFLAG_LONGHEADER | HDRFLAG_REQUEST; //
+
+ // as long as we do not have customized calls, no MOREFLAGS must be set
+ if( m_nMethodIndex >= 0x100 )
+ {
+ nFlags = nFlags | HDRFLAG_LONGMETHODID;
+ }
+ m_pBridgeImpl->m_blockMarshaler.packInt8( &nFlags );
+
+ if( nFlags & HDRFLAG_MOREFLAGS )
+ {
+ sal_uInt8 nMoreFlags = 0;
+ if( ! m_bOneway )
+ {
+ nMoreFlags = HDRFLAG_SYNCHRONOUS |HDRFLAG_MUSTREPLY;
+ }
+ m_pBridgeImpl->m_blockMarshaler.packInt8( &nMoreFlags );
+ }
+ if( nFlags & HDRFLAG_LONGMETHODID )
+ {
+ sal_uInt16 nMethod = (sal_uInt16 ) m_nMethodIndex;
+ m_pBridgeImpl->m_blockMarshaler.packInt16( &nMethod );
+ }
+ else
+ {
+ sal_uInt8 nMethod = (sal_uInt8) m_nMethodIndex;
+ m_pBridgeImpl->m_blockMarshaler.packInt8( &nMethod );
+ }
+ }
+ else
+ {
+ // no flag byte needed, simply marshal the method index
+ if( m_nMethodIndex >= 64 )
+ {
+ sal_uInt16 nMethod = ( sal_uInt16 ) m_nMethodIndex;
+ nMethod = nMethod | 0x4000;
+ m_pBridgeImpl->m_blockMarshaler.packInt16( &nMethod );
+ }
+ else
+ {
+ sal_uInt8 nMethod = (sal_uInt8 ) m_nMethodIndex;
+ m_pBridgeImpl->m_blockMarshaler.packInt8( &nMethod );
+ }
+ }
+
+ // marshal type,oid,tid
+ if( bType )
+ {
+ m_pBridgeImpl->m_lastOutType = m_pInterfaceType->aBase.pWeakRef;
+ m_pBridgeImpl->m_blockMarshaler.packType( &(m_pBridgeImpl->m_lastOutType) );
+ }
+ if( bOid )
+ {
+ m_pBridgeImpl->m_lastOutOid = *(OUString *)&m_pOid;
+ m_pBridgeImpl->m_blockMarshaler.packOid( m_pBridgeImpl->m_lastOutOid );
+ }
+ if( bTid )
+ {
+ m_pBridgeImpl->m_lastOutTid = *(ByteSequence*)&(m_pTid);
+ m_pBridgeImpl->m_blockMarshaler.packTid( m_pBridgeImpl->m_lastOutTid );
+ }
+
+ if ( m_pBridgeImpl->m_properties.bCurrentContext
+ && m_nMethodIndex != REMOTE_RELEASE_METHOD_INDEX
+ && m_pContext != 0 )
+ {
+ void * pCc = 0;
+ rtl::OUString aEnvName( RTL_CONSTASCII_USTRINGPARAM( "urp" ) );
+ bSuccess = bSuccess && uno_getCurrentContext(
+ &pCc, aEnvName.pData, m_pContext );
+ typelib_TypeDescription * pType = 0;
+ TYPELIB_DANGER_GET(
+ &pType, XCurrentContext::static_type().getTypeLibType() );
+ bSuccess = bSuccess && m_pBridgeImpl->m_blockMarshaler.pack(
+ &pCc, pType );
+ TYPELIB_DANGER_RELEASE( pType );
+ if ( pCc )
+ {
+ remote_Interface * p = static_cast< remote_Interface * >( pCc );
+ p->release( p );
+ }
+ }
+
+ // marshal arguments !
+#ifdef BRIDGES_URP_PROT
+ sal_Int32 nLogHeader = m_pBridgeImpl->m_blockMarshaler.getPos();
+#endif
+ if( m_pMethodType )
+ {
+ sal_Int32 i;
+ for( i = 0 ; i < m_pMethodType->nParams ; i ++ )
+ {
+ if( m_pMethodType->pParams[i].bIn )
+ {
+ typelib_TypeDescription *pType = 0;
+ TYPELIB_DANGER_GET( &pType , m_pMethodType->pParams[i].pTypeRef );
+ if( pType )
+ {
+ bSuccess =
+ bSuccess && m_pBridgeImpl->m_blockMarshaler.pack( m_ppArgs[i] , pType );
+ TYPELIB_DANGER_RELEASE( pType );
+ }
+ else
+ {
+ bSuccess = sal_False;
+ OUStringBuffer buffer( 128 );
+ buffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( "no typedescription available for type" ) );
+ buffer.append( m_pMethodType->pParams[i].pTypeRef->pTypeName );
+ m_pBridgeImpl->addError( buffer.makeStringAndClear() );
+ }
+ }
+ }
+ }
+ else if( m_pAttributeType && m_pReturn )
+ {
+ // nothing to do !
+ }
+ else if( m_pAttributeType && m_ppArgs )
+ {
+ typelib_TypeDescription *pType = 0;
+ TYPELIB_DANGER_GET( &pType , m_pAttributeType->pAttributeTypeRef );
+ if( pType )
+ {
+ bSuccess = bSuccess && m_pBridgeImpl->m_blockMarshaler.pack( m_ppArgs[0] , pType );
+ TYPELIB_DANGER_RELEASE( pType );
+ }
+ else
+ {
+ bSuccess = sal_False;
+ OUStringBuffer buffer( 128 );
+ buffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( "no typedescription available for type" ) );
+ buffer.append( m_pAttributeType->pAttributeTypeRef->pTypeName );
+ m_pBridgeImpl->addError( buffer.makeStringAndClear() );
+ }
+ }
+ else
+ {
+ OSL_ASSERT( 0 );
+ }
+
+#ifdef BRIDGES_URP_PROT
+ urp_logCall( m_pBridgeImpl, m_pBridgeImpl->m_blockMarshaler.getPos() - nLogStart,
+ m_pBridgeImpl->m_blockMarshaler.getPos() - nLogHeader, ! m_bOneway,
+ m_pMethodType ? m_pMethodType->aBase.pMemberName :
+ m_pAttributeType->aBase.pMemberName );
+#endif
+
+ if( bSuccess )
+ {
+ if( ! m_bOneway )
+ {
+ uno_threadpool_attach( m_pBridgeImpl->m_hThreadPool );
+ m_pBridgeImpl->m_clientJobContainer.add( *(ByteSequence*)&(m_pTid), this );
+ }
+
+ m_pBridgeImpl->m_nMarshaledMessages ++;
+ //---------------------------
+ // Inform the writer thread, that there is some work to do
+ //---------------------------
+ m_pBridgeImpl->m_pWriter->touch( ! m_bOneway );
+
+ if( m_bOneway )
+ {
+ *m_ppException = 0;
+ }
+ }
+ else
+ {
+ // Something went wrong during packing, which means, that the caches may not be in sync
+ // anymore. So we have no other choice than to dispose the environment.
+ m_pEnvRemote->dispose( m_pEnvRemote );
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "Error during marshaling " ) );
+ if( m_pMethodType )
+ {
+ buf.append( m_pMethodType->aBase.aBase.pTypeName );
+ }
+ else if( m_pAttributeType )
+ {
+ buf.append( m_pAttributeType->aBase.aBase.pTypeName );
+ }
+ buf.appendAscii( "\n" );
+ buf.append( m_pBridgeImpl->getErrorsAsString() );
+ prepareRuntimeExceptionClientSide( m_ppException , buf.makeStringAndClear() );
+ }
+ return bSuccess;
+ // release the guard
+ }
+
+ //------------------------------------------------------------------------------------
+ void ClientJob::wait()
+ {
+ //---------------------------
+ // Wait for the reply
+ //---------------------------
+ void * pDisposeReason = 0;
+
+ uno_threadpool_enter(m_pBridgeImpl->m_hThreadPool, &pDisposeReason );
+
+ if( ! pDisposeReason )
+ {
+ // thread has been disposed !
+ // avoid leak due continous calling on a disposed reference. The
+ // reply may or may not be within the container. If the reader thread
+ // got into problems during unmarshaling the reply for this request,
+ // it won't be in the container anymore, but it is eiterway safe to call
+ // the method
+ ClientJob *pJob =
+ m_pBridgeImpl->m_clientJobContainer.remove( *(ByteSequence*) &m_pTid );
+ if( pJob != this )
+ {
+ // this is not our job, it is probably one of the callstack below, so
+ // push it back
+ m_pBridgeImpl->m_clientJobContainer.add( *(ByteSequence*) &m_pTid , pJob );
+ }
+
+ OUStringBuffer sMessage( 256 );
+ sMessage.appendAscii( RTL_CONSTASCII_STRINGPARAM( "URP_Bridge : disposed\n" ) );
+ sMessage.append( m_pBridgeImpl->getErrorsAsString() );
+ prepareRuntimeExceptionClientSide( m_ppException, sMessage.makeStringAndClear() );
+ m_bExceptionOccured = sal_True;
+ }
+ else
+ {
+ OSL_ASSERT( pDisposeReason == (void*)this );
+ }
+ if( !m_bExceptionOccured )
+ {
+ *m_ppException = 0;
+ }
+ uno_threadpool_detach( m_pBridgeImpl->m_hThreadPool );
+ }
+
+ //------------------------------------------------------------------------------------
+ // ServerMultiJob
+ //------------------------------------------------------------------------------------
+ ServerMultiJob::ServerMultiJob(
+ uno_Environment *pEnvRemote,
+ remote_Context *pContext,
+ sal_Sequence *pTid,
+ struct urp_BridgeImpl *pBridgeImpl,
+ Unmarshal *pUnmarshal,
+ sal_Int32 nMaxMessages )
+ : Job( pEnvRemote, pContext, pTid, pBridgeImpl, pUnmarshal )
+ , m_pEnvRemote( pEnvRemote )
+ , m_nCalls( 0 )
+ , m_nMaxMessages( nMaxMessages )
+ , m_nCurrentMemPosition( 0 )
+ {
+ m_pEnvRemote->acquire( m_pEnvRemote );
+ m_nCurrentMemSize = MULTIJOB_STANDARD_MEMORY_SIZE + m_nMaxMessages * (
+ MULTIJOB_PER_CALL_MEMORY_SIZE + sizeof(ServerJobEntry) + sizeof(MemberTypeInfo) );
+ m_pCurrentMem = ( sal_Int8 * ) rtl_allocateMemory( m_nCurrentMemSize );
+ m_aEntries = ( ServerJobEntry * ) getHeap( m_nMaxMessages * sizeof( ServerJobEntry ) );
+ m_aTypeInfo = ( MemberTypeInfo * ) getHeap( m_nMaxMessages * sizeof( MemberTypeInfo ) );
+ }
+
+ ServerMultiJob::~ServerMultiJob()
+ {
+ sal_Int32 i;
+ for( i = 0 ; i < m_nCalls ; i ++ )
+ {
+ struct MemberTypeInfo *const pMTI = &( m_aTypeInfo[i] );
+ struct ServerJobEntry *const pSJE = &( m_aEntries[i] );
+
+ if( pSJE->m_pRemoteI )
+ pSJE->m_pRemoteI->release( pSJE->m_pRemoteI );
+
+ if( pSJE->m_pOid )
+ rtl_uString_release( pSJE->m_pOid );
+
+ if( pSJE->m_pInterfaceTypeRef )
+ typelib_typedescriptionreference_release( pSJE->m_pInterfaceTypeRef );
+
+ if( pMTI->m_pInterfaceType )
+ TYPELIB_DANGER_RELEASE( (typelib_TypeDescription *)pMTI->m_pInterfaceType );
+
+ for( sal_Int32 iArgs = 0 ; iArgs < pMTI->m_nArgCount ; iArgs ++ )
+ {
+ if( pMTI->m_ppArgType[iArgs] )
+ TYPELIB_DANGER_RELEASE( pMTI->m_ppArgType [iArgs] );
+ }
+ if( pMTI->m_pReturnType )
+ TYPELIB_DANGER_RELEASE( pMTI->m_pReturnType );
+
+ if( pMTI->m_pMethodType )
+ typelib_typedescription_release( (typelib_TypeDescription*)pMTI->m_pMethodType );
+ if( pMTI->m_pAttributeType )
+ typelib_typedescription_release( (typelib_TypeDescription*)pMTI->m_pAttributeType );
+ }
+
+ rtl_freeMemory( m_pCurrentMem );
+ for( list< sal_Int8 *>::iterator ii = m_lstMem.begin() ; ii != m_lstMem.end() ; ++ii )
+ rtl_freeMemory( *ii );
+
+ if( m_pEnvRemote )
+ m_pEnvRemote->release( m_pEnvRemote );
+ }
+
+ //-------------------------------------------------------------------------------------
+ void ServerMultiJob::execute()
+ {
+ Reference< XCurrentContext > xOldCc;
+ bool bHasOldCc = false;
+ for( sal_Int32 i = 0; i < m_nCalls ; i ++ )
+ {
+ struct MemberTypeInfo * const pMTI = &( m_aTypeInfo[i] );
+ struct ServerJobEntry * const pSJE = &( m_aEntries[i] );
+
+ if ( pSJE->m_bHasCurrentContext )
+ {
+ if ( !bHasOldCc )
+ {
+ xOldCc = com::sun::star::uno::getCurrentContext();
+ bHasOldCc = true;
+ }
+ rtl::OUString aEnvName( RTL_CONSTASCII_USTRINGPARAM( "urp" ) );
+ if ( !uno_setCurrentContext(
+ pSJE->m_pCurrentContext, aEnvName.pData, m_pContext ) )
+ {
+ throw RuntimeException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "fatal: uno_setCurrentContext failed" ) ),
+ Reference< XInterface >() );
+ }
+ if ( pSJE->m_pCurrentContext )
+ {
+ pSJE->m_pCurrentContext->release( pSJE->m_pCurrentContext );
+ }
+ }
+
+ if( ! pSJE->m_pRemoteI )
+ {
+ // -------------------
+ // Initial object ?
+ // ------------------
+ // be robust : Sending a release on a not constructed object
+ // provokes an segfault. Make sure, the call
+ // is not a release call.
+ remote_Context *pRemoteC = ((remote_Context*)m_pEnvRemote->pContext);
+
+ if( ! pMTI->m_bIsReleaseCall && pRemoteC->m_pInstanceProvider )
+ {
+ pSJE->m_pException = &(pSJE->m_exception);
+
+ pRemoteC->m_pInstanceProvider->getInstance(
+ pRemoteC->m_pInstanceProvider,
+ m_pEnvRemote,
+ &(pSJE->m_pRemoteI),
+ pSJE->m_pOid,
+ pMTI->m_pInterfaceType,
+ &(pSJE->m_pException));
+ }
+ else
+ {
+ prepareRuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "urp: No instance provider set")),i);
+ }
+ }
+
+ if( pSJE->m_pException )
+ {
+ // errors during extracting, do nothing
+ }
+ else if( ! pSJE->m_pRemoteI )
+ {
+ // May only occur during the queryInterface call on the initial object !!!
+ // construct the return value
+ uno_type_any_construct( (uno_Any*) pSJE->m_pReturn , 0 , 0 , 0 );
+ }
+ else
+ {
+ pSJE->m_pException = &(pSJE->m_exception );
+
+ if( pMTI->m_bIsReleaseCall )
+ {
+ pSJE->m_pRemoteI->release( pSJE->m_pRemoteI );
+ pSJE->m_pException = 0;
+ }
+ else
+ {
+ pSJE->m_pRemoteI->pDispatcher(
+ pSJE->m_pRemoteI,
+ pMTI->m_pMethodType ? (typelib_TypeDescription*) pMTI->m_pMethodType :
+ (typelib_TypeDescription*) pMTI->m_pAttributeType,
+ pSJE->m_pReturn,
+ pSJE->m_ppArgs,
+ &(pSJE->m_pException) );
+ }
+ }
+ if( pSJE->m_pRemoteI )
+ {
+ /**
+ Do the release here, in case of ForceSynchronous=1, calls
+ originated by the destructor of an UNO object must be sent BEFORE the
+ release returns ( otherwise we don't own the thread anymore ! )
+ */
+ pSJE->m_pRemoteI->release( pSJE->m_pRemoteI );
+ pSJE->m_pRemoteI = 0;
+ }
+
+ // now destruct parameters and marshal replies
+ // Note : when call is synchron => m_nCalls == 1
+ if( pMTI->m_bIsOneway )
+ {
+ // Oneway call, destruct in parameters
+ for( sal_Int32 j = 0 ; j < pMTI->m_pMethodType->nParams ; j ++ )
+ {
+ // usually all parameters must be in parameters, but to be robust ...
+ if( pMTI->m_pbIsIn[j] && !cppu_isSimpleType( pMTI->m_ppArgType[j] ) )
+ {
+ uno_destructData( pSJE->m_ppArgs[j] , pMTI->m_ppArgType[j] , 0 );
+ }
+ }
+
+ if( pSJE->m_pException )
+ {
+ uno_any_destruct( pSJE->m_pException, ::bridges_remote::remote_release );
+ }
+
+ }
+ else
+ {
+ // synchron, get the mutex to marshal reply and send immeadiatly
+ MutexGuard guard( m_pBridgeImpl->m_marshalingMutex );
+
+ sal_Bool bTid = sal_False;
+ sal_uInt8 nFlags = HDRFLAG_LONGHEADER;
+ ByteSequence tid = m_pTid;
+ if( !( tid == m_pBridgeImpl->m_lastOutTid ) || pSJE->m_bIgnoreCache )
+ {
+ // new threadid
+ nFlags = nFlags | HDRFLAG_NEWTID;
+ bTid = sal_True;
+ }
+
+ if( pSJE->m_pException )
+ {
+ nFlags = nFlags | HDRFLAG_EXCEPTION;
+ }
+#ifdef BRIDGES_URP_PROT
+ sal_Int32 nLogStart = m_pBridgeImpl->m_blockMarshaler.getPos();
+#endif
+ m_pBridgeImpl->m_blockMarshaler.packInt8( &nFlags );
+
+ if( bTid )
+ {
+ if( ! pSJE->m_bIgnoreCache )
+ {
+ m_pBridgeImpl->m_lastOutTid = tid;
+ }
+ m_pBridgeImpl->m_blockMarshaler.packTid( tid , pSJE->m_bIgnoreCache );
+ }
+
+#ifdef BRIDGES_URP_PROT
+ sal_Int32 nLogHeader = m_pBridgeImpl->m_blockMarshaler.getPos();
+#endif
+
+ if( pSJE->m_pException )
+ {
+ //--------------------
+ // an exception was thrown
+ //--------------------
+ m_pBridgeImpl->m_blockMarshaler.packAny( &(pSJE->m_exception) );
+ uno_any_destruct( &(pSJE->m_exception) , ::bridges_remote::remote_release );
+
+ // destroy in parameters
+ for( sal_Int32 j = 0 ; j < pMTI->m_nArgCount ; j ++ )
+ {
+ if( pMTI->m_pbIsIn[j] && ! cppu_isSimpleType( pMTI->m_ppArgType[j] ))
+ {
+ uno_destructData( pSJE->m_ppArgs[j] , pMTI->m_ppArgType[j] ,
+ ::bridges_remote::remote_release );
+ }
+ }
+ }
+ else
+ {
+ //---------------------------
+ // alles ist gut ...
+ //--------------------------
+ if( pMTI->m_pReturnType )
+ {
+ m_pBridgeImpl->m_blockMarshaler.pack(
+ pSJE->m_pReturn, pMTI->m_pReturnType );
+ if( ! cppu_isSimpleType( pMTI->m_pReturnType ) )
+ {
+ uno_destructData( pSJE->m_pReturn , pMTI->m_pReturnType ,
+ ::bridges_remote::remote_release );
+ }
+ }
+ for( sal_Int32 j = 0 ; j < pMTI->m_nArgCount ; j ++ )
+ {
+ if( pMTI->m_pbIsOut[j] )
+ {
+ m_pBridgeImpl->m_blockMarshaler.pack(
+ pSJE->m_ppArgs[j] , pMTI->m_ppArgType[j] );
+ }
+ if( ! cppu_isSimpleType( pMTI->m_ppArgType[j] ) )
+ {
+ uno_destructData( pSJE->m_ppArgs[j], pMTI->m_ppArgType[j] ,
+ ::bridges_remote::remote_release );
+ }
+ }
+ }
+
+#ifdef BRIDGES_URP_PROT
+ {
+ typelib_InterfaceMemberTypeDescription *pMemberType =
+ pMTI->m_pMethodType ?
+ (typelib_InterfaceMemberTypeDescription*)pMTI->m_pMethodType :
+ (typelib_InterfaceMemberTypeDescription*)pMTI->m_pAttributeType;
+
+ urp_logReplying( m_pBridgeImpl ,
+ m_pBridgeImpl->m_blockMarshaler.getPos() - nLogStart,
+ m_pBridgeImpl->m_blockMarshaler.getPos() - nLogHeader,
+ pMemberType->pMemberName );
+ }
+#endif
+
+ m_pBridgeImpl->m_nMarshaledMessages ++;
+ // put it on the wire
+ m_pBridgeImpl->m_pWriter->touch( sal_True );
+ } // MutexGuard marshalingMutex
+ }
+ if ( bHasOldCc )
+ {
+ if ( !com::sun::star::uno::setCurrentContext( xOldCc ) )
+ {
+ throw RuntimeException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "fatal: com::sun::star::uno::setCurrentContext"
+ " failed" ) ),
+ Reference< XInterface >() );
+ }
+ }
+ }
+
+ //-------------------------------------------------------------------------------------
+ void ServerMultiJob::prepareRuntimeException( const OUString & sMessage , sal_Int32 nCall )
+ {
+ // -------------------------------
+ // Construct the DisposedException
+ // -------------------------------
+ com::sun::star::lang::DisposedException exception( sMessage , Reference< XInterface > () );
+ Type type = getCppuType( &exception );
+ if( !isDisposedExceptionDescriptionAvail( type ) )
+ {
+ // if it is not available (probably missing type library),
+ // then we are satisfied with throwing a normal runtime exception,
+ // for which cppu provides a static description
+ type = getCppuType( ( RuntimeException * ) 0 );
+ }
+
+ m_aEntries[nCall].m_pException = &(m_aEntries[nCall].m_exception);
+ uno_type_any_construct( m_aEntries[nCall].m_pException , &exception , type.getTypeLibType() , 0 );
+ }
+
+ //-------------------------------------------------------------------------------------
+ void ServerMultiJob::initiate()
+ {
+ uno_threadpool_putJob(
+ m_pBridgeImpl->m_hThreadPool,
+ m_pTid,
+ this,
+ doit,
+ m_aTypeInfo[0].m_bIsOneway );
+ }
+
+
+ //-------------------------------------------------------------------------------------
+ sal_Bool ServerMultiJob::extract()
+ {
+ sal_Bool bContinue = sal_True;
+ struct MemberTypeInfo * const pMTI = &(m_aTypeInfo[m_nCalls]);
+ struct ServerJobEntry * const pSJE = &(m_aEntries[m_nCalls]);
+
+ pSJE->m_pException = 0;
+ pSJE->m_ppArgs = 0;
+ pSJE->m_pReturn = 0;
+ pMTI->m_pReturnType = 0;
+
+ if( pMTI->m_nArgCount )
+ {
+ pMTI->m_ppArgType =
+ ( typelib_TypeDescription ** ) getHeap( sizeof(void*) * pMTI->m_nArgCount );
+ pSJE->m_ppArgs = (void**) getHeap( sizeof( void * ) * pMTI->m_nArgCount );
+ pMTI->m_pbIsIn = (sal_Bool *) getHeap( sizeof( sal_Bool ) * pMTI->m_nArgCount );
+ pMTI->m_pbIsOut = (sal_Bool *) getHeap( sizeof( sal_Bool ) * pMTI->m_nArgCount );
+ }
+ if( pMTI->m_pMethodType &&
+ pMTI->m_pMethodType->pReturnTypeRef->eTypeClass != typelib_TypeClass_VOID )
+ {
+ TYPELIB_DANGER_GET( &(pMTI->m_pReturnType), pMTI->m_pMethodType->pReturnTypeRef );
+ }
+ else if( pMTI->m_pAttributeType && ! pMTI->m_nArgCount )
+ {
+ TYPELIB_DANGER_GET( &(pMTI->m_pReturnType) , pMTI->m_pAttributeType->pAttributeTypeRef );
+ }
+
+ // normal method
+ if( pMTI->m_pMethodType )
+ {
+ for( sal_Int32 i = 0 ; i < pMTI->m_nArgCount ; i ++ )
+ {
+ pMTI->m_ppArgType[i] = 0;
+ TYPELIB_DANGER_GET( & ( pMTI->m_ppArgType[i] ) , pMTI->m_pMethodType->pParams[i].pTypeRef);
+ pMTI->m_pbIsIn[i] = pMTI->m_pMethodType->pParams[i].bIn;
+ pMTI->m_pbIsOut[i] = pMTI->m_pMethodType->pParams[i].bOut;
+
+ pSJE->m_ppArgs[i] = getHeap( pMTI->m_ppArgType[i]->nSize );
+ if( pMTI->m_pbIsIn[i] )
+ {
+ // everything needs to be constructed
+ bContinue = m_pUnmarshal->unpack(
+ pSJE->m_ppArgs[i], pMTI->m_ppArgType[i] ) && bContinue;
+ }
+ }
+ }
+ else if( pMTI->m_nArgCount )
+ {
+ // set attribut
+ pMTI->m_ppArgType[0] = 0;
+ pMTI->m_pbIsIn[0] = sal_True;
+ pMTI->m_pbIsOut[0] = sal_False;
+ TYPELIB_DANGER_GET(
+ & ( pMTI->m_ppArgType[0] ) , pMTI->m_pAttributeType->pAttributeTypeRef );
+ pSJE->m_ppArgs[0] = getHeap( pMTI->m_ppArgType[0]->nSize );
+ bContinue = m_pUnmarshal->unpack(
+ pSJE->m_ppArgs[0], pMTI->m_ppArgType[0] ) && bContinue;
+ }
+
+ if( pMTI->m_pReturnType )
+ {
+ pSJE->m_pReturn = getHeap( pMTI->m_pReturnType->nSize );
+ }
+
+ m_nCalls ++;
+ return bContinue;
+ }
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_job.hxx b/bridges/source/remote/urp/urp_job.hxx
new file mode 100644
index 000000000000..08bc43f89184
--- /dev/null
+++ b/bridges/source/remote/urp/urp_job.hxx
@@ -0,0 +1,381 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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 _URP_JOB_HXX_
+#define _URP_JOB_HXX_
+#include <list>
+#include <typelib/typedescription.hxx>
+#include <uno/any2.h>
+#include <uno/environment.h>
+#include <uno/threadpool.h>
+#include "urp_threadid.hxx"
+#include "urp_unmarshal.hxx"
+#include "urp_bridgeimpl.hxx"
+
+
+namespace bridges_urp
+{
+const sal_Int32 MULTIJOB_STANDARD_MEMORY_SIZE = 1024;
+const sal_Int32 MULTIJOB_PER_CALL_MEMORY_SIZE = 96;
+
+class Unmarshal;
+struct urp_BridgeImpl;
+
+template < class t >
+inline t mymax( const t &t1 , const t &t2 )
+{
+ return t1 > t2 ? t1 : t2;
+}
+
+class Job
+{
+public:
+ Job( uno_Environment *pEnvRemote,
+ remote_Context *pContext,
+ sal_Sequence *pTid,
+ struct urp_BridgeImpl *pBridgeImpl,
+ Unmarshal *pUnmarshal );
+
+ Job( uno_Environment *pEnvRemote,
+ remote_Context *pContext,
+ struct urp_BridgeImpl *pBridgeImpl,
+ ::bridges_remote::RemoteThreadCounter_HoldEnvWeak value )
+ : m_pContext( pContext )
+ , m_pBridgeImpl( pBridgeImpl )
+ , m_pTid( 0 )
+ , m_counter( pEnvRemote , value )
+ {
+ if ( m_pContext )
+ {
+ m_pContext->aBase.acquire( &m_pContext->aBase );
+ }
+ }
+
+ ~Job();
+
+public:
+ remote_Context *m_pContext;
+ Unmarshal *m_pUnmarshal;
+ struct urp_BridgeImpl *m_pBridgeImpl;
+ sal_Sequence *m_pTid;
+ ::bridges_remote::RemoteThreadCounter m_counter;
+};
+
+class ClientJob : private Job
+{
+public:
+ // pContext is null for bridge-internal UrpProtocolProperties requests
+ inline ClientJob( uno_Environment *pEnvRemote, // weak !
+ remote_Context *pContext,
+ struct urp_BridgeImpl *pBridgeImpl,
+ rtl_uString *pOid, // weak
+ typelib_TypeDescription const * pMemberType, // weak
+ typelib_InterfaceTypeDescription *pInterfaceType, // weak
+ void *pReturn,
+ void *ppArgs[],
+ uno_Any **ppException );
+
+ // ~ClientJob
+ // no release for method type and attribute type necessary, because
+ // it was acquired by the caller of urp_sendRequest. The lifetime
+ // of the ClientJob object is always shorter than the urp_sendRequest call.
+ inline ~ClientJob()
+ {
+ if( m_bReleaseForTypeDescriptionNecessary )
+ typelib_typedescription_release( (typelib_TypeDescription*) m_pInterfaceType );
+ uno_releaseIdFromCurrentThread();
+ }
+
+ sal_Bool pack();
+ void wait();
+ sal_Bool extract( );
+ void initiate();
+
+ inline void setBridgePropertyCall()
+ { m_bBridgePropertyCall = sal_True; }
+ inline sal_Bool isBridgePropertyCall()
+ { return m_bBridgePropertyCall; }
+ inline sal_Bool isOneway()
+ { return m_bOneway; }
+
+ inline void setUnmarshal( Unmarshal *p )
+ { m_pUnmarshal = p; }
+public:
+ typelib_InterfaceMethodTypeDescription *m_pMethodType;
+ typelib_InterfaceAttributeTypeDescription *m_pAttributeType;
+ sal_Bool m_bExceptionOccured;
+
+private:
+ void **m_ppArgs;
+ void *m_pReturn;
+ typelib_InterfaceTypeDescription *m_pInterfaceType;
+ sal_Bool m_bReleaseForTypeDescriptionNecessary;
+
+ uno_Any **m_ppException;
+ sal_Bool m_bOneway;
+ sal_Bool m_bBridgePropertyCall;
+ sal_uInt16 m_nMethodIndex;
+ uno_Environment *m_pEnvRemote;
+ rtl_uString *m_pOid;
+ sal_Bool m_bCallingConventionForced;
+};
+
+struct MemberTypeInfo
+{
+ typelib_InterfaceTypeDescription *m_pInterfaceType;
+ typelib_InterfaceMethodTypeDescription *m_pMethodType;
+ typelib_InterfaceAttributeTypeDescription *m_pAttributeType;
+ sal_Int32 m_nArgCount;
+ sal_Bool m_bIsReleaseCall;
+ sal_Bool *m_pbIsIn;
+ sal_Bool *m_pbIsOut;
+ sal_Bool m_bIsOneway;
+ typelib_TypeDescription *m_pReturnType;
+ typelib_TypeDescription **m_ppArgType;
+};
+
+
+struct ServerJobEntry
+{
+ rtl_uString *m_pOid;
+ remote_Interface *m_pRemoteI;
+ typelib_TypeDescriptionReference *m_pInterfaceTypeRef;
+ void **m_ppArgs;
+ void *m_pReturn;
+ uno_Any m_exception;
+ uno_Any *m_pException;
+ remote_Interface *m_pCurrentContext;
+ sal_Bool m_bHasCurrentContext;
+ sal_Bool m_bIgnoreCache;
+};
+
+class ServerMultiJob : private Job
+{
+public:
+ ServerMultiJob( uno_Environment *pEnvRemote,
+ remote_Context *pContext,
+ sal_Sequence *pTid,
+ struct urp_BridgeImpl *pBridgeImpl,
+ Unmarshal *pUnmarshal,
+ sal_Int32 nMaxMessages );
+ ~ServerMultiJob();
+public:
+ sal_Bool extract( );
+ void initiate();
+ void execute();
+
+public:
+ // setMethodType or setAttributeType MUST be called before extract
+ inline void setMethodType(
+ typelib_InterfaceMethodTypeDescription *pMethodType,
+ sal_Bool bIsReleaseCall,
+ sal_Bool bIsOneway )
+ {
+ m_aTypeInfo[m_nCalls].m_pMethodType = pMethodType;
+ m_aTypeInfo[m_nCalls].m_pAttributeType = 0;
+ m_aTypeInfo[m_nCalls].m_nArgCount = pMethodType->nParams;
+ m_aTypeInfo[m_nCalls].m_bIsReleaseCall = bIsReleaseCall;
+ m_aTypeInfo[m_nCalls].m_bIsOneway = bIsOneway;
+ }
+
+ inline void setAttributeType(
+ typelib_InterfaceAttributeTypeDescription *pAttributeType, sal_Bool bIsSetter, sal_Bool bIsOneway )
+ {
+ m_aTypeInfo[m_nCalls].m_pAttributeType = pAttributeType;
+ m_aTypeInfo[m_nCalls].m_pMethodType = 0;
+ m_aTypeInfo[m_nCalls].m_nArgCount = bIsSetter ? 1 : 0;
+ m_aTypeInfo[m_nCalls].m_bIsReleaseCall = sal_False;
+ m_aTypeInfo[m_nCalls].m_bIsOneway = bIsOneway;
+ }
+
+ inline void setType( typelib_TypeDescriptionReference *pTypeRef )
+ {
+ m_aEntries[m_nCalls].m_pInterfaceTypeRef = pTypeRef;
+ typelib_typedescriptionreference_acquire( m_aEntries[m_nCalls].m_pInterfaceTypeRef );
+ TYPELIB_DANGER_GET(
+ (typelib_TypeDescription ** )&(m_aTypeInfo[m_nCalls].m_pInterfaceType) ,
+ pTypeRef );
+ }
+ // setOid or setInterface MUST be called before extract
+ inline void setOid( rtl_uString *pOid )
+ {
+ m_aEntries[m_nCalls].m_pOid = pOid;
+ rtl_uString_acquire( m_aEntries[m_nCalls].m_pOid );
+ m_aEntries[m_nCalls].m_pRemoteI = 0;
+ }
+
+ // setOid or setInterface MUST be called
+ inline void setInterface( remote_Interface *pRemoteI )
+ {
+ m_aEntries[m_nCalls].m_pRemoteI = pRemoteI;
+ pRemoteI->acquire( pRemoteI );
+ m_aEntries[m_nCalls].m_pOid = 0;
+ }
+
+ inline void setCurrentContext(
+ bool bHasCurrentContext, remote_Interface *pCurrentContext )
+ {
+ m_aEntries[m_nCalls].m_pCurrentContext = pCurrentContext;
+ m_aEntries[m_nCalls].m_bHasCurrentContext = bHasCurrentContext;
+ }
+
+ inline void setIgnoreCache( sal_Bool bIgnoreCache )
+ {
+ m_aEntries[m_nCalls].m_bIgnoreCache = bIgnoreCache;
+ }
+
+ inline sal_Bool isFull()
+ { return m_nCalls >= m_nMaxMessages; }
+
+ inline sal_Int8 *getHeap( sal_Int32 nSizeToAlloc )
+ {
+ if( nSizeToAlloc + m_nCurrentMemPosition > m_nCurrentMemSize )
+ {
+ m_lstMem.push_back( m_pCurrentMem );
+ m_nCurrentMemSize = mymax( nSizeToAlloc , MULTIJOB_STANDARD_MEMORY_SIZE ) +
+ (m_nMaxMessages -m_nCalls)*MULTIJOB_PER_CALL_MEMORY_SIZE;
+ m_pCurrentMem = (sal_Int8*) rtl_allocateMemory( m_nCurrentMemSize );
+ m_nCurrentMemPosition = 0;
+ }
+ sal_Int8 *pHeap = m_pCurrentMem + m_nCurrentMemPosition;
+ m_nCurrentMemPosition += nSizeToAlloc;
+
+ // care for alignment
+ if( m_nCurrentMemPosition & 0x7 )
+ {
+ m_nCurrentMemPosition = ( ((sal_uInt32)m_nCurrentMemPosition) & ( 0xffffffff - 0x7 )) + 8;
+ }
+ return pHeap;
+ }
+ void prepareRuntimeException( const ::rtl::OUString &sMessage, sal_Int32 nCall );
+
+private:
+ uno_Environment *m_pEnvRemote;
+ sal_Int32 m_nCalls;
+ sal_Int32 m_nMaxMessages;
+
+ ServerJobEntry *m_aEntries;
+ MemberTypeInfo *m_aTypeInfo;
+
+ sal_Int8 *m_pCurrentMem;
+ sal_Int32 m_nCurrentMemSize;
+ sal_Int32 m_nCurrentMemPosition;
+
+ // list of memory pointers, that must be freed
+ ::std::list< sal_Int8 * > m_lstMem;
+};
+
+
+
+//---------------------------------------------------------------------------------------------
+inline ClientJob::ClientJob(
+ uno_Environment *pEnvRemote,
+ remote_Context *pContext,
+ struct urp_BridgeImpl *pBridgeImpl,
+ rtl_uString *pOid,
+ typelib_TypeDescription const * pMemberType,
+ typelib_InterfaceTypeDescription *pInterfaceType,
+ void *pReturn,
+ void *ppArgs[],
+ uno_Any **ppException )
+ : Job(
+ pEnvRemote, pContext, pBridgeImpl, ::bridges_remote::RTC_HOLDENVWEAK )
+ , m_ppArgs( ppArgs )
+ , m_pReturn( pReturn )
+ , m_pInterfaceType( pInterfaceType ) // weak
+ , m_bReleaseForTypeDescriptionNecessary( sal_False )
+ , m_ppException( ppException )
+ , m_bBridgePropertyCall( sal_False )
+ , m_pEnvRemote( pEnvRemote ) // weak
+ , m_pOid( pOid ) // weak
+ , m_bCallingConventionForced( sal_False )
+{
+ uno_getIdOfCurrentThread( &m_pTid );
+
+ if( typelib_TypeClass_INTERFACE_METHOD == pMemberType->eTypeClass )
+ {
+ m_pMethodType = ( typelib_InterfaceMethodTypeDescription * ) pMemberType;
+ m_pAttributeType = 0;
+ }
+ else if( typelib_TypeClass_INTERFACE_ATTRIBUTE == pMemberType->eTypeClass )
+ {
+ m_pAttributeType = ( typelib_InterfaceAttributeTypeDescription * ) pMemberType;
+ m_pMethodType = 0;
+ }
+ else
+ {
+ OSL_ASSERT( ! "wrong member type" );
+ }
+
+ // calculate method index
+ if( ! m_pInterfaceType->aBase.bComplete )
+ {
+ // must be acquired because typedescription may be exchanged
+ typelib_typedescription_acquire((typelib_TypeDescription*) m_pInterfaceType );
+ m_bReleaseForTypeDescriptionNecessary = sal_True;
+ typelib_typedescription_complete( (typelib_TypeDescription ** ) &m_pInterfaceType );
+ }
+ m_nMethodIndex = (sal_uInt16) m_pInterfaceType->pMapMemberIndexToFunctionIndex[
+ ((typelib_InterfaceMemberTypeDescription*)pMemberType)->nPosition ];
+
+ if( m_pAttributeType && m_ppArgs )
+ {
+ // setter
+ m_nMethodIndex ++;
+ }
+
+ if( typelib_TypeClass_INTERFACE_METHOD == pMemberType->eTypeClass )
+ {
+// if( (( typelib_InterfaceMemberTypeDescription * ) pMemberType)->nPosition
+// == REMOTE_RELEASE_METHOD_INDEX )
+// {
+// m_bOneway = sal_True;
+// }
+// else
+ if( pBridgeImpl->m_properties.bForceSynchronous )
+ {
+ m_bOneway = sal_False;
+ if( (( typelib_InterfaceMethodTypeDescription * ) pMemberType)->bOneWay )
+ {
+ m_bCallingConventionForced = sal_True;
+ }
+ }
+ else
+ {
+ m_bOneway = (( typelib_InterfaceMethodTypeDescription * ) pMemberType)->bOneWay;
+ }
+ }
+ else
+ {
+ m_bOneway = sal_False;
+ }
+}
+
+}
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_log.cxx b/bridges/source/remote/urp/urp_log.cxx
new file mode 100644
index 000000000000..48c8543a8ebd
--- /dev/null
+++ b/bridges/source/remote/urp/urp_log.cxx
@@ -0,0 +1,150 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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_bridges.hxx"
+#include <osl/time.h>
+#include "urp_bridgeimpl.hxx"
+#include "urp_log.hxx"
+
+using namespace ::rtl;
+using namespace ::osl;
+namespace bridges_urp
+{
+#ifdef BRIDGES_URP_PROT
+ Mutex g_logFileMutex;
+
+ class FileAccess
+ {
+ public:
+ FileAccess( urp_BridgeImpl *pBridgeImpl_ ) :
+ pBridgeImpl( pBridgeImpl_ ),
+ guard( g_logFileMutex )
+ {
+ if( pBridgeImpl->m_pLogFile )
+ {
+ f = pBridgeImpl->m_pLogFile;
+ }
+ else
+ {
+ f = fopen( pBridgeImpl->m_sLogFileName.getStr() , "a" );
+ }
+ }
+ ~FileAccess()
+ {
+ if( ! pBridgeImpl->m_pLogFile )
+ {
+ fclose( f );
+ }
+ }
+ FILE *getFile()
+ {
+ return f;
+ }
+ private:
+ urp_BridgeImpl *pBridgeImpl;
+ MutexGuard guard;
+ FILE *f;
+ };
+
+ void urp_logCall( urp_BridgeImpl *pBridgeImpl, sal_Int32 nSize, sal_Int32 nUseData, sal_Bool bSynchron ,
+ const ::rtl::OUString &sMethodName )
+ {
+ if( pBridgeImpl->m_sLogFileName.getLength() && getenv( "PROT_REMOTE_ACTIVATE" ) )
+ {
+ OString sOperation = OUStringToOString( sMethodName,RTL_TEXTENCODING_ASCII_US );
+
+ FileAccess access( pBridgeImpl );
+ fprintf( access.getFile() ,
+ "%06u: calling [size=%d(usedata=%d)] [synchron=%d] [name=%s]\n" ,
+ static_cast< unsigned int > (osl_getGlobalTimer()),
+ static_cast< int > (nSize),
+ static_cast< int > (nUseData),
+ bSynchron, sOperation.pData->buffer );
+ }
+ }
+
+ void urp_logServingRequest( urp_BridgeImpl *pBridgeImpl,
+ sal_Int32 nSize, sal_Int32 nUseData, sal_Bool bSynchron ,
+ const ::rtl::OUString &sMethodName )
+ {
+ if( pBridgeImpl->m_sLogFileName.getLength() && getenv( "PROT_REMOTE_ACTIVATE" ) )
+ {
+ OString sOperation = OUStringToOString( sMethodName,RTL_TEXTENCODING_ASCII_US );
+
+ FileAccess access( pBridgeImpl );
+ fprintf(
+ access.getFile(),
+ "%06u: serving request [size=%d(usedata=%d)] [synchron=%d] [name=%s]\n",
+ static_cast< unsigned int > (osl_getGlobalTimer()),
+ static_cast< int > (nSize),
+ static_cast< int > (nUseData),
+ bSynchron,
+ sOperation.pData->buffer
+ );
+ }
+ }
+
+ void urp_logGettingReply( urp_BridgeImpl *pBridgeImpl,
+ sal_Int32 nSize, sal_Int32 nUseData,
+ const ::rtl::OUString &sMethodName )
+ {
+ if( pBridgeImpl->m_sLogFileName.getLength() && getenv( "PROT_REMOTE_ACTIVATE" ) )
+ {
+ OString sOperation = OUStringToOString( sMethodName,RTL_TEXTENCODING_ASCII_US );
+ FileAccess access( pBridgeImpl );
+ fprintf( access.getFile(),
+ "%06u: getting reply [size=%d(usedata=%d)][name=%s]\n" ,
+ static_cast< unsigned int > (osl_getGlobalTimer()),
+ static_cast< int > (nSize),
+ static_cast< int > (nUseData),
+ sOperation.pData->buffer);
+ }
+ }
+
+ void urp_logReplying( urp_BridgeImpl *pBridgeImpl,
+ sal_Int32 nSize , sal_Int32 nUseData,
+ const ::rtl::OUString &sMethodName )
+ {
+ if( pBridgeImpl->m_sLogFileName.getLength() && getenv( "PROT_REMOTE_ACTIVATE" ) )
+ {
+ OString sOperation = OUStringToOString(sMethodName,RTL_TEXTENCODING_ASCII_US);
+
+ FileAccess access( pBridgeImpl );
+ fprintf( access.getFile(),
+ "%06u: replying [size=%d(usedata=%d)] [name=%s]\n",
+ static_cast< unsigned int > (osl_getGlobalTimer()),
+ static_cast< int > (nSize),
+ static_cast< int > (nUseData),
+ sOperation.pData->buffer);
+ }
+ }
+#endif
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_log.hxx b/bridges/source/remote/urp/urp_log.hxx
new file mode 100644
index 000000000000..cc352e85f848
--- /dev/null
+++ b/bridges/source/remote/urp/urp_log.hxx
@@ -0,0 +1,53 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+namespace bridges_urp
+{
+#ifdef DBG_UTIL
+#define BRIDGES_URP_PROT
+#endif
+
+#ifdef BRIDGES_URP_PROT
+ void urp_logCall( urp_BridgeImpl *pBridgeImpl ,
+ sal_Int32 nSize, sal_Int32 nUseData, sal_Bool bSynchron ,
+ const ::rtl::OUString &sMethodName );
+
+ void urp_logServingRequest( urp_BridgeImpl *pBridgeImpl,
+ sal_Int32 nSize, sal_Int32 nUseData, sal_Bool bSynchron ,
+ const ::rtl::OUString &sMethodName );
+
+ void urp_logGettingReply( urp_BridgeImpl *pBridgeImpl,
+ sal_Int32 nSize, sal_Int32 nUseData,
+ const ::rtl::OUString &sMethodName );
+
+ void urp_logReplying( urp_BridgeImpl *pBridgeImpl,
+ sal_Int32 nSize , sal_Int32 nUseData,
+ const ::rtl::OUString &sMethodName );
+#endif
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_marshal.cxx b/bridges/source/remote/urp/urp_marshal.cxx
new file mode 100644
index 000000000000..29f8b35cec0f
--- /dev/null
+++ b/bridges/source/remote/urp/urp_marshal.cxx
@@ -0,0 +1,238 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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_bridges.hxx"
+#include <string.h>
+#include <osl/diagnose.h>
+#include <rtl/alloc.h>
+
+#include <uno/any2.h>
+#include <uno/sequence2.h>
+
+#include "urp_marshal.hxx"
+
+using namespace ::rtl;
+
+using namespace ::com::sun::star::uno;
+
+namespace bridges_urp {
+
+static int g_nDetectLittleEndian = 1;
+char g_bMarshalSystemIsLittleEndian = ((char*)&g_nDetectLittleEndian)[0];
+
+Marshal::Marshal( urp_BridgeImpl *pBridgeImpl,
+ sal_Int32 nBufferSize,
+ urp_extractOidCallback callback) :
+ m_nBufferSize( nBufferSize ),
+ m_base( (sal_Int8*)rtl_allocateMemory( nBufferSize ) ),
+ m_pos( m_base + 2*sizeof( sal_Int32 ) ),
+ m_pBridgeImpl( pBridgeImpl ),
+ m_callback( callback )
+{}
+
+Marshal::~Marshal( )
+{
+ rtl_freeMemory( m_base );
+}
+
+void Marshal::packOid( const ::rtl::OUString & oid )
+{
+ sal_uInt16 nIndex;
+ if( oid.getLength() )
+ {
+ nIndex = m_pBridgeImpl->m_oidCacheOut.seek( oid );
+ if( 0xffff == nIndex )
+ {
+ nIndex = m_pBridgeImpl->m_oidCacheOut.put( oid );
+ packString( (void*)(&oid.pData) );
+ }
+ else
+ {
+ OUString dummy;
+ packString( &dummy );
+ }
+ }
+ else
+ {
+ // null reference
+ nIndex = 0xffff;
+ OUString dummy;
+ packString( &dummy );
+ }
+ packInt16( &nIndex );
+}
+
+void Marshal::packTid( const ByteSequence & threadId, sal_Bool bIgnoreCache )
+{
+
+ sal_uInt16 nIndex = 0xffff;
+ if( ! bIgnoreCache )
+ {
+ nIndex = m_pBridgeImpl->m_tidCacheOut.seek( threadId );
+ }
+
+ if( 0xffff == nIndex )
+ {
+ if( ! bIgnoreCache )
+ {
+ nIndex = m_pBridgeImpl->m_tidCacheOut.put( threadId );
+ }
+ packByteSequence( (sal_Int8*) threadId.getConstArray() ,threadId.getLength());
+ }
+ else
+ {
+ packByteSequence( 0 , 0 );
+ }
+ packInt16( &nIndex );
+}
+
+
+void Marshal::packType( void *pSource )
+{
+ typelib_TypeDescriptionReference *pRef =
+ *(typelib_TypeDescriptionReference ** ) pSource;
+
+ OSL_ASSERT( pRef );
+
+ sal_uInt8 nTypeClass = ( sal_uInt8 ) pRef->eTypeClass;
+
+ if( nTypeClass <= /* any*/ 14 )
+ {
+ packInt8( (sal_Int8*)&nTypeClass );
+ }
+ else
+ {
+ OUString sTypeName;
+ sal_uInt16 nIndex = 0xffff;
+
+ nIndex = m_pBridgeImpl->m_typeCacheOut.seek( *(Type*)&pRef );
+ if( 0xffff == nIndex )
+ {
+ // put it into the cache
+ nIndex = m_pBridgeImpl->m_typeCacheOut.put( *(Type*)&pRef );
+ sTypeName = pRef->pTypeName;
+ nTypeClass = nTypeClass | 0x80;
+ }
+ packInt8( &nTypeClass );
+ packInt16( &nIndex );
+ if( 0x80 & nTypeClass )
+ {
+ packString( &sTypeName );
+ }
+ }
+}
+
+sal_Bool Marshal::packRecursive( void *pSource , typelib_TypeDescription *pType )
+{
+ sal_Bool bSuccess = sal_True;
+ switch( pType->eTypeClass )
+ {
+ case typelib_TypeClass_EXCEPTION:
+ case typelib_TypeClass_STRUCT:
+ {
+ typelib_CompoundTypeDescription * pCompType = (typelib_CompoundTypeDescription*)pType;
+
+ if (pCompType->pBaseTypeDescription)
+ {
+ bSuccess = pack( pSource , (typelib_TypeDescription*) pCompType->pBaseTypeDescription );
+ }
+
+ // then construct members
+ typelib_TypeDescriptionReference ** ppTypeRefs = pCompType->ppTypeRefs;
+ sal_Int32 * pMemberOffsets = pCompType->pMemberOffsets;
+ sal_Int32 nDescr = pCompType->nMembers;
+
+ for ( sal_Int32 nPos = 0; nPos < nDescr; ++nPos )
+ {
+ typelib_TypeDescription * pMemberType = 0;
+ TYPELIB_DANGER_GET( &pMemberType, ppTypeRefs[nPos] );
+ if( pMemberType )
+ {
+ bSuccess = bSuccess && pack( (char*)pSource + pMemberOffsets[nPos] , pMemberType );
+ TYPELIB_DANGER_RELEASE( pMemberType );
+ }
+ else
+ {
+ OUStringBuffer buf( 64 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("Couldn't get typedescription for type "));
+ buf.append( ppTypeRefs[nPos]->pTypeName );
+ m_pBridgeImpl->addError( buf.makeStringAndClear() );
+ bSuccess = sal_False;
+ }
+ }
+ break;
+ }
+ case typelib_TypeClass_SEQUENCE:
+ {
+ typelib_IndirectTypeDescription *pIndirectType =
+ ( typelib_IndirectTypeDescription* ) pType;
+
+ const sal_Int32 nElements = (*(uno_Sequence **)pSource)->nElements;
+ char * pSourceElements = (char *)(*(uno_Sequence **)pSource)->elements;
+
+ if( typelib_TypeClass_BYTE == pIndirectType->pType->eTypeClass )
+ {
+ // Byte sequences are optimized
+ packByteSequence( (sal_Int8*)pSourceElements , nElements );
+ }
+ else
+ {
+ typelib_TypeDescription *pElementType = 0;
+ TYPELIB_DANGER_GET( &pElementType, pIndirectType->pType );
+ if( pElementType )
+ {
+ const sal_Int32 nElementSize = pElementType->nSize;
+
+ packCompressedSize( nElements );
+ for ( sal_Int32 i = 0 ; i < nElements; i++ )
+ {
+ bSuccess = bSuccess && pack( pSourceElements + (nElementSize*i) , pElementType );
+ }
+ TYPELIB_DANGER_RELEASE( pElementType );
+ }
+ else
+ {
+ bSuccess = sal_False;
+ OUStringBuffer buf( 64 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("Couldn't get typedescription for type "));
+ buf.append( pIndirectType->pType->pTypeName );
+ m_pBridgeImpl->addError( buf.makeStringAndClear() );
+ }
+ }
+ break;
+ }
+ default:
+ OSL_ASSERT( 0 );
+ }
+ return bSuccess;
+}
+
+} // end namespace bridges
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_marshal.hxx b/bridges/source/remote/urp/urp_marshal.hxx
new file mode 100644
index 000000000000..c4ed70e9bbbd
--- /dev/null
+++ b/bridges/source/remote/urp/urp_marshal.hxx
@@ -0,0 +1,345 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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 _URP_MARSHAL_HXX_
+#define _URP_MARSHAL_HXX_
+#include <rtl/ustrbuf.hxx>
+#include <rtl/byteseq.hxx>
+#include <com/sun/star/uno/Type.hxx>
+#include "urp_bridgeimpl.hxx"
+#include "urp_marshal_decl.hxx"
+
+#include <string.h>
+
+struct remote_Interface;
+
+namespace bridges_urp
+{
+ // methods for accessing marshaling buffer
+ inline void Marshal::finish( sal_Int32 nMessageCount )
+ {
+ sal_Int32 nSize = getSize() - 2*sizeof( sal_Int32 );
+
+ // save the state
+ sal_Int8 *pos = m_pos;
+ m_pos = m_base;
+ packInt32( &nSize );
+ packInt32( &nMessageCount );
+
+ // reset the state
+ m_pos = pos;
+ }
+
+ inline void Marshal::restart()
+ {
+ m_pos = m_base + 2*sizeof( sal_Int32 );
+ }
+
+ inline sal_Int8 *Marshal::getBuffer()
+ {
+ return m_base;
+ }
+
+ inline sal_Bool Marshal::empty() const
+ {
+ return ( m_pos - m_base ) == 2*sizeof( sal_Int32 );
+ }
+
+ inline sal_Int32 Marshal::getSize()
+ {
+ return ((sal_Int32) (m_pos - m_base));
+ }
+
+ inline void Marshal::ensureAdditionalMem( sal_Int32 nMemToAdd )
+ {
+ sal_Int32 nDiff = m_pos - m_base;
+ if( nDiff + nMemToAdd > m_nBufferSize )
+ {
+ m_nBufferSize = m_nBufferSize * 2 > nDiff + nMemToAdd ?
+ m_nBufferSize* 2 :
+ nDiff + nMemToAdd;
+
+ m_base = ( sal_Int8 * ) rtl_reallocateMemory( m_base , m_nBufferSize );
+ m_pos = m_base + nDiff;
+ }
+ }
+
+ // marshaling methods
+ inline void Marshal::packInt8( void *pSource )
+ {
+ ensureAdditionalMem( 1 );
+ *m_pos = *((sal_Int8*) pSource );
+ m_pos++;
+ }
+
+ inline void Marshal::packInt16( void *pSource )
+ {
+ ensureAdditionalMem( 2 );
+ if( isSystemLittleEndian() )
+ {
+ m_pos[0] = ((unsigned char *)pSource)[1];
+ m_pos[1] = ((unsigned char *)pSource)[0];
+ }
+ else
+ {
+ m_pos[1] = ((unsigned char *)pSource)[1];
+ m_pos[0] = ((unsigned char *)pSource)[0];
+ }
+ m_pos +=2;
+ }
+
+ inline void Marshal::packByteSequence( sal_Int8 *pData , sal_Int32 nLength )
+ {
+ packCompressedSize( nLength );
+
+ ensureAdditionalMem( nLength );
+ memcpy( m_pos , pData , nLength );
+ m_pos += nLength;
+ }
+
+ inline void Marshal::packString( void *pSource )
+ {
+ rtl_uString *p = *( rtl_uString ** ) pSource;
+
+ // to be optimized !
+ // static buffer in marshal
+ ::rtl::OString o = ::rtl::OUStringToOString( p , RTL_TEXTENCODING_UTF8 );
+ sal_Int32 nLength = o.pData->length;
+ packCompressedSize( nLength );
+
+ ensureAdditionalMem( nLength );
+
+ memcpy( m_pos , o.pData->buffer , nLength );
+ m_pos += nLength;
+ }
+
+ inline sal_Bool Marshal::packAny( void *pSource )
+ {
+ sal_Bool bSuccess = sal_True;
+ uno_Any *pAny = (uno_Any * ) pSource;
+
+ // pack the type
+ packType( &( pAny->pType ) );
+ // pack the value
+ typelib_TypeDescription *pType = 0;
+ TYPELIB_DANGER_GET( &pType, pAny->pType );
+ if( pType )
+ {
+ pack( pAny->pData , pType );
+ TYPELIB_DANGER_RELEASE( pType );
+ }
+ else
+ {
+ rtl::OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("couldn't get typedescription for type " ) );
+ buf.append( pAny->pType->pTypeName );
+ m_pBridgeImpl->addError( buf.makeStringAndClear() );
+ bSuccess = sal_False;
+ }
+ return bSuccess;
+ }
+
+ inline void Marshal::packInt32( void *pSource )
+ {
+ ensureAdditionalMem( 4 );
+ if( isSystemLittleEndian() )
+ {
+ m_pos[0] = ((unsigned char *)pSource)[3];
+ m_pos[1] = ((unsigned char *)pSource)[2];
+ m_pos[2] = ((unsigned char *)pSource)[1];
+ m_pos[3] = ((unsigned char *)pSource)[0];
+ }
+ else {
+ m_pos[3] = ((unsigned char *)pSource)[3];
+ m_pos[2] = ((unsigned char *)pSource)[2];
+ m_pos[1] = ((unsigned char *)pSource)[1];
+ m_pos[0] = ((unsigned char *)pSource)[0];
+ }
+ m_pos +=4;
+ }
+
+ inline void Marshal::packCompressedSize( sal_Int32 nSize )
+ {
+ ensureAdditionalMem( 5 );
+
+ if( nSize < 0xff )
+ {
+ *((sal_uInt8*)m_pos) = (sal_uInt8) nSize;
+ m_pos ++;
+ }
+ else
+ {
+ *((sal_uInt8*)m_pos) = 0xff;
+ m_pos ++;
+ packInt32( &nSize );
+ }
+ }
+
+ inline sal_Bool Marshal::pack( void *pSource , typelib_TypeDescription *pType )
+ {
+ sal_Bool bSuccess = sal_True;
+ switch( pType->eTypeClass )
+ {
+ case typelib_TypeClass_BYTE:
+ {
+ packInt8( pSource );
+ break;
+ }
+ case typelib_TypeClass_BOOLEAN:
+ {
+ ensureAdditionalMem( 1 );
+ *m_pos = ( *((sal_Bool*) pSource ) ) ? 1 : 0;
+ m_pos++;
+ break;
+ }
+
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ {
+ packInt16( pSource );
+ break;
+ }
+ case typelib_TypeClass_ENUM:
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_FLOAT:
+ {
+ packInt32( pSource );
+ break;
+ }
+ case typelib_TypeClass_DOUBLE:
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ {
+ ensureAdditionalMem( 8 );
+ if( isSystemLittleEndian() )
+ {
+ m_pos[0] = ((unsigned char *)pSource)[7];
+ m_pos[1] = ((unsigned char *)pSource)[6];
+ m_pos[2] = ((unsigned char *)pSource)[5];
+ m_pos[3] = ((unsigned char *)pSource)[4];
+ m_pos[4] = ((unsigned char *)pSource)[3];
+ m_pos[5] = ((unsigned char *)pSource)[2];
+ m_pos[6] = ((unsigned char *)pSource)[1];
+ m_pos[7] = ((unsigned char *)pSource)[0];
+ }
+ else
+ {
+ m_pos[7] = ((unsigned char *)pSource)[7];
+ m_pos[6] = ((unsigned char *)pSource)[6];
+ m_pos[5] = ((unsigned char *)pSource)[5];
+ m_pos[4] = ((unsigned char *)pSource)[4];
+ m_pos[3] = ((unsigned char *)pSource)[3];
+ m_pos[2] = ((unsigned char *)pSource)[2];
+ m_pos[1] = ((unsigned char *)pSource)[1];
+ m_pos[0] = ((unsigned char *)pSource)[0];
+ }
+ m_pos += 8;
+ break;
+ }
+
+ case typelib_TypeClass_STRING:
+ {
+ packString( pSource );
+ break;
+ }
+ case typelib_TypeClass_TYPE:
+ {
+ packType( pSource );
+ break;
+ }
+ case typelib_TypeClass_ANY:
+ {
+ bSuccess = packAny( pSource );
+ break;
+ }
+ case typelib_TypeClass_TYPEDEF:
+ {
+ bSuccess = sal_False;
+ m_pBridgeImpl->addError( "can't handle typedef typedescriptions" );
+ break;
+ }
+ case typelib_TypeClass_INTERFACE:
+ {
+ remote_Interface *pRemoteI = *( remote_Interface ** )pSource;
+
+ ::rtl::OUString sOid;
+ sal_uInt16 nIndex = 0xffff;
+ if( pRemoteI )
+ {
+ m_callback( pRemoteI , &(sOid.pData) );
+
+ nIndex = m_pBridgeImpl->m_oidCacheOut.seek( sOid );
+ if( 0xffff == nIndex )
+ {
+ nIndex = m_pBridgeImpl->m_oidCacheOut.put( sOid );
+ }
+ else
+ {
+ // cached !
+ sOid = ::rtl::OUString();
+ }
+ }
+ packString( &sOid );
+ packInt16( &nIndex );
+ break;
+ }
+ case typelib_TypeClass_VOID:
+ {
+ // do nothing
+ break;
+ }
+ case typelib_TypeClass_EXCEPTION:
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_SEQUENCE:
+ {
+ bSuccess = packRecursive( pSource, pType );
+ break;
+ }
+ default:
+ {
+ bSuccess = sal_False;
+ rtl::OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "can't handle values with typeclass " ) );
+ buf.append( (sal_Int32 ) pType->eTypeClass , 10 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " (" ) );
+ buf.append( pType->pTypeName );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( ")" ) );
+ m_pBridgeImpl->addError( buf.makeStringAndClear() );
+ break;
+ }
+ }
+ return bSuccess;
+ }
+}
+
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_marshal_decl.hxx b/bridges/source/remote/urp/urp_marshal_decl.hxx
new file mode 100644
index 000000000000..411730bacf2f
--- /dev/null
+++ b/bridges/source/remote/urp/urp_marshal_decl.hxx
@@ -0,0 +1,109 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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 _URP_MARSHAL_DECL_HXX_
+#define _URP_MARSHAL_DECL_HXX_
+
+#include <rtl/ustring.hxx>
+#include <rtl/byteseq.hxx>
+
+#include <com/sun/star/uno/Type.hxx>
+
+namespace bridges_urp
+{
+ struct urp_BridgeImpl;
+
+ typedef void
+ ( SAL_CALL * urp_extractOidCallback )( remote_Interface *pRemoteI, rtl_uString **ppOid );
+
+ extern char g_bMarshalSystemIsLittleEndian;
+ class Marshal
+ {
+ public:
+ Marshal( /* cache access */ struct urp_BridgeImpl *,
+ sal_Int32 m_nBufferSize,
+ urp_extractOidCallback callback = 0
+ );
+ ~Marshal( );
+
+ inline sal_Bool pack( void *pSource , typelib_TypeDescription *pType );
+
+ sal_Bool packRecursive( void *pSource, typelib_TypeDescription *pType );
+
+ void packTid( const ::rtl::ByteSequence &id, sal_Bool bIgnoreCache = sal_False );
+ void packOid( const ::rtl::OUString &oid );
+ void packType( void *pSource );
+
+ inline void packCompressedSize( sal_Int32 nSize );
+ inline void packInt8( void *pSource );
+ inline void packInt16( void *pSource );
+ inline void packInt32( void *pSource );
+ inline void packString( void *pSource );
+ inline sal_Bool packAny( void *pSource );
+ inline void packByteSequence( sal_Int8 *pBuffer , sal_Int32 nSize );
+
+ // can be called during marshaling, but not between
+ // finish and restart
+ // returns true, when nothing has been marshaled
+ inline sal_Bool empty() const;
+
+ // stops marshaling, inserts size in front of the buffer
+ // getStart and getSize can now be called
+ inline void finish( sal_Int32 nMessageCount );
+
+ // must be called after finish. After calling restart,
+ // a new marshalling session is started invalidating
+ // the previous bufer
+ inline void restart();
+
+ // is only valid, after finish has been called.
+ // valid until destructed.
+ inline sal_Int8 *getBuffer();
+
+ // is only valid, after finish has been called.
+ // valid until destructed.
+ inline sal_Int32 getSize();
+
+ inline sal_Int32 getPos()
+ { return m_pos - m_base; }
+
+ inline sal_Bool isSystemLittleEndian()
+ { return g_bMarshalSystemIsLittleEndian; }
+
+ private:
+ inline void ensureAdditionalMem( sal_Int32 nMemToAdd );
+ sal_Int32 m_nBufferSize;
+ sal_Int8 *m_base;
+ sal_Int8 *m_pos;
+ struct urp_BridgeImpl *m_pBridgeImpl;
+ urp_extractOidCallback m_callback;
+ };
+}
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_property.hxx b/bridges/source/remote/urp/urp_property.hxx
new file mode 100644
index 000000000000..530cea697e56
--- /dev/null
+++ b/bridges/source/remote/urp/urp_property.hxx
@@ -0,0 +1,94 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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 _URP_PROPERTY_HXX_
+#define _URP_PROPERTY_HXX_
+#include <bridges/remote/remote.h>
+#include <rtl/ustring.hxx>
+#include <rtl/byteseq.hxx>
+
+namespace bridges_urp
+{
+ struct Properties
+ {
+ ::rtl::ByteSequence seqBridgeID;
+ sal_Int32 nTypeCacheSize;
+ sal_Int32 nOidCacheSize;
+ sal_Int32 nTidCacheSize;
+ ::rtl::OUString sSupportedVersions;
+ ::rtl::OUString sVersion;
+ sal_Int32 nFlushBlockSize;
+ sal_Int32 nOnewayTimeoutMUSEC;
+ sal_Bool bSupportsMustReply;
+ sal_Bool bSupportsSynchronous;
+ sal_Bool bSupportsMultipleSynchronous;
+ sal_Bool bClearCache;
+ sal_Bool bNegotiate;
+ sal_Bool bForceSynchronous;
+ sal_Bool bCurrentContext;
+
+ inline Properties()
+ : nTypeCacheSize( 256 )
+ , nOidCacheSize( 256 )
+ , nTidCacheSize( 256 )
+ , sSupportedVersions( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "1.0" ) ) )
+ , sVersion( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "1.0" )))
+ , nFlushBlockSize( 4*1024 )
+ , nOnewayTimeoutMUSEC( 10000 )
+ , bSupportsMustReply( sal_False )
+ , bSupportsSynchronous( sal_False )
+ , bSupportsMultipleSynchronous( sal_False )
+ , bClearCache( sal_False )
+ , bNegotiate( sal_True )
+ , bForceSynchronous( sal_True )
+ , bCurrentContext( sal_False )
+ {}
+
+ inline Properties & SAL_CALL operator = ( const Properties &props )
+ {
+ seqBridgeID = props.seqBridgeID;
+ nTypeCacheSize = props.nTypeCacheSize;
+ nOidCacheSize = props.nOidCacheSize;
+ nTidCacheSize = props.nTidCacheSize;
+ sSupportedVersions = props.sSupportedVersions;
+ sVersion = props.sVersion;
+ nFlushBlockSize = props.nFlushBlockSize;
+ nOnewayTimeoutMUSEC = props.nOnewayTimeoutMUSEC;
+ bSupportsMustReply = props.bSupportsMustReply;
+ bSupportsSynchronous = props.bSupportsSynchronous;
+ bSupportsMultipleSynchronous = props.bSupportsMultipleSynchronous;
+ bClearCache = props.bClearCache;
+ bNegotiate = props.bNegotiate;
+ bForceSynchronous = props.bForceSynchronous;
+ bCurrentContext = props.bCurrentContext;
+ return *this;
+ }
+ };
+} // end namespace bridges_urp
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_propertyobject.cxx b/bridges/source/remote/urp/urp_propertyobject.cxx
new file mode 100644
index 000000000000..95c290ef08f0
--- /dev/null
+++ b/bridges/source/remote/urp/urp_propertyobject.cxx
@@ -0,0 +1,796 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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_bridges.hxx"
+#include <stdlib.h>
+#include <osl/diagnose.h>
+
+#include <rtl/random.h>
+
+#include <uno/data.h>
+
+#include "com/sun/star/bridge/InvalidProtocolChangeException.hpp"
+#include <com/sun/star/bridge/XProtocolProperties.hpp>
+
+#include "urp_propertyobject.hxx"
+#include "urp_dispatch.hxx"
+#include "urp_bridgeimpl.hxx"
+#include "urp_job.hxx"
+
+using namespace ::rtl;
+using namespace ::osl;
+using namespace ::com::sun::star::bridge;
+using namespace ::com::sun::star::uno;
+
+using namespace bridges_urp;
+
+extern "C" {
+
+static void SAL_CALL staticAcquire( remote_Interface *pRemoteI )
+{
+ PropertyObject *pProperties = (PropertyObject *) pRemoteI;
+ pProperties->thisAcquire();
+}
+
+static void SAL_CALL staticRelease( remote_Interface *pRemoteI )
+{
+ PropertyObject *pProperties = (PropertyObject *) pRemoteI;
+ pProperties->thisRelease();
+}
+
+static void SAL_CALL staticDispatch(
+ remote_Interface * pRemoteI, typelib_TypeDescription const * pMemberType,
+ void * pReturn, void * pArgs[], uno_Any ** ppException )
+{
+ PropertyObject *pProperties = (PropertyObject *) pRemoteI;
+ pProperties->thisDispatch( pMemberType, pReturn, pArgs, ppException );
+}
+
+}
+
+namespace bridges_urp
+{
+// some nice constants ....
+static const sal_Int32 METHOD_QUERY_INTERFACE = 0;
+static const sal_Int32 METHOD_GET_PROPERTIES = 3;
+static const sal_Int32 METHOD_REQUEST_CHANGE = 4;
+static const sal_Int32 METHOD_COMMIT_CHANGE = 5;
+
+static const sal_Int32 PROPERTY_BRIDGEID = 0;
+static const sal_Int32 PROPERTY_TYPECACHESIZE = 1;
+static const sal_Int32 PROPERTY_OIDCACHESIZE = 2;
+static const sal_Int32 PROPERTY_TIDCACHESIZE = 3;
+static const sal_Int32 PROPERTY_SUPPORTEDVERSIONS = 4;
+static const sal_Int32 PROPERTY_VERSION =5;
+static const sal_Int32 PROPERTY_FLUSHBLOCKSIZE = 6;
+static const sal_Int32 PROPERTY_ONEWAYTIMEOUT_MUSEC = 7;
+static const sal_Int32 PROPERTY_SUPPORTSMUSTREPLY = 8;
+static const sal_Int32 PROPERTY_SUPPERTSSYNCHRONOUS = 9;
+static const sal_Int32 PROPERTY_SUPPORTSMULTIPLESYNCHRONOUS = 10;
+static const sal_Int32 PROPERTY_CLEARCACHE = 11;
+static const sal_Int32 PROPERTY_NEGOTIATE = 12;
+static const sal_Int32 PROPERTY_FORCESYNCHRONOUS = 13;
+static const sal_Int32 PROPERTY_CURRENTCONTEXT = 14;
+
+static const sal_Int32 MAX_PROPERTIES = PROPERTY_CURRENTCONTEXT +1;
+
+const sal_Char *g_aPropertyName[] =
+{
+ "BridgeId",
+ "TypeCacheSize",
+ "OidCacheSize",
+ "TidCacheSize",
+ "SupportedVersion",
+ "Version",
+ "FlushBlockSize",
+ "OnewayTimeoutMUSEC",
+ "SupportsMustReply",
+ "SupportsSynchronous",
+ "SupportsMultipleSynchronous",
+ "ClearCache",
+ "Negotiate",
+ "ForceSynchronous",
+ "CurrentContext"
+};
+
+// nice little helper functions for conversion
+template< class t >
+void assignToIdl( ProtocolProperty *pIdl, sal_Int32 nIndex, const t &value )
+{
+ pIdl->Name = OUString::createFromAscii( g_aPropertyName[nIndex] );
+ ( *(::com::sun::star::uno::Any *)&(pIdl->Value) ) <<= value;
+}
+
+template< class t >
+void assignFromIdl( t * p, const ProtocolProperty & property )
+{
+ property.Value >>=*p;
+}
+
+static sal_Int32 getIndexFromIdl( const ProtocolProperty & property )
+{
+ sal_Int32 nResult = -1;
+ for( sal_Int32 i = 0 ; i < MAX_PROPERTIES ; i ++ )
+ {
+ if( 0 == property.Name.compareToAscii( g_aPropertyName[i] ) )
+ {
+ nResult = i;
+ break;
+ }
+ }
+ return nResult;
+}
+
+static sal_Int32 getIndexFromString( const OUString & property )
+{
+ sal_Int32 nResult = -1;
+ for( sal_Int32 i = 0 ; i < MAX_PROPERTIES ; i ++ )
+ {
+ if( 0 == property.compareToAscii( g_aPropertyName[i] ) )
+ {
+ nResult = i;
+ break;
+ }
+ }
+ return nResult;
+}
+
+static sal_Bool assignFromIdlToStruct( Properties *pProps, const ProtocolProperty &idl )
+{
+ sal_Bool bReturn = sal_True;
+
+ sal_Int32 nIndex = getIndexFromIdl( idl );
+ if( nIndex >= 0 )
+ {
+ switch( nIndex )
+ {
+ case PROPERTY_SUPPORTSMULTIPLESYNCHRONOUS:
+ assignFromIdl( &(pProps->bSupportsMultipleSynchronous) , idl );
+ break;
+ case PROPERTY_SUPPERTSSYNCHRONOUS:
+ assignFromIdl( &(pProps->bSupportsMustReply) , idl );
+ break;
+ case PROPERTY_SUPPORTSMUSTREPLY:
+ assignFromIdl( &(pProps->bSupportsSynchronous) , idl );
+ break;
+ case PROPERTY_ONEWAYTIMEOUT_MUSEC:
+ assignFromIdl( &(pProps->nOnewayTimeoutMUSEC) , idl );
+ break;
+ case PROPERTY_BRIDGEID:
+ assignFromIdl( (Sequence< sal_Int8 > * )&(pProps->seqBridgeID), idl );
+ break;
+ case PROPERTY_TYPECACHESIZE:
+ assignFromIdl( &(pProps->nTypeCacheSize) , idl );
+ break;
+ case PROPERTY_OIDCACHESIZE:
+ assignFromIdl( &(pProps->nOidCacheSize) , idl );
+ break;
+ case PROPERTY_TIDCACHESIZE:
+ assignFromIdl( &(pProps->nTidCacheSize), idl );
+ break;
+ case PROPERTY_SUPPORTEDVERSIONS:
+ assignFromIdl( &(pProps->sSupportedVersions) , idl );
+ break;
+ case PROPERTY_VERSION:
+ assignFromIdl( &(pProps->sVersion) , idl );
+ break;
+ case PROPERTY_FLUSHBLOCKSIZE:
+ assignFromIdl( &(pProps->nFlushBlockSize) ,idl );
+ break;
+ case PROPERTY_CLEARCACHE:
+ assignFromIdl( &(pProps->bClearCache) ,idl );
+ break;
+ case PROPERTY_NEGOTIATE:
+ assignFromIdl( &(pProps->bNegotiate) ,idl );
+ break;
+ case PROPERTY_FORCESYNCHRONOUS:
+ assignFromIdl( &(pProps->bForceSynchronous) ,idl );
+ break;
+ case PROPERTY_CURRENTCONTEXT:
+ pProps->bCurrentContext = true;
+ break;
+ default:
+ bReturn = sal_False;
+ }
+ }
+ else
+ {
+ bReturn = sal_False;
+ }
+ return bReturn;
+}
+
+static void extractTokens(
+ const ::rtl::OUString &sProps , ::std::list< OUString > &lst )
+{
+ sal_Int32 nNext = 0;
+ while ( sal_True )
+ {
+ sal_Int32 nStart = nNext;
+ nNext = sProps.indexOf( ',' , nNext );
+ if( -1 == nNext )
+ {
+ lst.push_back( sProps.copy( nStart, sProps.getLength() - nStart ) );
+ break;
+ }
+ lst.push_back( sProps.copy( nStart , nNext - nStart ) );
+ nNext ++;
+ }
+}
+
+
+static void assignFromStringToPropSeq( const OUString &sProps, uno_Sequence **ppPropertySeq)
+{
+ ::std::list< OUString > lst;
+ extractTokens( sProps , lst );
+
+ typelib_TypeDescription *pSequenceType = 0;
+ getCppuType( (Sequence< ProtocolProperty > *)0).getDescription( &pSequenceType );
+ uno_Sequence *pSeq = 0;
+ uno_sequence_construct( &pSeq , pSequenceType , 0, lst.size() , 0 );
+ ProtocolProperty *pElements = (ProtocolProperty * ) pSeq->elements;
+
+ sal_Int32 i = 0;
+ for( ::std::list< OUString >::iterator ii = lst.begin() ; ii != lst.end() ; ++ ii, i++ )
+ {
+ sal_Int32 nAssign = (*ii).indexOf( '=' );
+ if( -1 == nAssign )
+ {
+ OString o = OUStringToOString( *ii, RTL_TEXTENCODING_ASCII_US );
+ OSL_ENSURE( !"wrong protocol propertyt format, ignored", o.getStr() );
+ }
+ OUString sPropName = (*ii).copy( 0, nAssign );
+ OUString sValue = (*ii).copy( nAssign +1, (*ii).getLength() - nAssign -1 );
+
+ sal_Int32 nIndex = getIndexFromString( sPropName );
+ if( -1 == nIndex )
+ {
+ OString o = OUStringToOString( sPropName , RTL_TEXTENCODING_ASCII_US);
+ OSL_ENSURE( !"unknown protocol property, ignored", o.getStr() );
+ }
+ switch( nIndex )
+ {
+ // voids
+ case PROPERTY_CURRENTCONTEXT:
+ pElements[i].Name = OUString::createFromAscii(
+ g_aPropertyName[nIndex] );
+ break;
+ // bools
+ case PROPERTY_CLEARCACHE:
+ case PROPERTY_NEGOTIATE:
+ case PROPERTY_FORCESYNCHRONOUS:
+ {
+ sal_Bool bClearCache = (sal_Bool ) sValue.toInt32();
+ assignToIdl( &(pElements[i]) , nIndex , bClearCache );
+ break;
+ }
+ // ints
+ case PROPERTY_TYPECACHESIZE:
+ case PROPERTY_OIDCACHESIZE:
+ case PROPERTY_TIDCACHESIZE:
+ case PROPERTY_FLUSHBLOCKSIZE:
+ case PROPERTY_ONEWAYTIMEOUT_MUSEC:
+ {
+ sal_Int32 nValue = sValue.toInt32();
+ assignToIdl( &(pElements[i]) , nIndex , nValue );
+ break;
+ }
+
+ // strings
+ case PROPERTY_VERSION:
+ assignToIdl( &(pElements[i]) , nIndex , sValue );
+ break;
+ default:
+ OString o = OUStringToOString( sPropName, RTL_TEXTENCODING_ASCII_US );
+ OSL_ENSURE( !"readonly protocol property, ignored" , o.getStr() );
+ }
+ }
+ *ppPropertySeq = pSeq;
+ typelib_typedescription_release( pSequenceType );
+}
+
+static void assignFromPropSeqToStruct( uno_Sequence *pSeq , struct Properties *pProps )
+{
+ sal_Int32 i;
+ ProtocolProperty *pElements = (ProtocolProperty *)pSeq->elements;
+ for( i = 0 ; i < pSeq->nElements ; i ++ )
+ {
+ assignFromIdlToStruct( pProps , pElements[i] );
+ }
+}
+
+void assignFromStringToStruct( const OUString & sProps , struct Properties *pProps )
+{
+ uno_Sequence *pSeq = 0;
+ assignFromStringToPropSeq( sProps , &pSeq );
+ assignFromPropSeqToStruct( pSeq , pProps );
+ uno_type_destructData( &pSeq, getCppuType( (Sequence< ProtocolProperty > *)0).getTypeLibType(),0);
+}
+
+
+//----------------------------------------------------------------------------------------------
+// PropertyObject implementation
+PropertyObject::PropertyObject(
+ struct Properties *pLocalSetting , uno_Environment *pEnvRemote, urp_BridgeImpl *pImpl )
+ : m_commitChangeCondition( osl_createCondition() )
+ , m_nRefCount( 0 )
+ , m_pBridgeImpl( pImpl )
+ , m_pLocalSetting( pLocalSetting )
+ , m_pEnvRemote( pEnvRemote )
+ , m_bRequestChangeHasBeenCalled( sal_False )
+ , m_bServerWaitingForCommit( sal_False )
+ , m_bApplyProperties( sal_False )
+{
+ acquire = staticAcquire;
+ release = staticRelease;
+ pDispatcher = staticDispatch;
+}
+
+PropertyObject::~PropertyObject()
+{
+ osl_destroyCondition( m_commitChangeCondition );
+}
+
+void SAL_CALL PropertyObject::thisDispatch(
+ typelib_TypeDescription const * pMemberType, void * pReturn, void * ppArgs[],
+ uno_Any ** ppException )
+{
+ OSL_ASSERT( pMemberType->eTypeClass == typelib_TypeClass_INTERFACE_METHOD );
+
+ typelib_InterfaceMethodTypeDescription *pMethodType =
+ ( typelib_InterfaceMethodTypeDescription * ) pMemberType;
+
+ switch( pMethodType->aBase.nPosition )
+ {
+ case METHOD_QUERY_INTERFACE:
+ OSL_ENSURE( 0 , "not implemented yet !" );
+ break;
+ case METHOD_GET_PROPERTIES:
+ {
+ implGetProperties( (uno_Sequence **) pReturn );
+ *ppException = 0;
+ break;
+ }
+ case METHOD_COMMIT_CHANGE:
+ {
+ implCommitChange( *(uno_Sequence ** ) ppArgs[0] , ppException );
+ break;
+ }
+ case METHOD_REQUEST_CHANGE:
+ {
+ *(sal_Int32 *) pReturn = implRequestChange( *(sal_Int32 *)ppArgs[0], ppException );
+ break;
+ }
+ default:
+ OSL_ENSURE( 0 , "unkown method !" );
+ }
+}
+
+void SAL_CALL PropertyObject::localGetPropertiesFromRemote( struct Properties *pR )
+{
+ OUString oid = OUString::createFromAscii( g_NameOfUrpProtocolPropertiesObject );
+
+ typelib_TypeDescription *pInterfaceType = 0;
+ getCppuType( (Reference< XProtocolProperties > *) 0 ).getDescription( &pInterfaceType );
+
+ if( !pInterfaceType->bComplete )
+ {
+ typelib_typedescription_complete( &pInterfaceType );
+ }
+
+ typelib_TypeDescription *pMethodType = 0;
+ typelib_typedescriptionreference_getDescription(
+ &pMethodType,
+ ((typelib_InterfaceTypeDescription*) pInterfaceType)->ppAllMembers[METHOD_GET_PROPERTIES] );
+
+
+ uno_Sequence *pResult = 0;
+ uno_Any exception;
+ uno_Any *pException = &exception;
+ urp_sendRequest( m_pEnvRemote,
+ pMethodType,
+ oid.pData,
+ (typelib_InterfaceTypeDescription*) pInterfaceType,
+ &pResult,
+ 0,
+ &pException );
+
+ if( pException )
+ {
+ OSL_ENSURE( 0 , "remote urp-bridge doesn't support property-object" );
+ uno_any_destruct( pException , 0 );
+ return;
+ }
+
+ ProtocolProperty *pP = (ProtocolProperty * ) pResult->elements;
+ for( sal_Int32 i = 0; i < pResult->nElements ; i ++ )
+ {
+ if( ! assignFromIdlToStruct( pR , pP[i] ) )
+ {
+ OSL_ENSURE( 0 , "unknown property !!!!" );
+ }
+ }
+
+ typelib_typedescription_release( pInterfaceType );
+ typelib_typedescription_release( pMethodType );
+}
+
+
+// implementation for call from remote
+void SAL_CALL PropertyObject::implGetProperties( uno_Sequence **ppReturnValue )
+{
+ typelib_TypeDescription *pElementType= 0;
+ getCppuType( (Sequence< ProtocolProperty > *)0).getDescription( &pElementType );
+
+ OSL_ENSURE( pElementType , "Couldn't get property type" );
+
+ *ppReturnValue = 0;
+ uno_sequence_construct( ppReturnValue , pElementType , 0, MAX_PROPERTIES , 0 );
+ ProtocolProperty *pElements = (ProtocolProperty * ) ( *ppReturnValue )->elements;
+ Properties *pP = m_pLocalSetting;
+
+ assignToIdl( &(pElements[PROPERTY_BRIDGEID]),PROPERTY_BRIDGEID, toUnoSequence(pP->seqBridgeID) );
+ assignToIdl( &(pElements[PROPERTY_TYPECACHESIZE]),PROPERTY_TYPECACHESIZE,pP->nTypeCacheSize );
+ assignToIdl( &(pElements[PROPERTY_OIDCACHESIZE]),PROPERTY_OIDCACHESIZE, pP->nOidCacheSize );
+ assignToIdl( &(pElements[PROPERTY_TIDCACHESIZE]),PROPERTY_TIDCACHESIZE, pP->nTidCacheSize );
+ assignToIdl( &(pElements[PROPERTY_SUPPORTEDVERSIONS]),PROPERTY_SUPPORTEDVERSIONS, pP->sSupportedVersions );
+ assignToIdl( &(pElements[PROPERTY_VERSION]),PROPERTY_VERSION, pP->sVersion );
+ assignToIdl( &(pElements[PROPERTY_FLUSHBLOCKSIZE]), PROPERTY_FLUSHBLOCKSIZE,pP->nFlushBlockSize );
+ assignToIdl( &(pElements[PROPERTY_ONEWAYTIMEOUT_MUSEC]), PROPERTY_ONEWAYTIMEOUT_MUSEC, pP->nOnewayTimeoutMUSEC );
+ assignToIdl( &(pElements[PROPERTY_SUPPORTSMUSTREPLY]), PROPERTY_SUPPORTSMUSTREPLY, pP->bSupportsMustReply );
+ assignToIdl( &(pElements[PROPERTY_SUPPERTSSYNCHRONOUS]), PROPERTY_SUPPERTSSYNCHRONOUS, pP->bSupportsSynchronous );
+ assignToIdl( &(pElements[PROPERTY_SUPPORTSMULTIPLESYNCHRONOUS]), PROPERTY_SUPPORTSMULTIPLESYNCHRONOUS, pP->bSupportsMultipleSynchronous );
+ assignToIdl( &(pElements[PROPERTY_CLEARCACHE]), PROPERTY_CLEARCACHE, pP->bClearCache );
+
+ typelib_typedescription_release( pElementType );
+}
+
+//----------------------------------------------------------------------------------------------
+sal_Int32 SAL_CALL PropertyObject::localRequestChange( )
+{
+ sal_Int32 nResult = 0;
+ sal_Bool bCall = sal_True;
+
+ // disallow marshaling NOW !
+ ClearableMutexGuard marshalingGuard( m_pBridgeImpl->m_marshalingMutex );
+ {
+ MutexGuard guard( m_mutex );
+ if( m_bRequestChangeHasBeenCalled || m_bServerWaitingForCommit )
+ {
+ // another transaction is already underway
+ // try again later !
+ bCall = sal_False;
+ }
+ m_bRequestChangeHasBeenCalled = sal_True;
+
+ if( bCall )
+ {
+ // calulate random number
+ rtlRandomPool pool = rtl_random_createPool ();
+ rtl_random_getBytes( pool , &m_nRandomNumberOfRequest, sizeof( m_nRandomNumberOfRequest ) );
+ rtl_random_destroyPool( pool );
+ }
+ }
+
+ if( bCall )
+ {
+ OUString oid = OUString::createFromAscii( g_NameOfUrpProtocolPropertiesObject );
+
+ // gather types for calling
+ typelib_TypeDescription *pInterfaceType = 0;
+ getCppuType( (Reference< XProtocolProperties > *) 0 ).getDescription( &pInterfaceType );
+
+ if( !pInterfaceType->bComplete )
+ {
+ typelib_typedescription_complete( &pInterfaceType );
+ }
+
+ typelib_TypeDescription *pMethodType = 0;
+ typelib_typedescriptionreference_getDescription(
+ &pMethodType,
+ ((typelib_InterfaceTypeDescription*) pInterfaceType)->ppAllMembers[METHOD_REQUEST_CHANGE] );
+
+ void *pArg1 = &m_nRandomNumberOfRequest;
+ void **ppArgs = &pArg1;
+
+ uno_Any exception;
+ uno_Any *pException = &exception;
+
+ ClientJob job( m_pEnvRemote,
+ 0,
+ m_pBridgeImpl,
+ oid.pData,
+ pMethodType,
+ (typelib_InterfaceTypeDescription*) pInterfaceType,
+ &nResult,
+ ppArgs,
+ &pException );
+
+ // put the call on the line !
+ sal_Bool bSuccess = job.pack();
+
+ // now allow writing on wire again.
+ // NOTE : this has been locked, because it is inevitable to set m_bRequestChangeHasBeenCalled
+ // and call requestChange in an atomar operation. Otherwise, implRequestChange may be called
+ // inbetween and reply, before the request is put on the wire. This certainly would
+ // be confusing for the remote counterpart !
+ marshalingGuard.clear();
+
+ // wait for the reply ...
+ if( bSuccess )
+ {
+ job.wait();
+
+ if( pException )
+ {
+ // the object is unknown on the other side.
+ uno_any_destruct( pException , 0 );
+ nResult = 0;
+ }
+ }
+ else
+ {
+ nResult = 0;
+ }
+ typelib_typedescription_release( pInterfaceType );
+ typelib_typedescription_release( pMethodType );
+ }
+
+ {
+ MutexGuard guard( m_mutex );
+ m_bRequestChangeHasBeenCalled = sal_False;
+ m_bServerWaitingForCommit = ( 0 == nResult );
+ }
+ return nResult;
+}
+
+// implementation for call from remote
+sal_Int32 SAL_CALL PropertyObject::implRequestChange( sal_Int32 nRandomNumber, uno_Any **ppException )
+{
+ sal_Int32 nResult = 0;
+ MutexGuard guard( m_mutex );
+ if( m_bRequestChangeHasBeenCalled )
+ {
+ // this side has also called requestChange, now negotiate, which side is allowed
+ // to commit the change !
+ if( m_nRandomNumberOfRequest > nRandomNumber )
+ {
+ // this side may commit !!!!
+ nResult = 0;
+ }
+ else if( m_nRandomNumberOfRequest == nRandomNumber )
+ {
+ // sorry, try again !
+ nResult = -1;
+ }
+ else if( m_nRandomNumberOfRequest < nRandomNumber )
+ {
+ // the other side may commit !
+ nResult = 1;
+ // m_bServerWaitingForCommit will be set by localRequestChange
+ }
+ }
+ else
+ {
+ // This side has NOT called requestChange, so the other side may commit
+ nResult = 1;
+ m_bServerWaitingForCommit = sal_True;
+ }
+
+ *ppException = 0;
+ return nResult;
+}
+
+
+
+void SAL_CALL PropertyObject::localCommitChange( const ::rtl::OUString &sProps , sal_Bool *pbExceptionThrown )
+{
+ // lock the bridge NOW !
+ // NOTE: it is not allowed for other threads to call, when a commit change is underway.
+ // The remote counterpart cannot if the call following the commit already uses
+ // the new properties or not.
+ MutexGuard guard( m_pBridgeImpl->m_marshalingMutex );
+
+ OUString oid = OUString::createFromAscii( g_NameOfUrpProtocolPropertiesObject );
+
+ osl_resetCondition( m_commitChangeCondition );
+
+ Properties props = *m_pLocalSetting;
+
+ typelib_TypeDescription *pInterfaceType = 0;
+ getCppuType( (Reference< XProtocolProperties > *) 0 ).getDescription( &pInterfaceType );
+
+ if( !pInterfaceType->bComplete )
+ {
+ typelib_typedescription_complete( &pInterfaceType );
+ }
+
+ typelib_TypeDescription *pMethodType = 0;
+ typelib_typedescriptionreference_getDescription(
+ &pMethodType,
+ ((typelib_InterfaceTypeDescription*) pInterfaceType)->ppAllMembers[METHOD_COMMIT_CHANGE] );
+
+// typelib_TypeDescription *pSequenceType= 0;
+
+
+ // extract name/value pairs
+ uno_Sequence *pSeq = 0;
+ assignFromStringToPropSeq( sProps, &pSeq );
+ assignFromPropSeqToStruct( pSeq , &props );
+// ::std::list< OUString > lst;
+// extractTokens( sProps , lst );
+
+// getCppuType( (Sequence< ProtocolProperty > *)0).getDescription( &pSequenceType );
+// uno_sequence_construct( &pSeq , pSequenceType , 0, lst.size() , 0 );
+// ProtocolProperty *pElements = (ProtocolProperty * ) pSeq->elements;
+
+// sal_Int32 i = 0;
+// for( ::std::list< OUString >::iterator ii = lst.begin() ; ii != lst.end() ; ++ ii, i++ )
+// {
+// sal_Int32 nAssign = (*ii).indexOf( '=' );
+// if( -1 == nAssign )
+// {
+// OString o = OUStringToOString( *ii, RTL_TEXTENCODING_ASCII_US );
+// OSL_ENSURE( !"wrong protocol propertyt format, ignored", o.getStr() );
+// }
+// OUString sPropName = (*ii).copy( 0, nAssign );
+// OUString sValue = (*ii).copy( nAssign +1, (*ii).getLength() - nAssign -1 );
+
+// sal_Int32 nIndex = getIndexFromString( sPropName );
+// if( -1 == nIndex )
+// {
+// OString o = OUStringToOString( sPropName , RTL_TEXTENCODING_ASCII_US);
+// OSL_ENSURE( !"unknown protocol property, ignored", o.getStr() );
+// }
+// switch( nIndex )
+// {
+// // bools
+// case PROPERTY_CLEARCACHE:
+// {
+// sal_Bool bClearCache = (sal_Bool ) sValue.toInt32();
+// assignToIdl( &(pElements[i]) , nIndex , bClearCache );
+// break;
+// }
+// // ints
+// case PROPERTY_TYPECACHESIZE:
+// case PROPERTY_OIDCACHESIZE:
+// case PROPERTY_TIDCACHESIZE:
+// case PROPERTY_FLUSHBLOCKSIZE:
+// case PROPERTY_ONEWAYTIMEOUT_MUSEC:
+// {
+// sal_Int32 nValue = sValue.toInt32();
+// assignToIdl( &(pElements[i]) , nIndex , nValue );
+// break;
+// }
+
+// // strings
+// case PROPERTY_VERSION:
+// assignToIdl( &(pElements[i]) , nIndex , sValue );
+// break;
+// default:
+// OString o = OUStringToOString( sPropName, RTL_TEXTENCODING_ASCII_US );
+// OSL_ENSURE( !"readonly protocol property, ignored" , o.getStr() );
+// }
+// assignFromIdlToStruct( &props, pElements[i] );
+// }
+
+ void *pArg1 = &pSeq;
+ uno_Any exception;
+ uno_Any *pException = &exception;
+
+ ClientJob job( m_pEnvRemote,
+ 0,
+ m_pBridgeImpl,
+ oid.pData,
+ pMethodType,
+ (typelib_InterfaceTypeDescription*) pInterfaceType,
+ 0,
+ &pArg1,
+ &pException );
+ job.setBridgePropertyCall();
+ if( job.pack() )
+ {
+ job.wait();
+ }
+ else
+ {
+ OSL_ASSERT( pException != NULL );
+ }
+
+ ::uno_type_destructData(
+ &pSeq, getCppuType( (Sequence< ProtocolProperty > *)0).getTypeLibType(), 0 );
+
+ *pbExceptionThrown = pException ? sal_True : sal_False;
+
+ if( pException )
+ {
+ OString o = OUStringToOString( ((com::sun::star::uno::Exception*)pException->pData)->Message,
+ RTL_TEXTENCODING_ASCII_US);
+ OSL_ENSURE( !"exception thrown during calling on PropertyObject",o.getStr() );
+ uno_any_destruct( pException , 0 );
+ }
+ else
+ {
+ m_pBridgeImpl->applyProtocolChanges( props );
+ m_bServerWaitingForCommit = sal_False;
+ m_bApplyProperties = sal_False;
+ }
+
+ // let the reader thread go ...
+ osl_setCondition( m_commitChangeCondition );
+
+ typelib_typedescription_release( pMethodType );
+ typelib_typedescription_release( pInterfaceType );
+}
+
+void SAL_CALL PropertyObject::implCommitChange( uno_Sequence *pSequence, uno_Any **ppException )
+{
+ MutexGuard guard( m_mutex );
+ m_propsToBeApplied = *m_pLocalSetting;
+
+ ProtocolProperty *pP = (ProtocolProperty * ) pSequence->elements;
+ for( sal_Int32 i = 0; i < pSequence->nElements ; i ++ )
+ {
+ if( ! assignFromIdlToStruct( &m_propsToBeApplied , pP[i] ) )
+ {
+ InvalidProtocolChangeException exception;
+ Type type = getCppuType( &exception );
+ exception.Message = OUString(RTL_CONSTASCII_USTRINGPARAM("urp: unknown Property "));
+ exception.Message += pP[i].Name;
+ exception.invalidProperty = pP[i];
+ exception.reason = 1;
+
+ uno_type_any_construct( *ppException, &exception, type.getTypeLibType() , 0 );
+
+ m_bApplyProperties = sal_False;
+ m_bServerWaitingForCommit = sal_False;
+ return;
+ }
+ }
+
+ m_bApplyProperties = sal_True;
+ *ppException = 0;
+}
+
+Properties SAL_CALL PropertyObject::getCommitedChanges()
+{
+ MutexGuard guard( m_mutex );
+ OSL_ASSERT( m_bApplyProperties );
+ m_bApplyProperties = sal_False;
+ m_bServerWaitingForCommit = sal_False;
+ return m_propsToBeApplied;
+}
+
+void SAL_CALL PropertyObject::waitUntilChangesAreCommitted()
+{
+ osl_waitCondition( m_commitChangeCondition , 0 );
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_propertyobject.hxx b/bridges/source/remote/urp/urp_propertyobject.hxx
new file mode 100644
index 000000000000..49628f522e3d
--- /dev/null
+++ b/bridges/source/remote/urp/urp_propertyobject.hxx
@@ -0,0 +1,107 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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 <stdio.h>
+#include <osl/interlck.h>
+#include <osl/mutex.hxx>
+
+#include <osl/conditn.h>
+#include <rtl/string.hxx>
+#include <uno/sequence2.h>
+
+#include <bridges/remote/remote.h>
+#include "urp_property.hxx"
+
+namespace bridges_urp {
+
+struct urp_BridgeImpl;
+const sal_Char g_NameOfUrpProtocolPropertiesObject[] = "UrpProtocolProperties";
+
+// helper functions
+void assignFromStringToStruct( const ::rtl::OUString & sProps , struct Properties *pProps );
+
+class PropertyObject : public remote_Interface
+{
+private:
+ ::osl::Mutex m_mutex;
+ oslCondition m_commitChangeCondition;
+ oslInterlockedCount m_nRefCount;
+ urp_BridgeImpl *m_pBridgeImpl;
+ struct Properties *m_pLocalSetting;
+ struct Properties m_propsToBeApplied;
+
+ uno_Environment *m_pEnvRemote;
+ sal_Int32 m_nRandomNumberOfRequest;
+ sal_Bool m_bRequestChangeHasBeenCalled;
+ sal_Bool m_bServerWaitingForCommit;
+ sal_Bool m_bApplyProperties;
+
+public:
+ PropertyObject(
+ struct Properties *pLocalSetting , uno_Environment *pEnvRemote, urp_BridgeImpl *pImpl );
+ ~PropertyObject();
+
+ void SAL_CALL thisAcquire( )
+ {
+ osl_incrementInterlockedCount( &m_nRefCount );
+ }
+
+ void SAL_CALL thisRelease()
+ {
+ if( ! osl_decrementInterlockedCount( &m_nRefCount ) )
+ {
+ delete this;
+ }
+ }
+
+ void SAL_CALL thisDispatch( typelib_TypeDescription const * pMemberType,
+ void * pReturn,
+ void * pArgs[],
+ uno_Any ** ppException );
+
+public: // local
+ sal_Int32 SAL_CALL localRequestChange( );
+ void SAL_CALL localCommitChange( const ::rtl::OUString &properties, sal_Bool *pbExceptionThrown );
+ void SAL_CALL localGetPropertiesFromRemote( struct Properties * );
+
+ // returns 0, if nothing was commited.
+ inline sal_Bool SAL_CALL changesHaveBeenCommited()
+ { return m_bApplyProperties; }
+ Properties SAL_CALL getCommitedChanges();
+
+ void SAL_CALL waitUntilChangesAreCommitted();
+
+protected:
+ // these methods are called by thisDispatch
+ void SAL_CALL implGetProperties( uno_Sequence **ppReturnValue );
+ sal_Int32 SAL_CALL implRequestChange( sal_Int32 nRandomNumber, uno_Any **ppException );
+ void SAL_CALL implCommitChange( uno_Sequence *seqOfProperties, uno_Any **ppException );
+};
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_reader.cxx b/bridges/source/remote/urp/urp_reader.cxx
new file mode 100644
index 000000000000..1dfaf30d4d1f
--- /dev/null
+++ b/bridges/source/remote/urp/urp_reader.cxx
@@ -0,0 +1,835 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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_bridges.hxx"
+#include <string.h>
+
+#include <osl/diagnose.h>
+#include <rtl/ustrbuf.hxx>
+
+#include <bridges/remote/connection.h>
+#include <bridges/remote/counter.hxx>
+#include <bridges/remote/context.h>
+#include <bridges/remote/helper.hxx>
+
+#include <com/sun/star/uno/XCurrentContext.hpp>
+#include <uno/environment.h>
+
+#include "urp_reader.hxx"
+#include "urp_writer.hxx"
+#include "urp_dispatch.hxx"
+#include "urp_job.hxx"
+#include "urp_bridgeimpl.hxx"
+#include "urp_log.hxx"
+#include "urp_propertyobject.hxx"
+
+using namespace ::rtl;
+using namespace ::osl;
+using namespace ::com::sun::star::uno;
+
+#if OSL_DEBUG_LEVEL > 1
+static MyCounter thisCounter( "DEBUG : ReaderThread" );
+#endif
+
+namespace bridges_urp
+{
+
+ /**
+ * This callback is used to ensure, that the release call is sent for the correct type.
+ *
+ ***/
+ void SAL_CALL urp_releaseRemoteCallback (
+ remote_Interface *, rtl_uString *pOid,
+ typelib_TypeDescriptionReference *pTypeRef, uno_Environment *pEnvRemote )
+ {
+ remote_Context *pContext = (remote_Context *) pEnvRemote->pContext;
+ urp_BridgeImpl *pImpl = (urp_BridgeImpl*) ( pContext->m_pBridgeImpl );
+
+ pImpl->m_pWriter->insertReleaseRemoteCall( pOid , pTypeRef );
+ }
+
+
+ struct MessageFlags
+ {
+ sal_uInt16 nMethodId;
+ sal_Bool bRequest;
+ sal_Bool bType;
+ sal_Bool bOid;
+ sal_Bool bTid;
+ sal_Bool bException;
+ sal_Bool bMustReply;
+ sal_Bool bSynchronous;
+ sal_Bool bMoreFlags;
+ sal_Bool bIgnoreCache;
+ sal_Bool bBridgePropertyCall;
+ ///--------------------------
+ inline MessageFlags()
+ {
+ bTid = sal_False;
+ bOid = sal_False;
+ bType = sal_False;
+ bException = sal_False;
+ bMoreFlags = sal_False;
+ bIgnoreCache = sal_False;
+ bBridgePropertyCall = sal_False;
+ }
+ //---------------------------
+ }; // end struct MessageFlags
+
+inline sal_Bool OReaderThread::getMemberTypeDescription(
+ typelib_InterfaceAttributeTypeDescription **ppAttributeType,
+ typelib_InterfaceMethodTypeDescription **ppMethodType,
+ sal_Bool *pbIsSetter,
+ sal_uInt16 nMethodId ,
+ typelib_TypeDescriptionReference * pITypeRef )
+{
+ if( pITypeRef->eTypeClass != typelib_TypeClass_INTERFACE )
+ {
+ OUStringBuffer sMessage;
+ sMessage.appendAscii( "interface type is not of typeclass interface (" );
+ sMessage.append( (sal_Int32) pITypeRef->eTypeClass );
+ m_pBridgeImpl->addError( sMessage.makeStringAndClear() );
+ OSL_ENSURE( 0 , "type is not an interface" );
+ return sal_False;
+ }
+
+ typelib_InterfaceTypeDescription *pInterfaceType = 0;
+ TYPELIB_DANGER_GET(
+ (typelib_TypeDescription **)&pInterfaceType , pITypeRef );
+ if( ! pInterfaceType )
+ {
+ OUStringBuffer sMessage;
+ sMessage.appendAscii( "No typedescription can be retrieved for type " );
+ sMessage.append( OUString( pITypeRef->pTypeName ) );
+ m_pBridgeImpl->addError( sMessage.makeStringAndClear() );
+ OSL_ENSURE( 0 , "urp: unknown type " );
+ return sal_False;
+ }
+
+ if( ! pInterfaceType->aBase.bComplete )
+ {
+ typelib_typedescription_complete( (typelib_TypeDescription **) &pInterfaceType );
+ }
+
+ if ( nMethodId >= pInterfaceType->nMapFunctionIndexToMemberIndex )
+ {
+ OUStringBuffer sMessage;
+ sMessage.appendAscii( "vtable out of range for type " );
+ sMessage.append( OUString( pITypeRef->pTypeName ) );
+ sMessage.appendAscii( " (" );
+ sMessage.append( (sal_Int32) nMethodId );
+ sMessage.appendAscii( " )" );
+ m_pBridgeImpl->addError( sMessage.makeStringAndClear() );
+
+ OSL_ENSURE( 0 , "vtable index out of range" );
+ return sal_False;
+ }
+
+ sal_Int32 nMemberIndex = pInterfaceType->pMapFunctionIndexToMemberIndex[ nMethodId ];
+
+ if( !( pInterfaceType->nAllMembers > nMemberIndex && nMemberIndex >= 0 ) )
+ {
+ OUStringBuffer sMessage;
+ sMessage.appendAscii( "vtable out of range for type " );
+ sMessage.append( OUString( pITypeRef->pTypeName ) );
+ sMessage.appendAscii( " (" );
+ sMessage.append( (sal_Int32) nMethodId );
+ sMessage.appendAscii( " )" );
+ m_pBridgeImpl->addError( sMessage.makeStringAndClear() );
+
+ OSL_ENSURE( 0 , "vtable index out of range" );
+ return sal_False;
+ }
+
+ typelib_InterfaceMemberTypeDescription *pMemberType = 0;
+ typelib_typedescriptionreference_getDescription(
+ (typelib_TypeDescription **) &pMemberType,pInterfaceType->ppAllMembers[nMemberIndex]);
+
+ if(! pMemberType )
+ {
+ OUStringBuffer sMessage;
+ sMessage.appendAscii( "unknown method type description for type" );
+ sMessage.append( OUString( pITypeRef->pTypeName ) );
+ sMessage.appendAscii( " (" );
+ sMessage.append( (sal_Int32) nMethodId );
+ sMessage.appendAscii( " )" );
+ m_pBridgeImpl->addError( sMessage.makeStringAndClear() );
+
+ OSL_ENSURE( 0 , "unknown method type description" );
+ return sal_False;
+ }
+
+ if( typelib_TypeClass_INTERFACE_ATTRIBUTE == pMemberType->aBase.eTypeClass )
+ {
+ // Note: pMapMemberIndexToFunctionIndex always contains the function
+ // index of the attribute getter! setter function index is getter index
+ // + 1.
+ *ppAttributeType = (typelib_InterfaceAttributeTypeDescription *) pMemberType;
+ *pbIsSetter = ! (
+ pInterfaceType->pMapMemberIndexToFunctionIndex[nMemberIndex] == nMethodId );
+ }
+ else
+ {
+ *ppMethodType = (typelib_InterfaceMethodTypeDescription *) pMemberType;
+ }
+
+ TYPELIB_DANGER_RELEASE( (typelib_TypeDescription * )pInterfaceType );
+ return sal_True;
+}
+
+OReaderThread::OReaderThread( remote_Connection *pConnection,
+ uno_Environment *pEnvRemote,
+ OWriterThread * pWriterThread ) :
+ m_pConnection( pConnection ),
+ m_pEnvRemote( pEnvRemote ),
+ m_pWriterThread( pWriterThread ),
+ m_bDestroyMyself( sal_False ),
+ m_bContinue( sal_True ),
+ m_pBridgeImpl((struct urp_BridgeImpl*)
+ ((remote_Context *)pEnvRemote->pContext)->m_pBridgeImpl ),
+ m_unmarshal( m_pBridgeImpl, m_pEnvRemote, ::bridges_remote::remote_createStub )
+{
+ m_pEnvRemote->acquireWeak( m_pEnvRemote );
+ m_pConnection->acquire( m_pConnection );
+#if OSL_DEBUG_LEVEL > 1
+ thisCounter.acquire();
+#endif
+}
+
+
+OReaderThread::~OReaderThread( )
+{
+ m_pEnvRemote->releaseWeak( m_pEnvRemote );
+#if OSL_DEBUG_LEVEL > 1
+ thisCounter.release();
+#endif
+}
+
+// may only be called in the callstack of this thread !!!!!
+// run() -> dispose() -> destroyYourself()
+void OReaderThread::destroyYourself()
+{
+ m_bDestroyMyself = sal_True;
+ m_pConnection->release( m_pConnection );
+ m_pConnection = 0;
+ m_bContinue = sal_False;
+}
+
+void OReaderThread::onTerminated()
+{
+ if( m_bDestroyMyself )
+ {
+ delete this;
+ }
+}
+
+
+void OReaderThread::disposeEnvironment()
+{
+ struct remote_Context *pContext =
+ ( struct remote_Context * ) m_pEnvRemote->pContext;
+ m_bContinue = sal_False;
+ if( ! pContext->m_pBridgeImpl->m_bDisposed )
+ {
+ uno_Environment *pEnvRemote = 0;
+ m_pEnvRemote->harden( &pEnvRemote , m_pEnvRemote );
+ if( pEnvRemote )
+ {
+ pEnvRemote->dispose( m_pEnvRemote );
+ pEnvRemote->release( m_pEnvRemote );
+ }
+ else
+ {
+ // environment has been disposed eitherway !
+ }
+ }
+}
+
+inline sal_Bool OReaderThread::readBlock( sal_Int32 *pnMessageCount )
+{
+ m_unmarshal.setSize( 8 );
+ if( 8 != m_pConnection->read( m_pConnection , m_unmarshal.getBuffer(), 8 ) )
+ {
+ OUString s( RTL_CONSTASCII_USTRINGPARAM( "Unexpected connection closure" ) );
+ m_pBridgeImpl->addError( s );
+ return sal_False;
+ }
+
+ sal_Int32 nSize;
+ m_unmarshal.unpackInt32( &nSize );
+ m_unmarshal.unpackInt32( pnMessageCount );
+
+ if( nSize < 0 )
+ {
+ // buffer too big
+ // no exception can be thrown, because there is no thread id, which could be
+ // used. -> terminate !
+ OUStringBuffer s;
+ s.appendAscii( "Packet-size too big (" );
+ s.append( (sal_Int64) (sal_uInt32 ) nSize );
+ s.append( sal_Unicode( ')' ) );
+ m_pBridgeImpl->addError( s.makeStringAndClear() );
+ OSL_ENSURE( 0 , "urp bridge: Packet-size too big" );
+ return sal_False;
+ }
+
+ if( 0 == nSize )
+ {
+ // normal termination !
+ return sal_False;
+ }
+
+ // allocate the necessary memory
+ if( ! m_unmarshal.setSize( nSize ) )
+ {
+ OUStringBuffer s;
+ s.appendAscii( "Packet-size too big, couln't allocate necessary memory (" );
+ s.append( (sal_Int64) (sal_uInt32 ) nSize );
+ s.append( sal_Unicode( ')' ) );
+ m_pBridgeImpl->addError( s.makeStringAndClear() );
+ OSL_ENSURE( 0 , "urp bridge: messages size too large, terminating connection" );
+ return sal_False;
+ }
+
+ sal_Int32 nRead = m_pConnection->read( m_pConnection , m_unmarshal.getBuffer() , nSize );
+
+ if( nSize != nRead )
+ {
+ OUStringBuffer s;
+ s.appendAscii( "Unexpected connection closure, inconsistent packet (" );
+ s.append( (sal_Int64) (sal_uInt32 ) nSize );
+ s.appendAscii( " asked, " );
+ s.append( (sal_Int64) (sal_uInt32 ) nRead );
+ s.appendAscii( " got )" );
+ m_pBridgeImpl->addError( s.makeStringAndClear() );
+ // couldn't get the asked amount of bytes, quit
+ // should only occur, when the environment has already been disposed
+ OSL_ENSURE( m_pBridgeImpl->m_bDisposed , "urp bridge: inconsistent packet, terminating connection." );
+ return sal_False;
+ }
+ return sal_True;
+}
+
+inline sal_Bool OReaderThread::readFlags( struct MessageFlags *pFlags )
+{
+ sal_uInt8 nBitField;
+ if( ! m_unmarshal.unpackInt8( &nBitField ) )
+ {
+ m_pBridgeImpl->addError( "Unexpected end of message header (1)" );
+ return sal_False;
+ }
+
+ if( HDRFLAG_LONGHEADER & nBitField )
+ {
+ // this is a long header, interpret the byte as bitfield
+ pFlags->bTid = (HDRFLAG_NEWTID & nBitField );
+ pFlags->bRequest = (HDRFLAG_REQUEST & nBitField);
+
+ if( pFlags->bRequest )
+ {
+ // request
+ pFlags->bType = ( HDRFLAG_NEWTYPE & nBitField );
+ pFlags->bOid = ( HDRFLAG_NEWOID & nBitField );
+ pFlags->bIgnoreCache = ( HDRFLAG_IGNORECACHE & nBitField );
+ pFlags->bMoreFlags = ( HDRFLAG_MOREFLAGS & nBitField );
+
+ if( pFlags->bMoreFlags )
+ {
+ // another byte with flags
+ sal_Int8 moreFlags;
+ if( ! m_unmarshal.unpackInt8( &moreFlags ) )
+ {
+ m_pBridgeImpl->addError( "Unexpected end of message header (2)" );
+ return sal_False;
+ }
+ pFlags->bSynchronous = ( HDRFLAG_SYNCHRONOUS & moreFlags );
+ pFlags->bMustReply = ( HDRFLAG_MUSTREPLY & moreFlags );
+ OSL_ENSURE( (pFlags->bSynchronous && pFlags->bMustReply) ||
+ (!pFlags->bSynchronous && !pFlags->bMustReply),
+ "urp-bridge : customized calls currently not supported !");
+ }
+
+ if( HDRFLAG_LONGMETHODID & nBitField )
+ {
+ // methodid as unsigned short
+ if( ! m_unmarshal.unpackInt16( &(pFlags->nMethodId )) )
+ {
+ m_pBridgeImpl->addError( "Unexpected end of message header (3)" );
+ return sal_False;
+ }
+ }
+ else
+ {
+ sal_uInt8 id;
+ if( ! m_unmarshal.unpackInt8( &id ) )
+ {
+ m_pBridgeImpl->addError( "Unexpected end of message header (4)" );
+ return sal_False;
+ }
+ pFlags->nMethodId = (sal_uInt16) id;
+ }
+ }
+ else
+ {
+ // reply
+ pFlags->bRequest = sal_False;
+ pFlags->bException = ( HDRFLAG_EXCEPTION & nBitField );
+ }
+ }
+ else
+ {
+ // short request
+ pFlags->bRequest = sal_True;
+ if( 0x40 & nBitField )
+ {
+ sal_uInt8 lower;
+ if( ! m_unmarshal.unpackInt8( &lower ) )
+ {
+ m_pBridgeImpl->addError( "Unexpected end of message header (5)" );
+ return sal_False;
+ }
+ pFlags->nMethodId = ( nBitField & 0x3f ) << 8 | lower;
+ }
+ else
+ {
+ pFlags->nMethodId = ( nBitField & 0x3f );
+ }
+ }
+ return sal_True;
+}
+
+void OReaderThread::run()
+{
+ // This vars are needed to hold oid,tid and type information, which should not be cached.
+ Type lastTypeNoCache;
+ OUString lastOidNoCache;
+ ByteSequence lastTidNoCache;
+
+ while( m_bContinue )
+ {
+ sal_Int32 nMessageCount;
+ if( ! readBlock( &nMessageCount ) )
+ {
+ disposeEnvironment();
+ break;
+ }
+
+ uno_Environment *pEnvRemote = 0;
+ m_pEnvRemote->harden( &pEnvRemote , m_pEnvRemote );
+ if( !pEnvRemote )
+ {
+ // environment has been disposed already, quit here
+ break;
+ }
+ ServerMultiJob *pMultiJob = 0;
+ remote_Interface *pLastRemoteI = 0;
+ while( ! m_unmarshal.finished() )
+ {
+#ifdef BRIDGES_URP_PROT
+ sal_uInt32 nLogStart = m_unmarshal.getPos();
+ sal_Bool bIsOneWay = sal_False;
+ OUString sMemberName;
+#endif
+ MessageFlags flags;
+
+ if( ! readFlags( &flags ) )
+ {
+ m_pBridgeImpl->addError( "incomplete message, skipping block" );
+ OSL_ENSURE ( 0 , "urp-bridge : incomplete message, skipping block" );
+ break;
+ }
+
+ // use these ** to access the ids fast ( avoid acquire/release calls )
+ sal_Sequence **ppLastTid = flags.bIgnoreCache ?
+ (sal_Sequence **) &lastTidNoCache :
+ (sal_Sequence **) &(m_pBridgeImpl->m_lastInTid);
+ rtl_uString **ppLastOid = flags.bIgnoreCache ?
+ (rtl_uString ** ) &lastOidNoCache :
+ (rtl_uString ** ) &(m_pBridgeImpl->m_lastInOid);
+ typelib_TypeDescriptionReference **ppLastType =
+ flags.bIgnoreCache ?
+ (typelib_TypeDescriptionReference ** ) &lastTypeNoCache :
+ (typelib_TypeDescriptionReference ** ) &(m_pBridgeImpl->m_lastInType);
+
+ // get new type
+ if( flags.bType )
+ {
+ typelib_TypeDescriptionReference *pTypeRef = 0;
+ if( m_unmarshal.unpackType( &pTypeRef ) )
+ {
+ // release the old type
+ typelib_typedescriptionreference_release( *ppLastType );
+ // set the new type
+ *ppLastType = pTypeRef;
+
+ // no release on pTypeRef necessary (will be released by type dtor)
+ }
+ else
+ {
+ typelib_typedescriptionreference_release( pTypeRef );
+ m_pBridgeImpl->addError( "error during unpacking (maybe cached) interface type" );
+ OSL_ENSURE( 0 , "urp-bridge : error during unpacking interface type, terminating connection" );
+ disposeEnvironment();
+ break;
+ }
+ if( m_pBridgeImpl->m_lastInType.getTypeClass() != TypeClass_INTERFACE )
+ {
+ OUStringBuffer sMessage;
+ sMessage.appendAscii( "interface type is not of typeclass interface (" );
+ sMessage.append( (sal_Int32) m_pBridgeImpl->m_lastInType.getTypeClass() );
+ m_pBridgeImpl->addError( sMessage.makeStringAndClear() );
+ OSL_ENSURE( 0 , "urp-bridge : not an interface type" );
+ disposeEnvironment();
+ break;
+ }
+ }
+ if( flags.bOid )
+ {
+ rtl_uString *pOid = 0;
+ if( m_unmarshal.unpackOid( &pOid ) )
+ {
+ rtl_uString_release( *ppLastOid );
+ *ppLastOid = pOid;
+ }
+ else
+ {
+ rtl_uString_release( pOid );
+ m_pBridgeImpl->addError( "error during unpacking (maybe cached) oid" );
+ OSL_ENSURE( 0 , "urp-bridge : error during unpacking cached data, terminating connection" );
+ disposeEnvironment();
+ break;
+ }
+ }
+
+ if( flags.bTid )
+ {
+ sal_Sequence *pSeq = 0;
+ if( m_unmarshal.unpackTid( &pSeq ) )
+ {
+ rtl_byte_sequence_release( *ppLastTid );
+ *ppLastTid = pSeq;
+ }
+ else
+ {
+ rtl_byte_sequence_release( pSeq );
+
+ m_pBridgeImpl->addError( "error during unpacking (maybe cached) tid" );
+ OSL_ENSURE( 0 , "urp-bridge : error during unpacking cached data, terminating connection" );
+ disposeEnvironment();
+ break;
+ }
+ }
+
+ // do the job
+ if( flags.bRequest )
+ {
+ bool bHasCc = m_pBridgeImpl->m_properties.bCurrentContext
+ && flags.nMethodId != REMOTE_RELEASE_METHOD_INDEX
+ && !rtl::OUString( *ppLastOid ).equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(
+ g_NameOfUrpProtocolPropertiesObject ) );
+ remote_Interface * pCc = 0;
+ if ( bHasCc )
+ {
+ typelib_TypeDescription * pType = 0;
+ TYPELIB_DANGER_GET(
+ &pType,
+ XCurrentContext::static_type().getTypeLibType() );
+ bool ok = m_unmarshal.unpack( &pCc, pType );
+ TYPELIB_DANGER_RELEASE( pType );
+ if ( !ok )
+ {
+ OSL_ENSURE(
+ false,
+ ("urp_bridge: error while unpacking current"
+ " context") );
+ disposeEnvironment();
+ break;
+ }
+ }
+
+ //--------------------------
+ // handle request
+ //--------------------------
+ // get the membertypedescription
+ typelib_InterfaceMethodTypeDescription *pMethodType = 0;
+ typelib_InterfaceAttributeTypeDescription *pAttributeType = 0;
+ sal_Bool bIsSetter = sal_False;
+
+ if( getMemberTypeDescription(
+ &pAttributeType, &pMethodType, &bIsSetter,
+ flags.nMethodId, *ppLastType ) )
+ {
+ if( ! pLastRemoteI || flags.bOid || flags.bType )
+ {
+ // a new interface must be retrieved
+
+ // retrieve the interface NOW from the environment
+ // (avoid race conditions : oneway followed by release )
+ typelib_InterfaceTypeDescription *pInterfaceType = 0;
+
+ TYPELIB_DANGER_GET(
+ (typelib_TypeDescription ** ) &pInterfaceType ,
+ *ppLastType );
+ if( !pInterfaceType )
+ {
+ OUStringBuffer sMessage;
+ sMessage.appendAscii( "Couldn't retrieve type description for type " );
+ sMessage.append( OUString( (*ppLastType)->pTypeName ) );
+ m_pBridgeImpl->addError( sMessage.makeStringAndClear() );
+ delete pMultiJob;
+ pMultiJob = 0;
+ disposeEnvironment();
+ pLastRemoteI = 0; // stubs are released during dispose eitherway
+ break;
+ }
+ pEnvRemote->pExtEnv->getRegisteredInterface(
+ pEnvRemote->pExtEnv, ( void ** ) &pLastRemoteI,
+ *ppLastOid, pInterfaceType );
+ TYPELIB_DANGER_RELEASE( (typelib_TypeDescription * )pInterfaceType );
+
+ if( !pLastRemoteI &&
+ REMOTE_RELEASE_METHOD_INDEX != flags.nMethodId &&
+ 0 == rtl_ustr_ascii_compare_WithLength(
+ (*ppLastOid)->buffer, (*ppLastOid)->length, g_NameOfUrpProtocolPropertiesObject ) )
+ {
+ // check for bridge internal propertyobject
+ pLastRemoteI = m_pBridgeImpl->m_pPropertyObject;
+ pLastRemoteI->acquire( pLastRemoteI );
+ flags.bBridgePropertyCall = sal_True;
+ }
+
+ // NOTE : Instance provider is called in the executing thread
+ // Otherwise, instance provider may block the bridge
+ }
+
+ sal_Bool bCallIsOneway = sal_False;
+ if( flags.bMoreFlags )
+ {
+ // flags override the default !
+ bCallIsOneway = ! flags.bSynchronous;
+ }
+ else if( pMethodType && pMethodType->bOneWay )
+ {
+ bCallIsOneway = sal_True;
+ }
+
+ if( pMultiJob && ! flags.bTid && bCallIsOneway && ! pMultiJob->isFull())
+ {
+ // add to the existing multijob, nothing to do here
+ }
+ else
+ {
+ // create a new multijob
+ if( pMultiJob )
+ {
+ // there exists an old one, start it first.
+ pMultiJob->initiate();
+ }
+
+ pMultiJob = new ServerMultiJob(
+ pEnvRemote,
+ static_cast< remote_Context * >(
+ pEnvRemote->pContext ),
+ *ppLastTid, m_pBridgeImpl, &m_unmarshal,
+ nMessageCount );
+ }
+
+ pMultiJob->setCurrentContext( bHasCc, pCc );
+ pMultiJob->setIgnoreCache( flags.bIgnoreCache );
+ pMultiJob->setType( *ppLastType );
+ if( pMethodType )
+ {
+ pMultiJob->setMethodType( pMethodType ,
+ REMOTE_RELEASE_METHOD_INDEX == flags.nMethodId,
+ bCallIsOneway );
+ }
+ else if( pAttributeType )
+ {
+ pMultiJob->setAttributeType( pAttributeType, bIsSetter, bCallIsOneway );
+ }
+ else
+ {
+ OSL_ASSERT( 0 );
+ }
+
+ if( pLastRemoteI )
+ pMultiJob->setInterface( pLastRemoteI );
+ else
+ pMultiJob->setOid( *ppLastOid );
+ } /* getMemberTypeDescription */
+ else
+ {
+ delete pMultiJob;
+ pMultiJob = 0;
+ pLastRemoteI = 0; // stubs are released during dispose eitherway
+ disposeEnvironment();
+ break;
+ }
+#ifdef BRIDGES_URP_PROT
+ bIsOneWay = pMethodType && pMethodType->bOneWay;
+ sMemberName = pMethodType ?
+ pMethodType->aBase.pMemberName :
+ pAttributeType->aBase.pMemberName;
+ sal_uInt32 nLogHeader = m_unmarshal.getPos();
+#endif
+ if( ! pMultiJob->extract( ) )
+ {
+ // severe error during extracting, dispose
+ delete pMultiJob;
+ pMultiJob = 0;
+ pLastRemoteI = 0; // stubs are released during dispose eitherway
+ disposeEnvironment();
+ break;
+ }
+
+#ifdef BRIDGES_URP_PROT
+ urp_logServingRequest(
+ m_pBridgeImpl, m_unmarshal.getPos() - nLogStart,
+ m_unmarshal.getPos() - nLogHeader,
+ !bIsOneWay,
+ sMemberName );
+#endif
+ if ( flags.bBridgePropertyCall )
+ {
+ // call to the bridge internal object.
+ // these calls MUST be executed within the dispatcher thread in order
+ // to synchronize properly with protocol changes
+ // NOTE : Threadid is not preserved for this call.
+
+ // lock the marshaling NOW !
+ {
+ MutexGuard guard( m_pBridgeImpl->m_marshalingMutex );
+
+ pMultiJob->execute();
+
+ if( m_pBridgeImpl->m_pPropertyObject->changesHaveBeenCommited() )
+ {
+ Properties props;
+ props = m_pBridgeImpl->m_pPropertyObject->getCommitedChanges();
+
+ // This call modified the protocol, apply the changes NOW !
+ m_pBridgeImpl->applyProtocolChanges( props );
+ }
+ }
+ delete pMultiJob;
+ pMultiJob = 0;
+ }
+ }
+ else
+ {
+ //--------------------------
+ // handle reply
+ //--------------------------
+ if( pMultiJob )
+ {
+ pMultiJob->initiate();
+ pMultiJob = 0;
+ }
+ if( pLastRemoteI )
+ {
+ pLastRemoteI->release( pLastRemoteI );
+ pLastRemoteI = 0;
+ }
+ ClientJob *pClientJob =
+ m_pBridgeImpl->m_clientJobContainer.remove( *( ByteSequence * )ppLastTid );
+
+ // Bridge MUST be already disposed, otherwise we got a wrong threadid
+ // from remote !
+ OSL_ASSERT( pClientJob || m_pBridgeImpl->m_bDisposed );
+ if( ! pClientJob )
+ {
+ OUStringBuffer error( 128 );
+ error.appendAscii( "ThreadID " );
+ OString o = byteSequence2HumanReadableString( *(ByteSequence* )ppLastTid );
+ error.appendAscii( o.getStr(), o.getLength() );
+ error.appendAscii( " unknown, so couldn't unmarshal reply" );
+ m_pBridgeImpl->addError( error.makeStringAndClear() );
+ pLastRemoteI = 0;
+ disposeEnvironment();
+ break;
+ }
+
+ pClientJob->m_bExceptionOccured = flags.bException;
+
+ pClientJob->setUnmarshal( &m_unmarshal );
+#ifdef BRIDGES_URP_PROT
+ sMemberName = pClientJob->m_pMethodType ?
+ pClientJob->m_pMethodType->aBase.pMemberName :
+ pClientJob->m_pAttributeType->aBase.pMemberName;
+ sal_uInt32 nLogHeader = m_unmarshal.getPos();
+#endif
+ if( ! pClientJob->extract( ) )
+ {
+ // severe error during extracting, dispose
+ pLastRemoteI = 0; // stubs are released during dispose eitherway
+ disposeEnvironment();
+ break;
+ }
+#ifdef BRIDGES_URP_PROT
+ urp_logGettingReply(
+ m_pBridgeImpl, m_unmarshal.getPos() - nLogStart,
+ m_unmarshal.getPos() - nLogHeader, sMemberName );
+#endif
+ sal_Bool bBridgePropertyCallAndWaitingForReply =
+ pClientJob->isBridgePropertyCall();
+
+ pClientJob->initiate();
+
+ if( bBridgePropertyCallAndWaitingForReply )
+ {
+ // NOTE : This must be the reply for commit change. The new properties
+ // are now applied by the clientJob thread, but the reader thread
+ // must wait for it, because the next message on the wire already
+ // uses the new protocol settings.
+ // waiting for the commit change reply
+ m_pBridgeImpl->m_pPropertyObject->waitUntilChangesAreCommitted();
+ }
+ }
+ } // end while( !m_unmarshal.finished() )
+
+ if( pLastRemoteI )
+ pLastRemoteI->release( pLastRemoteI );
+
+ if( pMultiJob )
+ pMultiJob->initiate();
+
+ if( pEnvRemote )
+ pEnvRemote->release( pEnvRemote );
+ }
+
+ if( m_pConnection )
+ {
+ m_pConnection->release( m_pConnection );
+ m_pConnection = 0;
+ }
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_reader.hxx b/bridges/source/remote/urp/urp_reader.hxx
new file mode 100644
index 000000000000..409cce526caf
--- /dev/null
+++ b/bridges/source/remote/urp/urp_reader.hxx
@@ -0,0 +1,81 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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 <osl/thread.hxx>
+
+#include "urp_unmarshal.hxx"
+
+struct remote_Connection;
+typedef struct _uno_Environment uno_Environment;
+
+namespace bridges_urp
+{
+
+class OWriterThread;
+struct MessageFlags;
+
+class OReaderThread :
+ public ::osl::Thread
+{
+public:
+ OReaderThread( remote_Connection *pConnection ,
+ uno_Environment *pEnvRemote,
+ OWriterThread *pWriterThread );
+ ~OReaderThread();
+
+ // may only be called in the callstack of this thread !!!!!
+ // run() -> disposeEnvironment() -> dispose() -> destroyYourself()
+ void destroyYourself();
+
+private:
+ virtual void SAL_CALL run();
+ virtual void SAL_CALL onTerminated();
+
+ inline sal_Bool readBlock( sal_Int32 *pnMessageCount );
+ inline sal_Bool readFlags( struct MessageFlags *pFlags );
+
+ void disposeEnvironment();
+
+ inline sal_Bool getMemberTypeDescription(
+ typelib_InterfaceAttributeTypeDescription **ppAttributeType,
+ typelib_InterfaceMethodTypeDescription **ppMethodType,
+ sal_Bool *pbIsSetter,
+ sal_uInt16 nMethodId ,
+ typelib_TypeDescriptionReference *pITypeRef);
+
+ remote_Connection *m_pConnection;
+ uno_Environment *m_pEnvRemote;
+ OWriterThread *m_pWriterThread;
+ sal_Bool m_bDestroyMyself;
+ sal_Bool m_bContinue;
+ urp_BridgeImpl *m_pBridgeImpl;
+ Unmarshal m_unmarshal;
+};
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_replycontainer.hxx b/bridges/source/remote/urp/urp_replycontainer.hxx
new file mode 100644
index 000000000000..ff04a15a8f94
--- /dev/null
+++ b/bridges/source/remote/urp/urp_replycontainer.hxx
@@ -0,0 +1,78 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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 <list>
+
+#include <osl/mutex.hxx>
+#include <osl/diagnose.h>
+
+#include "urp_threadid.hxx"
+
+namespace bridges_urp
+{
+ class ClientJob;
+ typedef ::std::hash_map< ::rtl::ByteSequence ,
+ ::std::list < ClientJob * > ,
+ HashThreadId ,
+ EqualThreadId > Id2ClientJobStackMap;
+
+ class urp_ClientJobContainer
+ {
+ public:
+ void add( const ::rtl::ByteSequence &id , ClientJob *p )
+ {
+ ::osl::MutexGuard guard( m_mutex );
+ m_map[id].push_back( p );
+ }
+
+ ClientJob *remove( const ::rtl::ByteSequence & id )
+ {
+ ::osl::MutexGuard guard( m_mutex );
+ Id2ClientJobStackMap::iterator ii = m_map.find( id );
+
+ ClientJob *p = 0;
+ if( ii != m_map.end() )
+ {
+ p = (*ii).second.back();
+ (*ii).second.pop_back();
+ if( (*ii).second.empty() )
+ {
+ m_map.erase( ii );
+ }
+ }
+
+ return p;
+ }
+
+ private:
+ ::osl::Mutex m_mutex;
+ Id2ClientJobStackMap m_map;
+ };
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_threadid.cxx b/bridges/source/remote/urp/urp_threadid.cxx
new file mode 100644
index 000000000000..4554057d22a8
--- /dev/null
+++ b/bridges/source/remote/urp/urp_threadid.cxx
@@ -0,0 +1,51 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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_bridges.hxx"
+#include "urp_threadid.hxx"
+
+#include <rtl/strbuf.hxx>
+
+using namespace rtl;
+
+namespace bridges_urp
+{
+ rtl::OString byteSequence2HumanReadableString( const rtl::ByteSequence &a )
+ {
+ const sal_uInt8 *p = (const sal_uInt8 * ) a.getConstArray();
+ sal_Int32 nLength = a.getLength();
+ OStringBuffer buf( a.getLength() * 2 + 2 );
+ buf.append( RTL_CONSTASCII_STRINGPARAM( "0x" ) );
+ for( sal_Int32 i = 0 ; i < nLength ; i ++ )
+ buf.append( (sal_Int32) p[i] , 16 );
+ return buf.makeStringAndClear();
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_threadid.hxx b/bridges/source/remote/urp/urp_threadid.hxx
new file mode 100644
index 000000000000..d26b1cdc0af9
--- /dev/null
+++ b/bridges/source/remote/urp/urp_threadid.hxx
@@ -0,0 +1,62 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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 _URP_THREADID_HXX_
+#define _URP_THREADID_HXX_
+
+#include <sal/types.h>
+#include <rtl/byteseq.hxx>
+#include <rtl/string.hxx>
+
+namespace bridges_urp
+{
+
+ 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;
+ }
+ };
+
+ rtl::OString byteSequence2HumanReadableString( const rtl::ByteSequence &a );
+}
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_unmarshal.cxx b/bridges/source/remote/urp/urp_unmarshal.cxx
new file mode 100644
index 000000000000..43802bc78d8a
--- /dev/null
+++ b/bridges/source/remote/urp/urp_unmarshal.cxx
@@ -0,0 +1,709 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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_bridges.hxx"
+#include <string.h>
+
+#include <osl/diagnose.h>
+
+#include <rtl/alloc.h>
+#include <rtl/ustrbuf.hxx>
+
+#include <uno/data.h>
+#include <uno/any2.h>
+#include <uno/sequence2.h>
+
+#include <com/sun/star/uno/Any.hxx>
+
+#include "urp_unmarshal.hxx"
+#include "urp_bridgeimpl.hxx"
+
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+namespace bridges_urp
+{
+static int g_nDetectLittleEndian = 1;
+char g_bSystemIsLittleEndian = ((char*)&g_nDetectLittleEndian)[0];
+
+
+Unmarshal::Unmarshal( struct urp_BridgeImpl *pBridgeImpl,
+ uno_Environment *pEnvRemote,
+ remote_createStubFunc callback ) :
+ m_nBufferSize( 4096 ),
+ m_base( (sal_Int8*) rtl_allocateMemory( m_nBufferSize ) ),
+ m_pos( m_base ),
+ m_nLength( 0 ),
+ m_callback( callback ),
+ m_pEnvRemote( pEnvRemote ),
+ m_pBridgeImpl( pBridgeImpl )
+{
+}
+
+Unmarshal::~Unmarshal()
+{
+ rtl_freeMemory( m_base );
+}
+
+// special unpacks
+sal_Bool Unmarshal::unpackTid( sal_Sequence **ppThreadId )
+{
+ sal_Int32 nSize;
+ sal_Bool bReturn = unpackCompressedSize( &nSize );
+ if( bReturn )
+ {
+ if( nSize )
+ {
+ rtl_byte_sequence_constructFromArray( ppThreadId , m_pos , nSize );
+ m_pos += nSize;
+ sal_uInt16 nIndex;
+ bReturn = unpackInt16( &nIndex );
+ if( nIndex < m_pBridgeImpl->m_properties.nTidCacheSize )
+ {
+ m_pBridgeImpl->m_pTidIn[nIndex] = *(ByteSequence * )ppThreadId;
+ }
+ else if( 0xffff != nIndex )
+ {
+ bReturn = sal_False;
+ rtl_byte_sequence_construct( ppThreadId , 0 );
+
+ OUStringBuffer error( 128 );
+ error.appendAscii( "cache index for tid " );
+ OString o = byteSequence2HumanReadableString( *(ByteSequence * ) ppThreadId );
+ error.appendAscii( o.getStr(), o.getLength() );
+ error.appendAscii( "out of range(0x");
+ error.append( (sal_Int32) nIndex ,16 );
+ error.appendAscii( ")" );
+ m_pBridgeImpl->addError( error.makeStringAndClear() );
+ }
+ }
+ else
+ {
+ sal_uInt16 nIndex;
+ bReturn = unpackInt16( &nIndex );
+ if( nIndex < m_pBridgeImpl->m_properties.nTidCacheSize )
+ {
+ *ppThreadId = m_pBridgeImpl->m_pTidIn[nIndex].getHandle();
+ rtl_byte_sequence_acquire( *ppThreadId );
+ }
+ else
+ {
+ bReturn = sal_False;
+ rtl_byte_sequence_construct( ppThreadId , 0 );
+ OUStringBuffer error(128);
+ error.appendAscii( "cache index for tids out of range(0x" );
+ error.append( (sal_Int32) nIndex ,16 );
+ error.appendAscii( ")" );
+ m_pBridgeImpl->addError( error.makeStringAndClear() );
+ }
+ }
+ }
+ else
+ {
+ m_pBridgeImpl->addError( "couldn't unpack thread id because of previous errors" );
+ }
+ return bReturn;
+}
+
+sal_Bool Unmarshal::unpackOid( rtl_uString **ppOid )
+{
+ sal_Bool bReturn = sal_True;
+ sal_uInt16 nCacheIndex = 0;
+
+ bReturn = bReturn && unpackString( ppOid );
+ bReturn = bReturn && unpackInt16( &nCacheIndex );
+
+ if( bReturn &&
+ ! ( 0xffff == nCacheIndex && 0 == (*ppOid)->length ) /* null reference */ )
+ {
+ if( (*ppOid)->length )
+ {
+ // new unknown reference
+ if( 0xffff != nCacheIndex )
+ {
+ // oid should be cached ?
+ if( nCacheIndex < m_pBridgeImpl->m_properties.nOidCacheSize )
+ {
+ m_pBridgeImpl->m_pOidIn[nCacheIndex] = *ppOid;
+ }
+ else
+ {
+ OUStringBuffer error( 128 );
+ error.appendAscii( "new oid provided (" );
+ error.append( *ppOid );
+ error.appendAscii( "), but new cache index is out of range(0x");
+ error.append( (sal_Int32) nCacheIndex ,16 );
+ error.appendAscii( ")" );
+ m_pBridgeImpl->addError( error.makeStringAndClear() );
+
+ bReturn = sal_False;
+ rtl_uString_new( ppOid );
+ }
+ }
+ }
+ else
+ {
+ // reference in cache !
+ if( nCacheIndex < m_pBridgeImpl->m_properties.nOidCacheSize )
+ {
+ rtl_uString_assign( ppOid , m_pBridgeImpl->m_pOidIn[nCacheIndex].pData );
+ }
+ else
+ {
+ bReturn = sal_False;
+ rtl_uString_new( ppOid );
+
+ OUStringBuffer error( 128 );
+ error.appendAscii( "cache index for oids out of range(0x");
+ error.append( (sal_Int32) nCacheIndex ,16 );
+ error.appendAscii( ")" );
+ m_pBridgeImpl->addError( error.makeStringAndClear() );
+ }
+ }
+ }
+
+ return bReturn;
+}
+
+sal_Bool Unmarshal::unpack( void *pDestination ,
+ typelib_TypeDescription *pTypeDescr )
+{
+ // Note: We implement unpack functionality without recursions in order
+ // to avoid stack overflows caused by rotten URP blocks.
+
+ m_aItemsToUnpack.push( UnpackItem( pDestination, pTypeDescr ) );
+
+ sal_Bool bReturn = sal_True;
+ do
+ {
+ void * pDest = m_aItemsToUnpack.top().pDest;
+ typelib_TypeDescription * pType = m_aItemsToUnpack.top().pType;
+ m_aItemsToUnpack.pop();
+
+ switch( pType->eTypeClass )
+ {
+ case typelib_TypeClass_VOID:
+ // do nothing
+ break;
+ case typelib_TypeClass_BYTE:
+ {
+ bReturn = unpackInt8( pDest );
+ break;
+ }
+ case typelib_TypeClass_BOOLEAN:
+ {
+ bReturn = ! checkOverflow( 1 );
+ if( bReturn )
+ {
+ *((sal_Bool*)pDest) = (sal_Bool ) ( *m_pos);
+ m_pos ++;
+ }
+ else
+ {
+ *((sal_Bool*)pDest) = 0;
+ }
+ break;
+ }
+
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ {
+ unpackInt16( pDest );
+ break;
+ }
+ case typelib_TypeClass_ENUM:
+ case typelib_TypeClass_FLOAT:
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ {
+ bReturn = unpackInt32( pDest );
+ break;
+ }
+ case typelib_TypeClass_DOUBLE:
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ {
+ sal_Int8 * p = static_cast< sal_Int8 * >(pDest);
+ bReturn = ! checkOverflow( 8 );
+ if( bReturn )
+ {
+ if( isSystemLittleEndian() )
+ {
+ p[7] = m_pos[0];
+ p[6] = m_pos[1];
+ p[5] = m_pos[2];
+ p[4] = m_pos[3];
+ p[3] = m_pos[4];
+ p[2] = m_pos[5];
+ p[1] = m_pos[6];
+ p[0] = m_pos[7];
+ }
+ else
+ {
+ p[0] = m_pos[0];
+ p[1] = m_pos[1];
+ p[2] = m_pos[2];
+ p[3] = m_pos[3];
+ p[4] = m_pos[4];
+ p[5] = m_pos[5];
+ p[6] = m_pos[6];
+ p[7] = m_pos[7];
+ }
+ m_pos += 8;
+ }
+ else
+ {
+ // Do not trigger alignment errors:
+ p[0] = p[1] = p[2] = p[3] = p[4] = p[5] = p[6] = p[7] = 0;
+ }
+ break;
+ }
+ case typelib_TypeClass_STRING:
+ {
+ unpackString( pDest );
+ break;
+ }
+ case typelib_TypeClass_ANY:
+ {
+ uno_Any *pAny = ( uno_Any * )pDest;
+
+ pAny->pType = 0;
+ // Type is acquired with typelib_typedescription_acquire
+
+ bReturn = unpackType( &(pAny->pType) );
+
+ typelib_TypeDescription *pDataType = 0;
+ if( bReturn && pAny->pType )
+ {
+ typelib_typedescriptionreference_getDescription( &pDataType , pAny->pType );
+
+ if( pDataType )
+ {
+ switch (pDataType->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ if (sizeof(void *) < sizeof(sal_Int64))
+ {
+ pAny->pData = rtl_allocateMemory( sizeof(sal_Int64) );
+ }
+ else
+ {
+ pAny->pData = &pAny->pReserved;
+ }
+ break;
+ case typelib_TypeClass_FLOAT:
+ if (sizeof(void *) < sizeof(float))
+ {
+ pAny->pData = rtl_allocateMemory( sizeof(float) );
+ }
+ else
+ {
+ pAny->pData = &pAny->pReserved;
+ }
+ break;
+ case typelib_TypeClass_DOUBLE:
+ if (sizeof(void *) < sizeof(double))
+ {
+ pAny->pData = rtl_allocateMemory( sizeof(double) );
+ }
+ else
+ {
+ pAny->pData = &pAny->pReserved;
+ }
+ break;
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_UNION:
+ case typelib_TypeClass_EXCEPTION:
+ case typelib_TypeClass_ARRAY:
+ pAny->pData = rtl_allocateMemory( pDataType->nSize );
+ break;
+ case typelib_TypeClass_ANY:
+ {
+ m_pBridgeImpl->addError(
+ OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "can't unmarshal any: any in any not supported!" ) ) );
+
+ pAny->pData = 0;
+ Type type; // void
+ pAny->pType = type.getTypeLibType();
+ typelib_typedescriptionreference_acquire( pAny->pType );
+
+ bReturn = sal_False;
+ break;
+ }
+ default:
+ pAny->pData = &pAny->pReserved;
+ }
+
+ if ( bReturn )
+ {
+ m_aItemsToUnpack.push(
+ UnpackItem( pAny->pData, pDataType ) );
+ }
+ }
+ else
+ {
+ OUStringBuffer error;
+ error.appendAscii( "can't unmarshal any because typedescription for " );
+ error.append( pAny->pType->pTypeName );
+ error.appendAscii( " is missing" );
+ m_pBridgeImpl->addError( error.makeStringAndClear() );
+ }
+ }
+
+ if( pDataType )
+ {
+ typelib_typedescription_release( pDataType );
+ }
+ else
+ {
+ pAny->pData = 0;
+ Type type; // void
+ pAny->pType = type.getTypeLibType();
+ typelib_typedescriptionreference_acquire( pAny->pType );
+
+ bReturn = sal_False;
+ }
+
+ break;
+ }
+ case typelib_TypeClass_INTERFACE:
+ {
+ *(remote_Interface**)pDest = 0;
+
+ rtl_uString *pString = 0;
+ bReturn = unpackOid( &pString ) && bReturn;
+
+ if( bReturn && pString && pString->length )
+ {
+ m_callback( (remote_Interface**) pDest ,
+ pString,
+ pType->pWeakRef ,
+ m_pEnvRemote,
+ urp_releaseRemoteCallback );
+ }
+ if( pString )
+ {
+ rtl_uString_release( pString );
+ }
+ break;
+ }
+ case typelib_TypeClass_TYPE:
+ {
+ bReturn = unpackType( pDest );
+ break;
+ }
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ typelib_CompoundTypeDescription * pCompType =
+ (typelib_CompoundTypeDescription *)pType;
+
+ // direct members
+ typelib_TypeDescriptionReference ** ppTypeRefs = pCompType->ppTypeRefs;
+ sal_Int32 * pMemberOffsets = pCompType->pMemberOffsets;
+ sal_Int32 nDescr = pCompType->nMembers;
+
+ // at least assume 1 byte per member
+ bReturn = bReturn && ! checkOverflow( nDescr * 1 );
+ for ( sal_Int32 nPos = nDescr; nPos; --nPos )
+ {
+ typelib_TypeDescription * pMemberType = 0;
+ typelib_typedescriptionreference_getDescription(
+ &pMemberType, ppTypeRefs[ nPos - 1 ] );
+
+ m_aItemsToUnpack.push(
+ UnpackItem( (char*)pDest + pMemberOffsets[ nPos - 1 ],
+ pMemberType,
+ true /* construct even in error case */ ) );
+
+ m_aTypesToRelease.push_back( pMemberType );
+ }
+
+ // parent
+ if (pCompType->pBaseTypeDescription)
+ {
+ m_aItemsToUnpack.push(
+ UnpackItem( pDest,
+ (typelib_TypeDescription *)
+ pCompType->pBaseTypeDescription ) );
+ }
+ break;
+ }
+ case typelib_TypeClass_SEQUENCE:
+ {
+ sal_Int32 nLen;
+ bReturn = unpackCompressedSize( &nLen );
+
+ // urp protocol does not allow to use the elementsize as a guess, if enough data
+ // is available. However, at least one byte per member must be within the message
+ bReturn = bReturn && ! checkOverflow( 1 * nLen );
+ uno_Sequence *pSequence = 0;
+ if( nLen && bReturn )
+ {
+ typelib_TypeDescriptionReference * pETRef =
+ ((typelib_IndirectTypeDescription *)pType)->pType;
+
+ typelib_TypeDescription * pET = 0;
+ typelib_typedescriptionreference_getDescription( &pET , pETRef );
+
+ if( pET )
+ {
+ sal_Int32 nElementSize = pET->nSize;
+
+ pSequence = (uno_Sequence *)rtl_allocateMemory(
+ SAL_SEQUENCE_HEADER_SIZE + nElementSize * nLen );
+ pSequence->nRefCount = 1;
+ pSequence->nElements = nLen;
+
+ if( typelib_TypeClass_BYTE == pET->eTypeClass )
+ {
+ memcpy( pSequence->elements , m_pos , nLen );
+ m_pos += nLen;
+ }
+ else
+ {
+ for ( sal_Int32 i = nLen; i; --i )
+ {
+ m_aItemsToUnpack.push(
+ UnpackItem(
+ ((char*)pSequence->elements)
+ + (i - 1) * nElementSize,
+ pET ) );
+ }
+ }
+ m_aTypesToRelease.push_back( pET );
+ }
+ else
+ {
+ bReturn = sal_False;
+ uno_constructData( &pSequence , pType );
+ OUStringBuffer error;
+ error.appendAscii( "can't unmarshal sequence, because there is no typedescription for element type " );
+ error.append( pETRef->pTypeName );
+ error.appendAscii( " available" );
+ m_pBridgeImpl->addError( error.makeStringAndClear() );
+ }
+ }
+ else
+ {
+ uno_constructData( &pSequence , pType );
+ }
+
+ *((uno_Sequence **)pDest) = pSequence;
+ break;
+ }
+ case typelib_TypeClass_UNION:
+ case typelib_TypeClass_ARRAY:
+ case typelib_TypeClass_SERVICE:
+ case typelib_TypeClass_MODULE:
+ case typelib_TypeClass_INTERFACE_METHOD:
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ case typelib_TypeClass_UNKNOWN:
+ default:
+ {
+ ::rtl::OUStringBuffer buffer( 128 );
+ buffer.appendAscii( RTL_CONSTASCII_STRINGPARAM("Unsupported typeclass during unmarshaling ("));
+ buffer.append( ( sal_Int32 ) pType->eTypeClass , 10 );
+ buffer.appendAscii( ")" );
+ m_pBridgeImpl->addError( buffer.makeStringAndClear() );
+ bReturn = sal_False;
+ }
+ }
+
+ if ( !bReturn )
+ {
+ // construct default data for every remaining item.
+ while ( !m_aItemsToUnpack.empty() )
+ {
+ const UnpackItem & rItem = m_aItemsToUnpack.top();
+
+ if ( rItem.bMustBeConstructed )
+ uno_constructData( rItem.pDest , rItem.pType );
+
+ m_aItemsToUnpack.pop();
+ }
+ }
+ }
+ while ( !m_aItemsToUnpack.empty() );
+
+ // release pending type descriptions
+ TypeDescVector::const_iterator it = m_aTypesToRelease.begin();
+ const TypeDescVector::const_iterator end = m_aTypesToRelease.end();
+ while ( it != end )
+ {
+ typelib_typedescription_release( *it );
+ it++;
+ }
+ m_aTypesToRelease.clear();
+
+ return bReturn;
+}
+
+sal_Bool Unmarshal::unpackType( void *pDest )
+{
+ *(typelib_TypeDescriptionReference **) pDest = 0;
+
+ sal_uInt8 nTypeClass;
+ sal_Bool bReturn = unpackInt8( &nTypeClass );
+
+ typelib_TypeDescriptionReference *pTypeRef = 0;
+ if( bReturn )
+ {
+ if( nTypeClass <= 14 /* any */ )
+ {
+ pTypeRef = * typelib_static_type_getByTypeClass((typelib_TypeClass )nTypeClass);
+ typelib_typedescriptionreference_acquire( pTypeRef );
+ }
+ else
+ {
+ sal_uInt16 nCacheIndex = 0;
+ bReturn = bReturn && unpackInt16( &nCacheIndex );
+
+ if( bReturn )
+ {
+ if( nTypeClass & 0x80 )
+ {
+ // new type
+ rtl_uString *pString = 0;
+ bReturn = bReturn && unpackString( &pString );
+ if( bReturn )
+ {
+ typelib_TypeDescription *pType = 0;
+ typelib_typedescription_getByName( &pType, pString );
+ if( pType )
+ {
+ // type is known in this process
+ if( (typelib_TypeClass )(nTypeClass & 0x7f) == pType->eTypeClass )
+ {
+ //typename and typeclass match, this is as it should be
+ pTypeRef = pType->pWeakRef;
+ typelib_typedescriptionreference_acquire( pTypeRef );
+ }
+ else
+ {
+ // typename and typeclass do not match, dispose the bridge
+ // as there must be inconsistent type base between both processes
+ // or trash comes over the wire ...
+ bReturn = sal_False;
+ OUStringBuffer error( 128 );
+ error.appendAscii( "it is tried to introduce type " );
+ error.append( pString );
+ error.appendAscii( "with typeclass " );
+ error.append( (sal_Int32)( nTypeClass & 0x7f ) , 10 );
+ error.appendAscii( " , which does not match with typeclass " );
+ error.append( (sal_Int32) pType->eTypeClass ,10 );
+ m_pBridgeImpl->addError( error.makeStringAndClear() );
+ }
+ typelib_typedescription_release( pType );
+ pType = 0;
+ }
+ else
+ {
+ // a type by this name is not known in the process.
+ if( (nTypeClass & 0x7f) < typelib_TypeClass_UNKNOWN )
+ {
+ // typeclass is within a valid range, introduce the new
+ // type.
+ typelib_typedescriptionreference_new(
+ &pTypeRef, (typelib_TypeClass )(nTypeClass & 0x7f), pString );
+ }
+ else
+ {
+ // typeclass is out of range !
+ bReturn = sal_False;
+ OUStringBuffer error( 128 );
+ error.appendAscii( "it is tried to introduce type " );
+ error.append( pString );
+ error.appendAscii( "with an out of range typeclass " );
+ error.append( (sal_Int32)( nTypeClass & 0x7f ) , 10 );
+ m_pBridgeImpl->addError( error.makeStringAndClear() );
+ }
+ }
+
+ if( bReturn && nCacheIndex != 0xffff )
+ {
+ if( nCacheIndex < m_pBridgeImpl->m_properties.nTypeCacheSize )
+ {
+ m_pBridgeImpl->m_pTypeIn[nCacheIndex] = *( Type * )&pTypeRef;
+ }
+ else
+ {
+ bReturn = sal_False;
+ OUStringBuffer error( 128 );
+ error.appendAscii( "cache index for type " );
+ error.append( pString );
+ error.appendAscii( "out of range(0x" );
+ error.append( (sal_Int32) nCacheIndex ,16 );
+ error.appendAscii( ")" );
+ m_pBridgeImpl->addError( error.makeStringAndClear() );
+ }
+ }
+ }
+ if( pString )
+ {
+ rtl_uString_release( pString );
+ }
+ }
+ else
+ {
+ if( nCacheIndex < m_pBridgeImpl->m_properties.nTypeCacheSize )
+ {
+ pTypeRef = m_pBridgeImpl->m_pTypeIn[nCacheIndex].getTypeLibType();
+ typelib_typedescriptionreference_acquire( pTypeRef );
+ }
+ else
+ {
+ bReturn = sal_False;
+ OUStringBuffer error;
+ error.appendAscii( "cache index for types out of range(0x" );
+ error.append( (sal_Int32) nCacheIndex ,16 );
+ error.appendAscii( ")" );
+ m_pBridgeImpl->addError( error.makeStringAndClear() );
+ }
+ }
+ }
+ }
+ }
+ if( ! pTypeRef )
+ {
+ pTypeRef = * typelib_static_type_getByTypeClass(typelib_TypeClass_VOID);
+ typelib_typedescriptionreference_acquire( pTypeRef );
+ }
+ // pTypeRef is already acquired
+ *(typelib_TypeDescriptionReference**)pDest = pTypeRef;
+ return bReturn;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_unmarshal.hxx b/bridges/source/remote/urp/urp_unmarshal.hxx
new file mode 100644
index 000000000000..07b03b606641
--- /dev/null
+++ b/bridges/source/remote/urp/urp_unmarshal.hxx
@@ -0,0 +1,281 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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 _URP_UNMARSHAL_HXX_
+#define _URP_UNMARSHAL_HXX_
+
+#include <stack>
+#include <vector>
+#include <rtl/byteseq.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <bridges/remote/context.h>
+
+#include <bridges/remote/helper.hxx>
+#include <com/sun/star/uno/Type.hxx>
+#include "urp_bridgeimpl.hxx"
+
+typedef struct _uno_Environment uno_Environment;
+struct remote_Interface;
+
+namespace bridges_urp
+{
+
+extern char g_bSystemIsLittleEndian;
+class ThreadId;
+struct urp_BridgeImpl;
+void SAL_CALL urp_releaseRemoteCallback(
+ remote_Interface *pRemoteI,rtl_uString *pOid,
+ typelib_TypeDescriptionReference *pTypeRef,
+ uno_Environment *pEnvRemote );
+
+struct UnpackItem
+{
+ void * pDest;
+ typelib_TypeDescription * pType;
+ bool bMustBeConstructed;
+
+ UnpackItem()
+ : pDest( 0 ), pType( 0 ), bMustBeConstructed( false ) {}
+ UnpackItem( void * d, typelib_TypeDescription * t, bool b = false )
+ : pDest( d ), pType( t ), bMustBeConstructed( b ) {}
+};
+
+typedef std::stack< UnpackItem > UnpackItemStack;
+typedef std::vector< typelib_TypeDescription * > TypeDescVector;
+
+class Unmarshal
+{
+public:
+ Unmarshal(
+ struct urp_BridgeImpl *,
+ uno_Environment *pEnvRemote,
+ remote_createStubFunc callback );
+ ~Unmarshal();
+
+ inline sal_Bool finished()
+ { return m_base + m_nLength == m_pos; }
+ inline sal_uInt32 getPos()
+ { return (sal_uInt32 ) (m_pos - m_base); }
+
+ inline sal_Bool setSize( sal_Int32 nSize );
+
+ sal_Bool unpack( void *pDest, typelib_TypeDescription *pType );
+ inline sal_Bool unpackCompressedSize( sal_Int32 *pData );
+ inline sal_Bool unpackInt8( void *pDest );
+ inline sal_Bool unpackString( void *pDest );
+ inline sal_Bool unpackInt16( void *pDest );
+ inline sal_Bool unpackInt32( void *pDest );
+ sal_Bool unpackType( void *pDest );
+
+ inline sal_Bool unpackAny( void *pDest );
+ sal_Bool unpackOid( rtl_uString **ppOid );
+ sal_Bool unpackTid( sal_Sequence **ppThreadId );
+
+ sal_Int8 *getBuffer()
+ { return m_base; }
+ inline sal_Bool isSystemLittleEndian()
+ { return g_bSystemIsLittleEndian; }
+
+private:
+ inline sal_Bool checkOverflow( sal_Int32 nNextMem );
+
+ UnpackItemStack m_aItemsToUnpack;
+ TypeDescVector m_aTypesToRelease;
+
+ sal_Int32 m_nBufferSize;
+ sal_Int8 *m_base;
+ sal_Int8 *m_pos;
+ sal_Int32 m_nLength;
+
+ remote_createStubFunc m_callback;
+ uno_Environment *m_pEnvRemote;
+ urp_BridgeImpl *m_pBridgeImpl;
+};
+
+inline sal_Bool Unmarshal::setSize( sal_Int32 nSize )
+{
+ if( nSize > m_nBufferSize )
+ {
+ // adjust buffer size and length.
+ sal_Int8 * base =
+ (sal_Int8*)rtl_reallocateMemory (m_base, sal_Size(nSize));
+ if (base != 0)
+ {
+ m_base = base;
+ m_nLength = m_nBufferSize = nSize;
+ }
+ }
+ else
+ {
+ // adjust buffer length, only.
+ m_nLength = nSize;
+ }
+
+ // reset buffer position, and leave.
+ m_pos = m_base;
+ return (m_nLength == nSize);
+}
+
+inline sal_Bool Unmarshal::checkOverflow( sal_Int32 nNextMem )
+{
+ sal_Bool bOverflow = nNextMem < 0 ||
+ (((sal_Int32)( m_pos - m_base )) + nNextMem ) > m_nLength;
+ if( bOverflow )
+ m_pBridgeImpl->addError( "message too short" );
+ return bOverflow;
+}
+
+
+inline sal_Bool Unmarshal::unpackInt8( void *pDest )
+{
+ sal_Bool bReturn = ! checkOverflow( 1 );
+ if( bReturn )
+ {
+ *((sal_Int8*)pDest ) = *m_pos;
+ m_pos++;
+ }
+ else
+ {
+ *((sal_Int8*)pDest ) = 0;
+ }
+ return bReturn;
+}
+
+inline sal_Bool Unmarshal::unpackInt32( void *pDest )
+{
+ sal_uInt32 *p = ( sal_uInt32 * ) pDest;
+ sal_Bool bReturn = ! checkOverflow(4);
+ if( bReturn )
+ {
+ if( isSystemLittleEndian() )
+ {
+ ((sal_Int8*) p )[3] = m_pos[0];
+ ((sal_Int8*) p )[2] = m_pos[1];
+ ((sal_Int8*) p )[1] = m_pos[2];
+ ((sal_Int8*) p )[0] = m_pos[3];
+ }
+ else
+ {
+ ((sal_Int8*) p )[3] = m_pos[3];
+ ((sal_Int8*) p )[2] = m_pos[2];
+ ((sal_Int8*) p )[1] = m_pos[1];
+ ((sal_Int8*) p )[0] = m_pos[0];
+ }
+ m_pos += 4;
+ }
+ else
+ {
+ *p = 0;
+ }
+ return bReturn;
+}
+
+inline sal_Bool Unmarshal::unpackInt16( void *pDest )
+{
+ sal_uInt16 *p = ( sal_uInt16 * ) pDest;
+
+ sal_Bool bReturn = ! checkOverflow( 2 );
+ if( bReturn )
+ {
+ if( isSystemLittleEndian() )
+ {
+ ((sal_Int8*) p )[1] = m_pos[0];
+ ((sal_Int8*) p )[0] = m_pos[1];
+ }
+ else
+ {
+ ((sal_Int8*) p )[1] = m_pos[1];
+ ((sal_Int8*) p )[0] = m_pos[0];
+ }
+ m_pos ++;
+ m_pos ++;
+ }
+ else
+ {
+ *p = 0;
+ }
+ return bReturn;
+}
+
+inline sal_Bool Unmarshal::unpackString( void *pDest )
+{
+ sal_Int32 nLength;
+ sal_Bool bReturn = unpackCompressedSize( &nLength );
+
+ bReturn = bReturn && ! checkOverflow( nLength );
+ if( bReturn )
+ {
+ *(rtl_uString **) pDest = 0;
+ rtl_string2UString( (rtl_uString**) pDest, (const sal_Char * )m_pos , nLength,
+ RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS );
+ m_pos += nLength;
+ }
+ else
+ {
+ *(rtl_uString ** ) pDest = 0;
+ rtl_uString_new( (rtl_uString **) pDest );
+ }
+ return bReturn;
+}
+
+inline sal_Bool Unmarshal::unpackCompressedSize( sal_Int32 *pData )
+{
+ sal_uInt8 n8Size;
+ sal_Bool bReturn = unpackInt8( &n8Size );
+ if( bReturn )
+ {
+ if( n8Size == 0xff )
+ {
+ unpackInt32( pData );
+ }
+ else
+ {
+ *pData = (sal_Int32 ) n8Size;
+ }
+ }
+ return bReturn;
+}
+
+inline sal_Bool Unmarshal::unpackAny( void *pDest )
+{
+ typelib_TypeDescriptionReference *pTypeRef =
+ * typelib_static_type_getByTypeClass( typelib_TypeClass_ANY );
+
+ typelib_TypeDescription * pTD = 0;
+ typelib_typedescriptionreference_getDescription( &pTD, pTypeRef );
+
+ sal_Bool bReturn = unpack( pDest, pTD );
+
+ typelib_typedescription_release( pTD );
+
+ return bReturn;
+}
+
+}
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_writer.cxx b/bridges/source/remote/urp/urp_writer.cxx
new file mode 100644
index 000000000000..38f85a7c4194
--- /dev/null
+++ b/bridges/source/remote/urp/urp_writer.cxx
@@ -0,0 +1,271 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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_bridges.hxx"
+#include <stdio.h>
+#include <osl/time.h>
+
+#include <osl/mutex.hxx>
+#include <osl/conditn.h>
+
+#include <typelib/typedescription.h>
+
+#include <bridges/remote/connection.h>
+#include <bridges/remote/remote.hxx>
+
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <bridges/remote/counter.hxx>
+
+#include "urp_writer.hxx"
+#include "urp_bridgeimpl.hxx"
+#include "urp_marshal.hxx"
+#include "urp_dispatch.hxx"
+
+#if OSL_DEBUG_LEVEL > 1
+static MyCounter thisCounter( "DEBUG : WriterThread" );
+#endif
+
+using namespace ::osl;
+
+namespace bridges_urp {
+
+OWriterThread::OWriterThread( remote_Connection *pConnection, urp_BridgeImpl *pBridgeImpl,
+ uno_Environment *pEnvRemote) :
+ m_bAbort( sal_False ),
+ m_bInBlockingWait( sal_False ),
+ m_bEnterBlockingWait( sal_False ),
+ m_pConnection( pConnection ),
+ m_pBridgeImpl( pBridgeImpl ),
+ m_pEnvRemote( pEnvRemote )
+
+{
+ m_oslCondition = osl_createCondition();
+ osl_resetCondition( m_oslCondition );
+ m_pConnection->acquire( m_pConnection );
+
+#if OSL_DEBUG_LEVEL > 1
+ thisCounter.acquire();
+#endif
+}
+
+OWriterThread::~OWriterThread()
+{
+ osl_destroyCondition( m_oslCondition );
+ m_pConnection->release( m_pConnection );
+#if OSL_DEBUG_LEVEL > 1
+ thisCounter.release();
+#endif
+}
+
+
+// touch is called with locked m_marshalingMutex
+void OWriterThread::touch( sal_Bool bImmediately )
+{
+ if( bImmediately || m_pBridgeImpl->m_blockMarshaler.getPos() > m_pBridgeImpl->m_properties.nFlushBlockSize )
+ {
+ write();
+ }
+ else
+ {
+ // wake the writer thread up
+ if( m_bInBlockingWait )
+ {
+ m_bInBlockingWait = sal_False;
+ osl_setCondition( m_oslCondition );
+ }
+ else
+ {
+ // ensure, that the writing thread does not enter blocking mode
+ m_bEnterBlockingWait = sal_False;
+ }
+ }
+}
+
+
+void OWriterThread::abortThread()
+{
+ MutexGuard guard( m_pBridgeImpl->m_marshalingMutex );
+
+ m_bAbort = sal_True;
+ m_bEnterBlockingWait = sal_False;
+ if( m_bInBlockingWait )
+ {
+ m_bInBlockingWait = sal_False;
+ osl_setCondition( m_oslCondition );
+ }
+}
+
+
+// must be called with locked marshaling mutex
+void OWriterThread::write()
+{
+ if( ! m_pBridgeImpl->m_blockMarshaler.empty() && ! m_bAbort )
+ {
+ m_pBridgeImpl->m_blockMarshaler.finish( m_pBridgeImpl->m_nMarshaledMessages);
+ m_pBridgeImpl->m_nMarshaledMessages = 0;
+
+ sal_Int32 nLength = m_pBridgeImpl->m_blockMarshaler.getSize();
+ sal_Int8 *pBuf = m_pBridgeImpl->m_blockMarshaler.getBuffer();
+
+ if( nLength != m_pConnection->write( m_pConnection, pBuf, nLength ))
+ {
+ m_pBridgeImpl->m_blockMarshaler.restart();
+ return;
+ }
+ m_pConnection->flush( m_pConnection );
+ m_pBridgeImpl->m_blockMarshaler.restart();
+ }
+}
+
+void OWriterThread::sendEmptyMessage()
+{
+ // must be called with locked marshaling mutex
+ sal_Int32 a[2] = {0,0};
+ m_pConnection->write( m_pConnection , (sal_Int8*) a , sizeof( sal_Int32) *2 );
+}
+
+void OWriterThread::insertReleaseRemoteCall(
+ rtl_uString *pOid,typelib_TypeDescriptionReference *pTypeRef)
+{
+ {
+ ::osl::MutexGuard guard( m_releaseCallMutex );
+
+ struct RemoteReleaseCall call;
+ call.sOid = pOid;
+ call.typeInterface = pTypeRef;
+ m_lstReleaseCalls.push_back( call );
+ }
+ {
+ MutexGuard guard( m_pBridgeImpl->m_marshalingMutex );
+ if( m_bInBlockingWait )
+ {
+ m_bInBlockingWait = sal_False;
+ osl_setCondition( m_oslCondition );
+ }
+ else
+ {
+ // ensure, that the writing thread does not enter blocking mode
+ m_bEnterBlockingWait = sal_False;
+ }
+ }
+}
+
+/* The release calls for doubled interfaces
+ *
+ *
+ ***/
+void OWriterThread::executeReleaseRemoteCalls()
+{
+ ::std::list< struct RemoteReleaseCall > lstReleaseCalls;
+ {
+ ::osl::MutexGuard guard( m_releaseCallMutex );
+ lstReleaseCalls.swap( m_lstReleaseCalls );
+ }
+
+ for( ::std::list< struct RemoteReleaseCall >::iterator ii = lstReleaseCalls.begin();
+ ii != lstReleaseCalls.end();
+ ++ ii )
+ {
+ struct RemoteReleaseCall &call = (*ii) ;
+
+ typelib_TypeDescription *pInterfaceTypeDesc = 0;
+ typelib_TypeDescription *pReleaseMethod = 0;
+
+ call.typeInterface.getDescription( &pInterfaceTypeDesc );
+ if( ! pInterfaceTypeDesc->bComplete )
+ {
+ typelib_typedescription_complete( &pInterfaceTypeDesc );
+ }
+
+ uno_Any any;
+ uno_Any *pAny = &any;
+
+ typelib_typedescriptionreference_getDescription(
+ &pReleaseMethod ,
+ ((typelib_InterfaceTypeDescription*)pInterfaceTypeDesc)->ppAllMembers[REMOTE_RELEASE_METHOD_INDEX] );
+
+ urp_sendRequest_internal(
+ m_pEnvRemote , pReleaseMethod, call.sOid.pData,
+ (typelib_InterfaceTypeDescription*) pInterfaceTypeDesc, 0, 0,
+ &pAny );
+
+ typelib_typedescription_release( pReleaseMethod );
+ typelib_typedescription_release( pInterfaceTypeDesc );
+ }
+}
+
+
+void OWriterThread::run()
+{
+ while( ! m_bAbort )
+ {
+ sal_Bool bWait;
+ {
+ MutexGuard guard( m_pBridgeImpl->m_marshalingMutex );
+ bWait = m_bEnterBlockingWait;
+ if( bWait )
+ {
+ osl_resetCondition( m_oslCondition );
+ m_bInBlockingWait = sal_True;
+ }
+ m_bEnterBlockingWait = sal_True;
+ }
+
+ // wait for some notification
+ if( bWait )
+ osl_waitCondition( m_oslCondition , 0 );
+ // (m_bInBlockingWait = sal_False was set by the activating thread)
+
+ if( m_bAbort )
+ break;
+
+ // Wait for the timeout
+ TimeValue value = { 0 , 1000 * m_pBridgeImpl->m_properties.nOnewayTimeoutMUSEC };
+ osl_resetCondition( m_oslCondition );
+ osl_waitCondition( m_oslCondition , &value );
+
+ // check if there are some release calls to be sent ....
+ executeReleaseRemoteCalls();
+
+ {
+ // write to the socket
+ MutexGuard guard( m_pBridgeImpl->m_marshalingMutex );
+ if( ! m_pBridgeImpl->m_blockMarshaler.empty() )
+ {
+ write();
+ }
+ }
+ }
+}
+
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_writer.hxx b/bridges/source/remote/urp/urp_writer.hxx
new file mode 100644
index 000000000000..f491bc9aadbc
--- /dev/null
+++ b/bridges/source/remote/urp/urp_writer.hxx
@@ -0,0 +1,85 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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 <list>
+
+#include <osl/conditn.h>
+#include <osl/mutex.hxx>
+
+#include <rtl/ustring.hxx>
+
+#include <osl/thread.hxx>
+
+#include <com/sun/star/uno/Type.hxx>
+
+struct remote_Connection;
+
+namespace bridges_urp
+{
+ struct RemoteReleaseCall
+ {
+ ::rtl::OUString sOid;
+ ::com::sun::star::uno::Type typeInterface;
+ };
+
+ struct urp_BridgeImpl;
+ class OWriterThread :
+ public ::osl::Thread
+ {
+ public:
+ OWriterThread( remote_Connection *pConnection,
+ urp_BridgeImpl *m_pBridgeImpl,
+ uno_Environment *pEnvRemote);
+ ~OWriterThread( );
+
+ virtual void SAL_CALL run();
+
+ void touch( sal_Bool bImmediately );
+ void sendEmptyMessage();
+
+ void abortThread();
+
+ void SAL_CALL insertReleaseRemoteCall (
+ rtl_uString *pOid,typelib_TypeDescriptionReference *pTypeRef);
+ void SAL_CALL executeReleaseRemoteCalls();
+
+ private:
+ void write();
+ oslCondition m_oslCondition;
+ sal_Bool m_bAbort;
+ sal_Bool m_bInBlockingWait;
+ sal_Bool m_bEnterBlockingWait;
+ remote_Connection *m_pConnection;
+ urp_BridgeImpl *m_pBridgeImpl;
+ uno_Environment *m_pEnvRemote; // this is held weak only
+
+ ::osl::Mutex m_releaseCallMutex;
+ ::std::list< struct RemoteReleaseCall > m_lstReleaseCalls;
+ };
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */