Coverage Report

Created: 2025-12-31 10:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sot/source/unoolestorage/xolesimplestorage.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
#include "xolesimplestorage.hxx"
21
22
#include <com/sun/star/embed/OLESimpleStorage.hpp>
23
#include <com/sun/star/lang/DisposedException.hpp>
24
#include <com/sun/star/lang/NoSupportException.hpp>
25
#include <com/sun/star/io/IOException.hpp>
26
#include <com/sun/star/io/XStream.hpp>
27
#include <com/sun/star/io/XInputStream.hpp>
28
#include <com/sun/star/io/XSeekable.hpp>
29
#include <com/sun/star/io/XTruncate.hpp>
30
#include <com/sun/star/io/TempFile.hpp>
31
32
#include <comphelper/storagehelper.hxx>
33
#include <unotools/ucbstreamhelper.hxx>
34
#include <cppuhelper/exc_hlp.hxx>
35
#include <cppuhelper/supportsservice.hxx>
36
#include <sot/stg.hxx>
37
#include <sot/storinfo.hxx>
38
#include <utility>
39
40
using namespace ::com::sun::star;
41
42
const sal_Int32 nBytesCount = 32000;
43
44
45
OLESimpleStorage::OLESimpleStorage(
46
        css::uno::Reference<css::uno::XComponentContext> xContext,
47
        css::uno::Sequence<css::uno::Any> const &aArguments)
