Line data Source code
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 "oox/helper/storagebase.hxx"
21 :
22 : #include <com/sun/star/embed/XTransactedObject.hpp>
23 : #include <com/sun/star/io/XStream.hpp>
24 : #include <osl/diagnose.h>
25 : #include <rtl/ustrbuf.hxx>
26 : #include "oox/helper/binaryinputstream.hxx"
27 : #include "oox/helper/binaryoutputstream.hxx"
28 :
29 : namespace oox {
30 :
31 : using namespace ::com::sun::star::embed;
32 : using namespace ::com::sun::star::io;
33 : using namespace ::com::sun::star::uno;
34 :
35 : namespace {
36 :
37 46858 : void lclSplitFirstElement( OUString& orElement, OUString& orRemainder, const OUString& _aFullName )
38 : {
39 46858 : OUString aFullName = _aFullName;
40 46858 : sal_Int32 nSlashPos = aFullName.indexOf( '/' );
41 :
42 : // strip leading slashes
43 94772 : while( nSlashPos == 0 )
44 : {
45 1056 : aFullName = aFullName.copy(1);
46 1056 : nSlashPos = aFullName.indexOf( '/' );
47 : }
48 :
49 46858 : if( (0 <= nSlashPos) && (nSlashPos < aFullName.getLength()) )
50 : {
51 27685 : orElement = aFullName.copy( 0, nSlashPos );
52 27685 : orRemainder = aFullName.copy( nSlashPos + 1 );
53 : }
54 : else
55 : {
56 19173 : orElement = aFullName;
57 46858 : }
58 46858 : }
59 :
60 : } // namespace
61 :
62 14248 : StorageBase::StorageBase( const Reference< XInputStream >& rxInStream, bool bBaseStreamAccess ) :
63 : mxInStream( rxInStream ),
64 : mbBaseStreamAccess( bBaseStreamAccess ),
65 14248 : mbReadOnly( true )
66 : {
67 : OSL_ENSURE( mxInStream.is(), "StorageBase::StorageBase - missing base input stream" );
68 14248 : }
69 :
70 675 : StorageBase::StorageBase( const Reference< XStream >& rxOutStream, bool bBaseStreamAccess ) :
71 : mxOutStream( rxOutStream ),
72 : mbBaseStreamAccess( bBaseStreamAccess ),
73 675 : mbReadOnly( false )
74 : {
75 : OSL_ENSURE( mxOutStream.is(), "StorageBase::StorageBase - missing base output stream" );
76 675 : }
77 :
78 10421 : StorageBase::StorageBase( const StorageBase& rParentStorage, const OUString& rStorageName, bool bReadOnly ) :
79 : maParentPath( rParentStorage.getPath() ),
80 : maStorageName( rStorageName ),
81 : mbBaseStreamAccess( false ),
82 10421 : mbReadOnly( bReadOnly )
83 : {
84 10421 : }
85 :
86 25344 : StorageBase::~StorageBase()
87 : {
88 25344 : }
89 :
90 12783 : bool StorageBase::isStorage() const
91 : {
92 12783 : return implIsStorage();
93 : }
94 :
95 0 : bool StorageBase::isRootStorage() const
96 : {
97 0 : return implIsStorage() && maStorageName.isEmpty();
98 : }
99 :
100 2162 : Reference< XStorage > StorageBase::getXStorage() const
101 : {
102 2162 : return implGetXStorage();
103 : }
104 :
105 10421 : OUString StorageBase::getPath() const
106 : {
107 10421 : OUStringBuffer aBuffer( maParentPath );
108 10421 : if( !aBuffer.isEmpty() )
109 593 : aBuffer.append( '/' );
110 10421 : aBuffer.append( maStorageName );
111 10421 : return aBuffer.makeStringAndClear();
112 : }
113 :
114 96 : void StorageBase::getElementNames( ::std::vector< OUString >& orElementNames ) const
115 : {
116 96 : orElementNames.clear();
117 96 : implGetElementNames( orElementNames );
118 96 : }
119 :
120 824 : StorageRef StorageBase::openSubStorage( const OUString& rStorageName, bool bCreateMissing )
121 : {
122 824 : StorageRef xSubStorage;
123 : OSL_ENSURE( !bCreateMissing || !mbReadOnly, "StorageBase::openSubStorage - cannot create substorage in read-only mode" );
124 824 : if( !bCreateMissing || !mbReadOnly )
125 : {
126 1648 : OUString aElement, aRemainder;
127 824 : lclSplitFirstElement( aElement, aRemainder, rStorageName );
128 824 : if( !aElement.isEmpty() )
129 824 : xSubStorage = getSubStorage( aElement, bCreateMissing );
130 824 : if( xSubStorage.get() && !aRemainder.isEmpty() )
131 824 : xSubStorage = xSubStorage->openSubStorage( aRemainder, bCreateMissing );
132 : }
133 824 : return xSubStorage;
134 : }
135 :
136 27890 : Reference< XInputStream > StorageBase::openInputStream( const OUString& rStreamName )
137 : {
138 27890 : Reference< XInputStream > xInStream;
139 55780 : OUString aElement, aRemainder;
140 27890 : lclSplitFirstElement( aElement, aRemainder, rStreamName );
141 27890 : if( !aElement.isEmpty() )
142 : {
143 27890 : if( !aRemainder.isEmpty() )
144 : {
145 17409 : StorageRef xSubStorage = getSubStorage( aElement, false );
146 17409 : if( xSubStorage.get() )
147 16201 : xInStream = xSubStorage->openInputStream( aRemainder );
148 : }
149 : else
150 : {
151 10481 : xInStream = implOpenInputStream( aElement );
152 : }
153 : }
154 0 : else if( mbBaseStreamAccess )
155 : {
156 0 : xInStream = mxInStream;
157 : }
158 55780 : return xInStream;
159 : }
160 :
161 18144 : Reference< XOutputStream > StorageBase::openOutputStream( const OUString& rStreamName )
162 : {
163 18144 : Reference< XOutputStream > xOutStream;
164 : OSL_ENSURE( !mbReadOnly, "StorageBase::openOutputStream - cannot create output stream in read-only mode" );
165 18144 : if( !mbReadOnly )
166 : {
167 36288 : OUString aElement, aRemainder;
168 18144 : lclSplitFirstElement( aElement, aRemainder, rStreamName );
169 18144 : if( !aElement.isEmpty() )
170 : {
171 18144 : if( !aRemainder.isEmpty() )
172 : {
173 10276 : StorageRef xSubStorage = getSubStorage( aElement, true );
174 10276 : if( xSubStorage.get() )
175 10276 : xOutStream = xSubStorage->openOutputStream( aRemainder );
176 : }
177 : else
178 : {
179 7868 : xOutStream = implOpenOutputStream( aElement );
180 : }
181 : }
182 0 : else if( mbBaseStreamAccess )
183 : {
184 0 : xOutStream = mxOutStream->getOutputStream();
185 18144 : }
186 : }
187 18144 : return xOutStream;
188 : }
189 :
190 508 : void StorageBase::copyToStorage( StorageBase& rDestStrg, const OUString& rElementName )
191 : {
192 : OSL_ENSURE( rDestStrg.isStorage() && !rDestStrg.isReadOnly(), "StorageBase::copyToStorage - invalid destination" );
193 : OSL_ENSURE( !rElementName.isEmpty(), "StorageBase::copyToStorage - invalid element name" );
194 508 : if( rDestStrg.isStorage() && !rDestStrg.isReadOnly() && !rElementName.isEmpty() )
195 : {
196 508 : StorageRef xSubStrg = openSubStorage( rElementName, false );
197 508 : if( xSubStrg.get() )
198 : {
199 33 : StorageRef xDestSubStrg = rDestStrg.openSubStorage( rElementName, true );
200 33 : if( xDestSubStrg.get() )
201 33 : xSubStrg->copyStorageToStorage( *xDestSubStrg );
202 : }
203 : else
204 : {
205 475 : Reference< XInputStream > xInStrm = openInputStream( rElementName );
206 475 : if( xInStrm.is() )
207 : {
208 475 : Reference< XOutputStream > xOutStrm = rDestStrg.openOutputStream( rElementName );
209 475 : if( xOutStrm.is() )
210 : {
211 475 : BinaryXInputStream aInStrm( xInStrm, true );
212 950 : BinaryXOutputStream aOutStrm( xOutStrm, true );
213 950 : aInStrm.copyToStream( aOutStrm );
214 475 : }
215 475 : }
216 508 : }
217 : }
218 508 : }
219 :
220 64 : void StorageBase::copyStorageToStorage( StorageBase& rDestStrg )
221 : {
222 : OSL_ENSURE( rDestStrg.isStorage() && !rDestStrg.isReadOnly(), "StorageBase::copyToStorage - invalid destination" );
223 64 : if( rDestStrg.isStorage() && !rDestStrg.isReadOnly() )
224 : {
225 64 : ::std::vector< OUString > aElements;
226 64 : getElementNames( aElements );
227 572 : for( ::std::vector< OUString >::iterator aIt = aElements.begin(), aEnd = aElements.end(); aIt != aEnd; ++aIt )
228 572 : copyToStorage( rDestStrg, *aIt );
229 : }
230 64 : }
231 :
232 2719 : void StorageBase::commit()
233 : {
234 : OSL_ENSURE( !mbReadOnly, "StorageBase::commit - cannot commit in read-only mode" );
235 2719 : if( !mbReadOnly )
236 : {
237 : // commit all open substorages
238 2719 : maSubStorages.forEachMem( &StorageBase::commit );
239 : // commit this storage
240 2719 : implCommit();
241 : }
242 2719 : }
243 :
244 : // private --------------------------------------------------------------------
245 :
246 28509 : StorageRef StorageBase::getSubStorage( const OUString& rElementName, bool bCreateMissing )
247 : {
248 28509 : StorageRef& rxSubStrg = maSubStorages[ rElementName ];
249 28509 : if( !rxSubStrg )
250 12290 : rxSubStrg = implOpenSubStorage( rElementName, bCreateMissing );
251 28509 : return rxSubStrg;
252 : }
253 :
254 246 : } // namespace oox
255 :
256 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|