summaryrefslogtreecommitdiff
path: root/automation/source/simplecm
diff options
context:
space:
mode:
Diffstat (limited to 'automation/source/simplecm')
-rw-r--r--automation/source/simplecm/communiio.hxx68
-rw-r--r--automation/source/simplecm/makefile.mk46
-rw-r--r--automation/source/simplecm/packethandler.cxx338
-rw-r--r--automation/source/simplecm/packethandler.hxx72
-rw-r--r--automation/source/simplecm/simplecm.cxx701
-rw-r--r--automation/source/simplecm/tcpio.cxx74
-rw-r--r--automation/source/simplecm/tcpio.hxx64
7 files changed, 1363 insertions, 0 deletions
diff --git a/automation/source/simplecm/communiio.hxx b/automation/source/simplecm/communiio.hxx
new file mode 100644
index 000000000000..65466a26b271
--- /dev/null
+++ b/automation/source/simplecm/communiio.hxx
@@ -0,0 +1,68 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+/*************************************************************************
+ *
+ * ATTENTION
+ * This file is intended to work inside and outside the StarOffice environment.
+ * Only adaption of file commtypes.hxx should be necessary. Else it is a bug!
+ *
+ ************************************************************************/
+
+#include <automation/commtypes.hxx>
+
+#define C_ERROR_NONE 0x0001
+#define C_ERROR_PERMANENT 0x0002
+#define C_ERROR_RETRY 0x0003
+#define C_ERROR_TIMEOUT 0x0004
+
+class ITransmiter
+{
+protected:
+ comm_ULONG nLastSent;
+public:
+ ITransmiter() :nLastSent( 0 ){}
+ virtual ~ITransmiter() {}
+ virtual comm_USHORT TransferBytes( const void* pBuffer, comm_UINT32 nLen ) = 0;
+
+ comm_ULONG GetLastSent() const { return nLastSent; }
+};
+
+class IReceiver
+{
+protected:
+ comm_ULONG nLastReceived;
+public:
+ IReceiver() :nLastReceived( 0 ){}
+ virtual ~IReceiver() {;}
+ virtual comm_USHORT ReceiveBytes( void* pBuffer, comm_UINT32 nLen ) = 0;
+
+ comm_ULONG GetLastReceived() const { return nLastReceived; }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/automation/source/simplecm/makefile.mk b/automation/source/simplecm/makefile.mk
new file mode 100644
index 000000000000..b6318ab4fd46
--- /dev/null
+++ b/automation/source/simplecm/makefile.mk
@@ -0,0 +1,46 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=automation
+TARGET=simplecm
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES= \
+ $(SLO)$/tcpio.obj \
+ $(SLO)$/packethandler.obj \
+ $(SLO)$/simplecm.obj \
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/automation/source/simplecm/packethandler.cxx b/automation/source/simplecm/packethandler.cxx
new file mode 100644
index 000000000000..4cd2ad7d3106
--- /dev/null
+++ b/automation/source/simplecm/packethandler.cxx
@@ -0,0 +1,338 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_automation.hxx"
+
+/*************************************************************************
+ *
+ * ATTENTION
+ * This file is intended to work inside and outside the StarOffice environment.
+ * Only adaption of file commtypes.hxx should be necessary. Else it is a bug!
+ *
+ ************************************************************************/
+
+#include "packethandler.hxx"
+#include <automation/commtypes.hxx>
+#include <automation/commdefines.hxx>
+#include "communiio.hxx"
+#include <osl/diagnose.h>
+
+/**
+Forces switch to multichannel headers even for old communication Method
+**/
+#define FORCE_MULTI_CHANNEL_HEADERS
+
+
+PacketHandler::PacketHandler( ITransmiter* pTransmitter_, IReceiver* pReceiver_, comm_BOOL bMC )
+: pTransmitter( pTransmitter_ )
+, pReceiver( pReceiver_ )
+, bMultiChannel( bMC )
+{
+}
+
+unsigned char PacketHandler::CalcCheckByte( comm_UINT32 nBytes )
+{
+ comm_UINT16 nRes = 0;
+ nRes += HIBYTE( HIWORD( nBytes ) ) ^ 0xf0;
+ nRes += LOBYTE( HIWORD( nBytes ) ) ^ 0x0f;
+ nRes += HIBYTE( LOWORD( nBytes ) ) ^ 0xf0;
+ nRes += LOBYTE( LOWORD( nBytes ) ) ^ 0x0f;
+
+ nRes ^= HIBYTE( nRes );
+
+ return LOBYTE( nRes );
+}
+
+
+#define READ_SOCKET( pBuffer, nLength )\
+ if ( !bWasError )\
+ {\
+ bWasError |= pReceiver->ReceiveBytes( pBuffer, nLength ) != C_ERROR_NONE;\
+ }
+
+#define READ_SOCKET_LEN( pBuffer, nLength, nTotal )\
+ READ_SOCKET( pBuffer, nLength );\
+ if ( !bWasError )\
+ {nTotal += nLength;}
+
+comm_BOOL PacketHandler::ReceiveData( void* &pData, comm_UINT32 &nLen )
+{
+ DBG_ASSERT( !pData, "pData should be NULL -> memory leak" );
+
+ nLen = 0;
+ pData = NULL;
+ comm_BOOL bWasError = sal_False;
+ comm_BOOL bForceMultiChannelThisPacket = sal_False;
+ if ( pReceiver )
+ {
+ comm_UINT32 nBytes = 0;
+ nReceiveProtocol = CM_PROTOCOL_OLDSTYLE;
+ nReceiveHeaderType = CH_NoHeader;
+
+ READ_SOCKET( &nBytes, sizeof(nBytes) )
+ if ( bWasError )
+ return sal_False;
+
+ if ( 0xFFFFFFFF == nBytes ) // Expliziter Request f�r dieses Datenpaket auf MultiChannel umzuschalten
+ {
+ READ_SOCKET( &nBytes, sizeof(nBytes) )
+ if ( bWasError )
+ return sal_False;
+ bForceMultiChannelThisPacket = sal_True;
+ }
+
+ nBytes = NETDWORD( nBytes );
+
+ if ( bMultiChannel || bForceMultiChannelThisPacket )
+ {
+ comm_ULONG nReadSoFar = 0;
+ comm_ULONG nHeaderReadSoFar = 0;
+
+ // Pr�fbyte f�r L�ngenangabe
+ unsigned char nLenCheck = 0;
+ READ_SOCKET_LEN( &nLenCheck, 1, nReadSoFar );
+ // Stimmt das Pr�fbyte?
+ bWasError |= nLenCheck != CalcCheckByte( nBytes );
+
+
+ comm_UINT16 nHeaderBytes;
+ READ_SOCKET_LEN( &nHeaderBytes, 2, nReadSoFar );
+ nHeaderBytes = NETWORD( nHeaderBytes );
+ // reicht der Header �ber das Ende hinaus?
+ bWasError |= !(nBytes >= nReadSoFar + nHeaderBytes);
+
+ READ_SOCKET_LEN( &nReceiveHeaderType, 2, nHeaderReadSoFar );
+ nReceiveHeaderType = NETWORD( nReceiveHeaderType );
+
+ switch ( nReceiveHeaderType )
+ {
+ case CH_SimpleMultiChannel:
+ {
+ READ_SOCKET_LEN( &nReceiveProtocol, 2, nHeaderReadSoFar );
+ nReceiveProtocol = NETWORD( nReceiveProtocol );
+ }
+ break;
+ case CH_Handshake:
+ {
+ }
+ break;
+ default:
+ {
+ OSL_FAIL("Unbekannter Headertyp in der Kommunikation");
+ bWasError = sal_True;
+ }
+
+ }
+
+ if ( bWasError )
+ return sal_False;
+
+ /// L�ngen anpassen und ggf restheader �berlesen.
+ while ( nHeaderBytes > nHeaderReadSoFar )
+ {
+ unsigned char nDummy;
+ READ_SOCKET_LEN( &nDummy, 1, nHeaderReadSoFar );
+ }
+
+ nReadSoFar += nHeaderReadSoFar;
+ nBytes -= nReadSoFar;
+
+ }
+
+ /* @@@ Notes @@@
+ *
+ * 1) a 'void*' allocated via 'new char[]' is always deallocated
+ * via plain 'delete()', not via array 'delete[]()'; it's just
+ * raw memory.
+ *
+ * 2) as the caller of this routine later-on changes ownership
+ * of 'pData' via 'SvMemoryStream::SetBuffer()' (in 'simplecm.cxx',
+ * 'SimpleCommunicationLinkViaSocket::DoReceiveDataStream()'),
+ * the allocator used here for 'void* pData' must match the
+ * deallocator used in 'SvMemoryStream::FreeMemory()', i.e.
+ * '::operator delete()'.
+ */
+ pData = ::operator new(nBytes);
+ READ_SOCKET( pData, nBytes )
+ if ( bWasError )
+ {
+ ::operator delete(pData), pData = 0;
+ return sal_False;
+ }
+ nLen = nBytes;
+ }
+ else
+ bWasError = sal_True;
+
+ return !bWasError;
+}
+
+/*#define WRITE_SOCKET( pBuffer, nLength )\
+ if ( !bWasError )\
+ bWasError |= !pStreamSocket || (pStreamSocket->write( pBuffer, nLength ) != nLength)*/
+
+#define WRITE_SOCKET( pBuffer, nLength )\
+ if ( !bWasError )\
+ {bWasError |= pTransmitter->TransferBytes( pBuffer, nLength ) != C_ERROR_NONE;}
+
+
+
+comm_BOOL PacketHandler::TransferData( const void* pData, comm_UINT32 nLen, CMProtocol nProtocol )
+{
+ comm_UINT32 nBuffer = nLen;
+ comm_BOOL bWasError = sal_False;
+
+#ifndef FORCE_MULTI_CHANNEL_HEADERS
+ if ( bMultiChannel )
+#endif
+ nBuffer += 1+2+2+2; // f�r einen CH_SimpleMultiChannel
+
+#ifdef FORCE_MULTI_CHANNEL_HEADERS
+ if ( !bMultiChannel )
+ {
+ comm_UINT32 n32;
+ n32 = 0xffffffff; // Umschalten auf MultiChannel
+ n32 = NETDWORD( n32 );
+ WRITE_SOCKET( &n32, 4 );
+ }
+#endif
+
+
+ comm_UINT32 nNetworkBuffer = NETDWORD( nBuffer );
+ WRITE_SOCKET( &nNetworkBuffer, sizeof(nNetworkBuffer) );
+
+
+#ifndef FORCE_MULTI_CHANNEL_HEADERS
+ if ( bMultiChannel )
+#endif
+ {
+ comm_UINT16 n16;
+ unsigned char c;
+
+ c = CalcCheckByte( nBuffer );
+ WRITE_SOCKET( &c, 1 );
+
+ n16 = 4; // L�nge des Headers f�r einen CH_SimpleMultiChannel
+ n16 = NETWORD( n16 );
+ WRITE_SOCKET( &n16, 2 );
+
+ n16 = CH_SimpleMultiChannel; // Typ des Headers
+ n16 = NETWORD( n16 );
+ WRITE_SOCKET( &n16, 2 );
+
+ nProtocol = NETWORD( nProtocol );
+ WRITE_SOCKET( &nProtocol, 2 );
+ }
+
+ WRITE_SOCKET( pData, nLen );
+ return !bWasError;
+}
+
+comm_BOOL PacketHandler::SendHandshake( HandshakeType aHandshakeType, const void* pData, comm_UINT32 nLen )
+{
+ comm_BOOL bWasError = sal_False;
+
+ comm_UINT32 nBuffer = 0;
+
+// if ( pMyManager->IsMultiChannel() ) Wir senden immer FFFFFFFF vorweg -> immer MultiChannel (Oder GPF bei �lteren)
+ nBuffer += 1+2+2; // f�r einen CH_Handshake
+
+ nBuffer += 2; // f�r den Typ des Handshakes
+
+ switch ( aHandshakeType )
+ {
+ case CH_REQUEST_HandshakeAlive:
+ nBuffer += 0; // Keine extra Daten
+ break;
+ case CH_RESPONSE_HandshakeAlive:
+ nBuffer += 0; // Keine extra Daten
+ break;
+ case CH_REQUEST_ShutdownLink:
+ nBuffer += 0; // Keine extra Daten
+ break;
+ case CH_ShutdownLink:
+ nBuffer += 0; // Keine extra Daten
+ break;
+ case CH_SUPPORT_OPTIONS:
+ nBuffer += 2 ; // one word extradata for options
+ break;
+ case CH_SetApplication:
+ nBuffer += 0 ; // one word extradata for options
+ break;
+ default:
+ OSL_FAIL("Unknown HandshakeType");
+ }
+
+ if ( pData )
+ nBuffer += nLen; // Extra data in Buffer
+
+ comm_UINT32 n32;
+ n32 = 0xffffffff; // Umschalten auf MultiChannel
+ n32 = NETDWORD( n32 );
+ WRITE_SOCKET( &n32, 4 );
+
+ comm_UINT32 nNetworkBuffer = NETDWORD( nBuffer );
+ WRITE_SOCKET( &nNetworkBuffer, sizeof(nNetworkBuffer) );
+
+
+ comm_UINT16 n16;
+ unsigned char c;
+
+ c = CalcCheckByte( nBuffer );
+ WRITE_SOCKET( &c, 1 );
+
+ n16 = 2; // L�nge des Headers f�r einen CH_Handshake
+ n16 = NETWORD( n16 );
+ WRITE_SOCKET( &n16, 2 );
+
+ n16 = CH_Handshake; // Typ des Headers
+ n16 = NETWORD( n16 );
+ WRITE_SOCKET( &n16, 2 );
+
+ n16 = aHandshakeType; // Typ des Handshakes
+ n16 = NETWORD( n16 );
+ WRITE_SOCKET( &n16, 2 );
+
+
+ switch ( aHandshakeType )
+ {
+ case CH_SUPPORT_OPTIONS:
+ n16 = OPT_USE_SHUTDOWN_PROTOCOL;
+ n16 = NETWORD( n16 );
+ WRITE_SOCKET( &n16, 2 );
+ break;
+ }
+
+ if ( pData )
+ WRITE_SOCKET( pData, nLen );
+
+ return !bWasError;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/automation/source/simplecm/packethandler.hxx b/automation/source/simplecm/packethandler.hxx
new file mode 100644
index 000000000000..8ea04d96f043
--- /dev/null
+++ b/automation/source/simplecm/packethandler.hxx
@@ -0,0 +1,72 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+/*************************************************************************
+ *
+ * ATTENTION
+ * This file is intended to work inside and outside the StarOffice environment.
+ * Only adaption of file commtypes.hxx should be necessary. Else it is a bug!
+ *
+ ************************************************************************/
+
+#ifndef _TOOLS_PACKETHANDLER_HXX_
+#define _TOOLS_PACKETHANDLER_HXX_
+
+#include <automation/commtypes.hxx>
+#include <automation/commdefines.hxx>
+
+class ITransmiter;
+class IReceiver;
+
+class PacketHandler
+{
+private:
+ unsigned char CalcCheckByte( comm_UINT32 nBytes );
+ ITransmiter* pTransmitter;
+ IReceiver* pReceiver;
+
+ comm_BOOL bMultiChannel;
+
+protected:
+ comm_UINT16 nReceiveProtocol;
+ comm_UINT16 nReceiveHeaderType;
+
+public:
+ PacketHandler( ITransmiter* pTransmitter_, IReceiver* pReceiver_, comm_BOOL bMC = sal_False );
+
+ comm_UINT16 GetReceiveProtocol() const { return nReceiveProtocol; }
+ comm_UINT16 GetReceiveHeaderType() const { return nReceiveHeaderType; }
+
+ comm_BOOL ReceiveData( void* &pData, comm_UINT32 &nLen ); /// Recieve DataPacket from Socket
+ virtual comm_BOOL SendHandshake( HandshakeType aHandshakeType, const void* pData = NULL, comm_UINT32 nLen = 0 );
+ virtual comm_BOOL TransferData( const void* pData, comm_UINT32 nLen, CMProtocol nProtocol = CM_PROTOCOL_OLDSTYLE );
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/automation/source/simplecm/simplecm.cxx b/automation/source/simplecm/simplecm.cxx
new file mode 100644
index 000000000000..01c37e99e26b
--- /dev/null
+++ b/automation/source/simplecm/simplecm.cxx
@@ -0,0 +1,701 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_automation.hxx"
+
+
+#define ENABLE_BYTESTRING_STREAM_OPERATORS
+#include <tools/solar.h>
+#include <automation/simplecm.hxx>
+#include <osl/diagnose.h>
+
+#include <automation/commdefines.hxx>
+#include "packethandler.hxx"
+#include "tcpio.hxx"
+
+#if OSL_DEBUG_LEVEL > 1
+#include <stdio.h>
+void debug_printf( const char *chars )
+{
+ static BOOL bPrint = (getenv("DEBUG") != NULL);
+ if ( bPrint )
+ {
+ printf( "%c\n", chars );
+ fflush( stdout );
+ }
+}
+#endif
+
+CommunicationLink::CommunicationLink( CommunicationManager *pMan )
+: pMyManager(pMan)
+, pServiceData(NULL)
+, nServiceProtocol( 0 )
+, bIsInsideCallback( sal_False )
+, nTotalBytes( 0 )
+, maApplication("Undefined")
+#if OSL_DEBUG_LEVEL > 1
+, bFlag( sal_False )
+, nSomething( 0 )
+#endif
+{
+}
+
+CommunicationLink::~CommunicationLink()
+{
+#if OSL_DEBUG_LEVEL > 1
+ if ( !bFlag ) // bFlag will be set if deletion is expected else we can set a breakpoint
+ bFlag = sal_False;
+#endif
+ if ( pMyManager )
+ pMyManager->DestroyingLink( this );
+}
+
+void CommunicationLink::CallInfoMsg( InfoString aMsg )
+{
+ if ( pMyManager )
+ pMyManager->InfoMsg( aMsg );
+};
+
+CM_InfoType CommunicationLink::GetInfoType()
+{
+ if ( pMyManager )
+ return pMyManager->GetInfoType();
+ else
+ return CM_NO_TEXT;
+}
+
+IMPL_LINK( CommunicationLink, ConnectionClosed, void*, EMPTYARG )
+{
+ if ( pMyManager )
+ pMyManager->CallConnectionClosed( this );
+ return 1;
+}
+
+IMPL_LINK( CommunicationLink, DataReceived, void*, EMPTYARG )
+{
+ if ( pMyManager )
+ pMyManager->CallDataReceived( this );
+ return 1;
+}
+
+sal_Bool CommunicationLink::DoTransferDataStream( SvStream *pDataStream, CMProtocol nProtocol )
+{
+ INFO_MSG( CByteString("S :").Append( GetCommunicationPartner( CM_FQDN ) ),
+ CByteString("Daten Senden:").Append( GetCommunicationPartner( CM_FQDN ) ),
+ CM_SEND, this );
+ sal_Bool bWasError = sal_False;
+
+ sal_uInt32 nBuffer;
+ nBuffer = pDataStream->SeekRel(0) +1;
+ bWasError = pPacketHandler->TransferData( ((SvMemoryStream*)pDataStream)->GetData(), nBuffer, nProtocol ) != C_ERROR_NONE;
+
+ if ( bWasError )
+ {
+ INFO_MSG( CByteString("Send Failed:").Append( GetCommunicationPartner( CM_FQDN ) ),
+ CByteString( "Socket wird wegen Fehlers beim Senden geschlossen: ").Append( GetCommunicationPartner( CM_FQDN ) ),
+ CM_ERROR, this );
+ ShutdownCommunication();
+ }
+ return !bWasError;
+}
+
+sal_Bool CommunicationLink::TransferDataStream( SvStream *pDataStream, CMProtocol nProtocol )
+{
+ aLastAccess = DateTime();
+ nTotalBytes += pDataStream->Seek( STREAM_SEEK_TO_END );
+ return DoTransferDataStream( pDataStream, nProtocol );
+}
+
+void CommunicationLink::SetApplication( const ByteString& aApp )
+{
+ maApplication = aApp;
+}
+
+
+SimpleCommunicationLinkViaSocket::SimpleCommunicationLinkViaSocket( CommunicationManager *pMan, osl::StreamSocket* pSocket )
+: CommunicationLink( pMan )
+, aCommunicationPartner()
+, aMyName()
+, pStreamSocket( pSocket )
+, pReceiveStream( NULL )
+, bIsRequestShutdownPending( sal_False )
+{
+ pTCPIO = new TCPIO( pStreamSocket );
+ pPacketHandler = new PacketHandler( (ITransmiter*) pTCPIO, pTCPIO, pMyManager->IsMultiChannel() );
+}
+
+SimpleCommunicationLinkViaSocket::~SimpleCommunicationLinkViaSocket()
+{
+ delete pPacketHandler;
+ pPacketHandler = NULL;
+ delete pTCPIO;
+ pTCPIO = NULL;
+ delete pStreamSocket;
+ pStreamSocket = NULL;
+}
+
+void SimpleCommunicationLinkViaSocket::SetStreamSocket( osl::StreamSocket* pSocket )
+{
+ if ( pTCPIO )
+ pTCPIO->SetStreamSocket( pSocket );
+ pStreamSocket = pSocket;
+}
+
+sal_Bool SimpleCommunicationLinkViaSocket::StopCommunication()
+{
+ CommunicationLinkRef rHold(this); // avoid deleting this link before the end of the method
+ if ( !IsCommunicationError() ) // Meaning that the Communication is still runnung
+ {
+#if OSL_DEBUG_LEVEL > 1
+ debug_printf("Sending REQUEST_ShutdownLink\n");
+#endif
+ SendHandshake( CH_REQUEST_ShutdownLink );
+ }
+ WaitForShutdown();
+ return sal_True;
+}
+
+sal_Bool SimpleCommunicationLinkViaSocket::IsCommunicationError()
+{
+ return !pStreamSocket;
+}
+
+ByteString SimpleCommunicationLinkViaSocket::GetCommunicationPartner( CM_NameType eType )
+{
+ if ( pStreamSocket )
+ {
+ switch ( eType )
+ {
+ case CM_DOTTED:
+ {
+ rtl::OUString aDotted;
+ osl::SocketAddr* pPeerAdr = new osl::SocketAddr;
+ pStreamSocket->getPeerAddr( *pPeerAdr );
+ osl_getDottedInetAddrOfSocketAddr( pPeerAdr->getHandle(), &aDotted.pData);
+ delete pPeerAdr;
+ return ByteString( UniString(aDotted), RTL_TEXTENCODING_UTF8 );
+ }
+ //break;
+ case CM_FQDN:
+ {
+ if ( !aCommunicationPartner.Len() )
+ {
+ rtl::OUString aFQDN( pStreamSocket->getPeerHost());
+ aCommunicationPartner = ByteString( UniString(aFQDN), RTL_TEXTENCODING_UTF8 );
+ }
+ return aCommunicationPartner;
+ }
+ //break;
+ }
+ }
+ return CByteString( "Unknown" );
+}
+
+ByteString SimpleCommunicationLinkViaSocket::GetMyName( CM_NameType eType )
+{
+ if ( pStreamSocket )
+ {
+ switch ( eType )
+ {
+ case CM_DOTTED:
+ {
+ rtl::OUString aDotted;
+ osl::SocketAddr* pPeerAdr = new osl::SocketAddr;
+ pStreamSocket->getPeerAddr( *pPeerAdr );
+ osl_getDottedInetAddrOfSocketAddr( pPeerAdr->getHandle(), &aDotted.pData);
+ delete pPeerAdr;
+ return ByteString( UniString(aDotted), RTL_TEXTENCODING_UTF8 );
+ }
+ //break;
+ case CM_FQDN:
+ {
+ if ( !aMyName.Len() )
+ {
+ rtl::OUString aFQDN(pStreamSocket->getLocalHost());
+ aMyName = ByteString( UniString(aFQDN), RTL_TEXTENCODING_UTF8 );
+ }
+ return aMyName;
+ }
+ //break;
+ }
+ }
+ return CByteString( "Error" );
+}
+
+SvStream* SimpleCommunicationLinkViaSocket::GetBestCommunicationStream()
+{
+ SvStream* pStream = new SvMemoryStream;
+// pStream->SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
+ return pStream;
+}
+
+#define READ_SOCKET( pBuffer, nLength )\
+ if ( !bWasError )\
+ {bWasError |= pTCPIO->ReceiveBytes( pBuffer, nLength ) != C_ERROR_NONE;}
+
+#define READ_SOCKET_LEN( pBuffer, nLength, nTotal )\
+ READ_SOCKET( pBuffer, nLength );\
+ if ( !bWasError )\
+ {nTotal += nLength;}
+
+sal_Bool SimpleCommunicationLinkViaSocket::DoReceiveDataStream()
+{
+ sal_Bool bWasError = sal_False;
+ void* pBuffer = NULL;
+ comm_UINT32 nLen;
+ bWasError = pPacketHandler->ReceiveData( pBuffer, nLen ) != C_ERROR_NONE;
+ if ( !bWasError )
+ {
+ pReceiveStream = GetBestCommunicationStream();
+ DBG_ASSERT( pReceiveStream->IsA() == ID_MEMORYSTREAM, "CommunicationStream is not an SvMemoryStream. Communication has to be reimplemented here!");
+ if ( pReceiveStream->IsA() == ID_MEMORYSTREAM )
+ ((SvMemoryStream*)pReceiveStream)->SetBuffer( pBuffer, nLen, sal_True, nLen );
+ DBG_ASSERT( pReceiveStream, "Datastream is NULL");
+ }
+
+ return !bWasError;
+}
+
+void SimpleCommunicationLinkViaSocket::SetApplication( const ByteString& aApp )
+{
+ CommunicationLink::SetApplication( aApp );
+ SvStream* pData = GetBestCommunicationStream();
+ *pData << aApp;
+ SendHandshake( CH_SetApplication, pData );
+ delete pData;
+}
+
+void SimpleCommunicationLinkViaSocket::SetNewPacketAsCurrent()
+{
+ pServiceData = pReceiveStream;
+ nServiceProtocol = pPacketHandler->GetReceiveProtocol();
+ nServiceHeaderType = pPacketHandler->GetReceiveHeaderType();
+}
+
+sal_Bool SimpleCommunicationLinkViaSocket::SendHandshake( HandshakeType aHandshakeType, SvStream* pData )
+{
+ sal_Bool bWasError;
+
+ if ( pData )
+ {
+ sal_uInt32 nBuffer;
+ nBuffer = pData->Seek( STREAM_SEEK_TO_END );
+ bWasError = !pPacketHandler->SendHandshake( aHandshakeType, ((SvMemoryStream*)pData)->GetData(), nBuffer );
+ }
+ else
+ bWasError = !pPacketHandler->SendHandshake( aHandshakeType );
+
+
+ if ( bWasError )
+ {
+ INFO_MSG( CByteString("Send Failed:").Append( GetCommunicationPartner( CM_FQDN ) ),
+ CByteString( "Socket wird wegen Fehlers beim Senden geschlossen: ").Append( GetCommunicationPartner( CM_FQDN ) ),
+ CM_ERROR, this );
+ ShutdownCommunication();
+ }
+ else
+ { // set new status
+ switch ( aHandshakeType )
+ {
+ case CH_REQUEST_HandshakeAlive:
+ break;
+ case CH_RESPONSE_HandshakeAlive:
+ break;
+ case CH_REQUEST_ShutdownLink:
+ bIsRequestShutdownPending = sal_True;
+ break;
+ case CH_ShutdownLink:
+ break;
+ case CH_SUPPORT_OPTIONS:
+ break;
+ case CH_SetApplication:
+ break;
+ default:
+ OSL_FAIL("Unknown HandshakeType");
+ }
+ }
+ return !bWasError;
+}
+
+SimpleCommunicationLinkViaSocketWithReceiveCallbacks::SimpleCommunicationLinkViaSocketWithReceiveCallbacks( CommunicationManager *pMan, osl::StreamSocket* pSocket )
+: SimpleCommunicationLinkViaSocket( pMan, pSocket )
+{
+}
+
+SimpleCommunicationLinkViaSocketWithReceiveCallbacks::~SimpleCommunicationLinkViaSocketWithReceiveCallbacks()
+{
+ if ( pMyManager && pMyManager->IsLinkValid( this ) && !bIsRequestShutdownPending )
+ StopCommunication();
+}
+
+bool SimpleCommunicationLinkViaSocket::IsReceiveReady()
+{
+ if ( !IsCommunicationError() )
+ {
+ TimeValue aTime = {30, 0}; // 30 seconds
+ return pStreamSocket->isRecvReady( &aTime );
+ }
+
+ return false;
+}
+
+void SimpleCommunicationLinkViaSocketWithReceiveCallbacks::WaitForShutdown()
+{
+ CommunicationLinkRef rHold(this); // avoid deleting this link before the end of the method
+
+ while( pMyManager && !IsCommunicationError() && IsReceiveReady())
+ ReceiveDataStream();
+}
+
+sal_Bool SimpleCommunicationLinkViaSocketWithReceiveCallbacks::ReceiveDataStream()
+{
+ if ( DoReceiveDataStream() )
+ {
+ SetNewPacketAsCurrent();
+ StartCallback();
+ DataReceived();
+ return sal_True;
+ }
+ else
+ {
+ StartCallback();
+ ShutdownCommunication();
+ return sal_False;
+ }
+}
+
+sal_Bool SimpleCommunicationLinkViaSocketWithReceiveCallbacks::ShutdownCommunication()
+{
+ if ( GetStreamSocket() )
+ GetStreamSocket()->shutdown();
+
+ if ( GetStreamSocket() )
+ GetStreamSocket()->close();
+
+ osl::StreamSocket* pTempSocket = GetStreamSocket();
+ SetStreamSocket( NULL );
+ delete pTempSocket;
+
+ ConnectionClosed();
+
+ return sal_True;
+}
+
+
+
+CommunicationManager::CommunicationManager( sal_Bool bUseMultiChannel )
+: nInfoType( CM_NONE )
+, bIsCommunicationRunning( sal_False )
+, maApplication("Unknown")
+, bIsMultiChannel( bUseMultiChannel )
+{
+}
+
+CommunicationManager::~CommunicationManager()
+{
+ xLastNewLink.Clear();
+}
+
+sal_Bool CommunicationManager::StartCommunication( String aApp, String aParams )
+{
+ (void) aApp; /* avoid warning about unused parameter */
+ (void) aParams; /* avoid warning about unused parameter */
+ return sal_False;
+}
+
+sal_Bool CommunicationManager::StartCommunication( ByteString aHost, sal_uLong nPort )
+{
+ (void) aHost; /* avoid warning about unused parameter */
+ (void) nPort; /* avoid warning about unused parameter */
+ return sal_False;
+}
+
+ByteString CommunicationManager::GetMyName( CM_NameType )
+{
+ rtl::OUString aHostname( osl::SocketAddr::getLocalHostname());
+ return ByteString( UniString(aHostname), RTL_TEXTENCODING_UTF8 );
+}
+
+void CommunicationManager::CallConnectionOpened( CommunicationLink* pCL )
+{
+ pCL->StartCallback(); // Sollte bereits vor dem Aufruf gerufen werden
+ pCL->aStart = DateTime();
+ pCL->aLastAccess = pCL->aStart;
+ bIsCommunicationRunning = sal_True;
+ pCL->SetApplication( GetApplication() );
+
+ xLastNewLink = pCL;
+
+ INFO_MSG( CByteString("C+:").Append( pCL->GetCommunicationPartner( CM_FQDN ) ),
+ CByteString("Verbindung aufgebaut: ").Append( pCL->GetCommunicationPartner( CM_FQDN ) ),
+ CM_OPEN, pCL );
+ ConnectionOpened( pCL );
+ pCL->FinishCallback();
+}
+
+void CommunicationManager::CallConnectionClosed( CommunicationLink* pCL )
+{
+ pCL->StartCallback(); // Sollte bereits vor dem Aufruf gerufen werden
+ pCL->aLastAccess = DateTime();
+
+ INFO_MSG( CByteString("C-:").Append( pCL->GetCommunicationPartner( CM_FQDN ) ),
+ CByteString("Verbindung abgebrochen: ").Append( pCL->GetCommunicationPartner( CM_FQDN ) ),
+ CM_CLOSE, pCL );
+ ConnectionClosed( pCL );
+
+ if ( xLastNewLink == pCL )
+ xLastNewLink.Clear();
+
+ pCL->FinishCallback();
+// delete pCL;
+}
+
+void CommunicationManager::CallDataReceived( CommunicationLink* pCL )
+{
+ pCL->StartCallback(); // Sollte bereits vor dem Aufruf gerufen werden
+ pCL->aLastAccess = DateTime();
+ CommunicationLinkRef rHold(pCL); // H�lt den Zeiger bis zum Ende des calls
+
+ // should be impossible but happens for mysterious reasons
+ if ( !pCL->pServiceData )
+ {
+ OSL_FAIL( "Datastream is NULL" );
+ pCL->FinishCallback();
+ return;
+ }
+
+
+ if ( CH_Handshake == pCL->nServiceHeaderType )
+ {
+ SvStream *pData = pCL->GetServiceData();
+ sal_uInt16 nType;
+ pData->SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN ); // Unfortulately it is written this way :((
+ *pData >> nType;
+ pData->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+ switch ( nType )
+ {
+ case CH_REQUEST_HandshakeAlive:
+ {
+ pCL->SendHandshake( CH_RESPONSE_HandshakeAlive );
+ }
+ break;
+ case CH_REQUEST_ShutdownLink:
+ {
+#if OSL_DEBUG_LEVEL > 1
+ debug_printf("Sending ShutdownLink\n");
+#endif
+ pCL->SendHandshake( CH_ShutdownLink );
+ }
+ break;
+ case CH_ShutdownLink:
+ {
+#if OSL_DEBUG_LEVEL > 1
+ debug_printf("Executing ShutdownLink\n");
+#endif
+ pCL->ShutdownCommunication();
+ }
+ break;
+ case CH_SetApplication:
+ {
+ ByteString aApplication;
+ *pData >> aApplication;
+ pCL->CommunicationLink::SetApplication( aApplication );
+#if OSL_DEBUG_LEVEL > 1
+ debug_printf( "Setting Application to " );
+ debug_printf( aApplication.GetBuffer() );
+ debug_printf( "\n" );
+#endif
+ }
+ break;
+
+#if OSL_DEBUG_LEVEL > 1
+ default:
+ {
+ debug_printf("Unknown Handshake received\n");
+ }
+#endif
+ }
+ delete pData;
+ }
+ else
+ {
+ if ( pCL->pServiceData )
+ {
+ pCL->nTotalBytes += pCL->pServiceData->Seek( STREAM_SEEK_TO_END );
+ pCL->pServiceData->Seek( STREAM_SEEK_TO_BEGIN );
+ }
+
+ INFO_MSG( CByteString("D :").Append( pCL->GetCommunicationPartner( CM_FQDN ) ),
+ CByteString("Daten Empfangen:").Append( pCL->GetCommunicationPartner( CM_FQDN ) ),
+ CM_RECEIVE, pCL );
+ DataReceived( pCL );
+ }
+ delete pCL->GetServiceData();
+ pCL->FinishCallback();
+}
+
+void CommunicationManager::CallInfoMsg( InfoString aMsg )
+{
+ // Hier wird es wohl kein Housekeeping geben
+ InfoMsg( aMsg );
+}
+
+void CommunicationManager::SetApplication( const ByteString& aApp, sal_Bool bRunningLinks )
+{
+ maApplication = aApp;
+ if ( bRunningLinks )
+ {
+ sal_uInt16 i;
+ for ( i = 0 ; i < GetCommunicationLinkCount() ; i++ )
+ GetCommunicationLink( i )->SetApplication( aApp );
+ }
+}
+
+
+
+SingleCommunicationManager::SingleCommunicationManager( sal_Bool bUseMultiChannel )
+: CommunicationManager( bUseMultiChannel )
+{
+ xActiveLink = NULL;
+ pInactiveLink = NULL;
+}
+
+SingleCommunicationManager::~SingleCommunicationManager()
+{
+ StopCommunication();
+ if ( pInactiveLink )
+ pInactiveLink->InvalidateManager();
+}
+
+sal_Bool SingleCommunicationManager::StopCommunication()
+{
+ if ( xActiveLink.Is() )
+ {
+ sal_Bool bSuccess = xActiveLink->StopCommunication();
+ if ( pInactiveLink )
+ pInactiveLink->InvalidateManager();
+ pInactiveLink = xActiveLink;
+ xActiveLink.Clear();
+ return bSuccess;
+ }
+ return sal_True;
+}
+
+sal_Bool SingleCommunicationManager::IsLinkValid( CommunicationLink* pCL )
+{
+ return &xActiveLink == pCL;
+}
+
+sal_uInt16 SingleCommunicationManager::GetCommunicationLinkCount()
+{
+ return IsCommunicationRunning()?1:0;
+}
+
+CommunicationLinkRef SingleCommunicationManager::GetCommunicationLink( sal_uInt16 )
+{
+ return xActiveLink;
+}
+
+void SingleCommunicationManager::CallConnectionOpened( CommunicationLink* pCL )
+{
+ DBG_ASSERT( !xActiveLink.Is(), "Es ist bereits ein CommunicationLink aktiv");
+ if ( xActiveLink.Is() )
+ {
+ if ( pInactiveLink )
+ pInactiveLink->InvalidateManager();
+ pInactiveLink = xActiveLink;
+ xActiveLink->StopCommunication(); // Den alten Link brutal abw�rgen
+ }
+ xActiveLink = pCL;
+ CommunicationManager::CallConnectionOpened( pCL );
+}
+
+void SingleCommunicationManager::CallConnectionClosed( CommunicationLink* pCL )
+{
+ CommunicationManager::CallConnectionClosed( pCL );
+
+ DBG_ASSERT( pCL == xActiveLink, "SingleCommunicationManager::CallConnectionClosed mit fremdem Link");
+ if ( pInactiveLink )
+ pInactiveLink->InvalidateManager();
+ pInactiveLink = xActiveLink;
+ xActiveLink.Clear();
+ bIsCommunicationRunning = sal_False;
+}
+
+void SingleCommunicationManager::DestroyingLink( CommunicationLink *pCL )
+{
+ pInactiveLink = NULL;
+ pCL->InvalidateManager();
+}
+
+
+SingleCommunicationManagerClientViaSocket::SingleCommunicationManagerClientViaSocket( ByteString aHost, sal_uLong nPort, sal_Bool bUseMultiChannel )
+: SingleCommunicationManager( bUseMultiChannel )
+, aHostToTalk( aHost )
+, nPortToTalk( nPort )
+{
+}
+
+
+SingleCommunicationManagerClientViaSocket::SingleCommunicationManagerClientViaSocket( sal_Bool bUseMultiChannel )
+: SingleCommunicationManager( bUseMultiChannel )
+, aHostToTalk()
+, nPortToTalk( 0 )
+{
+}
+
+
+sal_Bool CommonSocketFunctions::DoStartCommunication( CommunicationManager *pCM, ICommunicationManagerClient *pCMC, ByteString aHost, sal_uLong nPort )
+{
+ osl::SocketAddr Addr( rtl::OUString( UniString( aHost, RTL_TEXTENCODING_UTF8 ) ), nPort );
+ osl::ConnectorSocket *pConnSocket;
+
+
+ TimeValue aTV;
+ aTV.Seconds = 10; // Warte 10 Sekunden
+ aTV.Nanosec = 0;
+ do
+ {
+ pConnSocket = new osl::ConnectorSocket();
+ pConnSocket->setOption( osl_Socket_OptionTcpNoDelay, 1 );
+ if ( pConnSocket->connect( Addr, &aTV ) == osl_Socket_Ok )
+ {
+ pConnSocket->setOption( osl_Socket_OptionTcpNoDelay, 1 );
+ pCM->CallConnectionOpened( CreateCommunicationLink( pCM, pConnSocket ) );
+ return sal_True;
+ }
+ else
+ delete pConnSocket;
+
+ } while ( pCMC->RetryConnect() );
+
+ return sal_False;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/automation/source/simplecm/tcpio.cxx b/automation/source/simplecm/tcpio.cxx
new file mode 100644
index 000000000000..e71afb399b84
--- /dev/null
+++ b/automation/source/simplecm/tcpio.cxx
@@ -0,0 +1,74 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_automation.hxx"
+
+#include "tcpio.hxx"
+
+/// implement ITransmiter
+comm_USHORT TCPIO::TransferBytes( const void* pBuffer, comm_UINT32 nLen )
+{
+ osl::MutexGuard aGuard( aMSocketWriteAccess );
+ if ( !pStreamSocket )
+ {
+ nLastSent = 0;
+ return C_ERROR_PERMANENT;
+ }
+ nLastSent = pStreamSocket->write( pBuffer, nLen );
+ if ( nLastSent == nLen )
+ return C_ERROR_NONE;
+ return C_ERROR_PERMANENT;
+}
+
+
+/// implement IReceiver
+comm_USHORT TCPIO::ReceiveBytes( void* pBuffer, comm_UINT32 nLen )
+{
+ osl::MutexGuard aGuard( aMSocketReadAccess );
+ if ( !pStreamSocket )
+ {
+ nLastReceived = 0;
+ return C_ERROR_PERMANENT;
+ }
+ nLastReceived = pStreamSocket->read( pBuffer, nLen );
+ if ( nLastReceived == nLen )
+ return C_ERROR_NONE;
+ return C_ERROR_PERMANENT;
+}
+
+
+// helper
+void TCPIO::SetStreamSocket( osl::StreamSocket* pSocket )
+{
+ osl::MutexGuard aRGuard( aMSocketReadAccess );
+ osl::MutexGuard aWGuard( aMSocketWriteAccess );
+ pStreamSocket = pSocket;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/automation/source/simplecm/tcpio.hxx b/automation/source/simplecm/tcpio.hxx
new file mode 100644
index 000000000000..07c3edba7a5b
--- /dev/null
+++ b/automation/source/simplecm/tcpio.hxx
@@ -0,0 +1,64 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef TCPIO_HXX
+#define TCPIO_HXX
+
+#include <osl/socket.hxx>
+#include <osl/mutex.hxx>
+
+#include "communiio.hxx"
+
+class TCPIO : public ITransmiter, public IReceiver
+{
+private:
+ osl::StreamSocket* pStreamSocket;
+ osl::Mutex aMSocketReadAccess;
+ osl::Mutex aMSocketWriteAccess;
+
+public:
+
+ ///
+ TCPIO( osl::StreamSocket* pSocket ):pStreamSocket( pSocket ){}
+ virtual ~TCPIO(){}
+
+
+ /// implement ITransmiter
+ virtual comm_USHORT TransferBytes( const void* pBuffer, comm_UINT32 nLen );
+
+ /// implement IReceiver
+ virtual comm_USHORT ReceiveBytes( void* pBuffer, comm_UINT32 nLen );
+
+ // helper
+ void SetStreamSocket( osl::StreamSocket* pSocket );
+
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */