sb138: #i116038# fresh implementation of binary URP bridge

This commit is contained in:
sb
2011-01-26 09:26:59 +01:00
parent 6770fbe36b
commit 138ab06ecc
111 changed files with 6040 additions and 12788 deletions

3
binaryurp/prj/build.lst Normal file
View File

@@ -0,0 +1,3 @@
bu binaryurp : BOOST:boost LIBXSLT:libxslt cppu cppuhelper offuh sal salhelper stlport NULL
bu binaryurp\source nmake - all bu_source NULL
bu binaryurp\qa nmake - all bu_qa bu_source NULL

4
binaryurp/prj/d.lst Normal file
View File

@@ -0,0 +1,4 @@
..\%__SRC%\bin\binaryurp.uno.dll %_DEST%\bin%_EXT%\binaryurp.uno.dll
..\%__SRC%\lib\binaryurp.uno.dylib %_DEST%\lib%_EXT%\binaryurp.uno.dylib
..\%__SRC%\lib\binaryurp.uno.so %_DEST%\lib%_EXT%\binaryurp.uno.so
..\%__SRC%\misc\binaryurp.component %_DEST%\xml%_EXT%\binaryurp.component

77
binaryurp/qa/makefile.mk Normal file
View File

@@ -0,0 +1,77 @@
#*************************************************************************
#
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# Copyright 2000, 2011 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 = binaryurp
TARGET = qa
ENABLE_EXCEPTIONS = TRUE
.INCLUDE: settings.mk
CFLAGSCXX += $(CPPUNIT_CFLAGS)
DLLPRE =
SLOFILES = $(SLO)/test-cache.obj $(SLO)/test-unmarshal.obj
SHL1IMPLIB = i$(SHL1TARGET)
SHL1OBJS = $(SLO)/test-cache.obj
SHL1RPATH = NONE
SHL1STDLIBS = $(CPPUNITLIB) $(SALLIB)
SHL1TARGET = test-cache
SHL1VERSIONMAP = version.map
DEF1NAME = $(SHL1TARGET)
SHL2IMPLIB = i$(SHL2TARGET)
SHL2OBJS = \
$(SLO)/test-unmarshal.obj \
$(SLO)/binaryany.obj \
$(SLO)/bridge.obj \
$(SLO)/bridgefactory.obj \
$(SLO)/currentcontext.obj \
$(SLO)/incomingrequest.obj \
$(SLO)/lessoperators.obj \
$(SLO)/marshal.obj \
$(SLO)/outgoingrequests.obj \
$(SLO)/proxy.obj \
$(SLO)/reader.obj \
$(SLO)/unmarshal.obj \
$(SLO)/writer.obj
SHL2RPATH = NONE
SHL2STDLIBS = \
$(CPPUHELPERLIB) \
$(CPPULIB) \
$(CPPUNITLIB) \
$(SALHELPERLIB) \
$(SALLIB)
SHL2TARGET = test-unmarshal
SHL2VERSIONMAP = version.map
DEF2NAME = $(SHL2TARGET)
.INCLUDE: target.mk
.INCLUDE: _cppunit.mk

View File

@@ -0,0 +1,84 @@
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2000, 2011 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 "sal/config.h"
#include "cppunit/TestAssert.h"
#include "cppunit/TestFixture.h"
#include "cppunit/extensions/HelperMacros.h"
#include "cppunit/plugin/TestPlugIn.h"
#include "../source/cache.hxx"
namespace {
class Test: public CppUnit::TestFixture {
private:
CPPUNIT_TEST_SUITE(Test);
CPPUNIT_TEST(testNothingLostFromLruList);
CPPUNIT_TEST_SUITE_END();
void testNothingLostFromLruList();
};
// cf. jurt/test/com/sun/star/lib/uno/protocols/urp/Cache_Test.java:
void Test::testNothingLostFromLruList() {
int a[8];
for (int i = 0; i != sizeof a / sizeof a[0]; ++i) {
for (int j = 0; j != i; ++j) {
a[j] = 0;
}
for (;;) {
binaryurp::Cache< int > c(4);
for (int k = 0; k != i; ++k) {
bool f;
c.add(a[k], &f);
}
bool f;
CPPUNIT_ASSERT_EQUAL(
6,
c.add(-1, &f) + c.add(-2, &f) + c.add(-3, &f) + c.add(-4, &f));
int j = i - 1;
while (j >= 0 && a[j] == 3) {
--j;
}
if (j < 0) {
break;
}
++a[j];
for (int k = j + 1; k != i; ++k) {
a[k] = 0;
}
}
}
}
CPPUNIT_TEST_SUITE_REGISTRATION(Test);
}
CPPUNIT_PLUGIN_IMPLEMENT();

View File

@@ -0,0 +1,112 @@
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2000, 2011 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 "sal/config.h"
#include "com/sun/star/io/IOException.hpp"
#include "com/sun/star/uno/Sequence.hxx"
#include "cppu/unotype.hxx"
#include "cppunit/TestAssert.h"
#include "cppunit/TestFixture.h"
#include "cppunit/extensions/HelperMacros.h"
#include "cppunit/plugin/TestPlugIn.h"
#include "rtl/ref.hxx"
#include "rtl/string.h"
#include "sal/types.h"
#include "typelib/typedescription.hxx"
#include "../source/bridge.hxx"
#include "../source/cache.hxx"
#include "../source/readerstate.hxx"
#include "../source/unmarshal.hxx"
namespace {
namespace css = com::sun::star;
class Test: public CppUnit::TestFixture {
private:
CPPUNIT_TEST_SUITE(Test);
CPPUNIT_TEST(testTypeOfBooleanSequence);
CPPUNIT_TEST(testTypeOfVoidSequence);
CPPUNIT_TEST_SUITE_END();
void testTypeOfBooleanSequence();
void testTypeOfVoidSequence();
};
void Test::testTypeOfBooleanSequence() {
binaryurp::ReaderState state;
css::uno::Sequence< sal_Int8 > buf(13);
buf[0] = static_cast< sal_Int8 >(20 | 0x80); // sequence type | cache flag
buf[1] = static_cast< sal_Int8 >(binaryurp::cache::ignore >> 8);
buf[2] = static_cast< sal_Int8 >(binaryurp::cache::ignore & 0xFF);
buf[3] = RTL_CONSTASCII_LENGTH("[]boolean");
buf[4] = '[';
buf[5] = ']';
buf[6] = 'b';
buf[7] = 'o';
buf[8] = 'o';
buf[9] = 'l';
buf[10] = 'e';
buf[11] = 'a';
buf[12] = 'n';
binaryurp::Unmarshal m(rtl::Reference< binaryurp::Bridge >(), state, buf);
css::uno::TypeDescription t(m.readType());
CPPUNIT_ASSERT(
t.equals(
css::uno::TypeDescription(
cppu::UnoType< css::uno::Sequence< bool > >::get())));
m.done();
}
void Test::testTypeOfVoidSequence() {
binaryurp::ReaderState state;
css::uno::Sequence< sal_Int8 > buf(10);
buf[0] = static_cast< sal_Int8 >(20 | 0x80); // sequence type | cache flag
buf[1] = static_cast< sal_Int8 >(binaryurp::cache::ignore >> 8);
buf[2] = static_cast< sal_Int8 >(binaryurp::cache::ignore & 0xFF);
buf[3] = RTL_CONSTASCII_LENGTH("[]void");
buf[4] = '[';
buf[5] = ']';
buf[6] = 'v';
buf[7] = 'o';
buf[8] = 'i';
buf[9] = 'd';
binaryurp::Unmarshal m(rtl::Reference< binaryurp::Bridge >(), state, buf);
try {
m.readType();
CPPUNIT_FAIL("exception expected");
} catch (css::io::IOException &) {}
}
CPPUNIT_TEST_SUITE_REGISTRATION(Test);
}
CPPUNIT_PLUGIN_IMPLEMENT();

View File

@@ -1,8 +1,8 @@
#*************************************************************************
#
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# Copyright 2000, 2010 Oracle and/or its affiliates.
#
# Copyright 2000, 2011 Oracle and/or its affiliates.
#
# OpenOffice.org - a multi-platform office productivity suite
#
@@ -23,43 +23,12 @@
# <http://www.openoffice.org/license.html>
# for a copy of the LGPLv3 License.
#
#*************************************************************************
#***********************************************************************/
PRJ=..$/..$/..
UDK_3_0_0 {
global:
cppunitTestPlugIn;
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
local:
*;
};

View File

@@ -0,0 +1,98 @@
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2000, 2011 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 "sal/config.h"
#include "osl/diagnose.h"
#include "typelib/typeclass.h"
#include "typelib/typedescription.hxx"
#include "uno/any2.h"
#include "binaryany.hxx"
namespace binaryurp {
namespace {
namespace css = com::sun::star;
}
BinaryAny::BinaryAny() throw () {
uno_any_construct(&data_, 0, 0, 0);
}
BinaryAny::BinaryAny(css::uno::TypeDescription const & type, void * value)
throw ()
{
OSL_ASSERT(type.is());
uno_any_construct(&data_, value, type.get(), 0);
}
BinaryAny::BinaryAny(uno_Any const & raw) throw () {
OSL_ASSERT(raw.pType != 0);
data_.pType = raw.pType;
typelib_typedescriptionreference_acquire(data_.pType);
data_.pData = raw.pData == &raw.pReserved ? &data_.pReserved : raw.pData;
data_.pReserved = raw.pReserved;
}
BinaryAny::BinaryAny(BinaryAny const & other) throw () {
uno_type_any_construct(&data_, other.data_.pData, other.data_.pType, 0);
}
BinaryAny::~BinaryAny() throw () {
uno_any_destruct(&data_, 0);
}
BinaryAny & BinaryAny::operator =(BinaryAny const & other) throw () {
if (&other != this) {
uno_type_any_assign(&data_, other.data_.pData, other.data_.pType, 0, 0);
}
return *this;
}
uno_Any * BinaryAny::get() throw () {
return &data_;
}
css::uno::TypeDescription BinaryAny::getType() const throw () {
return css::uno::TypeDescription(data_.pType);
}
void * BinaryAny::getValue(css::uno::TypeDescription const & type) const
throw ()
{
OSL_ASSERT(
type.is() &&
(type.get()->eTypeClass == typelib_TypeClass_ANY ||
type.equals(css::uno::TypeDescription(data_.pType))));
return type.get()->eTypeClass == typelib_TypeClass_ANY
? &data_ : data_.pData;
}
}

View File

@@ -0,0 +1,73 @@
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2000, 2011 Oracle and/or its affiliates.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org. If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/
#ifndef INCLUDED_BINARYURP_SOURCE_BINARYANY_HXX
#define INCLUDED_BINARYURP_SOURCE_BINARYANY_HXX
#include "sal/config.h"
#include "uno/any2.h"
namespace com { namespace sun { namespace star { namespace uno {
class TypeDescription;
} } } }
namespace binaryurp {
class BinaryAny {
public:
BinaryAny() throw ();
BinaryAny(com::sun::star::uno::TypeDescription const & type, void * value)
throw ();
explicit BinaryAny(uno_Any const & raw) throw ();
// takes over raw.pData (but copies raw.pType); raw must not be passed
// to uno_any_destruct
BinaryAny(BinaryAny const & other) throw ();
~BinaryAny() throw ();
BinaryAny & operator =(BinaryAny const & other) throw ();
uno_Any * get() throw ();
com::sun::star::uno::TypeDescription getType() const throw ();
void * getValue(com::sun::star::uno::TypeDescription const & type) const
throw ();
private:
mutable uno_Any data_;
// mutable so that getValue() can return a non-const void *, as in turn
// required at various places in binary UNO
};
}
#endif

View File

@@ -3,7 +3,7 @@
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2000, 2010 Oracle and/or its affiliates.
* Copyright 2000, 2011 Oracle and/or its affiliates.
*
* OpenOffice.org - a multi-platform office productivity suite
*
@@ -28,7 +28,7 @@
<component loader="com.sun.star.loader.SharedLibrary"
xmlns="http://openoffice.org/2010/uno-components">
<implementation name="com.sun.star.comp.remotebridges.BridgeFactory">
<implementation name="com.sun.star.comp.bridge.BridgeFactory">
<service name="com.sun.star.bridge.BridgeFactory"/>
</implementation>
</component>

978
binaryurp/source/bridge.cxx Normal file
View File

@@ -0,0 +1,978 @@
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2000, 2011 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 "sal/config.h"
#include <algorithm>
#include <cstddef>
#include <limits>
#include <memory>
#include <vector>
#include "boost/noncopyable.hpp"
#include "com/sun/star/bridge/InvalidProtocolChangeException.hpp"
#include "com/sun/star/bridge/XBridge.hpp"
#include "com/sun/star/bridge/XInstanceProvider.hpp"
#include "com/sun/star/bridge/XProtocolProperties.hpp"
#include "com/sun/star/connection/XConnection.hpp"
#include "com/sun/star/io/IOException.hpp"
#include "com/sun/star/lang/DisposedException.hpp"
#include "com/sun/star/lang/EventObject.hpp"
#include "com/sun/star/lang/XEventListener.hpp"
#include "com/sun/star/uno/Reference.hxx"
#include "com/sun/star/uno/RuntimeException.hpp"
#include "com/sun/star/uno/Sequence.hxx"
#include "com/sun/star/uno/XInterface.hpp"
#include "cppuhelper/exc_hlp.hxx"
#include "cppuhelper/weak.hxx"
#include "osl/diagnose.h"
#include "osl/mutex.hxx"
#include "osl/thread.hxx"
#include "rtl/byteseq.hxx"
#include "rtl/random.h"
#include "rtl/ref.hxx"
#include "rtl/textenc.h"
#include "rtl/ustrbuf.hxx"
#include "rtl/ustring.h"
#include "rtl/ustring.hxx"
#include "sal/types.h"
#include "typelib/typeclass.h"
#include "typelib/typedescription.h"
#include "typelib/typedescription.hxx"
#include "uno/dispatcher.hxx"
#include "uno/environment.hxx"
#include "uno/lbnames.h"
#include "binaryany.hxx"
#include "bridge.hxx"
#include "bridgefactory.hxx"
#include "incomingreply.hxx"
#include "lessoperators.hxx"
#include "outgoingrequest.hxx"
#include "outgoingrequests.hxx"
#include "proxy.hxx"
#include "reader.hxx"
namespace binaryurp {
namespace {
namespace css = com::sun::star;
sal_Int32 random() {
sal_Int32 n;
rtlRandomPool pool = rtl_random_createPool();
rtl_random_getBytes(pool, &n, sizeof n);
rtl_random_destroyPool(pool);
return n;
}
extern "C" void SAL_CALL freeProxyCallback(uno_ExtEnvironment *, void * pProxy)
{
OSL_ASSERT(pProxy != 0);
static_cast< Proxy * >(pProxy)->do_free();
}
void joinThread(osl::Thread * thread) {
OSL_ASSERT(thread != 0);
if (thread->getIdentifier() != osl::Thread::getCurrentIdentifier()) {
thread->join();
}
}
class AttachThread: private boost::noncopyable {
public:
explicit AttachThread(uno_ThreadPool threadPool);
~AttachThread();
rtl::ByteSequence getTid() throw ();
private:
uno_ThreadPool threadPool_;
rtl::ByteSequence tid_;
};
AttachThread::AttachThread(uno_ThreadPool threadPool): threadPool_(threadPool) {
sal_Sequence * s = 0;
uno_getIdOfCurrentThread(&s);
tid_ = rtl::ByteSequence(s, rtl::BYTESEQ_NOACQUIRE);
uno_threadpool_attach(threadPool_);
}
AttachThread::~AttachThread() {
uno_threadpool_detach(threadPool_);
uno_releaseIdFromCurrentThread();
}
rtl::ByteSequence AttachThread::getTid() throw () {
return tid_;
}
class PopOutgoingRequest: private boost::noncopyable {
public:
PopOutgoingRequest(
OutgoingRequests & requests, rtl::ByteSequence const & tid,
OutgoingRequest const & request);
~PopOutgoingRequest();
void clear();
private:
OutgoingRequests & requests_;
rtl::ByteSequence tid_;
bool cleared_;
};
PopOutgoingRequest::PopOutgoingRequest(
OutgoingRequests & requests, rtl::ByteSequence const & tid,
OutgoingRequest const & request):
requests_(requests), tid_(tid), cleared_(false)
{
requests_.push(tid_, request);
}
PopOutgoingRequest::~PopOutgoingRequest() {
if (!cleared_) {
requests_.pop(tid_);
}
}
void PopOutgoingRequest::clear() {
cleared_ = true;
}
}
struct Bridge::SubStub {
com::sun::star::uno::UnoInterfaceReference object;
sal_uInt32 references;
};
Bridge::Bridge(
rtl::Reference< BridgeFactory > const & factory, rtl::OUString const & name,
css::uno::Reference< css::connection::XConnection > const & connection,
css::uno::Reference< css::bridge::XInstanceProvider > const & provider):
factory_(factory), name_(name), connection_(connection),
provider_(provider),
binaryUno_(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(UNO_LB_UNO))),
cppToBinaryMapping_(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME)),
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(UNO_LB_UNO))),
binaryToCppMapping_(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(UNO_LB_UNO)),
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME))),
protPropTid_(
reinterpret_cast< sal_Int8 const * >(".UrpProtocolPropertiesTid"),
RTL_CONSTASCII_LENGTH(".UrpProtocolPropertiesTid")),
protPropOid_(RTL_CONSTASCII_USTRINGPARAM("UrpProtocolProperties")),
protPropType_(
cppu::UnoType<
css::uno::Reference< css::bridge::XProtocolProperties > >::get()),
protPropRequest_(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"com.sun.star.bridge.XProtocolProperties::requestChange"))),
protPropCommit_(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"com.sun.star.bridge.XProtocolProperties::commitChange"))),
threadPool_(0), currentContextMode_(false), proxies_(0), calls_(0),
normalCall_(false), activeCalls_(0), terminated_(false),
mode_(MODE_REQUESTED)
{
OSL_ASSERT(factory.is() && connection.is());
if (!binaryUno_.is()) {
throw css::uno::RuntimeException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM("URP: no binary UNO environment")),
css::uno::Reference< css::uno::XInterface >());
}
if (!(cppToBinaryMapping_.is() && binaryToCppMapping_.is())) {
throw css::uno::RuntimeException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM("URP: no C++ UNO mapping")),
css::uno::Reference< css::uno::XInterface >());
}
passive_.set();
}
void Bridge::start() {
OSL_ASSERT(threadPool_ == 0 && !writer_.is() && !reader_.is());
threadPool_ = uno_threadpool_create();
OSL_ASSERT(threadPool_ != 0);
writer_.set(new Writer(this));
writer_->create();
reader_.set(new Reader(this));
reader_->create();
}
void Bridge::terminate() {
rtl::Reference< Reader > r;
rtl::Reference< Writer > w;
Listeners ls;
{
osl::MutexGuard g(mutex_);
if (terminated_) {
return;
}
std::swap(reader_, r);
std::swap(writer_, w);
ls.swap(listeners_);
terminated_ = true;
}
try {
connection_->close();
} catch (css::io::IOException & e) {
OSL_TRACE(
OSL_LOG_PREFIX "caught IO exception '%s'",
rtl::OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8).getStr());
}
OSL_ASSERT(w.is());
w->stop();
joinThread(r.get());
joinThread(w.get());
OSL_ASSERT(threadPool_ != 0);
uno_threadpool_dispose(threadPool_);
Stubs s;
{
osl::MutexGuard g(mutex_);
s.swap(stubs_);
}
for (Stubs::iterator i(s.begin()); i != s.end(); ++i) {
for (Stub::iterator j(i->second.begin()); j != i->second.end(); ++j) {
binaryUno_.get()->pExtEnv->revokeInterface(
binaryUno_.get()->pExtEnv, j->second.object.get());
}
}
factory_->removeBridge(this);
for (Listeners::iterator i(ls.begin()); i != ls.end(); ++i) {
try {
(*i)->disposing(
css::lang::EventObject(
static_cast< cppu::OWeakObject * >(this)));
} catch (css::uno::RuntimeException & e) {
OSL_TRACE(
OSL_LOG_PREFIX "caught runtime exception '%s'",
rtl::OUStringToOString(
e.Message, RTL_TEXTENCODING_UTF8).getStr());
}
}
}
css::uno::Reference< css::connection::XConnection > Bridge::getConnection()
const
{
return connection_;
}
css::uno::Reference< css::bridge::XInstanceProvider > Bridge::getProvider()
const
{
return provider_;
}
css::uno::Mapping & Bridge::getCppToBinaryMapping() {
return cppToBinaryMapping_;
}
BinaryAny Bridge::mapCppToBinaryAny(css::uno::Any const & cppAny) {
css::uno::Any in(cppAny);
BinaryAny out;
out.~BinaryAny();
uno_copyAndConvertData(
out.get(), &in,
css::uno::TypeDescription(cppu::UnoType< css::uno::Any >::get()).get(),
cppToBinaryMapping_.get());
return out;
}
uno_ThreadPool Bridge::getThreadPool() const {
OSL_ASSERT(threadPool_ != 0);
return threadPool_;
}
rtl::Reference< Writer > Bridge::getWriter() {
osl::MutexGuard g(mutex_);
if (terminated_) {
throw css::lang::DisposedException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"Binary URP bridge already disposed")),
static_cast< cppu::OWeakObject * >(this));
}
OSL_ASSERT(writer_.is());
return writer_;
}
css::uno::UnoInterfaceReference Bridge::registerIncomingInterface(
rtl::OUString const & oid, css::uno::TypeDescription const & type)
{
OSL_ASSERT(type.is());
if (oid.getLength() == 0) {
return css::uno::UnoInterfaceReference();
}
css::uno::UnoInterfaceReference obj(findStub(oid, type));
if (!obj.is()) {
binaryUno_.get()->pExtEnv->getRegisteredInterface(
binaryUno_.get()->pExtEnv,
reinterpret_cast< void ** >(&obj.m_pUnoI), oid.pData,
reinterpret_cast< typelib_InterfaceTypeDescription * >(type.get()));
if (obj.is()) {
makeReleaseCall(oid, type);
} else {
obj.set(new Proxy(this, oid, type), SAL_NO_ACQUIRE);
{
osl::MutexGuard g(mutex_);
OSL_ASSERT(
proxies_ < std::numeric_limits< std::size_t >::max());
++proxies_;
}
binaryUno_.get()->pExtEnv->registerProxyInterface(
binaryUno_.get()->pExtEnv,
reinterpret_cast< void ** >(&obj.m_pUnoI), &freeProxyCallback,
oid.pData,
reinterpret_cast< typelib_InterfaceTypeDescription * >(
type.get()));
}
}
return obj;
}
rtl::OUString Bridge::registerOutgoingInterface(
css::uno::UnoInterfaceReference const & object,
css::uno::TypeDescription const & type)
{
OSL_ASSERT(type.is());
if (!object.is()) {
return rtl::OUString();
}
rtl::OUString oid;
if (!Proxy::isProxy(this, object, &oid)) {
binaryUno_.get()->pExtEnv->getObjectIdentifier(
binaryUno_.get()->pExtEnv, &oid.pData, object.get());
osl::MutexGuard g(mutex_);
Stubs::iterator i(stubs_.find(oid));
Stub newStub;
Stub * stub = i == stubs_.end() ? &newStub : &i->second;
Stub::iterator j(stub->find(type));
//TODO: Release sub-stub if it is not successfully sent to remote side
// (otherwise, stub will leak until terminate()):
if (j == stub->end()) {
j = stub->insert(Stub::value_type(type, SubStub())).first;
if (stub == &newStub) {
i = stubs_.insert(Stubs::value_type(oid, Stub())).first;
std::swap(i->second, newStub);
j = i->second.find(type);
OSL_ASSERT(j != i->second.end());
}
j->second.object = object;
j->second.references = 1;
binaryUno_.get()->pExtEnv->registerInterface(
binaryUno_.get()->pExtEnv,
reinterpret_cast< void ** >(&j->second.object.m_pUnoI),
oid.pData,
reinterpret_cast< typelib_InterfaceTypeDescription * >(
type.get()));
} else {
OSL_ASSERT(stub != &newStub);
if (j->second.references == SAL_MAX_UINT32) {
throw css::uno::RuntimeException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"URP: stub reference count overflow")),
css::uno::Reference< css::uno::XInterface >());
}
++j->second.references;
}
}
return oid;
}
css::uno::UnoInterfaceReference Bridge::findStub(
rtl::OUString const & oid, css::uno::TypeDescription const & type)
{
OSL_ASSERT(oid.getLength() != 0 && type.is());
osl::MutexGuard g(mutex_);
Stubs::iterator i(stubs_.find(oid));
if (i != stubs_.end()) {
Stub::iterator j(i->second.find(type));
if (j != i->second.end()) {
return j->second.object;
}
for (j = i->second.begin(); j != i->second.end(); ++j) {
if (typelib_typedescription_isAssignableFrom(
type.get(), j->first.get()))
{
return j->second.object;
}
}
}
return css::uno::UnoInterfaceReference();
}
void Bridge::releaseStub(
rtl::OUString const & oid, css::uno::TypeDescription const & type)
{
OSL_ASSERT(oid.getLength() != 0 && type.is());
css::uno::UnoInterfaceReference obj;
bool unused;
{
osl::MutexGuard g(mutex_);
Stubs::iterator i(stubs_.find(oid));
if (i == stubs_.end()) {
throw css::uno::RuntimeException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM("URP: release unknown stub")),
css::uno::Reference< css::uno::XInterface >());
}
Stub::iterator j(i->second.find(type));
if (j == i->second.end()) {
throw css::uno::RuntimeException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM("URP: release unknown stub")),
css::uno::Reference< css::uno::XInterface >());
}
OSL_ASSERT(j->second.references > 0);
--j->second.references;
if (j->second.references == 0) {
obj = j->second.object;
i->second.erase(j);
if (i->second.empty()) {
stubs_.erase(i);
}
}
unused = becameUnused();
}
if (obj.is()) {
binaryUno_.get()->pExtEnv->revokeInterface(
binaryUno_.get()->pExtEnv, obj.get());
}
terminateWhenUnused(unused);
}
void Bridge::resurrectProxy(Proxy & proxy) {
uno_Interface * p = &proxy;
binaryUno_.get()->pExtEnv->registerProxyInterface(
binaryUno_.get()->pExtEnv,
reinterpret_cast< void ** >(&p), &freeProxyCallback,
proxy.getOid().pData,
reinterpret_cast< typelib_InterfaceTypeDescription * >(
proxy.getType().get()));
OSL_ASSERT(p == &proxy);
}
void Bridge::revokeProxy(Proxy & proxy) {
binaryUno_.get()->pExtEnv->revokeInterface(
binaryUno_.get()->pExtEnv, &proxy);
}
void Bridge::freeProxy(Proxy & proxy) {
try {
makeReleaseCall(proxy.getOid(), proxy.getType());
} catch (css::uno::RuntimeException & e) {
OSL_TRACE(
OSL_LOG_PREFIX "caught runtime exception '%s'",
rtl::OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8).getStr());
} catch (std::exception & e) {
OSL_TRACE(OSL_LOG_PREFIX "caught C++ exception '%s'", e.what());
}
bool unused;
{
osl::MutexGuard g(mutex_);
OSL_ASSERT(proxies_ > 0);
--proxies_;
unused = becameUnused();
}
terminateWhenUnused(unused);
}
void Bridge::incrementCalls(bool normalCall) throw () {
osl::MutexGuard g(mutex_);
OSL_ASSERT(calls_ < std::numeric_limits< std::size_t >::max());
++calls_;
normalCall_ |= normalCall;
}
void Bridge::decrementCalls() {
bool unused;
{
osl::MutexGuard g(mutex_);
OSL_ASSERT(calls_ > 0);
--calls_;
unused = becameUnused();
}
terminateWhenUnused(unused);
}
void Bridge::incrementActiveCalls() throw () {
osl::MutexGuard g(mutex_);
OSL_ASSERT(
activeCalls_ <= calls_ &&
activeCalls_ < std::numeric_limits< std::size_t >::max());
++activeCalls_;
passive_.reset();
}
void Bridge::decrementActiveCalls() throw () {
osl::MutexGuard g(mutex_);
OSL_ASSERT(activeCalls_ <= calls_ && activeCalls_ > 0);
--activeCalls_;
if (activeCalls_ == 0) {
passive_.set();
}
}
bool Bridge::makeCall(
rtl::OUString const & oid, css::uno::TypeDescription const & member,
bool setter, std::vector< BinaryAny > const & inArguments,
BinaryAny * returnValue, std::vector< BinaryAny > * outArguments)
{
std::auto_ptr< IncomingReply > resp;
{
AttachThread att(threadPool_);
PopOutgoingRequest pop(
outgoingRequests_, att.getTid(),
OutgoingRequest(OutgoingRequest::KIND_NORMAL, member, setter));
sendRequest(
att.getTid(), oid, css::uno::TypeDescription(), member,
inArguments);
pop.clear();
incrementCalls(true);
incrementActiveCalls();
void * job;
uno_threadpool_enter(threadPool_, &job);
resp.reset(static_cast< IncomingReply * >(job));
decrementActiveCalls();
decrementCalls();
}
if (resp.get() == 0) {
throw css::lang::DisposedException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"Binary URP bridge disposed during call")),
static_cast< cppu::OWeakObject * >(this));
}
*returnValue = resp->returnValue;
if (!resp->exception) {
*outArguments = resp->outArguments;
}
return resp->exception;
}
void Bridge::sendRequestChangeRequest() {
OSL_ASSERT(mode_ == MODE_REQUESTED);
random_ = random();
std::vector< BinaryAny > a;
a.push_back(
BinaryAny(
css::uno::TypeDescription(cppu::UnoType< sal_Int32 >::get()),
&random_));
sendProtPropRequest(OutgoingRequest::KIND_REQUEST_CHANGE, a);
}
void Bridge::handleRequestChangeReply(
bool exception, BinaryAny const & returnValue)
{
throwException(exception, returnValue);
sal_Int32 n = *static_cast< sal_Int32 * >(
returnValue.getValue(
css::uno::TypeDescription(cppu::UnoType< sal_Int32 >::get())));
sal_Int32 exp = 0;
switch (mode_) {
case MODE_REQUESTED:
case MODE_REPLY_1:
exp = 1;
break;
case MODE_REPLY_MINUS1:
exp = -1;
mode_ = MODE_REQUESTED;
break;
case MODE_REPLY_0:
exp = 0;
mode_ = MODE_WAIT;
break;
default:
OSL_ASSERT(false); // this cannot happen
break;
}
if (n != exp) {
throw css::uno::RuntimeException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"URP: requestChange reply with unexpected return value"
" received")),
static_cast< cppu::OWeakObject * >(this));
}
decrementCalls();
switch (exp) {
case -1:
sendRequestChangeRequest();
break;
case 0:
break;
case 1:
sendCommitChangeRequest();
break;
default:
OSL_ASSERT(false); // this cannot happen
break;
}
}
void Bridge::handleCommitChangeReply(
bool exception, BinaryAny const & returnValue)
{
bool ccMode = true;
try {
throwException(exception, returnValue);
} catch (css::bridge::InvalidProtocolChangeException &) {
ccMode = false;
}
if (ccMode) {
setCurrentContextMode();
}
OSL_ASSERT(mode_ == MODE_REQUESTED || mode_ == MODE_REPLY_1);
mode_ = MODE_NORMAL;
getWriter()->unblock();
decrementCalls();
}
void Bridge::handleRequestChangeRequest(
rtl::ByteSequence const & tid, std::vector< BinaryAny > const & inArguments)
{
OSL_ASSERT(inArguments.size() == 1);
switch (mode_) {
case MODE_REQUESTED:
{
sal_Int32 n2 = *static_cast< sal_Int32 * >(
inArguments[0].getValue(
css::uno::TypeDescription(
cppu::UnoType< sal_Int32 >::get())));
sal_Int32 ret;
if (n2 > random_) {
ret = 1;
mode_ = MODE_REPLY_0;
} else if (n2 == random_) {
ret = -1;
mode_ = MODE_REPLY_MINUS1;
} else {
ret = 0;
mode_ = MODE_REPLY_1;
}
getWriter()->sendDirectReply(
tid, protPropRequest_, false,
BinaryAny(
css::uno::TypeDescription(
cppu::UnoType< sal_Int32 >::get()),
&ret),
std::vector< BinaryAny >());
break;
}
case MODE_NORMAL:
{
mode_ = MODE_NORMAL_WAIT;
sal_Int32 ret = 1;
getWriter()->queueReply(
tid, protPropRequest_, false, false,
BinaryAny(
css::uno::TypeDescription(
cppu::UnoType< sal_Int32 >::get()),
&ret),
std::vector< BinaryAny >(), false);
break;
}
default:
throw css::uno::RuntimeException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"URP: unexpected requestChange request received")),
static_cast< cppu::OWeakObject * >(this));
}
}
void Bridge::handleCommitChangeRequest(
rtl::ByteSequence const & tid, std::vector< BinaryAny > const & inArguments)
{
bool ccMode = false;
bool exc = false;
BinaryAny ret;
OSL_ASSERT(inArguments.size() == 1);
css::uno::Sequence< css::bridge::ProtocolProperty > s;
OSL_VERIFY(mapBinaryToCppAny(inArguments[0]) >>= s);
for (sal_Int32 i = 0; i != s.getLength(); ++i) {
if (s[i].Name.equalsAsciiL(
RTL_CONSTASCII_STRINGPARAM("CurrentContext")))
{
ccMode = true;
} else {
ccMode = false;
exc = true;
ret = mapCppToBinaryAny(
css::uno::makeAny(
css::bridge::InvalidProtocolChangeException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"InvalidProtocolChangeException")),
css::uno::Reference< css::uno::XInterface >(), s[i],
1)));
break;
}
}
switch (mode_) {
case MODE_WAIT:
getWriter()->sendDirectReply(
tid, protPropCommit_, exc, ret, std::vector< BinaryAny >());
if (ccMode) {
setCurrentContextMode();
mode_ = MODE_NORMAL;
getWriter()->unblock();
} else {
mode_ = MODE_REQUESTED;
sendRequestChangeRequest();
}
break;
case MODE_NORMAL_WAIT:
getWriter()->queueReply(
tid, protPropCommit_, false, false, ret, std::vector< BinaryAny >(),
ccMode);
mode_ = MODE_NORMAL;
break;
default:
throw css::uno::RuntimeException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"URP: unexpected commitChange request received")),
static_cast< cppu::OWeakObject * >(this));
}
}
OutgoingRequest Bridge::lastOutgoingRequest(rtl::ByteSequence const & tid) {
OutgoingRequest req(outgoingRequests_.top(tid));
outgoingRequests_.pop(tid);
return req;
}
bool Bridge::isProtocolPropertiesRequest(
rtl::OUString const & oid, css::uno::TypeDescription const & type) const
{
return oid == protPropOid_ && type.equals(protPropType_);
}
void Bridge::setCurrentContextMode() {
osl::MutexGuard g(mutex_);
currentContextMode_ = true;
}
bool Bridge::isCurrentContextMode() {
osl::MutexGuard g(mutex_);
return currentContextMode_;
}
Bridge::~Bridge() {
if (threadPool_ != 0) {
uno_threadpool_destroy(threadPool_);
}
}
css::uno::Reference< css::uno::XInterface > Bridge::getInstance(
rtl::OUString const & sInstanceName) throw (css::uno::RuntimeException)
{
if (sInstanceName.getLength() == 0) {
throw css::uno::RuntimeException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"XBridge::getInstance sInstanceName must be non-empty")),
static_cast< cppu::OWeakObject * >(this));
}
for (sal_Int32 i = 0; i != sInstanceName.getLength(); ++i) {
if (sInstanceName[i] > 0x7F) {
throw css::io::IOException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"XBridge::getInstance sInstanceName contains non-ASCII"
" character")),
css::uno::Reference< css::uno::XInterface >());
}
}
css::uno::TypeDescription ifc(
cppu::UnoType< css::uno::Reference< css::uno::XInterface > >::get());
typelib_TypeDescription * p = ifc.get();
std::vector< BinaryAny > inArgs;
inArgs.push_back(
BinaryAny(
css::uno::TypeDescription(cppu::UnoType< css::uno::Type >::get()),
&p));
BinaryAny ret;
std::vector< BinaryAny> outArgs;
bool exc = makeCall(
sInstanceName,
css::uno::TypeDescription(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"com.sun.star.uno.XInterface::queryInterface"))),
false, inArgs, &ret, &outArgs);
throwException(exc, ret);
return css::uno::Reference< css::uno::XInterface >(
static_cast< css::uno::XInterface * >(
binaryToCppMapping_.mapInterface(
*static_cast< uno_Interface ** >(ret.getValue(ifc)),
ifc.get())),
css::uno::UNO_REF_NO_ACQUIRE);
}
rtl::OUString Bridge::getName() throw (css::uno::RuntimeException) {
return name_;
}
rtl::OUString Bridge::getDescription() throw (css::uno::RuntimeException) {
rtl::OUStringBuffer b(name_);
b.append(sal_Unicode(':'));
b.append(connection_->getDescription());
return b.makeStringAndClear();
}
void Bridge::dispose() throw (css::uno::RuntimeException) {
terminate();
// OOo expects dispose to not return while there are still remote calls in
// progress; an external protocol must ensure that dispose is not called
// from within an incoming or outgoing remote call, as passive_.wait() would
// otherwise deadlock:
passive_.wait();
}
void Bridge::addEventListener(
css::uno::Reference< css::lang::XEventListener > const & xListener)
throw (css::uno::RuntimeException)
{
OSL_ASSERT(xListener.is());
{
osl::MutexGuard g(mutex_);
if (!terminated_) {
listeners_.push_back(xListener);
return;
}
}
xListener->disposing(
css::lang::EventObject(static_cast< cppu::OWeakObject * >(this)));
}
void Bridge::removeEventListener(
css::uno::Reference< css::lang::XEventListener > const & aListener)
throw (css::uno::RuntimeException)
{
osl::MutexGuard g(mutex_);
Listeners::iterator i(
std::find(listeners_.begin(), listeners_.end(), aListener));
if (i != listeners_.end()) {
listeners_.erase(i);
}
}
void Bridge::sendCommitChangeRequest() {
OSL_ASSERT(mode_ == MODE_REQUESTED || mode_ == MODE_REPLY_1);
css::uno::Sequence< css::bridge::ProtocolProperty > s(1);
s[0].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CurrentContext"));
std::vector< BinaryAny > a;
a.push_back(mapCppToBinaryAny(css::uno::makeAny(s)));
sendProtPropRequest(OutgoingRequest::KIND_COMMIT_CHANGE, a);
}
void Bridge::sendProtPropRequest(
OutgoingRequest::Kind kind, std::vector< BinaryAny > const & inArguments)
{
OSL_ASSERT(
kind == OutgoingRequest::KIND_REQUEST_CHANGE ||
kind == OutgoingRequest::KIND_COMMIT_CHANGE);
incrementCalls(false);
css::uno::TypeDescription member(
kind == OutgoingRequest::KIND_REQUEST_CHANGE
? protPropRequest_ : protPropCommit_);
PopOutgoingRequest pop(
outgoingRequests_, protPropTid_, OutgoingRequest(kind, member, false));
getWriter()->sendDirectRequest(
protPropTid_, protPropOid_, protPropType_, member, inArguments);
pop.clear();
}
void Bridge::makeReleaseCall(
rtl::OUString const & oid, css::uno::TypeDescription const & type)
{
AttachThread att(threadPool_);
sendRequest(
att.getTid(), oid, type,
css::uno::TypeDescription(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"com.sun.star.uno.XInterface::release"))),
std::vector< BinaryAny >());
}
void Bridge::sendRequest(
rtl::ByteSequence const & tid, rtl::OUString const & oid,
css::uno::TypeDescription const & type,
css::uno::TypeDescription const & member,
std::vector< BinaryAny > const & inArguments)
{
getWriter()->queueRequest(tid, oid, type, member, inArguments);
}
void Bridge::throwException(bool exception, BinaryAny const & value) {
if (exception) {
cppu::throwException(mapBinaryToCppAny(value));
}
}
css::uno::Any Bridge::mapBinaryToCppAny(BinaryAny const & binaryAny) {
BinaryAny in(binaryAny);
css::uno::Any out;
out.~Any();
uno_copyAndConvertData(
&out, in.get(),
css::uno::TypeDescription(cppu::UnoType< css::uno::Any >::get()).get(),
binaryToCppMapping_.get());
return out;
}
bool Bridge::becameUnused() const {
return stubs_.empty() && proxies_ == 0 && calls_ == 0 && normalCall_;
}
void Bridge::terminateWhenUnused(bool unused) {
if (unused) {
// That the current thread considers the bridge unused implies that it
// is not within an incoming or outgoing remote call (so calling
// terminate cannot lead to deadlock):
terminate();
}
}
}

