xref: /trunk/main/oox/source/helper/storagebase.cxx (revision ca5ec200)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #include "oox/helper/storagebase.hxx"
25 
26 #include <com/sun/star/embed/XTransactedObject.hpp>
27 #include <com/sun/star/io/XStream.hpp>
28 #include <rtl/ustrbuf.hxx>
29 #include "oox/helper/binaryinputstream.hxx"
30 #include "oox/helper/binaryoutputstream.hxx"
31 
32 namespace oox {
33 
34 // ============================================================================
35 
36 using namespace ::com::sun::star::embed;
37 using namespace ::com::sun::star::io;
38 using namespace ::com::sun::star::uno;
39 
40 using ::rtl::OUString;
41 using ::rtl::OUStringBuffer;
42 
43 // ============================================================================
44 
45 namespace {
46 
lclSplitFirstElement(OUString & orElement,OUString & orRemainder,const OUString & rFullName)47 void lclSplitFirstElement( OUString& orElement, OUString& orRemainder, const OUString& rFullName )
48 {
49     sal_Int32 nSlashPos = rFullName.indexOf( '/' );
50     if( (0 <= nSlashPos) && (nSlashPos < rFullName.getLength()) )
51     {
52         orElement = rFullName.copy( 0, nSlashPos );
53         orRemainder = rFullName.copy( nSlashPos + 1 );
54     }
55     else
56     {
57         orElement = rFullName;
58     }
59 }
60 
61 } // namespace
62 
63 // ----------------------------------------------------------------------------
64 
StorageBase(const Reference<XInputStream> & rxInStream,bool bBaseStreamAccess)65 StorageBase::StorageBase( const Reference< XInputStream >& rxInStream, bool bBaseStreamAccess ) :
66     mxInStream( rxInStream ),
67     mbBaseStreamAccess( bBaseStreamAccess ),
68     mbReadOnly( true )
69 {
70     OSL_ENSURE( mxInStream.is(), "StorageBase::StorageBase - missing base input stream" );
71 }
72 
StorageBase(const Reference<XStream> & rxOutStream,bool bBaseStreamAccess)73 StorageBase::StorageBase( const Reference< XStream >& rxOutStream, bool bBaseStreamAccess ) :
74     mxOutStream( rxOutStream ),
75     mbBaseStreamAccess( bBaseStreamAccess ),
76     mbReadOnly( false )
77 {
78     OSL_ENSURE( mxOutStream.is(), "StorageBase::StorageBase - missing base output stream" );
79 }
80 
StorageBase(const StorageBase & rParentStorage,const OUString & rStorageName,bool bReadOnly)81 StorageBase::StorageBase( const StorageBase& rParentStorage, const OUString& rStorageName, bool bReadOnly ) :
82     maParentPath( rParentStorage.getPath() ),
83     maStorageName( rStorageName ),
84     mbBaseStreamAccess( false ),
85     mbReadOnly( bReadOnly )
86 {
87 }
88 
~StorageBase()89 StorageBase::~StorageBase()
90 {
91 }
92 
isStorage() const93 bool StorageBase::isStorage() const
94 {
95     return implIsStorage();
96 }
97 
isRootStorage() const98 bool StorageBase::isRootStorage() const
99 {
100     return implIsStorage() && (maStorageName.getLength() == 0);
101 }
102 
isReadOnly() const103 bool StorageBase::isReadOnly() const
104 {
105     return mbReadOnly;
106 }
107 
getXStorage() const108 Reference< XStorage > StorageBase::getXStorage() const
109 {
110     return implGetXStorage();
111 }
112 
getName() const113 const OUString& StorageBase::getName() const
114 {
115     return maStorageName;
116 }
117 
getPath() const118 OUString StorageBase::getPath() const
119 {
120     OUStringBuffer aBuffer( maParentPath );
121     if( aBuffer.getLength() > 0 )
122         aBuffer.append( sal_Unicode( '/' ) );
123     aBuffer.append( maStorageName );
124     return aBuffer.makeStringAndClear();
125 }
126 
getElementNames(::std::vector<OUString> & orElementNames) const127 void StorageBase::getElementNames( ::std::vector< OUString >& orElementNames ) const
128 {
129     orElementNames.clear();
130     implGetElementNames( orElementNames );
131 }
132 
openSubStorage(const OUString & rStorageName,bool bCreateMissing)133 StorageRef StorageBase::openSubStorage( const OUString& rStorageName, bool bCreateMissing )
134 {
135     StorageRef xSubStorage;
136     OSL_ENSURE( !bCreateMissing || !mbReadOnly, "StorageBase::openSubStorage - cannot create substorage in read-only mode" );
137     if( !bCreateMissing || !mbReadOnly )
138     {
139         OUString aElement, aRemainder;
140         lclSplitFirstElement( aElement, aRemainder, rStorageName );
141         if( aElement.getLength() > 0 )
142             xSubStorage = getSubStorage( aElement, bCreateMissing );
143         if( xSubStorage.get() && (aRemainder.getLength() > 0) )
144             xSubStorage = xSubStorage->openSubStorage( aRemainder, bCreateMissing );
145     }
146     return xSubStorage;
147 }
148 
openInputStream(const OUString & rStreamName)149 Reference< XInputStream > StorageBase::openInputStream( const OUString& rStreamName )
150 {
151     Reference< XInputStream > xInStream;
152     OUString aElement, aRemainder;
153     lclSplitFirstElement( aElement, aRemainder, rStreamName );
154     if( aElement.getLength() > 0 )
155     {
156         if( aRemainder.getLength() > 0 )
157         {
158             StorageRef xSubStorage = getSubStorage( aElement, false );
159             if( xSubStorage.get() )
160                 xInStream = xSubStorage->openInputStream( aRemainder );
161         }
162         else
163         {
164             xInStream = implOpenInputStream( aElement );
165         }
166     }
167     else if( mbBaseStreamAccess )
168     {
169         xInStream = mxInStream;
170     }
171     return xInStream;
172 }
173 
openOutputStream(const OUString & rStreamName)174 Reference< XOutputStream > StorageBase::openOutputStream( const OUString& rStreamName )
175 {
176     Reference< XOutputStream > xOutStream;
177     OSL_ENSURE( !mbReadOnly, "StorageBase::openOutputStream - cannot create output stream in read-only mode" );
178     if( !mbReadOnly )
179     {
180         OUString aElement, aRemainder;
181         lclSplitFirstElement( aElement, aRemainder, rStreamName );
182         if( aElement.getLength() > 0 )
183         {
184             if( aRemainder.getLength() > 0 )
185             {
186                 StorageRef xSubStorage = getSubStorage( aElement, true );
187                 if( xSubStorage.get() )
188                     xOutStream = xSubStorage->openOutputStream( aRemainder );
189             }
190             else
191             {
192                 xOutStream = implOpenOutputStream( aElement );
193             }
194         }
195         else if( mbBaseStreamAccess )
196         {
197             xOutStream = mxOutStream->getOutputStream();
198         }
199     }
200     return xOutStream;
201 }
202 
copyToStorage(StorageBase & rDestStrg,const OUString & rElementName)203 void StorageBase::copyToStorage( StorageBase& rDestStrg, const OUString& rElementName )
204 {
205     OSL_ENSURE( rDestStrg.isStorage() && !rDestStrg.isReadOnly(), "StorageBase::copyToStorage - invalid destination" );
206     OSL_ENSURE( rElementName.getLength() > 0, "StorageBase::copyToStorage - invalid element name" );
207     if( rDestStrg.isStorage() && !rDestStrg.isReadOnly() && (rElementName.getLength() > 0) )
208     {
209         StorageRef xSubStrg = openSubStorage( rElementName, false );
210         if( xSubStrg.get() )
211         {
212             StorageRef xDestSubStrg = rDestStrg.openSubStorage( rElementName, true );
213             if( xDestSubStrg.get() )
214                 xSubStrg->copyStorageToStorage( *xDestSubStrg );
215         }
216         else
217         {
218             Reference< XInputStream > xInStrm = openInputStream( rElementName );
219             if( xInStrm.is() )
220             {
221                 Reference< XOutputStream > xOutStrm = rDestStrg.openOutputStream( rElementName );
222                 if( xOutStrm.is() )
223                 {
224                     BinaryXInputStream aInStrm( xInStrm, true );
225                     BinaryXOutputStream aOutStrm( xOutStrm, true );
226                     aInStrm.copyToStream( aOutStrm );
227                 }
228             }
229         }
230     }
231 }
232 
copyStorageToStorage(StorageBase & rDestStrg)233 void StorageBase::copyStorageToStorage( StorageBase& rDestStrg )
234 {
235     OSL_ENSURE( rDestStrg.isStorage() && !rDestStrg.isReadOnly(), "StorageBase::copyToStorage - invalid destination" );
236     if( rDestStrg.isStorage() && !rDestStrg.isReadOnly() )
237     {
238         ::std::vector< OUString > aElements;
239         getElementNames( aElements );
240         for( ::std::vector< OUString >::iterator aIt = aElements.begin(), aEnd = aElements.end(); aIt != aEnd; ++aIt )
241             copyToStorage( rDestStrg, *aIt );
242     }
243 }
244 
commit()245 void StorageBase::commit()
246 {
247     OSL_ENSURE( !mbReadOnly, "StorageBase::commit - cannot commit in read-only mode" );
248     if( !mbReadOnly )
249     {
250         // commit all open substorages
251         maSubStorages.forEachMem( &StorageBase::commit );
252         // commit this storage
253         implCommit();
254     }
255 }
256 
257 // private --------------------------------------------------------------------
258 
getSubStorage(const OUString & rElementName,bool bCreateMissing)259 StorageRef StorageBase::getSubStorage( const OUString& rElementName, bool bCreateMissing )
260 {
261     StorageRef& rxSubStrg = maSubStorages[ rElementName ];
262     if( !rxSubStrg )
263         rxSubStrg = implOpenSubStorage( rElementName, bCreateMissing );
264     return rxSubStrg;
265 }
266 
267 // ============================================================================
268 
269 } // namespace oox
270