1*3716f815SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*3716f815SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*3716f815SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*3716f815SAndrew Rist * distributed with this work for additional information 6*3716f815SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*3716f815SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*3716f815SAndrew Rist * "License"); you may not use this file except in compliance 9*3716f815SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*3716f815SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*3716f815SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*3716f815SAndrew Rist * software distributed under the License is distributed on an 15*3716f815SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*3716f815SAndrew Rist * KIND, either express or implied. See the License for the 17*3716f815SAndrew Rist * specific language governing permissions and limitations 18*3716f815SAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*3716f815SAndrew Rist *************************************************************/ 21*3716f815SAndrew Rist 22*3716f815SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_io.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include <map> 28cdf0e10cSrcweir #include <vector> 29cdf0e10cSrcweir 30cdf0e10cSrcweir #include <com/sun/star/io/XMarkableStream.hpp> 31cdf0e10cSrcweir #include <com/sun/star/io/XOutputStream.hpp> 32cdf0e10cSrcweir #include <com/sun/star/io/XInputStream.hpp> 33cdf0e10cSrcweir #include <com/sun/star/io/XActiveDataSource.hpp> 34cdf0e10cSrcweir #include <com/sun/star/io/XActiveDataSink.hpp> 35cdf0e10cSrcweir #include <com/sun/star/io/XConnectable.hpp> 36cdf0e10cSrcweir #include <com/sun/star/lang/XServiceInfo.hpp> 37cdf0e10cSrcweir 38cdf0e10cSrcweir #include <cppuhelper/factory.hxx> 39cdf0e10cSrcweir #include <cppuhelper/weak.hxx> // OWeakObject 40cdf0e10cSrcweir #include <cppuhelper/implbase5.hxx> 41cdf0e10cSrcweir 42cdf0e10cSrcweir #include <osl/mutex.hxx> 43cdf0e10cSrcweir #include <rtl/ustrbuf.hxx> 44cdf0e10cSrcweir 45cdf0e10cSrcweir #include <string.h> 46cdf0e10cSrcweir 47cdf0e10cSrcweir 48cdf0e10cSrcweir using namespace ::std; 49cdf0e10cSrcweir using namespace ::rtl; 50cdf0e10cSrcweir using namespace ::cppu; 51cdf0e10cSrcweir using namespace ::osl; 52cdf0e10cSrcweir using namespace ::com::sun::star::io; 53cdf0e10cSrcweir using namespace ::com::sun::star::uno; 54cdf0e10cSrcweir using namespace ::com::sun::star::lang; 55cdf0e10cSrcweir 56cdf0e10cSrcweir #include "streamhelper.hxx" 57cdf0e10cSrcweir #include "factreg.hxx" 58cdf0e10cSrcweir 59cdf0e10cSrcweir namespace io_stm { 60cdf0e10cSrcweir 61cdf0e10cSrcweir /*********************** 62cdf0e10cSrcweir * 63cdf0e10cSrcweir * OMarkableOutputStream. 64cdf0e10cSrcweir * 65cdf0e10cSrcweir * This object allows to set marks in an outputstream. It is allowed to jump back to the marks and 66cdf0e10cSrcweir * rewrite the some bytes. 67cdf0e10cSrcweir * 68cdf0e10cSrcweir * The object must buffer the data since the last mark set. Flush will not 69cdf0e10cSrcweir * have any effect. As soon as the last mark has been removed, the object may write the data 70cdf0e10cSrcweir * through to the chained object. 71cdf0e10cSrcweir * 72cdf0e10cSrcweir **********************/ 73cdf0e10cSrcweir class OMarkableOutputStream : 74cdf0e10cSrcweir public WeakImplHelper5< XOutputStream , 75cdf0e10cSrcweir XActiveDataSource , 76cdf0e10cSrcweir XMarkableStream , 77cdf0e10cSrcweir XConnectable, 78cdf0e10cSrcweir XServiceInfo 79cdf0e10cSrcweir > 80cdf0e10cSrcweir { 81cdf0e10cSrcweir public: 82cdf0e10cSrcweir OMarkableOutputStream( ); 83cdf0e10cSrcweir ~OMarkableOutputStream(); 84cdf0e10cSrcweir 85cdf0e10cSrcweir public: // XOutputStream 86cdf0e10cSrcweir virtual void SAL_CALL writeBytes(const Sequence< sal_Int8 >& aData) 87cdf0e10cSrcweir throw ( NotConnectedException, 88cdf0e10cSrcweir BufferSizeExceededException, 89cdf0e10cSrcweir RuntimeException); 90cdf0e10cSrcweir virtual void SAL_CALL flush(void) 91cdf0e10cSrcweir throw ( NotConnectedException, 92cdf0e10cSrcweir BufferSizeExceededException, 93cdf0e10cSrcweir RuntimeException); 94cdf0e10cSrcweir virtual void SAL_CALL closeOutput(void) 95cdf0e10cSrcweir throw ( NotConnectedException, 96cdf0e10cSrcweir BufferSizeExceededException, 97cdf0e10cSrcweir RuntimeException); 98cdf0e10cSrcweir 99cdf0e10cSrcweir public: // XMarkable 100cdf0e10cSrcweir virtual sal_Int32 SAL_CALL createMark(void) 101cdf0e10cSrcweir throw (IOException, RuntimeException); 102cdf0e10cSrcweir virtual void SAL_CALL deleteMark(sal_Int32 Mark) 103cdf0e10cSrcweir throw (IOException, 104cdf0e10cSrcweir IllegalArgumentException, 105cdf0e10cSrcweir RuntimeException); 106cdf0e10cSrcweir virtual void SAL_CALL jumpToMark(sal_Int32 nMark) 107cdf0e10cSrcweir throw (IOException, 108cdf0e10cSrcweir IllegalArgumentException, 109cdf0e10cSrcweir RuntimeException); 110cdf0e10cSrcweir virtual void SAL_CALL jumpToFurthest(void) 111cdf0e10cSrcweir throw (IOException, RuntimeException); 112cdf0e10cSrcweir virtual sal_Int32 SAL_CALL offsetToMark(sal_Int32 nMark) 113cdf0e10cSrcweir throw (IOException, 114cdf0e10cSrcweir IllegalArgumentException, 115cdf0e10cSrcweir RuntimeException); 116cdf0e10cSrcweir 117cdf0e10cSrcweir public: // XActiveDataSource 118cdf0e10cSrcweir virtual void SAL_CALL setOutputStream(const Reference < XOutputStream > & aStream) 119cdf0e10cSrcweir throw (RuntimeException); 120cdf0e10cSrcweir virtual Reference < XOutputStream > SAL_CALL getOutputStream(void) 121cdf0e10cSrcweir throw (RuntimeException); 122cdf0e10cSrcweir 123cdf0e10cSrcweir public: // XConnectable 124cdf0e10cSrcweir virtual void SAL_CALL setPredecessor(const Reference < XConnectable > & aPredecessor) 125cdf0e10cSrcweir throw (RuntimeException); 126cdf0e10cSrcweir virtual Reference < XConnectable > SAL_CALL getPredecessor(void) throw (RuntimeException); 127cdf0e10cSrcweir virtual void SAL_CALL setSuccessor(const Reference < XConnectable >& aSuccessor) 128cdf0e10cSrcweir throw (RuntimeException); 129cdf0e10cSrcweir virtual Reference< XConnectable > SAL_CALL getSuccessor(void) throw (RuntimeException); 130cdf0e10cSrcweir 131cdf0e10cSrcweir public: // XServiceInfo 132cdf0e10cSrcweir OUString SAL_CALL getImplementationName() throw (); 133cdf0e10cSrcweir Sequence< OUString > SAL_CALL getSupportedServiceNames(void) throw (); 134cdf0e10cSrcweir sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw (); 135cdf0e10cSrcweir 136cdf0e10cSrcweir private: 137cdf0e10cSrcweir // helper methods 138cdf0e10cSrcweir void checkMarksAndFlush() throw( NotConnectedException, BufferSizeExceededException); 139cdf0e10cSrcweir 140cdf0e10cSrcweir Reference< XConnectable > m_succ; 141cdf0e10cSrcweir Reference< XConnectable > m_pred; 142cdf0e10cSrcweir 143cdf0e10cSrcweir Reference< XOutputStream > m_output; 144cdf0e10cSrcweir sal_Bool m_bValidStream; 145cdf0e10cSrcweir 146cdf0e10cSrcweir IRingBuffer *m_pBuffer; 147cdf0e10cSrcweir map<sal_Int32,sal_Int32,less< sal_Int32 > > m_mapMarks; 148cdf0e10cSrcweir sal_Int32 m_nCurrentPos; 149cdf0e10cSrcweir sal_Int32 m_nCurrentMark; 150cdf0e10cSrcweir 151cdf0e10cSrcweir Mutex m_mutex; 152cdf0e10cSrcweir }; 153cdf0e10cSrcweir 154cdf0e10cSrcweir OMarkableOutputStream::OMarkableOutputStream( ) 155cdf0e10cSrcweir { 156cdf0e10cSrcweir g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); 157cdf0e10cSrcweir m_pBuffer = new MemRingBuffer; 158cdf0e10cSrcweir m_nCurrentPos = 0; 159cdf0e10cSrcweir m_nCurrentMark = 0; 160cdf0e10cSrcweir } 161cdf0e10cSrcweir 162cdf0e10cSrcweir OMarkableOutputStream::~OMarkableOutputStream() 163cdf0e10cSrcweir { 164cdf0e10cSrcweir delete m_pBuffer; 165cdf0e10cSrcweir g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); 166cdf0e10cSrcweir } 167cdf0e10cSrcweir 168cdf0e10cSrcweir 169cdf0e10cSrcweir // XOutputStream 170cdf0e10cSrcweir void OMarkableOutputStream::writeBytes(const Sequence< sal_Int8 >& aData) 171cdf0e10cSrcweir throw ( NotConnectedException, 172cdf0e10cSrcweir BufferSizeExceededException, 173cdf0e10cSrcweir RuntimeException) 174cdf0e10cSrcweir { 175cdf0e10cSrcweir if( m_bValidStream ) { 176cdf0e10cSrcweir if( m_mapMarks.empty() && ( m_pBuffer->getSize() == 0 ) ) { 177cdf0e10cSrcweir // no mark and buffer active, simple write through 178cdf0e10cSrcweir m_output->writeBytes( aData ); 179cdf0e10cSrcweir } 180cdf0e10cSrcweir else { 181cdf0e10cSrcweir MutexGuard guard( m_mutex ); 182cdf0e10cSrcweir // new data must be buffered 183cdf0e10cSrcweir try 184cdf0e10cSrcweir { 185cdf0e10cSrcweir m_pBuffer->writeAt( m_nCurrentPos , aData ); 186cdf0e10cSrcweir m_nCurrentPos += aData.getLength(); 187cdf0e10cSrcweir } 188cdf0e10cSrcweir catch( IRingBuffer_OutOfBoundsException & ) 189cdf0e10cSrcweir { 190cdf0e10cSrcweir throw BufferSizeExceededException(); 191cdf0e10cSrcweir } 192cdf0e10cSrcweir catch( IRingBuffer_OutOfMemoryException & ) 193cdf0e10cSrcweir { 194cdf0e10cSrcweir throw BufferSizeExceededException(); 195cdf0e10cSrcweir } 196cdf0e10cSrcweir checkMarksAndFlush(); 197cdf0e10cSrcweir } 198cdf0e10cSrcweir } 199cdf0e10cSrcweir else { 200cdf0e10cSrcweir throw NotConnectedException(); 201cdf0e10cSrcweir } 202cdf0e10cSrcweir } 203cdf0e10cSrcweir 204cdf0e10cSrcweir void OMarkableOutputStream::flush(void) 205cdf0e10cSrcweir throw ( NotConnectedException, 206cdf0e10cSrcweir BufferSizeExceededException, 207cdf0e10cSrcweir RuntimeException) 208cdf0e10cSrcweir { 209cdf0e10cSrcweir Reference< XOutputStream > output; 210cdf0e10cSrcweir { 211cdf0e10cSrcweir MutexGuard guard( m_mutex ); 212cdf0e10cSrcweir output = m_output; 213cdf0e10cSrcweir } 214cdf0e10cSrcweir 215cdf0e10cSrcweir // Markable cannot flush buffered data, because the data may get rewritten, 216cdf0e10cSrcweir // however one can forward the flush to the chained stream to give it 217cdf0e10cSrcweir // a chance to write data buffered in the chained stream. 218cdf0e10cSrcweir if( output.is() ) 219cdf0e10cSrcweir { 220cdf0e10cSrcweir output->flush(); 221cdf0e10cSrcweir } 222cdf0e10cSrcweir } 223cdf0e10cSrcweir 224cdf0e10cSrcweir void OMarkableOutputStream::closeOutput(void) 225cdf0e10cSrcweir throw ( NotConnectedException, 226cdf0e10cSrcweir BufferSizeExceededException, 227cdf0e10cSrcweir RuntimeException) 228cdf0e10cSrcweir { 229cdf0e10cSrcweir if( m_bValidStream ) { 230cdf0e10cSrcweir MutexGuard guard( m_mutex ); 231cdf0e10cSrcweir // all marks must be cleared and all 232cdf0e10cSrcweir 233cdf0e10cSrcweir if( ! m_mapMarks.empty() ) 234cdf0e10cSrcweir { 235cdf0e10cSrcweir m_mapMarks.clear(); 236cdf0e10cSrcweir } 237cdf0e10cSrcweir m_nCurrentPos = m_pBuffer->getSize(); 238cdf0e10cSrcweir checkMarksAndFlush(); 239cdf0e10cSrcweir 240cdf0e10cSrcweir m_output->closeOutput(); 241cdf0e10cSrcweir 242cdf0e10cSrcweir setOutputStream( Reference< XOutputStream > () ); 243cdf0e10cSrcweir setPredecessor( Reference < XConnectable >() ); 244cdf0e10cSrcweir setSuccessor( Reference< XConnectable > () ); 245cdf0e10cSrcweir } 246cdf0e10cSrcweir else { 247cdf0e10cSrcweir throw NotConnectedException(); 248cdf0e10cSrcweir } 249cdf0e10cSrcweir } 250cdf0e10cSrcweir 251cdf0e10cSrcweir 252cdf0e10cSrcweir sal_Int32 OMarkableOutputStream::createMark(void) 253cdf0e10cSrcweir throw ( IOException, 254cdf0e10cSrcweir RuntimeException) 255cdf0e10cSrcweir { 256cdf0e10cSrcweir MutexGuard guard( m_mutex ); 257cdf0e10cSrcweir sal_Int32 nMark = m_nCurrentMark; 258cdf0e10cSrcweir 259cdf0e10cSrcweir m_mapMarks[nMark] = m_nCurrentPos; 260cdf0e10cSrcweir 261cdf0e10cSrcweir m_nCurrentMark ++; 262cdf0e10cSrcweir return nMark; 263cdf0e10cSrcweir } 264cdf0e10cSrcweir 265cdf0e10cSrcweir void OMarkableOutputStream::deleteMark(sal_Int32 Mark) 266cdf0e10cSrcweir throw( IOException, 267cdf0e10cSrcweir IllegalArgumentException, 268cdf0e10cSrcweir RuntimeException) 269cdf0e10cSrcweir { 270cdf0e10cSrcweir MutexGuard guard( m_mutex ); 271cdf0e10cSrcweir map<sal_Int32,sal_Int32,less<sal_Int32> >::iterator ii = m_mapMarks.find( Mark ); 272cdf0e10cSrcweir 273cdf0e10cSrcweir if( ii == m_mapMarks.end() ) { 274cdf0e10cSrcweir OUStringBuffer buf( 128 ); 275cdf0e10cSrcweir buf.appendAscii( "MarkableOutputStream::deleteMark unknown mark (" ); 276cdf0e10cSrcweir buf.append( Mark ); 277cdf0e10cSrcweir buf.appendAscii( ")"); 278cdf0e10cSrcweir throw IllegalArgumentException( buf.makeStringAndClear(), *this, 0); 279cdf0e10cSrcweir } 280cdf0e10cSrcweir else { 281cdf0e10cSrcweir m_mapMarks.erase( ii ); 282cdf0e10cSrcweir checkMarksAndFlush(); 283cdf0e10cSrcweir } 284cdf0e10cSrcweir } 285cdf0e10cSrcweir 286cdf0e10cSrcweir void OMarkableOutputStream::jumpToMark(sal_Int32 nMark) 287cdf0e10cSrcweir throw (IOException, 288cdf0e10cSrcweir IllegalArgumentException, 289cdf0e10cSrcweir RuntimeException) 290cdf0e10cSrcweir { 291cdf0e10cSrcweir MutexGuard guard( m_mutex ); 292cdf0e10cSrcweir map<sal_Int32,sal_Int32,less<sal_Int32> >::iterator ii = m_mapMarks.find( nMark ); 293cdf0e10cSrcweir 294cdf0e10cSrcweir if( ii == m_mapMarks.end() ) { 295cdf0e10cSrcweir OUStringBuffer buf( 128 ); 296cdf0e10cSrcweir buf.appendAscii( "MarkableOutputStream::jumpToMark unknown mark (" ); 297cdf0e10cSrcweir buf.append( nMark ); 298cdf0e10cSrcweir buf.appendAscii( ")"); 299cdf0e10cSrcweir throw IllegalArgumentException( buf.makeStringAndClear(), *this, 0); 300cdf0e10cSrcweir } 301cdf0e10cSrcweir else { 302cdf0e10cSrcweir m_nCurrentPos = (*ii).second; 303cdf0e10cSrcweir } 304cdf0e10cSrcweir } 305cdf0e10cSrcweir 306cdf0e10cSrcweir void OMarkableOutputStream::jumpToFurthest(void) 307cdf0e10cSrcweir throw (IOException, 308cdf0e10cSrcweir RuntimeException) 309cdf0e10cSrcweir { 310cdf0e10cSrcweir MutexGuard guard( m_mutex ); 311cdf0e10cSrcweir m_nCurrentPos = m_pBuffer->getSize(); 312cdf0e10cSrcweir checkMarksAndFlush(); 313cdf0e10cSrcweir } 314cdf0e10cSrcweir 315cdf0e10cSrcweir sal_Int32 OMarkableOutputStream::offsetToMark(sal_Int32 nMark) 316cdf0e10cSrcweir throw (IOException, 317cdf0e10cSrcweir IllegalArgumentException, 318cdf0e10cSrcweir RuntimeException) 319cdf0e10cSrcweir { 320cdf0e10cSrcweir 321cdf0e10cSrcweir MutexGuard guard( m_mutex ); 322cdf0e10cSrcweir map<sal_Int32,sal_Int32,less<sal_Int32> >::const_iterator ii = m_mapMarks.find( nMark ); 323cdf0e10cSrcweir 324cdf0e10cSrcweir if( ii == m_mapMarks.end() ) 325cdf0e10cSrcweir { 326cdf0e10cSrcweir OUStringBuffer buf( 128 ); 327cdf0e10cSrcweir buf.appendAscii( "MarkableOutputStream::offsetToMark unknown mark (" ); 328cdf0e10cSrcweir buf.append( nMark ); 329cdf0e10cSrcweir buf.appendAscii( ")"); 330cdf0e10cSrcweir throw IllegalArgumentException( buf.makeStringAndClear(), *this, 0); 331cdf0e10cSrcweir } 332cdf0e10cSrcweir return m_nCurrentPos - (*ii).second; 333cdf0e10cSrcweir } 334cdf0e10cSrcweir 335cdf0e10cSrcweir 336cdf0e10cSrcweir 337cdf0e10cSrcweir // XActiveDataSource2 338cdf0e10cSrcweir void OMarkableOutputStream::setOutputStream(const Reference < XOutputStream >& aStream) 339cdf0e10cSrcweir throw (RuntimeException) 340cdf0e10cSrcweir { 341cdf0e10cSrcweir if( m_output != aStream ) { 342cdf0e10cSrcweir m_output = aStream; 343cdf0e10cSrcweir 344cdf0e10cSrcweir Reference < XConnectable > succ( m_output , UNO_QUERY ); 345cdf0e10cSrcweir setSuccessor( succ ); 346cdf0e10cSrcweir } 347cdf0e10cSrcweir m_bValidStream = m_output.is(); 348cdf0e10cSrcweir } 349cdf0e10cSrcweir 350cdf0e10cSrcweir Reference< XOutputStream > OMarkableOutputStream::getOutputStream(void) throw (RuntimeException) 351cdf0e10cSrcweir { 352cdf0e10cSrcweir return m_output; 353cdf0e10cSrcweir } 354cdf0e10cSrcweir 355cdf0e10cSrcweir 356cdf0e10cSrcweir 357cdf0e10cSrcweir void OMarkableOutputStream::setSuccessor( const Reference< XConnectable > &r ) 358cdf0e10cSrcweir throw (RuntimeException) 359cdf0e10cSrcweir { 360cdf0e10cSrcweir /// if the references match, nothing needs to be done 361cdf0e10cSrcweir if( m_succ != r ) { 362cdf0e10cSrcweir /// store the reference for later use 363cdf0e10cSrcweir m_succ = r; 364cdf0e10cSrcweir 365cdf0e10cSrcweir if( m_succ.is() ) { 366cdf0e10cSrcweir m_succ->setPredecessor( Reference < XConnectable > ( 367cdf0e10cSrcweir SAL_STATIC_CAST( XConnectable * , this ) ) ); 368cdf0e10cSrcweir } 369cdf0e10cSrcweir } 370cdf0e10cSrcweir } 371cdf0e10cSrcweir Reference <XConnectable > OMarkableOutputStream::getSuccessor() throw (RuntimeException) 372cdf0e10cSrcweir { 373cdf0e10cSrcweir return m_succ; 374cdf0e10cSrcweir } 375cdf0e10cSrcweir 376cdf0e10cSrcweir 377cdf0e10cSrcweir // XDataSource 378cdf0e10cSrcweir void OMarkableOutputStream::setPredecessor( const Reference< XConnectable > &r ) 379cdf0e10cSrcweir throw (RuntimeException) 380cdf0e10cSrcweir { 381cdf0e10cSrcweir if( r != m_pred ) { 382cdf0e10cSrcweir m_pred = r; 383cdf0e10cSrcweir if( m_pred.is() ) { 384cdf0e10cSrcweir m_pred->setSuccessor( Reference < XConnectable > ( 385cdf0e10cSrcweir SAL_STATIC_CAST ( XConnectable * , this ) ) ); 386cdf0e10cSrcweir } 387cdf0e10cSrcweir } 388cdf0e10cSrcweir } 389cdf0e10cSrcweir Reference < XConnectable > OMarkableOutputStream::getPredecessor() throw (RuntimeException) 390cdf0e10cSrcweir { 391cdf0e10cSrcweir return m_pred; 392cdf0e10cSrcweir } 393cdf0e10cSrcweir 394cdf0e10cSrcweir 395cdf0e10cSrcweir // private methods 396cdf0e10cSrcweir 397cdf0e10cSrcweir void OMarkableOutputStream::checkMarksAndFlush() throw( NotConnectedException, 398cdf0e10cSrcweir BufferSizeExceededException) 399cdf0e10cSrcweir { 400cdf0e10cSrcweir map<sal_Int32,sal_Int32,less<sal_Int32> >::iterator ii; 401cdf0e10cSrcweir 402cdf0e10cSrcweir // find the smallest mark 403cdf0e10cSrcweir sal_Int32 nNextFound = m_nCurrentPos; 404cdf0e10cSrcweir for( ii = m_mapMarks.begin() ; ii != m_mapMarks.end() ; ii ++ ) { 405cdf0e10cSrcweir if( (*ii).second <= nNextFound ) { 406cdf0e10cSrcweir nNextFound = (*ii).second; 407cdf0e10cSrcweir } 408cdf0e10cSrcweir } 409cdf0e10cSrcweir 410cdf0e10cSrcweir if( nNextFound ) { 411cdf0e10cSrcweir // some data must be released ! 412cdf0e10cSrcweir m_nCurrentPos -= nNextFound; 413cdf0e10cSrcweir for( ii = m_mapMarks.begin() ; ii != m_mapMarks.end() ; ii ++ ) { 414cdf0e10cSrcweir (*ii).second -= nNextFound; 415cdf0e10cSrcweir } 416cdf0e10cSrcweir 417cdf0e10cSrcweir Sequence<sal_Int8> seq(nNextFound); 418cdf0e10cSrcweir m_pBuffer->readAt( 0 , seq , nNextFound ); 419cdf0e10cSrcweir m_pBuffer->forgetFromStart( nNextFound ); 420cdf0e10cSrcweir 421cdf0e10cSrcweir // now write data through to streams 422cdf0e10cSrcweir m_output->writeBytes( seq ); 423cdf0e10cSrcweir } 424cdf0e10cSrcweir else { 425cdf0e10cSrcweir // nothing to do. There is a mark or the current cursor position, that prevents 426cdf0e10cSrcweir // releasing data ! 427cdf0e10cSrcweir } 428cdf0e10cSrcweir } 429cdf0e10cSrcweir 430cdf0e10cSrcweir 431cdf0e10cSrcweir // XServiceInfo 432cdf0e10cSrcweir OUString OMarkableOutputStream::getImplementationName() throw () 433cdf0e10cSrcweir { 434cdf0e10cSrcweir return OMarkableOutputStream_getImplementationName(); 435cdf0e10cSrcweir } 436cdf0e10cSrcweir 437cdf0e10cSrcweir // XServiceInfo 438cdf0e10cSrcweir sal_Bool OMarkableOutputStream::supportsService(const OUString& ServiceName) throw () 439cdf0e10cSrcweir { 440cdf0e10cSrcweir Sequence< OUString > aSNL = getSupportedServiceNames(); 441cdf0e10cSrcweir const OUString * pArray = aSNL.getConstArray(); 442cdf0e10cSrcweir 443cdf0e10cSrcweir for( sal_Int32 i = 0; i < aSNL.getLength(); i++ ) 444cdf0e10cSrcweir if( pArray[i] == ServiceName ) 445cdf0e10cSrcweir return sal_True; 446cdf0e10cSrcweir 447cdf0e10cSrcweir return sal_False; 448cdf0e10cSrcweir } 449cdf0e10cSrcweir 450cdf0e10cSrcweir // XServiceInfo 451cdf0e10cSrcweir Sequence< OUString > OMarkableOutputStream::getSupportedServiceNames(void) throw () 452cdf0e10cSrcweir { 453cdf0e10cSrcweir return OMarkableOutputStream_getSupportedServiceNames(); 454cdf0e10cSrcweir } 455cdf0e10cSrcweir 456cdf0e10cSrcweir 457cdf0e10cSrcweir 458cdf0e10cSrcweir 459cdf0e10cSrcweir /*------------------------ 460cdf0e10cSrcweir * 461cdf0e10cSrcweir * external binding 462cdf0e10cSrcweir * 463cdf0e10cSrcweir *------------------------*/ 464cdf0e10cSrcweir Reference< XInterface > SAL_CALL OMarkableOutputStream_CreateInstance( const Reference < XComponentContext > & ) throw(Exception) 465cdf0e10cSrcweir { 466cdf0e10cSrcweir OMarkableOutputStream *p = new OMarkableOutputStream( ); 467cdf0e10cSrcweir 468cdf0e10cSrcweir return Reference < XInterface > ( ( OWeakObject * ) p ); 469cdf0e10cSrcweir } 470cdf0e10cSrcweir 471cdf0e10cSrcweir OUString OMarkableOutputStream_getImplementationName() 472cdf0e10cSrcweir { 473cdf0e10cSrcweir return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.io.stm.MarkableOutputStream" )); 474cdf0e10cSrcweir } 475cdf0e10cSrcweir 476cdf0e10cSrcweir Sequence<OUString> OMarkableOutputStream_getSupportedServiceNames(void) 477cdf0e10cSrcweir { 478cdf0e10cSrcweir Sequence<OUString> aRet(1); 479cdf0e10cSrcweir aRet.getArray()[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.MarkableOutputStream" ) ); 480cdf0e10cSrcweir 481cdf0e10cSrcweir return aRet; 482cdf0e10cSrcweir } 483cdf0e10cSrcweir 484cdf0e10cSrcweir 485cdf0e10cSrcweir 486cdf0e10cSrcweir 487cdf0e10cSrcweir 488cdf0e10cSrcweir 489cdf0e10cSrcweir //------------------------------------------------ 490cdf0e10cSrcweir // 491cdf0e10cSrcweir // XMarkableInputStream 492cdf0e10cSrcweir // 493cdf0e10cSrcweir //------------------------------------------------ 494cdf0e10cSrcweir 495cdf0e10cSrcweir class OMarkableInputStream : 496cdf0e10cSrcweir public WeakImplHelper5 497cdf0e10cSrcweir < 498cdf0e10cSrcweir XInputStream, 499cdf0e10cSrcweir XActiveDataSink, 500cdf0e10cSrcweir XMarkableStream, 501cdf0e10cSrcweir XConnectable, 502cdf0e10cSrcweir XServiceInfo 503cdf0e10cSrcweir > 504cdf0e10cSrcweir { 505cdf0e10cSrcweir public: 506cdf0e10cSrcweir OMarkableInputStream( ); 507cdf0e10cSrcweir ~OMarkableInputStream(); 508cdf0e10cSrcweir 509cdf0e10cSrcweir 510cdf0e10cSrcweir public: // XInputStream 511cdf0e10cSrcweir virtual sal_Int32 SAL_CALL readBytes(Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead) 512cdf0e10cSrcweir throw ( NotConnectedException, 513cdf0e10cSrcweir BufferSizeExceededException, 514cdf0e10cSrcweir RuntimeException) ; 515cdf0e10cSrcweir virtual sal_Int32 SAL_CALL readSomeBytes(Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead) 516cdf0e10cSrcweir throw ( NotConnectedException, 517cdf0e10cSrcweir BufferSizeExceededException, 518cdf0e10cSrcweir RuntimeException); 519cdf0e10cSrcweir virtual void SAL_CALL skipBytes(sal_Int32 nBytesToSkip) 520cdf0e10cSrcweir throw ( NotConnectedException, 521cdf0e10cSrcweir BufferSizeExceededException, 522cdf0e10cSrcweir RuntimeException); 523cdf0e10cSrcweir 524cdf0e10cSrcweir virtual sal_Int32 SAL_CALL available(void) 525cdf0e10cSrcweir throw ( NotConnectedException, 526cdf0e10cSrcweir RuntimeException); 527cdf0e10cSrcweir virtual void SAL_CALL closeInput(void) throw (NotConnectedException, RuntimeException); 528cdf0e10cSrcweir 529cdf0e10cSrcweir public: // XMarkable 530cdf0e10cSrcweir virtual sal_Int32 SAL_CALL createMark(void) 531cdf0e10cSrcweir throw (IOException, RuntimeException); 532cdf0e10cSrcweir virtual void SAL_CALL deleteMark(sal_Int32 Mark) 533cdf0e10cSrcweir throw (IOException, IllegalArgumentException, RuntimeException); 534cdf0e10cSrcweir virtual void SAL_CALL jumpToMark(sal_Int32 nMark) 535cdf0e10cSrcweir throw (IOException, IllegalArgumentException, RuntimeException); 536cdf0e10cSrcweir virtual void SAL_CALL jumpToFurthest(void) 537cdf0e10cSrcweir throw (IOException, RuntimeException); 538cdf0e10cSrcweir virtual sal_Int32 SAL_CALL offsetToMark(sal_Int32 nMark) 539cdf0e10cSrcweir throw (IOException, IllegalArgumentException,RuntimeException); 540cdf0e10cSrcweir 541cdf0e10cSrcweir public: // XActiveDataSink 542cdf0e10cSrcweir virtual void SAL_CALL setInputStream(const Reference < XInputStream > & aStream) 543cdf0e10cSrcweir throw (RuntimeException); 544cdf0e10cSrcweir virtual Reference < XInputStream > SAL_CALL getInputStream(void) 545cdf0e10cSrcweir throw (RuntimeException); 546cdf0e10cSrcweir 547cdf0e10cSrcweir public: // XConnectable 548cdf0e10cSrcweir virtual void SAL_CALL setPredecessor(const Reference < XConnectable > & aPredecessor) 549cdf0e10cSrcweir throw (RuntimeException); 550cdf0e10cSrcweir virtual Reference < XConnectable > SAL_CALL getPredecessor(void) 551cdf0e10cSrcweir throw (RuntimeException); 552cdf0e10cSrcweir virtual void SAL_CALL setSuccessor(const Reference < XConnectable > & aSuccessor) 553cdf0e10cSrcweir throw (RuntimeException); 554cdf0e10cSrcweir virtual Reference < XConnectable > SAL_CALL getSuccessor(void) throw (RuntimeException); 555cdf0e10cSrcweir 556cdf0e10cSrcweir public: // XServiceInfo 557cdf0e10cSrcweir OUString SAL_CALL getImplementationName() throw (); 558cdf0e10cSrcweir Sequence< OUString > SAL_CALL getSupportedServiceNames(void) throw (); 559cdf0e10cSrcweir sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw (); 560cdf0e10cSrcweir 561cdf0e10cSrcweir private: 562cdf0e10cSrcweir void checkMarksAndFlush(); 563cdf0e10cSrcweir 564cdf0e10cSrcweir Reference < XConnectable > m_succ; 565cdf0e10cSrcweir Reference < XConnectable > m_pred; 566cdf0e10cSrcweir 567cdf0e10cSrcweir Reference< XInputStream > m_input; 568cdf0e10cSrcweir sal_Bool m_bValidStream; 569cdf0e10cSrcweir 570cdf0e10cSrcweir IRingBuffer *m_pBuffer; 571cdf0e10cSrcweir map<sal_Int32,sal_Int32,less< sal_Int32 > > m_mapMarks; 572cdf0e10cSrcweir sal_Int32 m_nCurrentPos; 573cdf0e10cSrcweir sal_Int32 m_nCurrentMark; 574cdf0e10cSrcweir 575cdf0e10cSrcweir Mutex m_mutex; 576cdf0e10cSrcweir }; 577cdf0e10cSrcweir 578cdf0e10cSrcweir OMarkableInputStream::OMarkableInputStream() 579cdf0e10cSrcweir { 580cdf0e10cSrcweir g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); 581cdf0e10cSrcweir m_nCurrentPos = 0; 582cdf0e10cSrcweir m_nCurrentMark = 0; 583cdf0e10cSrcweir m_pBuffer = new MemRingBuffer; 584cdf0e10cSrcweir } 585cdf0e10cSrcweir 586cdf0e10cSrcweir 587cdf0e10cSrcweir OMarkableInputStream::~OMarkableInputStream() 588cdf0e10cSrcweir { 589cdf0e10cSrcweir if( m_pBuffer ) { 590cdf0e10cSrcweir delete m_pBuffer; 591cdf0e10cSrcweir } 592cdf0e10cSrcweir g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); 593cdf0e10cSrcweir } 594cdf0e10cSrcweir 595cdf0e10cSrcweir 596cdf0e10cSrcweir 597cdf0e10cSrcweir 598cdf0e10cSrcweir // XInputStream 599cdf0e10cSrcweir 600cdf0e10cSrcweir sal_Int32 OMarkableInputStream::readBytes(Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead) 601cdf0e10cSrcweir throw ( NotConnectedException, 602cdf0e10cSrcweir BufferSizeExceededException, 603cdf0e10cSrcweir RuntimeException) 604cdf0e10cSrcweir { 605cdf0e10cSrcweir sal_Int32 nBytesRead; 606cdf0e10cSrcweir 607cdf0e10cSrcweir if( m_bValidStream ) { 608cdf0e10cSrcweir MutexGuard guard( m_mutex ); 609cdf0e10cSrcweir if( m_mapMarks.empty() && ! m_pBuffer->getSize() ) { 610cdf0e10cSrcweir // normal read ! 611cdf0e10cSrcweir nBytesRead = m_input->readBytes( aData, nBytesToRead ); 612cdf0e10cSrcweir } 613cdf0e10cSrcweir else { 614cdf0e10cSrcweir // read from buffer 615cdf0e10cSrcweir sal_Int32 nRead; 616cdf0e10cSrcweir 617cdf0e10cSrcweir // read enough bytes into buffer 618cdf0e10cSrcweir if( m_pBuffer->getSize() - m_nCurrentPos < nBytesToRead ) { 619cdf0e10cSrcweir sal_Int32 nToRead = nBytesToRead - ( m_pBuffer->getSize() - m_nCurrentPos ); 620cdf0e10cSrcweir nRead = m_input->readBytes( aData , nToRead ); 621cdf0e10cSrcweir 622cdf0e10cSrcweir OSL_ASSERT( aData.getLength() == nRead ); 623cdf0e10cSrcweir 624cdf0e10cSrcweir try 625cdf0e10cSrcweir { 626cdf0e10cSrcweir m_pBuffer->writeAt( m_pBuffer->getSize() , aData ); 627cdf0e10cSrcweir } 628cdf0e10cSrcweir catch( IRingBuffer_OutOfMemoryException & ) { 629cdf0e10cSrcweir throw BufferSizeExceededException(); 630cdf0e10cSrcweir } 631cdf0e10cSrcweir catch( IRingBuffer_OutOfBoundsException & ) { 632cdf0e10cSrcweir throw BufferSizeExceededException(); 633cdf0e10cSrcweir } 634cdf0e10cSrcweir 635cdf0e10cSrcweir if( nRead < nToRead ) { 636cdf0e10cSrcweir nBytesToRead = nBytesToRead - (nToRead-nRead); 637cdf0e10cSrcweir } 638cdf0e10cSrcweir } 639cdf0e10cSrcweir 640cdf0e10cSrcweir OSL_ASSERT( m_pBuffer->getSize() - m_nCurrentPos >= nBytesToRead ); 641cdf0e10cSrcweir 642cdf0e10cSrcweir m_pBuffer->readAt( m_nCurrentPos , aData , nBytesToRead ); 643cdf0e10cSrcweir 644cdf0e10cSrcweir m_nCurrentPos += nBytesToRead; 645cdf0e10cSrcweir nBytesRead = nBytesToRead; 646cdf0e10cSrcweir } 647cdf0e10cSrcweir } 648cdf0e10cSrcweir else { 649cdf0e10cSrcweir throw NotConnectedException( 650cdf0e10cSrcweir OUString( RTL_CONSTASCII_USTRINGPARAM("MarkableInputStream::readBytes NotConnectedException")) , 651cdf0e10cSrcweir *this ); 652cdf0e10cSrcweir } 653cdf0e10cSrcweir return nBytesRead; 654cdf0e10cSrcweir } 655cdf0e10cSrcweir 656cdf0e10cSrcweir 657cdf0e10cSrcweir sal_Int32 OMarkableInputStream::readSomeBytes(Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead) 658cdf0e10cSrcweir throw ( NotConnectedException, 659cdf0e10cSrcweir BufferSizeExceededException, 660cdf0e10cSrcweir RuntimeException) 661cdf0e10cSrcweir { 662cdf0e10cSrcweir 663cdf0e10cSrcweir sal_Int32 nBytesRead; 664cdf0e10cSrcweir if( m_bValidStream ) { 665cdf0e10cSrcweir MutexGuard guard( m_mutex ); 666cdf0e10cSrcweir if( m_mapMarks.empty() && ! m_pBuffer->getSize() ) { 667cdf0e10cSrcweir // normal read ! 668cdf0e10cSrcweir nBytesRead = m_input->readSomeBytes( aData, nMaxBytesToRead ); 669cdf0e10cSrcweir } 670cdf0e10cSrcweir else { 671cdf0e10cSrcweir // read from buffer 672cdf0e10cSrcweir sal_Int32 nRead = 0; 673cdf0e10cSrcweir sal_Int32 nInBuffer = m_pBuffer->getSize() - m_nCurrentPos; 674cdf0e10cSrcweir sal_Int32 nAdditionalBytesToRead = Min(nMaxBytesToRead-nInBuffer,m_input->available()); 675cdf0e10cSrcweir nAdditionalBytesToRead = Max(0 , nAdditionalBytesToRead ); 676cdf0e10cSrcweir 677cdf0e10cSrcweir // read enough bytes into buffer 678cdf0e10cSrcweir if( 0 == nInBuffer ) { 679cdf0e10cSrcweir nRead = m_input->readSomeBytes( aData , nMaxBytesToRead ); 680cdf0e10cSrcweir } 681cdf0e10cSrcweir else if( nAdditionalBytesToRead ) { 682cdf0e10cSrcweir nRead = m_input->readBytes( aData , nAdditionalBytesToRead ); 683cdf0e10cSrcweir } 684cdf0e10cSrcweir 685cdf0e10cSrcweir if( nRead ) { 686cdf0e10cSrcweir aData.realloc( nRead ); 687cdf0e10cSrcweir try 688cdf0e10cSrcweir { 689cdf0e10cSrcweir m_pBuffer->writeAt( m_pBuffer->getSize() , aData ); 690cdf0e10cSrcweir } 691cdf0e10cSrcweir catch( IRingBuffer_OutOfMemoryException & ) 692cdf0e10cSrcweir { 693cdf0e10cSrcweir throw BufferSizeExceededException(); 694cdf0e10cSrcweir } 695cdf0e10cSrcweir catch( IRingBuffer_OutOfBoundsException & ) 696cdf0e10cSrcweir { 697cdf0e10cSrcweir throw BufferSizeExceededException(); 698cdf0e10cSrcweir } 699cdf0e10cSrcweir } 700cdf0e10cSrcweir 701cdf0e10cSrcweir nBytesRead = Min( nMaxBytesToRead , nInBuffer + nRead ); 702cdf0e10cSrcweir 703cdf0e10cSrcweir // now take everything from buffer ! 704cdf0e10cSrcweir m_pBuffer->readAt( m_nCurrentPos , aData , nBytesRead ); 705cdf0e10cSrcweir 706cdf0e10cSrcweir m_nCurrentPos += nBytesRead; 707cdf0e10cSrcweir } 708cdf0e10cSrcweir } 709cdf0e10cSrcweir else 710cdf0e10cSrcweir { 711cdf0e10cSrcweir throw NotConnectedException( 712cdf0e10cSrcweir OUString( RTL_CONSTASCII_USTRINGPARAM("MarkableInputStream::readSomeBytes NotConnectedException")) , 713cdf0e10cSrcweir *this ); 714cdf0e10cSrcweir } 715cdf0e10cSrcweir return nBytesRead; 716cdf0e10cSrcweir 717cdf0e10cSrcweir 718cdf0e10cSrcweir } 719cdf0e10cSrcweir 720cdf0e10cSrcweir 721cdf0e10cSrcweir void OMarkableInputStream::skipBytes(sal_Int32 nBytesToSkip) 722cdf0e10cSrcweir throw ( NotConnectedException, 723cdf0e10cSrcweir BufferSizeExceededException, 724cdf0e10cSrcweir RuntimeException) 725cdf0e10cSrcweir { 726cdf0e10cSrcweir if ( nBytesToSkip < 0 ) 727cdf0e10cSrcweir throw BufferSizeExceededException( 728cdf0e10cSrcweir ::rtl::OUString::createFromAscii( "precondition not met: XInputStream::skipBytes: non-negative integer required!" ), 729cdf0e10cSrcweir *this 730cdf0e10cSrcweir ); 731cdf0e10cSrcweir 732cdf0e10cSrcweir // this method is blocking 733cdf0e10cSrcweir sal_Int32 nRead; 734cdf0e10cSrcweir Sequence<sal_Int8> seqDummy( nBytesToSkip ); 735cdf0e10cSrcweir 736cdf0e10cSrcweir nRead = readBytes( seqDummy , nBytesToSkip ); 737cdf0e10cSrcweir } 738cdf0e10cSrcweir 739cdf0e10cSrcweir sal_Int32 OMarkableInputStream::available(void) throw (NotConnectedException, RuntimeException) 740cdf0e10cSrcweir { 741cdf0e10cSrcweir sal_Int32 nAvail; 742cdf0e10cSrcweir if( m_bValidStream ) { 743cdf0e10cSrcweir MutexGuard guard( m_mutex ); 744cdf0e10cSrcweir nAvail = m_input->available() + ( m_pBuffer->getSize() - m_nCurrentPos ); 745cdf0e10cSrcweir } 746cdf0e10cSrcweir else 747cdf0e10cSrcweir { 748cdf0e10cSrcweir throw NotConnectedException( 749cdf0e10cSrcweir OUString( RTL_CONSTASCII_USTRINGPARAM( "MarkableInputStream::available NotConnectedException" ) ) , 750cdf0e10cSrcweir *this ); 751cdf0e10cSrcweir } 752cdf0e10cSrcweir 753cdf0e10cSrcweir return nAvail; 754cdf0e10cSrcweir } 755cdf0e10cSrcweir 756cdf0e10cSrcweir 757cdf0e10cSrcweir void OMarkableInputStream::closeInput(void) throw (NotConnectedException, RuntimeException) 758cdf0e10cSrcweir { 759cdf0e10cSrcweir if( m_bValidStream ) { 760cdf0e10cSrcweir MutexGuard guard( m_mutex ); 761cdf0e10cSrcweir 762cdf0e10cSrcweir m_input->closeInput(); 763cdf0e10cSrcweir 764cdf0e10cSrcweir setInputStream( Reference< XInputStream > () ); 765cdf0e10cSrcweir setPredecessor( Reference< XConnectable > () ); 766cdf0e10cSrcweir setSuccessor( Reference< XConnectable >() ); 767cdf0e10cSrcweir 768cdf0e10cSrcweir delete m_pBuffer; 769cdf0e10cSrcweir m_pBuffer = 0; 770cdf0e10cSrcweir m_nCurrentPos = 0; 771cdf0e10cSrcweir m_nCurrentMark = 0; 772cdf0e10cSrcweir } 773cdf0e10cSrcweir else { 774cdf0e10cSrcweir throw NotConnectedException( 775cdf0e10cSrcweir OUString( RTL_CONSTASCII_USTRINGPARAM( "MarkableInputStream::closeInput NotConnectedException" ) ) , 776cdf0e10cSrcweir *this ); 777cdf0e10cSrcweir } 778cdf0e10cSrcweir } 779cdf0e10cSrcweir 780cdf0e10cSrcweir // XMarkable 781cdf0e10cSrcweir 782cdf0e10cSrcweir sal_Int32 OMarkableInputStream::createMark(void) throw (IOException, RuntimeException) 783cdf0e10cSrcweir { 784cdf0e10cSrcweir MutexGuard guard( m_mutex ); 785cdf0e10cSrcweir sal_Int32 nMark = m_nCurrentMark; 786cdf0e10cSrcweir 787cdf0e10cSrcweir m_mapMarks[nMark] = m_nCurrentPos; 788cdf0e10cSrcweir 789cdf0e10cSrcweir m_nCurrentMark ++; 790cdf0e10cSrcweir return nMark; 791cdf0e10cSrcweir } 792cdf0e10cSrcweir 793cdf0e10cSrcweir void OMarkableInputStream::deleteMark(sal_Int32 Mark) throw (IOException, IllegalArgumentException, RuntimeException) 794cdf0e10cSrcweir { 795cdf0e10cSrcweir MutexGuard guard( m_mutex ); 796cdf0e10cSrcweir map<sal_Int32,sal_Int32,less<sal_Int32> >::iterator ii = m_mapMarks.find( Mark ); 797cdf0e10cSrcweir 798cdf0e10cSrcweir if( ii == m_mapMarks.end() ) { 799cdf0e10cSrcweir OUStringBuffer buf( 128 ); 800cdf0e10cSrcweir buf.appendAscii( "MarkableInputStream::deleteMark unknown mark (" ); 801cdf0e10cSrcweir buf.append( Mark ); 802cdf0e10cSrcweir buf.appendAscii( ")"); 803cdf0e10cSrcweir throw IllegalArgumentException( buf.makeStringAndClear(), *this , 0 ); 804cdf0e10cSrcweir } 805cdf0e10cSrcweir else { 806cdf0e10cSrcweir m_mapMarks.erase( ii ); 807cdf0e10cSrcweir checkMarksAndFlush(); 808cdf0e10cSrcweir } 809cdf0e10cSrcweir } 810cdf0e10cSrcweir 811cdf0e10cSrcweir void OMarkableInputStream::jumpToMark(sal_Int32 nMark) 812cdf0e10cSrcweir throw (IOException, 813cdf0e10cSrcweir IllegalArgumentException, 814cdf0e10cSrcweir RuntimeException) 815cdf0e10cSrcweir { 816cdf0e10cSrcweir MutexGuard guard( m_mutex ); 817cdf0e10cSrcweir map<sal_Int32,sal_Int32,less<sal_Int32> >::iterator ii = m_mapMarks.find( nMark ); 818cdf0e10cSrcweir 819cdf0e10cSrcweir if( ii == m_mapMarks.end() ) 820cdf0e10cSrcweir { 821cdf0e10cSrcweir OUStringBuffer buf( 128 ); 822cdf0e10cSrcweir buf.appendAscii( "MarkableInputStream::jumpToMark unknown mark (" ); 823cdf0e10cSrcweir buf.append( nMark ); 824cdf0e10cSrcweir buf.appendAscii( ")"); 825cdf0e10cSrcweir throw IllegalArgumentException( buf.makeStringAndClear(), *this , 0 ); 826cdf0e10cSrcweir } 827cdf0e10cSrcweir else 828cdf0e10cSrcweir { 829cdf0e10cSrcweir m_nCurrentPos = (*ii).second; 830cdf0e10cSrcweir } 831cdf0e10cSrcweir } 832cdf0e10cSrcweir 833cdf0e10cSrcweir void OMarkableInputStream::jumpToFurthest(void) throw (IOException, RuntimeException) 834cdf0e10cSrcweir { 835cdf0e10cSrcweir MutexGuard guard( m_mutex ); 836cdf0e10cSrcweir m_nCurrentPos = m_pBuffer->getSize(); 837cdf0e10cSrcweir checkMarksAndFlush(); 838cdf0e10cSrcweir } 839cdf0e10cSrcweir 840cdf0e10cSrcweir sal_Int32 OMarkableInputStream::offsetToMark(sal_Int32 nMark) 841cdf0e10cSrcweir throw (IOException, 842cdf0e10cSrcweir IllegalArgumentException, 843cdf0e10cSrcweir RuntimeException) 844cdf0e10cSrcweir { 845cdf0e10cSrcweir MutexGuard guard( m_mutex ); 846cdf0e10cSrcweir map<sal_Int32,sal_Int32,less<sal_Int32> >::const_iterator ii = m_mapMarks.find( nMark ); 847cdf0e10cSrcweir 848cdf0e10cSrcweir if( ii == m_mapMarks.end() ) 849cdf0e10cSrcweir { 850cdf0e10cSrcweir OUStringBuffer buf( 128 ); 851cdf0e10cSrcweir buf.appendAscii( "MarkableInputStream::offsetToMark unknown mark (" ); 852cdf0e10cSrcweir buf.append( nMark ); 853cdf0e10cSrcweir buf.appendAscii( ")"); 854cdf0e10cSrcweir throw IllegalArgumentException( buf.makeStringAndClear(), *this , 0 ); 855cdf0e10cSrcweir } 856cdf0e10cSrcweir return m_nCurrentPos - (*ii).second; 857cdf0e10cSrcweir } 858cdf0e10cSrcweir 859cdf0e10cSrcweir 860cdf0e10cSrcweir 861cdf0e10cSrcweir 862cdf0e10cSrcweir 863cdf0e10cSrcweir 864cdf0e10cSrcweir 865cdf0e10cSrcweir // XActiveDataSource 866cdf0e10cSrcweir void OMarkableInputStream::setInputStream(const Reference< XInputStream > & aStream) 867cdf0e10cSrcweir throw (RuntimeException) 868cdf0e10cSrcweir { 869cdf0e10cSrcweir 870cdf0e10cSrcweir if( m_input != aStream ) { 871cdf0e10cSrcweir m_input = aStream; 872cdf0e10cSrcweir 873cdf0e10cSrcweir Reference < XConnectable > pred( m_input , UNO_QUERY ); 874cdf0e10cSrcweir setPredecessor( pred ); 875cdf0e10cSrcweir } 876cdf0e10cSrcweir 877cdf0e10cSrcweir m_bValidStream = m_input.is(); 878cdf0e10cSrcweir 879cdf0e10cSrcweir } 880cdf0e10cSrcweir 881cdf0e10cSrcweir Reference< XInputStream > OMarkableInputStream::getInputStream(void) throw (RuntimeException) 882cdf0e10cSrcweir { 883cdf0e10cSrcweir return m_input; 884cdf0e10cSrcweir } 885cdf0e10cSrcweir 886cdf0e10cSrcweir 887cdf0e10cSrcweir 888cdf0e10cSrcweir // XDataSink 889cdf0e10cSrcweir void OMarkableInputStream::setSuccessor( const Reference< XConnectable > &r ) 890cdf0e10cSrcweir throw (RuntimeException) 891cdf0e10cSrcweir { 892cdf0e10cSrcweir /// if the references match, nothing needs to be done 893cdf0e10cSrcweir if( m_succ != r ) { 894cdf0e10cSrcweir /// store the reference for later use 895cdf0e10cSrcweir m_succ = r; 896cdf0e10cSrcweir 897cdf0e10cSrcweir if( m_succ.is() ) { 898cdf0e10cSrcweir /// set this instance as the sink ! 899cdf0e10cSrcweir m_succ->setPredecessor( Reference< XConnectable > ( 900cdf0e10cSrcweir SAL_STATIC_CAST( XConnectable * , this ) ) ); 901cdf0e10cSrcweir } 902cdf0e10cSrcweir } 903cdf0e10cSrcweir } 904cdf0e10cSrcweir 905cdf0e10cSrcweir Reference < XConnectable > OMarkableInputStream::getSuccessor() throw (RuntimeException) 906cdf0e10cSrcweir { 907cdf0e10cSrcweir return m_succ; 908cdf0e10cSrcweir } 909cdf0e10cSrcweir 910cdf0e10cSrcweir 911cdf0e10cSrcweir // XDataSource 912cdf0e10cSrcweir void OMarkableInputStream::setPredecessor( const Reference < XConnectable > &r ) 913cdf0e10cSrcweir throw (RuntimeException) 914cdf0e10cSrcweir { 915cdf0e10cSrcweir if( r != m_pred ) { 916cdf0e10cSrcweir m_pred = r; 917cdf0e10cSrcweir if( m_pred.is() ) { 918cdf0e10cSrcweir m_pred->setSuccessor( Reference< XConnectable > ( 919cdf0e10cSrcweir SAL_STATIC_CAST( XConnectable * , this ) ) ); 920cdf0e10cSrcweir } 921cdf0e10cSrcweir } 922cdf0e10cSrcweir } 923cdf0e10cSrcweir Reference< XConnectable > OMarkableInputStream::getPredecessor() throw (RuntimeException) 924cdf0e10cSrcweir { 925cdf0e10cSrcweir return m_pred; 926cdf0e10cSrcweir } 927cdf0e10cSrcweir 928cdf0e10cSrcweir 929cdf0e10cSrcweir 930cdf0e10cSrcweir 931cdf0e10cSrcweir void OMarkableInputStream::checkMarksAndFlush() 932cdf0e10cSrcweir { 933cdf0e10cSrcweir map<sal_Int32,sal_Int32,less<sal_Int32> >::iterator ii; 934cdf0e10cSrcweir 935cdf0e10cSrcweir // find the smallest mark 936cdf0e10cSrcweir sal_Int32 nNextFound = m_nCurrentPos; 937cdf0e10cSrcweir for( ii = m_mapMarks.begin() ; ii != m_mapMarks.end() ; ii ++ ) { 938cdf0e10cSrcweir if( (*ii).second <= nNextFound ) { 939cdf0e10cSrcweir nNextFound = (*ii).second; 940cdf0e10cSrcweir } 941cdf0e10cSrcweir } 942cdf0e10cSrcweir 943cdf0e10cSrcweir if( nNextFound ) { 944cdf0e10cSrcweir // some data must be released ! 945cdf0e10cSrcweir m_nCurrentPos -= nNextFound; 946cdf0e10cSrcweir for( ii = m_mapMarks.begin() ; ii != m_mapMarks.end() ; ii ++ ) { 947cdf0e10cSrcweir (*ii).second -= nNextFound; 948cdf0e10cSrcweir } 949cdf0e10cSrcweir 950cdf0e10cSrcweir m_pBuffer->forgetFromStart( nNextFound ); 951cdf0e10cSrcweir 952cdf0e10cSrcweir } 953cdf0e10cSrcweir else { 954cdf0e10cSrcweir // nothing to do. There is a mark or the current cursor position, that prevents 955cdf0e10cSrcweir // releasing data ! 956cdf0e10cSrcweir } 957cdf0e10cSrcweir } 958cdf0e10cSrcweir 959cdf0e10cSrcweir 960cdf0e10cSrcweir 961cdf0e10cSrcweir // XServiceInfo 962cdf0e10cSrcweir OUString OMarkableInputStream::getImplementationName() throw () 963cdf0e10cSrcweir { 964cdf0e10cSrcweir return OMarkableInputStream_getImplementationName(); 965cdf0e10cSrcweir } 966cdf0e10cSrcweir 967cdf0e10cSrcweir // XServiceInfo 968cdf0e10cSrcweir sal_Bool OMarkableInputStream::supportsService(const OUString& ServiceName) throw () 969cdf0e10cSrcweir { 970cdf0e10cSrcweir Sequence< OUString > aSNL = getSupportedServiceNames(); 971cdf0e10cSrcweir const OUString * pArray = aSNL.getConstArray(); 972cdf0e10cSrcweir 973cdf0e10cSrcweir for( sal_Int32 i = 0; i < aSNL.getLength(); i++ ) 974cdf0e10cSrcweir if( pArray[i] == ServiceName ) 975cdf0e10cSrcweir return sal_True; 976cdf0e10cSrcweir 977cdf0e10cSrcweir return sal_False; 978cdf0e10cSrcweir } 979cdf0e10cSrcweir 980cdf0e10cSrcweir // XServiceInfo 981cdf0e10cSrcweir Sequence< OUString > OMarkableInputStream::getSupportedServiceNames(void) throw () 982cdf0e10cSrcweir { 983cdf0e10cSrcweir return OMarkableInputStream_getSupportedServiceNames(); 984cdf0e10cSrcweir } 985cdf0e10cSrcweir 986cdf0e10cSrcweir 987cdf0e10cSrcweir /*------------------------ 988cdf0e10cSrcweir * 989cdf0e10cSrcweir * external binding 990cdf0e10cSrcweir * 991cdf0e10cSrcweir *------------------------*/ 992cdf0e10cSrcweir Reference < XInterface > SAL_CALL OMarkableInputStream_CreateInstance( 993cdf0e10cSrcweir const Reference < XComponentContext > & ) throw(Exception) 994cdf0e10cSrcweir { 995cdf0e10cSrcweir OMarkableInputStream *p = new OMarkableInputStream( ); 996cdf0e10cSrcweir return Reference< XInterface > ( (OWeakObject * ) p ); 997cdf0e10cSrcweir } 998cdf0e10cSrcweir 999cdf0e10cSrcweir OUString OMarkableInputStream_getImplementationName() 1000cdf0e10cSrcweir { 1001cdf0e10cSrcweir return OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.io.stm.MarkableInputStream" )); 1002cdf0e10cSrcweir } 1003cdf0e10cSrcweir 1004cdf0e10cSrcweir Sequence<OUString> OMarkableInputStream_getSupportedServiceNames(void) 1005cdf0e10cSrcweir { 1006cdf0e10cSrcweir Sequence<OUString> aRet(1); 1007cdf0e10cSrcweir aRet.getArray()[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.MarkableInputStream" )); 1008cdf0e10cSrcweir return aRet; 1009cdf0e10cSrcweir } 1010cdf0e10cSrcweir 1011cdf0e10cSrcweir } 1012