LibreOffice Module io (master) 1
omark.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20
21#include <map>
22#include <memory>
23
24#include <com/sun/star/io/BufferSizeExceededException.hpp>
25#include <com/sun/star/io/NotConnectedException.hpp>
26#include <com/sun/star/io/XMarkableStream.hpp>
27#include <com/sun/star/io/XOutputStream.hpp>
28#include <com/sun/star/io/XInputStream.hpp>
29#include <com/sun/star/io/XActiveDataSource.hpp>
30#include <com/sun/star/io/XActiveDataSink.hpp>
31#include <com/sun/star/io/XConnectable.hpp>
32#include <com/sun/star/lang/IllegalArgumentException.hpp>
33#include <com/sun/star/lang/XServiceInfo.hpp>
34#include <com/sun/star/uno/XComponentContext.hpp>
35
36#include <cppuhelper/weak.hxx>
39
40#include <osl/diagnose.h>
41#include <mutex>
42
43using namespace ::cppu;
44using namespace ::osl;
45using namespace ::com::sun::star::io;
46using namespace ::com::sun::star::uno;
47using namespace ::com::sun::star::lang;
48
49#include "streamhelper.hxx"
50
51namespace io_stm {
52
53namespace {
54
55/***********************
56*
57* OMarkableOutputStream.
58*
59* This object allows to set marks in an outputstream. It is allowed to jump back to the marks and
60* rewrite the same bytes.
61*
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.
65*
66**********************/
67class OMarkableOutputStream :
68 public WeakImplHelper< XOutputStream ,
69 XActiveDataSource ,
70 XMarkableStream ,
71 XConnectable,
72 XServiceInfo
73 >
74{
75public:
76 OMarkableOutputStream( );
77
78public: // XOutputStream
79 virtual void SAL_CALL writeBytes(const Sequence< sal_Int8 >& aData) override;
80 virtual void SAL_CALL flush() override;
81 virtual void SAL_CALL closeOutput() override;
82
83public: // XMarkable
84 virtual sal_Int32 SAL_CALL createMark() override;
85 virtual void SAL_CALL deleteMark(sal_Int32 Mark) override;
86 virtual void SAL_CALL jumpToMark(sal_Int32 nMark) override;
87 virtual void SAL_CALL jumpToFurthest() override;
88 virtual sal_Int32 SAL_CALL offsetToMark(sal_Int32 nMark) override;
89
90public: // XActiveDataSource
91 virtual void SAL_CALL setOutputStream(const Reference < XOutputStream > & aStream) override;
92 virtual Reference < XOutputStream > SAL_CALL getOutputStream() override;
93
94public: // XConnectable
95 virtual void SAL_CALL setPredecessor(const Reference < XConnectable > & aPredecessor) override;
96 virtual Reference < XConnectable > SAL_CALL getPredecessor() override;
97 virtual void SAL_CALL setSuccessor(const Reference < XConnectable >& aSuccessor) override;
98 virtual Reference< XConnectable > SAL_CALL getSuccessor() override;
99
100public: // XServiceInfo
101 OUString SAL_CALL getImplementationName() override;
103 sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override;
104
105private:
106 // helper methods
109 void checkMarksAndFlush();
110
113
116
117 MemRingBuffer m_aRingBuffer;
118 std::map<sal_Int32,sal_Int32,std::less< sal_Int32 > > m_mapMarks;
119 sal_Int32 m_nCurrentPos;
120 sal_Int32 m_nCurrentMark;
121
122 std::mutex m_mutex;
123};
124
125}
126
127OMarkableOutputStream::OMarkableOutputStream( )
128 : m_bValidStream(false)
129 , m_nCurrentPos(0)
130 , m_nCurrentMark(0)
131{
132}
133
134// XOutputStream
135void OMarkableOutputStream::writeBytes(const Sequence< sal_Int8 >& aData)
136{
137 if( !m_bValidStream ) {
138 throw NotConnectedException();
139 }
140 if( m_mapMarks.empty() && ( m_aRingBuffer.getSize() == 0 ) ) {
141 // no mark and buffer active, simple write through
142 m_output->writeBytes( aData );
143 }
144 else {
145 std::unique_lock guard( m_mutex );
146 // new data must be buffered
147 m_aRingBuffer.writeAt( m_nCurrentPos , aData );
148 m_nCurrentPos += aData.getLength();
149 checkMarksAndFlush();
150 }
151
152}
153
154void OMarkableOutputStream::flush()
155{
157 {
158 std::unique_lock guard( m_mutex );
159 output = m_output;
160 }
161
162 // Markable cannot flush buffered data, because the data may get rewritten,
163 // however one can forward the flush to the chained stream to give it
164 // a chance to write data buffered in the chained stream.
165 if( output.is() )
166 {
167 output->flush();
168 }
169}
170
171void OMarkableOutputStream::closeOutput()
172{
173 if( !m_bValidStream ) {
174 throw NotConnectedException();
175 }
176 std::unique_lock guard( m_mutex );
177 // all marks must be cleared and all
178
179 m_mapMarks.clear();
180 m_nCurrentPos = m_aRingBuffer.getSize();
181 checkMarksAndFlush();
182
183 m_output->closeOutput();
184
185 setOutputStream( Reference< XOutputStream > () );
186 setPredecessor( Reference < XConnectable >() );
187 setSuccessor( Reference< XConnectable > () );
188
189}
190
191
192sal_Int32 OMarkableOutputStream::createMark()
193{
194 std::unique_lock guard( m_mutex );
195 sal_Int32 nMark = m_nCurrentMark;
196
197 m_mapMarks[nMark] = m_nCurrentPos;
198
200 return nMark;
201}
202
203void OMarkableOutputStream::deleteMark(sal_Int32 Mark)
204{
205 std::unique_lock guard( m_mutex );
206 std::map<sal_Int32,sal_Int32,std::less<sal_Int32> >::iterator ii = m_mapMarks.find( Mark );
207
208 if( ii == m_mapMarks.end() ) {
209 throw IllegalArgumentException(
210 "MarkableOutputStream::deleteMark unknown mark (" + OUString::number(Mark) + ")",
211 *this, 0);
212 }
213 m_mapMarks.erase( ii );
214 checkMarksAndFlush();
215}
216
217void OMarkableOutputStream::jumpToMark(sal_Int32 nMark)
218{
219 std::unique_lock guard( m_mutex );
220 std::map<sal_Int32,sal_Int32,std::less<sal_Int32> >::iterator ii = m_mapMarks.find( nMark );
221
222 if( ii == m_mapMarks.end() ) {
223 throw IllegalArgumentException(
224 "MarkableOutputStream::jumpToMark unknown mark (" + OUString::number(nMark) + ")",
225 *this, 0);
226 }
227 m_nCurrentPos = (*ii).second;
228}
229
230void OMarkableOutputStream::jumpToFurthest()
231{
232 std::unique_lock guard( m_mutex );
233 m_nCurrentPos = m_aRingBuffer.getSize();
234 checkMarksAndFlush();
235}
236
237sal_Int32 OMarkableOutputStream::offsetToMark(sal_Int32 nMark)
238{
239
240 std::unique_lock guard( m_mutex );
241 std::map<sal_Int32,sal_Int32,std::less<sal_Int32> >::const_iterator ii = m_mapMarks.find( nMark );
242
243 if( ii == m_mapMarks.end() )
244 {
245 throw IllegalArgumentException(
246 "MarkableOutputStream::offsetToMark unknown mark (" + OUString::number(nMark) + ")",
247 *this, 0);
248 }
249 return m_nCurrentPos - (*ii).second;
250}
251
252
253// XActiveDataSource2
254void OMarkableOutputStream::setOutputStream(const Reference < XOutputStream >& aStream)
255{
256 if( m_output != aStream ) {
257 m_output = aStream;
258
259 Reference < XConnectable > succ( m_output , UNO_QUERY );
260 setSuccessor( succ );
261 }
263}
264
265Reference< XOutputStream > OMarkableOutputStream::getOutputStream()
266{
267 return m_output;
268}
269
270
271void OMarkableOutputStream::setSuccessor( const Reference< XConnectable > &r )
272{
274 if( m_succ != r ) {
276 m_succ = r;
277
278 if( m_succ.is() ) {
279 m_succ->setPredecessor( Reference < XConnectable > (
280 static_cast< XConnectable * >(this) ) );
281 }
282 }
283}
284Reference <XConnectable > OMarkableOutputStream::getSuccessor()
285{
286 return m_succ;
287}
288
289
290// XDataSource
291void OMarkableOutputStream::setPredecessor( const Reference< XConnectable > &r )
292{
293 if( r != m_pred ) {
294 m_pred = r;
295 if( m_pred.is() ) {
296 m_pred->setSuccessor( Reference < XConnectable > (
297 static_cast< XConnectable * >(this ) ) );
298 }
299 }
300}
301Reference < XConnectable > OMarkableOutputStream::getPredecessor()
302{
303 return m_pred;
304}
305
306
307// private methods
308
309void OMarkableOutputStream::checkMarksAndFlush()
310{
311 // find the smallest mark
312 sal_Int32 nNextFound = m_nCurrentPos;
313 for (auto const& mark : m_mapMarks)
314 {
315 if( mark.second <= nNextFound ) {
316 nNextFound = mark.second;
317 }
318 }
319
320 if( nNextFound ) {
321 // some data must be released !
322 m_nCurrentPos -= nNextFound;
323 for (auto & mark : m_mapMarks)
324 {
325 mark.second -= nNextFound;
326 }
327
328 Sequence<sal_Int8> seq(nNextFound);
329 m_aRingBuffer.readAt( 0 , seq , nNextFound );
330 m_aRingBuffer.forgetFromStart( nNextFound );
331
332 // now write data through to streams
333 m_output->writeBytes( seq );
334 }
335 else {
336 // nothing to do. There is a mark or the current cursor position, that prevents
337 // releasing data !
338 }
339}
340
341
342// XServiceInfo
343OUString OMarkableOutputStream::getImplementationName()
344{
345 return "com.sun.star.comp.io.stm.MarkableOutputStream";
346}
347
348// XServiceInfo
349sal_Bool OMarkableOutputStream::supportsService(const OUString& ServiceName)
350{
351 return cppu::supportsService(this, ServiceName);
352}
353
354// XServiceInfo
355Sequence< OUString > OMarkableOutputStream::getSupportedServiceNames()
356{
357 return { "com.sun.star.io.MarkableOutputStream" };
358}
359
360extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
362 css::uno::XComponentContext* , css::uno::Sequence<css::uno::Any> const&)
363{
364 return cppu::acquire(new OMarkableOutputStream());
365}
366
367
368// XMarkableInputStream
369
370namespace {
371
372class OMarkableInputStream :
373 public WeakImplHelper
374 <
375 XInputStream,
376 XActiveDataSink,
377 XMarkableStream,
378 XConnectable,
379 XServiceInfo
380 >
381{
382public:
383 OMarkableInputStream( );
384
385
386public: // XInputStream
387 virtual sal_Int32 SAL_CALL readBytes(Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead) override ;
388 virtual sal_Int32 SAL_CALL readSomeBytes(Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead) override;
389 virtual void SAL_CALL skipBytes(sal_Int32 nBytesToSkip) override;
390
391 virtual sal_Int32 SAL_CALL available() override;
392 virtual void SAL_CALL closeInput() override;
393
394public: // XMarkable
395 virtual sal_Int32 SAL_CALL createMark() override;
396 virtual void SAL_CALL deleteMark(sal_Int32 Mark) override;
397 virtual void SAL_CALL jumpToMark(sal_Int32 nMark) override;
398 virtual void SAL_CALL jumpToFurthest() override;
399 virtual sal_Int32 SAL_CALL offsetToMark(sal_Int32 nMark) override;
400
401public: // XActiveDataSink
402 virtual void SAL_CALL setInputStream(const Reference < XInputStream > & aStream) override;
403 virtual Reference < XInputStream > SAL_CALL getInputStream() override;
404
405public: // XConnectable
406 virtual void SAL_CALL setPredecessor(const Reference < XConnectable > & aPredecessor) override;
407 virtual Reference < XConnectable > SAL_CALL getPredecessor() override;
408 virtual void SAL_CALL setSuccessor(const Reference < XConnectable > & aSuccessor) override;
409 virtual Reference < XConnectable > SAL_CALL getSuccessor() override;
410
411public: // XServiceInfo
412 OUString SAL_CALL getImplementationName() override;
414 sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override;
415
416private:
417 void checkMarksAndFlush();
418
421
423 bool m_bValidStream;
424
425 std::unique_ptr<MemRingBuffer> m_pBuffer;
426 std::map<sal_Int32,sal_Int32,std::less< sal_Int32 > > m_mapMarks;
427 sal_Int32 m_nCurrentPos;
428 sal_Int32 m_nCurrentMark;
429
430 std::mutex m_mutex;
431};
432
433}
434
435OMarkableInputStream::OMarkableInputStream()
436 : m_bValidStream(false)
437 , m_nCurrentPos(0)
438 , m_nCurrentMark(0)
439{
440 m_pBuffer.reset( new MemRingBuffer );
441}
442
443
444// XInputStream
445
446sal_Int32 OMarkableInputStream::readBytes(Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead)
447{
448 sal_Int32 nBytesRead;
449
450 if( !m_bValidStream ) {
451 throw NotConnectedException(
452 "MarkableInputStream::readBytes NotConnectedException",
453 *this );
454 }
455 std::unique_lock guard( m_mutex );
456 if( m_mapMarks.empty() && ! m_pBuffer->getSize() ) {
457 // normal read !
458 nBytesRead = m_input->readBytes( aData, nBytesToRead );
459 }
460 else {
461 // read from buffer
462 sal_Int32 nRead;
463
464 // read enough bytes into buffer
465 if( m_pBuffer->getSize() - m_nCurrentPos < nBytesToRead ) {
466 sal_Int32 nToRead = nBytesToRead - ( m_pBuffer->getSize() - m_nCurrentPos );
467 nRead = m_input->readBytes( aData , nToRead );
468
469 OSL_ASSERT( aData.getLength() == nRead );
470
471 m_pBuffer->writeAt( m_pBuffer->getSize() , aData );
472
473 if( nRead < nToRead ) {
474 nBytesToRead = nBytesToRead - (nToRead-nRead);
475 }
476 }
477
478 OSL_ASSERT( m_pBuffer->getSize() - m_nCurrentPos >= nBytesToRead );
479
480 m_pBuffer->readAt( m_nCurrentPos , aData , nBytesToRead );
481
482 m_nCurrentPos += nBytesToRead;
483 nBytesRead = nBytesToRead;
484 }
485
486 return nBytesRead;
487}
488
489
490sal_Int32 OMarkableInputStream::readSomeBytes(Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead)
491{
492
493 sal_Int32 nBytesRead;
494 if( !m_bValidStream ) {
495 throw NotConnectedException(
496 "MarkableInputStream::readSomeBytes NotConnectedException",
497 *this );
498 }
499
500 std::unique_lock guard( m_mutex );
501 if( m_mapMarks.empty() && ! m_pBuffer->getSize() ) {
502 // normal read !
503 nBytesRead = m_input->readSomeBytes( aData, nMaxBytesToRead );
504 }
505 else {
506 // read from buffer
507 sal_Int32 nRead = 0;
508 sal_Int32 nInBuffer = m_pBuffer->getSize() - m_nCurrentPos;
509 sal_Int32 nAdditionalBytesToRead = std::min<sal_Int32>(nMaxBytesToRead-nInBuffer,m_input->available());
510 nAdditionalBytesToRead = std::max<sal_Int32>(0 , nAdditionalBytesToRead );
511
512 // read enough bytes into buffer
513 if( 0 == nInBuffer ) {
514 nRead = m_input->readSomeBytes( aData , nMaxBytesToRead );
515 }
516 else if( nAdditionalBytesToRead ) {
517 nRead = m_input->readBytes( aData , nAdditionalBytesToRead );
518 }
519
520 if( nRead ) {
521 aData.realloc( nRead );
522 m_pBuffer->writeAt( m_pBuffer->getSize() , aData );
523 }
524
525 nBytesRead = std::min( nMaxBytesToRead , nInBuffer + nRead );
526
527 // now take everything from buffer !
528 m_pBuffer->readAt( m_nCurrentPos , aData , nBytesRead );
529
530 m_nCurrentPos += nBytesRead;
531 }
532
533 return nBytesRead;
534
535
536}
537
538
539void OMarkableInputStream::skipBytes(sal_Int32 nBytesToSkip)
540{
541 if ( nBytesToSkip < 0 )
542 throw BufferSizeExceededException(
543 "precondition not met: XInputStream::skipBytes: non-negative integer required!",
544 *this
545 );
546
547 // this method is blocking
548 Sequence<sal_Int8> seqDummy( nBytesToSkip );
549 readBytes( seqDummy , nBytesToSkip );
550}
551
552sal_Int32 OMarkableInputStream::available()
553{
554 if( !m_bValidStream ) {
555 throw NotConnectedException(
556 "MarkableInputStream::available NotConnectedException",
557 *this );
558 }
559
560 std::unique_lock guard( m_mutex );
561 sal_Int32 nAvail = m_input->available() + ( m_pBuffer->getSize() - m_nCurrentPos );
562 return nAvail;
563}
564
565
566void OMarkableInputStream::closeInput()
567{
568 if( !m_bValidStream ) {
569 throw NotConnectedException(
570 "MarkableInputStream::closeInput NotConnectedException",
571 *this );
572 }
573 std::unique_lock guard( m_mutex );
574
575 m_input->closeInput();
576
577 setInputStream( Reference< XInputStream > () );
578 setPredecessor( Reference< XConnectable > () );
579 setSuccessor( Reference< XConnectable >() );
580
581 m_pBuffer.reset();
582 m_nCurrentPos = 0;
583 m_nCurrentMark = 0;
584}
585
586// XMarkable
587
588sal_Int32 OMarkableInputStream::createMark()
589{
590 std::unique_lock guard( m_mutex );
591 sal_Int32 nMark = m_nCurrentMark;
592
593 m_mapMarks[nMark] = m_nCurrentPos;
594
596 return nMark;
597}
598
599void OMarkableInputStream::deleteMark(sal_Int32 Mark)
600{
601 std::unique_lock guard( m_mutex );
602 std::map<sal_Int32,sal_Int32,std::less<sal_Int32> >::iterator ii = m_mapMarks.find( Mark );
603
604 if( ii == m_mapMarks.end() ) {
605 throw IllegalArgumentException(
606 "MarkableInputStream::deleteMark unknown mark (" + OUString::number(Mark) + ")",
607 *this , 0 );
608 }
609 m_mapMarks.erase( ii );
610 checkMarksAndFlush();
611}
612
613void OMarkableInputStream::jumpToMark(sal_Int32 nMark)
614{
615 std::unique_lock guard( m_mutex );
616 std::map<sal_Int32,sal_Int32,std::less<sal_Int32> >::iterator ii = m_mapMarks.find( nMark );
617
618 if( ii == m_mapMarks.end() )
619 {
620 throw IllegalArgumentException(
621 "MarkableInputStream::jumpToMark unknown mark (" + OUString::number(nMark) + ")",
622 *this , 0 );
623 }
624 m_nCurrentPos = (*ii).second;
625}
626
627void OMarkableInputStream::jumpToFurthest()
628{
629 std::unique_lock guard( m_mutex );
630 m_nCurrentPos = m_pBuffer->getSize();
631 checkMarksAndFlush();
632}
633
634sal_Int32 OMarkableInputStream::offsetToMark(sal_Int32 nMark)
635{
636 std::unique_lock guard( m_mutex );
637 std::map<sal_Int32,sal_Int32,std::less<sal_Int32> >::const_iterator ii = m_mapMarks.find( nMark );
638
639 if( ii == m_mapMarks.end() )
640 {
641 throw IllegalArgumentException(
642 "MarkableInputStream::offsetToMark unknown mark (" + OUString::number(nMark) + ")",
643 *this, 0 );
644 }
645 return m_nCurrentPos - (*ii).second;
646}
647
648
649// XActiveDataSource
650void OMarkableInputStream::setInputStream(const Reference< XInputStream > & aStream)
651{
652
653 if( m_input != aStream ) {
654 m_input = aStream;
655
656 Reference < XConnectable > pred( m_input , UNO_QUERY );
657 setPredecessor( pred );
658 }
659
660 m_bValidStream = m_input.is();
661
662}
663
664Reference< XInputStream > OMarkableInputStream::getInputStream()
665{
666 return m_input;
667}
668
669
670// XDataSink
671void OMarkableInputStream::setSuccessor( const Reference< XConnectable > &r )
672{
674 if( m_succ != r ) {
676 m_succ = r;
677
678 if( m_succ.is() ) {
680 m_succ->setPredecessor( Reference< XConnectable > (
681 static_cast< XConnectable * >(this) ) );
682 }
683 }
684}
685
686Reference < XConnectable > OMarkableInputStream::getSuccessor()
687{
688 return m_succ;
689}
690
691
692// XDataSource
693void OMarkableInputStream::setPredecessor( const Reference < XConnectable > &r )
694{
695 if( r != m_pred ) {
696 m_pred = r;
697 if( m_pred.is() ) {
698 m_pred->setSuccessor( Reference< XConnectable > (
699 static_cast< XConnectable * >(this) ) );
700 }
701 }
702}
703Reference< XConnectable > OMarkableInputStream::getPredecessor()
704{
705 return m_pred;
706}
707
708
709void OMarkableInputStream::checkMarksAndFlush()
710{
711 // find the smallest mark
712 sal_Int32 nNextFound = m_nCurrentPos;
713 for (auto const& mark : m_mapMarks)
714 {
715 if( mark.second <= nNextFound ) {
716 nNextFound = mark.second;
717 }
718 }
719
720 if( nNextFound ) {
721 // some data must be released !
722 m_nCurrentPos -= nNextFound;
723 for (auto & mark : m_mapMarks)
724 {
725 mark.second -= nNextFound;
726 }
727
728 m_pBuffer->forgetFromStart( nNextFound );
729
730 }
731 else {
732 // nothing to do. There is a mark or the current cursor position, that prevents
733 // releasing data !
734 }
735}
736
737// XServiceInfo
738OUString OMarkableInputStream::getImplementationName()
739{
740 return "com.sun.star.comp.io.stm.MarkableInputStream";
741}
742
743// XServiceInfo
744sal_Bool OMarkableInputStream::supportsService(const OUString& ServiceName)
745{
746 return cppu::supportsService(this, ServiceName);
747}
748
749// XServiceInfo
750Sequence< OUString > OMarkableInputStream::getSupportedServiceNames()
751{
752 return { "com.sun.star.io.MarkableInputStream" };
753}
754
755extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
757 css::uno::XComponentContext* , css::uno::Sequence<css::uno::Any> const&)
758{
759 return cppu::acquire(new OMarkableInputStream());
760}
761
762}
763
764/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
constexpr OUStringLiteral aData
css::uno::Sequence< OUString > getSupportedServiceNames()
OUString getImplementationName()
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
Definition: odata.cxx:47
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * io_OMarkableInputStream_get_implementation(css::uno::XComponentContext *, css::uno::Sequence< css::uno::Any > const &)
Definition: omark.cxx:756
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * io_OMarkableOutputStream_get_implementation(css::uno::XComponentContext *, css::uno::Sequence< css::uno::Any > const &)
Definition: omark.cxx:361
bool getOutputStream(ProgramOptions const &options, OString const &extension, std::ostream **ppOutputStream, OString &targetSourceFileName, OString &tmpSourceFileName)
Reference< XConnectable > m_succ
Definition: omark.cxx:111
std::map< sal_Int32, sal_Int32, std::less< sal_Int32 > > m_mapMarks
Definition: omark.cxx:118
std::unique_ptr< MemRingBuffer > m_pBuffer
Definition: omark.cxx:425
std::mutex m_mutex
Definition: omark.cxx:122
Reference< XOutputStream > m_output
Definition: omark.cxx:114
sal_Int32 m_nCurrentPos
Definition: omark.cxx:119
Reference< XConnectable > m_pred
Definition: omark.cxx:112
bool m_bValidStream
Definition: omark.cxx:115
Reference< XInputStream > m_input
Definition: omark.cxx:422
sal_Int32 m_nCurrentMark
Definition: omark.cxx:120
MemRingBuffer m_aRingBuffer
Definition: omark.cxx:117
unsigned char sal_Bool