287
binaryurp/source/bridge.hxx Normal file
View File

@@ -0,0 +1,287 @@
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2000, 2011 Oracle and/or its affiliates.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org. If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/
#ifndef INCLUDED_BINARYURP_SOURCE_BRIDGE_HXX
#define INCLUDED_BINARYURP_SOURCE_BRIDGE_HXX
#include "sal/config.h"
#include <cstddef>
#include <list>
#include <map>
#include <vector>
#include "boost/noncopyable.hpp"
#include "com/sun/star/bridge/XBridge.hpp"
#include "com/sun/star/lang/XComponent.hpp"
#include "com/sun/star/uno/Reference.hxx"
#include "com/sun/star/uno/RuntimeException.hpp"
#include "cppuhelper/implbase2.hxx"
#include "osl/conditn.hxx"
#include "osl/mutex.hxx"
#include "rtl/ref.hxx"
#include "rtl/ustring.hxx"
#include "sal/types.h"
#include "uno/environment.hxx"
#include "uno/mapping.hxx"
#include "uno/threadpool.h"
#include "outgoingrequest.hxx"
#include "outgoingrequests.hxx"
#include "writer.hxx"
namespace binaryurp {
class BinaryAny;
class BridgeFactory;
class Proxy;
class Reader;
}
namespace com { namespace sun { namespace star {
namespace bridge { class XInstanceProvider; }
namespace connection { class XConnection; }
namespace lang { class XEventListener; }
namespace uno {
class Any;
class TypeDescription;
class UnoInterfaceReference;
class XInterface;
}
} } }
namespace rtl { class ByteSequence; }
namespace binaryurp {
class Bridge:
public cppu::WeakImplHelper2<
com::sun::star::bridge::XBridge, com::sun::star::lang::XComponent >,
private boost::noncopyable
{
public:
Bridge(
rtl::Reference< BridgeFactory > const & factory,
rtl::OUString const & name,
com::sun::star::uno::Reference<
com::sun::star::connection::XConnection > const & connection,
com::sun::star::uno::Reference<
com::sun::star::bridge::XInstanceProvider > const & provider);
void start();
// Internally waits for all incoming and outgoing remote calls to terminate,
// so must not be called from within such a call:
void terminate();
com::sun::star::uno::Reference< com::sun::star::connection::XConnection >
getConnection() const;
com::sun::star::uno::Reference< com::sun::star::bridge::XInstanceProvider >
getProvider() const;
com::sun::star::uno::Mapping & getCppToBinaryMapping();
BinaryAny mapCppToBinaryAny(com::sun::star::uno::Any const & cppAny);
uno_ThreadPool getThreadPool() const;
rtl::Reference< Writer > getWriter();
com::sun::star::uno::UnoInterfaceReference registerIncomingInterface(
rtl::OUString const & oid,
com::sun::star::uno::TypeDescription const & type);
rtl::OUString registerOutgoingInterface(
com::sun::star::uno::UnoInterfaceReference const & object,
com::sun::star::uno::TypeDescription const & type);
com::sun::star::uno::UnoInterfaceReference findStub(
rtl::OUString const & oid,
com::sun::star::uno::TypeDescription const & type);
void releaseStub(
rtl::OUString const & oid,
com::sun::star::uno::TypeDescription const & type);
void resurrectProxy(Proxy & proxy);
void revokeProxy(Proxy & proxy);
void freeProxy(Proxy & proxy);
void incrementCalls(bool normalCall) throw ();
void decrementCalls();
void incrementActiveCalls() throw ();
void decrementActiveCalls() throw ();
bool makeCall(
rtl::OUString const & oid,
com::sun::star::uno::TypeDescription const & member, bool setter,
std::vector< BinaryAny > const & inArguments, BinaryAny * returnValue,
std::vector< BinaryAny > * outArguments);
// Only called from reader_ thread:
void sendRequestChangeRequest();
// Only called from reader_ thread:
void handleRequestChangeReply(
bool exception, BinaryAny const & returnValue);
// Only called from reader_ thread:
void handleCommitChangeReply(bool exception, BinaryAny const & returnValue);
// Only called from reader_ thread:
void handleRequestChangeRequest(
rtl::ByteSequence const & tid,
std::vector< BinaryAny > const & inArguments);
// Only called from reader_ thread:
void handleCommitChangeRequest(
rtl::ByteSequence const & tid,
std::vector< BinaryAny > const & inArguments);
OutgoingRequest lastOutgoingRequest(rtl::ByteSequence const & tid);
bool isProtocolPropertiesRequest(
rtl::OUString const & oid,
com::sun::star::uno::TypeDescription const & type) const;
void setCurrentContextMode();
bool isCurrentContextMode();
private:
virtual ~Bridge();
virtual com::sun::star::uno::Reference< com::sun::star::uno::XInterface >
SAL_CALL getInstance(rtl::OUString const & sInstanceName)
throw (com::sun::star::uno::RuntimeException);
virtual rtl::OUString SAL_CALL getName()
throw (com::sun::star::uno::RuntimeException);
virtual rtl::OUString SAL_CALL getDescription()
throw (com::sun::star::uno::RuntimeException);
virtual void SAL_CALL dispose()
throw (com::sun::star::uno::RuntimeException);
virtual void SAL_CALL addEventListener(
com::sun::star::uno::Reference< com::sun::star::lang::XEventListener >
const & xListener)
throw (com::sun::star::uno::RuntimeException);
virtual void SAL_CALL removeEventListener(
com::sun::star::uno::Reference< com::sun::star::lang::XEventListener >
const & aListener)
throw (com::sun::star::uno::RuntimeException);
// Only called from reader_ thread:
void sendCommitChangeRequest();
// Only called from reader_ thread:
void sendProtPropRequest(
OutgoingRequest::Kind kind,
std::vector< BinaryAny > const & inArguments);
void makeReleaseCall(
rtl::OUString const & oid,
com::sun::star::uno::TypeDescription const & type);
void sendRequest(
rtl::ByteSequence const & tid, rtl::OUString const & oid,
com::sun::star::uno::TypeDescription const & type,
com::sun::star::uno::TypeDescription const & member,
std::vector< BinaryAny > const & inArguments);
void throwException(bool exception, BinaryAny const & value);
com::sun::star::uno::Any mapBinaryToCppAny(BinaryAny const & binaryAny);
bool becameUnused() const;
void terminateWhenUnused(bool unused);
typedef
std::list<
com::sun::star::uno::Reference<
com::sun::star::lang::XEventListener > >
Listeners;
struct SubStub;
typedef std::map< com::sun::star::uno::TypeDescription, SubStub > Stub;
typedef std::map< rtl::OUString, Stub > Stubs;
enum Mode {
MODE_REQUESTED, MODE_REPLY_MINUS1, MODE_REPLY_0, MODE_REPLY_1,
MODE_WAIT, MODE_NORMAL, MODE_NORMAL_WAIT };
rtl::Reference< BridgeFactory > factory_;
rtl::OUString name_;
com::sun::star::uno::Reference< com::sun::star::connection::XConnection >
connection_;
com::sun::star::uno::Reference< com::sun::star::bridge::XInstanceProvider >
provider_;
com::sun::star::uno::Environment binaryUno_;
com::sun::star::uno::Mapping cppToBinaryMapping_;
com::sun::star::uno::Mapping binaryToCppMapping_;
rtl::ByteSequence protPropTid_;
rtl::OUString protPropOid_;
com::sun::star::uno::TypeDescription protPropType_;
com::sun::star::uno::TypeDescription protPropRequest_;
com::sun::star::uno::TypeDescription protPropCommit_;
uno_ThreadPool threadPool_;
OutgoingRequests outgoingRequests_;
osl::Mutex mutex_;
Listeners listeners_;
rtl::Reference< Writer > writer_;
rtl::Reference< Reader > reader_;
bool currentContextMode_;
Stubs stubs_;
std::size_t proxies_;
std::size_t calls_;
bool normalCall_;
std::size_t activeCalls_;
osl::Condition passive_;
// to guarantee that passive_ is eventually set (to avoid deadlock, see
// dispose), activeCalls_ only counts those calls for which it can be
// guaranteed that incrementActiveCalls is indeed followed by
// decrementActiveCalls, without an intervening exception
bool terminated_;
// Only accessed from reader_ thread:
Mode mode_;
sal_Int32 random_;
};
}
#endif

View File

@@ -0,0 +1,232 @@
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2000, 2011 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 "sal/config.h"
#include <algorithm>
#include "com/sun/star/connection/XConnection.hpp"
#include "com/sun/star/uno/Exception.hpp"
#include "com/sun/star/uno/Reference.hxx"
#include "com/sun/star/uno/RuntimeException.hpp"
#include "com/sun/star/uno/XComponentContext.hpp"
#include "com/sun/star/uno/XInterface.hpp"
#include "cppuhelper/factory.hxx"
#include "cppuhelper/implementationentry.hxx"
#include "osl/diagnose.h"
#include "rtl/ref.hxx"
#include "sal/types.h"
#include "uno/lbnames.h"
#include "bridge.hxx"
#include "bridgefactory.hxx"
namespace binaryurp {
namespace {
namespace css = com::sun::star;
}
css::uno::Reference< css::uno::XInterface > BridgeFactory::static_create(
css::uno::Reference< css::uno::XComponentContext > const & xContext)
SAL_THROW((css::uno::Exception))
{
return static_cast< cppu::OWeakObject * >(new BridgeFactory(xContext));
}
rtl::OUString BridgeFactory::static_getImplementationName() {
return rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"com.sun.star.comp.bridge.BridgeFactory"));
}
css::uno::Sequence< rtl::OUString >
BridgeFactory::static_getSupportedServiceNames() {
rtl::OUString name(
RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bridge.BridgeFactory"));
return css::uno::Sequence< rtl::OUString >(&name, 1);
}
void BridgeFactory::removeBridge(
css::uno::Reference< css::bridge::XBridge > const & bridge)
{
OSL_ASSERT(bridge.is());
rtl::OUString n(bridge->getName());
osl::MutexGuard g(*this);
if (n.getLength() == 0) {
BridgeList::iterator i(
std::find(unnamed_.begin(), unnamed_.end(), bridge));
if (i != unnamed_.end()) {
unnamed_.erase(i);
}
} else {
BridgeMap::iterator i(named_.find(n));
if (i != named_.end() && i->second == bridge) {
named_.erase(i);
}
}
}
BridgeFactory::BridgeFactory(
css::uno::Reference< css::uno::XComponentContext > const & context):
BridgeFactoryBase(*static_cast< osl::Mutex * >(this)), context_(context)
{
OSL_ASSERT(context.is());
}
BridgeFactory::~BridgeFactory() {}
rtl::OUString BridgeFactory::getImplementationName()
throw (css::uno::RuntimeException)
{
return static_getImplementationName();
}
sal_Bool BridgeFactory::supportsService(rtl::OUString const & ServiceName)
throw (css::uno::RuntimeException)
{
css::uno::Sequence< rtl::OUString > s(getSupportedServiceNames());
for (sal_Int32 i = 0; i != s.getLength(); ++i) {
if (ServiceName == s[i]) {
return true;
}
}
return false;
}
css::uno::Sequence< rtl::OUString > BridgeFactory::getSupportedServiceNames()
throw (css::uno::RuntimeException)
{
return static_getSupportedServiceNames();
}
css::uno::Reference< css::bridge::XBridge > BridgeFactory::createBridge(
rtl::OUString const & sName, rtl::OUString const & sProtocol,
css::uno::Reference< css::connection::XConnection > const & aConnection,
css::uno::Reference< css::bridge::XInstanceProvider > const &
anInstanceProvider)
throw (
css::bridge::BridgeExistsException, css::lang::IllegalArgumentException,
css::uno::RuntimeException)
{
rtl::Reference< Bridge > b;
{
osl::MutexGuard g(*this);
if (named_.find(sName) != named_.end()) {
throw css::bridge::BridgeExistsException(
sName, static_cast< cppu::OWeakObject * >(this));
}
if (!(sProtocol.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("urp")) &&
aConnection.is()))
{
throw css::lang::IllegalArgumentException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"BridgeFactory::createBridge: sProtocol != urp ||"
" aConnection == null")),
static_cast< cppu::OWeakObject * >(this), -1);
}
b.set(new Bridge(this, sName, aConnection, anInstanceProvider));
if (sName.getLength() == 0) {
unnamed_.push_back(
css::uno::Reference< css::bridge::XBridge >(b.get()));
} else {
named_[sName] = b.get();
}
}
b->start();
return css::uno::Reference< css::bridge::XBridge >(b.get());
}
css::uno::Reference< css::bridge::XBridge > BridgeFactory::getBridge(
rtl::OUString const & sName) throw (css::uno::RuntimeException)
{
osl::MutexGuard g(*this);
BridgeMap::iterator i(named_.find(sName));
return i == named_.end()
? css::uno::Reference< css::bridge::XBridge >() : i->second;
}
css::uno::Sequence< css::uno::Reference< css::bridge::XBridge > >
BridgeFactory::getExistingBridges() throw (css::uno::RuntimeException) {
osl::MutexGuard g(*this);
if (unnamed_.size() > SAL_MAX_INT32) {
throw css::uno::RuntimeException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"BridgeFactory::getExistingBridges: too many")),
static_cast< cppu::OWeakObject * >(this));
}
sal_Int32 n = static_cast< sal_Int32 >(unnamed_.size());
if (named_.size() > static_cast< sal_uInt32 >(SAL_MAX_INT32 - n)) {
throw css::uno::RuntimeException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"BridgeFactory::getExistingBridges: too many")),
static_cast< cppu::OWeakObject * >(this));
}
n = static_cast< sal_Int32 >(n + named_.size());
css::uno::Sequence< css::uno::Reference< css::bridge::XBridge > > s(n);
sal_Int32 i = 0;
for (BridgeList::iterator j(unnamed_.begin()); j != unnamed_.end(); ++j) {
s[i++] = *j;
}
for (BridgeMap::iterator j(named_.begin()); j != named_.end(); ++j) {
s[i++] = j->second;
}
return s;
}
}
namespace {
static cppu::ImplementationEntry const services[] = {
{ &binaryurp::BridgeFactory::static_create,
&binaryurp::BridgeFactory::static_getImplementationName,
&binaryurp::BridgeFactory::static_getSupportedServiceNames,
&cppu::createSingleComponentFactory, 0, 0 },
{ 0, 0, 0, 0, 0, 0 }
};
}
extern "C" SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory(
char const * pImplName, void * pServiceManager, void * pRegistryKey)
{
return cppu::component_getFactoryHelper(
pImplName, pServiceManager, pRegistryKey, services);
}
extern "C" SAL_DLLPUBLIC_EXPORT void SAL_CALL
component_getImplementationEnvironment(
char const ** ppEnvTypeName, uno_Environment **)
{
*ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
}

View File

@@ -0,0 +1,144 @@
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2000, 2011 Oracle and/or its affiliates.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org. If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/
#ifndef INCLUDED_BINARYURP_SOURCE_BRIDGEFACTORY_HXX
#define INCLUDED_BINARYURP_SOURCE_BRIDGEFACTORY_HXX
#include "sal/config.h"
#include <list>
#include <map>
#include "boost/noncopyable.hpp"
#include "com/sun/star/bridge/XBridgeFactory.hpp"
#include "com/sun/star/lang/XServiceInfo.hpp"
#include "com/sun/star/uno/Exception.hpp"
#include "com/sun/star/uno/Reference.hxx"
#include "com/sun/star/uno/RuntimeException.hpp"
#include "cppuhelper/compbase2.hxx"
#include "sal/types.h"
namespace com { namespace sun { namespace star {
namespace connection { class XConnection; }
namespace uno {
class XComponentContext;
class XInterface;
}
} } }
namespace binaryurp {
// That BridgeFactory derives from XComponent appears to be a historic mistake;
// the implementation does not care about a disposed state:
typedef
cppu::WeakComponentImplHelper2<
com::sun::star::lang::XServiceInfo,
com::sun::star::bridge::XBridgeFactory >
BridgeFactoryBase;
class BridgeFactory:
private osl::Mutex, public BridgeFactoryBase, private boost::noncopyable
{
public:
static com::sun::star::uno::Reference< com::sun::star::uno::XInterface >
SAL_CALL static_create(
com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >
const & xContext)
SAL_THROW((com::sun::star::uno::Exception));
static rtl::OUString SAL_CALL static_getImplementationName();
static com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL
static_getSupportedServiceNames();
void removeBridge(
com::sun::star::uno::Reference< com::sun::star::bridge::XBridge >
const & bridge);
using BridgeFactoryBase::acquire;
using BridgeFactoryBase::release;
private:
explicit BridgeFactory(
com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >
const & context);
virtual ~BridgeFactory();
virtual rtl::OUString SAL_CALL getImplementationName()
throw (com::sun::star::uno::RuntimeException);
virtual sal_Bool SAL_CALL supportsService(rtl::OUString const & ServiceName)
throw (com::sun::star::uno::RuntimeException);
virtual com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL
getSupportedServiceNames() throw (com::sun::star::uno::RuntimeException);
virtual com::sun::star::uno::Reference< com::sun::star::bridge::XBridge >
SAL_CALL createBridge(
rtl::OUString const & sName, rtl::OUString const & sProtocol,
com::sun::star::uno::Reference<
com::sun::star::connection::XConnection > const & aConnection,
com::sun::star::uno::Reference<
com::sun::star::bridge::XInstanceProvider > const &
anInstanceProvider)
throw (
com::sun::star::bridge::BridgeExistsException,
com::sun::star::lang::IllegalArgumentException,
com::sun::star::uno::RuntimeException);
virtual com::sun::star::uno::Reference< com::sun::star::bridge::XBridge >
SAL_CALL getBridge(
rtl::OUString const & sName)
throw (com::sun::star::uno::RuntimeException);
virtual
com::sun::star::uno::Sequence<
com::sun::star::uno::Reference< com::sun::star::bridge::XBridge > >
SAL_CALL getExistingBridges() throw (com::sun::star::uno::RuntimeException);
typedef
std::list<
com::sun::star::uno::Reference< com::sun::star::bridge::XBridge > >
BridgeList;
typedef
std::map<
rtl::OUString,
com::sun::star::uno::Reference< com::sun::star::bridge::XBridge > >
BridgeMap;
com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >
context_;
BridgeList unnamed_;
BridgeMap named_;
};
}
#endif

134
binaryurp/source/cache.hxx Executable file
View File

@@ -0,0 +1,134 @@
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2000, 2011 Oracle and/or its affiliates.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org. If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/
#ifndef INCLUDED_BINARYURP_SOURCE_CACHE_HXX
#define INCLUDED_BINARYURP_SOURCE_CACHE_HXX
#include "sal/config.h"
#include <cstddef>
#include <map>
#include "boost/noncopyable.hpp"
#include "osl/diagnose.h"
#include "sal/types.h"
namespace binaryurp {
namespace cache {
enum { size = 256, ignore = 0xFFFF };
}
template< typename T > class Cache: private boost::noncopyable {
public:
explicit Cache(std::size_t size):
size_(size), first_(map_.end()), last_(map_.end())
{
OSL_ASSERT(size < cache::ignore);
}
sal_uInt16 add(T const & content, bool * found) {
OSL_ASSERT(found != 0);
typename Map::iterator i(map_.find(content));
*found = i != map_.end();
if (i == map_.end()) {
typename Map::size_type n = map_.size();
if (n < size_) {
i =
(map_.insert(
typename Map::value_type(
content,
Entry(
static_cast< sal_uInt16 >(n), map_.end(),
first_)))).
first;
if (first_ == map_.end()) {
last_ = i;
} else {
first_->second.prev = i;
}
first_ = i;
} else if (last_ != map_.end()) {
i =
(map_.insert(
typename Map::value_type(
content,
Entry(last_->second.index, map_.end(), first_)))).
first;
first_->second.prev = i;
first_ = i;
typename Map::iterator j(last_);
last_ = last_->second.prev;
last_->second.next = map_.end();
map_.erase(j);
} else {
// Reached iff size_ == 0:
return cache::ignore;
}
} else if (i != first_) {
// Move to front (reached only if size_ > 1):
i->second.prev->second.next = i->second.next;
if (i->second.next == map_.end()) {
last_ = i->second.prev;
} else {
i->second.next->second.prev = i->second.prev;
}
i->second.prev = map_.end();
i->second.next = first_;
first_->second.prev = i;
first_ = i;
}
return i->second.index;
}
private:
struct Entry;
typedef std::map< T, Entry > Map;
struct Entry {
sal_uInt16 index;
typename Map::iterator prev;
typename Map::iterator next;
Entry(
sal_uInt16 theIndex, typename Map::iterator thePrev,
typename Map::iterator theNext):
index(theIndex), prev(thePrev), next(theNext) {}
};
std::size_t size_;
Map map_;
typename Map::iterator first_;
typename Map::iterator last_;
};
}
#endif

View File

@@ -0,0 +1,80 @@
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2000, 2011 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 "sal/config.h"
#include "com/sun/star/uno/Reference.hxx"
#include "com/sun/star/uno/RuntimeException.hpp"
#include "com/sun/star/uno/XInterface.hpp"
#include "rtl/ustring.h"
#include "rtl/ustring.hxx"
#include "uno/current_context.h"
#include "uno/dispatcher.hxx"
#include "uno/lbnames.h"
#include "currentcontext.hxx"
namespace binaryurp {
namespace {
namespace css = com::sun::star;
}
namespace current_context {
css::uno::UnoInterfaceReference get() {
css::uno::UnoInterfaceReference cc;
if (!uno_getCurrentContext(
reinterpret_cast< void ** >(&cc.m_pUnoI),
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(UNO_LB_UNO)).pData, 0))
{
throw css::uno::RuntimeException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM("uno_getCurrentContext failed")),
css::uno::Reference< css::uno::XInterface >());
}
return cc;
}
void set(css::uno::UnoInterfaceReference const & value) {
css::uno::UnoInterfaceReference cc(value);
if (!uno_setCurrentContext(
cc.m_pUnoI,
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(UNO_LB_UNO)).pData, 0))
{
throw css::uno::RuntimeException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM("uno_setCurrentContext failed")),
css::uno::Reference< css::uno::XInterface >());
}
}
}
}

View File

@@ -0,0 +1,49 @@
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2000, 2011 Oracle and/or its affiliates.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org. If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/
#ifndef INCLUDED_BINARYURP_SOURCE_CURRENTCONTEXT_HXX
#define INCLUDED_BINARYURP_SOURCE_CURRENTCONTEXT_HXX
#include "sal/config.h"
namespace com { namespace sun { namespace star { namespace uno {
class UnoInterfaceReference;
} } } }
namespace binaryurp {
namespace current_context {
com::sun::star::uno::UnoInterfaceReference get();
void set(com::sun::star::uno::UnoInterfaceReference const & value);
}
}
#endif

View File

@@ -0,0 +1,58 @@
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2000, 2011 Oracle and/or its affiliates.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org. If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/
#ifndef INCLUDED_BINARYURP_SOURCE_INCOMINGREPLY_HXX
#define INCLUDED_BINARYURP_SOURCE_INCOMINGREPLY_HXX
#include "sal/config.h"
#include <vector>
#include "boost/noncopyable.hpp"
#include "binaryany.hxx"
namespace binaryurp {
struct IncomingReply: private boost::noncopyable {
IncomingReply(
bool theException, BinaryAny const & theReturnValue,
std::vector< BinaryAny > const & theOutArguments):
exception(theException), returnValue(theReturnValue),
outArguments(theOutArguments)
{}
bool exception;
BinaryAny returnValue;
std::vector< BinaryAny > outArguments;
};
}
#endif

View File

@@ -0,0 +1,300 @@
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2000, 2011 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 "sal/config.h"
#include <list>
#include <vector>
#include "boost/noncopyable.hpp"
#include "com/sun/star/bridge/XInstanceProvider.hpp"
#include "cppuhelper/exc_hlp.hxx"
#include "rtl/byteseq.hxx"
#include "rtl/ref.hxx"
#include "rtl/ustring.hxx"
#include "sal/types.h"
#include "typelib/typedescription.hxx"
#include "uno/dispatcher.hxx"
#include "binaryany.hxx"
#include "bridge.hxx"
#include "currentcontext.hxx"
#include "incomingrequest.hxx"
#include "specialfunctionids.hxx"
namespace binaryurp {
namespace {
namespace css = com::sun::star;
}
IncomingRequest::IncomingRequest(
rtl::Reference< Bridge > const & bridge, rtl::ByteSequence const & tid,
rtl::OUString const & oid, css::uno::UnoInterfaceReference const & object,
css::uno::TypeDescription const & type, sal_uInt16 functionId,
bool synchronous, css::uno::TypeDescription const & member, bool setter,
std::vector< BinaryAny > const & inArguments, bool currentContextMode,
css::uno::UnoInterfaceReference const & currentContext):
bridge_(bridge), tid_(tid), oid_(oid), object_(object), type_(type),
functionId_(functionId), synchronous_(synchronous), member_(member),
setter_(setter), inArguments_(inArguments),
currentContextMode_(currentContextMode), currentContext_(currentContext)
{
OSL_ASSERT(bridge.is() && member.is() && member.get()->bComplete);
}
IncomingRequest::~IncomingRequest() {}
void IncomingRequest::execute() const {
BinaryAny ret;
std::vector< BinaryAny > outArgs;
bool isExc;
try {
bool resetCc = false;
css::uno::UnoInterfaceReference oldCc;
if (currentContextMode_) {
oldCc = current_context::get();
current_context::set(currentContext_);
resetCc = true;
}
try {
try {
isExc = !execute_throw(&ret, &outArgs);
} catch (std::exception & e) {
throw css::uno::RuntimeException(
(rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM("caught C++ exception: ")) +
rtl::OStringToOUString(
rtl::OString(e.what()), RTL_TEXTENCODING_ASCII_US)),
css::uno::Reference< css::uno::XInterface >());
// best-effort string conversion
}
} catch (css::uno::RuntimeException &) {
css::uno::Any exc(cppu::getCaughtException());
ret = bridge_->mapCppToBinaryAny(exc);
isExc = true;
}
if (resetCc) {
current_context::set(oldCc);
}
} catch (css::uno::RuntimeException &) {
css::uno::Any exc(cppu::getCaughtException());
ret = bridge_->mapCppToBinaryAny(exc);
isExc = true;
}
if (synchronous_) {
bridge_->decrementActiveCalls();
try {
bridge_->getWriter()->queueReply(
tid_, member_, setter_, isExc, ret, outArgs, false);
return;
} catch (css::uno::RuntimeException & e) {
OSL_TRACE(
OSL_LOG_PREFIX "caught UNO runtime exception '%s'",
(rtl::OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8).
getStr()));
} catch (std::exception & e) {
OSL_TRACE(OSL_LOG_PREFIX "caught C++ exception '%s'", e.what());
}
bridge_->terminate();
} else {
if (isExc) {
OSL_TRACE(OSL_LOG_PREFIX "oneway method raised exception");
}
bridge_->decrementCalls();
}
}
bool IncomingRequest::execute_throw(
BinaryAny * returnValue, std::vector< BinaryAny > * outArguments) const
{
OSL_ASSERT(
returnValue != 0 &&
returnValue->getType().equals(
css::uno::TypeDescription(
cppu::UnoType< cppu::UnoVoidType >::get())) &&
outArguments != 0 && outArguments->empty());
bool isExc = false;
switch (functionId_) {
case SPECIAL_FUNCTION_ID_RESERVED:
OSL_ASSERT(false); // this cannot happen
break;
case SPECIAL_FUNCTION_ID_RELEASE:
bridge_->releaseStub(oid_, type_);
break;
case SPECIAL_FUNCTION_ID_QUERY_INTERFACE:
if (!object_.is()) {
css::uno::Reference< css::uno::XInterface > ifc;
css::uno::Reference< css::bridge::XInstanceProvider > prov(
bridge_->getProvider());
if (prov.is()) {
try {
ifc = prov->getInstance(oid_);
} catch (css::container::NoSuchElementException & e) {
OSL_TRACE(
(OSL_LOG_PREFIX "initial element '%s':"
" NoSuchElementException '%s'"),
(rtl::OUStringToOString(oid_, RTL_TEXTENCODING_UTF8).
getStr()),
(rtl::OUStringToOString(
e.Message, RTL_TEXTENCODING_UTF8).
getStr()));
}
}
if (ifc.is()) {
css::uno::UnoInterfaceReference unoIfc(
static_cast< uno_Interface * >(
bridge_->getCppToBinaryMapping().mapInterface(
ifc.get(),
(css::uno::TypeDescription(
cppu::UnoType<
css::uno::Reference<
css::uno::XInterface > >::get()).
get()))),
SAL_NO_ACQUIRE);
*returnValue = BinaryAny(
css::uno::TypeDescription(
cppu::UnoType<
css::uno::Reference<
css::uno::XInterface > >::get()),
&unoIfc.m_pUnoI);
}
break;
}
// fall through
default:
{
OSL_ASSERT(object_.is());
css::uno::TypeDescription retType;
std::list< std::vector< char > > outBufs;
std::vector< void * > args;
switch (member_.get()->eTypeClass) {
case typelib_TypeClass_INTERFACE_ATTRIBUTE:
{
css::uno::TypeDescription t(
reinterpret_cast<
typelib_InterfaceAttributeTypeDescription * >(
member_.get())->
pAttributeTypeRef);
if (setter_) {
OSL_ASSERT(inArguments_.size() == 1);
args.push_back(inArguments_[0].getValue(t));
} else {
OSL_ASSERT(inArguments_.empty());
retType = t;
}
break;
}
case typelib_TypeClass_INTERFACE_METHOD:
{
typelib_InterfaceMethodTypeDescription * mtd =
reinterpret_cast<
typelib_InterfaceMethodTypeDescription * >(
member_.get());
retType = css::uno::TypeDescription(mtd->pReturnTypeRef);
std::vector< BinaryAny >::const_iterator i(
inArguments_.begin());
for (sal_Int32 j = 0; j != mtd->nParams; ++j) {
void * p;
if (mtd->pParams[j].bIn) {
p = i++->getValue(
css::uno::TypeDescription(
mtd->pParams[j].pTypeRef));
} else {
outBufs.push_back(
std::vector< char >(
css::uno::TypeDescription(
mtd->pParams[j].pTypeRef).
get()->nSize));
p = &outBufs.back()[0];
}
args.push_back(p);
if (mtd->pParams[j].bOut) {
outArguments->push_back(BinaryAny());
}
}
OSL_ASSERT(i == inArguments_.end());
break;
}
default:
OSL_ASSERT(false); // this cannot happen
break;
}
std::vector< char > retBuf(retType.is() ? retType.get()->nSize : 0);
uno_Any exc;
uno_Any * pexc = &exc;
(*object_.get()->pDispatcher)(
object_.get(), member_.get(), retBuf.empty() ? 0 : &retBuf[0],
args.empty() ? 0 : &args[0], &pexc);
isExc = pexc != 0;
if (isExc) {
*returnValue = BinaryAny(
css::uno::TypeDescription(
cppu::UnoType< css::uno::Any >::get()),
&exc);
uno_any_destruct(&exc, 0);
} else {
if (!retBuf.empty()) {
*returnValue = BinaryAny(retType, &retBuf[0]);
uno_destructData(&retBuf[0], retType.get(), 0);
}
if (!outArguments->empty()) {
OSL_ASSERT(
member_.get()->eTypeClass ==
typelib_TypeClass_INTERFACE_METHOD);
typelib_InterfaceMethodTypeDescription * mtd =
reinterpret_cast<
typelib_InterfaceMethodTypeDescription * >(
member_.get());
std::vector< BinaryAny >::iterator i(outArguments->begin());
std::list< std::vector< char > >::iterator j(
outBufs.begin());
for (sal_Int32 k = 0; k != mtd->nParams; ++k) {
if (mtd->pParams[k].bOut) {
*i++ = BinaryAny(
css::uno::TypeDescription(
mtd->pParams[k].pTypeRef),
args[k]);
}
if (!mtd->pParams[k].bIn) {
uno_type_destructData(
&(*j++)[0], mtd->pParams[k].pTypeRef, 0);
}
}
OSL_ASSERT(i == outArguments->end());
OSL_ASSERT(j == outBufs.end());
}
}
break;
}
}
return !isExc;
}
}

View File

@@ -0,0 +1,86 @@
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2000, 2011 Oracle and/or its affiliates.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org. If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/
#ifndef INCLUDED_BINARYURP_SOURCE_INCOMINGREQUEST_HXX
#define INCLUDED_BINARYURP_SOURCE_INCOMINGREQUEST_HXX
#include "sal/config.h"
#include <vector>
#include "boost/noncopyable.hpp"
#include "rtl/byteseq.hxx"
#include "rtl/ref.hxx"
#include "rtl/ustring.hxx"
#include "sal/types.h"
#include "typelib/typedescription.hxx"
#include "uno/dispatcher.hxx"
namespace binaryurp {
class BinaryAny;
class Bridge;
}
namespace binaryurp {
class IncomingRequest: private boost::noncopyable {
public:
IncomingRequest(
rtl::Reference< Bridge > const & bridge, rtl::ByteSequence const & tid,
rtl::OUString const & oid,
com::sun::star::uno::UnoInterfaceReference const & object,
com::sun::star::uno::TypeDescription const & type,
sal_uInt16 functionId, bool synchronous,
com::sun::star::uno::TypeDescription const & member, bool setter,
std::vector< BinaryAny > const & inArguments, bool currentContextMode,
com::sun::star::uno::UnoInterfaceReference const & currentContext);
~IncomingRequest();
void execute() const;
private:
bool execute_throw(
BinaryAny * returnValue, std::vector< BinaryAny > * outArguments) const;
rtl::Reference< Bridge > bridge_;
rtl::ByteSequence tid_;
rtl::OUString oid_; // initial object queryInterface; release
com::sun::star::uno::UnoInterfaceReference object_;
com::sun::star::uno::TypeDescription type_;
sal_uInt16 functionId_;
bool synchronous_;
com::sun::star::uno::TypeDescription member_;
bool setter_;
std::vector< BinaryAny > inArguments_;
bool currentContextMode_;
com::sun::star::uno::UnoInterfaceReference currentContext_;
};
}
#endif

View File

@@ -0,0 +1,71 @@
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2000, 2011 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 "sal/config.h"
#include <algorithm>
#include "osl/diagnose.h"
#include "rtl/byteseq.hxx"
#include "rtl/ustring.hxx"
#include "sal/types.h"
#include "typelib/typeclass.h"
#include "typelib/typedescription.hxx"
#include "lessoperators.hxx"
namespace com { namespace sun { namespace star { namespace uno {
bool operator <(TypeDescription const & left, TypeDescription const & right) {
OSL_ASSERT(left.is() && right.is());
typelib_TypeClass tc1 = left.get()->eTypeClass;
typelib_TypeClass tc2 = right.get()->eTypeClass;
return tc1 < tc2 ||
(tc1 == tc2 &&
(rtl::OUString(left.get()->pTypeName) <
rtl::OUString(right.get()->pTypeName)));
}
} } } }
namespace rtl {
bool operator <(ByteSequence const & left, ByteSequence const & right) {
for (sal_Int32 i = 0; i != std::min(left.getLength(), right.getLength());
++i)
{
if (left[i] < right[i]) {
return true;
}
if (right[i] < left[i]) {
return false;
}
}
return left.getLength() < right.getLength();
}
}

View File

@@ -0,0 +1,50 @@
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2000, 2011 Oracle and/or its affiliates.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org. If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/
#ifndef INCLUDED_BINARYURP_SOURCE_LESSOPERATORS_HXX
#define INCLUDED_BINARYURP_SOURCE_LESSOPERATORS_HXX
#include "sal/config.h"
namespace com { namespace sun { namespace star { namespace uno {
class TypeDescription;
} } } }
namespace rtl { class ByteSequence; }
namespace com { namespace sun { namespace star { namespace uno {
bool operator <(TypeDescription const & left, TypeDescription const & right);
} } } }
namespace rtl {
bool operator <(ByteSequence const & left, ByteSequence const & right);
}
#endif

View File

@@ -1,8 +1,8 @@
#*************************************************************************
#
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# Copyright 2000, 2010 Oracle and/or its affiliates.
#
# Copyright 2000, 2011 Oracle and/or its affiliates.
#
# OpenOffice.org - a multi-platform office productivity suite
#
@@ -23,51 +23,47 @@
# <http://www.openoffice.org/license.html>
# for a copy of the LGPLv3 License.
#
#*************************************************************************
#***********************************************************************/
PRJ=..$/..
PRJ = ..
PRJNAME = binaryurp
TARGET = binaryurp
PRJNAME=remotebridges
TARGET = bridgefac.uno
ENABLE_EXCEPTIONS=TRUE
COMP1TYPELIST = brdgfctr
ENABLE_EXCEPTIONS = TRUE
VISIBILITY_HIDDEN = TRUE
.INCLUDE: settings.mk
# --- Settings -----------------------------------------------------
.INCLUDE : settings.mk
.IF "$(L10N_framework)"==""
DLLPRE =
# ------------------------------------------------------------------
SLOFILES= \
$(SLO)$/bridgefactory.obj\
$(SLO)$/bridgeimpl.obj
SLOFILES = \
$(SLO)/binaryany.obj \
$(SLO)/bridge.obj \
$(SLO)/bridgefactory.obj \
$(SLO)/currentcontext.obj \
$(SLO)/incomingrequest.obj \
$(SLO)/lessoperators.obj \
$(SLO)/marshal.obj \
$(SLO)/outgoingrequests.obj \
$(SLO)/proxy.obj \
$(SLO)/reader.obj \
$(SLO)/unmarshal.obj \
$(SLO)/writer.obj
SHL1TARGET= $(TARGET)
SHL1VERSIONMAP = $(SOLARENV)/src/unloadablecomponent.map
SHL1IMPLIB = i$(SHL1TARGET)
SHL1OBJS = $(SLOFILES)
SHL1RPATH = URELIB
SHL1STDLIBS = $(CPPUHELPERLIB) $(CPPULIB) $(SALHELPERLIB) $(SALLIB)
SHL1TARGET = binaryurp.uno
SHL1USE_EXPORTS = name
DEF1NAME = $(SHL1TARGET)
SHL1STDLIBS= \
$(SALLIB) \
$(CPPULIB) \
$(CPPUHELPERLIB) \
$(RMCXTLIB)
.INCLUDE: target.mk
#SHL1DEPN=
SHL1IMPLIB= i$(TARGET)
SHL1LIBS= $(SLB)$/$(TARGET).lib
SHL1DEF= $(MISC)$/$(SHL1TARGET).def
SHL1RPATH= URELIB
ALLTAR : $(MISC)/binaryurp.component
DEF1NAME= $(SHL1TARGET)
.ENDIF # L10N_framework
# --- Targets ------------------------------------------------------
.INCLUDE : target.mk
ALLTAR : $(MISC)/bridgefac.component
$(MISC)/bridgefac.component .ERRREMOVE : $(SOLARENV)/bin/createcomponent.xslt \
bridgefac.component
$(MISC)/binaryurp.component .ERRREMOVE : $(SOLARENV)/bin/createcomponent.xslt \
binaryurp.component
$(XSLTPROC) --nonet --stringparam uri \
'$(COMPONENTPREFIX_URE_NATIVE)$(SHL1TARGETN:f)' -o $@ \
$(SOLARENV)/bin/createcomponent.xslt bridgefac.component
$(SOLARENV)/bin/createcomponent.xslt binaryurp.component

View File

