[Libreoffice-commits] .: sd/Library_sd.mk sd/source

Andrzej J.R. Hunt ajrhunt at kemper.freedesktop.org
Fri Aug 10 09:43:52 PDT 2012


 sd/Library_sd.mk                                    |    1 
 sd/source/ui/inc/RemoteServer.hxx                   |   10 +--
 sd/source/ui/remotecontrol/BufferedStreamSocket.cxx |   61 ++++++++++++++++++
 sd/source/ui/remotecontrol/BufferedStreamSocket.hxx |   45 +++++++++++++
 sd/source/ui/remotecontrol/Communicator.cxx         |   13 ++-
 sd/source/ui/remotecontrol/Communicator.hxx         |    6 +
 sd/source/ui/remotecontrol/Server.cxx               |   66 +++++++++++++++++---
 7 files changed, 185 insertions(+), 17 deletions(-)

New commits:
commit f4ab85cb44664a4c46c52d5a34eee300947e6069
Author: Andrzej J.R. Hunt <andrzej at ahunt.org>
Date:   Fri Aug 10 18:42:49 2012 +0200

    Pairing implemented server side.
    
    Change-Id: I542e563df68d38691f7c95cebf66aeb32071bd66

diff --git a/sd/Library_sd.mk b/sd/Library_sd.mk
index 92db929..283971c 100644
--- a/sd/Library_sd.mk
+++ b/sd/Library_sd.mk
@@ -327,6 +327,7 @@ $(eval $(call gb_Library_add_exception_objects,sd,\
     sd/source/ui/presenter/PresenterPreviewCache \
     sd/source/ui/presenter/PresenterTextView \
     sd/source/ui/presenter/SlideRenderer \
+    sd/source/ui/remotecontrol/BufferedStreamSocket \
     sd/source/ui/remotecontrol/Communicator \
     sd/source/ui/remotecontrol/DiscoveryService \
     sd/source/ui/remotecontrol/ImagePreparer \
diff --git a/sd/source/ui/inc/RemoteServer.hxx b/sd/source/ui/inc/RemoteServer.hxx
index a77f5ab..c64bf94 100644
--- a/sd/source/ui/inc/RemoteServer.hxx
+++ b/sd/source/ui/inc/RemoteServer.hxx
@@ -38,6 +38,7 @@ namespace css = ::com::sun::star;
 namespace sd
 {
     class Communicator;
+    class BufferedStreamSocket;
 
     struct ClientInfo
     {
@@ -53,14 +54,14 @@ namespace sd
     struct ClientInfoInternal:
         ClientInfo
     {
-        osl::StreamSocket mStreamSocket;
+        BufferedStreamSocket *mpStreamSocket;
         rtl::OUString mPin;
 
         ClientInfoInternal( const rtl::OUString rName,
                             const rtl::OUString rAddress,
-                            osl::StreamSocket &rSocket, rtl::OUString rPin ):
+                            BufferedStreamSocket *pSocket, rtl::OUString rPin ):
                 ClientInfo( rName, rAddress ),
-                mStreamSocket( rSocket ),
+                mpStreamSocket( pSocket ),
                 mPin( rPin ) {}
     };
 
@@ -77,7 +78,8 @@ namespace sd
 
             // For the control dialog
             SD_DLLPUBLIC static std::vector<ClientInfo*> getClients();
-            SD_DLLPUBLIC static void connectClient( ClientInfo aClient, rtl::OString aPin );
+            SD_DLLPUBLIC static sal_Bool connectClient( ClientInfo *pClient,
+                                                        rtl::OUString aPin );
 
             // For the communicator
             static void removeCommunicator( Communicator* pCommunicator );
diff --git a/sd/source/ui/remotecontrol/BufferedStreamSocket.cxx b/sd/source/ui/remotecontrol/BufferedStreamSocket.cxx
new file mode 100644
index 0000000..8232bd0
--- /dev/null
+++ b/sd/source/ui/remotecontrol/BufferedStreamSocket.cxx
@@ -0,0 +1,61 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <BufferedStreamSocket.hxx>
+
+#include <algorithm>
+
+using namespace sd;
+using namespace std;
+using namespace osl;
+
+BufferedStreamSocket::BufferedStreamSocket( const osl::StreamSocket &aSocket ):
+    StreamSocket( aSocket ),
+    aRet( 0 ),
+    aRead( 0 ),
+    aBuffer()
+{
+}
+
+sal_Int32 BufferedStreamSocket::readLine( OString& aLine )
+{
+    while ( true )
+    {
+        aBuffer.resize( aRead + 100 );
+        aRet = recv( &aBuffer[aRead], 100 );
+        if ( aRet == 0 )
+        {
+                return aRet;
+        }
+        // Prevent buffer from growing massively large.
+        if ( aRead > MAX_LINE_LENGTH )
+        {
+            aBuffer.erase( aBuffer.begin(), aBuffer.end() );
+            return 0;
+        }
+        aRead += aRet;
+        vector<char>::iterator aIt;
+        while ( (aIt = find( aBuffer.begin(), aBuffer.end(), '\n' ))
+            != aBuffer.end() )
+        {
+            sal_uInt64 aLocation = aIt - aBuffer.begin();
+
+            aLine = OString( &(*aBuffer.begin()), aLocation );
+
+            aBuffer.erase( aBuffer.begin(), aIt + 1 ); // Also delete the empty line
+            aRead -= (aLocation + 1);
+
+            return aLine.getLength();
+        }
+    }
+
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/remotecontrol/BufferedStreamSocket.hxx b/sd/source/ui/remotecontrol/BufferedStreamSocket.hxx
new file mode 100644
index 0000000..53b6e2a
--- /dev/null
+++ b/sd/source/ui/remotecontrol/BufferedStreamSocket.hxx
@@ -0,0 +1,45 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+#ifndef _SD_IMPRESSREMOTE_BUFFEREDSTREAMSOCKET_HXX
+#define _SD_IMPRESSREMOTE_BUFFEREDSTREAMSOCKET_HXX
+
+#include <boost/noncopyable.hpp>
+#include <osl/socket.hxx>
+#include <vector>
+
+#define CHARSET RTL_TEXTENCODING_UTF8
+#define MAX_LINE_LENGTH 20000
+
+namespace sd
+{
+
+    /**
+     * A wrapper for an osl StreamSocket to allow reading lines.
+     */
+    class BufferedStreamSocket :
+        public ::osl::StreamSocket,
+        private ::boost::noncopyable
+    {
+        public:
+            BufferedStreamSocket( const osl::StreamSocket &aSocket );
+            BufferedStreamSocket( const BufferedStreamSocket &aSocket );
+            /**
+             * Blocks until a line is read.
+             * Returns whatever the last call of recv returned, i.e. 0 or less
+             * if there was a problem in communications.
+             */
+            sal_Int32 readLine(OString& aLine);
+        private:
+            sal_Int32 aRet, aRead;
+            std::vector<char> aBuffer;
+    };
+}
+
+#endif // _SD_IMPRESSREMOTE_BUFFEREDSTREAMSOCKET_HXX
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/remotecontrol/Communicator.cxx b/sd/source/ui/remotecontrol/Communicator.cxx
index d4775f9..303f85a 100644
--- a/sd/source/ui/remotecontrol/Communicator.cxx
+++ b/sd/source/ui/remotecontrol/Communicator.cxx
@@ -22,9 +22,9 @@ using namespace std;
 using namespace com::sun::star;
 using namespace osl;
 
-Communicator::Communicator( StreamSocket &aSocket ):
+Communicator::Communicator( BufferedStreamSocket *pSocket ):
     Thread( "CommunicatorThread" ),
-    mSocket( aSocket ),
+    mpSocket( pSocket ),
     pTransmitter( 0 ),
     mListener( 0 )
 {
@@ -37,8 +37,11 @@ Communicator::~Communicator()
 // Run as a thread
 void Communicator::execute()
 {
-    pTransmitter = new Transmitter( mSocket );
+    pTransmitter = new Transmitter( *mpSocket );
     pTransmitter->launch();
+
+    pTransmitter->addMessage( "LO_SERVER_SERVER_PAIRED\n\n",
+                              Transmitter::PRIORITY_HIGH );
     Receiver aReceiver( pTransmitter );
     try {
         uno::Reference< lang::XMultiServiceFactory > xServiceManager(
@@ -65,7 +68,7 @@ void Communicator::execute()
     while ( true )
     {
         aBuffer.resize( aRead + 100 );
-        aRet = mSocket.recv( &aBuffer[aRead], 100 );
+        aRet = mpSocket->recv( &aBuffer[aRead], 100 );
         if ( aRet == 0 )
         {
             break; // I.e. transmission finished.
@@ -94,6 +97,8 @@ void Communicator::execute()
     pTransmitter->join();
     pTransmitter = NULL;
 
+    delete mpSocket;
+
     RemoteServer::removeCommunicator( this );
 }
 
diff --git a/sd/source/ui/remotecontrol/Communicator.hxx b/sd/source/ui/remotecontrol/Communicator.hxx
index 089fffa..d7ad796 100644
--- a/sd/source/ui/remotecontrol/Communicator.hxx
+++ b/sd/source/ui/remotecontrol/Communicator.hxx
@@ -22,6 +22,8 @@
 
 #include <com/sun/star/presentation/XSlideShowController.hpp>
 
+#include "BufferedStreamSocket.hxx"
+
 #define CHARSET RTL_TEXTENCODING_UTF8
 namespace css = ::com::sun::star;
 
@@ -40,7 +42,7 @@ namespace sd
     class Communicator : public salhelper::Thread
     {
         public:
-            Communicator( osl::StreamSocket &aSocket );
+            Communicator( BufferedStreamSocket *pSocket );
             ~Communicator();
 
             Transmitter* getTransmitter();
@@ -51,7 +53,7 @@ namespace sd
 
         private:
             void execute();
-            osl::StreamSocket mSocket;
+            BufferedStreamSocket *mpSocket;
 
             Transmitter *pTransmitter;
             rtl::Reference<Listener> mListener;
diff --git a/sd/source/ui/remotecontrol/Server.cxx b/sd/source/ui/remotecontrol/Server.cxx
index eb4adc1..af4170a 100644
--- a/sd/source/ui/remotecontrol/Server.cxx
+++ b/sd/source/ui/remotecontrol/Server.cxx
@@ -68,11 +68,39 @@ void RemoteServer::execute()
     while ( true )
     {
         StreamSocket aSocket;
-        if ( mSocket.acceptConnection( aSocket ) == osl_Socket_Error ) {
+        if ( mSocket.acceptConnection( aSocket ) == osl_Socket_Error )
+        {
+            return; // Closed, or other issue.
+        }
+        BufferedStreamSocket *pSocket = new BufferedStreamSocket( aSocket);
+        OString aLine;
+        if ( pSocket->readLine( aLine)
+            && aLine.equals( "LO_SERVER_CLIENT_PAIR" ) &&
+            pSocket->readLine( aLine ) )
+        {
+            OString aName( aLine );
+
+            if ( ! pSocket->readLine( aLine ) ) delete pSocket;
+            OString aPin( aLine );
+
+            SocketAddr aClientAddr;
+            pSocket->getPeerAddr( aClientAddr );
+            OUString aAddress = aClientAddr.getHostname();
+
             MutexGuard aGuard( mDataMutex );
-            // FIXME: read one line in, parse the data.
-            mAvailableClients.push_back( new ClientInfoInternal( "A name",
-                                        "An address", aSocket, "0000" ) );
+            mAvailableClients.push_back( new ClientInfoInternal(
+                    OStringToOUString( aName, RTL_TEXTENCODING_UTF8 ),
+                    aAddress, pSocket, OStringToOUString( aPin,
+                    RTL_TEXTENCODING_UTF8 ) ) );
+
+            // Read off any additional non-empty lines
+            do
+            {
+                pSocket->readLine( aLine );
+            }
+            while ( aLine.getLength() > 0 );
+        } else {
+            delete pSocket;
         }
     }
 
@@ -141,10 +169,34 @@ std::vector<ClientInfo*> RemoteServer::getClients()
     return aClients;
 }
 
-void RemoteServer::connectClient( ClientInfo aClient, rtl::OString aPin )
+sal_Bool RemoteServer::connectClient( ClientInfo* pClient, rtl::OUString aPin )
 {
-    (void) aClient;
-    (void) aPin;
+    if ( !spServer )
+        return false;
+
+    ClientInfoInternal *apClient = (ClientInfoInternal*) pClient;
+    if ( apClient->mPin.equals( aPin ) )
+    {
+        Communicator* pCommunicator = new Communicator( apClient->mpStreamSocket );
+        MutexGuard aGuard( spServer->mDataMutex );
+
+        spServer->mCommunicators.push_back( pCommunicator );
+
+        for ( vector<ClientInfoInternal*>::iterator aIt = spServer->mAvailableClients.begin();
+            aIt < spServer->mAvailableClients.end(); aIt++ )
+        {
+            if ( pClient == *aIt )
+            {
+                spServer->mAvailableClients.erase( aIt );
+            break;
+            }
+        }
+        return true;
+    }
+    else
+    {
+        return false;
+    }
 }
 
 void SdDLL::RegisterRemotes()


More information about the Libreoffice-commits mailing list