48
88.0k
: m_bDisposed( false )
49
88.0k
, m_xContext(std::move( xContext ))
50
88.0k
, m_bNoTemporaryCopy( false )
51
88.0k
{
52
88.0k
    sal_Int32 nArgNum = aArguments.getLength();
53
88.0k
    if ( nArgNum < 1 || nArgNum > 2 )
54
0
        throw lang::IllegalArgumentException(); // TODO:
55
56
88.0k
    uno::Reference< io::XStream > xStream;
57
88.0k
    uno::Reference< io::XInputStream > xInputStream;
58
88.0k
    if ( !( aArguments[0] >>= xStream ) && !( aArguments[0] >>= xInputStream ) )
59
0
        throw lang::IllegalArgumentException(); // TODO:
60
61
88.0k
    if ( nArgNum == 2 )
62
88.0k
    {
63
88.0k
        if ( !( aArguments[1] >>= m_bNoTemporaryCopy ) )
64
0
            throw lang::IllegalArgumentException(); // TODO:
65
88.0k
    }
66
67
88.0k
    if ( m_bNoTemporaryCopy )
68
88.0k
    {
69
        // TODO: ???
70
        // If the temporary stream is not created, the original stream must be wrapped
71
        // since SvStream wrapper closes the stream is owns
72
88.0k
        if ( xInputStream.is() )
73
9.17k
        {
74
            // the stream must be seekable for direct access
75
9.17k
            uno::Reference< io::XSeekable > xSeek( xInputStream, uno::UNO_QUERY_THROW );
76
9.17k
            m_pStream = ::utl::UcbStreamHelper::CreateStream( xInputStream, false );
77
9.17k
        }
78
78.8k
        else if ( xStream.is() )
79
78.8k
        {
80
            // the stream must be seekable for direct access
81
78.8k
            uno::Reference< io::XSeekable > xSeek( xStream, uno::UNO_QUERY_THROW );
82
78.8k
            m_pStream = ::utl::UcbStreamHelper::CreateStream( xStream, false );
83
78.8k
        }
84
0
        else
85
0
            throw lang::IllegalArgumentException(); // TODO:
86
88.0k
    }
87
0
    else
88
0
    {
89
0
        uno::Reference < io::XStream > xTempFile( io::TempFile::create(m_xContext),
90
0
                uno::UNO_QUERY_THROW );
91
0
        uno::Reference < io::XSeekable > xTempSeek( xTempFile, uno::UNO_QUERY_THROW );
92
0
        uno::Reference< io::XOutputStream > xTempOut = xTempFile->getOutputStream();
93
0
        if ( !xTempOut.is() )
94
0
            throw uno::RuntimeException();
95
96
0
        if ( xInputStream.is() )
97
0
        {
98
0
            try
99
0
            {
100
0
                uno::Reference< io::XSeekable > xSeek( xInputStream, uno::UNO_QUERY );
101
0
                if (xSeek)
102
0
                    xSeek->seek( 0 );
103
0
            }
104
0
            catch( uno::Exception& )
105
0
            {}
106
107
0
            ::comphelper::OStorageHelper::CopyInputToOutput( xInputStream, xTempOut );
108
0
            xTempOut->closeOutput();
109
0
            xTempSeek->seek( 0 );
110
0
            uno::Reference< io::XInputStream > xTempInput = xTempFile->getInputStream();
111
0
            m_pStream = ::utl::UcbStreamHelper::CreateStream( xTempInput, false );
112
0
        }
113
0
        else if ( xStream.is() )
114
0
        {
115
            // not sure that the storage flashes the stream on commit
116
0
            m_xStream = xStream;
117
0
            m_xTempStream = xTempFile;
118
119
0
            uno::Reference< io::XSeekable > xSeek( xStream, uno::UNO_QUERY_THROW );
120
0
            xSeek->seek( 0 );
121
0
            uno::Reference< io::XInputStream > xInpStream = xStream->getInputStream();
122
0
            if ( !xInpStream.is() || !xStream->getOutputStream().is() )
123
0
                throw uno::RuntimeException();
124
125
0
            ::comphelper::OStorageHelper::CopyInputToOutput( xInpStream, xTempOut );
126
0
            xTempOut->flush();
127
0
            xTempSeek->seek( 0 );
128
129
0
            m_pStream = ::utl::UcbStreamHelper::CreateStream( xTempFile, false );
130
0
        }
131
0
        else
132
0
            throw lang::IllegalArgumentException(); // TODO:
133
0
    }
134
135
88.0k
    if ( !m_pStream || m_pStream->GetError() )
136
0
        throw io::IOException(); // TODO
137
138
88.0k
    m_pStorage.reset(new Storage( *m_pStream, false ));
139
88.0k
}
140
141
OLESimpleStorage::~OLESimpleStorage()
142
88.0k
{
143
88.0k
    try {
144
88.0k
        osl_atomic_increment(&m_refCount);
145
88.0k
        dispose();
146
88.0k
    } catch( uno::Exception& )
147
88.0k
    {}
148
88.0k
}
149
150
void OLESimpleStorage::UpdateOriginal_Impl()
151
0
{
152
0
    if ( m_bNoTemporaryCopy )
153
0
        return;
154
155
0
    uno::Reference< io::XSeekable > xSeek( m_xStream, uno::UNO_QUERY_THROW );
156
0
    xSeek->seek( 0 );
157
158
0
    uno::Reference< io::XSeekable > xTempSeek( m_xTempStream, uno::UNO_QUERY_THROW );
159
0
    sal_Int64 nPos = xTempSeek->getPosition();
160
0
    xTempSeek->seek( 0 );
161
162
0
    uno::Reference< io::XInputStream > xTempInp = m_xTempStream->getInputStream();
163
0
    uno::Reference< io::XOutputStream > xOutputStream = m_xStream->getOutputStream();
164
0
    if ( !xTempInp.is() || !xOutputStream.is() )
165
0
        throw uno::RuntimeException();
166
167
0
    uno::Reference< io::XTruncate > xTrunc( xOutputStream, uno::UNO_QUERY_THROW );
168
0
    xTrunc->truncate();
169
170
0
    ::comphelper::OStorageHelper::CopyInputToOutput( xTempInp, xOutputStream );
171
0
    xOutputStream->flush();
172
0
    xTempSeek->seek( nPos );
173
0
}
174
175
176
void OLESimpleStorage::InsertInputStreamToStorage_Impl( BaseStorage* pStorage, const OUString & aName, const uno::Reference< io::XInputStream >& xInputStream )
177
0
{
178
0
    if ( !pStorage || aName.isEmpty() || !xInputStream.is() )
179
0
        throw uno::RuntimeException();
180
181
0
    if ( pStorage->IsContained( aName ) )
182
0
        throw container::ElementExistException(); // TODO:
183
184
0
    std::unique_ptr<BaseStorageStream> pNewStream(pStorage->OpenStream( aName ));
185
0
    if ( !pNewStream || pNewStream->GetError() || pStorage->GetError() )
186
0
    {
187
0
        pNewStream.reset();
188
0
        pStorage->ResetError();
189
0
        throw io::IOException(); // TODO
190
0
    }
191
192
0
    try
193
0
    {
194
0
        uno::Sequence< sal_Int8 > aData( nBytesCount );
195
0
        sal_Int32 nRead = 0;
196
0
        do
197
0
        {
198
0
            nRead = xInputStream->readBytes( aData, nBytesCount );
199
200
0
            sal_Int32 nWritten = pNewStream->Write( aData.getConstArray(), nRead );
201
0
            if ( nWritten < nRead )
202
0
                throw io::IOException();
203
0
        } while( nRead == nBytesCount );
204
0
    }
205
0
    catch( uno::Exception& )
206
0
    {
207
0
        pNewStream.reset();
208
0
        pStorage->Remove( aName );
209
210
0
        throw;
211
0
    }
212
0
}
213
214
215
void OLESimpleStorage::InsertNameAccessToStorage_Impl( BaseStorage* pStorage, const OUString & aName, const uno::Reference< container::XNameAccess >& xNameAccess )
216
0
{
217
0
    if ( !pStorage || aName.isEmpty() || !xNameAccess.is() )
218
0
        throw uno::RuntimeException();
219
220
0
    if ( pStorage->IsContained( aName ) )
221
0
        throw container::ElementExistException(); // TODO:
222
223
0
    std::unique_ptr<BaseStorage> pNewStorage(pStorage->OpenStorage( aName ));
224
0
    if ( !pNewStorage || pNewStorage->GetError() || pStorage->GetError() )
225
0
    {
226
0
        pNewStorage.reset();
227
0
        pStorage->ResetError();
228
0
        throw io::IOException(); // TODO
229
0
    }
230
231
0
    try
232
0
    {
233
0
        const uno::Sequence< OUString > aElements = xNameAccess->getElementNames();
234
0
        for ( const auto& rElement : aElements )
235
0
        {
236
0
            uno::Reference< io::XInputStream > xInputStream;
237
0
            uno::Reference< container::XNameAccess > xSubNameAccess;
238
0
            uno::Any aAny = xNameAccess->getByName( rElement );
239
0
            if ( aAny >>= xInputStream )
240
0
                InsertInputStreamToStorage_Impl( pNewStorage.get(), rElement, xInputStream );
241
0
            else if ( aAny >>= xSubNameAccess )
242
0
                InsertNameAccessToStorage_Impl( pNewStorage.get(), rElement, xSubNameAccess );
243
0
        }
244
0
    }
245
0
    catch( uno::Exception& )
246
0
    {
247
0
        pNewStorage.reset();
248
0
        pStorage->Remove( aName );
249
250
0
        throw;
251
0
    }
252
0
}
253
254
255
//  XNameContainer
256
257
258
void SAL_CALL OLESimpleStorage::insertByName( const OUString& aName, const uno::Any& aElement )
259
0
{
260
0
    std::unique_lock aGuard( m_aMutex );
261
262
0
    if ( m_bDisposed )
263
0
        throw lang::DisposedException();
264
265
0
    if ( !m_pStorage )
266
0
        throw uno::RuntimeException();
267
268
0
    uno::Reference< io::XStream > xStream;
269
0
    uno::Reference< io::XInputStream > xInputStream;
270
0
    uno::Reference< container::XNameAccess > xNameAccess;
271
272
0
    try
273
0
    {
274
0
        if ( !m_bNoTemporaryCopy && !m_xStream.is() )
275
0
            throw io::IOException(); // TODO
276
277
0
        if ( aElement >>= xStream )
278
0
            xInputStream = xStream->getInputStream();
279
0
        else if ( !( aElement >>= xInputStream ) && !( aElement >>= xNameAccess ) )
280
0
            throw lang::IllegalArgumentException(); // TODO:
281
282
0
        if ( xInputStream.is() )
283
0
            InsertInputStreamToStorage_Impl( m_pStorage.get(), aName, xInputStream );
284
0
        else if ( xNameAccess.is() )
285
0
            InsertNameAccessToStorage_Impl( m_pStorage.get(), aName, xNameAccess );
286
0
        else
287
0
            throw uno::RuntimeException();
288
0
    }
289
0
    catch( uno::RuntimeException& )
290
0
    {
291
0
        throw;
292
0
    }
293
0
    catch( container::ElementExistException& )
294
0
    {
295
0
        throw;
296
0
    }
297
0
    catch( const uno::Exception& )
298
0
    {
299
0
        css::uno::Any anyEx = cppu::getCaughtException();
300
0
        throw lang::WrappedTargetException(u"Insert has failed!"_ustr,
301
0
                                            uno::Reference< uno::XInterface >(),
302
0
                                            anyEx );
303
0
    }
304
0
}
305
306
307
void SAL_CALL OLESimpleStorage::removeByName( const OUString& aName )
308
0
{
309
0
    std::unique_lock aGuard( m_aMutex );
310
311
0
    if ( m_bDisposed )
312
0
        throw lang::DisposedException();
313
314
0
    if ( !m_pStorage )
315
0
        throw uno::RuntimeException();
316
317
0
    if ( !m_bNoTemporaryCopy && !m_xStream.is() )
318
0
        throw lang::WrappedTargetException(); // io::IOException(); // TODO
319
320
0
    if ( !m_pStorage->IsContained( aName ) )
321
0
        throw container::NoSuchElementException(); // TODO:
322
323
0
    m_pStorage->Remove( aName );
324
325
0
    if ( m_pStorage->GetError() )
326
0
    {
327
0
        m_pStorage->ResetError();
328
0
        throw lang::WrappedTargetException(); // io::IOException(); // TODO
329
0
    }
330
0
}
331
332
333
void SAL_CALL OLESimpleStorage::replaceByName( const OUString& aName, const uno::Any& aElement )
334
0
{
335
0
    std::unique_lock aGuard( m_aMutex );
336
337
0
    if ( m_bDisposed )
338
0
        throw lang::DisposedException();
339
340
0
    removeByName( aName );
341
342
0
    try
343
0
    {
344
0
        insertByName( aName, aElement );
345
0
    }
346
0
    catch( container::ElementExistException& )
347
0
    {
348
0
        uno::Any aCaught( ::cppu::getCaughtException() );
349
350
0
        throw lang::WrappedTargetException(u"Can't copy raw stream"_ustr,
351
0
                                            uno::Reference< uno::XInterface >(),
352
0
                                            aCaught );
353
0
    }
354
0
}
355
356
357
uno::Any SAL_CALL OLESimpleStorage::getByName( const OUString& aName )
358
488k
{
359
488k
    std::unique_lock aGuard( m_aMutex );
360
361
488k
    if ( m_bDisposed )
362
0
        throw lang::DisposedException();
363
364
488k
    if ( !m_pStorage )
365
0
        throw uno::RuntimeException();
366
367
488k
    if ( !m_pStorage->IsContained( aName ) )
368
6.66k
        throw container::NoSuchElementException(); // TODO:
369
370
481k
    uno::Any aResult;
371
372
481k
    uno::Reference< io::XStream > xTempFile = io::TempFile::create(m_xContext);
373
481k
    uno::Reference< io::XSeekable > xSeekable( xTempFile, uno::UNO_QUERY_THROW );
374
481k
    uno::Reference< io::XOutputStream > xOutputStream = xTempFile->getOutputStream();
375
481k
    uno::Reference< io::XInputStream > xInputStream = xTempFile->getInputStream();
376
481k
    if ( !xOutputStream.is() || !xInputStream.is() )
377
0
        throw uno::RuntimeException();
378
379
481k
    if ( m_pStorage->IsStorage( aName ) )
380
78.7k
    {
381
78.7k
        std::unique_ptr<BaseStorage> pStrg(m_pStorage->OpenStorage( aName ));
382
78.7k
        m_pStorage->ResetError();
383
78.7k
        if ( !pStrg )
384
0
            throw lang::WrappedTargetException(); // io::IOException(); // TODO
385
386
78.7k
        std::unique_ptr<SvStream> pStream = ::utl::UcbStreamHelper::CreateStream( xTempFile, false ); // do not close the original stream
387
78.7k
        if ( !pStream )
388
0
            throw uno::RuntimeException();
389
390
78.7k
        std::unique_ptr<BaseStorage> pNewStor(new Storage( *pStream, false ));
391
78.7k
        bool bSuccess = ( pStrg->CopyTo( *pNewStor ) && pNewStor->Commit() &&
392
76.9k
                          !pNewStor->GetError() && !pStrg->GetError() );
393
394
78.7k
        pNewStor.reset();
395
78.7k
        pStrg.reset();
396
78.7k
        pStream.reset();
397
398
78.7k
        if ( !bSuccess )
399
1.77k
            throw uno::RuntimeException();
400
401
76.9k
        uno::Reference< container::XNameContainer > xResultNameContainer(
402
76.9k
            css::embed::OLESimpleStorage::createFromInputStream(m_xContext, xInputStream, true),
403
76.9k
            uno::UNO_QUERY_THROW );
404
405
76.9k
        aResult <<= xResultNameContainer;
406
76.9k
    }
407
402k
    else
408
402k
    {
409
402k
        std::unique_ptr<BaseStorageStream> pStream(m_pStorage->OpenStream( aName, StreamMode::READ | StreamMode::SHARE_DENYALL | StreamMode::NOCREATE ));
410
402k
        try
411
402k
        {
412
402k
            if ( !pStream || pStream->GetError() || m_pStorage->GetError() )
413
183
            {
414
183
                m_pStorage->ResetError();
415
183
                throw io::IOException(); // TODO
416
183
            }
417
418
402k
            uno::Sequence< sal_Int8 > aData( nBytesCount );
419
402k
            sal_Int32 nSize = nBytesCount;
420
402k
            sal_Int32 nRead = 0;
421
663k
            while( 0 != ( nRead = pStream->Read( aData.getArray(), nSize ) ) )
422
261k
            {
423
261k
                if ( nRead < nSize )
424
217k
                {
425
217k
                    nSize = nRead;
426
217k
                    aData.realloc( nSize );
427
217k
                }
428
429
261k
                xOutputStream->writeBytes( aData );
430
261k
            }
431
432
402k
            if ( pStream->GetError() )
433
3.14k
                throw io::IOException(); // TODO
434
435
399k
            xOutputStream->closeOutput();
436
399k
            xSeekable->seek( 0 );
437
399k
        }
438
402k
        catch (const uno::RuntimeException&)
439
402k
        {
440
0
            throw;
441
0
        }
442
402k
        catch (const uno::Exception& ex)
443
402k
        {
444
3.32k
            css::uno::Any anyEx = cppu::getCaughtException();
445
3.32k
            throw css::lang::WrappedTargetException( ex.Message,
446
3.32k
                    nullptr, anyEx );
447
3.32k
        }
448
449
399k
        pStream.reset();
450
451
399k
        aResult <<= xInputStream;
452
399k
    }
453
454
476k
    return aResult;
455
481k
}
456
457
458
uno::Sequence< OUString > SAL_CALL OLESimpleStorage::getElementNames()
459
84.0k
{
460
84.0k
    std::unique_lock aGuard( m_aMutex );
461
462
84.0k
    if ( m_bDisposed )
463
0
        throw lang::DisposedException();
464
465
84.0k
    if ( !m_pStorage )
466
0
        throw uno::RuntimeException();
467
468
84.0k
    SvStorageInfoList aList;
469
84.0k
    m_pStorage->FillInfoList( &aList );
470
471
84.0k
    if ( m_pStorage->GetError() )
472
0
    {
473
0
        m_pStorage->ResetError();
474
0
        throw uno::RuntimeException(); // TODO:
475
0
    }
476
477
84.0k
    uno::Sequence< OUString > aSeq( aList.size() );
478
84.0k
    auto aSeqRange = asNonConstRange(aSeq);
479
406k
    for ( size_t nInd = 0; nInd < aList.size(); nInd++ )
480
322k
        aSeqRange[nInd] = aList[nInd].GetName();
481
482
84.0k
    return aSeq;
483
84.0k
}
484
485
486
sal_Bool SAL_CALL OLESimpleStorage::hasByName( const OUString& aName )
487
0
{
488
0
    std::unique_lock aGuard( m_aMutex );
489
490
0
    if ( m_bDisposed )
491
0
        throw lang::DisposedException();
492
493
0
    if ( !m_pStorage )
494
0
        throw uno::RuntimeException();
495
496
0
    bool bResult = m_pStorage->IsContained( aName );
497
498
0
    if ( m_pStorage->GetError() )
499
0
    {
500
0
        m_pStorage->ResetError();
501
0
        throw uno::RuntimeException(); // TODO:
502
0
    }
503
504
0
    return bResult;
505
0
}
506
507
508
uno::Type SAL_CALL OLESimpleStorage::getElementType()
509
0
{
510
0
    std::unique_lock aGuard( m_aMutex );
511
512
0
    if ( m_bDisposed )
513
0
        throw lang::DisposedException();
514
515
0
    return cppu::UnoType<io::XInputStream>::get();
516
0
}
517
518
519
sal_Bool SAL_CALL OLESimpleStorage::hasElements()
520
339k
{
521
339k
    std::unique_lock aGuard( m_aMutex );
522
523
339k
    if ( m_bDisposed )
524
0
        throw lang::DisposedException();
525
526
339k
    if ( !m_pStorage )
527
0
        throw uno::RuntimeException();
528
529
339k
    SvStorageInfoList aList;
530
339k
    m_pStorage->FillInfoList( &aList );
531
532
339k
    if ( m_pStorage->GetError() )
533
3.66k
    {
534
3.66k
        m_pStorage->ResetError();
535
3.66k
        throw uno::RuntimeException(); // TODO:
536
3.66k
    }
537
538
336k
    return !aList.empty();
539
339k
}
540
541
542
//  XComponent
543
544
545
void SAL_CALL OLESimpleStorage::dispose()
546
88.0k
{
547
88.0k
    std::unique_lock aGuard( m_aMutex );
548
549
88.0k
    if ( m_bDisposed )
550
0
        return;
551
552
88.0k
    if ( m_aListenersContainer.getLength(aGuard) )
553
0
    {
554
0
        lang::EventObject aSource( getXWeak() );
555
0
        m_aListenersContainer.disposeAndClear( aGuard, aSource );
556
0
    }
557
558
88.0k
    m_pStorage.reset();
559
88.0k
    m_pStream.reset();
560
561
88.0k
    m_xStream.clear();
562
88.0k
    m_xTempStream.clear();
563
564
88.0k
    m_bDisposed = true;
565
88.0k
}
566
567
568
void SAL_CALL OLESimpleStorage::addEventListener(
569
            const uno::Reference< lang::XEventListener >& xListener )