@@ -0,0 +1,314 @@
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2000, 2011 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 "sal/config.h"
#include <vector>
#include "boost/noncopyable.hpp"
#include "com/sun/star/uno/Reference.hxx"
#include "com/sun/star/uno/RuntimeException.hpp"
#include "com/sun/star/uno/Sequence.hxx"
#include "com/sun/star/uno/XInterface.hpp"
#include "cppu/unotype.hxx"
#include "osl/diagnose.h"
#include "rtl/byteseq.hxx"
#include "rtl/string.hxx"
#include "rtl/textcvt.h"
#include "rtl/textenc.h"
#include "rtl/ustring.h"
#include "rtl/ustring.hxx"
#include "sal/types.h"
#include "typelib/typeclass.h"
#include "typelib/typedescription.h"
#include "typelib/typedescription.hxx"
#include "uno/dispatcher.hxx"
#include "binaryany.hxx"
#include "bridge.hxx"
#include "cache.hxx"
#include "lessoperators.hxx"
#include "marshal.hxx"
namespace binaryurp {
namespace {
namespace css = com::sun::star;
void write64(std::vector< unsigned char > * buffer, sal_uInt64 value) {
Marshal::write8(buffer, value >> 56);
Marshal::write8(buffer, (value >> 48) & 0xFF);
Marshal::write8(buffer, (value >> 40) & 0xFF);
Marshal::write8(buffer, (value >> 32) & 0xFF);
Marshal::write8(buffer, (value >> 24) & 0xFF);
Marshal::write8(buffer, (value >> 16) & 0xFF);
Marshal::write8(buffer, (value >> 8) & 0xFF);
Marshal::write8(buffer, value & 0xFF);
}
void writeCompressed(std::vector< unsigned char > * buffer, sal_uInt32 value) {
if (value < 0xFF) {
Marshal::write8(buffer, static_cast< sal_uInt8 >(value));
} else {
Marshal::write8(buffer, 0xFF);
Marshal::write32(buffer, value);
}
}
void writeString(
std::vector< unsigned char > * buffer, rtl::OUString const & value)
{
OSL_ASSERT(buffer != 0);
rtl::OString v;
if (!value.convertToString(
&v, RTL_TEXTENCODING_UTF8,
(RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
{
throw css::uno::RuntimeException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"UNO string contains invalid UTF-16 sequence")),
css::uno::Reference< css::uno::XInterface >());
}
writeCompressed(buffer, static_cast< sal_uInt32 >(v.getLength()));
buffer->insert(buffer->end(), v.getStr(), v.getStr() + v.getLength());
}
}
Marshal::Marshal(rtl::Reference< Bridge > const & bridge, WriterState & state):
bridge_(bridge), state_(state)
{
OSL_ASSERT(bridge.is());
}
Marshal::~Marshal() {}
void Marshal::write8(std::vector< unsigned char > * buffer, sal_uInt8 value) {
OSL_ASSERT(buffer != 0);
buffer->push_back(value);
}
void Marshal::write16(std::vector< unsigned char > * buffer, sal_uInt16 value) {
write8(buffer, value >> 8);
write8(buffer, value & 0xFF);
}
void Marshal::write32(std::vector< unsigned char > * buffer, sal_uInt32 value) {
write8(buffer, value >> 24);
write8(buffer, (value >> 16) & 0xFF);
write8(buffer, (value >> 8) & 0xFF);
write8(buffer, value & 0xFF);
}
void Marshal::writeValue(
std::vector< unsigned char > * buffer,
css::uno::TypeDescription const & type, BinaryAny const & value)
{
OSL_ASSERT(
type.is() &&
(type.get()->eTypeClass == typelib_TypeClass_ANY ||
value.getType().equals(type)));
writeValue(buffer, type, value.getValue(type));
}
void Marshal::writeType(
std::vector< unsigned char > * buffer,
css::uno::TypeDescription const & value)
{
value.makeComplete();
OSL_ASSERT(value.is());
typelib_TypeClass tc = value.get()->eTypeClass;
if (tc <= typelib_TypeClass_ANY) {
write8(buffer, static_cast< sal_uInt8 >(tc));
} else {
bool found;
sal_uInt16 idx = state_.typeCache.add(value, &found);
if (found) {
write8(buffer, static_cast< sal_uInt8 >(tc));
write16(buffer, idx);
} else {
write8(buffer, static_cast< sal_uInt8 >(tc) | 0x80);
write16(buffer, idx);
writeString(buffer, rtl::OUString(value.get()->pTypeName));
}
}
}
void Marshal::writeOid(
std::vector< unsigned char > * buffer, rtl::OUString const & oid)
{
bool found;
sal_uInt16 idx;
if (oid.getLength() == 0) {
found = true;
idx = cache::ignore;
} else {
idx = state_.oidCache.add(oid, &found);
}
if (found) {
write8(buffer, 0);
} else {
writeString(buffer, oid);
}
write16(buffer, idx);
}
void Marshal::writeTid(
std::vector< unsigned char > * buffer, rtl::ByteSequence const & tid)
{
bool found;
sal_uInt16 idx = state_.tidCache.add(tid, &found);
if (found) {
write8(buffer, 0);
} else {
sal_Sequence * p = tid.getHandle();
writeValue(
buffer,
css::uno::TypeDescription(
cppu::UnoType< css::uno::Sequence< sal_Int8 > >::get()), &p);
}
write16(buffer, idx);
}
void Marshal::writeValue(
std::vector< unsigned char > * buffer,
css::uno::TypeDescription const & type, void const * value)
{
OSL_ASSERT(buffer != 0 && type.is());
type.makeComplete();
switch (type.get()->eTypeClass) {
case typelib_TypeClass_VOID:
break;
case typelib_TypeClass_BOOLEAN:
OSL_ASSERT(*static_cast< sal_uInt8 const * >(value) <= 1);
// fall through
case typelib_TypeClass_BYTE:
write8(buffer, *static_cast< sal_uInt8 const * >(value));
break;
case typelib_TypeClass_SHORT:
case typelib_TypeClass_UNSIGNED_SHORT:
case typelib_TypeClass_CHAR:
write16(buffer, *static_cast< sal_uInt16 const * >(value));
break;
case typelib_TypeClass_LONG:
case typelib_TypeClass_UNSIGNED_LONG:
case typelib_TypeClass_FLOAT:
case typelib_TypeClass_ENUM:
write32(buffer, *static_cast< sal_uInt32 const * >(value));
break;
case typelib_TypeClass_HYPER:
case typelib_TypeClass_UNSIGNED_HYPER:
case typelib_TypeClass_DOUBLE:
write64(buffer, *static_cast< sal_uInt64 const * >(value));
break;
case typelib_TypeClass_STRING:
writeString(
buffer,
rtl::OUString(*static_cast< rtl_uString * const * >(value)));
break;
case typelib_TypeClass_TYPE:
writeType(
buffer,
css::uno::TypeDescription(
*static_cast< typelib_TypeDescriptionReference * const * >(
value)));
break;
case typelib_TypeClass_ANY:
{
uno_Any const * p = static_cast< uno_Any const * >(value);
css::uno::TypeDescription t(p->pType);
writeType(buffer, t);
writeValue(buffer, t, p->pData);
break;
}
case typelib_TypeClass_SEQUENCE:
{
sal_Sequence * p = *static_cast< sal_Sequence * const * >(value);
writeCompressed(buffer, static_cast< sal_uInt32 >(p->nElements));
css::uno::TypeDescription ctd(
reinterpret_cast< typelib_IndirectTypeDescription * >(
type.get())->
pType);
OSL_ASSERT(ctd.is());
if (ctd.get()->eTypeClass == typelib_TypeClass_BYTE) {
buffer->insert(
buffer->end(), p->elements, p->elements + p->nElements);
} else {
for (sal_Int32 i = 0; i != p->nElements; ++i) {
writeValue(buffer, ctd, p->elements + i * ctd.get()->nSize);
}
}
break;
}
case typelib_TypeClass_STRUCT:
case typelib_TypeClass_EXCEPTION:
writeMemberValues(buffer, type, value);
break;
case typelib_TypeClass_INTERFACE:
writeOid(
buffer,
bridge_->registerOutgoingInterface(
css::uno::UnoInterfaceReference(
*static_cast< uno_Interface * const * >(value)),
type));
break;
default:
OSL_ASSERT(false); // this cannot happen
break;
}
}
void Marshal::writeMemberValues(
std::vector< unsigned char > * buffer,
css::uno::TypeDescription const & type, void const * aggregateValue)
{
OSL_ASSERT(
type.is() &&
(type.get()->eTypeClass == typelib_TypeClass_STRUCT ||
type.get()->eTypeClass == typelib_TypeClass_EXCEPTION) &&
aggregateValue != 0);
type.makeComplete();
typelib_CompoundTypeDescription * ctd =
reinterpret_cast< typelib_CompoundTypeDescription * >(type.get());
if (ctd->pBaseTypeDescription != 0) {
writeMemberValues(
buffer,
css::uno::TypeDescription(&ctd->pBaseTypeDescription->aBase),
aggregateValue);
}
for (sal_Int32 i = 0; i != ctd->nMembers; ++i) {
writeValue(
buffer, css::uno::TypeDescription(ctd->ppTypeRefs[i]),
(static_cast< char const * >(aggregateValue) +
ctd->pMemberOffsets[i]));
}
}
}

95
binaryurp/source/marshal.hxx Executable file
View File

@@ -0,0 +1,95 @@
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2000, 2011 Oracle and/or its affiliates.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org. If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/
#ifndef INCLUDED_BINARYURP_SOURCE_MARSHAL_HXX
#define INCLUDED_BINARYURP_SOURCE_MARSHAL_HXX
#include "sal/config.h"
#include <vector>
#include "boost/noncopyable.hpp"
#include "rtl/byteseq.hxx"
#include "rtl/ref.hxx"
#include "rtl/ustring.hxx"
#include "sal/types.h"
#include "typelib/typedescription.hxx"
namespace binaryurp {
class BinaryAny;
class Bridge;
struct WriterState;
}
namespace binaryurp {
class Marshal: private boost::noncopyable {
public:
Marshal(rtl::Reference< Bridge > const & bridge, WriterState & state);
~Marshal();
static void write8(std::vector< unsigned char > * buffer, sal_uInt8 value);
static void write16(
std::vector< unsigned char > * buffer, sal_uInt16 value);
static void write32(
std::vector< unsigned char > * buffer, sal_uInt32 value);
void writeValue(
std::vector< unsigned char > * buffer,
com::sun::star::uno::TypeDescription const & type,
BinaryAny const & value);
void writeType(
std::vector< unsigned char > * buffer,
com::sun::star::uno::TypeDescription const & value);
void writeOid(
std::vector< unsigned char > * buffer, rtl::OUString const & oid);
void writeTid(
std::vector< unsigned char > * buffer, rtl::ByteSequence const & tid);
private:
void writeValue(
std::vector< unsigned char > * buffer,
com::sun::star::uno::TypeDescription const & type, void const * value);
void writeMemberValues(
std::vector< unsigned char > * buffer,
com::sun::star::uno::TypeDescription const & type,
void const * aggregateValue);
rtl::Reference< Bridge > bridge_;
WriterState & state_;
};
}
#endif

View File

@@ -0,0 +1,55 @@
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2000, 2011 Oracle and/or its affiliates.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org. If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/
#ifndef INCLUDED_BINARYURP_SOURCE_OUTGOINGREQUEST_HXX
#define INCLUDED_BINARYURP_SOURCE_OUTGOINGREQUEST_HXX
#include "sal/config.h"
#include "typelib/typedescription.hxx"
namespace binaryurp {
struct OutgoingRequest {
enum Kind { KIND_NORMAL, KIND_REQUEST_CHANGE, KIND_COMMIT_CHANGE };
OutgoingRequest(
Kind theKind, com::sun::star::uno::TypeDescription const & theMember,
bool theSetter):
kind(theKind), member(theMember), setter(theSetter)
{}
Kind kind;
com::sun::star::uno::TypeDescription member;
bool setter;
};
}
#endif

View File

@@ -0,0 +1,80 @@
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2000, 2011 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 "sal/config.h"
#include "com/sun/star/uno/RuntimeException.hpp"
#include "rtl/byteseq.hxx"
#include "osl/mutex.hxx"
#include "lessoperators.hxx"
#include "outgoingrequest.hxx"
#include "outgoingrequests.hxx"
namespace binaryurp {
namespace {
namespace css = com::sun::star;
}
OutgoingRequests::OutgoingRequests() {}
OutgoingRequests::~OutgoingRequests() {}
void OutgoingRequests::push(
rtl::ByteSequence const & tid, OutgoingRequest const & request)
{
osl::MutexGuard g(mutex_);
map_[tid].push_back(request);
}
OutgoingRequest OutgoingRequests::top(rtl::ByteSequence const & tid) {
osl::MutexGuard g(mutex_);
Map::iterator i(map_.find(tid));
if (i == map_.end()) {
throw css::uno::RuntimeException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM("URP: reply for unknown TID")),
css::uno::Reference< css::uno::XInterface >());
}
OSL_ASSERT(!i->second.empty());
return i->second.back();
}
void OutgoingRequests::pop(rtl::ByteSequence const & tid) throw () {
osl::MutexGuard g(mutex_);
Map::iterator i(map_.find(tid));
OSL_ASSERT(i != map_.end());
i->second.pop_back();
if (i->second.empty()) {
map_.erase(i);
}
}
}

View File

@@ -0,0 +1,65 @@
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2000, 2011 Oracle and/or its affiliates.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org. If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/
#ifndef INCLUDED_BINARYURP_SOURCE_OUTGOINGREQUESTS_HXX
#define INCLUDED_BINARYURP_SOURCE_OUTGOINGREQUESTS_HXX
#include "sal/config.h"
#include <map>
#include <vector>
#include "boost/noncopyable.hpp"
#include "osl/mutex.hxx"
namespace binaryurp { struct OutgoingRequest; }
namespace rtl { class ByteSequence; }
namespace binaryurp {
class OutgoingRequests: private boost::noncopyable {
public:
OutgoingRequests();
~OutgoingRequests();
void push(rtl::ByteSequence const & tid, OutgoingRequest const & request);
OutgoingRequest top(rtl::ByteSequence const & tid);
void pop(rtl::ByteSequence const & tid) throw ();
private:
typedef std::map< rtl::ByteSequence, std::vector< OutgoingRequest > > Map;
osl::Mutex mutex_;
Map map_;
};
}
#endif

260
binaryurp/source/proxy.cxx Normal file
View File

@@ -0,0 +1,260 @@
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2000, 2011 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 "sal/config.h"
#include <exception>
#include <vector>
#include "cppuhelper/exc_hlp.hxx"
#include "osl/diagnose.h"
#include "rtl/ref.hxx"
#include "rtl/ustring.hxx"
#include "sal/types.h"
#include "typelib/typedescription.h"
#include "typelib/typedescription.hxx"
#include "uno/any2.h"
#include "uno/dispatcher.h"
#include "uno/dispatcher.hxx"
#include "binaryany.hxx"
#include "bridge.hxx"
#include "proxy.hxx"
namespace binaryurp {
namespace {
namespace css = com::sun::star;
extern "C" void SAL_CALL proxy_acquireInterface(uno_Interface * pInterface) {
OSL_ASSERT(pInterface != 0);
static_cast< Proxy * >(pInterface)->do_acquire();
}
extern "C" void SAL_CALL proxy_releaseInterface(uno_Interface * pInterface) {
OSL_ASSERT(pInterface != 0);
static_cast< Proxy * >(pInterface)->do_release();
}
extern "C" void SAL_CALL proxy_dispatchInterface(
uno_Interface * pUnoI, typelib_TypeDescription const * pMemberType,
void * pReturn, void ** pArgs, uno_Any ** ppException)
{
OSL_ASSERT(pUnoI != 0);
static_cast< Proxy * >(pUnoI)->do_dispatch(
pMemberType, pReturn, pArgs, ppException);
}
}
Proxy::Proxy(
rtl::Reference< Bridge > const & bridge, rtl::OUString const & oid,
css::uno::TypeDescription const & type):
bridge_(bridge), oid_(oid), type_(type), references_(1)
{
OSL_ASSERT(bridge.is());
acquire = &proxy_acquireInterface;
release = &proxy_releaseInterface;
pDispatcher = &proxy_dispatchInterface;
}
rtl::OUString Proxy::getOid() const {
return oid_;
}
css::uno::TypeDescription Proxy::getType() const {
return type_;
}
void Proxy::do_acquire() {
if (osl_incrementInterlockedCount(&references_) == 1) {
bridge_->resurrectProxy(*this);
}
}
void Proxy::do_release() {
if (osl_decrementInterlockedCount(&references_) == 0) {
bridge_->revokeProxy(*this);
}
}
void Proxy::do_free() {
bridge_->freeProxy(*this);
delete this;
}
void Proxy::do_dispatch(
typelib_TypeDescription const * member, void * returnValue,
void ** arguments, uno_Any ** exception) const
{
try {
try {
do_dispatch_throw(member, returnValue, arguments, exception);
} catch (std::exception & e) {
throw css::uno::RuntimeException(
(rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM("caught C++ exception: ")) +
rtl::OStringToOUString(
rtl::OString(e.what()), RTL_TEXTENCODING_ASCII_US)),
css::uno::Reference< css::uno::XInterface >());
// best-effort string conversion
}
} catch (css::uno::RuntimeException &) {
css::uno::Any exc(cppu::getCaughtException());
uno_copyAndConvertData(
*exception, &exc,
(css::uno::TypeDescription(cppu::UnoType< css::uno::Any >::get()).
get()),
bridge_->getCppToBinaryMapping().get());
}
}
bool Proxy::isProxy(
rtl::Reference< Bridge > const & bridge,
css::uno::UnoInterfaceReference const & object, rtl::OUString * oid)
{
OSL_ASSERT(object.is());
return object.m_pUnoI->acquire == &proxy_acquireInterface &&
static_cast< Proxy * >(object.m_pUnoI)->isProxy(bridge, oid);
}
Proxy::~Proxy() {}
void Proxy::do_dispatch_throw(
typelib_TypeDescription const * member, void * returnValue,
void ** arguments, uno_Any ** exception) const
{
//TODO: Optimize queryInterface:
OSL_ASSERT(member != 0);
bool setter = false;
std::vector< BinaryAny > inArgs;
switch (member->eTypeClass) {
case typelib_TypeClass_INTERFACE_ATTRIBUTE:
setter = returnValue == 0;
if (setter) {
inArgs.push_back(
BinaryAny(
css::uno::TypeDescription(
reinterpret_cast<
typelib_InterfaceAttributeTypeDescription const * >(
member)->
pAttributeTypeRef),
arguments[0]));
}
break;
case typelib_TypeClass_INTERFACE_METHOD:
{
typelib_InterfaceMethodTypeDescription const * mtd =
reinterpret_cast<
typelib_InterfaceMethodTypeDescription const * >(member);
for (sal_Int32 i = 0; i != mtd->nParams; ++i) {
if (mtd->pParams[i].bIn) {
inArgs.push_back(
BinaryAny(
css::uno::TypeDescription(mtd->pParams[i].pTypeRef),
arguments[i]));
}
}
break;
}
default:
OSL_ASSERT(false); // this cannot happen
break;
}
BinaryAny ret;
std::vector< BinaryAny > outArgs;
if (bridge_->makeCall(
oid_,
css::uno::TypeDescription(
const_cast< typelib_TypeDescription * >(member)),
setter, inArgs, &ret, &outArgs))
{
OSL_ASSERT(
ret.getType().get()->eTypeClass == typelib_TypeClass_EXCEPTION);
uno_any_construct(
*exception, ret.getValue(ret.getType()), ret.getType().get(), 0);
} else {
switch (member->eTypeClass) {
case typelib_TypeClass_INTERFACE_ATTRIBUTE:
if (!setter) {
css::uno::TypeDescription t(
reinterpret_cast<
typelib_InterfaceAttributeTypeDescription const * >(
member)->
pAttributeTypeRef);
uno_copyData(returnValue, ret.getValue(t), t.get(), 0);
}
break;
case typelib_TypeClass_INTERFACE_METHOD:
{
typelib_InterfaceMethodTypeDescription const * mtd =
reinterpret_cast<
typelib_InterfaceMethodTypeDescription const * >(
member);
css::uno::TypeDescription t(mtd->pReturnTypeRef);
if (t.get()->eTypeClass != typelib_TypeClass_VOID) {
uno_copyData(returnValue, ret.getValue(t), t.get(), 0);
}
std::vector< BinaryAny >::iterator i(outArgs.begin());
for (sal_Int32 j = 0; j != mtd->nParams; ++j) {
if (mtd->pParams[j].bOut) {
css::uno::TypeDescription pt(mtd->pParams[j].pTypeRef);
if (mtd->pParams[j].bIn) {
uno_assignData(
arguments[j], pt.get(), i++->getValue(pt),
pt.get(), 0, 0, 0);
} else {
uno_copyData(
arguments[j], i++->getValue(pt), pt.get(), 0);
}
}
}
OSL_ASSERT(i == outArgs.end());
break;
}
default:
OSL_ASSERT(false); // this cannot happen
break;
}
*exception = 0;
}
}
bool Proxy::isProxy(
rtl::Reference< Bridge > const & bridge, rtl::OUString * oid) const
{
OSL_ASSERT(oid != 0);
if (bridge == bridge_) {
*oid = oid_;
return true;
} else {
return false;
}
}
}

View File

@@ -0,0 +1,92 @@
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2000, 2011 Oracle and/or its affiliates.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org. If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/
#ifndef INCLUDED_BINARYURP_SOURCE_PROXY_HXX
#define INCLUDED_BINARYURP_SOURCE_PROXY_HXX
#include "sal/config.h"
#include "boost/noncopyable.hpp"
#include "osl/interlck.h"
#include "rtl/ref.hxx"
#include "rtl/ustring.hxx"
#include "typelib/typedescription.h"
#include "typelib/typedescription.hxx"
#include "uno/any2.h"
#include "uno/dispatcher.h"
namespace binaryurp { class Bridge; }
namespace com { namespace sun { namespace star { namespace uno {
class UnoInterfaceReference;
} } } }
namespace binaryurp {
class Proxy: public uno_Interface, private boost::noncopyable {
public:
Proxy(
rtl::Reference< Bridge > const & bridge, rtl::OUString const & oid,
com::sun::star::uno::TypeDescription const & type);
rtl::OUString getOid() const;
com::sun::star::uno::TypeDescription getType() const;
void do_acquire();
void do_release();
void do_free();
void do_dispatch(
typelib_TypeDescription const * member, void * returnValue,
void ** arguments, uno_Any ** exception) const;
static bool isProxy(
rtl::Reference< Bridge > const & bridge,
com::sun::star::uno::UnoInterfaceReference const & object,
rtl::OUString * oid);
private:
~Proxy();
void do_dispatch_throw(
typelib_TypeDescription const * member, void * returnValue,
void ** arguments, uno_Any ** exception) const;
bool isProxy(rtl::Reference< Bridge > const & bridge, rtl::OUString * oid)
const;
rtl::Reference< Bridge > bridge_;
rtl::OUString oid_;
com::sun::star::uno::TypeDescription type_;
oslInterlockedCount references_;
};
}
#endif

552
binaryurp/source/reader.cxx Executable file
View File

@@ -0,0 +1,552 @@
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2000, 2011 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 "sal/config.h"
#include <exception>
#include <memory>
#include <vector>
#include "com/sun/star/connection/XConnection.hpp"
#include "com/sun/star/io/IOException.hpp"
#include "com/sun/star/uno/Any.hxx"
#include "com/sun/star/uno/Exception.hpp"
#include "com/sun/star/uno/Reference.hxx"
#include "com/sun/star/uno/RuntimeException.hpp"
#include "com/sun/star/uno/Sequence.hxx"
#include "com/sun/star/uno/Type.hxx"
#include "com/sun/star/uno/XCurrentContext.hpp"
#include "com/sun/star/uno/XInterface.hpp"
#include "cppu/unotype.hxx"
#include "osl/diagnose.h"
#include "rtl/byteseq.h"
#include "rtl/string.h"
#include "rtl/textenc.h"
#include "rtl/ustring.h"
#include "rtl/ustring.hxx"
#include "sal/types.h"
#include "typelib/typeclass.h"
#include "typelib/typedescription.h"
#include "typelib/typedescription.hxx"
#include "uno/lbnames.h"
#include "binaryany.hxx"
#include "bridge.hxx"
#include "incomingreply.hxx"
#include "incomingrequest.hxx"
#include "outgoingrequest.hxx"
#include "reader.hxx"
#include "specialfunctionids.hxx"
#include "unmarshal.hxx"
namespace binaryurp {
namespace {
namespace css = com::sun::star;
css::uno::Sequence< sal_Int8 > read(
css::uno::Reference< css::connection::XConnection > const & connection,
sal_uInt32 size, bool eofOk)
{
OSL_ASSERT(connection.is());
if (size > SAL_MAX_INT32) {
throw css::uno::RuntimeException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"binaryurp::Reader: block size too large")),
css::uno::Reference< css::uno::XInterface >());
}
css::uno::Sequence< sal_Int8 > buf;
sal_Int32 n = connection->read(buf, static_cast< sal_Int32 >(size));
if (n == 0 && eofOk) {
return css::uno::Sequence< sal_Int8 >();
}
if (n != static_cast< sal_Int32 >(size)) {
throw css::io::IOException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"binaryurp::Reader: premature end of input")),
css::uno::Reference< css::uno::XInterface >());
}
OSL_ASSERT(buf.getLength() == static_cast< sal_Int32 >(size));
return buf;
}
extern "C" void SAL_CALL request(void * pThreadSpecificData) {
OSL_ASSERT(pThreadSpecificData != 0);
std::auto_ptr< IncomingRequest >(
static_cast< IncomingRequest * >(pThreadSpecificData))->
execute();
}
}
Reader::Reader(rtl::Reference< Bridge > const & bridge): bridge_(bridge) {
OSL_ASSERT(bridge.is());
acquire();
}
Reader::~Reader() {}
void Reader::run() {
try {
bridge_->sendRequestChangeRequest();
css::uno::Reference< css::connection::XConnection > con(
bridge_->getConnection());
for (;;) {
css::uno::Sequence< sal_Int8 > s(read(con, 8, true));
if (s.getLength() == 0) {
break;
}
Unmarshal header(bridge_, state_, s);
sal_uInt32 size = header.read32();
sal_uInt32 count = header.read32();
header.done();
if (count == 0) {
throw css::io::IOException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"binaryurp::Reader: block with zero message count"
" received")),
css::uno::Reference< css::uno::XInterface >());
}
Unmarshal block(bridge_, state_, read(con, size, false));
for (sal_uInt32 i = 0; i != count; ++i) {
readMessage(block);
}
block.done();
}
} catch (css::uno::Exception & e) {
OSL_TRACE(
OSL_LOG_PREFIX "caught UNO exception '%s'",
rtl::OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8).getStr());
} catch (std::exception & e) {
OSL_TRACE(OSL_LOG_PREFIX "caught C++ exception '%s'", e.what());
}
bridge_->terminate();
}
void Reader::onTerminated() {
release();
}
void Reader::readMessage(Unmarshal & unmarshal) {
sal_uInt8 flags1 = unmarshal.read8();
bool newType;
bool newOid;
bool newTid;
bool forceSynchronous;
sal_uInt16 functionId;
if ((flags1 & 0x80) != 0) { // bit 7: LONGHEADER
if ((flags1 & 0x40) == 0) { // bit 6: REQUEST
readReplyMessage(unmarshal, flags1);
return;
}
newType = (flags1 & 0x20) != 0; // bit 5: NEWTYPE
newOid = (flags1 & 0x10) != 0; // bit 4: NEWOID
newTid = (flags1 & 0x08) != 0; // bit 3: NEWTID
if ((flags1 & 0x01) != 0) { // bit 0: MOREFLAGSS
sal_uInt8 flags2 = unmarshal.read8();
forceSynchronous = (flags2 & 0x80) != 0; // bit 7: MUSTREPLY
if (((flags2 & 0x40) != 0) != forceSynchronous) {
// bit 6: SYNCHRONOUS
throw css::uno::RuntimeException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"URP: request message with MUSTREPLY != SYNCHRONOUS"
" received")),
css::uno::Reference< css::uno::XInterface >());
}
} else {
forceSynchronous = false;
}
functionId = ((flags1 & 0x04) != 0) // bit 2: FUNCTIONID16
? unmarshal.read16() : unmarshal.read8();
} else {
newType = false;
newOid = false;
newTid = false;
forceSynchronous = false;
functionId = ((flags1 & 0x40) != 0) // bit 6: FUNCTIONID14
? ((flags1 & 0x3F) << 8) | unmarshal.read8() : flags1 & 0x3F;
}
css::uno::TypeDescription type;
if (newType) {
type = unmarshal.readType();
lastType_ = type;
} else {
if (!lastType_.is()) {
throw css::uno::RuntimeException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"URP: request message with NEWTYPE received when last"
" interface type has not yet been set")),
css::uno::Reference< css::uno::XInterface >());
}
type = lastType_;
}
rtl::OUString oid;
if (newOid) {
oid = unmarshal.readOid();
if (oid.getLength() == 0) {
throw css::io::IOException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"binaryurp::Unmarshal: emtpy OID")),
css::uno::Reference< css::uno::XInterface >());
}
lastOid_ = oid;
} else {
if (lastOid_.getLength() == 0) {
throw css::uno::RuntimeException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"URP: request message with NEWOID received when last"
" OID has not yet been set")),
css::uno::Reference< css::uno::XInterface >());
}
oid = lastOid_;
}
rtl::ByteSequence tid(getTid(unmarshal, newTid));
lastTid_ = tid;
type.makeComplete();
if (type.get()->eTypeClass != typelib_TypeClass_INTERFACE) {
throw css::uno::RuntimeException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"URP: request message with non-interface interface type"
" received")),
css::uno::Reference< css::uno::XInterface >());
}
typelib_InterfaceTypeDescription * itd =
reinterpret_cast< typelib_InterfaceTypeDescription * >(type.get());
if (functionId >= itd->nMapFunctionIndexToMemberIndex) {
throw css::uno::RuntimeException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"URP: request message with unknown function ID received")),
css::uno::Reference< css::uno::XInterface >());
}
sal_Int32 memberId = itd->pMapFunctionIndexToMemberIndex[functionId];
css::uno::TypeDescription memberTd(itd->ppAllMembers[memberId]);
memberTd.makeComplete();
OSL_ASSERT(memberTd.is());
bool protProps = bridge_->isProtocolPropertiesRequest(oid, type);
bool ccMode = !protProps && functionId != SPECIAL_FUNCTION_ID_RELEASE &&
bridge_->isCurrentContextMode();
css::uno::UnoInterfaceReference cc;
if (ccMode) {
css::uno::TypeDescription t(
cppu::UnoType< css::uno::Reference< css::uno::XCurrentContext > >::
get());
cc.set(
*static_cast< uno_Interface ** >(
unmarshal.readValue(t).getValue(t)));
}
bool synchronous;
if (memberTd.get()->eTypeClass == typelib_TypeClass_INTERFACE_METHOD &&
(reinterpret_cast< typelib_InterfaceMethodTypeDescription * >(
memberTd.get())->
bOneWay))
{
synchronous = forceSynchronous;
} else {
if (forceSynchronous) {
throw css::uno::RuntimeException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"URP: synchronous request message with non-oneway"
" function ID received")),
css::uno::Reference< css::uno::XInterface >());
}
synchronous = true;
}
bool setter = false;
std::vector< BinaryAny > inArgs;
switch (memberTd.get()->eTypeClass) {
case typelib_TypeClass_INTERFACE_ATTRIBUTE:
setter = itd->pMapMemberIndexToFunctionIndex[memberId] != functionId;
// pMapMemberIndexToFunctionIndex contains function index of
// attribute getter
if (setter) {
inArgs.push_back(
unmarshal.readValue(
css::uno::TypeDescription(
reinterpret_cast<
typelib_InterfaceAttributeTypeDescription * >(
memberTd.get())->
pAttributeTypeRef)));
}
break;
case typelib_TypeClass_INTERFACE_METHOD:
{
typelib_InterfaceMethodTypeDescription * mtd =
reinterpret_cast< typelib_InterfaceMethodTypeDescription * >(
memberTd.get());
for (sal_Int32 i = 0; i != mtd->nParams; ++i) {
if (mtd->pParams[i].bIn) {
inArgs.push_back(
unmarshal.readValue(
css::uno::TypeDescription(
mtd->pParams[i].pTypeRef)));
}
}
break;
}
default:
OSL_ASSERT(false); // this cannot happen
break;
}
bridge_->incrementCalls(
!protProps && functionId != SPECIAL_FUNCTION_ID_RELEASE);
if (protProps) {
switch (functionId) {
case SPECIAL_FUNCTION_ID_REQUEST_CHANGE:
bridge_->handleRequestChangeRequest(tid, inArgs);
break;
case SPECIAL_FUNCTION_ID_COMMIT_CHANGE:
bridge_->handleCommitChangeRequest(tid, inArgs);
break;
default:
throw css::uno::RuntimeException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"URP: request message with UrpProtocolProperties OID"
" and unknown function ID received")),
css::uno::Reference< css::uno::XInterface >());
}
} else {
css::uno::UnoInterfaceReference obj;
switch (functionId) {
case SPECIAL_FUNCTION_ID_QUERY_INTERFACE:
obj = bridge_->findStub(oid, type);
if (!obj.is()) {
OSL_ASSERT(
inArgs.size() == 1
&& inArgs[0].getType().equals(
css::uno::TypeDescription(
cppu::UnoType< css::uno::Type >::get())));
if (!(type.equals(
css::uno::TypeDescription(
cppu::UnoType<
css::uno::Reference<
css::uno::XInterface > >::get()))
&& (css::uno::TypeDescription(
*static_cast<
typelib_TypeDescriptionReference ** >(
inArgs[0].getValue(inArgs[0].getType()))).
equals(
css::uno::TypeDescription(
cppu::UnoType<
css::uno::Reference<
css::uno::XInterface > >::get())))))
{
throw css::uno::RuntimeException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"URP: queryInterface request message with"
" unknown OID received")),
css::uno::Reference< css::uno::XInterface >());
}
}
break;
case SPECIAL_FUNCTION_ID_RESERVED:
throw css::uno::RuntimeException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"URP: request message with unknown function ID 1"
" received")),
css::uno::Reference< css::uno::XInterface >());
case SPECIAL_FUNCTION_ID_RELEASE:
break;
default:
obj = bridge_->findStub(oid, type);
if (!obj.is()) {
throw css::uno::RuntimeException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"URP: request message with unknown OID received")),
css::uno::Reference< css::uno::XInterface >());
}
break;
}
std::auto_ptr< IncomingRequest > req(
new IncomingRequest(
bridge_, tid, oid, obj, type, functionId, synchronous, memberTd,
setter, inArgs, ccMode, cc));
if (synchronous) {
bridge_->incrementActiveCalls();
}
uno_threadpool_putJob(
bridge_->getThreadPool(), tid.getHandle(), req.get(), &request,
!synchronous);
req.release();
}
}
void Reader::readReplyMessage(Unmarshal & unmarshal, sal_uInt8 flags1) {
rtl::ByteSequence tid(getTid(unmarshal, (flags1 & 0x08) != 0));
// bit 3: NEWTID
lastTid_ = tid;
OutgoingRequest req(bridge_->lastOutgoingRequest(tid));
bool exc = (flags1 & 0x20) != 0; // bit 5: EXCEPTION
BinaryAny ret;
std::vector< BinaryAny > outArgs;
if (exc) {
ret = unmarshal.readValue(
css::uno::TypeDescription(cppu::UnoType< css::uno::Any >::get()));
if (!typelib_typedescription_isAssignableFrom(
(css::uno::TypeDescription(
cppu::UnoType< css::uno::RuntimeException >::get()).
get()),
ret.getType().get()))
{
sal_Int32 n = 0;
typelib_TypeDescriptionReference ** p = 0;
switch (req.member.get()->eTypeClass) {
case typelib_TypeClass_INTERFACE_ATTRIBUTE:
{
typelib_InterfaceAttributeTypeDescription * atd =
reinterpret_cast<
typelib_InterfaceAttributeTypeDescription * >(
req.member.get());
n = req.setter ? atd->nSetExceptions : atd->nGetExceptions;
p = req.setter
? atd->ppSetExceptions : atd->ppGetExceptions;
break;
}
case typelib_TypeClass_INTERFACE_METHOD:
{
typelib_InterfaceMethodTypeDescription * mtd =
reinterpret_cast<
typelib_InterfaceMethodTypeDescription * >(
req.member.get());
n = mtd->nExceptions;
p = mtd->ppExceptions;
break;
}
default:
OSL_ASSERT(false); // this cannot happen
break;
}
bool ok = false;
for (sal_Int32 i = 0; i != n; ++i) {
if (typelib_typedescriptionreference_isAssignableFrom(
p[i],
reinterpret_cast< typelib_TypeDescriptionReference * >(
ret.getType().get())))
{
ok = true;
break;
}
}
if (!ok) {
throw css::uno::RuntimeException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"URP: reply message with bad exception type"
" received")),
css::uno::Reference< css::uno::XInterface >());
}
}
} else {
switch (req.member.get()->eTypeClass) {
case typelib_TypeClass_INTERFACE_ATTRIBUTE:
if (!req.setter) {
ret = unmarshal.readValue(
css::uno::TypeDescription(
reinterpret_cast<
typelib_InterfaceAttributeTypeDescription * >(
req.member.get())->
pAttributeTypeRef));
}
break;
case typelib_TypeClass_INTERFACE_METHOD:
{
typelib_InterfaceMethodTypeDescription * mtd =
reinterpret_cast<
typelib_InterfaceMethodTypeDescription * >(
req.member.get());
ret = unmarshal.readValue(
css::uno::TypeDescription(mtd->pReturnTypeRef));
for (sal_Int32 i = 0; i != mtd->nParams; ++i) {
if (mtd->pParams[i].bOut) {
outArgs.push_back(
unmarshal.readValue(
css::uno::TypeDescription(
mtd->pParams[i].pTypeRef)));
}
}
break;
}
default:
OSL_ASSERT(false); // this cannot happen
break;
}
}
switch (req.kind) {
case OutgoingRequest::KIND_NORMAL:
{
std::auto_ptr< IncomingReply > resp(
new IncomingReply(exc, ret, outArgs));
uno_threadpool_putJob(
bridge_->getThreadPool(), tid.getHandle(), resp.get(), 0,
false);
resp.release();
break;
}
case OutgoingRequest::KIND_REQUEST_CHANGE:
OSL_ASSERT(outArgs.empty());
bridge_->handleRequestChangeReply(exc, ret);
break;
case OutgoingRequest::KIND_COMMIT_CHANGE:
OSL_ASSERT(outArgs.empty());
bridge_->handleCommitChangeReply(exc, ret);
break;
default:
OSL_ASSERT(false); // this cannot happen
break;
}
}
rtl::ByteSequence Reader::getTid(Unmarshal & unmarshal, bool newTid) const {
if (newTid) {
return unmarshal.readTid();
}
if (lastTid_.getLength() == 0) {
throw css::uno::RuntimeException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"URP: message with NEWTID received when last TID has not"
" yet been set")),
css::uno::Reference< css::uno::XInterface >());
}
return lastTid_;
}
}

View File

@@ -0,0 +1,89 @@
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2000, 2011 Oracle and/or its affiliates.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org. If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/
#ifndef INCLUDED_BINARYURP_SOURCE_READER_HXX
#define INCLUDED_BINARYURP_SOURCE_READER_HXX
#include "sal/config.h"
#include <cstddef>
#include "boost/noncopyable.hpp"
#include "osl/thread.hxx"
#include "rtl/byteseq.hxx"
#include "rtl/ref.hxx"
#include "rtl/ustring.hxx"
#include "sal/types.h"
#include "salhelper/simplereferenceobject.hxx"
#include "typelib/typedescription.hxx"
#include "readerstate.hxx"
namespace binaryurp {
class BinaryAny;
class Bridge;
class Unmarshal;
}
namespace binaryurp {
class Reader:
public osl::Thread, public salhelper::SimpleReferenceObject,
private boost::noncopyable
{
public:
static void * operator new(std::size_t size)
{ return Thread::operator new(size); }
static void operator delete(void * pointer)
{ Thread::operator delete(pointer); }
explicit Reader(rtl::Reference< Bridge > const & bridge);
private:
virtual ~Reader();
virtual void SAL_CALL run();
virtual void SAL_CALL onTerminated();
void readMessage(Unmarshal & unmarshal);
void readReplyMessage(Unmarshal & unmarshal, sal_uInt8 flags1);
rtl::ByteSequence getTid(Unmarshal & unmarshal, bool newTid) const;
rtl::Reference< Bridge > bridge_;
com::sun::star::uno::TypeDescription lastType_;
rtl::OUString lastOid_;
rtl::ByteSequence lastTid_;
ReaderState state_;
};
}
#endif

View File

@@ -0,0 +1,52 @@
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2000, 2011 Oracle and/or its affiliates.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org. If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/
#ifndef INCLUDED_BINARYURP_SOURCE_READERSTATE_HXX
#define INCLUDED_BINARYURP_SOURCE_READERSTATE_HXX
#include "sal/config.h"
#include "boost/noncopyable.hpp"
#include "rtl/byteseq.hxx"
#include "rtl/ustring.hxx"
#include "typelib/typedescription.hxx"
#include "cache.hxx"
namespace binaryurp {
struct ReaderState: private boost::noncopyable {
com::sun::star::uno::TypeDescription typeCache[cache::size];
rtl::OUString oidCache[cache::size];
rtl::ByteSequence tidCache[cache::size];
};
}
#endif

View File

@@ -1,9 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--**********************************************************************
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2000, 2010 Oracle and/or its affiliates.
* Copyright 2000, 2011 Oracle and/or its affiliates.
*
* OpenOffice.org - a multi-platform office productivity suite
*
@@ -24,13 +23,27 @@
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
**********************************************************************-->
************************************************************************/
<component loader="com.sun.star.loader.SharedLibrary"
xmlns="http://openoffice.org/2010/uno-components">
<implementation name="com.sun.star.comp.remotebridges.Bridge.various">
<service name="com.sun.star.bridge.Bridge"/>
<service name="com.sun.star.bridge.IiopBridge"/>
<service name="com.sun.star.bridge.UrpBridge"/>
</implementation>
</component>
#ifndef INCLUDED_BINARYURP_SOURCE_SPECIALFUNCTIONIDS_HXX
#define INCLUDED_BINARYURP_SOURCE_SPECIALFUNCTIONIDS_HXX
#include "sal/config.h"
namespace binaryurp {
enum SpecialFunctionIds {
SPECIAL_FUNCTION_ID_QUERY_INTERFACE = 0,
SPECIAL_FUNCTION_ID_RESERVED = 1,
SPECIAL_FUNCTION_ID_RELEASE = 2,
SPECIAL_FUNCTION_ID_REQUEST_CHANGE = 4,
SPECIAL_FUNCTION_ID_COMMIT_CHANGE = 5
};
}
#endif

563
binaryurp/source/unmarshal.cxx Executable file
View File

@@ -0,0 +1,563 @@
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2000, 2011 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 "sal/config.h"
#include <cstdlib>
#include <new>
#include <vector>
#include "boost/noncopyable.hpp"
#include "com/sun/star/io/IOException.hpp"
#include "com/sun/star/uno/Reference.hxx"
#include "com/sun/star/uno/RuntimeException.hpp"
#include "com/sun/star/uno/Sequence.hxx"
#include "com/sun/star/uno/XInterface.hpp"
#include "cppu/unotype.hxx"
#include "osl/diagnose.h"
#include "rtl/byteseq.hxx"
#include "rtl/ref.hxx"
#include "rtl/textcvt.h"
#include "rtl/textenc.h"
#include "rtl/ustring.h"
#include "rtl/ustring.hxx"
#include "sal/types.h"
#include "typelib/typeclass.h"
#include "typelib/typedescription.h"
#include "typelib/typedescription.hxx"
#include "uno/any2.h"
#include "uno/data.h"
#include "uno/dispatcher.hxx"
#include "binaryany.hxx"
#include "bridge.hxx"
#include "cache.hxx"
#include "readerstate.hxx"
#include "unmarshal.hxx"
namespace binaryurp {
namespace {
namespace css = com::sun::star;
void * allocate(sal_Size size) {
void * p = rtl_allocateMemory(size);
if (p == 0) {
throw std::bad_alloc();
}
return p;
}
std::vector< BinaryAny >::iterator copyMemberValues(
css::uno::TypeDescription const & type,
std::vector< BinaryAny >::iterator const & it, void * buffer) throw ()
{
OSL_ASSERT(
type.is() &&
(type.get()->eTypeClass == typelib_TypeClass_STRUCT ||
type.get()->eTypeClass == typelib_TypeClass_EXCEPTION) &&
buffer != 0);
type.makeComplete();
std::vector< BinaryAny >::iterator i(it);
typelib_CompoundTypeDescription * ctd =
reinterpret_cast< typelib_CompoundTypeDescription * >(type.get());
if (ctd->pBaseTypeDescription != 0) {
i = copyMemberValues(
css::uno::TypeDescription(&ctd->pBaseTypeDescription->aBase), i,
buffer);
}
for (sal_Int32 j = 0; j != ctd->nMembers; ++j) {
uno_type_copyData(
static_cast< char * >(buffer) + ctd->pMemberOffsets[j],
const_cast< void * >(
i++->getValue(css::uno::TypeDescription(ctd->ppTypeRefs[j]))),
ctd->ppTypeRefs[j], 0);
}
return i;
}
}
Unmarshal::Unmarshal(
rtl::Reference< Bridge > const & bridge, ReaderState & state,
css::uno::Sequence< sal_Int8 > const & buffer):
bridge_(bridge), state_(state), buffer_(buffer)
{
data_ = reinterpret_cast< sal_uInt8 const * >(buffer_.getConstArray());
end_ = data_ + buffer_.getLength();
}
Unmarshal::~Unmarshal() {}
sal_uInt8 Unmarshal::read8() {
check(1);
return *data_++;
}
sal_uInt16 Unmarshal::read16() {
check(2);
sal_uInt16 n = static_cast< sal_uInt16 >(*data_++) << 8;
return n | *data_++;
}
sal_uInt32 Unmarshal::read32() {
check(4);
sal_uInt32 n = static_cast< sal_uInt32 >(*data_++) << 24;
n |= static_cast< sal_uInt32 >(*data_++) << 16;
n |= static_cast< sal_uInt32 >(*data_++) << 8;
return n | *data_++;
}
css::uno::TypeDescription Unmarshal::readType() {
sal_uInt8 flags = read8();
typelib_TypeClass tc = static_cast< typelib_TypeClass >(flags & 0x7F);
switch (tc) {
case typelib_TypeClass_VOID:
case typelib_TypeClass_BOOLEAN:
case typelib_TypeClass_BYTE:
case typelib_TypeClass_SHORT:
case typelib_TypeClass_UNSIGNED_SHORT:
case typelib_TypeClass_LONG:
case typelib_TypeClass_UNSIGNED_LONG:
case typelib_TypeClass_HYPER:
case typelib_TypeClass_UNSIGNED_HYPER:
case typelib_TypeClass_FLOAT:
case typelib_TypeClass_DOUBLE:
case typelib_TypeClass_CHAR:
case typelib_TypeClass_STRING:
case typelib_TypeClass_TYPE:
case typelib_TypeClass_ANY:
if ((flags & 0x80) != 0) {
throw css::io::IOException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"binaryurp::Unmarshal: cache flag of simple type is"
" set")),
css::uno::Reference< css::uno::XInterface >());
}
return css::uno::TypeDescription(
*typelib_static_type_getByTypeClass(
static_cast< typelib_TypeClass >(tc)));
case typelib_TypeClass_SEQUENCE:
case typelib_TypeClass_ENUM:
case typelib_TypeClass_STRUCT:
case typelib_TypeClass_EXCEPTION:
case typelib_TypeClass_INTERFACE:
{
sal_uInt16 idx = readCacheIndex();
if ((flags & 0x80) == 0) {
if (idx == cache::ignore || !state_.typeCache[idx].is()) {
throw css::io::IOException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"binaryurp::Unmarshal: unknown type cache"
" index")),
css::uno::Reference< css::uno::XInterface >());
}
return state_.typeCache[idx];
} else {
css::uno::TypeDescription t(readString());
if (!t.is() ||
t.get()->eTypeClass != static_cast< typelib_TypeClass >(tc))
{
throw css::io::IOException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"binaryurp::Unmarshal: type with unknown"
" name")),
css::uno::Reference< css::uno::XInterface >());
}
for (css::uno::TypeDescription t2(t);
t2.get()->eTypeClass == typelib_TypeClass_SEQUENCE;)
{
t2.makeComplete();
t2 = css::uno::TypeDescription(
reinterpret_cast< typelib_IndirectTypeDescription * >(
t2.get())->pType);
if (!t2.is()) {
throw css::io::IOException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"binaryurp::Unmarshal: sequence type with"
" unknown component type")),
css::uno::Reference< css::uno::XInterface >());
}
switch (t2.get()->eTypeClass) {
case typelib_TypeClass_VOID:
case typelib_TypeClass_EXCEPTION:
throw css::io::IOException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"binaryurp::Unmarshal: sequence type with"
" bad component type")),
css::uno::Reference< css::uno::XInterface >());
default:
break;
}
}
if (idx != cache::ignore) {
state_.typeCache[idx] = t;
}
return t;
}
}
default:
throw css::io::IOException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"binaryurp::Unmarshal: type of unknown type class")),
css::uno::Reference< css::uno::XInterface >());
}
}
rtl::OUString Unmarshal::readOid() {
rtl::OUString oid(readString());
for (sal_Int32 i = 0; i != oid.getLength(); ++i) {
if (oid[i] > 0x7F) {
throw css::io::IOException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"binaryurp::Unmarshal: OID contains non-ASCII"
" character")),
css::uno::Reference< css::uno::XInterface >());
}
}
sal_uInt16 idx = readCacheIndex();
if (oid.getLength() == 0 && idx != cache::ignore) {
if (state_.oidCache[idx].getLength() == 0) {
throw css::io::IOException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"binaryurp::Unmarshal: unknown OID cache index")),
css::uno::Reference< css::uno::XInterface >());
}
return state_.oidCache[idx];
}
if (idx != cache::ignore) {
state_.oidCache[idx] = oid;
}
return oid;
}
rtl::ByteSequence Unmarshal::readTid() {
rtl::ByteSequence tid(
*static_cast< sal_Sequence * const * >(
readSequence(
css::uno::TypeDescription(
cppu::UnoType< css::uno::Sequence< sal_Int8 > >::get())).
getValue(
css::uno::TypeDescription(
cppu::UnoType< css::uno::Sequence< sal_Int8 > >::get()))));
sal_uInt16 idx = readCacheIndex();
if (tid.getLength() == 0) {
if (idx == cache::ignore || state_.tidCache[idx].getLength() == 0) {
throw css::io::IOException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"binaryurp::Unmarshal: unknown TID cache index")),
css::uno::Reference< css::uno::XInterface >());
}
return state_.tidCache[idx];
}
if (idx != cache::ignore) {
state_.tidCache[idx] = tid;
}
return tid;
}
BinaryAny Unmarshal::readValue(css::uno::TypeDescription const & type) {
OSL_ASSERT(type.is());
switch (type.get()->eTypeClass) {
default:
std::abort(); // this cannot happen
// pseudo fall-through to avoid compiler warnings
case typelib_TypeClass_VOID:
return BinaryAny();
case typelib_TypeClass_BOOLEAN:
{
sal_uInt8 v = read8();
if (v > 1) {
throw css::io::IOException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"binaryurp::Unmarshal: boolean of unknown value")),
css::uno::Reference< css::uno::XInterface >());
}
return BinaryAny(type, &v);
}
case typelib_TypeClass_BYTE:
{
sal_uInt8 v = read8();
return BinaryAny(type, &v);
}
case typelib_TypeClass_SHORT:
case typelib_TypeClass_UNSIGNED_SHORT:
case typelib_TypeClass_CHAR:
{
sal_uInt16 v = read16();
return BinaryAny(type, &v);
}
case typelib_TypeClass_LONG:
case typelib_TypeClass_UNSIGNED_LONG:
case typelib_TypeClass_FLOAT:
{
sal_uInt32 v = read32();
return BinaryAny(type, &v);
}
case typelib_TypeClass_HYPER:
case typelib_TypeClass_UNSIGNED_HYPER:
case typelib_TypeClass_DOUBLE:
{
sal_uInt64 v = read64();
return BinaryAny(type, &v);
}
case typelib_TypeClass_STRING:
{
rtl::OUString v(readString());
return BinaryAny(type, &v.pData);
}
case typelib_TypeClass_TYPE:
{
css::uno::TypeDescription v(readType());
typelib_TypeDescription * p = v.get();
return BinaryAny(type, &p);
}
case typelib_TypeClass_ANY:
{
css::uno::TypeDescription t(readType());
if (t.get()->eTypeClass == typelib_TypeClass_ANY) {
throw css::io::IOException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"binaryurp::Unmarshal: any of type ANY")),
css::uno::Reference< css::uno::XInterface >());
}
return readValue(t);
}
case typelib_TypeClass_SEQUENCE:
type.makeComplete();
return readSequence(type);
case typelib_TypeClass_ENUM:
{
sal_Int32 v = static_cast< sal_Int32 >(read32());
type.makeComplete();
typelib_EnumTypeDescription * etd =
reinterpret_cast< typelib_EnumTypeDescription * >(type.get());
bool found = false;
for (sal_Int32 i = 0; i != etd->nEnumValues; ++i) {
if (etd->pEnumValues[i] == v) {
found = true;
break;
}
}
if (!found) {
throw css::io::IOException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"binaryurp::Unmarshal: unknown enum value")),
css::uno::Reference< css::uno::XInterface >());
}
return BinaryAny(type, &v);
}
case typelib_TypeClass_STRUCT:
case typelib_TypeClass_EXCEPTION:
{
std::vector< BinaryAny > as;
readMemberValues(type, &as);
void * buf = allocate(type.get()->nSize);
copyMemberValues(type, as.begin(), buf);
uno_Any raw;
raw.pType = reinterpret_cast< typelib_TypeDescriptionReference * >(
type.get());
raw.pData = buf;
raw.pReserved = 0;
return BinaryAny(raw);
}
case typelib_TypeClass_INTERFACE:
{
css::uno::UnoInterfaceReference obj(
bridge_->registerIncomingInterface(readOid(), type));
return BinaryAny(type, &obj.m_pUnoI);
}
}
}
void Unmarshal::done() const {
if (data_ != end_) {
throw css::io::IOException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"binaryurp::Unmarshal: block contains excess data")),
css::uno::Reference< css::uno::XInterface >());
}
}
void Unmarshal::check(sal_Int32 size) const {
if (end_ - data_ < size) {
throw css::io::IOException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"binaryurp::Unmarshal: trying to read past end of block")),
css::uno::Reference< css::uno::XInterface >());
}
}
sal_uInt32 Unmarshal::readCompressed() {
sal_uInt8 n = read8();
return n == 0xFF ? read32() : n;
}
sal_uInt16 Unmarshal::readCacheIndex() {
sal_uInt16 idx = read16();
if (idx >= cache::size && idx != cache::ignore) {
throw css::io::IOException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"binaryurp::Unmarshal: cache index out of range")),
css::uno::Reference< css::uno::XInterface >());
}
return idx;
}
sal_uInt64 Unmarshal::read64() {
check(8);
sal_uInt64 n = static_cast< sal_uInt64 >(*data_++) << 56;
n |= static_cast< sal_uInt64 >(*data_++) << 48;
n |= static_cast< sal_uInt64 >(*data_++) << 40;
n |= static_cast< sal_uInt64 >(*data_++) << 32;
n |= static_cast< sal_uInt64 >(*data_++) << 24;
n |= static_cast< sal_uInt64 >(*data_++) << 16;
n |= static_cast< sal_uInt64 >(*data_++) << 8;
return n | *data_++;
}
rtl::OUString Unmarshal::readString() {
sal_uInt32 n = readCompressed();
if (n > SAL_MAX_INT32) {
throw css::uno::RuntimeException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"binaryurp::Unmarshal: string size too large")),
css::uno::Reference< css::uno::XInterface >());
}
check(static_cast< sal_Int32 >(n));
rtl::OUString s;
if (!rtl_convertStringToUString(
&s.pData, reinterpret_cast< char const * >(data_),
static_cast< sal_Int32 >(n), RTL_TEXTENCODING_UTF8,
(RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR |
RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR |
RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)))
{
throw css::io::IOException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"binaryurp::Unmarshal: string does not contain UTF-8")),
css::uno::Reference< css::uno::XInterface >());
}
data_ += n;
return s;
}
BinaryAny Unmarshal::readSequence(css::uno::TypeDescription const & type) {
OSL_ASSERT(
type.is() && type.get()->eTypeClass == typelib_TypeClass_SEQUENCE);
sal_uInt32 n = readCompressed();
if (n > SAL_MAX_INT32) {
throw css::uno::RuntimeException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"binaryurp::Unmarshal: sequence size too large")),
css::uno::Reference< css::uno::XInterface >());
}
if (n == 0) {
return BinaryAny(type, 0);
}
css::uno::TypeDescription ctd(
reinterpret_cast< typelib_IndirectTypeDescription * >(
type.get())->pType);
if (ctd.get()->eTypeClass == typelib_TypeClass_BYTE) {
check(static_cast< sal_Int32 >(n));
rtl::ByteSequence s(
reinterpret_cast< sal_Int8 const * >(data_),
static_cast< sal_Int32 >(n));
data_ += n;
sal_Sequence * p = s.getHandle();
return BinaryAny(type, &p);
}
std::vector< BinaryAny > as;
for (sal_uInt32 i = 0; i != n; ++i) {
as.push_back(readValue(ctd));
}
OSL_ASSERT(ctd.get()->nSize >= 0);
sal_uInt64 size = static_cast< sal_uInt64 >(n) *
static_cast< sal_uInt64 >(ctd.get()->nSize);
// sal_uInt32 * sal_Int32 -> sal_uInt64 cannot overflow
if (size > SAL_MAX_SIZE - SAL_SEQUENCE_HEADER_SIZE) {
throw css::uno::RuntimeException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"binaryurp::Unmarshal: sequence size too large")),
css::uno::Reference< css::uno::XInterface >());
}
void * buf = allocate(
SAL_SEQUENCE_HEADER_SIZE + static_cast< sal_Size >(size));
static_cast< sal_Sequence * >(buf)->nRefCount = 0;
static_cast< sal_Sequence * >(buf)->nElements =
static_cast< sal_Int32 >(n);
for (sal_uInt32 i = 0; i != n; ++i) {
uno_copyData(
static_cast< sal_Sequence * >(buf)->elements + i * ctd.get()->nSize,
const_cast< void * >(as[i].getValue(ctd)), ctd.get(), 0);
}
return BinaryAny(type, reinterpret_cast< sal_Sequence ** >(&buf));
}
void Unmarshal::readMemberValues(
css::uno::TypeDescription const & type, std::vector< BinaryAny > * values)
{
OSL_ASSERT(
type.is() &&
(type.get()->eTypeClass == typelib_TypeClass_STRUCT ||
type.get()->eTypeClass == typelib_TypeClass_EXCEPTION) &&
values != 0);
type.makeComplete();
typelib_CompoundTypeDescription * ctd =
reinterpret_cast< typelib_CompoundTypeDescription * >(type.get());
if (ctd->pBaseTypeDescription != 0) {
readMemberValues(
css::uno::TypeDescription(&ctd->pBaseTypeDescription->aBase),
values);
}
for (sal_Int32 i = 0; i != ctd->nMembers; ++i) {
values->push_back(
readValue(css::uno::TypeDescription(ctd->ppTypeRefs[i])));
}
}
}

