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 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 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 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 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 89 StorageBase::~StorageBase() 90 { 91 } 92 93 bool StorageBase::isStorage() const 94 { 95 return implIsStorage(); 96 } 97 98 bool StorageBase::isRootStorage() const 99 { 100 return implIsStorage() && (maStorageName.getLength() == 0); 101 } 102 103 bool StorageBase::isReadOnly() const 104 { 105 return mbReadOnly; 106 } 107 108 Reference< XStorage > StorageBase::getXStorage() const 109 { 110 return implGetXStorage(); 111 } 112 113 const OUString& StorageBase::getName() const 114 { 115 return maStorageName; 116 } 117 118 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 127 void StorageBase::getElementNames( ::std::vector< OUString >& orElementNames ) const 128 { 129 orElementNames.clear(); 130 implGetElementNames( orElementNames ); 131 } 132 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 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 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 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 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 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 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