/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ #include "oox/helper/storagebase.hxx" #include #include #include #include "oox/helper/binaryinputstream.hxx" #include "oox/helper/binaryoutputstream.hxx" namespace oox { // ============================================================================ using namespace ::com::sun::star::embed; using namespace ::com::sun::star::io; using namespace ::com::sun::star::uno; using ::rtl::OUString; using ::rtl::OUStringBuffer; // ============================================================================ namespace { void lclSplitFirstElement( OUString& orElement, OUString& orRemainder, const OUString& rFullName ) { sal_Int32 nSlashPos = rFullName.indexOf( '/' ); if( (0 <= nSlashPos) && (nSlashPos < rFullName.getLength()) ) { orElement = rFullName.copy( 0, nSlashPos ); orRemainder = rFullName.copy( nSlashPos + 1 ); } else { orElement = rFullName; } } } // namespace // ---------------------------------------------------------------------------- StorageBase::StorageBase( const Reference< XInputStream >& rxInStream, bool bBaseStreamAccess ) : mxInStream( rxInStream ), mbBaseStreamAccess( bBaseStreamAccess ), mbReadOnly( true ) { OSL_ENSURE( mxInStream.is(), "StorageBase::StorageBase - missing base input stream" ); } StorageBase::StorageBase( const Reference< XStream >& rxOutStream, bool bBaseStreamAccess ) : mxOutStream( rxOutStream ), mbBaseStreamAccess( bBaseStreamAccess ), mbReadOnly( false ) { OSL_ENSURE( mxOutStream.is(), "StorageBase::StorageBase - missing base output stream" ); } StorageBase::StorageBase( const StorageBase& rParentStorage, const OUString& rStorageName, bool bReadOnly ) : maParentPath( rParentStorage.getPath() ), maStorageName( rStorageName ), mbBaseStreamAccess( false ), mbReadOnly( bReadOnly ) { } StorageBase::~StorageBase() { } bool StorageBase::isStorage() const { return implIsStorage(); } bool StorageBase::isRootStorage() const { return implIsStorage() && (maStorageName.getLength() == 0); } bool StorageBase::isReadOnly() const { return mbReadOnly; } Reference< XStorage > StorageBase::getXStorage() const { return implGetXStorage(); } const OUString& StorageBase::getName() const { return maStorageName; } OUString StorageBase::getPath() const { OUStringBuffer aBuffer( maParentPath ); if( aBuffer.getLength() > 0 ) aBuffer.append( sal_Unicode( '/' ) ); aBuffer.append( maStorageName ); return aBuffer.makeStringAndClear(); } void StorageBase::getElementNames( ::std::vector< OUString >& orElementNames ) const { orElementNames.clear(); implGetElementNames( orElementNames ); } StorageRef StorageBase::openSubStorage( const OUString& rStorageName, bool bCreateMissing ) { StorageRef xSubStorage; OSL_ENSURE( !bCreateMissing || !mbReadOnly, "StorageBase::openSubStorage - cannot create substorage in read-only mode" ); if( !bCreateMissing || !mbReadOnly ) { OUString aElement, aRemainder; lclSplitFirstElement( aElement, aRemainder, rStorageName ); if( aElement.getLength() > 0 ) xSubStorage = getSubStorage( aElement, bCreateMissing ); if( xSubStorage.get() && (aRemainder.getLength() > 0) ) xSubStorage = xSubStorage->openSubStorage( aRemainder, bCreateMissing ); } return xSubStorage; } Reference< XInputStream > StorageBase::openInputStream( const OUString& rStreamName ) { Reference< XInputStream > xInStream; OUString aElement, aRemainder; lclSplitFirstElement( aElement, aRemainder, rStreamName ); if( aElement.getLength() > 0 ) { if( aRemainder.getLength() > 0 ) { StorageRef xSubStorage = getSubStorage( aElement, false ); if( xSubStorage.get() ) xInStream = xSubStorage->openInputStream( aRemainder ); } else { xInStream = implOpenInputStream( aElement ); } } else if( mbBaseStreamAccess ) { xInStream = mxInStream; } return xInStream; } Reference< XOutputStream > StorageBase::openOutputStream( const OUString& rStreamName ) { Reference< XOutputStream > xOutStream; OSL_ENSURE( !mbReadOnly, "StorageBase::openOutputStream - cannot create output stream in read-only mode" ); if( !mbReadOnly ) { OUString aElement, aRemainder; lclSplitFirstElement( aElement, aRemainder, rStreamName ); if( aElement.getLength() > 0 ) { if( aRemainder.getLength() > 0 ) { StorageRef xSubStorage = getSubStorage( aElement, true ); if( xSubStorage.get() ) xOutStream = xSubStorage->openOutputStream( aRemainder ); } else { xOutStream = implOpenOutputStream( aElement ); } } else if( mbBaseStreamAccess ) { xOutStream = mxOutStream->getOutputStream(); } } return xOutStream; } void StorageBase::copyToStorage( StorageBase& rDestStrg, const OUString& rElementName ) { OSL_ENSURE( rDestStrg.isStorage() && !rDestStrg.isReadOnly(), "StorageBase::copyToStorage - invalid destination" ); OSL_ENSURE( rElementName.getLength() > 0, "StorageBase::copyToStorage - invalid element name" ); if( rDestStrg.isStorage() && !rDestStrg.isReadOnly() && (rElementName.getLength() > 0) ) { StorageRef xSubStrg = openSubStorage( rElementName, false ); if( xSubStrg.get() ) { StorageRef xDestSubStrg = rDestStrg.openSubStorage( rElementName, true ); if( xDestSubStrg.get() ) xSubStrg->copyStorageToStorage( *xDestSubStrg ); } else { Reference< XInputStream > xInStrm = openInputStream( rElementName ); if( xInStrm.is() ) { Reference< XOutputStream > xOutStrm = rDestStrg.openOutputStream( rElementName ); if( xOutStrm.is() ) { BinaryXInputStream aInStrm( xInStrm, true ); BinaryXOutputStream aOutStrm( xOutStrm, true ); aInStrm.copyToStream( aOutStrm ); } } } } } void StorageBase::copyStorageToStorage( StorageBase& rDestStrg ) { OSL_ENSURE( rDestStrg.isStorage() && !rDestStrg.isReadOnly(), "StorageBase::copyToStorage - invalid destination" ); if( rDestStrg.isStorage() && !rDestStrg.isReadOnly() ) { ::std::vector< OUString > aElements; getElementNames( aElements ); for( ::std::vector< OUString >::iterator aIt = aElements.begin(), aEnd = aElements.end(); aIt != aEnd; ++aIt ) copyToStorage( rDestStrg, *aIt ); } } void StorageBase::commit() { OSL_ENSURE( !mbReadOnly, "StorageBase::commit - cannot commit in read-only mode" ); if( !mbReadOnly ) { // commit all open substorages maSubStorages.forEachMem( &StorageBase::commit ); // commit this storage implCommit(); } } // private -------------------------------------------------------------------- StorageRef StorageBase::getSubStorage( const OUString& rElementName, bool bCreateMissing ) { StorageRef& rxSubStrg = maSubStorages[ rElementName ]; if( !rxSubStrg ) rxSubStrg = implOpenSubStorage( rElementName, bCreateMissing ); return rxSubStrg; } // ============================================================================ } // namespace oox