View File

@@ -0,0 +1,106 @@
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2000, 2011 Oracle and/or its affiliates.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org. If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/
#ifndef INCLUDED_BINARYURP_SOURCE_UNMARSHAL_HXX
#define INCLUDED_BINARYURP_SOURCE_UNMARSHAL_HXX
#include "sal/config.h"
#include <vector>
#include "boost/noncopyable.hpp"
#include "com/sun/star/uno/Sequence.hxx"
#include "rtl/ref.hxx"
#include "sal/types.h"
#include "typelib/typedescription.hxx"
namespace binaryurp {
class BinaryAny;
class Bridge;
struct ReaderState;
}
namespace com { namespace sun { namespace star { namespace uno {
class TypeDescription;
} } } }
namespace rtl {
class ByteSequecne;
class OUString;
}
namespace binaryurp {
class Unmarshal: private boost::noncopyable {
public:
Unmarshal(
rtl::Reference< Bridge > const & bridge, ReaderState & state,
com::sun::star::uno::Sequence< sal_Int8 > const & buffer);
~Unmarshal();
sal_uInt8 read8();
sal_uInt16 read16();
sal_uInt32 read32();
com::sun::star::uno::TypeDescription readType();
rtl::OUString readOid();
rtl::ByteSequence readTid();
BinaryAny readValue(com::sun::star::uno::TypeDescription const & type);
void done() const;
private:
void check(sal_Int32 size) const;
sal_uInt32 readCompressed();
sal_uInt16 readCacheIndex();
sal_uInt64 read64();
rtl::OUString readString();
BinaryAny readSequence(com::sun::star::uno::TypeDescription const & type);
void readMemberValues(
com::sun::star::uno::TypeDescription const & type,
std::vector< BinaryAny > * values);
rtl::Reference< Bridge > bridge_;
ReaderState & state_;
com::sun::star::uno::Sequence< sal_Int8 > buffer_;
sal_uInt8 const * data_;
sal_uInt8 const * end_;
};
}
#endif

475
binaryurp/source/writer.cxx Executable file
View File

@@ -0,0 +1,475 @@
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2000, 2011 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 "sal/config.h"
#include <exception>
#include <vector>
#include "com/sun/star/connection/XConnection.hpp"
#include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
#include "com/sun/star/uno/XCurrentContext.hpp"
#include "cppuhelper/exc_hlp.hxx"
#include "osl/mutex.hxx"
#include "rtl/memory.h"
#include "uno/dispatcher.hxx"
#include "binaryany.hxx"
#include "bridge.hxx"
#include "currentcontext.hxx"
#include "specialfunctionids.hxx"
#include "writer.hxx"
namespace binaryurp {
namespace {
namespace css = com::sun::star;
bool isProtocolPropertyMessage(rtl::OUString const & oid) {
return oid.equalsAsciiL(
RTL_CONSTASCII_STRINGPARAM("UrpProtocolProperties"));
}
}
Writer::Item::Item() {}
Writer::Item::Item(
rtl::ByteSequence const & theTid, rtl::OUString const & theOid,
css::uno::TypeDescription const & theType,
css::uno::TypeDescription const & theMember,
std::vector< BinaryAny > const & inArguments,
css::uno::UnoInterfaceReference const & theCurrentContext):
request(true), tid(theTid), oid(theOid), type(theType), member(theMember),
arguments(inArguments), currentContext(theCurrentContext)
{}
Writer::Item::Item(
rtl::ByteSequence const & theTid,
css::uno::TypeDescription const & theMember, bool theSetter,
bool theException, BinaryAny const & theReturnValue,
std::vector< BinaryAny > const & outArguments,
bool theSetCurrentContextMode):
request(false), tid(theTid), member(theMember), setter(theSetter),
arguments(outArguments), exception(theException),
returnValue(theReturnValue), setCurrentContextMode(theSetCurrentContextMode)
{}
Writer::Writer(rtl::Reference< Bridge > const & bridge):
bridge_(bridge), marshal_(bridge, state_), stop_(false)
{
OSL_ASSERT(bridge.is());
acquire();
}
void Writer::sendDirectRequest(
rtl::ByteSequence const & tid, rtl::OUString const & oid,
css::uno::TypeDescription const & type,
css::uno::TypeDescription const & member,
std::vector< BinaryAny > const & inArguments)
{
OSL_ASSERT(!unblocked_.check());
sendRequest(
tid, oid, type, member, inArguments, false,
css::uno::UnoInterfaceReference());
}
void Writer::sendDirectReply(
rtl::ByteSequence const & tid, css::uno::TypeDescription const & member,
bool exception, BinaryAny const & returnValue,
std::vector< BinaryAny > const & outArguments)
{
OSL_ASSERT(!unblocked_.check());
sendReply(tid, member, false, exception, returnValue,outArguments);
}
void Writer::queueRequest(
rtl::ByteSequence const & tid, rtl::OUString const & oid,
css::uno::TypeDescription const & type,
css::uno::TypeDescription const & member,
std::vector< BinaryAny > const & inArguments)
{
css::uno::UnoInterfaceReference cc(current_context::get());
osl::MutexGuard g(mutex_);
queue_.push_back(Item(tid, oid, type, member, inArguments, cc));
items_.set();
}
void Writer::queueReply(
rtl::ByteSequence const & tid,
com::sun::star::uno::TypeDescription const & member, bool setter,
bool exception, BinaryAny const & returnValue,
std::vector< BinaryAny > const & outArguments, bool setCurrentContextMode)
{
osl::MutexGuard g(mutex_);
queue_.push_back(
Item(
tid, member, setter, exception, returnValue, outArguments,
setCurrentContextMode));
items_.set();
}
void Writer::unblock() {
// Assumes that osl::Condition::set works as a memory barrier, so that
// changes made by preceeding sendDirectRequest/Reply calls are visible to
// subsequent sendRequest/Reply calls:
unblocked_.set();
}
void Writer::stop() {
{
osl::MutexGuard g(mutex_);
stop_ = true;
}
unblocked_.set();
items_.set();
}
Writer::~Writer() {}
void Writer::run() {
try {
unblocked_.wait();
for (;;) {
items_.wait();
Item item;
{
osl::MutexGuard g(mutex_);
if (stop_) {
return;
}
OSL_ASSERT(!queue_.empty());
item = queue_.front();
queue_.pop_front();
if (queue_.empty()) {
items_.reset();
}
}
if (item.request) {
sendRequest(
item.tid, item.oid, item.type, item.member, item.arguments,
(!item.oid.equalsAsciiL(
RTL_CONSTASCII_STRINGPARAM("UrpProtocolProperties")) &&
!item.member.equals(
css::uno::TypeDescription(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"com.sun.star.uno.XInterface::"
"release")))) &&
bridge_->isCurrentContextMode()),
item.currentContext);
} else {
sendReply(
item.tid, item.member, item.setter, item.exception,
item.returnValue, item.arguments);
if (item.setCurrentContextMode) {
bridge_->setCurrentContextMode();
}
}
}
} catch (css::uno::Exception & e) {
OSL_TRACE(
OSL_LOG_PREFIX "caught UNO exception '%s'",
rtl::OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8).getStr());
} catch (std::exception & e) {
OSL_TRACE(OSL_LOG_PREFIX "caught C++ exception '%s'", e.what());
}
bridge_->terminate();
}
void Writer::onTerminated() {
release();
}
void Writer::sendRequest(
rtl::ByteSequence const & tid, rtl::OUString const & oid,
css::uno::TypeDescription const & type,
css::uno::TypeDescription const & member,
std::vector< BinaryAny > const & inArguments, bool currentContextMode,
css::uno::UnoInterfaceReference const & currentContext)
{
OSL_ASSERT(tid.getLength() != 0 && oid.getLength() != 0 && member.is());
css::uno::TypeDescription t(type);
sal_Int32 functionId = 0;
bool forceSynchronous = false;
member.makeComplete();
switch (member.get()->eTypeClass) {
case typelib_TypeClass_INTERFACE_ATTRIBUTE:
{
typelib_InterfaceAttributeTypeDescription * atd =
reinterpret_cast< typelib_InterfaceAttributeTypeDescription * >(
member.get());
OSL_ASSERT(atd->pInterface != 0);
if (!t.is()) {
t = css::uno::TypeDescription(&atd->pInterface->aBase);
}
t.makeComplete();
functionId = atd->pInterface->pMapMemberIndexToFunctionIndex[
atd->aBase.nPosition];
if (!inArguments.empty()) { // setter
++functionId;
}
break;
}
case typelib_TypeClass_INTERFACE_METHOD:
{
typelib_InterfaceMethodTypeDescription * mtd =
reinterpret_cast< typelib_InterfaceMethodTypeDescription * >(
member.get());
OSL_ASSERT(mtd->pInterface != 0);
if (!t.is()) {
t = css::uno::TypeDescription(&mtd->pInterface->aBase);
}
t.makeComplete();
functionId = mtd->pInterface->pMapMemberIndexToFunctionIndex[
mtd->aBase.nPosition];
forceSynchronous = mtd->bOneWay &&
functionId != SPECIAL_FUNCTION_ID_RELEASE;
break;
}
default:
OSL_ASSERT(false); // this cannot happen
break;
}
OSL_ASSERT(functionId >= 0);
if (functionId > SAL_MAX_UINT16) {
throw css::uno::RuntimeException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM("function ID too large for URP")),
css::uno::Reference< css::uno::XInterface >());
}
std::vector< unsigned char > buf;
bool newType = !(lastType_.is() && t.equals(lastType_));
bool newOid = oid != lastOid_;
bool newTid = tid != lastTid_;
if (newType || newOid || newTid || forceSynchronous || functionId > 0x3FFF)
// > 14 bit function ID
{
Marshal::write8(
&buf,
(0xC0 | (newType ? 0x20 : 0) | (newOid ? 0x10 : 0) |
(newTid ? 0x08 : 0) | (functionId > 0xFF ? 0x04 : 0) |
(forceSynchronous ? 0x01 : 0)));
// bit 7: LONGHEADER, bit 6: REQUEST, bit 5: NEWTYPE, bit 4: NEWOID,
// bit 3: NEWTID, bit 2: FUNCTIONID16, bit 0: MOREFLAGS
if (forceSynchronous) {
Marshal::write8(&buf, 0xC0); // bit 7: MUSTREPLY, bit 6: SYNCHRONOUS
}
if (functionId <= 0xFF) {
Marshal::write8(&buf, static_cast< sal_uInt8 >(functionId));
} else {
Marshal::write16(&buf, static_cast< sal_uInt16 >(functionId));
}
if (newType) {
marshal_.writeType(&buf, t);
}
if (newOid) {
marshal_.writeOid(&buf, oid);
}
if (newTid) {
marshal_.writeTid(&buf, tid);
}
} else if (functionId <= 0x3F) { // <= 6 bit function ID
Marshal::write8(&buf, static_cast< sal_uInt8 >(functionId));
// bit 7: !LONGHEADER, bit 6: !FUNCTIONID14
} else {
Marshal::write8(
&buf, static_cast< sal_uInt8 >(0x40 | (functionId >> 8)));
// bit 7: !LONGHEADER, bit 6: FUNCTIONID14
Marshal::write8(&buf, functionId & 0xFF);
}
if (currentContextMode) {
css::uno::UnoInterfaceReference cc(currentContext);
marshal_.writeValue(
&buf,
css::uno::TypeDescription(
cppu::UnoType<
css::uno::Reference< css::uno::XCurrentContext > >::get()),
BinaryAny(
css::uno::TypeDescription(
cppu::UnoType<
css::uno::Reference<
css::uno::XCurrentContext > >::get()),
&cc.m_pUnoI));
}
switch (member.get()->eTypeClass) {
case typelib_TypeClass_INTERFACE_ATTRIBUTE:
if (!inArguments.empty()) { // setter
OSL_ASSERT(inArguments.size() == 1);
marshal_.writeValue(
&buf,
css::uno::TypeDescription(
reinterpret_cast<
typelib_InterfaceAttributeTypeDescription * >(
member.get())->
pAttributeTypeRef),
inArguments.front());
}
break;
case typelib_TypeClass_INTERFACE_METHOD:
{
typelib_InterfaceMethodTypeDescription * mtd =
reinterpret_cast< typelib_InterfaceMethodTypeDescription * >(
member.get());
std::vector< BinaryAny >::const_iterator i(inArguments.begin());
for (sal_Int32 j = 0; j != mtd->nParams; ++j) {
if (mtd->pParams[j].bIn) {
marshal_.writeValue(
&buf,
css::uno::TypeDescription(mtd->pParams[j].pTypeRef),
*i++);
}
}
OSL_ASSERT(i == inArguments.end());
break;
}
default:
OSL_ASSERT(false); // this cannot happen
break;
}
sendMessage(buf);
lastType_ = t;
lastOid_ = oid;
lastTid_ = tid;
}
void Writer::sendReply(
rtl::ByteSequence const & tid,
com::sun::star::uno::TypeDescription const & member, bool setter,
bool exception, BinaryAny const & returnValue,
std::vector< BinaryAny > const & outArguments)
{
OSL_ASSERT(tid.getLength() != 0 && member.is() && member.get()->bComplete);
std::vector< unsigned char > buf;
bool newTid = tid != lastTid_;
Marshal::write8(&buf, 0x80 | (exception ? 0x20 : 0) | (newTid ? 0x08 : 0));
// bit 7: LONGHEADER; bit 6: !REQUEST; bit 5: EXCEPTION; bit 3: NEWTID
if (newTid) {
marshal_.writeTid(&buf, tid);
}
if (exception) {
marshal_.writeValue(
&buf,
css::uno::TypeDescription(cppu::UnoType< css::uno::Any >::get()),
returnValue);
} else {
switch (member.get()->eTypeClass) {
case typelib_TypeClass_INTERFACE_ATTRIBUTE:
if (!setter) {
marshal_.writeValue(
&buf,
css::uno::TypeDescription(
reinterpret_cast<
typelib_InterfaceAttributeTypeDescription * >(
member.get())->
pAttributeTypeRef),
returnValue);
}
break;
case typelib_TypeClass_INTERFACE_METHOD:
{
typelib_InterfaceMethodTypeDescription * mtd =
reinterpret_cast<
typelib_InterfaceMethodTypeDescription * >(
member.get());
marshal_.writeValue(
&buf, css::uno::TypeDescription(mtd->pReturnTypeRef),
returnValue);
std::vector< BinaryAny >::const_iterator i(
outArguments.begin());
for (sal_Int32 j = 0; j != mtd->nParams; ++j) {
if (mtd->pParams[j].bOut) {
marshal_.writeValue(
&buf,
css::uno::TypeDescription(mtd->pParams[j].pTypeRef),
*i++);
}
}
OSL_ASSERT(i == outArguments.end());
break;
}
default:
OSL_ASSERT(false); // this cannot happen
break;
}
}
sendMessage(buf);
lastTid_ = tid;
bridge_->decrementCalls();
}
void Writer::sendMessage(std::vector< unsigned char > const & buffer) {
std::vector< unsigned char > header;
if (buffer.size() > SAL_MAX_UINT32) {
throw css::uno::RuntimeException(
rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM("message too large for URP")),
css::uno::Reference< css::uno::XInterface >());
}
Marshal::write32(&header, static_cast< sal_uInt32 >(buffer.size()));
Marshal::write32(&header, 1);
OSL_ASSERT(!buffer.empty());
unsigned char const * p = &buffer[0];
std::vector< unsigned char >::size_type n = buffer.size();
OSL_ASSERT(header.size() <= SAL_MAX_INT32 && SAL_MAX_INT32 <= SAL_MAX_SIZE);
sal_Size k = SAL_MAX_INT32 - header.size();
if (n < k) {
k = static_cast< sal_Size >(n);
}
css::uno::Sequence< sal_Int8 > s(
static_cast< sal_Int32 >(header.size() + k));
OSL_ASSERT(!header.empty());
rtl_copyMemory(
s.getArray(), &header[0], static_cast< sal_Size >(header.size()));
for (;;) {
rtl_copyMemory(s.getArray() + s.getLength() - k, p, k);
try {
bridge_->getConnection()->write(s);
} catch (css::io::IOException & e) {
css::uno::Any exc(cppu::getCaughtException());
throw css::lang::WrappedTargetRuntimeException(
(rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"Binary URP write raised IO exception: ")) +
e.Message),
css::uno::Reference< css::uno::XInterface >(), exc);
}
n = static_cast< std::vector< unsigned char >::size_type >(n - k);
if (n == 0) {
break;
}
p += k;
k = SAL_MAX_INT32;
if (n < k) {
k = static_cast< sal_Size >(n);
}
s.realloc(k);
}
}
}

185
binaryurp/source/writer.hxx Normal file
View File

@@ -0,0 +1,185 @@
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2000, 2011 Oracle and/or its affiliates.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org. If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/
#ifndef INCLUDED_BINARYURP_SOURCE_WRITER_HXX
#define INCLUDED_BINARYURP_SOURCE_WRITER_HXX
#include "sal/config.h"
#include <cstddef>
#include <deque>
#include <vector>
#include "boost/noncopyable.hpp"
#include "osl/conditn.hxx"
#include "osl/mutex.hxx"
#include "osl/thread.hxx"
#include "rtl/byteseq.hxx"
#include "rtl/ref.hxx"
#include "rtl/ustring.hxx"
#include "sal/types.h"
#include "salhelper/simplereferenceobject.hxx"
#include "typelib/typedescription.hxx"
#include "uno/dispatcher.hxx"
#include "binaryany.hxx"
#include "marshal.hxx"
#include "writerstate.hxx"
namespace binaryurp { class Bridge; }
namespace binaryurp {
class Writer:
public osl::Thread, public salhelper::SimpleReferenceObject,
private boost::noncopyable
{
public:
static void * operator new(std::size_t size)
{ return Thread::operator new(size); }
static void operator delete(void * pointer)
{ Thread::operator delete(pointer); }
explicit Writer(rtl::Reference< Bridge > const & bridge);
// Only called from Bridge::reader_ thread, and only before Bridge::writer_
// thread is unblocked:
void sendDirectRequest(
rtl::ByteSequence const & tid, rtl::OUString const & oid,
com::sun::star::uno::TypeDescription const & type,
com::sun::star::uno::TypeDescription const & member,
std::vector< BinaryAny > const & inArguments);
// Only called from Bridge::reader_ thread, and only before Bridge::writer_
// thread is unblocked:
void sendDirectReply(
rtl::ByteSequence const & tid,
com::sun::star::uno::TypeDescription const & member,
bool exception, BinaryAny const & returnValue,
std::vector< BinaryAny > const & outArguments);
void queueRequest(
rtl::ByteSequence const & tid, rtl::OUString const & oid,
com::sun::star::uno::TypeDescription const & type,
com::sun::star::uno::TypeDescription const & member,
std::vector< BinaryAny > const & inArguments);
void queueReply(
rtl::ByteSequence const & tid,
com::sun::star::uno::TypeDescription const & member, bool setter,
bool exception, BinaryAny const & returnValue,
std::vector< BinaryAny > const & outArguments,
bool setCurrentContextMode);
void unblock();
void stop();
private:
virtual ~Writer();
virtual void SAL_CALL run();
virtual void SAL_CALL onTerminated();
void sendRequest(
rtl::ByteSequence const & tid, rtl::OUString const & oid,
com::sun::star::uno::TypeDescription const & type,
com::sun::star::uno::TypeDescription const & member,
std::vector< BinaryAny > const & inArguments, bool currentContextMode,
com::sun::star::uno::UnoInterfaceReference const & currentContext);
void sendReply(
rtl::ByteSequence const & tid,
com::sun::star::uno::TypeDescription const & member, bool setter,
bool exception, BinaryAny const & returnValue,
std::vector< BinaryAny > const & outArguments);
void sendMessage(std::vector< unsigned char > const & buffer);
struct Item {
Item();
// Request:
Item(
rtl::ByteSequence const & theTid, rtl::OUString const & theOid,
com::sun::star::uno::TypeDescription const & theType,
com::sun::star::uno::TypeDescription const & theMember,
std::vector< BinaryAny > const & inArguments,
com::sun::star::uno::UnoInterfaceReference const &
theCurrentContext);
// Reply:
Item(
rtl::ByteSequence const & theTid,
com::sun::star::uno::TypeDescription const & theMember,
bool theSetter, bool theException, BinaryAny const & theReturnValue,
std::vector< BinaryAny > const & outArguments,
bool theSetCurrentContextMode);
bool request;
rtl::ByteSequence tid; // request + reply
rtl::OUString oid; // request
com::sun::star::uno::TypeDescription type; // request
com::sun::star::uno::TypeDescription member; // request + reply
bool setter; // reply
std::vector< BinaryAny > arguments;
// request: inArguments; reply: outArguments
bool exception; // reply
BinaryAny returnValue; // reply
com::sun::star::uno::UnoInterfaceReference currentContext; // request
bool setCurrentContextMode; // reply
};
rtl::Reference< Bridge > bridge_;
WriterState state_;
Marshal marshal_;
com::sun::star::uno::TypeDescription lastType_;
rtl::OUString lastOid_;
rtl::ByteSequence lastTid_;
osl::Condition unblocked_;
osl::Condition items_;
osl::Mutex mutex_;
std::deque< Item > queue_;
bool stop_;
};
}
#endif

View File

@@ -0,0 +1,55 @@
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2000, 2011 Oracle and/or its affiliates.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org. If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/
#ifndef INCLUDED_BINARYURP_SOURCE_WRITERSTATE_HXX
#define INCLUDED_BINARYURP_SOURCE_WRITERSTATE_HXX
#include "sal/config.h"
#include "boost/noncopyable.hpp"
#include "rtl/byteseq.hxx"
#include "rtl/ustring.hxx"
#include "typelib/typedescription.hxx"
#include "cache.hxx"
namespace binaryurp {
struct WriterState: private boost::noncopyable {
WriterState():
typeCache(cache::size), oidCache(cache::size), tidCache(cache::size) {}
Cache< com::sun::star::uno::TypeDescription > typeCache;
Cache< rtl::OUString > oidCache;
Cache< rtl::ByteSequence > tidCache;
};
}
#endif

View File

@@ -1,94 +0,0 @@
/*************************************************************************
*
* 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_BRIDGEIMPL_HXX_
#define _BRIDGES_REMOTE_BRIDGEIMPL_HXX_
#include <osl/interlck.h>
#include <uno/environment.h>
#include <bridges/remote/context.h>
#include <bridges/remote/remote.h>
struct remote_BridgeImpl
{
void (SAL_CALL * m_allThreadsAreGone ) ( uno_Environment * );
requestClientSideDispatcher m_sendRequest;
oslInterlockedCount m_nRemoteThreads;
sal_Bool m_bDisposed;
sal_Bool m_bReleaseStubsCalled;
};
namespace bridges_remote {
enum RemoteThreadCounter_HoldEnvWeak
{
RTC_HOLDENVWEAK = 0x1
};
class RemoteThreadCounter
{
public:
// performance optimization. In some cases, it is not necessary to acquire the
// environment.
RemoteThreadCounter( uno_Environment *pEnvRemote, RemoteThreadCounter_HoldEnvWeak )
: m_bReleaseEnvironment( sal_False )
, m_pEnvRemote( pEnvRemote )
{
remote_Context *pContext = ((remote_Context *) m_pEnvRemote->pContext );
osl_incrementInterlockedCount( &( pContext->m_pBridgeImpl->m_nRemoteThreads ) );
}
RemoteThreadCounter( uno_Environment *pEnvRemote )
: m_bReleaseEnvironment( sal_True )
, m_pEnvRemote( pEnvRemote )
{
m_pEnvRemote->acquire( m_pEnvRemote );
remote_Context *pContext = ((remote_Context *) m_pEnvRemote->pContext );
osl_incrementInterlockedCount( &( pContext->m_pBridgeImpl->m_nRemoteThreads ) );
}
~RemoteThreadCounter( )
{
remote_Context *pContext = ((remote_Context *) m_pEnvRemote->pContext );
if( 0 == osl_decrementInterlockedCount( &( pContext->m_pBridgeImpl->m_nRemoteThreads)) &&
pContext->m_pBridgeImpl->m_bDisposed &&
! pContext->m_pBridgeImpl->m_bReleaseStubsCalled )
{
pContext->m_pBridgeImpl->m_allThreadsAreGone( m_pEnvRemote );
}
if( m_bReleaseEnvironment )
m_pEnvRemote->release( m_pEnvRemote );
}
sal_Bool m_bReleaseEnvironment;
uno_Environment *m_pEnvRemote;
};
}
#endif

View File

@@ -1,67 +0,0 @@
/*************************************************************************
*
* 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_CONNECTION_H_
#define _BRIDGES_REMOTE_CONNECTION_H_
#include <sal/types.h>
/** Specfies a C-interface for a bidirectional bytestream,
which is used by a UNO remote environment.
*/
struct remote_Connection
{
void ( SAL_CALL * acquire ) ( remote_Connection *);
void ( SAL_CALL * release ) ( remote_Connection *);
/**
reads nSize bytes from the connection. This method blocks, until
all bytes are available or an error occurs.
@return Number of bytes read.
If the return value is less than nSize, an unrecoverable
i/o error has occured or the connection was closed.
*/
sal_Int32 (SAL_CALL * read)(remote_Connection *, sal_Int8 *pDest, sal_Int32 nSize );
/**
@return Number of bytes written.
if the return value is less than nSize an unrecoverable
i/o error has occured or the connection was closed.
*/
sal_Int32 (SAL_CALL * write)(remote_Connection *, const sal_Int8 *pSource, sal_Int32 nSize );
void ( SAL_CALL * flush ) ( remote_Connection * );
/** closes the connection.
Any read or write operation after this call shall not be served
anymore. Any ongoing read or write operation must return immeadiatly after this call.
The implementation should cope with multiple calls to this method.
*/
void (SAL_CALL * close) ( remote_Connection * );
};
#endif

View File

@@ -1,260 +0,0 @@
/*************************************************************************
*
* 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_CONTEXT_H_
#define _BRIDGES_REMOTE_CONTEXT_H_
#include <osl/interlck.h>
#include <osl/conditn.h>
#include <typelib/typedescription.h>
#include <uno/environment.h>
#include <uno/any2.h>
/** Interface for refcounted contexts of uno-environments.
Not all uno_Contexts need to be refcounted, in case they are,
they should be 'derived' from this struct.
This is used as a base class for the remote_Context.
@see uno_Environment
@see uno_getEnvironment()
@see remote_Context
*/
struct uno_Context
{
/** increase the refcount of the context
*/
void (SAL_CALL * acquire)( uno_Context *pContext );
/** decrements the recount of the context. In case the recount drops to zero,
the context gets destroye.
*/
void (SAL_CALL * release)( uno_Context *pContext);
/** Allows to query for a different interface of the uno_Context.
The result of the void pointer is unspecified and depends on the concrete context.
*/
void * (SAL_CALL *query ) ( uno_Context *pContext , rtl_uString *pId);
};
struct remote_Connection;
struct remote_Context;
struct remote_Interface;
/** performs a query-interface for a certain interface via the remote connection !
@param pEnvRemote The environment, that shall perform the call.
@param ppRemoteI in/out parameter contains the interface returned by queryInterface
@param pOid the oid of the 'ghost' object on which the call must be done.
***/
typedef void ( SAL_CALL * remote_getInstanceFunc ) (
uno_Environment *pEnvRemote,
remote_Interface **ppRemoteI,
rtl_uString *pOid,
typelib_TypeDescriptionReference *pInterfaceTypeRef,
uno_Any **ppException );
/** refcounted C-interface, which provides object by name.
*/
struct remote_InstanceProvider
{
void (SAL_CALL * acquire ) ( remote_InstanceProvider * pProvider );
void (SAL_CALL * release ) ( remote_InstanceProvider * pProvider );
void (SAL_CALL * getInstance ) ( remote_InstanceProvider * pProvider ,
uno_Environment *pEnvRemote,
remote_Interface **ppRemoteI,
rtl_uString *pInstanceName,
typelib_InterfaceTypeDescription *pType,
uno_Any **ppException );
};
/** refcounted C-interface, which allows to register a listener to an
remote bridge to be informed when the bridge gets disposed.
@see remote_Context
*/
struct remote_DisposingListener
{
void (SAL_CALL * acquire ) ( remote_DisposingListener * pProvider );
void (SAL_CALL * release ) ( remote_DisposingListener * pProvider );
void (SAL_CALL * disposing ) ( remote_DisposingListener * pProvider,
rtl_uString *pBridgeName );
};
/**
Try to get an existing context characterized by the pIdString. Each ID-String must
uniquely charcterize a certain connection. The context can't be retrieved via this
function anymore, after it got disposed.
@return 0 when such a context does not exist, otherwise
a pointer to an acquired remote_Context.
**/
extern "C" remote_Context * SAL_CALL
remote_getContext( rtl_uString *pIdString );
/**
Create an acquired remote context. The Context is weakly held by the context administration
and can be accessed later through remote_getContext() (using the same id-string).
@param pIdString A string, that uniquely describes the connection. For e.g. a socket connection,
host and port of the local and remote host should be in the string.
@param pDescription
Description of the connection, that may brought up to the user.
@param pProtocol
The protocol, that the environment uses for
communicating with the remote process.
The format of the protocol string is : "protocolname,para1=para1value,..."
@return 0, when a context with this name already exists.
@see remote_getContext()
@see remote_Context
*/
extern "C" remote_Context * SAL_CALL
remote_createContext( remote_Connection *pConnection,
rtl_uString *pIdStr,
rtl_uString *pDescription,
rtl_uString *pProtocol,
remote_InstanceProvider *);
const sal_Int32 REMOTE_CONTEXT_CREATE = 1;
const sal_Int32 REMOTE_CONTEXT_DESTROY = 2;
typedef void ( SAL_CALL * remote_contextListenerFunc ) (
void *pThis,
sal_Int32 nRemoteContextMode,
rtl_uString *sName,
rtl_uString *sDescription
);
/** Registers a listener at the context administration, which allows to keep
track of existing remote connections.
@param pObject object which is handed to the listener function, when called.
*/
extern "C" void SAL_CALL
remote_addContextListener( remote_contextListenerFunc listener, void *pObject );
/** Removes a listener from the context administration.
*/
extern "C" void SAL_CALL
remote_removeContextListener( remote_contextListenerFunc listener , void *pObject );
/** Allows to retrieve all existing context strings.
@param pnStringCount out parameter. Contains the number of rtl_uStrings in the array
@param memAlloc a memory allocation function for the array of pointers to rtl_uStrings
@return array of rtl strings. The caller must call release on all rtl_uString s and must free
the pointer array.
*/
extern "C" rtl_uString ** SAL_CALL
remote_getContextList(
sal_Int32 *pnStringCount,
void * ( SAL_CALL * memAlloc ) ( sal_Size nBytesToAlloc ) );
struct remote_BridgeImpl;
/** The context structure for a remote bridge.
@see uno_getEnvironment()
*/
struct remote_Context
{
struct uno_Context aBase;
/**
These methods are implemented by context administration
*/
void ( SAL_CALL * addDisposingListener ) ( remote_Context *,
remote_DisposingListener * );
void ( SAL_CALL * removeDisposingListener ) ( remote_Context *,
remote_DisposingListener * );
/**
will be called by the environment when it gets disposed
*/
void ( SAL_CALL * dispose ) ( remote_Context * );
/** The method is set by the remote-environment during environment initialization.
@see remote_getInstanceFunc
*/
remote_getInstanceFunc getRemoteInstance;
/**
The protocol, that the environment uses for communicating with the remote process.
The format of the protocol string is : "protocolname,para1=para1value,..."
The parameters are protocol dependend
*/
rtl_uString *m_pProtocol;
/**
It may be the same as m_pName.
Livetime is handled by the context administration.
*/
rtl_uString *m_pDescription;
/**
The name of this context at context administration.
A string, that uniquely describes this environment.
Livetime is handled by the context administration.
*/
rtl_uString *m_pName;
/** The instance-provider, which is used to look up unknown object identifiers.
Is usually called on server side, when the first client request comes in.
Maybe 0. Livetime is handled by the context administration.
*/
remote_InstanceProvider *m_pInstanceProvider;
/**
The connection of this context.
Livetime is handled by the context administration.
*/
remote_Connection *m_pConnection;
/**
Here arbitrary data may be stored. It may be used by a connection
service to store environment specific data. The bridge does not
use it.
*/
void *m_pAdditionalInformation;
/**
here the bridge stores its private per environment data.
*/
struct remote_BridgeImpl *m_pBridgeImpl;
};
#endif

View File

@@ -1,57 +0,0 @@
/*************************************************************************
*
* 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_COUNTER_H_
#define _BRIDGES_REMOTE_COUNTER_H_
#include <stdio.h>
#if OSL_DEBUG_LEVEL > 1
struct MyCounter
{
MyCounter( sal_Char const *pName ) :
m_nCounter( 0 ),
m_pName ( pName )
{
}
~MyCounter()
{
if( m_nCounter ) {
printf(
"%s : %ld left\n", m_pName,
sal::static_int_cast< long >(m_nCounter) );
}
}
void acquire()
{ m_nCounter ++; }
void release()
{ m_nCounter --; }
sal_Int32 m_nCounter;
sal_Char const *m_pName;
};
#endif
#endif

View File

@@ -1,68 +0,0 @@
/*************************************************************************
*
* 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 <bridges/remote/bridgeimpl.hxx>
typedef void ( SAL_CALL * ReleaseRemoteCallbackFunc ) (
remote_Interface *ppRemoteI,
rtl_uString *pOid,
typelib_TypeDescriptionReference *pTypeRef,
uno_Environment *pEnvRemote
);
typedef void ( SAL_CALL * remote_createStubFunc ) (
remote_Interface **ppRemoteI,
rtl_uString *pOid ,
typelib_TypeDescriptionReference *pTypeRef,
uno_Environment *pEnvRemote,
ReleaseRemoteCallbackFunc callback
);
namespace bridges_remote
{
/** @param callback If the bridge implementation wants to handle the remote release call,
it can do it giving this callback. If callback == 0, the releaseRemote
method of the stub is called.
*/
void SAL_CALL remote_createStub (
remote_Interface **ppRemoteI,
rtl_uString *pOid ,
typelib_TypeDescriptionReference *pType,
uno_Environment *pEnvRemote,
ReleaseRemoteCallbackFunc callback );
void SAL_CALL remote_retrieveOidFromProxy(
remote_Interface *pRemtoeI,
rtl_uString **ppOid );
void SAL_CALL remote_sendQueryInterface(
uno_Environment *pEnvRemote,
remote_Interface **ppRemoteI,
rtl_uString *pOid ,
typelib_TypeDescriptionReference *pType,
uno_Any **ppException
);
}

View File

@@ -1,69 +0,0 @@
/*************************************************************************
*
* 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_MAPPING_HXX_
#define _BRIDGES_REMOTE_MAPPING_HXX_
#include <osl/interlck.h>
#include <rtl/ustring.hxx>
#include <typelib/typedescription.h>
#include <bridges/remote/remote.h>
typedef struct _uno_Environment uno_Environment;
namespace bridges_remote
{
extern "C" typedef void SAL_CALL RemoteToUno(
uno_Mapping *pMapping, void **ppOut, void *pInterface,
typelib_InterfaceTypeDescription *pInterfaceTypeDescr );
RemoteToUno remoteToUno;
extern "C" typedef void SAL_CALL UnoToRemote(
uno_Mapping *pMapping, void **ppOut, void *pInterface,
typelib_InterfaceTypeDescription *pInterfaceTypeDescr );
UnoToRemote unoToRemote;
extern "C" typedef void SAL_CALL FreeRemoteMapping(uno_Mapping * mapping);
FreeRemoteMapping freeRemoteMapping;
class RemoteMapping :
public remote_Mapping
{
public:
RemoteMapping( uno_Environment *pEnvUno ,
uno_Environment *pEnvRemote,
uno_MapInterfaceFunc func ,
const ::rtl::OUString sPurpose);
~RemoteMapping();
oslInterlockedCount m_nRef;
::rtl::OUString m_sPurpose;
};
}
#endif

View File

@@ -1,91 +0,0 @@
/*************************************************************************
*
* 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/interlck.h>
#include <uno/environment.h>
#include <uno/dispatcher.h>
#include <uno/mapping.hxx>
#include <bridges/remote/remote.h>
namespace bridges_remote {
extern "C" typedef void SAL_CALL FreeRemote2UnoProxy(
uno_ExtEnvironment * environment, void * proxy);
FreeRemote2UnoProxy freeRemote2UnoProxy;
// private:
extern "C" typedef void SAL_CALL AcquireRemote2UnoProxy(uno_Interface *);
AcquireRemote2UnoProxy acquireRemote2UnoProxy;
// private:
extern "C" typedef void SAL_CALL ReleaseRemote2UnoProxy(uno_Interface *);
ReleaseRemote2UnoProxy releaseRemote2UnoProxy;
// private:
extern "C" typedef void SAL_CALL DispatchRemote2UnoProxy(
uno_Interface *, typelib_TypeDescription const *, void *, void **,
uno_Any **);
DispatchRemote2UnoProxy dispatchRemote2UnoProxy;
extern "C" void SAL_CALL remote_release( void * );
class Remote2UnoProxy :
public uno_Interface
{
public:
Remote2UnoProxy(
remote_Interface *pRemoteI,
rtl_uString *pOid,
typelib_InterfaceTypeDescription *pType ,
uno_Environment *pEnvUno,
uno_Environment *pEnvRemote
);
~Remote2UnoProxy();
private:
::rtl::OUString m_sOid;
typelib_InterfaceTypeDescription *m_pType;
remote_Interface *m_pRemoteI;
uno_Environment *m_pEnvUno;
uno_Environment *m_pEnvRemote;
::com::sun::star::uno::Mapping m_mapRemote2Uno;
::com::sun::star::uno::Mapping m_mapUno2Remote;
oslInterlockedCount m_nRef;
friend void SAL_CALL acquireRemote2UnoProxy(uno_Interface *);
friend void SAL_CALL releaseRemote2UnoProxy(uno_Interface *);
friend void SAL_CALL dispatchRemote2UnoProxy(
uno_Interface *, typelib_TypeDescription const *, void *, void **,
uno_Any **);
};
}

View File

@@ -1,93 +0,0 @@
/*************************************************************************
*
* 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_REMOTE_H
#define _BRIDGES_REMOTE_REMOTE_H
#include <uno/mapping.h>
#include <uno/any2.h>
#include <typelib/typedescription.h>
#include <uno/environment.h>
#define CORBA_STRING8_NAME "com.sun.star.corba.CorbaString8"
#define CORBA_STRING8_NAME_LENGTH (sizeof(CORBA_STRING8_NAME)-1)
#define CORBA_UNION_NAME "com.sun.star.corba.CorbaUnion"
#define CORBA_UNION_NAME_LENGTH (sizeof(CORBA_UNION_NAME)-1)
#define REMOTE_MARSHALED_MSGHDR_SIZE 12
#define REMOTE_RELEASE_METHOD_INDEX 2
#define REMOTE_RELEASE_METHOD_NAME "release"
#define CURRENT_IIOP_PROTOCOL_MAJOR 1
#define CURRENT_IIOP_PROTOCOL_MINOR 2
extern "C" {
struct remote_Interface;
/** @internal
*/
typedef void (SAL_CALL * remote_DispatchMethod)(
remote_Interface * pRemoteI, typelib_TypeDescription const * pMemberType,
void * pReturn, void * pArgs[], uno_Any ** ppException );
/**
@internal
*/
typedef void ( SAL_CALL * requestClientSideDispatcher ) (
uno_Environment *pEnvRemote,
typelib_TypeDescription const * pMemberType,
rtl_uString *pOid,
typelib_InterfaceTypeDescription *pInterfaceType,
void *pReturn,
void *ppArgs[],
uno_Any **ppException );
/** The base class of an UNO interface in a remote environment.
*/
struct remote_Interface
{
void (SAL_CALL * acquire)( remote_Interface * pInterface );
void (SAL_CALL * release)( remote_Interface * pInterface );
remote_DispatchMethod pDispatcher;
};
/** The mapping between an binary-c-uno and a remote environment.
@internal
*/
struct remote_Mapping
{
uno_Mapping aBase;
uno_Environment *pEnvRemote;
uno_Environment *pEnvUno;
};
}
#endif

View File

