1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
24 #include <com/sun/star/io/XMarkableStream.hpp>
25 #include <com/sun/star/io/XOutputStream.hpp>
26 #include <com/sun/star/io/XInputStream.hpp>
27 #include <com/sun/star/io/XActiveDataSource.hpp>
28 #include <com/sun/star/io/XActiveDataSink.hpp>
29 #include <com/sun/star/io/XConnectable.hpp>
30 #include <com/sun/star/lang/XServiceInfo.hpp>
32 #include <cppuhelper/factory.hxx>
33 #include <cppuhelper/weak.hxx>
34 #include <cppuhelper/implbase5.hxx>
36 #include <osl/mutex.hxx>
37 #include <rtl/ustrbuf.hxx>
42 using namespace ::std
;
43 using namespace ::rtl
;
44 using namespace ::cppu
;
45 using namespace ::osl
;
46 using namespace ::com::sun::star::io
;
47 using namespace ::com::sun::star::uno
;
48 using namespace ::com::sun::star::lang
;
50 #include "services.hxx"
51 #include "streamhelper.hxx"
55 /***********************
57 * OMarkableOutputStream.
59 * This object allows to set marks in an outputstream. It is allowed to jump back to the marks and
60 * rewrite the some bytes.
62 * The object must buffer the data since the last mark set. Flush will not
63 * have any effect. As soon as the last mark has been removed, the object may write the data
64 * through to the chained object.
66 **********************/
67 class OMarkableOutputStream
:
68 public WeakImplHelper5
< XOutputStream
,
76 OMarkableOutputStream( );
77 ~OMarkableOutputStream();
79 public: // XOutputStream
80 virtual void SAL_CALL
writeBytes(const Sequence
< sal_Int8
>& aData
)
81 throw ( NotConnectedException
,
82 BufferSizeExceededException
,
84 virtual void SAL_CALL
flush(void)
85 throw ( NotConnectedException
,
86 BufferSizeExceededException
,
88 virtual void SAL_CALL
closeOutput(void)
89 throw ( NotConnectedException
,
90 BufferSizeExceededException
,
94 virtual sal_Int32 SAL_CALL
createMark(void)
95 throw (IOException
, RuntimeException
);
96 virtual void SAL_CALL
deleteMark(sal_Int32 Mark
)
98 IllegalArgumentException
,
100 virtual void SAL_CALL
jumpToMark(sal_Int32 nMark
)
102 IllegalArgumentException
,
104 virtual void SAL_CALL
jumpToFurthest(void)
105 throw (IOException
, RuntimeException
);
106 virtual sal_Int32 SAL_CALL
offsetToMark(sal_Int32 nMark
)
108 IllegalArgumentException
,
111 public: // XActiveDataSource
112 virtual void SAL_CALL
setOutputStream(const Reference
< XOutputStream
> & aStream
)
113 throw (RuntimeException
);
114 virtual Reference
< XOutputStream
> SAL_CALL
getOutputStream(void)
115 throw (RuntimeException
);
117 public: // XConnectable
118 virtual void SAL_CALL
setPredecessor(const Reference
< XConnectable
> & aPredecessor
)
119 throw (RuntimeException
);
120 virtual Reference
< XConnectable
> SAL_CALL
getPredecessor(void) throw (RuntimeException
);
121 virtual void SAL_CALL
setSuccessor(const Reference
< XConnectable
>& aSuccessor
)
122 throw (RuntimeException
);
123 virtual Reference
< XConnectable
> SAL_CALL
getSuccessor(void) throw (RuntimeException
);
125 public: // XServiceInfo
126 OUString SAL_CALL
getImplementationName() throw ();
127 Sequence
< OUString
> SAL_CALL
getSupportedServiceNames(void) throw ();
128 sal_Bool SAL_CALL
supportsService(const OUString
& ServiceName
) throw ();
132 void checkMarksAndFlush() throw( NotConnectedException
, BufferSizeExceededException
);
134 Reference
< XConnectable
> m_succ
;
135 Reference
< XConnectable
> m_pred
;
137 Reference
< XOutputStream
> m_output
;
138 sal_Bool m_bValidStream
;
140 IRingBuffer
*m_pBuffer
;
141 map
<sal_Int32
,sal_Int32
,less
< sal_Int32
> > m_mapMarks
;
142 sal_Int32 m_nCurrentPos
;
143 sal_Int32 m_nCurrentMark
;
148 OMarkableOutputStream::OMarkableOutputStream( )
150 m_pBuffer
= new MemRingBuffer
;
155 OMarkableOutputStream::~OMarkableOutputStream()
162 void OMarkableOutputStream::writeBytes(const Sequence
< sal_Int8
>& aData
)
163 throw ( NotConnectedException
,
164 BufferSizeExceededException
,
167 if( m_bValidStream
) {
168 if( m_mapMarks
.empty() && ( m_pBuffer
->getSize() == 0 ) ) {
169 // no mark and buffer active, simple write through
170 m_output
->writeBytes( aData
);
173 MutexGuard
guard( m_mutex
);
174 // new data must be buffered
177 m_pBuffer
->writeAt( m_nCurrentPos
, aData
);
178 m_nCurrentPos
+= aData
.getLength();
180 catch( IRingBuffer_OutOfBoundsException
& )
182 throw BufferSizeExceededException();
184 catch( IRingBuffer_OutOfMemoryException
& )
186 throw BufferSizeExceededException();
188 checkMarksAndFlush();
192 throw NotConnectedException();
196 void OMarkableOutputStream::flush(void)
197 throw ( NotConnectedException
,
198 BufferSizeExceededException
,
201 Reference
< XOutputStream
> output
;
203 MutexGuard
guard( m_mutex
);
207 // Markable cannot flush buffered data, because the data may get rewritten,
208 // however one can forward the flush to the chained stream to give it
209 // a chance to write data buffered in the chained stream.
216 void OMarkableOutputStream::closeOutput(void)
217 throw ( NotConnectedException
,
218 BufferSizeExceededException
,
221 if( m_bValidStream
) {
222 MutexGuard
guard( m_mutex
);
223 // all marks must be cleared and all
225 if( ! m_mapMarks
.empty() )
229 m_nCurrentPos
= m_pBuffer
->getSize();
230 checkMarksAndFlush();
232 m_output
->closeOutput();
234 setOutputStream( Reference
< XOutputStream
> () );
235 setPredecessor( Reference
< XConnectable
>() );
236 setSuccessor( Reference
< XConnectable
> () );
239 throw NotConnectedException();
244 sal_Int32
OMarkableOutputStream::createMark(void)
248 MutexGuard
guard( m_mutex
);
249 sal_Int32 nMark
= m_nCurrentMark
;
251 m_mapMarks
[nMark
] = m_nCurrentPos
;
257 void OMarkableOutputStream::deleteMark(sal_Int32 Mark
)
259 IllegalArgumentException
,
262 MutexGuard
guard( m_mutex
);
263 map
<sal_Int32
,sal_Int32
,less
<sal_Int32
> >::iterator ii
= m_mapMarks
.find( Mark
);
265 if( ii
== m_mapMarks
.end() ) {
266 OUStringBuffer
buf( 128 );
267 buf
.appendAscii( "MarkableOutputStream::deleteMark unknown mark (" );
269 buf
.appendAscii( ")");
270 throw IllegalArgumentException( buf
.makeStringAndClear(), *this, 0);
273 m_mapMarks
.erase( ii
);
274 checkMarksAndFlush();
278 void OMarkableOutputStream::jumpToMark(sal_Int32 nMark
)
280 IllegalArgumentException
,
283 MutexGuard
guard( m_mutex
);
284 map
<sal_Int32
,sal_Int32
,less
<sal_Int32
> >::iterator ii
= m_mapMarks
.find( nMark
);
286 if( ii
== m_mapMarks
.end() ) {
287 OUStringBuffer
buf( 128 );
288 buf
.appendAscii( "MarkableOutputStream::jumpToMark unknown mark (" );
290 buf
.appendAscii( ")");
291 throw IllegalArgumentException( buf
.makeStringAndClear(), *this, 0);
294 m_nCurrentPos
= (*ii
).second
;
298 void OMarkableOutputStream::jumpToFurthest(void)
302 MutexGuard
guard( m_mutex
);
303 m_nCurrentPos
= m_pBuffer
->getSize();
304 checkMarksAndFlush();
307 sal_Int32
OMarkableOutputStream::offsetToMark(sal_Int32 nMark
)
309 IllegalArgumentException
,
313 MutexGuard
guard( m_mutex
);
314 map
<sal_Int32
,sal_Int32
,less
<sal_Int32
> >::const_iterator ii
= m_mapMarks
.find( nMark
);
316 if( ii
== m_mapMarks
.end() )
318 OUStringBuffer
buf( 128 );
319 buf
.appendAscii( "MarkableOutputStream::offsetToMark unknown mark (" );
321 buf
.appendAscii( ")");
322 throw IllegalArgumentException( buf
.makeStringAndClear(), *this, 0);
324 return m_nCurrentPos
- (*ii
).second
;
329 // XActiveDataSource2
330 void OMarkableOutputStream::setOutputStream(const Reference
< XOutputStream
>& aStream
)
331 throw (RuntimeException
)
333 if( m_output
!= aStream
) {
336 Reference
< XConnectable
> succ( m_output
, UNO_QUERY
);
337 setSuccessor( succ
);
339 m_bValidStream
= m_output
.is();
342 Reference
< XOutputStream
> OMarkableOutputStream::getOutputStream(void) throw (RuntimeException
)
349 void OMarkableOutputStream::setSuccessor( const Reference
< XConnectable
> &r
)
350 throw (RuntimeException
)
352 /// if the references match, nothing needs to be done
354 /// store the reference for later use
358 m_succ
->setPredecessor( Reference
< XConnectable
> (
359 (static_cast< XConnectable
* >(this)) ) );
363 Reference
<XConnectable
> OMarkableOutputStream::getSuccessor() throw (RuntimeException
)
370 void OMarkableOutputStream::setPredecessor( const Reference
< XConnectable
> &r
)
371 throw (RuntimeException
)
376 m_pred
->setSuccessor( Reference
< XConnectable
> (
377 (static_cast< XConnectable
* >(this )) ) );
381 Reference
< XConnectable
> OMarkableOutputStream::getPredecessor() throw (RuntimeException
)
389 void OMarkableOutputStream::checkMarksAndFlush() throw( NotConnectedException
,
390 BufferSizeExceededException
)
392 map
<sal_Int32
,sal_Int32
,less
<sal_Int32
> >::iterator ii
;
394 // find the smallest mark
395 sal_Int32 nNextFound
= m_nCurrentPos
;
396 for( ii
= m_mapMarks
.begin() ; ii
!= m_mapMarks
.end() ; ++ii
) {
397 if( (*ii
).second
<= nNextFound
) {
398 nNextFound
= (*ii
).second
;
403 // some data must be released !
404 m_nCurrentPos
-= nNextFound
;
405 for( ii
= m_mapMarks
.begin() ; ii
!= m_mapMarks
.end() ; ++ii
) {
406 (*ii
).second
-= nNextFound
;
409 Sequence
<sal_Int8
> seq(nNextFound
);
410 m_pBuffer
->readAt( 0 , seq
, nNextFound
);
411 m_pBuffer
->forgetFromStart( nNextFound
);
413 // now write data through to streams
414 m_output
->writeBytes( seq
);
417 // nothing to do. There is a mark or the current cursor position, that prevents
424 OUString
OMarkableOutputStream::getImplementationName() throw ()
426 return OMarkableOutputStream_getImplementationName();
430 sal_Bool
OMarkableOutputStream::supportsService(const OUString
& ServiceName
) throw ()
432 Sequence
< OUString
> aSNL
= getSupportedServiceNames();
433 const OUString
* pArray
= aSNL
.getConstArray();
435 for( sal_Int32 i
= 0; i
< aSNL
.getLength(); i
++ )
436 if( pArray
[i
] == ServiceName
)
443 Sequence
< OUString
> OMarkableOutputStream::getSupportedServiceNames(void) throw ()
445 return OMarkableOutputStream_getSupportedServiceNames();
451 /*------------------------
455 *------------------------*/
456 Reference
< XInterface
> SAL_CALL
OMarkableOutputStream_CreateInstance(
457 SAL_UNUSED_PARAMETER
const Reference
< XComponentContext
> & )
460 OMarkableOutputStream
*p
= new OMarkableOutputStream( );
462 return Reference
< XInterface
> ( ( OWeakObject
* ) p
);
465 OUString
OMarkableOutputStream_getImplementationName()
467 return OUString("com.sun.star.comp.io.stm.MarkableOutputStream");
470 Sequence
<OUString
> OMarkableOutputStream_getSupportedServiceNames(void)
472 Sequence
<OUString
> aRet(1);
473 aRet
.getArray()[0] = "com.sun.star.io.MarkableOutputStream";
483 //------------------------------------------------
485 // XMarkableInputStream
487 //------------------------------------------------
489 class OMarkableInputStream
:
490 public WeakImplHelper5
500 OMarkableInputStream( );
501 ~OMarkableInputStream();
504 public: // XInputStream
505 virtual sal_Int32 SAL_CALL
readBytes(Sequence
< sal_Int8
>& aData
, sal_Int32 nBytesToRead
)
506 throw ( NotConnectedException
,
507 BufferSizeExceededException
,
509 virtual sal_Int32 SAL_CALL
readSomeBytes(Sequence
< sal_Int8
>& aData
, sal_Int32 nMaxBytesToRead
)
510 throw ( NotConnectedException
,
511 BufferSizeExceededException
,
513 virtual void SAL_CALL
skipBytes(sal_Int32 nBytesToSkip
)
514 throw ( NotConnectedException
,
515 BufferSizeExceededException
,
518 virtual sal_Int32 SAL_CALL
available(void)
519 throw ( NotConnectedException
,
521 virtual void SAL_CALL
closeInput(void) throw (NotConnectedException
, RuntimeException
);
524 virtual sal_Int32 SAL_CALL
createMark(void)
525 throw (IOException
, RuntimeException
);
526 virtual void SAL_CALL
deleteMark(sal_Int32 Mark
)
527 throw (IOException
, IllegalArgumentException
, RuntimeException
);
528 virtual void SAL_CALL
jumpToMark(sal_Int32 nMark
)
529 throw (IOException
, IllegalArgumentException
, RuntimeException
);
530 virtual void SAL_CALL
jumpToFurthest(void)
531 throw (IOException
, RuntimeException
);
532 virtual sal_Int32 SAL_CALL
offsetToMark(sal_Int32 nMark
)
533 throw (IOException
, IllegalArgumentException
,RuntimeException
);
535 public: // XActiveDataSink
536 virtual void SAL_CALL
setInputStream(const Reference
< XInputStream
> & aStream
)
537 throw (RuntimeException
);
538 virtual Reference
< XInputStream
> SAL_CALL
getInputStream(void)
539 throw (RuntimeException
);
541 public: // XConnectable
542 virtual void SAL_CALL
setPredecessor(const Reference
< XConnectable
> & aPredecessor
)
543 throw (RuntimeException
);
544 virtual Reference
< XConnectable
> SAL_CALL
getPredecessor(void)
545 throw (RuntimeException
);
546 virtual void SAL_CALL
setSuccessor(const Reference
< XConnectable
> & aSuccessor
)
547 throw (RuntimeException
);
548 virtual Reference
< XConnectable
> SAL_CALL
getSuccessor(void) throw (RuntimeException
);
550 public: // XServiceInfo
551 OUString SAL_CALL
getImplementationName() throw ();
552 Sequence
< OUString
> SAL_CALL
getSupportedServiceNames(void) throw ();
553 sal_Bool SAL_CALL
supportsService(const OUString
& ServiceName
) throw ();
556 void checkMarksAndFlush();
558 Reference
< XConnectable
> m_succ
;
559 Reference
< XConnectable
> m_pred
;
561 Reference
< XInputStream
> m_input
;
562 sal_Bool m_bValidStream
;
564 IRingBuffer
*m_pBuffer
;
565 map
<sal_Int32
,sal_Int32
,less
< sal_Int32
> > m_mapMarks
;
566 sal_Int32 m_nCurrentPos
;
567 sal_Int32 m_nCurrentMark
;
572 OMarkableInputStream::OMarkableInputStream()
576 m_pBuffer
= new MemRingBuffer
;
580 OMarkableInputStream::~OMarkableInputStream()
592 sal_Int32
OMarkableInputStream::readBytes(Sequence
< sal_Int8
>& aData
, sal_Int32 nBytesToRead
)
593 throw ( NotConnectedException
,
594 BufferSizeExceededException
,
597 sal_Int32 nBytesRead
;
599 if( m_bValidStream
) {
600 MutexGuard
guard( m_mutex
);
601 if( m_mapMarks
.empty() && ! m_pBuffer
->getSize() ) {
603 nBytesRead
= m_input
->readBytes( aData
, nBytesToRead
);
609 // read enough bytes into buffer
610 if( m_pBuffer
->getSize() - m_nCurrentPos
< nBytesToRead
) {
611 sal_Int32 nToRead
= nBytesToRead
- ( m_pBuffer
->getSize() - m_nCurrentPos
);
612 nRead
= m_input
->readBytes( aData
, nToRead
);
614 OSL_ASSERT( aData
.getLength() == nRead
);
618 m_pBuffer
->writeAt( m_pBuffer
->getSize() , aData
);
620 catch( IRingBuffer_OutOfMemoryException
& ) {
621 throw BufferSizeExceededException();
623 catch( IRingBuffer_OutOfBoundsException
& ) {
624 throw BufferSizeExceededException();
627 if( nRead
< nToRead
) {
628 nBytesToRead
= nBytesToRead
- (nToRead
-nRead
);
632 OSL_ASSERT( m_pBuffer
->getSize() - m_nCurrentPos
>= nBytesToRead
);
634 m_pBuffer
->readAt( m_nCurrentPos
, aData
, nBytesToRead
);
636 m_nCurrentPos
+= nBytesToRead
;
637 nBytesRead
= nBytesToRead
;
641 throw NotConnectedException(
642 OUString("MarkableInputStream::readBytes NotConnectedException") ,
649 sal_Int32
OMarkableInputStream::readSomeBytes(Sequence
< sal_Int8
>& aData
, sal_Int32 nMaxBytesToRead
)
650 throw ( NotConnectedException
,
651 BufferSizeExceededException
,
655 sal_Int32 nBytesRead
;
656 if( m_bValidStream
) {
657 MutexGuard
guard( m_mutex
);
658 if( m_mapMarks
.empty() && ! m_pBuffer
->getSize() ) {
660 nBytesRead
= m_input
->readSomeBytes( aData
, nMaxBytesToRead
);
665 sal_Int32 nInBuffer
= m_pBuffer
->getSize() - m_nCurrentPos
;
666 sal_Int32 nAdditionalBytesToRead
= Min(nMaxBytesToRead
-nInBuffer
,m_input
->available());
667 nAdditionalBytesToRead
= Max(0 , nAdditionalBytesToRead
);
669 // read enough bytes into buffer
670 if( 0 == nInBuffer
) {
671 nRead
= m_input
->readSomeBytes( aData
, nMaxBytesToRead
);
673 else if( nAdditionalBytesToRead
) {
674 nRead
= m_input
->readBytes( aData
, nAdditionalBytesToRead
);
678 aData
.realloc( nRead
);
681 m_pBuffer
->writeAt( m_pBuffer
->getSize() , aData
);
683 catch( IRingBuffer_OutOfMemoryException
& )
685 throw BufferSizeExceededException();
687 catch( IRingBuffer_OutOfBoundsException
& )
689 throw BufferSizeExceededException();
693 nBytesRead
= Min( nMaxBytesToRead
, nInBuffer
+ nRead
);
695 // now take everything from buffer !
696 m_pBuffer
->readAt( m_nCurrentPos
, aData
, nBytesRead
);
698 m_nCurrentPos
+= nBytesRead
;
703 throw NotConnectedException(
704 OUString("MarkableInputStream::readSomeBytes NotConnectedException") ,
713 void OMarkableInputStream::skipBytes(sal_Int32 nBytesToSkip
)
714 throw ( NotConnectedException
,
715 BufferSizeExceededException
,
718 if ( nBytesToSkip
< 0 )
719 throw BufferSizeExceededException(
720 OUString("precondition not met: XInputStream::skipBytes: non-negative integer required!"),
724 // this method is blocking
725 Sequence
<sal_Int8
> seqDummy( nBytesToSkip
);
726 readBytes( seqDummy
, nBytesToSkip
);
729 sal_Int32
OMarkableInputStream::available(void) throw (NotConnectedException
, RuntimeException
)
732 if( m_bValidStream
) {
733 MutexGuard
guard( m_mutex
);
734 nAvail
= m_input
->available() + ( m_pBuffer
->getSize() - m_nCurrentPos
);
738 throw NotConnectedException(
739 OUString("MarkableInputStream::available NotConnectedException") ,
747 void OMarkableInputStream::closeInput(void) throw (NotConnectedException
, RuntimeException
)
749 if( m_bValidStream
) {
750 MutexGuard
guard( m_mutex
);
752 m_input
->closeInput();
754 setInputStream( Reference
< XInputStream
> () );
755 setPredecessor( Reference
< XConnectable
> () );
756 setSuccessor( Reference
< XConnectable
>() );
764 throw NotConnectedException(
765 OUString("MarkableInputStream::closeInput NotConnectedException") ,
772 sal_Int32
OMarkableInputStream::createMark(void) throw (IOException
, RuntimeException
)
774 MutexGuard
guard( m_mutex
);
775 sal_Int32 nMark
= m_nCurrentMark
;
777 m_mapMarks
[nMark
] = m_nCurrentPos
;
783 void OMarkableInputStream::deleteMark(sal_Int32 Mark
) throw (IOException
, IllegalArgumentException
, RuntimeException
)
785 MutexGuard
guard( m_mutex
);
786 map
<sal_Int32
,sal_Int32
,less
<sal_Int32
> >::iterator ii
= m_mapMarks
.find( Mark
);
788 if( ii
== m_mapMarks
.end() ) {
789 OUStringBuffer
buf( 128 );
790 buf
.appendAscii( "MarkableInputStream::deleteMark unknown mark (" );
792 buf
.appendAscii( ")");
793 throw IllegalArgumentException( buf
.makeStringAndClear(), *this , 0 );
796 m_mapMarks
.erase( ii
);
797 checkMarksAndFlush();
801 void OMarkableInputStream::jumpToMark(sal_Int32 nMark
)
803 IllegalArgumentException
,
806 MutexGuard
guard( m_mutex
);
807 map
<sal_Int32
,sal_Int32
,less
<sal_Int32
> >::iterator ii
= m_mapMarks
.find( nMark
);
809 if( ii
== m_mapMarks
.end() )
811 OUStringBuffer
buf( 128 );
812 buf
.appendAscii( "MarkableInputStream::jumpToMark unknown mark (" );
814 buf
.appendAscii( ")");
815 throw IllegalArgumentException( buf
.makeStringAndClear(), *this , 0 );
819 m_nCurrentPos
= (*ii
).second
;
823 void OMarkableInputStream::jumpToFurthest(void) throw (IOException
, RuntimeException
)
825 MutexGuard
guard( m_mutex
);
826 m_nCurrentPos
= m_pBuffer
->getSize();
827 checkMarksAndFlush();
830 sal_Int32
OMarkableInputStream::offsetToMark(sal_Int32 nMark
)
832 IllegalArgumentException
,
835 MutexGuard
guard( m_mutex
);
836 map
<sal_Int32
,sal_Int32
,less
<sal_Int32
> >::const_iterator ii
= m_mapMarks
.find( nMark
);
838 if( ii
== m_mapMarks
.end() )
840 OUStringBuffer
buf( 128 );
841 buf
.appendAscii( "MarkableInputStream::offsetToMark unknown mark (" );
843 buf
.appendAscii( ")");
844 throw IllegalArgumentException( buf
.makeStringAndClear(), *this , 0 );
846 return m_nCurrentPos
- (*ii
).second
;
856 void OMarkableInputStream::setInputStream(const Reference
< XInputStream
> & aStream
)
857 throw (RuntimeException
)
860 if( m_input
!= aStream
) {
863 Reference
< XConnectable
> pred( m_input
, UNO_QUERY
);
864 setPredecessor( pred
);
867 m_bValidStream
= m_input
.is();
871 Reference
< XInputStream
> OMarkableInputStream::getInputStream(void) throw (RuntimeException
)
879 void OMarkableInputStream::setSuccessor( const Reference
< XConnectable
> &r
)
880 throw (RuntimeException
)
882 /// if the references match, nothing needs to be done
884 /// store the reference for later use
888 /// set this instance as the sink !
889 m_succ
->setPredecessor( Reference
< XConnectable
> (
890 (static_cast< XConnectable
* >(this)) ) );
895 Reference
< XConnectable
> OMarkableInputStream::getSuccessor() throw (RuntimeException
)
902 void OMarkableInputStream::setPredecessor( const Reference
< XConnectable
> &r
)
903 throw (RuntimeException
)
908 m_pred
->setSuccessor( Reference
< XConnectable
> (
909 (static_cast< XConnectable
* >(this)) ) );
913 Reference
< XConnectable
> OMarkableInputStream::getPredecessor() throw (RuntimeException
)
921 void OMarkableInputStream::checkMarksAndFlush()
923 map
<sal_Int32
,sal_Int32
,less
<sal_Int32
> >::iterator ii
;
925 // find the smallest mark
926 sal_Int32 nNextFound
= m_nCurrentPos
;
927 for( ii
= m_mapMarks
.begin() ; ii
!= m_mapMarks
.end() ; ++ii
) {
928 if( (*ii
).second
<= nNextFound
) {
929 nNextFound
= (*ii
).second
;
934 // some data must be released !
935 m_nCurrentPos
-= nNextFound
;
936 for( ii
= m_mapMarks
.begin() ; ii
!= m_mapMarks
.end() ; ++ii
) {
937 (*ii
).second
-= nNextFound
;
940 m_pBuffer
->forgetFromStart( nNextFound
);
944 // nothing to do. There is a mark or the current cursor position, that prevents
952 OUString
OMarkableInputStream::getImplementationName() throw ()
954 return OMarkableInputStream_getImplementationName();
958 sal_Bool
OMarkableInputStream::supportsService(const OUString
& ServiceName
) throw ()
960 Sequence
< OUString
> aSNL
= getSupportedServiceNames();
961 const OUString
* pArray
= aSNL
.getConstArray();
963 for( sal_Int32 i
= 0; i
< aSNL
.getLength(); i
++ )
964 if( pArray
[i
] == ServiceName
)
971 Sequence
< OUString
> OMarkableInputStream::getSupportedServiceNames(void) throw ()
973 return OMarkableInputStream_getSupportedServiceNames();
977 /*------------------------
981 *------------------------*/
982 Reference
< XInterface
> SAL_CALL
OMarkableInputStream_CreateInstance(
983 SAL_UNUSED_PARAMETER
const Reference
< XComponentContext
> & )
986 OMarkableInputStream
*p
= new OMarkableInputStream( );
987 return Reference
< XInterface
> ( (OWeakObject
* ) p
);
990 OUString
OMarkableInputStream_getImplementationName()
992 return OUString("com.sun.star.comp.io.stm.MarkableInputStream");
995 Sequence
<OUString
> OMarkableInputStream_getSupportedServiceNames(void)
997 Sequence
<OUString
> aRet(1);
998 aRet
.getArray()[0] = "com.sun.star.io.MarkableInputStream";
1004 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */