Coverage Report

Created: 2025-11-16 09:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/ucb/source/ucp/tdoc/tdoc_stgelems.cxx
Line
Count
Source
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
/**************************************************************************
22
                                TODO
23
 **************************************************************************
24
25
 - remove root storage access workaround
26
27
 *************************************************************************/
28
29
#include <comphelper/diagnose_ex.hxx>
30
#include <com/sun/star/io/IOException.hpp>
31
#include <com/sun/star/lang/DisposedException.hpp>
32
#include <com/sun/star/reflection/ProxyFactory.hpp>
33
#include <utility>
34
35
#include "tdoc_docmgr.hxx"
36
#include "tdoc_uri.hxx"
37
38
#include "tdoc_stgelems.hxx"
39
40
using namespace com::sun::star;
41
using namespace tdoc_ucp;
42
43
44
// ParentStorageHolder Implementation.
45
46
47
ParentStorageHolder::ParentStorageHolder(
48
            uno::Reference< embed::XStorage > xParentStorage,
49
            const OUString & rUri )
50
0
: m_xParentStorage(std::move( xParentStorage )),
51
0
  m_bParentIsRootStorage( false )
52
0
{
53
0
    Uri aUri( rUri );
54
0
    if ( aUri.isDocument() )
55
0
        m_bParentIsRootStorage = true;
56
0
}
57
58
59
// Storage Implementation.
60
61
62
Storage::Storage( const uno::Reference< uno::XComponentContext > & rxContext,
63
                  rtl::Reference< StorageElementFactory > xFactory,
64
                  const OUString & rUri,
65
                  const uno::Reference< embed::XStorage > & xParentStorage,
66
                  const uno::Reference< embed::XStorage > & xStorageToWrap )
67
0
: ParentStorageHolder( xParentStorage, Uri( rUri ).getParentUri() ),
68
0
  m_xFactory(std::move( xFactory )),
69
0
  m_xWrappedStorage( xStorageToWrap ),
70
0
  m_xWrappedTransObj( xStorageToWrap, uno::UNO_QUERY ), // optional interface
71
0
  m_xWrappedComponent( xStorageToWrap ),
72
0
  m_xWrappedTypeProv( xStorageToWrap, uno::UNO_QUERY ),
73
0
  m_bIsDocumentStorage( Uri( rUri ).isDocument() )
74
0
{
75
0
    OSL_ENSURE( m_xWrappedStorage.is(),
76
0
                "Storage::Storage: No storage to wrap!" );
77
78
0
    OSL_ENSURE( m_xWrappedComponent.is(),
79
0
                "Storage::Storage: No component to wrap!" );
80
81
0
    OSL_ENSURE( m_xWrappedTypeProv.is(),
82
0
                "Storage::Storage: No Type Provider!" );
83
84
    // Use proxy factory service to create aggregatable proxy.
85
0
    try
86
0
    {
87
0
        uno::Reference< reflection::XProxyFactory > xProxyFac =
88
0
            reflection::ProxyFactory::create( rxContext );
89
0
        m_xAggProxy = xProxyFac->createProxy( m_xWrappedStorage );
90
0
    }
91
0
    catch ( uno::Exception const & )
92
0
    {
93
0
        TOOLS_WARN_EXCEPTION("ucb.ucp", "");
94
0
    }
95
96
0
    OSL_ENSURE( m_xAggProxy.is(),
97
0
                "Storage::Storage: Wrapped storage cannot be aggregated!" );
98
99
0
    if ( !m_xAggProxy.is() )
100
0
        return;
101
102
0
    osl_atomic_increment( &m_refCount );
103
0
    {
104
        // Solaris compiler problem:
105
        // Extra block to enforce destruction of temporary object created
106
        // in next statement _before_ osl_atomic_decrement is
107
        // called.  Otherwise 'this' will destroy itself even before ctor
108
        // is completed (See impl. of XInterface::release())!
109
110
0
        m_xAggProxy->setDelegator(
111
0
            getXWeak() );
112
0
    }
113
0
    osl_atomic_decrement( &m_refCount );
114
0
}
115
116
117
// virtual
118
Storage::~Storage()
119
0
{
120
0
    if ( m_xAggProxy.is() )
121
0
        m_xAggProxy->setDelegator( uno::Reference< uno::XInterface >() );
122
123
    // Never dispose a document storage. Not owner!
124
0
    if ( m_bIsDocumentStorage )
125
0
        return;
126
127
0
    if ( !m_xWrappedComponent.is() )
128
0
        return;
129
130
    // "Auto-dispose"...
131
0
    try
132
0
    {
133
0
        m_xWrappedComponent->dispose();
134
0
    }
135
0
    catch ( lang::DisposedException const & )
136
0
    {
137
        // might happen.
138
0
    }
139
0
    catch ( ... )
140
0
    {
141
0
        TOOLS_WARN_EXCEPTION( "ucb", "Storage::~Storage - Caught exception!" );
142
0
    }
143
0
}
144
145
146
// uno::XInterface
147
148
149
// virtual
150
uno::Any SAL_CALL Storage::queryInterface( const uno::Type& aType )
151
0
{
152
    // First, try to use interfaces implemented by myself and base class(es)
153
0
    uno::Any aRet = StorageUNOBase::queryInterface( aType );
154
155
0
    if ( aRet.hasValue() )
156
0
        return aRet;
157
158
    // Try to use requested interface from aggregated storage
159
0
    return m_xAggProxy->queryAggregation( aType );
160
0
}
161
162
163
// virtual
164
void SAL_CALL Storage::acquire()
165
    noexcept