@@ -1,73 +0,0 @@
/*************************************************************************
*
* 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_REMOTE_HXX_
#define _BRIDGES_REMOTE_REMOTE_HXX_
#include <list>
#include <osl/mutex.hxx>
#include <osl/conditn.h>
#include <osl/interlck.h>
#include <uno/environment.h>
#include <bridges/remote/remote.h>
#include <bridges/remote/connection.h>
#include <com/sun/star/uno/Sequence.hxx>
namespace bridges_remote {
extern "C" typedef void SAL_CALL AcquireRemote2RemoteStub(
remote_Interface * pThis);
AcquireRemote2RemoteStub acquireRemote2RemoteStub;
extern "C" typedef void SAL_CALL FreeRemote2RemoteStub(
uno_ExtEnvironment * environment, void * stub);
FreeRemote2RemoteStub freeRemote2RemoteStub;
class Remote2RemoteStub :
public remote_Interface
{
public:
Remote2RemoteStub(rtl_uString *pOid,
typelib_InterfaceTypeDescription *pType,
uno_Environment *pEnvRemote,
requestClientSideDispatcher dispatch );
~Remote2RemoteStub();
void releaseRemote();
public:
::rtl::OUString m_sOid;
typelib_InterfaceTypeDescription *m_pType;
oslInterlockedCount m_nRef;
uno_Environment *m_pEnvRemote;
requestClientSideDispatcher m_dispatch;
oslInterlockedCount m_nReleaseRemote;
};
}
#endif

View File

@@ -1,64 +0,0 @@
/*************************************************************************
*
* 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 <bridges/remote/remote.hxx>
#include <uno/dispatcher.h>
#include <uno/mapping.hxx>
namespace bridges_remote {
extern "C" typedef void SAL_CALL AcquireUno2RemoteStub( remote_Interface *pThis );
AcquireUno2RemoteStub acquireUno2RemoteStub;
extern "C" typedef void SAL_CALL FreeUno2RemoteStub(
uno_ExtEnvironment * environment, void * stub);
FreeUno2RemoteStub freeUno2RemoteStub;
class Uno2RemoteStub :
public remote_Interface
{
public:
Uno2RemoteStub( uno_Interface *pUnoI,
rtl_uString *pOid,
typelib_InterfaceTypeDescription *pType,
uno_Environment *pEnvUno,
uno_Environment *pEnvRemote );
~Uno2RemoteStub();
public:
::rtl::OUString m_sOid;
typelib_InterfaceTypeDescription *m_pType;
uno_Interface *m_pUnoI;
oslInterlockedCount m_nRef;
uno_Environment *m_pEnvUno;
uno_Environment *m_pEnvRemote;
::com::sun::star::uno::Mapping m_mapRemote2Uno;
::com::sun::star::uno::Mapping m_mapUno2Remote;
};
}

View File

@@ -38,8 +38,6 @@
#include "com/sun/star/bridge/XBridge.hpp"
#include "com/sun/star/bridge/XBridgeFactory.hpp"
#include "com/sun/star/bridge/XInstanceProvider.hpp"
#include "com/sun/star/bridge/XProtocolProperties.hdl"
#include "com/sun/star/bridge/XProtocolProperties.hpp"
#include "com/sun/star/bridge/XUnoUrlResolver.hpp"
#include "com/sun/star/connection/ConnectionSetupException.hpp"
#include "com/sun/star/connection/NoConnectException.hpp"
@@ -49,8 +47,6 @@
#include "com/sun/star/frame/XComponentLoader.hpp"
#include "com/sun/star/io/XInputStream.hpp"
#include "com/sun/star/io/XOutputStream.hpp"
#include "com/sun/star/lang/DisposedException.hdl"
#include "com/sun/star/lang/DisposedException.hpp"
#include "com/sun/star/lang/IllegalArgumentException.hpp"
#include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
#include "com/sun/star/lang/XComponent.hpp"

View File

@@ -2,9 +2,6 @@ br bridges : cppuhelper jurt jvmaccess salhelper NULL
br bridges usr1 - all br_mkout NULL
br bridges\inc nmake - all br_inc NULL
br bridges\unotypes nmake - all br_unotypes NULL
br bridges\source\remote\static nmake - all br_rem_static br_unotypes br_inc NULL
br bridges\source\remote\urp nmake - all br_rem_urp br_rem_static br_inc NULL
br bridges\source\remote\context nmake - all br_rcon br_unotypes br_inc NULL
br bridges\source\cpp_uno\mingw_intel nmake - w br_gcc3i br_cppuno_shared br_unotypes br_inc NULL
br bridges\source\cpp_uno\msvc_win32_intel nmake - w br_msci br_cppuno_shared br_unotypes br_inc NULL
br bridges\source\cpp_uno\gcc3_linux_intel nmake - u br_gcc3li br_cppuno_shared br_unotypes br_inc NULL

View File

@@ -1,16 +1,3 @@
mkdir: %_DEST%\inc%_EXT%\bridges
mkdir: %_DEST%\inc%_EXT%\bridges\remote
..\inc\bridges\remote\connection.h %_DEST%\inc%_EXT%\bridges\remote\connection.h
..\inc\bridges\remote\context.h %_DEST%\inc%_EXT%\bridges\remote\context.h
..\inc\bridges\remote\remote.h %_DEST%\inc%_EXT%\bridges\remote\remote.h
..\%__SRC%\lib\irmcxt* %_DEST%\lib%_EXT%\*
..\%__SRC%\lib\librmcxt.*.* %_DEST%\lib%_EXT%\*
..\%__SRC%\bin\rmcxt*.dll %_DEST%\bin%_EXT%\*
..\%__SRC%\lib\liburp_uno* %_DEST%\lib%_EXT%\liburp_uno*
..\%__SRC%\bin\urp_uno* %_DEST%\bin%_EXT%\urp_uno*
..\%__SRC%\lib\libjava_uno* %_DEST%\lib%_EXT%\libjava_uno*
..\%__SRC%\bin\java_uno* %_DEST%\bin%_EXT%\java_uno*
..\%__SRC%\class\java_uno*.jar %_DEST%\bin%_EXT%\java_uno*.jar
@@ -21,8 +8,3 @@ mkdir: %_DEST%\inc%_EXT%\bridges\remote
..\%__SRC%\lib\libgcc3_uno.* %_DEST%\lib%_EXT%\libgcc3_uno.*
..\%__SRC%\bin\gcc3_uno.* %_DEST%\bin%_EXT%\gcc3_uno.*
..\%__SRC%\lib\libsunpro5_uno.* %_DEST%\lib%_EXT%\libsunpro5_uno.*
..\%__SRC%\lib\rmcxt3.lib %_DEST%\lib%_EXT%\rmcxt.lib
linklib: librmcxt.*.*

View File

@@ -1,484 +0,0 @@
/*************************************************************************
*
* 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 );
}

View File

@@ -1,5 +0,0 @@
remote_getContext
remote_createContext
remote_getContextList
remote_removeContextListener
remote_addContextListener

View File

@@ -1,10 +0,0 @@
UDK_3_0_0 {
global:
remote_getContext;
remote_createContext;
remote_getContextList;
remote_removeContextListener;
remote_addContextListener;
local:
*;
};

View File

@@ -1,88 +0,0 @@
/*************************************************************************
*
* 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
};
};
};
};
};

View File

@@ -1,209 +0,0 @@
/*************************************************************************
*
* 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::createFromAscii("::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 );
}
}
}

View File

@@ -1,61 +0,0 @@
#*************************************************************************
#
# 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

View File

@@ -1,218 +0,0 @@
/*************************************************************************
*
* 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 );
}
}

View File

@@ -1,338 +0,0 @@
/*************************************************************************
*
* 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

View File

@@ -1,161 +0,0 @@
/*************************************************************************
*
* 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

View File

@@ -1,96 +0,0 @@
/*************************************************************************
*
* 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;
}
}

View File

@@ -1,89 +0,0 @@
/*************************************************************************
*
* 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

View File

@@ -1,336 +0,0 @@
/*************************************************************************
*
* 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

View File

@@ -1,78 +0,0 @@
#*************************************************************************
#
# 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

View File

@@ -1,250 +0,0 @@
/*************************************************************************
*
* 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::createFromAscii( ") " );
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::createFromAscii( ") " );
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;
}
}

View File

@@ -1,133 +0,0 @@
/*************************************************************************
*
* 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>
#ifndef _UNO_THREADPOOL_H_
#include <uno/threadpool.h>
#endif
#include <bridges/remote/bridgeimpl.hxx>
#ifndef _URP_CACHE_HXX_
#include "urp_cache.hxx"
#endif
#include "urp_marshal_decl.hxx"
#ifndef _URP_REPLYCONTAINER_HXX_
#include "urp_replycontainer.hxx"
#endif
#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

View File

@@ -1,57 +0,0 @@
/*************************************************************************
*
* 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;
};
}

View File

@@ -1,160 +0,0 @@
/*************************************************************************
*
* 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;
}
}

View File

@@ -1,116 +0,0 @@
/*************************************************************************
*
* 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();
}
}
}

View File

@@ -1,78 +0,0 @@
/*************************************************************************
*
* 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
);
}

View File

@@ -1,551 +0,0 @@
/*************************************************************************
*
* 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 = OUString::createFromAscii( UNO_LB_UNO );
::rtl::OUString sRemote = OUString::createFromAscii( "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 );
}
}

View File

@@ -1,939 +0,0 @@
/*************************************************************************
*
* 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;
}
}

View File

@@ -1,379 +0,0 @@
/*************************************************************************
*
* 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_bExceptionOccured( false )
, 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

View File

@@ -1,147 +0,0 @@
/*************************************************************************
*
* 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
}

View File

@@ -1,50 +0,0 @@
/*************************************************************************
*
* 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
}

View File

@@ -1,235 +0,0 @@
/*************************************************************************
*
* 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

View File

@@ -1,343 +0,0 @@
/*************************************************************************
*
* 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

View File

@@ -1,106 +0,0 @@
/*************************************************************************
*
* 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

View File

@@ -1,93 +0,0 @@
/*************************************************************************
*
* 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_
#ifndef _BRIDGES_REMOTE_REMOTE_H_
#include <bridges/remote/remote.h>
#endif
#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

View File

@@ -1,793 +0,0 @@
/*************************************************************************
*
* 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, *(Sequence< sal_Int8 > *)&(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::createFromAscii( "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 );
}
}

View File

@@ -1,108 +0,0 @@
/*************************************************************************
*
* 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>
#ifndef _OSL_CONDITN_H_
#include <osl/conditn.h>
#endif
#include <rtl/string.hxx>
#include <uno/sequence2.h>
#ifndef _BRIDGES_REMOTE_REMOTE_H_
#include <bridges/remote/remote.h>
#endif
#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 );
};
}

View File

@@ -1,832 +0,0 @@
/*************************************************************************
*
* 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;
}
}
}

View File

@@ -1,78 +0,0 @@
/*************************************************************************
*
* 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;
};
}

View File

@@ -1,75 +0,0 @@
/*************************************************************************
*
* 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;
};
}

View File

@@ -1,48 +0,0 @@
/*************************************************************************
*
* 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();
}
}

View File

@@ -1,59 +0,0 @@
/*************************************************************************
*
* 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

View File

@@ -1,707 +0,0 @@
/*************************************************************************
*
* 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;
}
}

View File

@@ -1,280 +0,0 @@
/*************************************************************************
*
* 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>
#ifndef _BRIDGES_REMOTE_HELPER_HXX_
#include <bridges/remote/helper.hxx>
#endif
#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

View File

@@ -1,269 +0,0 @@
/*************************************************************************
*
* 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();
}
}
}
}
}

View File

@@ -1,83 +0,0 @@
/*************************************************************************
*
* 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;
};
}

View File

@@ -41,20 +41,7 @@ UNOUCRRDB=$(SOLARBINDIR)$/udkapi.rdb
UNOUCROUT=$(OUT)$/inc
UNOTYPES = \
com.sun.star.bridge.XProtocolProperties \
com.sun.star.corba.giop.MessageHeader_1_2 \
com.sun.star.corba.giop.MsgType_1_1 \
com.sun.star.corba.iop.ServiceContextList \
com.sun.star.corba.iop.ProfileIdGroup \
com.sun.star.corba.iiop.ProfileBody_1_1 \
com.sun.star.corba.LogicalThreadID \
com.sun.star.corba.iop.ServiceIdGroup \
com.sun.star.corba.giop.ReplyHeader_1_2 \
com.sun.star.corba.giop.RequestHeader_1_2 \
com.sun.star.corba.TCKind \
com.sun.star.corba.ObjectKey \
com.sun.star.uno.XInterface \
com.sun.star.lang.DisposedException \
com.sun.star.uno.TypeClass
# --- Targets ------------------------------------------------------

View File

@@ -275,23 +275,14 @@ void createInstance(
OUString( RTL_CONSTASCII_USTRINGPARAM(
"com.sun.star.comp.io.Connector") ),
xSF, Reference< XRegistryKey >() ) ) );
// iiop bridge
xSet->insert( makeAny( loadSharedLibComponentFactory(
OUString( RTL_CONSTASCII_USTRINGPARAM(
"remotebridge.uno" SAL_DLLEXTENSION) ),
OUString(),
OUString( RTL_CONSTASCII_USTRINGPARAM(
"com.sun.star.comp.remotebridges."
"Bridge.various") ),
xSF, Reference< XRegistryKey >() ) ) );
// bridge factory
xSet->insert( makeAny( loadSharedLibComponentFactory(
OUString( RTL_CONSTASCII_USTRINGPARAM(
"bridgefac.uno" SAL_DLLEXTENSION) ),
"binaryurp.uno" SAL_DLLEXTENSION) ),
OUString(),
OUString( RTL_CONSTASCII_USTRINGPARAM(
"com.sun.star.comp.remotebridges."
"BridgeFactory") ),
OUString(
RTL_CONSTASCII_USTRINGPARAM(
"com.sun.star.comp.bridge.BridgeFactory") ),
xSF, Reference< XRegistryKey >() ) ) );
}
s_bSet = sal_True;

View File

@@ -1,6 +1,2 @@
rb remotebridges : LIBXSLT:libxslt bridges rdbmaker NULL
rb remotebridges usr1 - all rb_mkout NULL
rb remotebridges\source\bridge nmake - all rb_iiop NULL
rb remotebridges\source\factory nmake - all rb_factory NULL
rb remotebridges : LIBXSLT:libxslt cppu cppuhelper offuh rdbmaker sal NULL
rb remotebridges\source\unourl_resolver nmake - all rb_urlresolv NULL
rb remotebridges\source\dynamicloader nmake - all rb_dynloader NULL

20
remotebridges/prj/d.lst Normal file → Executable file
View File

@@ -1,20 +1,4 @@
..\%__SRC%\bin\bridgefa*.dll %_DEST%\bin%_EXT%\bridgefa*.dll
..\%__SRC%\bin\remotebr*.dll %_DEST%\bin%_EXT%\remotebr*.dll
..\%__SRC%\bin\dynamicl*.dll %_DEST%\bin%_EXT%\dynamicl*.dll
..\%__SRC%\bin\uuresolv*.dll %_DEST%\bin%_EXT%\uuresolv*.dll
..\%__SRC%\bin\brdgfctr.rdb %_DEST%\rdb%_EXT%\brdgfctr.rdb
..\%__SRC%\bin\remotebridge.rdb %_DEST%\rdb%_EXT%\remotebridge.rdb
..\%__SRC%\bin\dynamicloader.rdb %_DEST%\rdb%_EXT%\dynamicloader.rdb
..\%__SRC%\bin\uuresolver.rdb %_DEST%\rdb%_EXT%\uuresolver.rdb
..\source\factory\brdgfctr.xml %_DEST%\xml%_EXT%\bridgefac.uno.xml
..\source\bridge\remotebridge.xml %_DEST%\xml%_EXT%\remotebridge.uno.xml
..\source\dynamicloader\dynamicloader.xml %_DEST%\xml%_EXT%\dynamicloader.uno.xml
..\source\unourl_resolver\uuresolver.xml %_DEST%\xml%_EXT%\uuresolver.uno.xml
..\%__SRC%\lib\bridgefac.uno.so %_DEST%\lib%_EXT%\bridgefac.uno.so
..\%__SRC%\lib\remotebridge.uno.so %_DEST%\lib%_EXT%\remotebridge.uno.so
..\%__SRC%\lib\dynamicloader.uno.so %_DEST%\lib%_EXT%\dynamicloader.uno.so
..\%__SRC%\bin\uuresolver.uno.dll %_DEST%\bin%_EXT%\uuresolver.uno.dll
..\%__SRC%\lib\uuresolver.uno.dylib %_DEST%\lib%_EXT%\uuresolver.uno.dylib
..\%__SRC%\lib\uuresolver.uno.so %_DEST%\lib%_EXT%\uuresolver.uno.so
..\%__SRC%\lib\*.dylib %_DEST%\lib%_EXT%\*
..\%__SRC%\misc\bridgefac.component %_DEST%\xml%_EXT%\bridgefac.component
..\%__SRC%\misc\remotebridge.component %_DEST%\xml%_EXT%\remotebridge.component
..\%__SRC%\misc\uuresolver.component %_DEST%\xml%_EXT%\uuresolver.component

View File

@@ -1,139 +0,0 @@
/*************************************************************************
*
* 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 "bridge_connection.hxx"
#include "remote_bridge.hxx"
#include <rtl/byteseq.hxx>
#include <string.h>
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::connection;
namespace remotebridges_bridge
{
OConnectionWrapper::OConnectionWrapper( const Reference < XConnection > &r ) :
m_r( r ),
m_nRef( 0 )
{
g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
acquire = thisAcquire;
release = thisRelease;
read = thisRead;
write = thisWrite;
flush = thisFlush;
close = thisClose;
}
OConnectionWrapper::~OConnectionWrapper()
{
g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
}
void OConnectionWrapper::thisAcquire( remote_Connection *p)
{
OConnectionWrapper * m = ( OConnectionWrapper * ) p;
osl_incrementInterlockedCount( &(m->m_nRef ) );
}
void OConnectionWrapper::thisRelease( remote_Connection * p)
{
OConnectionWrapper * m = ( OConnectionWrapper * ) p;
if( ! osl_decrementInterlockedCount( &( m->m_nRef ) ) )
{
delete m;
}
}
sal_Int32 OConnectionWrapper::thisRead( remote_Connection *p , sal_Int8 *pDest , sal_Int32 nSize )
{
// guard the C-Code
OConnectionWrapper * m = ( OConnectionWrapper * ) p;
try
{
// TODO possible optimization : give
Sequence<sal_Int8> seq = toUnoSequence( ::rtl::ByteSequence(nSize, ::rtl::BYTESEQ_NODEFAULT) );
sal_Int32 nRead = m->m_r->read( seq , nSize );
memcpy( pDest , seq.getConstArray() , nRead );
return nRead;
}
catch ( Exception & )
{
return 0;
}
catch (::std::bad_alloc &)
{
return 0;
}
}
sal_Int32 OConnectionWrapper::thisWrite( remote_Connection *p ,
const sal_Int8 *pSource ,
sal_Int32 nSize )
{
// guard the C-Code
OConnectionWrapper * m = ( OConnectionWrapper * ) p;
try
{
Sequence< sal_Int8 > seq( pSource , nSize );
m->m_r->write( seq );
return nSize;
}
catch ( Exception & )
{
return 0;
}
}
void OConnectionWrapper::thisFlush( remote_Connection *p )
{
// guard the C-Code
try
{
OConnectionWrapper * m = ( OConnectionWrapper * ) p;
m->m_r->flush();
}
catch ( Exception & )
{
}
}
void OConnectionWrapper::thisClose( remote_Connection * p)
{
// guard the C-Code
try
{
OConnectionWrapper * m = ( OConnectionWrapper * ) p;
m->m_r->close();
}
catch( Exception & )
{
}
}
}

View File

@@ -1,57 +0,0 @@
/*************************************************************************
*
* 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/interlck.h>
#include <bridges/remote/connection.h>
#include <com/sun/star/connection/XConnection.hpp>
namespace remotebridges_bridge
{
class OConnectionWrapper :
public remote_Connection
{
public:
OConnectionWrapper( const ::com::sun::star::uno::Reference <
::com::sun::star::connection::XConnection > & );
~OConnectionWrapper();
static void SAL_CALL thisAcquire( remote_Connection *);
static void SAL_CALL thisRelease( remote_Connection *);
static sal_Int32 SAL_CALL thisRead( remote_Connection * , sal_Int8 *pDest , sal_Int32 nSize );
static sal_Int32 SAL_CALL thisWrite( remote_Connection * ,
const sal_Int8 *pSource ,
sal_Int32 nSize );
static void SAL_CALL thisFlush( remote_Connection * );
static void SAL_CALL thisClose( remote_Connection * );
::com::sun::star::uno::Reference < ::com::sun::star::connection::XConnection > m_r;
oslInterlockedCount m_nRef;
};
}

View File

@@ -1,179 +0,0 @@
/*************************************************************************
*
* 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 "remote_bridge.hxx"
#include <osl/diagnose.h>
#include <rtl/ustrbuf.hxx>
#include <uno/mapping.hxx>
#include <uno/environment.h>
#include <bridges/remote/remote.h>
using namespace ::rtl;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::bridge;
namespace remotebridges_bridge
{
OInstanceProviderWrapper::OInstanceProviderWrapper(
const Reference <XInstanceProvider > & rProvider,
ORemoteBridge * pBridgeCallback ) :
m_rProvider( rProvider ),
m_nRef( 0 ),
m_pBridgeCallback( pBridgeCallback )
{
g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
acquire = thisAcquire;
release = thisRelease;
getInstance = thisGetInstance;
}
OInstanceProviderWrapper::~OInstanceProviderWrapper()
{
g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
}
void OInstanceProviderWrapper::thisAcquire( remote_InstanceProvider *p )
{
OInstanceProviderWrapper * m = (OInstanceProviderWrapper *) p;
osl_incrementInterlockedCount( &(m->m_nRef ) );
}
void OInstanceProviderWrapper::thisRelease( remote_InstanceProvider *p )
{
OInstanceProviderWrapper * m = ( OInstanceProviderWrapper *) p;
if( ! osl_decrementInterlockedCount( &(m->m_nRef ) ) )
{
delete m;
}
}
static void convertToRemoteRuntimeException ( uno_Any **ppException,
const ::rtl::OUString &sMessage,
const Reference< XInterface > &rContext,
Mapping &map )
{
uno_type_any_construct( *ppException ,
0 ,
getCppuType( (RuntimeException *)0 ).getTypeLibType() ,
0 );
typelib_CompoundTypeDescription * pCompType = 0 ;
getCppuType( (Exception*)0 ).getDescription( (typelib_TypeDescription **) &pCompType );
if( ! ((typelib_TypeDescription *)pCompType)->bComplete )
{
typelib_typedescription_complete( (typelib_TypeDescription**) &pCompType );
}
char *pValue = (char*) (*ppException)->pData;
rtl_uString_assign( (rtl_uString ** ) pValue , sMessage.pData );
*((remote_Interface**) pValue+pCompType->pMemberOffsets[1]) =
(remote_Interface*) map.mapInterface(
rContext.get(), getCppuType( &rContext) );
typelib_typedescription_release( (typelib_TypeDescription *) pCompType );
}
void OInstanceProviderWrapper::thisGetInstance(
remote_InstanceProvider * pProvider ,
uno_Environment *pEnvRemote,
remote_Interface **ppRemoteI,
rtl_uString *pInstanceName,
typelib_InterfaceTypeDescription *pType,
uno_Any **ppException
)
{
OInstanceProviderWrapper * m = (OInstanceProviderWrapper *)pProvider;
OSL_ASSERT( ppRemoteI );
if( *ppRemoteI )
{
(*ppRemoteI)->release( *ppRemoteI );
*ppRemoteI = 0;
}
OUString sCppuName( RTL_CONSTASCII_USTRINGPARAM( CPPU_CURRENT_LANGUAGE_BINDING_NAME ) );
uno_Environment *pEnvThis = 0;
uno_getEnvironment( &pEnvThis ,
sCppuName.pData ,
0 );
Mapping map( pEnvThis , pEnvRemote );
pEnvThis->release( pEnvThis );
if( OUString( pType->aBase.pTypeName ) ==
getCppuType( (Reference<XInterface>*)0).getTypeName() )
{
try
{
Reference< XInterface > r = m->m_rProvider->getInstance(
OUString( pInstanceName ) );
*ppRemoteI = (remote_Interface*) map.mapInterface (
r.get(),
getCppuType( (Reference< XInterface > *) 0 )
);
if( *ppRemoteI && m->m_pBridgeCallback )
{
m->m_pBridgeCallback->objectMappedSuccesfully();
m->m_pBridgeCallback = 0;
}
*ppException = 0;
}
catch( ::com::sun::star::container::NoSuchElementException &e )
{
// NoSuchElementException not specified, so convert it to a runtime exception
convertToRemoteRuntimeException(
ppException , e.Message.pData , e.Context.get(), map );
}
catch( ::com::sun::star::uno::RuntimeException &e )
{
convertToRemoteRuntimeException(
ppException , e.Message.pData , e.Context.get(), map );
}
}
else
{
OUStringBuffer msg;
msg.appendAscii(
RTL_CONSTASCII_STRINGPARAM(
"getInstance expected XInterface but got "));
msg.append(pType->aBase.pTypeName);
convertToRemoteRuntimeException(
ppException, msg.getStr(), Reference< XInterface >(), map);
}
}
}

View File

@@ -1,72 +0,0 @@
#*************************************************************************
#
# 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=remotebridges
TARGET = remotebridge.uno
ENABLE_EXCEPTIONS=TRUE
COMP1TYPELIST = remotebridge
# --- Settings -----------------------------------------------------
.INCLUDE : settings.mk
.IF "$(L10N_framework)"==""
DLLPRE =
# ------------------------------------------------------------------
SLOFILES= \
$(SLO)$/remote_bridge.obj \
$(SLO)$/bridge_connection.obj\
$(SLO)$/bridge_provider.obj
SHL1TARGET= $(TARGET)
SHL1VERSIONMAP = $(SOLARENV)/src/unloadablecomponent.map
SHL1STDLIBS= \
$(SALLIB) \
$(CPPULIB) \
$(CPPUHELPERLIB) \
$(RMCXTLIB)
SHL1DEPN=
SHL1IMPLIB= i$(TARGET)
SHL1LIBS= $(SLB)$/$(TARGET).lib
SHL1DEF= $(MISC)$/$(SHL1TARGET).def
SHL1RPATH= URELIB
DEF1NAME= $(SHL1TARGET)
.ENDIF # L10N_framework
# --- Targets ------------------------------------------------------
.INCLUDE : target.mk
ALLTAR : $(MISC)/remotebridge.component
$(MISC)/remotebridge.component .ERRREMOVE : \
$(SOLARENV)/bin/createcomponent.xslt remotebridge.component
$(XSLTPROC) --nonet --stringparam uri \
'$(COMPONENTPREFIX_URE_NATIVE)$(SHL1TARGETN:f)' -o $@ \
$(SOLARENV)/bin/createcomponent.xslt remotebridge.component

View File

@@ -1,470 +0,0 @@
/*************************************************************************
*
* 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 "remote_bridge.hxx"
#include "bridge_connection.hxx"
#include <cppuhelper/implementationentry.hxx>
#include <com/sun/star/lang/IllegalArgumentException.hpp>
#include <com/sun/star/bridge/BridgeExistsException.hpp>
#define IMPLEMENTATION_NAME "com.sun.star.comp.remotebridges.Bridge.various"
using namespace ::rtl;
using namespace ::cppu;
using namespace ::osl;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::bridge;
using namespace ::com::sun::star::registry;
using namespace ::com::sun::star::connection;
namespace remotebridges_bridge
{
rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT;
ORemoteBridge::ORemoteBridge() :
OComponentHelper( m_mutex ),
m_pContext( 0 ),
m_pEnvRemote(0 )
{
g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
remote_DisposingListener::acquire = thisAcquire;
remote_DisposingListener::release = thisRelease;
remote_DisposingListener::disposing = thisDisposing;
}
ORemoteBridge::~ORemoteBridge()
{
if( m_pContext )
{
m_pContext->aBase.release( (uno_Context *) m_pContext );
}
if( m_pEnvRemote )
{
m_pEnvRemote->release( m_pEnvRemote );
}
g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
}
void ORemoteBridge::objectMappedSuccesfully()
{
MutexGuard guard( m_mutex );
if( m_pEnvRemote )
{
m_pEnvRemote->release( m_pEnvRemote );
m_pEnvRemote = 0;
}
}
Any ORemoteBridge::queryInterface( const Type & aType ) throw(RuntimeException)
{
Any a = ::cppu::queryInterface(
aType ,
SAL_STATIC_CAST( XInitialization * , this ) ,
SAL_STATIC_CAST( XBridge * , this ),
SAL_STATIC_CAST( XTypeProvider * , this ) );
if( a.hasValue() )
{
return a;
}
return OComponentHelper::queryInterface( aType );
}
void ORemoteBridge::initialize( const Sequence< Any >& aArguments )
throw( Exception, RuntimeException)
{
MutexGuard guard( m_mutex );
if( 4 != aArguments.getLength() )
{
throw IllegalArgumentException( rtl::OUString::createFromAscii("wrong number of arguments") ,
Reference< XInterface >(),
0 );
}
OUString swName;
OUString swProtocol;
Reference < XConnection > rConnection;
Reference < XInstanceProvider > rProvider;
aArguments.getConstArray()[0] >>= swName;
aArguments.getConstArray()[1] >>= swProtocol;
aArguments.getConstArray()[2] >>= rConnection;
aArguments.getConstArray()[3] >>= rProvider;
if( ! rConnection.is() )
{
throw IllegalArgumentException( rtl::OUString::createFromAscii("connection is missing") ,
Reference < XInterface > (),
2 );
}
remote_Connection *pConnection = new OConnectionWrapper( rConnection );
remote_InstanceProvider *pProvider = 0;
if( rProvider.is( ))
{
pProvider = new OInstanceProviderWrapper( rProvider , this );
}
OUString sName = swName;
m_sDescription = swProtocol;
m_sDescription += OUString( RTL_CONSTASCII_USTRINGPARAM(":"));
m_sDescription += rConnection->getDescription();
if( 0 == sName.getLength() )
{
sName = m_sDescription;
}
else
{
m_sName = sName;
}
m_pContext = remote_createContext( pConnection,
sName.pData,
m_sDescription.pData,
swProtocol.pData,
pProvider );
if( ! m_pContext )
{
throw BridgeExistsException();
}
m_pContext->addDisposingListener( m_pContext ,
(remote_DisposingListener *) this );
// environment will be released by the first succesfull mapping
OUString sRemoteEnv;
if( swProtocol.indexOf( ',') == -1 )
{
sRemoteEnv = swProtocol;
}
else
{
sRemoteEnv = swProtocol.copy( 0 , swProtocol.indexOf( ',' ) );
}
m_sProtocol = sRemoteEnv;
uno_getEnvironment( &m_pEnvRemote ,
sRemoteEnv.pData ,
m_pContext );
if( ! m_pEnvRemote )
{
m_pContext->removeDisposingListener( m_pContext ,
(remote_DisposingListener*) this );
m_pContext->aBase.release( (uno_Context * ) m_pContext );
m_pContext = 0;
// forgotten exception when specifying the interface
throw RuntimeException( rtl::OUString::createFromAscii("couldn't create uno-remote-environment") ,
Reference < XInterface > () );
}
}
Reference< XInterface > ORemoteBridge::getInstance( const ::rtl::OUString& sInstanceName )
throw(::com::sun::star::uno::RuntimeException)
{
Reference < XInterface > rReturn;
remote_Context *pContext = 0;
{
MutexGuard guard( m_mutex );
if( m_pContext && m_pContext->getRemoteInstance )
{
pContext = m_pContext;
pContext->aBase.acquire( (uno_Context*)pContext );
}
}
if( pContext )
{
// get the appropriate remote environment
uno_Environment *pEnvRemote = 0;
uno_getEnvironment( &pEnvRemote , m_sProtocol.pData , pContext );
if( ! pEnvRemote )
{
pContext->aBase.release( (uno_Context*) pContext );
throw RuntimeException(
OUString( RTL_CONSTASCII_USTRINGPARAM( "RemoteBridge: bridge already disposed" ) ),
Reference< XInterface > () );
}
Type type = getCppuType( (Reference < XInterface > * ) 0 );
remote_Interface *pRemoteI = 0;
uno_Any exception;
uno_Any *pException = &exception;
pContext->getRemoteInstance(
pEnvRemote,
&pRemoteI,
sInstanceName.pData,
type.getTypeLibType(),
&pException );
pContext->aBase.release( (uno_Context*) pContext );
pContext = 0;
uno_Environment *pEnvCpp =0;
OUString sCppuName( RTL_CONSTASCII_USTRINGPARAM( CPPU_CURRENT_LANGUAGE_BINDING_NAME ) );
uno_getEnvironment( &pEnvCpp ,
sCppuName.pData ,
0 );
Mapping map( pEnvRemote , pEnvCpp );
pEnvCpp->release( pEnvCpp );
pEnvRemote->release( pEnvRemote );
if( pException )
{
typelib_CompoundTypeDescription * pCompType = 0 ;
getCppuType( (Exception*)0 ).getDescription( (typelib_TypeDescription **) &pCompType );
if( ! ((typelib_TypeDescription *)pCompType)->bComplete )
{
typelib_typedescription_complete( (typelib_TypeDescription**) &pCompType );
}
XInterface *pXInterface = (XInterface *) map.mapInterface(
*(remote_Interface**) ( ((char*)pException->pData)+pCompType->pMemberOffsets[1] ),
getCppuType( (Reference< XInterface > *)0 ) );
RuntimeException myException(
*((rtl_uString **)pException->pData),
Reference< XInterface > ( pXInterface , SAL_NO_ACQUIRE) );
uno_any_destruct( pException , 0 );
throw myException;
}
else if( pRemoteI )
{
// got an interface !
XInterface * pCppI = ( XInterface * ) map.mapInterface( pRemoteI, type );
rReturn = Reference<XInterface > ( pCppI, SAL_NO_ACQUIRE );
pRemoteI->release( pRemoteI );
objectMappedSuccesfully();
}
}
else
{
throw RuntimeException(
OUString( RTL_CONSTASCII_USTRINGPARAM( "RemoteBridge: bridge already disposed." ) ),
Reference< XInterface > () );
}
return rReturn;
}
::rtl::OUString SAL_CALL ORemoteBridge::getName( )
throw(::com::sun::star::uno::RuntimeException)
{
return m_sName;
}
::rtl::OUString SAL_CALL ORemoteBridge::getDescription( )
throw(::com::sun::star::uno::RuntimeException)
{
return m_sDescription;
}
// XTypeProvider
Sequence< Type > SAL_CALL ORemoteBridge::getTypes(void) throw( RuntimeException )
{
static OTypeCollection *pCollection = 0;
if( ! pCollection )
{
MutexGuard guard( Mutex::getGlobalMutex() );
if( ! pCollection )
{
static OTypeCollection collection(
getCppuType( (Reference< XTypeProvider> * )0),
getCppuType( (Reference< XBridge > * ) 0 ),
getCppuType( (Reference< XInitialization > * ) 0 ),
OComponentHelper::getTypes() );
pCollection = &collection;
}
}
return (*pCollection).getTypes();
}
Sequence< sal_Int8 > SAL_CALL ORemoteBridge::getImplementationId( ) throw( RuntimeException)
{
static OImplementationId *pId = 0;
if( ! pId )
{
MutexGuard guard( Mutex::getGlobalMutex() );
if( ! pId )
{
static OImplementationId id( sal_False );
pId = &id;
}
}
return (*pId).getImplementationId();
}
void ORemoteBridge::disposing()
{
MutexGuard guard( m_mutex );
if( m_pContext )
{
m_pContext->removeDisposingListener( m_pContext , ( remote_DisposingListener * )this);
if( ! m_pEnvRemote )
{
if( m_pContext->m_pConnection )
{
sal_Int32 nIndex = 0;
OUString sProtocol = OUString( m_pContext->m_pProtocol ).getToken( 0 , ',' , nIndex );
uno_getEnvironment( &m_pEnvRemote , sProtocol.pData , m_pContext );
OSL_ASSERT( m_pEnvRemote );
}
else
{
// within disposing from the context, no further dispose necessary !
}
}
if( m_pEnvRemote )
{
m_pEnvRemote->dispose( m_pEnvRemote );
m_pEnvRemote->release( m_pEnvRemote );
m_pEnvRemote = 0;
}
m_pContext->aBase.release( (uno_Context*)m_pContext );
m_pContext = 0;
}
}
//----------------------
// static methods
//----------------------
void ORemoteBridge::thisAcquire( remote_DisposingListener *p )
{
ORemoteBridge *m = (ORemoteBridge * ) p;
m->acquire();
}
void ORemoteBridge::thisRelease( remote_DisposingListener *p )
{
ORemoteBridge *m = (ORemoteBridge * ) p;
m->release();
}
void ORemoteBridge::thisDisposing( remote_DisposingListener * p,
rtl_uString * )
{
ORemoteBridge *m = (ORemoteBridge * ) p;
m->dispose();
}
//---------------------------------
//
//---------------------------------
Reference< XInterface > SAL_CALL CreateInstance( const Reference< XComponentContext > &)
{
return Reference< XInterface > ( ( OWeakObject * ) new ORemoteBridge );
}
OUString getImplementationName()
{
static OUString *pImplName = 0;
if( ! pImplName )
{
MutexGuard guard( Mutex::getGlobalMutex() );
if( ! pImplName )
{
static OUString implName(
RTL_CONSTASCII_USTRINGPARAM( IMPLEMENTATION_NAME ) );
pImplName = &implName;
}
}
return *pImplName;
}
Sequence< OUString > getSupportedServiceNames()
{
static Sequence < OUString > *pNames = 0;
if( ! pNames )
{
MutexGuard guard( Mutex::getGlobalMutex() );
if( !pNames )
{
static Sequence< OUString > seqNames(3);
seqNames.getArray()[0] = OUString::createFromAscii( "com.sun.star.bridge.Bridge" );
seqNames.getArray()[1] = OUString::createFromAscii( "com.sun.star.bridge.IiopBridge" );
seqNames.getArray()[2] = OUString::createFromAscii( "com.sun.star.bridge.UrpBridge" );
pNames = &seqNames;
}
}
return *pNames;
}
}
using namespace remotebridges_bridge;
static struct ImplementationEntry g_entries[] =
{
{
remotebridges_bridge::CreateInstance, remotebridges_bridge::getImplementationName,
remotebridges_bridge::getSupportedServiceNames, createSingleComponentFactory,
&g_moduleCount.modCnt , 0
},
{ 0, 0, 0, 0, 0, 0 }
};
extern "C"
{
sal_Bool SAL_CALL component_canUnload( TimeValue *pTime )
{
return g_moduleCount.canUnload( &g_moduleCount , pTime );
}
//==================================================================================================
void SAL_CALL component_getImplementationEnvironment(
const sal_Char ** ppEnvTypeName, uno_Environment ** )
{
*ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
}
//==================================================================================================
void * SAL_CALL component_getFactory(
const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
{
return component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey , g_entries );
}
}

View File

@@ -1,147 +0,0 @@
/*************************************************************************
*
* 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/mutex.hxx>
#include <osl/diagnose.h>
#include <uno/mapping.hxx>
#include <uno/environment.h>
#include <bridges/remote/context.h>
#include <bridges/remote/remote.h>
#include <cppuhelper/factory.hxx>
#include <cppuhelper/component.hxx>
#include <cppuhelper/typeprovider.hxx>
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/lang/XInitialization.hpp>
#include <com/sun/star/bridge/XBridge.hpp>
#include <com/sun/star/bridge/XInstanceProvider.hpp>
namespace remotebridges_bridge
{
extern rtl_StandardModuleCount g_moduleCount;
struct MyMutex
{
::osl::Mutex m_mutex;
};
class ORemoteBridge :
public MyMutex,
public remote_DisposingListener,
public ::com::sun::star::lang::XInitialization,
public ::com::sun::star::bridge::XBridge,
public ::cppu::OComponentHelper
{
public:
ORemoteBridge();
~ORemoteBridge();
// XInterface
public:
::com::sun::star::uno::Any SAL_CALL
queryInterface( const ::com::sun::star::uno::Type & aType ) throw(::com::sun::star::uno::RuntimeException);
void SAL_CALL acquire() throw()
{ OComponentHelper::acquire(); }
void SAL_CALL release() throw()
{ OComponentHelper::release(); }
public:
virtual void SAL_CALL disposing(); // called by OComponentHelper
public:
// Methods
virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence<
::com::sun::star::uno::Any >& aArguments )
throw( ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
public:
virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL
getInstance( const ::rtl::OUString& sInstanceName )
throw(::com::sun::star::uno::RuntimeException);
virtual ::rtl::OUString SAL_CALL getName( )
throw(::com::sun::star::uno::RuntimeException);
virtual ::rtl::OUString SAL_CALL getDescription( )
throw(::com::sun::star::uno::RuntimeException);
public:
virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL
getTypes( ) throw(::com::sun::star::uno::RuntimeException);
virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL
getImplementationId( ) throw(::com::sun::star::uno::RuntimeException);
public:
static void SAL_CALL thisAcquire( remote_DisposingListener * );
static void SAL_CALL thisRelease( remote_DisposingListener * );
static void SAL_CALL thisDisposing( remote_DisposingListener * ,
rtl_uString * pBridgeName );
public:
void objectMappedSuccesfully();
public:
remote_Context *m_pContext;
uno_Environment *m_pEnvRemote;
::rtl::OUString m_sName;
::rtl::OUString m_sDescription;
::rtl::OUString m_sProtocol;
};
class OInstanceProviderWrapper :
public remote_InstanceProvider
{
public:
OInstanceProviderWrapper( const ::com::sun::star::uno::Reference <
::com::sun::star::bridge::XInstanceProvider > & rProvider ,
ORemoteBridge * pBridgeCallback );
~OInstanceProviderWrapper();
public:
static void SAL_CALL thisAcquire( remote_InstanceProvider * );
static void SAL_CALL thisRelease( remote_InstanceProvider * );
static void SAL_CALL thisGetInstance( remote_InstanceProvider * pProvider ,
uno_Environment *pEnvRemote,
remote_Interface **ppRemoteI,
rtl_uString *pInstanceName,
typelib_InterfaceTypeDescription *pType,
uno_Any **ppException );
private:
::com::sun::star::uno::Reference <
::com::sun::star::bridge::XInstanceProvider > m_rProvider;
oslInterlockedCount m_nRef;
ORemoteBridge *m_pBridgeCallback;
};
}

Some files were not shown because too many files have changed in this diff Show More