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