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