/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: */ |