166
0
{
167
0
    osl_atomic_increment( &m_refCount );
168
0
}
169
170
171
// virtual
172
void SAL_CALL Storage::release()
173
    noexcept
174
0
{
175
    //#i120738, Storage::release overrides OWeakObject::release(),
176
    //need call OWeakObject::release() to release OWeakObject::m_pWeakConnectionPoint
177
178
0
    if ( m_refCount == 1 )
179
0
        m_xFactory->releaseElement( this );
180
181
    //delete this;
182
0
    OWeakObject::release();
183
0
}
184
185
186
// lang::XTypeProvider
187
188
189
// virtual
190
uno::Sequence< uno::Type > SAL_CALL Storage::getTypes()
191
0
{
192
0
    return m_xWrappedTypeProv->getTypes();
193
0
}
194
195
196
// virtual
197
uno::Sequence< sal_Int8 > SAL_CALL Storage::getImplementationId()
198
0
{
199
0
    return css::uno::Sequence<sal_Int8>();
200
0
}
201
202
203
// lang::XComponent (base of embed::XStorage)
204
205
206
// virtual
207
void SAL_CALL Storage::dispose()
208
0
{
209
0
    m_xWrappedStorage->dispose();
210
0
    m_xWrappedStorage.clear();
211
0
}
212
213
214
// virtual
215
void SAL_CALL Storage::addEventListener(
216
        const uno::Reference< lang::XEventListener >& xListener )
217
0
{
218
0
    m_xWrappedStorage->addEventListener( xListener );
219
0
}
220
221
// virtual
222
void SAL_CALL Storage::removeEventListener(
223
        const uno::Reference< lang::XEventListener >& aListener )
224
0
{
225
0
    m_xWrappedStorage->removeEventListener( aListener );
226
0
}
227
228
229
// container::XElementAccess (base of container::XNameAccess)
230
231
232
// virtual
233
uno::Type SAL_CALL Storage::getElementType()
234
0
{
235
0
    return m_xWrappedStorage->getElementType();
236
0
}
237
238
239
// virtual
240
sal_Bool SAL_CALL Storage::hasElements()
241
0
{
242
0
    return m_xWrappedStorage->hasElements();
243
0
}
244
245
246
// container::XNameAccess (base of embed::XStorage)
247
248
249
// virtual
250
uno::Any SAL_CALL Storage::getByName( const OUString& aName )
251
0
{
252
0
    return m_xWrappedStorage->getByName( aName );
253
0
}
254
255
256
// virtual
257
uno::Sequence< OUString > SAL_CALL Storage::getElementNames()
258
0
{
259
0
    return m_xWrappedStorage->getElementNames();
260
0
}
261
262
263
// virtual
264
sal_Bool SAL_CALL Storage::hasByName( const OUString& aName )
265
0
{
266
0
    return m_xWrappedStorage->hasByName( aName );
267
0
}
268
269
270
// embed::XStorage
271
272
273
// virtual
274
void SAL_CALL Storage::copyToStorage(
275
        const uno::Reference< embed::XStorage >& xDest )
276
0
{
277
0
    m_xWrappedStorage->copyToStorage( xDest );
278
0
}
279
280
281
// virtual
282
uno::Reference< io::XStream > SAL_CALL Storage::openStreamElement(
283
        const OUString& aStreamName, sal_Int32 nOpenMode )
284
0
{
285
0
    return m_xWrappedStorage->openStreamElement( aStreamName, nOpenMode );
286
0
}
287
288
289
// virtual
290
uno::Reference< io::XStream > SAL_CALL Storage::openEncryptedStreamElement(
291
        const OUString& aStreamName,
292
        sal_Int32 nOpenMode,
293
        const OUString& aPassword )
294
0
{
295
0
    return m_xWrappedStorage->openEncryptedStreamElement(
296
0
        aStreamName, nOpenMode, aPassword );
297
0
}
298
299
300
// virtual
301
uno::Reference< embed::XStorage > SAL_CALL Storage::openStorageElement(
302
        const OUString& aStorName, sal_Int32 nOpenMode )
303
0
{
304
0
    return m_xWrappedStorage->openStorageElement( aStorName, nOpenMode );
305
0
}
306
307
308
// virtual
309
uno::Reference< io::XStream > SAL_CALL Storage::cloneStreamElement(
310
        const OUString& aStreamName )
311
0
{
312
0
    return m_xWrappedStorage->cloneStreamElement( aStreamName );
313
0
}
314
315
316
// virtual
317
uno::Reference< io::XStream > SAL_CALL Storage::cloneEncryptedStreamElement(
318
        const OUString& aStreamName,
319
        const OUString& aPassword )
320
0
{
321
0
    return m_xWrappedStorage->cloneEncryptedStreamElement( aStreamName,
322
0
                                                           aPassword );
323
0
}
324
325
326
// virtual
327
void SAL_CALL Storage::copyLastCommitTo(
328
        const uno::Reference< embed::XStorage >& xTargetStorage )
329
0
{
330
0
    m_xWrappedStorage->copyLastCommitTo( xTargetStorage );
331
0
}
332
333
334
// virtual
335
void SAL_CALL Storage::copyStorageElementLastCommitTo(
336
        const OUString& aStorName,
337
        const uno::Reference< embed::XStorage >& xTargetStorage )
338
0
{
339
0
    m_xWrappedStorage->copyStorageElementLastCommitTo( aStorName, xTargetStorage );
340
0
}
341
342
343
// virtual
344
sal_Bool SAL_CALL Storage::isStreamElement(
345
        const OUString& aElementName )
346
0
{
347
0
    return m_xWrappedStorage->isStreamElement( aElementName );
348
0
}
349
350
351
// virtual
352
sal_Bool SAL_CALL Storage::isStorageElement(
353
        const OUString& aElementName )
354
0
{
355
0
    return m_xWrappedStorage->isStorageElement( aElementName );
356
0
}
357
358
359
// virtual
360
void SAL_CALL Storage::removeElement( const OUString& aElementName )
361
0
{
362
0
    m_xWrappedStorage->removeElement( aElementName );
363
0
}
364
365
366
// virtual
367
void SAL_CALL Storage::renameElement( const OUString& aEleName,
368
                                      const OUString& aNewName )
369
0
{
370
0
    m_xWrappedStorage->renameElement( aEleName, aNewName );
371
0
}
372
373
374
// virtual
375
void SAL_CALL Storage::copyElementTo(
376
        const OUString& aElementName,
377
        const uno::Reference< embed::XStorage >& xDest,
378
        const OUString& aNewName )
379
0
{
380
0
    m_xWrappedStorage->copyElementTo( aElementName, xDest, aNewName );
381
0
}
382
383
384
// virtual
385
void SAL_CALL Storage::moveElementTo(
386
        const OUString& aElementName,
387
        const uno::Reference< embed::XStorage >& xDest,
388
        const OUString& rNewName )
