1*b1cdbd2cSJim Jagielski /************************************************************** 2*b1cdbd2cSJim Jagielski * 3*b1cdbd2cSJim Jagielski * Licensed to the Apache Software Foundation (ASF) under one 4*b1cdbd2cSJim Jagielski * or more contributor license agreements. See the NOTICE file 5*b1cdbd2cSJim Jagielski * distributed with this work for additional information 6*b1cdbd2cSJim Jagielski * regarding copyright ownership. The ASF licenses this file 7*b1cdbd2cSJim Jagielski * to you under the Apache License, Version 2.0 (the 8*b1cdbd2cSJim Jagielski * "License"); you may not use this file except in compliance 9*b1cdbd2cSJim Jagielski * with the License. You may obtain a copy of the License at 10*b1cdbd2cSJim Jagielski * 11*b1cdbd2cSJim Jagielski * http://www.apache.org/licenses/LICENSE-2.0 12*b1cdbd2cSJim Jagielski * 13*b1cdbd2cSJim Jagielski * Unless required by applicable law or agreed to in writing, 14*b1cdbd2cSJim Jagielski * software distributed under the License is distributed on an 15*b1cdbd2cSJim Jagielski * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*b1cdbd2cSJim Jagielski * KIND, either express or implied. See the License for the 17*b1cdbd2cSJim Jagielski * specific language governing permissions and limitations 18*b1cdbd2cSJim Jagielski * under the License. 19*b1cdbd2cSJim Jagielski * 20*b1cdbd2cSJim Jagielski *************************************************************/ 21*b1cdbd2cSJim Jagielski 22*b1cdbd2cSJim Jagielski 23*b1cdbd2cSJim Jagielski 24*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove 25*b1cdbd2cSJim Jagielski #include "precompiled_io.hxx" 26*b1cdbd2cSJim Jagielski 27*b1cdbd2cSJim Jagielski #include "connector.hxx" 28*b1cdbd2cSJim Jagielski #include <rtl/ustrbuf.hxx> 29*b1cdbd2cSJim Jagielski #include <algorithm> 30*b1cdbd2cSJim Jagielski 31*b1cdbd2cSJim Jagielski using namespace ::osl; 32*b1cdbd2cSJim Jagielski using namespace ::rtl; 33*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::uno; 34*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::io; 35*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::connection; 36*b1cdbd2cSJim Jagielski 37*b1cdbd2cSJim Jagielski 38*b1cdbd2cSJim Jagielski namespace stoc_connector { 39*b1cdbd2cSJim Jagielski template<class T> notifyListeners(SocketConnection * pCon,sal_Bool * notified,T t)40*b1cdbd2cSJim Jagielski void notifyListeners(SocketConnection * pCon, sal_Bool * notified, T t) 41*b1cdbd2cSJim Jagielski { 42*b1cdbd2cSJim Jagielski XStreamListener_hash_set listeners; 43*b1cdbd2cSJim Jagielski 44*b1cdbd2cSJim Jagielski { 45*b1cdbd2cSJim Jagielski ::osl::MutexGuard guard(pCon->_mutex); 46*b1cdbd2cSJim Jagielski if(!*notified) 47*b1cdbd2cSJim Jagielski { 48*b1cdbd2cSJim Jagielski *notified = sal_True; 49*b1cdbd2cSJim Jagielski listeners = pCon->_listeners; 50*b1cdbd2cSJim Jagielski } 51*b1cdbd2cSJim Jagielski } 52*b1cdbd2cSJim Jagielski 53*b1cdbd2cSJim Jagielski ::std::for_each(listeners.begin(), listeners.end(), t); 54*b1cdbd2cSJim Jagielski } 55*b1cdbd2cSJim Jagielski 56*b1cdbd2cSJim Jagielski callStarted(Reference<XStreamListener> xStreamListener)57*b1cdbd2cSJim Jagielski static void callStarted(Reference<XStreamListener> xStreamListener) 58*b1cdbd2cSJim Jagielski { 59*b1cdbd2cSJim Jagielski xStreamListener->started(); 60*b1cdbd2cSJim Jagielski } 61*b1cdbd2cSJim Jagielski 62*b1cdbd2cSJim Jagielski struct callError { 63*b1cdbd2cSJim Jagielski const Any & any; 64*b1cdbd2cSJim Jagielski 65*b1cdbd2cSJim Jagielski callError(const Any & any); 66*b1cdbd2cSJim Jagielski 67*b1cdbd2cSJim Jagielski void operator () (Reference<XStreamListener> xStreamListener); 68*b1cdbd2cSJim Jagielski }; 69*b1cdbd2cSJim Jagielski callError(const Any & aAny)70*b1cdbd2cSJim Jagielski callError::callError(const Any & aAny) 71*b1cdbd2cSJim Jagielski : any(aAny) 72*b1cdbd2cSJim Jagielski { 73*b1cdbd2cSJim Jagielski } 74*b1cdbd2cSJim Jagielski operator ()(Reference<XStreamListener> xStreamListener)75*b1cdbd2cSJim Jagielski void callError::operator () (Reference<XStreamListener> xStreamListener) 76*b1cdbd2cSJim Jagielski { 77*b1cdbd2cSJim Jagielski xStreamListener->error(any); 78*b1cdbd2cSJim Jagielski } 79*b1cdbd2cSJim Jagielski callClosed(Reference<XStreamListener> xStreamListener)80*b1cdbd2cSJim Jagielski static void callClosed(Reference<XStreamListener> xStreamListener) 81*b1cdbd2cSJim Jagielski { 82*b1cdbd2cSJim Jagielski xStreamListener->closed(); 83*b1cdbd2cSJim Jagielski } 84*b1cdbd2cSJim Jagielski 85*b1cdbd2cSJim Jagielski SocketConnection(const OUString & sConnectionDescription)86*b1cdbd2cSJim Jagielski SocketConnection::SocketConnection( const OUString &sConnectionDescription ) : 87*b1cdbd2cSJim Jagielski m_nStatus( 0 ), 88*b1cdbd2cSJim Jagielski m_sDescription( sConnectionDescription ), 89*b1cdbd2cSJim Jagielski _started(sal_False), 90*b1cdbd2cSJim Jagielski _closed(sal_False), 91*b1cdbd2cSJim Jagielski _error(sal_False) 92*b1cdbd2cSJim Jagielski { 93*b1cdbd2cSJim Jagielski // make it unique 94*b1cdbd2cSJim Jagielski g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); 95*b1cdbd2cSJim Jagielski m_sDescription += OUString( RTL_CONSTASCII_USTRINGPARAM( ",uniqueValue=" ) ); 96*b1cdbd2cSJim Jagielski m_sDescription += OUString::valueOf( 97*b1cdbd2cSJim Jagielski sal::static_int_cast< sal_Int64 >( 98*b1cdbd2cSJim Jagielski reinterpret_cast< sal_IntPtr >(&m_socket)), 99*b1cdbd2cSJim Jagielski 10 ); 100*b1cdbd2cSJim Jagielski } 101*b1cdbd2cSJim Jagielski ~SocketConnection()102*b1cdbd2cSJim Jagielski SocketConnection::~SocketConnection() 103*b1cdbd2cSJim Jagielski { 104*b1cdbd2cSJim Jagielski g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); 105*b1cdbd2cSJim Jagielski } 106*b1cdbd2cSJim Jagielski completeConnectionString()107*b1cdbd2cSJim Jagielski void SocketConnection::completeConnectionString() 108*b1cdbd2cSJim Jagielski { 109*b1cdbd2cSJim Jagielski sal_Int32 nPort; 110*b1cdbd2cSJim Jagielski 111*b1cdbd2cSJim Jagielski nPort = m_socket.getPeerPort(); 112*b1cdbd2cSJim Jagielski 113*b1cdbd2cSJim Jagielski OUStringBuffer buf( 256 ); 114*b1cdbd2cSJim Jagielski buf.appendAscii( ",peerPort=" ); 115*b1cdbd2cSJim Jagielski buf.append( (sal_Int32) nPort ); 116*b1cdbd2cSJim Jagielski buf.appendAscii( ",peerHost=" ); 117*b1cdbd2cSJim Jagielski buf.append( m_socket.getPeerHost() ); 118*b1cdbd2cSJim Jagielski 119*b1cdbd2cSJim Jagielski buf.appendAscii( ",localPort=" ); 120*b1cdbd2cSJim Jagielski buf.append( (sal_Int32) nPort ); 121*b1cdbd2cSJim Jagielski buf.appendAscii( ",localHost=" ); 122*b1cdbd2cSJim Jagielski buf.append( m_socket.getLocalHost( ) ); 123*b1cdbd2cSJim Jagielski 124*b1cdbd2cSJim Jagielski m_sDescription += buf.makeStringAndClear(); 125*b1cdbd2cSJim Jagielski } 126*b1cdbd2cSJim Jagielski read(Sequence<sal_Int8> & aReadBytes,sal_Int32 nBytesToRead)127*b1cdbd2cSJim Jagielski sal_Int32 SocketConnection::read( Sequence < sal_Int8 > & aReadBytes , sal_Int32 nBytesToRead ) 128*b1cdbd2cSJim Jagielski throw(::com::sun::star::io::IOException, 129*b1cdbd2cSJim Jagielski ::com::sun::star::uno::RuntimeException) 130*b1cdbd2cSJim Jagielski { 131*b1cdbd2cSJim Jagielski if( ! m_nStatus ) 132*b1cdbd2cSJim Jagielski { 133*b1cdbd2cSJim Jagielski notifyListeners(this, &_started, callStarted); 134*b1cdbd2cSJim Jagielski 135*b1cdbd2cSJim Jagielski if( aReadBytes.getLength() != nBytesToRead ) 136*b1cdbd2cSJim Jagielski { 137*b1cdbd2cSJim Jagielski aReadBytes.realloc( nBytesToRead ); 138*b1cdbd2cSJim Jagielski } 139*b1cdbd2cSJim Jagielski sal_Int32 i = m_socket.read( aReadBytes.getArray() , aReadBytes.getLength() ); 140*b1cdbd2cSJim Jagielski 141*b1cdbd2cSJim Jagielski if(i != nBytesToRead && m_socket.getError() != osl_Socket_E_None) 142*b1cdbd2cSJim Jagielski { 143*b1cdbd2cSJim Jagielski OUString message(RTL_CONSTASCII_USTRINGPARAM("ctr_socket.cxx:SocketConnection::read: error - ")); 144*b1cdbd2cSJim Jagielski message += m_socket.getErrorAsString(); 145*b1cdbd2cSJim Jagielski 146*b1cdbd2cSJim Jagielski IOException ioException(message, Reference<XInterface>(static_cast<XConnection *>(this))); 147*b1cdbd2cSJim Jagielski 148*b1cdbd2cSJim Jagielski Any any; 149*b1cdbd2cSJim Jagielski any <<= ioException; 150*b1cdbd2cSJim Jagielski 151*b1cdbd2cSJim Jagielski notifyListeners(this, &_error, callError(any)); 152*b1cdbd2cSJim Jagielski 153*b1cdbd2cSJim Jagielski throw ioException; 154*b1cdbd2cSJim Jagielski } 155*b1cdbd2cSJim Jagielski 156*b1cdbd2cSJim Jagielski return i; 157*b1cdbd2cSJim Jagielski } 158*b1cdbd2cSJim Jagielski else 159*b1cdbd2cSJim Jagielski { 160*b1cdbd2cSJim Jagielski OUString message(RTL_CONSTASCII_USTRINGPARAM("ctr_socket.cxx:SocketConnection::read: error - connection already closed")); 161*b1cdbd2cSJim Jagielski 162*b1cdbd2cSJim Jagielski IOException ioException(message, Reference<XInterface>(static_cast<XConnection *>(this))); 163*b1cdbd2cSJim Jagielski 164*b1cdbd2cSJim Jagielski Any any; 165*b1cdbd2cSJim Jagielski any <<= ioException; 166*b1cdbd2cSJim Jagielski 167*b1cdbd2cSJim Jagielski notifyListeners(this, &_error, callError(any)); 168*b1cdbd2cSJim Jagielski 169*b1cdbd2cSJim Jagielski throw ioException; 170*b1cdbd2cSJim Jagielski } 171*b1cdbd2cSJim Jagielski } 172*b1cdbd2cSJim Jagielski write(const Sequence<sal_Int8> & seq)173*b1cdbd2cSJim Jagielski void SocketConnection::write( const Sequence < sal_Int8 > &seq ) 174*b1cdbd2cSJim Jagielski throw(::com::sun::star::io::IOException, 175*b1cdbd2cSJim Jagielski ::com::sun::star::uno::RuntimeException) 176*b1cdbd2cSJim Jagielski { 177*b1cdbd2cSJim Jagielski if( ! m_nStatus ) 178*b1cdbd2cSJim Jagielski { 179*b1cdbd2cSJim Jagielski if( m_socket.write( seq.getConstArray() , seq.getLength() ) != seq.getLength() ) 180*b1cdbd2cSJim Jagielski { 181*b1cdbd2cSJim Jagielski OUString message(RTL_CONSTASCII_USTRINGPARAM("ctr_socket.cxx:SocketConnection::write: error - ")); 182*b1cdbd2cSJim Jagielski message += m_socket.getErrorAsString(); 183*b1cdbd2cSJim Jagielski 184*b1cdbd2cSJim Jagielski IOException ioException(message, Reference<XInterface>(static_cast<XConnection *>(this))); 185*b1cdbd2cSJim Jagielski 186*b1cdbd2cSJim Jagielski Any any; 187*b1cdbd2cSJim Jagielski any <<= ioException; 188*b1cdbd2cSJim Jagielski 189*b1cdbd2cSJim Jagielski notifyListeners(this, &_error, callError(any)); 190*b1cdbd2cSJim Jagielski 191*b1cdbd2cSJim Jagielski throw ioException; 192*b1cdbd2cSJim Jagielski } 193*b1cdbd2cSJim Jagielski } 194*b1cdbd2cSJim Jagielski else 195*b1cdbd2cSJim Jagielski { 196*b1cdbd2cSJim Jagielski OUString message(RTL_CONSTASCII_USTRINGPARAM("ctr_socket.cxx:SocketConnection::write: error - connection already closed")); 197*b1cdbd2cSJim Jagielski 198*b1cdbd2cSJim Jagielski IOException ioException(message, Reference<XInterface>(static_cast<XConnection *>(this))); 199*b1cdbd2cSJim Jagielski 200*b1cdbd2cSJim Jagielski Any any; 201*b1cdbd2cSJim Jagielski any <<= ioException; 202*b1cdbd2cSJim Jagielski 203*b1cdbd2cSJim Jagielski notifyListeners(this, &_error, callError(any)); 204*b1cdbd2cSJim Jagielski 205*b1cdbd2cSJim Jagielski throw ioException; 206*b1cdbd2cSJim Jagielski } 207*b1cdbd2cSJim Jagielski } 208*b1cdbd2cSJim Jagielski flush()209*b1cdbd2cSJim Jagielski void SocketConnection::flush( ) 210*b1cdbd2cSJim Jagielski throw(::com::sun::star::io::IOException, 211*b1cdbd2cSJim Jagielski ::com::sun::star::uno::RuntimeException) 212*b1cdbd2cSJim Jagielski { 213*b1cdbd2cSJim Jagielski 214*b1cdbd2cSJim Jagielski } 215*b1cdbd2cSJim Jagielski close()216*b1cdbd2cSJim Jagielski void SocketConnection::close() 217*b1cdbd2cSJim Jagielski throw(::com::sun::star::io::IOException, 218*b1cdbd2cSJim Jagielski ::com::sun::star::uno::RuntimeException) 219*b1cdbd2cSJim Jagielski { 220*b1cdbd2cSJim Jagielski // ensure that close is called only once 221*b1cdbd2cSJim Jagielski if( 1 == osl_incrementInterlockedCount( (&m_nStatus) ) ) 222*b1cdbd2cSJim Jagielski { 223*b1cdbd2cSJim Jagielski m_socket.shutdown(); 224*b1cdbd2cSJim Jagielski notifyListeners(this, &_closed, callClosed); 225*b1cdbd2cSJim Jagielski } 226*b1cdbd2cSJim Jagielski } 227*b1cdbd2cSJim Jagielski getDescription()228*b1cdbd2cSJim Jagielski OUString SocketConnection::getDescription() 229*b1cdbd2cSJim Jagielski throw( ::com::sun::star::uno::RuntimeException) 230*b1cdbd2cSJim Jagielski { 231*b1cdbd2cSJim Jagielski return m_sDescription; 232*b1cdbd2cSJim Jagielski } 233*b1cdbd2cSJim Jagielski 234*b1cdbd2cSJim Jagielski 235*b1cdbd2cSJim Jagielski 236*b1cdbd2cSJim Jagielski // XConnectionBroadcaster addStreamListener(const Reference<XStreamListener> & aListener)237*b1cdbd2cSJim Jagielski void SAL_CALL SocketConnection::addStreamListener(const Reference<XStreamListener> & aListener) throw(RuntimeException) 238*b1cdbd2cSJim Jagielski { 239*b1cdbd2cSJim Jagielski MutexGuard guard(_mutex); 240*b1cdbd2cSJim Jagielski 241*b1cdbd2cSJim Jagielski _listeners.insert(aListener); 242*b1cdbd2cSJim Jagielski } 243*b1cdbd2cSJim Jagielski removeStreamListener(const Reference<XStreamListener> & aListener)244*b1cdbd2cSJim Jagielski void SAL_CALL SocketConnection::removeStreamListener(const Reference<XStreamListener> & aListener) throw(RuntimeException) 245*b1cdbd2cSJim Jagielski { 246*b1cdbd2cSJim Jagielski MutexGuard guard(_mutex); 247*b1cdbd2cSJim Jagielski 248*b1cdbd2cSJim Jagielski _listeners.erase(aListener); 249*b1cdbd2cSJim Jagielski } 250*b1cdbd2cSJim Jagielski } 251*b1cdbd2cSJim Jagielski 252