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