389
0
{
390
0
    m_xWrappedStorage->moveElementTo( aElementName, xDest, rNewName );
391
0
}
392
393
394
// embed::XTransactedObject
395
396
397
// virtual
398
void SAL_CALL Storage::commit()
399
0
{
400
    // Never commit a root storage (-> has no parent)!
401
    // Would lead in writing the whole document to disk.
402
403
0
    uno::Reference< embed::XStorage > xParentStorage = getParentStorage();
404
0
    if ( !xParentStorage.is() )
405
0
        return;
406
407
0
    OSL_ENSURE( m_xWrappedTransObj.is(), "No XTransactedObject interface!" );
408
409
0
    if ( !m_xWrappedTransObj.is() )
410
0
        return;
411
412
0
    m_xWrappedTransObj->commit();
413
414
0
    if ( !isParentARootStorage() )
415
0
    {
416
0
        uno::Reference< embed::XTransactedObject > xParentTA(
417
0
            xParentStorage, uno::UNO_QUERY );
418
0
        OSL_ENSURE( xParentTA.is(), "No XTransactedObject interface!" );
419
420
0
        if ( xParentTA.is() )
421
0
            xParentTA->commit();
422
0
    }
423
0
}
424
425
426
// virtual
427
void SAL_CALL Storage::revert()
428
0
{
429
0
    uno::Reference< embed::XStorage > xParentStorage = getParentStorage();
430
0
    if ( !xParentStorage.is() )
431
0
        return;
432
433
0
    OSL_ENSURE( m_xWrappedTransObj.is(), "No XTransactedObject interface!" );
434
435
0
    if ( !m_xWrappedTransObj.is() )
436
0
        return;
437
438
0
    m_xWrappedTransObj->revert();
439
440
0
    if ( !isParentARootStorage() )
441
0
    {
442
0
        uno::Reference< embed::XTransactedObject > xParentTA(
443
0
            xParentStorage, uno::UNO_QUERY );
444
0
        OSL_ENSURE( xParentTA.is(), "No XTransactedObject interface!" );
445
446
0
        if ( xParentTA.is() )
447
0
            xParentTA->revert();
448
0
    }
449
0
}
450
451
452
// OutputStream Implementation.
453
454
455
OutputStream::OutputStream(
456
            const uno::Reference< uno::XComponentContext > & rxContext,
457
            const OUString & rUri,
458
            const uno::Reference< embed::XStorage >  & xParentStorage,
459
            const uno::Reference< io::XOutputStream > & xStreamToWrap )
460
0
: ParentStorageHolder( xParentStorage, Uri( rUri ).getParentUri() ),
461
0
  m_xWrappedStream( xStreamToWrap ),
462
0
  m_xWrappedComponent( xStreamToWrap, uno::UNO_QUERY ),
463
0
  m_xWrappedTypeProv( xStreamToWrap, uno::UNO_QUERY )
464
0
{
465
0
    OSL_ENSURE( m_xWrappedStream.is(),
466
0
                "OutputStream::OutputStream: No stream to wrap!" );
467
468
0
    OSL_ENSURE( m_xWrappedComponent.is(),
469
0
                "OutputStream::OutputStream: No component to wrap!" );
470
471
0
    OSL_ENSURE( m_xWrappedTypeProv.is(),
472
0
                "OutputStream::OutputStream: No Type Provider!" );
473
474
    // Use proxy factory service to create aggregatable proxy.
475
0
    try
476
0
    {
477
0
        uno::Reference< reflection::XProxyFactory > xProxyFac =
478
0
            reflection::ProxyFactory::create( rxContext );
479
0
        m_xAggProxy = xProxyFac->createProxy( m_xWrappedStream );
480
0
    }
481
0
    catch ( uno::Exception const & )
482
0
    {
483
0
        TOOLS_WARN_EXCEPTION("ucb.ucp", "");
484
0
    }
485
486
0
    OSL_ENSURE( m_xAggProxy.is(),
487
0
            "OutputStream::OutputStream: Wrapped stream cannot be aggregated!" );
488
489
0
    if ( !m_xAggProxy.is() )
490
0
        return;
491
492
0
    osl_atomic_increment( &m_refCount );
493
0
    {
494
        // Solaris compiler problem:
495
        // Extra block to enforce destruction of temporary object created
496
        // in next statement _before_ osl_atomic_decrement is
497
        // called.  Otherwise 'this' will destroy itself even before ctor
498
        // is completed (See impl. of XInterface::release())!
499
500
0
        m_xAggProxy->setDelegator(
501
0
            getXWeak() );
502
0
    }
503
0
    osl_atomic_decrement( &m_refCount );
504
0
}
505
506
507
// virtual
508
OutputStream::~OutputStream()
509
0
{
510
0
    if ( m_xAggProxy.is() )
511
0
        m_xAggProxy->setDelegator( uno::Reference< uno::XInterface >() );
512
0
}
513
514
515
// uno::XInterface
516
517
518
// virtual
519
uno::Any SAL_CALL OutputStream::queryInterface( const uno::Type& aType )
520
0
{
521
0
    uno::Any aRet = OutputStreamUNOBase::queryInterface( aType );
522
523
0
    if ( aRet.hasValue() )
524
0
        return aRet;
525
526
0
    if ( m_xAggProxy.is() )
527
0
        return m_xAggProxy->queryAggregation( aType );
528
0
    else
529
0
        return uno::Any();
530
0
}
531
532
533
// lang::XTypeProvider
534
535
536
// virtual
537
uno::Sequence< uno::Type > SAL_CALL OutputStream::getTypes()
538
0
{
539
0
    return m_xWrappedTypeProv->getTypes();
540
0
}
541
542
543
// virtual
544
uno::Sequence< sal_Int8 > SAL_CALL OutputStream::getImplementationId()
545
0
{
546
0
    return css::uno::Sequence<sal_Int8>();
547
0
}
548
549
550
// io::XOutputStream
551
552
553
// virtual
554
void SAL_CALL
555
OutputStream::writeBytes( const uno::Sequence< sal_Int8 >& aData )
556
0
{
557
0
    m_xWrappedStream->writeBytes( aData );
558
0
}
559
560
561
// virtual
562
void SAL_CALL
563
OutputStream::flush()
564
0
{
565
0
    m_xWrappedStream->flush();
566
0
}
567
568
569
// virtual
570
void SAL_CALL
571
OutputStream::closeOutput(  )
572
0
{
573
0
    m_xWrappedStream->closeOutput();
574
575
    // Release parent storage.
576
    // Now, that the stream is closed/disposed it is not needed any longer.
577
0
    clearParentStorage();
578
0
}
579
580
581
// lang::XComponent
582
583
584
// virtual
585
void SAL_CALL
586
OutputStream::dispose()
587
0
{
588
0
    m_xWrappedComponent->dispose();
589
590
    // Release parent storage.
591
    // Now, that the stream is closed/disposed it is not needed any longer.
592
0
    clearParentStorage();
593
0
}
594
595
596
// virtual
597
void SAL_CALL
598
OutputStream::addEventListener(
599
        const uno::Reference< lang::XEventListener >& xListener )
600
0
{
601
0
    m_xWrappedComponent->addEventListener( xListener );
602
0
}
603
604
605
// virtual
606
void SAL_CALL
607
OutputStream::removeEventListener(
608
        const uno::Reference< lang::XEventListener >& aListener )
609
0
{
610
0
    m_xWrappedComponent->removeEventListener( aListener );
611
0
}
612
613
614
// Stream Implementation.
615
616
617
Stream::Stream(
618
            const uno::Reference< uno::XComponentContext > & rxContext,
619
            rtl::Reference<OfficeDocumentsManager> const & docsMgr,
620
            const OUString & rUri,
621
            const uno::Reference< embed::XStorage >  & xParentStorage,
622
            const uno::Reference< io::XStream > & xStreamToWrap )
623
0
: ParentStorageHolder( xParentStorage, Uri( rUri ).getParentUri() ),
624
0
  m_docsMgr(docsMgr),
625
0
  m_uri(rUri),
626
0
  m_xWrappedStream( xStreamToWrap ),
627
0
  m_xWrappedOutputStream( xStreamToWrap->getOutputStream() ), // might be empty
628
0
  m_xWrappedTruncate( m_xWrappedOutputStream, uno::UNO_QUERY ), // might be empty
629
0
  m_xWrappedInputStream( xStreamToWrap->getInputStream() ),
630
0
  m_xWrappedComponent( xStreamToWrap, uno::UNO_QUERY ),
631
0
  m_xWrappedTypeProv( xStreamToWrap, uno::UNO_QUERY )
632
0
{
633
0
    OSL_ENSURE( m_xWrappedStream.is(),
634
0
                "OutputStream::OutputStream: No stream to wrap!" );
635
636
0
    OSL_ENSURE( m_xWrappedComponent.is(),
637
0
                "OutputStream::OutputStream: No component to wrap!" );
638
639
0
    OSL_ENSURE( m_xWrappedTypeProv.is(),
640
0
                "OutputStream::OutputStream: No Type Provider!" );
641
642
    // Use proxy factory service to create aggregatable proxy.
643
0
    try
644
0
    {
645
0
        uno::Reference< reflection::XProxyFactory > xProxyFac =
646
0
            reflection::ProxyFactory::create( rxContext );
647
0
        m_xAggProxy = xProxyFac->createProxy( m_xWrappedStream );
648
0
    }
649
0
    catch ( uno::Exception const & )
650
0
    {
651
0
        TOOLS_WARN_EXCEPTION("ucb.ucp", "");
652
0
    }
653
654
0
    OSL_ENSURE( m_xAggProxy.is(),
655
0
            "OutputStream::OutputStream: Wrapped stream cannot be aggregated!" );
656
657
0
    if ( !m_xAggProxy.is() )
658
0
        return;
659
660
0
    osl_atomic_increment( &m_refCount );
661
0
    {
662
        // Solaris compiler problem:
663
        // Extra block to enforce destruction of temporary object created
664
        // in next statement _before_ osl_atomic_decrement is
665
        // called.  Otherwise 'this' will destroy itself even before ctor
666
        // is completed (See impl. of XInterface::release())!
667
668
0
        m_xAggProxy->setDelegator(
669
0
            getXWeak() );
670
0
    }
671
0
    osl_atomic_decrement( &m_refCount );
672
0
}
673
674
675
// virtual
676
Stream::~Stream()
677
0
{
678
0
    if ( m_xAggProxy.is() )
679
0
        m_xAggProxy->setDelegator( uno::Reference< uno::XInterface >() );
680
0
}
681
682
683
// uno::XInterface
684
685
686
// virtual
687
uno::Any SAL_CALL Stream::queryInterface( const uno::Type& aType )
688
0
{
689
0
    uno::Any aRet = StreamUNOBase::queryInterface( aType );
690
691
0
    if ( aRet.hasValue() )
692
0
        return aRet;
693
694
0
    if ( m_xAggProxy.is() )
695
0
        return m_xAggProxy->queryAggregation( aType );
696
0
    else
697
0
        return uno::Any();
698
0
}
699
700
701
// lang::XTypeProvider
702
703
704
// virtual
705
uno::Sequence< uno::Type > SAL_CALL Stream::getTypes()
706
0
{
707
0
    return m_xWrappedTypeProv->getTypes();
708
0
}
709
710
711
// virtual
712
uno::Sequence< sal_Int8 > SAL_CALL Stream::getImplementationId()
713
0
{
714
0
    return css::uno::Sequence<sal_Int8>();
715
0
}
716
717
718
// io::XStream.
719
720
721
// virtual
722
uno::Reference< io::XInputStream > SAL_CALL Stream::getInputStream()
723
0
{
724
0
    return uno::Reference< io::XInputStream >( this );
725
0
}
726
727
728
// virtual
729
uno::Reference< io::XOutputStream > SAL_CALL Stream::getOutputStream()
730
0
{
731
0
    return uno::Reference< io::XOutputStream >( this );
732
0
}
733
734
735
// io::XOutputStream.
736
737
738
// virtual
739
void SAL_CALL Stream::writeBytes( const uno::Sequence< sal_Int8 >& aData )
740
0
{
741
0
    if ( m_xWrappedOutputStream.is() )
742
0
    {
743
0
        m_xWrappedOutputStream->writeBytes( aData );
744
0
        commitChanges();
745
0
    }
746
0
}
747
748
749
// virtual
750
void SAL_CALL Stream::flush()
751
0
{
752
0
    if ( m_xWrappedOutputStream.is() )
753
0
    {
754
0
        m_xWrappedOutputStream->flush();
755
0
        commitChanges();
756
0
    }
757
0
}
758
759
760
// virtual
761
void SAL_CALL Stream::closeOutput()
762
0
{
763
0
    if ( m_xWrappedOutputStream.is() )
764
0
    {
765
0
        m_xWrappedOutputStream->closeOutput();
766
0
        commitChanges();
767
0
    }
768
769
    // Release parent storage.
770
    // Now, that the stream is closed/disposed it is not needed any longer.
771
0
    clearParentStorage();
772
0
}
773
774
775
// io::XTruncate.
776
777
778
// virtual
779
void SAL_CALL Stream::truncate()
780
0
{
781
0
    if ( m_xWrappedTruncate.is() )
782
0
    {
783
0
        m_xWrappedTruncate->truncate();
784
0
        commitChanges();
785
0
    }
786
0
}
787
788
789
// io::XInputStream.
790
791
792
// virtual
793
sal_Int32 SAL_CALL Stream::readBytes( uno::Sequence< sal_Int8 >& aData,
794
                                      sal_Int32 nBytesToRead )
795
0
{
796
0
    return m_xWrappedInputStream->readBytes( aData, nBytesToRead );
797
0
}
798
799
800
// virtual
801
sal_Int32 SAL_CALL Stream::readSomeBytes( uno::Sequence< sal_Int8 >& aData,
802
                                          sal_Int32 nMaxBytesToRead )
803
0
{
804
0
    return m_xWrappedInputStream->readSomeBytes( aData, nMaxBytesToRead );
805
0
}
806
807
808
// virtual
809
void SAL_CALL Stream::skipBytes( sal_Int32 nBytesToSkip )
810
0
{
811
0
    m_xWrappedInputStream->skipBytes( nBytesToSkip );
812
0
}
813
814
815
// virtual
816
sal_Int32 SAL_CALL Stream::available()
817
0
{
818
0
    return m_xWrappedInputStream->available();
819
0
}
820
821
822
// virtual
823
void SAL_CALL Stream::closeInput()
824
0
{
825
0
    m_xWrappedInputStream->closeInput();
826
0
}
827
828
829
// lang::XComponent
830
831
832
// virtual
833
void SAL_CALL Stream::dispose()
834
0
{
835
0
    m_xWrappedComponent->dispose();
836
837
    // Release parent storage.
838
    // Now, that the stream is closed/disposed it is not needed any longer.
839
0
    clearParentStorage();
840
0
}
841
842
843
// virtual
844
void SAL_CALL Stream::addEventListener(
845
        const uno::Reference< lang::XEventListener >& xListener )
846
0
{
847
0
    m_xWrappedComponent->addEventListener( xListener );
848
0
}
849
850
851
// virtual
852
void SAL_CALL Stream::removeEventListener(
853
        const uno::Reference< lang::XEventListener >& aListener )
854
0
{
855
0
    m_xWrappedComponent->removeEventListener( aListener );
856
0
}
857
858
859
// Non-UNO
860
861
862
void Stream::commitChanges()
863
0
{
864
0
    uno::Reference< embed::XTransactedObject >
865
0
        xParentTA( getParentStorage(), uno::UNO_QUERY );
866
0
    OSL_ENSURE( xParentTA.is(), "No XTransactedObject interface!" );
867
868
0
    if ( xParentTA.is() )
869
0
    {
870
0
        try
871
0
        {
872
0
            xParentTA->commit();
873
0
        }
874
0
        catch ( lang::WrappedTargetException const & )
875
0
        {
876
0
            throw io::IOException(); // @@@
877
0
        }
878
0
    }
879
0
    m_docsMgr->updateStreamDateModified(m_uri);
880
0
}
881
882
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */