| /************************************************************** |
| * |
| * 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. |
| * |
| **************************************************************/ |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| //This file is about the conversion of the UOF v2.0 and ODF document format |
| #include "precompiled_filter.hxx" |
| |
| |
| #include "uof2storage.hxx" |
| |
| #include <com/sun/star/io/XInputStream.hpp> |
| #include <com/sun/star/uno/Exception.hpp> |
| #include <rtl/ustrbuf.hxx> |
| #include <com/sun/star/io/XOutputStream.hpp> |
| #include <com/sun/star/io/XStream.hpp> |
| #include <comphelper/storagehelper.hxx> |
| #include <com/sun/star/container/NoSuchElementException.hpp> |
| #include <com/sun/star/embed/XTransactedObject.hpp> |
| |
| namespace XSLT{ |
| |
| namespace{ |
| |
| void lclSplitFirstElement( ::rtl::OUString& orElement, ::rtl::OUString& orRemainder, const ::rtl::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; |
| } |
| } |
| |
| } |
| |
| StorageBase::StorageBase( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStream, |
| bool bBaseStreamAccess ) |
| : m_xInStream(rxInStream) |
| , m_bBaseStreamAccess(bBaseStreamAccess) |
| , m_bReadOnly(true) |
| { |
| OSL_ENSURE(m_xInStream.is(), "StorageBase::StorageBase - missing base input stream"); |
| } |
| |
| StorageBase::StorageBase( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& rxOutStream, bool bBaseStreamAccess ) |
| : m_xOutStream(rxOutStream) |
| , m_bBaseStreamAccess(bBaseStreamAccess) |
| , m_bReadOnly(false) |
| { |
| OSL_ENSURE(m_xOutStream.is(), "StorageBase::StorageBase - missing base output stream"); |
| } |
| |
| StorageBase::StorageBase( const StorageBase& rParentStorage, const ::rtl::OUString& rStorageName, bool bReadOnly ) |
| : m_aParentPath(rParentStorage.getPath()) |
| , m_aStorageName(rStorageName) |
| , m_bBaseStreamAccess(false) |
| , m_bReadOnly(bReadOnly) |
| { |
| } |
| |
| StorageBase::~StorageBase() |
| { |
| } |
| |
| bool StorageBase::isStorage() const |
| { |
| return implIsStorage(); |
| } |
| |
| bool StorageBase::isRootStorage() const |
| { |
| return implIsStorage() && (m_aStorageName.getLength() == 0); |
| } |
| |
| bool StorageBase::isReadOnly() const |
| { |
| return m_bReadOnly; |
| } |
| |
| ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > StorageBase::getXStorage() const |
| { |
| return implGetXStorage(); |
| } |
| |
| const ::rtl::OUString& StorageBase::getName() const |
| { |
| return m_aStorageName; |
| } |
| |
| ::rtl::OUString StorageBase::getPath() const |
| { |
| ::rtl::OUStringBuffer aBuffer(m_aParentPath); |
| if(aBuffer.getLength() > 0) |
| { |
| aBuffer.append(sal_Unicode('/')); |
| } |
| |
| aBuffer.append(m_aStorageName); |
| return aBuffer.makeStringAndClear(); |
| } |
| |
| void StorageBase::getElementNames( ::std::vector< ::rtl::OUString >& orElementNames ) const |
| { |
| orElementNames.clear(); |
| implGetElementNames(orElementNames); |
| } |
| |
| XSLT::StorageRef StorageBase::openSubStorage( const ::rtl::OUString& rStorageName, bool bCreatedMissing ) |
| { |
| StorageRef xSubStorage; |
| OSL_ENSURE(!bCreatedMissing || !m_bReadOnly, "StorageBase::openSubStorage - can not create substorage in read-only mode"); |
| if(!bCreatedMissing || !m_bReadOnly) |
| { |
| ::rtl::OUString aElement, aRemainder; |
| lclSplitFirstElement(aElement, aRemainder, rStorageName); |
| if(aElement.getLength() > 0) |
| xSubStorage = getSubStorage(aElement, bCreatedMissing); |
| if(xSubStorage.get() && (aRemainder.getLength() > 0)) |
| xSubStorage = xSubStorage->openSubStorage(aRemainder, bCreatedMissing); |
| } |
| |
| return xSubStorage; |
| } |
| |
| ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > StorageBase::openInputStream( const ::rtl::OUString& rStreamName ) |
| { |
| ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > xInStream; |
| ::rtl::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(m_bBaseStreamAccess) |
| { |
| xInStream = m_xInStream; |
| } |
| |
| return xInStream; |
| } |
| |
| ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > StorageBase::openOutputStream( const ::rtl::OUString& rStreamName ) |
| { |
| ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > xOutStream; |
| OSL_ENSURE(!m_bReadOnly, "StorageBase::openOutputStream - can not create output stream in read-only mode"); |
| if(!m_bReadOnly) |
| { |
| ::rtl::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(m_bBaseStreamAccess) |
| { |
| xOutStream = m_xOutStream->getOutputStream(); |
| } |
| } |
| |
| return xOutStream; |
| } |
| |
| void StorageBase::copyToStorage( StorageBase& rDestStrg, const ::rtl::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 |
| { |
| ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > xInStrm = openInputStream(rElementName); |
| if(xInStrm.get()) |
| { |
| ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > xOutStm = rDestStrg.openOutputStream(rElementName); |
| if(xOutStm.is()) |
| { |
| /*BinaryXInputStream aInStrm(xInStrm, true); |
| BinaryXOutputStream aOutStrm(xOutStm, true); |
| aInStrm.copyToStream(aOutStrm);*/ |
| } |
| } |
| } |
| } |
| } |
| |
| void StorageBase::copyStorageToStorage( StorageBase& rDestStrg ) |
| { |
| OSL_ENSURE(rDestStrg.isStorage() && !rDestStrg.isReadOnly(), "StorageBase::copyStorageToStorage - invalid destination"); |
| if(rDestStrg.isStorage() && !rDestStrg.isReadOnly()) |
| { |
| ::std::vector< ::rtl::OUString > aElements; |
| getElementNames(aElements); |
| for( ::std::vector< ::rtl::OUString >::iterator aIter = aElements.begin(); |
| aIter != aElements.end(); ++aIter) |
| copyToStorage(rDestStrg, *aIter); |
| } |
| } |
| |
| void StorageBase::commit() |
| { |
| OSL_ENSURE(!m_bReadOnly, "StorageBase::commit - can not commit in read-only mode"); |
| if(!m_bReadOnly) |
| { |
| m_aSubStorages.forEachMem(&StorageBase::commit); |
| implCommit(); |
| } |
| } |
| |
| XSLT::StorageRef StorageBase::getSubStorage( const ::rtl::OUString& rElementName, bool bCreateMissing ) |
| { |
| StorageRef& rxSubStrg = m_aSubStorages[rElementName]; |
| if(!rxSubStrg) |
| rxSubStrg = implOpenSubStorage(rElementName, bCreateMissing); |
| return rxSubStrg; |
| } |
| |
| ZipStorage::ZipStorage( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStream ) |
| : StorageBase(rxInStream, false) |
| { |
| OSL_ENSURE(rxFactory.is(), "ZipStorage::ZipStorage - missing service factory"); |
| //create base storage object |
| try |
| { |
| m_xStorage = ::comphelper::OStorageHelper::GetStorageOfFormatFromInputStream( |
| ZIP_STORAGE_FORMAT_STRING, rxInStream, rxFactory, sal_True); |
| } |
| catch( ::com::sun::star::uno::Exception&) |
| { |
| } |
| } |
| |
| ZipStorage::ZipStorage( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& rxStream ) |
| : StorageBase(rxStream, false) |
| { |
| OSL_ENSURE(rxFactory.is(), "ZipStorage::ZipStorage - missing service factory"); |
| try |
| { |
| using namespace ::com::sun::star::embed::ElementModes; |
| m_xStorage = ::comphelper::OStorageHelper::GetStorageOfFormatFromStream( |
| ZIP_STORAGE_FORMAT_STRING, rxStream, READWRITE | TRUNCATE, rxFactory, sal_True); |
| } |
| catch( ::com::sun::star::uno::Exception& ) |
| { |
| OSL_ENSURE(false, "ZipStorage::ZipStorage - can not open output storage"); |
| } |
| } |
| |
| ZipStorage::ZipStorage( const ZipStorage& rParentStorage, const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& rxStorage, const ::rtl::OUString& rElementName ) |
| : StorageBase(rParentStorage, rElementName, rParentStorage.isReadOnly()) |
| , m_xStorage(rxStorage) |
| { |
| OSL_ENSURE(m_xStorage.is(), "ZipStorage::ZipStorage - missing storage"); |
| } |
| |
| ZipStorage::~ZipStorage() |
| { |
| |
| } |
| |
| bool ZipStorage::implIsStorage() const |
| { |
| return m_xStorage.is(); |
| } |
| |
| ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > ZipStorage::implGetXStorage() const |
| { |
| return m_xStorage; |
| } |
| |
| void ZipStorage::implGetElementNames( ::std::vector< ::rtl::OUString >& orElementNames ) const |
| { |
| ::com::sun::star::uno::Sequence< ::rtl::OUString > aNames; |
| if(m_xStorage.is()) |
| { |
| try |
| { |
| aNames = m_xStorage->getElementNames(); |
| if(aNames.getLength() > 0) |
| orElementNames.insert(orElementNames.end(), aNames.getConstArray(), aNames.getConstArray()+aNames.getLength()); |
| } |
| catch( ::com::sun::star::uno::Exception& ) |
| { |
| } |
| } |
| } |
| |
| XSLT::StorageRef ZipStorage::implOpenSubStorage( const ::rtl::OUString& rElementName, bool bCreatedMissing ) |
| { |
| ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > xSubXStorage; |
| bool bMissing = false; |
| if(m_xStorage.is()) |
| { |
| try |
| { |
| if(m_xStorage->isStorageElement(rElementName)) |
| { |
| xSubXStorage = m_xStorage->openStorageElement(rElementName, ::com::sun::star::embed::ElementModes::READ); |
| } |
| } |
| catch( ::com::sun::star::container::NoSuchElementException& ) |
| { |
| bMissing = true; |
| } |
| catch( ::com::sun::star::uno::Exception& ) |
| { |
| } |
| } |
| |
| if(bMissing && bCreatedMissing) |
| { |
| try |
| { |
| xSubXStorage = m_xStorage->openStorageElement(rElementName, ::com::sun::star::embed::ElementModes::READWRITE); |
| } |
| catch( ::com::sun::star::uno::Exception& ) |
| { |
| } |
| } |
| |
| StorageRef xSubStorage; |
| if(xSubXStorage.is()) |
| xSubStorage.reset(new ZipStorage( *this, xSubXStorage, rElementName )); |
| |
| return xSubStorage; |
| } |
| |
| ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > ZipStorage::implOpenInputStream( const ::rtl::OUString& rElementName ) |
| { |
| ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > xInStream; |
| if(m_xStorage.is()) |
| { |
| try |
| { |
| xInStream.set(m_xStorage->openStreamElement( |
| rElementName, ::com::sun::star::embed::ElementModes::READ), ::com::sun::star::uno::UNO_QUERY); |
| } |
| catch( ::com::sun::star::uno::Exception& ) |
| { |
| } |
| } |
| |
| return xInStream; |
| } |
| |
| ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > ZipStorage::implOpenOutputStream( const ::rtl::OUString& rElementName ) |
| { |
| ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > xOutStream; |
| if(m_xStorage.is()) |
| { |
| try |
| { |
| xOutStream.set(m_xStorage->openStreamElement( |
| rElementName, ::com::sun::star::embed::ElementModes::READWRITE), ::com::sun::star::uno::UNO_QUERY); |
| } |
| catch( ::com::sun::star::uno::Exception& ) |
| { |
| } |
| } |
| |
| return xOutStream; |
| } |
| |
| void ZipStorage::implCommit() const |
| { |
| try |
| { |
| ::com::sun::star::uno::Reference< ::com::sun::star::embed::XTransactedObject > (m_xStorage, |
| ::com::sun::star::uno::UNO_QUERY_THROW)->commit(); |
| } |
| catch( ::com::sun::star::uno::Exception& ) |
| { |
| } |
| } |
| |
| |
| UOF2Storage::UOF2Storage( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory, |
| const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStream ) |
| : m_pMainStorage(new ZipStorage(rxFactory, rxInStream)) |
| { |
| } |
| |
| UOF2Storage::UOF2Storage( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory, |
| const ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& rxOutStream ) |
| : m_pMainStorage(new ZipStorage(rxFactory, rxOutStream)) |
| { |
| } |
| |
| UOF2Storage::~UOF2Storage() |
| { |
| } |
| |
| ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > UOF2Storage::getMetaInputStream() const |
| { |
| return m_pMainStorage->openInputStream(METAELEMNAME); |
| } |
| |
| ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > UOF2Storage::getMetaOutputStream( bool /*bMissingCreate*/ ) |
| { |
| return m_pMainStorage->openOutputStream(METAELEMNAME); |
| } |
| |
| bool UOF2Storage::isValidUOF2Doc() const |
| { |
| if(!m_pMainStorage->isStorage()) |
| return false; |
| |
| return ((getMetaInputStream().is()) |
| && (m_pMainStorage->openInputStream(UOFELEMNAME).is()) |
| && (m_pMainStorage->openInputStream(CONTENTELEMNAME).is())); |
| } |
| |
| } |