570
0
{
571
0
    std::unique_lock aGuard( m_aMutex );
572
573
0
    if ( m_bDisposed )
574
0
        throw lang::DisposedException();
575
576
0
    m_aListenersContainer.addInterface( aGuard, xListener );
577
0
}
578
579
580
void SAL_CALL OLESimpleStorage::removeEventListener(
581
            const uno::Reference< lang::XEventListener >& xListener )
582
0
{
583
0
    std::unique_lock aGuard( m_aMutex );
584
585
0
    if ( m_bDisposed )
586
0
        throw lang::DisposedException();
587
588
0
    m_aListenersContainer.removeInterface( aGuard, xListener );
589
0
}
590
591
592
//  XTransactedObject
593
594
595
void SAL_CALL OLESimpleStorage::commit()
596
0
{
597
0
    std::unique_lock aGuard( m_aMutex );
598
599
0
    if ( m_bDisposed )
600
0
        throw lang::DisposedException();
601
602
0
    if ( !m_pStorage )
603
0
        throw uno::RuntimeException();
604
605
0
    if ( !m_bNoTemporaryCopy && !m_xStream.is() )
606
0
        throw io::IOException(); // TODO
607
608
0
    if ( !m_pStorage->Commit() || m_pStorage->GetError() )
609
0
    {
610
0
        m_pStorage->ResetError();
611
0
        throw io::IOException(); // TODO
612
0
    }
613
614
0
    UpdateOriginal_Impl();
615
0
}
616
617
618
void SAL_CALL OLESimpleStorage::revert()
619
0
{
620
0
    std::unique_lock aGuard( m_aMutex );
621
622
0
    if ( m_bDisposed )
623
0
        throw lang::DisposedException();
624
625
0
    if ( !m_pStorage )
626
0
        throw uno::RuntimeException();
627
628
0
    if ( !m_bNoTemporaryCopy && !m_xStream.is() )
629
0
        throw io::IOException(); // TODO
630
631
0
    if ( !m_pStorage->Revert() || m_pStorage->GetError() )
632
0
    {
633
0
        m_pStorage->ResetError();
634
0
        throw io::IOException(); // TODO
635
0
    }
636
637
0
    UpdateOriginal_Impl();
638
0
}
639
640
641
//  XClassifiedObject
642
643
644
uno::Sequence< sal_Int8 > SAL_CALL OLESimpleStorage::getClassID()
645
0
{
646
0
    std::unique_lock aGuard( m_aMutex );
647
648
0
    if ( m_bDisposed )
649
0
        throw lang::DisposedException();
650
651
0
    if ( !m_pStorage )
652
0
        throw uno::RuntimeException();
653
654
0
    return m_pStorage->GetClassName().GetByteSequence();
655
0
}
656
657
OUString SAL_CALL OLESimpleStorage::getClassName()
658
0
{
659
0
    return OUString();
660
0
}
661
662
void SAL_CALL OLESimpleStorage::setClassInfo( const uno::Sequence< sal_Int8 >& /*aClassID*/,
663
                            const OUString& /*sClassName*/ )
664
0
{
665
0
    throw lang::NoSupportException();
666
0
}
667
668
//  XServiceInfo
669
OUString SAL_CALL OLESimpleStorage::getImplementationName()
670
0
{
671
0
    return u"com.sun.star.comp.embed.OLESimpleStorage"_ustr;
672
0
}
673
674
sal_Bool SAL_CALL OLESimpleStorage::supportsService( const OUString& ServiceName )
675
0
{
676
0
    return cppu::supportsService(this, ServiceName);
677
0
}
678
679
uno::Sequence< OUString > SAL_CALL OLESimpleStorage::getSupportedServiceNames()
680
0
{
681
0
    return { u"com.sun.star.embed.OLESimpleStorage"_ustr };
682
0
}
683
684
extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
685
com_sun_star_comp_embed_OLESimpleStorage(
686
    css::uno::XComponentContext *context,
687
    css::uno::Sequence<css::uno::Any> const &arguments)
688
88.0k
{
689
88.0k
    return cppu::acquire(new OLESimpleStorage(context, arguments));
690
88.0k
}
691
692
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */