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
OMarkableOutputStream()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
~OMarkableOutputStream()162cdf0e10cSrcweir OMarkableOutputStream::~OMarkableOutputStream()
163cdf0e10cSrcweir {
164cdf0e10cSrcweir delete m_pBuffer;
165cdf0e10cSrcweir g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
166cdf0e10cSrcweir }
167cdf0e10cSrcweir
168cdf0e10cSrcweir
169cdf0e10cSrcweir // XOutputStream
writeBytes(const Sequence<sal_Int8> & aData)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
flush(void)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
closeOutput(void)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
createMark(void)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
deleteMark(sal_Int32 Mark)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
jumpToMark(sal_Int32 nMark)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
jumpToFurthest(void)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
offsetToMark(sal_Int32 nMark)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
setOutputStream(const Reference<XOutputStream> & aStream)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
getOutputStream(void)350cdf0e10cSrcweir Reference< XOutputStream > OMarkableOutputStream::getOutputStream(void) throw (RuntimeException)
351cdf0e10cSrcweir {
352cdf0e10cSrcweir return m_output;
353cdf0e10cSrcweir }
354cdf0e10cSrcweir
355cdf0e10cSrcweir
356cdf0e10cSrcweir
setSuccessor(const Reference<XConnectable> & r)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 }
getSuccessor()371cdf0e10cSrcweir Reference <XConnectable > OMarkableOutputStream::getSuccessor() throw (RuntimeException)
372cdf0e10cSrcweir {
373cdf0e10cSrcweir return m_succ;
374cdf0e10cSrcweir }
375cdf0e10cSrcweir
376cdf0e10cSrcweir
377cdf0e10cSrcweir // XDataSource
setPredecessor(const Reference<XConnectable> & r)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 }
getPredecessor()389cdf0e10cSrcweir Reference < XConnectable > OMarkableOutputStream::getPredecessor() throw (RuntimeException)
390cdf0e10cSrcweir {
391cdf0e10cSrcweir return m_pred;
392cdf0e10cSrcweir }
393cdf0e10cSrcweir
394cdf0e10cSrcweir
395cdf0e10cSrcweir // private methods
396cdf0e10cSrcweir
checkMarksAndFlush()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
getImplementationName()432cdf0e10cSrcweir OUString OMarkableOutputStream::getImplementationName() throw ()
433cdf0e10cSrcweir {
434cdf0e10cSrcweir return OMarkableOutputStream_getImplementationName();
435cdf0e10cSrcweir }
436cdf0e10cSrcweir
437cdf0e10cSrcweir // XServiceInfo
supportsService(const OUString & ServiceName)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
getSupportedServiceNames(void)451cdf0e10cSrcweir Sequence< OUString > OMarkableOutputStream::getSupportedServiceNames(void) throw ()
452cdf0e10cSrcweir {
453cdf0e10cSrcweir return OMarkableOutputStream_getSupportedServiceNames();
454cdf0e10cSrcweir }
455cdf0e10cSrcweir
456cdf0e10cSrcweir
457cdf0e10cSrcweir
458cdf0e10cSrcweir
459cdf0e10cSrcweir /*------------------------
460cdf0e10cSrcweir *
461cdf0e10cSrcweir * external binding
462cdf0e10cSrcweir *
463cdf0e10cSrcweir *------------------------*/
OMarkableOutputStream_CreateInstance(const Reference<XComponentContext> &)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
OMarkableOutputStream_getImplementationName()471cdf0e10cSrcweir OUString OMarkableOutputStream_getImplementationName()
472cdf0e10cSrcweir {
473cdf0e10cSrcweir return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.io.stm.MarkableOutputStream" ));
474cdf0e10cSrcweir }
475cdf0e10cSrcweir
OMarkableOutputStream_getSupportedServiceNames(void)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
OMarkableInputStream()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
~OMarkableInputStream()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
readBytes(Sequence<sal_Int8> & aData,sal_Int32 nBytesToRead)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
readSomeBytes(Sequence<sal_Int8> & aData,sal_Int32 nMaxBytesToRead)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
skipBytes(sal_Int32 nBytesToSkip)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
available(void)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
closeInput(void)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
createMark(void)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
deleteMark(sal_Int32 Mark)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
jumpToMark(sal_Int32 nMark)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
jumpToFurthest(void)833cdf0e10cSrcweir void OMarkableInputStream::jumpToFurthest(void) throw (IOException, RuntimeException)
834cdf0e10cSrcweir {
835cdf0e10cSrcweir MutexGuard guard( m_mutex );
836cdf0e10cSrcweir m_nCurrentPos = m_pBuffer->getSize();
837cdf0e10cSrcweir checkMarksAndFlush();
838cdf0e10cSrcweir }
839cdf0e10cSrcweir
offsetToMark(sal_Int32 nMark)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
setInputStream(const Reference<XInputStream> & aStream)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
getInputStream(void)881cdf0e10cSrcweir Reference< XInputStream > OMarkableInputStream::getInputStream(void) throw (RuntimeException)
882cdf0e10cSrcweir {
883cdf0e10cSrcweir return m_input;
884cdf0e10cSrcweir }
885cdf0e10cSrcweir
886cdf0e10cSrcweir
887cdf0e10cSrcweir
888cdf0e10cSrcweir // XDataSink
setSuccessor(const Reference<XConnectable> & r)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
getSuccessor()905cdf0e10cSrcweir Reference < XConnectable > OMarkableInputStream::getSuccessor() throw (RuntimeException)
906cdf0e10cSrcweir {
907cdf0e10cSrcweir return m_succ;
908cdf0e10cSrcweir }
909cdf0e10cSrcweir
910cdf0e10cSrcweir
911cdf0e10cSrcweir // XDataSource
setPredecessor(const Reference<XConnectable> & r)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 }
getPredecessor()923cdf0e10cSrcweir Reference< XConnectable > OMarkableInputStream::getPredecessor() throw (RuntimeException)
924cdf0e10cSrcweir {
925cdf0e10cSrcweir return m_pred;
926cdf0e10cSrcweir }
927cdf0e10cSrcweir
928cdf0e10cSrcweir
929cdf0e10cSrcweir
930cdf0e10cSrcweir
checkMarksAndFlush()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
getImplementationName()962cdf0e10cSrcweir OUString OMarkableInputStream::getImplementationName() throw ()
963cdf0e10cSrcweir {
964cdf0e10cSrcweir return OMarkableInputStream_getImplementationName();
965cdf0e10cSrcweir }
966cdf0e10cSrcweir
967cdf0e10cSrcweir // XServiceInfo
supportsService(const OUString & ServiceName)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
getSupportedServiceNames(void)981cdf0e10cSrcweir Sequence< OUString > OMarkableInputStream::getSupportedServiceNames(void) throw ()
982cdf0e10cSrcweir {
983cdf0e10cSrcweir return OMarkableInputStream_getSupportedServiceNames();
984cdf0e10cSrcweir }
985cdf0e10cSrcweir
986cdf0e10cSrcweir
987cdf0e10cSrcweir /*------------------------
988cdf0e10cSrcweir *
989cdf0e10cSrcweir * external binding
990cdf0e10cSrcweir *
991cdf0e10cSrcweir *------------------------*/
OMarkableInputStream_CreateInstance(const Reference<XComponentContext> &)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
OMarkableInputStream_getImplementationName()999cdf0e10cSrcweir OUString OMarkableInputStream_getImplementationName()
1000cdf0e10cSrcweir {
1001cdf0e10cSrcweir return OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.io.stm.MarkableInputStream" ));
1002cdf0e10cSrcweir }
1003cdf0e10cSrcweir
OMarkableInputStream_getSupportedServiceNames(void)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