1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_io.hxx" 30 #include "osl/security.hxx" 31 #include "acceptor.hxx" 32 #include <com/sun/star/connection/ConnectionSetupException.hpp> 33 34 #include <cppuhelper/implbase1.hxx> 35 36 using namespace ::rtl; 37 using namespace ::osl; 38 using namespace ::cppu; 39 using namespace ::com::sun::star::uno; 40 using namespace ::com::sun::star::lang; 41 using namespace ::com::sun::star::connection; 42 using namespace ::com::sun::star::io; 43 44 45 namespace io_acceptor 46 { 47 48 typedef WeakImplHelper1< XConnection > MyPipeConnection; 49 50 class PipeConnection : 51 public MyPipeConnection 52 { 53 public: 54 PipeConnection( const OUString &sConnectionDescription); 55 ~PipeConnection(); 56 57 virtual sal_Int32 SAL_CALL read( Sequence< sal_Int8 >& aReadBytes, sal_Int32 nBytesToRead ) 58 throw(::com::sun::star::io::IOException, 59 ::com::sun::star::uno::RuntimeException); 60 virtual void SAL_CALL write( const Sequence< sal_Int8 >& aData ) 61 throw(::com::sun::star::io::IOException, 62 ::com::sun::star::uno::RuntimeException); 63 virtual void SAL_CALL flush( ) throw( 64 ::com::sun::star::io::IOException, 65 ::com::sun::star::uno::RuntimeException); 66 virtual void SAL_CALL close( ) 67 throw(::com::sun::star::io::IOException, 68 ::com::sun::star::uno::RuntimeException); 69 virtual ::rtl::OUString SAL_CALL getDescription( ) 70 throw(::com::sun::star::uno::RuntimeException); 71 public: 72 ::osl::StreamPipe m_pipe; 73 oslInterlockedCount m_nStatus; 74 OUString m_sDescription; 75 }; 76 77 78 79 PipeConnection::PipeConnection( const OUString &sConnectionDescription) : 80 m_nStatus( 0 ), 81 m_sDescription( sConnectionDescription ) 82 { 83 g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); 84 85 // make it unique 86 m_sDescription += OUString::createFromAscii( ",uniqueValue=" ); 87 m_sDescription += OUString::valueOf( 88 sal::static_int_cast<sal_Int64 >( 89 reinterpret_cast< sal_IntPtr >(&m_pipe)), 90 10 ); 91 } 92 93 PipeConnection::~PipeConnection() 94 { 95 g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); 96 } 97 98 sal_Int32 PipeConnection::read( Sequence < sal_Int8 > & aReadBytes , sal_Int32 nBytesToRead ) 99 throw(::com::sun::star::io::IOException, 100 ::com::sun::star::uno::RuntimeException) 101 { 102 if( ! m_nStatus ) 103 { 104 if( aReadBytes.getLength() < nBytesToRead ) 105 { 106 aReadBytes.realloc( nBytesToRead ); 107 } 108 sal_Int32 n = m_pipe.read( aReadBytes.getArray(), nBytesToRead ); 109 OSL_ASSERT( n >= 0 && n <= aReadBytes.getLength() ); 110 if( n < aReadBytes.getLength() ) 111 { 112 aReadBytes.realloc( n ); 113 } 114 return n; 115 } 116 else { 117 throw IOException(); 118 } 119 } 120 121 void PipeConnection::write( const Sequence < sal_Int8 > &seq ) 122 throw(::com::sun::star::io::IOException, 123 ::com::sun::star::uno::RuntimeException) 124 { 125 if( ! m_nStatus ) 126 { 127 if( m_pipe.write( seq.getConstArray() , seq.getLength() ) != seq.getLength() ) 128 { 129 throw IOException(); 130 } 131 } 132 else { 133 throw IOException(); 134 } 135 } 136 137 void PipeConnection::flush( ) 138 throw( ::com::sun::star::io::IOException, 139 ::com::sun::star::uno::RuntimeException) 140 { 141 } 142 143 void PipeConnection::close() 144 throw( ::com::sun::star::io::IOException, 145 ::com::sun::star::uno::RuntimeException) 146 { 147 if( 1 == osl_incrementInterlockedCount( (&m_nStatus) ) ) 148 { 149 m_pipe.close(); 150 } 151 } 152 153 OUString PipeConnection::getDescription() 154 throw(::com::sun::star::uno::RuntimeException) 155 { 156 return m_sDescription; 157 } 158 159 /*************** 160 * PipeAcceptor 161 **************/ 162 PipeAcceptor::PipeAcceptor( const OUString &sPipeName , const OUString & sConnectionDescription) : 163 m_sPipeName( sPipeName ), 164 m_sConnectionDescription( sConnectionDescription ), 165 m_bClosed( sal_False ) 166 { 167 } 168 169 170 void PipeAcceptor::init() 171 { 172 m_pipe = Pipe( m_sPipeName.pData , osl_Pipe_CREATE , osl::Security() ); 173 if( ! m_pipe.is() ) 174 { 175 OUString error = OUString::createFromAscii( "io.acceptor: Couldn't setup pipe " ); 176 error += m_sPipeName; 177 throw ConnectionSetupException( error, Reference< XInterface > () ); 178 } 179 } 180 181 Reference< XConnection > PipeAcceptor::accept( ) 182 { 183 Pipe pipe; 184 { 185 MutexGuard guard( m_mutex ); 186 pipe = m_pipe; 187 } 188 if( ! pipe.is() ) 189 { 190 OUString error = OUString::createFromAscii( "io.acceptor: pipe already closed" ); 191 error += m_sPipeName; 192 throw ConnectionSetupException( error, Reference< XInterface > () ); 193 } 194 PipeConnection *pConn = new PipeConnection( m_sConnectionDescription ); 195 196 oslPipeError status = pipe.accept( pConn->m_pipe ); 197 198 if( m_bClosed ) 199 { 200 // stopAccepting was called ! 201 delete pConn; 202 return Reference < XConnection >(); 203 } 204 else if( osl_Pipe_E_None == status ) 205 { 206 return Reference < XConnection > ( (XConnection * ) pConn ); 207 } 208 else 209 { 210 OUString error = OUString::createFromAscii( "io.acceptor: Couldn't setup pipe " ); 211 error += m_sPipeName; 212 throw ConnectionSetupException( error, Reference< XInterface > ()); 213 } 214 } 215 216 void PipeAcceptor::stopAccepting() 217 { 218 m_bClosed = sal_True; 219 Pipe pipe; 220 { 221 MutexGuard guard( m_mutex ); 222 pipe = m_pipe; 223 m_pipe.clear(); 224 } 225 if( pipe.is() ) 226 { 227 pipe.close(); 228 } 229 } 230 } 231