Coverage Report

Created: 2026-09-28 10:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/package/source/xstor/owriteablestream.hxx
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
#ifndef INCLUDED_PACKAGE_SOURCE_XSTOR_OWRITEABLESTREAM_HXX
21
#define INCLUDED_PACKAGE_SOURCE_XSTOR_OWRITEABLESTREAM_HXX
22
23
#include <com/sun/star/io/XInputStream.hpp>
24
#include <com/sun/star/io/XOutputStream.hpp>
25
#include <com/sun/star/io/XStream.hpp>
26
#include <com/sun/star/io/XSeekable.hpp>
27
#include <com/sun/star/io/XTruncate.hpp>
28
#include <com/sun/star/packages/XDataSinkEncrSupport.hpp>
29
#include <com/sun/star/lang/XEventListener.hpp>
30
#include <com/sun/star/lang/XSingleServiceFactory.hpp>
31
#include <com/sun/star/embed/XEncryptionProtectedSource2.hpp>
32
#include <com/sun/star/embed/XStorage.hpp>
33
#include <com/sun/star/embed/XRelationshipAccess.hpp>
34
#include <com/sun/star/embed/XExtendedStorageStream.hpp>
35
#include <com/sun/star/embed/XTransactedObject.hpp>
36
#include <com/sun/star/embed/XTransactionBroadcaster.hpp>
37
#include <com/sun/star/container/XNameContainer.hpp>
38
#include <com/sun/star/beans/StringPair.hpp>
39
40
#include <cppuhelper/weak.hxx>
41
#include <cppuhelper/typeprovider.hxx>
42
#include <comphelper/multicontainer2.hxx>
43
44
#include <comphelper/bytereader.hxx>
45
#include <comphelper/refcountedmutex.hxx>
46
#include <comphelper/sequenceashashmap.hxx>
47
#include <unotools/tempfile.hxx>
48
49
#include <vector>
50
#include <memory>
51
#include <string_view>
52
53
#include "ocompinstream.hxx"
54
55
namespace com::sun::star::uno {
56
    class XComponentContext;
57
}
58
59
namespace package {
60
    // all data in aHash1 is contained in aHash2
61
    bool PackageEncryptionDataLessOrEqual( const ::comphelper::SequenceAsHashMap& aHash1, const ::comphelper::SequenceAsHashMap& aHash2 );
62
}
63
64
struct OStorage_Impl;
65
class OWriteStream;
66
67
struct OWriteStream_Impl
68
{
69
    rtl::Reference<comphelper::RefCountedMutex> m_xMutex;
70
71
    friend struct OStorage_Impl;
72
    friend class OWriteStream;
73
    friend class OInputCompStream;
74
75
    OWriteStream*   m_pAntiImpl;
76
    std::optional<utl::TempFileFast> m_oTempFile;
77
78
    css::uno::Reference< css::io::XStream > m_xCacheStream;
79
    css::uno::Reference< css::io::XSeekable > m_xCacheSeek;
80
81
    std::vector< OInputCompStream* > m_aInputStreamsVector;
82
83
    bool                        m_bHasDataToFlush;    // only modified elements will be sent to the original content
84
    bool                        m_bFlushed;      // sending the streams is coordinated by the root storage of the package
85
86
    css::uno::Reference< css::packages::XDataSinkEncrSupport > m_xPackageStream;
87
88
    css::uno::Reference< css::uno::XComponentContext > m_xContext;
89
90
    OStorage_Impl* m_pParent;
91
92
    css::uno::Sequence< css::beans::PropertyValue > m_aProps;
93
94
    bool m_bForceEncrypted;
95
96
    bool m_bUseCommonEncryption;
97
    bool m_bHasCachedEncryptionData;
98
    ::comphelper::SequenceAsHashMap m_aEncryptionData;
99
100
    bool m_bCompressedSetExplicit;
101
102
    css::uno::Reference< css::lang::XSingleServiceFactory > m_xPackage;
103
104
    bool m_bHasInsertedStreamOptimization;
105
106
    sal_Int32 m_nStorageType;
107
108
    // Relations info related data, stored in *.rels file in OFOPXML format
109
    css::uno::Reference< css::io::XInputStream > m_xOrigRelInfoStream;
110
    css::uno::Sequence< css::uno::Sequence< css::beans::StringPair > > m_aOrigRelInfo;
111
    bool m_bOrigRelInfoBroken;
112
113
    css::uno::Sequence< css::uno::Sequence< css::beans::StringPair > > m_aNewRelInfo;
114
    css::uno::Reference< css::io::XInputStream > m_xNewRelInfoStream;
115
    sal_Int16 m_nRelInfoStatus;
116
    sal_Int32 m_nRelId;
117
118
private:
119
    void GetFilledTempFileIfNo( const css::uno::Reference< css::io::XInputStream >& xStream );
120
    void FillTempGetFileName();
121
    css::uno::Reference< css::io::XStream >       GetTempFileAsStream();
122
    css::uno::Reference< css::io::XInputStream >  GetTempFileAsInputStream();
123
124
    css::uno::Reference< css::io::XStream > GetStream_Impl( sal_Int32 nStreamMode,
125
                                                                                        bool bHierarchyAccess );
126
127
    /// @throws css::packages::NoEncryptionException
128
    ::comphelper::SequenceAsHashMap GetCommonRootEncryptionData();
129
130
    css::uno::Sequence< css::beans::PropertyValue > ReadPackageStreamProperties();
131
    css::uno::Sequence< css::beans::PropertyValue > InsertOwnProps(
132
                            const css::uno::Sequence< css::beans::PropertyValue >& aProps,
133
                            bool bUseCommonEncryption );
134
135
public:
136
    OWriteStream_Impl(
137
                OStorage_Impl* pParent,
138
                const css::uno::Reference< css::packages::XDataSinkEncrSupport >& xPackageStream,
139
                const css::uno::Reference< css::lang::XSingleServiceFactory >& xPackage,
140
                css::uno::Reference< css::uno::XComponentContext > xContext,
141
                bool bForceEncrypted,
142
                sal_Int32 nStorageType,
143
                bool bDefaultCompress,
144
                css::uno::Reference< css::io::XInputStream > xRelInfoStream =
145
                    css::uno::Reference< css::io::XInputStream >() );
146
147
    ~OWriteStream_Impl();
148
149
    void CleanCacheStream();
150
151
0
    bool UsesCommonEncryption_Impl() const { return m_bUseCommonEncryption; }
152
0
    bool HasTempFile_Impl() const { return m_oTempFile.has_value(); }
153
    bool IsTransacted();
154
155
0
    bool HasWriteOwner_Impl() const { return ( m_pAntiImpl != nullptr ); }
156
157
    void InsertIntoPackageFolder(
158
            const OUString& aName,
159
            const css::uno::Reference< css::container::XNameContainer >& xParentPackageFolder );
160
161
0
    void SetToBeCommited() { m_bFlushed = true; }
162
163
0
    bool HasCachedEncryptionData() const { return m_bHasCachedEncryptionData; }
164
0
    ::comphelper::SequenceAsHashMap& GetCachedEncryptionData() { return m_aEncryptionData; }
165
166
0
    bool IsModified() const { return m_bHasDataToFlush || m_bFlushed; }
167
168
    bool IsEncrypted();
169
    void SetDecrypted();
170
    void SetEncrypted( const ::comphelper::SequenceAsHashMap& aEncryptionData );
171
172
    void DisposeWrappers();
173
174
    void InsertStreamDirectly(
175
            const css::uno::Reference< css::io::XInputStream >& xInStream,
176
            const css::uno::Sequence< css::beans::PropertyValue >& aProps );
177
178
    void Commit();
179
    void Revert();
180
181
    css::uno::Sequence< css::beans::PropertyValue > const & GetStreamProperties();
182
183
    css::uno::Sequence< css::uno::Sequence< css::beans::StringPair > > GetAllRelationshipsIfAny();
184
185
    void CopyInternallyTo_Impl( const css::uno::Reference< css::io::XStream >& xDestStream,
186
                                const ::comphelper::SequenceAsHashMap& aEncryptionData );
187
    void CopyInternallyTo_Impl( const css::uno::Reference< css::io::XStream >& xDestStream );
188
189
    css::uno::Reference< css::io::XStream > GetStream(
190
                        sal_Int32 nStreamMode,
191
                        const ::comphelper::SequenceAsHashMap& aEncryptionData,
192
                        bool bHierarchyAccess );
193
194
    css::uno::Reference< css::io::XStream > GetStream(
195
                        sal_Int32 nStreamMode,
196
                        bool bHierarchyAccess );
197
198
    css::uno::Reference< css::io::XInputStream > GetRawInStream();
199
    css::uno::Reference< css::io::XInputStream > GetPlainRawInStream();
200
201
    void InputStreamDisposed( OInputCompStream* pStream );
202
203
    void CreateReadonlyCopyBasedOnData(
204
                    const css::uno::Reference< css::io::XInputStream >& xDataToCopy,
205
                    const css::uno::Sequence< css::beans::PropertyValue >& aProps,
206
                    css::uno::Reference< css::io::XStream >& xTargetStream );
207
208
    void GetCopyOfLastCommit( css::uno::Reference< css::io::XStream >& xTargetStream );
209
    void GetCopyOfLastCommit(
210
                  css::uno::Reference< css::io::XStream >& xTargetStream,
211
                            const ::comphelper::SequenceAsHashMap& aEncryptionData );
212
213
    void CommitStreamRelInfo(
214
                    const css::uno::Reference< css::embed::XStorage >& xRelStorage,
215
                    std::u16string_view aOrigStreamName,
216
                    std::u16string_view aNewStreamName );
217
218
    void ReadRelInfoIfNecessary();
219
220
0
    sal_Int32 GetNewRelId() { return m_nRelId ++; }
221
};
222
223
class OWriteStream : public css::lang::XTypeProvider
224
            , public css::io::XInputStream
225
            , public css::io::XOutputStream
226
            , public css::embed::XExtendedStorageStream
227
            , public css::io::XSeekable
228
            , public css::io::XTruncate
229
            , public css::embed::XEncryptionProtectedSource2
230
            , public css::embed::XRelationshipAccess
231
            , public css::embed::XTransactedObject
232
            , public css::embed::XTransactionBroadcaster
233
            , public css::beans::XPropertySet
234
            , public ::cppu::OWeakObject
235
            , public comphelper::ByteReader
236
            , public comphelper::ByteWriter
237
{
238
    friend struct OWriteStream_Impl;
239
240
protected:
241
    css::uno::Reference < css::io::XInputStream > m_xInStream;
242
    css::uno::Reference < css::io::XOutputStream > m_xOutStream;
243
    css::uno::Reference < css::io::XSeekable > m_xSeekable;
244
245
    OWriteStream_Impl* m_pImpl;
246
    rtl::Reference<comphelper::RefCountedMutex> m_xSharedMutex;
247
    ::std::optional< ::cppu::OTypeCollection> m_oTypeCollection;
248
    comphelper::OMultiTypeInterfaceContainerHelper2 m_aListenersContainer; // list of listeners
249
    sal_Int32 m_nStorageType;
250
251
    bool m_bInStreamDisconnected;
252
    bool m_bInitOnDemand;
253
    sal_Int64 m_nInitPosition;
254
255
    bool m_bTransacted;
256
257
    OWriteStream( OWriteStream_Impl& rImpl, bool bTransacted );
258
    OWriteStream( OWriteStream_Impl& rImpl, css::uno::Reference< css::io::XStream > const & xStream, bool bTransacted );
259
260
    void CloseOutput_Impl();
261
262
    void CopyToStreamInternally_Impl( const css::uno::Reference< css::io::XStream >& xStream );
263
264
    void ModifyParentUnlockMutex_Impl(osl::ClearableMutexGuard& aGuard);
265
266
    void BroadcastTransaction( sal_Int8 nMessage );
267
268
public:
269
270
    virtual ~OWriteStream() override;
271
272
    // XInterface
273
    virtual css::uno::Any SAL_CALL queryInterface( const css::uno::Type& rType ) override;
274
    virtual void SAL_CALL acquire() noexcept override;
275
    virtual void SAL_CALL release() noexcept override;
276
277
    //  XTypeProvider
278
    virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override;
279
    virtual css::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() override;
280
281
    // XInputStream
282
    virtual sal_Int32 SAL_CALL readBytes( css::uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead ) override;
283
    virtual sal_Int32 SAL_CALL readSomeBytes( css::uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead ) override;
284
    virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip ) override;
285
    virtual sal_Int32 SAL_CALL available(  ) override;
286
    virtual void SAL_CALL closeInput(  ) override;
287
288
    // XOutputStream
289
    virtual void SAL_CALL writeBytes( const css::uno::Sequence< sal_Int8 >& aData ) override;
290
    virtual void SAL_CALL flush(  ) override;
291
    virtual void SAL_CALL closeOutput(  ) override;
292
293
    //XSeekable
294
    virtual void SAL_CALL seek( sal_Int64 location ) override;
295
    virtual sal_Int64 SAL_CALL getPosition() override;
296
    virtual sal_Int64 SAL_CALL getLength() override;
297
298
    //XStream
299
    virtual css::uno::Reference< css::io::XInputStream > SAL_CALL getInputStream(  ) override;
300
    virtual css::uno::Reference< css::io::XOutputStream > SAL_CALL getOutputStream(  ) override;
301
302
    // XTruncate
303
    virtual void SAL_CALL truncate() override;
304
305
    //XComponent
306
    virtual void SAL_CALL dispose() override;
307
    virtual void SAL_CALL addEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener ) override;
308
    virtual void SAL_CALL removeEventListener( const css::uno::Reference< css::lang::XEventListener >& aListener ) override;
309
310
    //XEncryptionProtectedSource
311
    virtual void SAL_CALL setEncryptionPassword( const OUString& aPass ) override;
312
    virtual void SAL_CALL removeEncryption() override;
313
314
    //XEncryptionProtectedSource2
315
    virtual void SAL_CALL setEncryptionData( const css::uno::Sequence< css::beans::NamedValue >& aEncryptionData ) override;
316
    virtual sal_Bool SAL_CALL hasEncryptionData() override;
317
318
    //XRelationshipAccess
319
    virtual sal_Bool SAL_CALL hasByID( const OUString& sID ) override;
320
    virtual OUString SAL_CALL getTargetByID( const OUString& sID ) override;
321
    virtual OUString SAL_CALL getTypeByID( const OUString& sID ) override;
322
    virtual css::uno::Sequence< css::beans::StringPair > SAL_CALL getRelationshipByID( const OUString& sID ) override;
323
    virtual css::uno::Sequence< css::uno::Sequence< css::beans::StringPair > > SAL_CALL getRelationshipsByType( const OUString& sType ) override;
324
    virtual css::uno::Sequence< css::uno::Sequence< css::beans::StringPair > > SAL_CALL getAllRelationships(  ) override;
325
    virtual void SAL_CALL insertRelationshipByID( const OUString& sID, const css::uno::Sequence< css::beans::StringPair >& aEntry, sal_Bool bReplace ) override;
326
    virtual void SAL_CALL removeRelationshipByID( const OUString& sID ) override;
327
    virtual void SAL_CALL insertRelationships( const css::uno::Sequence< css::uno::Sequence< css::beans::StringPair > >& aEntries, sal_Bool bReplace ) override;
328
    virtual void SAL_CALL clearRelationships(  ) override;
329
330
    //XPropertySet
331
    virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override;
332
    virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const css::uno::Any& aValue ) override;
333
    virtual css::uno::Any SAL_CALL getPropertyValue( const OUString& PropertyName ) override;
334
    virtual void SAL_CALL addPropertyChangeListener( const OUString& aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener >& xListener ) override;
335
    virtual void SAL_CALL removePropertyChangeListener( const OUString& aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener >& aListener ) override;
336
    virtual void SAL_CALL addVetoableChangeListener( const OUString& PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override;
337
    virtual void SAL_CALL removeVetoableChangeListener( const OUString& PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override;
338
339
    // XTransactedObject
340
    virtual void SAL_CALL commit() override;
341
    virtual void SAL_CALL revert() override;
342
343
    // XTransactionBroadcaster
344
    virtual void SAL_CALL addTransactionListener(
345
            const css::uno::Reference< css::embed::XTransactionListener >& aListener ) override;
346
    virtual void SAL_CALL removeTransactionListener(
347
            const css::uno::Reference< css::embed::XTransactionListener >& aListener ) override;
348
349
    // comphelper::ByteReader
350
    virtual sal_Int32 readSomeBytes(sal_Int8* aData, sal_Int32 nBytesToRead) override;
351
352
    // comphelper::ByteWriter
353
    virtual void writeBytes(const sal_Int8* aData, sal_Int32 nBytesToWrite) override;
354
355
private:
356
    void CheckInitOnDemand();
357
    void CheckInitOnWriteDemand(sal_Int32 dataSize);
358
    void DeInit();
359
};
360
361
#endif
362
363
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */