[Libreoffice-commits] core.git: 3 commits - package/inc package/source writerperfect/source
David Tardon
dtardon at redhat.com
Wed Jan 15 12:29:12 PST 2014
package/inc/ZipPackage.hxx | 14 +
package/source/zippackage/ZipPackage.cxx | 25 ++
writerperfect/source/common/WPXSvStream.cxx | 299 +++++++++++++++++++++++++++-
3 files changed, 326 insertions(+), 12 deletions(-)
New commits:
commit 723863ff26f46e294adde61009b85f6f0e28b5b0
Author: David Tardon <dtardon at redhat.com>
Date: Wed Jan 15 21:15:28 2014 +0100
finish zip support in WPXSvInputStream
Change-Id: I48017873991abdc054e8be93912f2b2f5ae4383f
diff --git a/writerperfect/source/common/WPXSvStream.cxx b/writerperfect/source/common/WPXSvStream.cxx
index 9bc6984..0084ec3 100644
--- a/writerperfect/source/common/WPXSvStream.cxx
+++ b/writerperfect/source/common/WPXSvStream.cxx
@@ -9,7 +9,10 @@
#include "WPXSvStream.hxx"
+#include <com/sun/star/container/XEnumerationAccess.hpp>
#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/io/XActiveDataSink.hpp>
#include <com/sun/star/uno/Any.hxx>
#include <comphelper/processfactory.hxx>
@@ -86,9 +89,9 @@ const rtl::OUString concatPath(const rtl::OUString &lhs, const rtl::OUString &rh
return lhs + "/" + rhs;
}
-struct StreamData
+struct OLEStreamData
{
- explicit StreamData(const rtl::OString &rName);
+ explicit OLEStreamData(const rtl::OString &rName);
SotStorageStreamRefWrapper stream;
@@ -136,12 +139,12 @@ private:
public:
SotStorageRefWrapper mxRootStorage; //< root storage of the OLE2
OLEStorageMap_t maStorageMap; //< map of all sub storages by name
- ::std::vector< StreamData > maStreams; //< list of streams and their names
+ ::std::vector< OLEStreamData > maStreams; //< list of streams and their names
NameMap_t maNameMap; //< map of stream names to indexes (into @c maStreams)
bool mbInitialized;
};
-StreamData::StreamData(const rtl::OString &rName)
+OLEStreamData::OLEStreamData(const rtl::OString &rName)
: stream()
, name(rName)
{
@@ -202,7 +205,7 @@ void OLEStorageImpl::traverse(const SotStorageRef &rStorage, const rtl::OUString
{
if (aIt->IsStream())
{
- maStreams.push_back(StreamData(rtl::OUStringToOString(aIt->GetName(), RTL_TEXTENCODING_UTF8)));
+ maStreams.push_back(OLEStreamData(rtl::OUStringToOString(aIt->GetName(), RTL_TEXTENCODING_UTF8)));
maNameMap[concatPath(rPath, aIt->GetName())] = maStreams.size() - 1;
}
else if (aIt->IsStorage())
@@ -243,6 +246,162 @@ SotStorageStreamRef OLEStorageImpl::createStream(const rtl::OUString &rPath)
}
+namespace
+{
+
+struct ZipStreamData
+{
+ explicit ZipStreamData(const rtl::OString &rName);
+
+ Reference<XInputStream> xStream;
+
+ /** Name of the stream.
+ *
+ * This is not @c rtl::OUString, because we need to be able to
+ * produce const char* from it.
+ */
+ rtl::OString aName;
+};
+
+typedef boost::unordered_map<rtl::OUString, Reference<XInputStream>, rtl::OUStringHash> ZipStorageMap_t;
+
+/** Representation of a Zip storage.
+ *
+ * This is quite similar to OLEStorageImpl, except that we do not need
+ * to keep all storages (folders) open.
+ */
+struct ZipStorageImpl
+{
+ ZipStorageImpl(const Reference<container::XHierarchicalNameAccess> &rxRoot);
+
+ /** Initialize for access.
+ *
+ * This creates a bidirectional map of stream names to their
+ * indexes (index of a stream is determined by deep-first
+ * traversal).
+ */
+ void initialize();
+
+ Reference<XInputStream> getStream(const rtl::OUString &rPath);
+ Reference<XInputStream> getStream(std::size_t nId);
+
+private:
+ void traverse(const Reference<container::XEnumeration> &rxEnum, const rtl::OUString &rPath);
+
+ Reference<XInputStream> createStream(const rtl::OUString &rPath);
+
+public:
+ Reference<container::XHierarchicalNameAccess> mxRoot; //< root of the Zip
+ ::std::vector< ZipStreamData > maStreams; //< list of streams and their names
+ NameMap_t maNameMap; //< map of stream names to indexes (into @c maStreams)
+ bool mbInitialized;
+};
+
+ZipStreamData::ZipStreamData(const rtl::OString &rName)
+ : xStream()
+ , aName(rName)
+{
+}
+
+ZipStorageImpl::ZipStorageImpl(const Reference<container::XHierarchicalNameAccess> &rxRoot)
+ : mxRoot(rxRoot)
+ , maStreams()
+ , maNameMap()
+ , mbInitialized(false)
+{
+ assert(mxRoot.is());
+}
+
+void ZipStorageImpl::initialize()
+{
+ const Reference<container::XEnumerationAccess> xEnum(mxRoot, UNO_QUERY);
+
+ if (xEnum.is())
+ traverse(xEnum->createEnumeration(), "");
+
+ mbInitialized = true;
+}
+
+Reference<XInputStream> ZipStorageImpl::getStream(const rtl::OUString &rPath)
+{
+ NameMap_t::iterator aIt = maNameMap.find(rPath);
+
+ // For the while don't return stream in this situation.
+ // Later, given how libcdr's zip stream implementation behaves,
+ // return the first stream in the storage if there is one.
+ if (maNameMap.end() == aIt)
+ return Reference<XInputStream>();
+
+ if (!maStreams[aIt->second].xStream.is())
+ maStreams[aIt->second].xStream = createStream(rPath);
+
+ return maStreams[aIt->second].xStream;
+}
+
+Reference<XInputStream> ZipStorageImpl::getStream(const std::size_t nId)
+{
+ if (!maStreams[nId].xStream.is())
+ maStreams[nId].xStream = createStream(rtl::OStringToOUString(maStreams[nId].aName, RTL_TEXTENCODING_UTF8));
+
+ return maStreams[nId].xStream;
+}
+
+void ZipStorageImpl::traverse(const Reference<container::XEnumeration> &rxEnum, const rtl::OUString &rPath)
+{
+ while (rxEnum->hasMoreElements())
+ {
+ Any aItem;
+ try
+ {
+ aItem = rxEnum->nextElement();
+ }
+ catch (const Exception &)
+ {
+ continue;
+ }
+
+ const Reference<container::XNamed> xNamed(aItem, UNO_QUERY);
+ const Reference<XActiveDataSink> xSink(aItem, UNO_QUERY);
+ const Reference<container::XEnumerationAccess> xEnum(aItem, UNO_QUERY);
+
+ if (xSink.is() && xNamed.is())
+ {
+ maStreams.push_back(ZipStreamData(rtl::OUStringToOString(xNamed->getName(), RTL_TEXTENCODING_UTF8)));
+ maNameMap[concatPath(rPath, xNamed->getName())] = maStreams.size() - 1;
+ }
+ else if (xEnum.is() && xNamed.is())
+ {
+ const rtl::OUString aPath = concatPath(rPath, xNamed->getName());
+
+ // deep-first traversal
+ traverse(xEnum->createEnumeration(), aPath);
+ }
+ else
+ {
+ assert(0);
+ }
+ }
+}
+
+Reference<XInputStream> ZipStorageImpl::createStream(const rtl::OUString &rPath)
+{
+ Reference<XInputStream> xStream;
+
+ try
+ {
+ const Reference<XActiveDataSink> xSink(mxRoot->getByHierarchicalName(rPath), UNO_QUERY_THROW);
+ xStream.set(xSink->getInputStream(), UNO_QUERY_THROW);
+ }
+ catch (const Exception &)
+ {
+ // nothing needed
+ }
+
+ return xStream;
+}
+
+}
+
class WPXSvInputStreamImpl
{
public :
@@ -269,6 +428,7 @@ private:
void ensureOLEIsInitialized();
bool isZip();
+ void ensureZipIsInitialized();
WPXInputStream *createWPXStream(const SotStorageStreamRef &rxStorage);
@@ -277,10 +437,7 @@ private:
::com::sun::star::uno::Reference< ::com::sun::star::io::XSeekable > mxSeekable;
::com::sun::star::uno::Sequence< sal_Int8 > maData;
boost::scoped_ptr< OLEStorageImpl > mpOLEStorage;
- // TODO: this is not sufficient to implement RVNGInputStream, as
- // packages::Package does not support any kind of enumeration of
- // its content
- ::com::sun::star::uno::Reference< container::XHierarchicalNameAccess > mxZipStorage;
+ boost::scoped_ptr< ZipStorageImpl > mpZipStorage;
bool mbCheckedOLE;
bool mbCheckedZip;
public:
@@ -295,7 +452,7 @@ WPXSvInputStreamImpl::WPXSvInputStreamImpl( Reference< XInputStream > xStream )
mxSeekable(xStream, UNO_QUERY),
maData(0),
mpOLEStorage(0),
- mxZipStorage(),
+ mpZipStorage(0),
mbCheckedOLE(false),
mbCheckedZip(false),
mnLength(0),
@@ -391,7 +548,12 @@ bool WPXSvInputStreamImpl::isStructured()
PositionHolder pos(mxSeekable);
mxSeekable->seek(0);
- return isOLE() || isZip();
+ if (isOLE())
+ return true;
+
+ mxSeekable->seek(0);
+
+ return isZip();
}
unsigned WPXSvInputStreamImpl::subStreamCount()
@@ -409,7 +571,14 @@ unsigned WPXSvInputStreamImpl::subStreamCount()
return mpOLEStorage->maStreams.size();
}
- // TODO: zip impl.
+ mxSeekable->seek(0);
+
+ if (isZip())
+ {
+ ensureZipIsInitialized();
+
+ return mpZipStorage->maStreams.size();
+ }
return 0;
}
@@ -432,7 +601,17 @@ const char *WPXSvInputStreamImpl::subStreamName(const unsigned id)
return mpOLEStorage->maStreams[id].name.getStr();
}
- // TODO: zip impl.
+ mxSeekable->seek(0);
+
+ if (isZip())
+ {
+ ensureZipIsInitialized();
+
+ if (mpZipStorage->maStreams.size() <= id)
+ return 0;
+
+ return mpZipStorage->maStreams[id].aName.getStr();
+ }
return 0;
}
@@ -456,8 +635,13 @@ bool WPXSvInputStreamImpl::existsSubStream(const char *const name)
return mpOLEStorage->maNameMap.end() != mpOLEStorage->maNameMap.find(aName);
}
+ mxSeekable->seek(0);
+
if (isZip())
- return mxZipStorage->hasByHierarchicalName(aName);
+ {
+ ensureZipIsInitialized();
+ return mpZipStorage->maNameMap.end() != mpZipStorage->maNameMap.find(aName);
+ }
return false;
}
@@ -481,12 +665,15 @@ WPXInputStream *WPXSvInputStreamImpl::getSubStreamByName(const char *const name)
return createWPXStream(mpOLEStorage->getStream(aName));
}
+ mxSeekable->seek(0);
+
if (isZip())
{
+ ensureZipIsInitialized();
+
try
{
- const Reference<XStream> xStream(mxZipStorage->getByHierarchicalName(aName), UNO_QUERY_THROW);
- return new WPXSvInputStream(xStream->getInputStream());
+ return new WPXSvInputStream(mpZipStorage->getStream(aName));
}
catch (const Exception &)
{
@@ -515,8 +702,24 @@ WPXInputStream *WPXSvInputStreamImpl::getSubStreamById(const unsigned id)
return createWPXStream(mpOLEStorage->getStream(id));
}
- // TODO: zip impl.
+ mxSeekable->seek(0);
+
+ if (isZip())
+ {
+ ensureZipIsInitialized();
+
+ if (mpZipStorage->maStreams.size() <= id)
+ return 0;
+ try
+ {
+ return new WPXSvInputStream(mpZipStorage->getStream(id));
+ }
+ catch (const Exception &)
+ {
+ // nothing needed
+ }
+ }
return 0;
}
@@ -568,9 +771,10 @@ bool WPXSvInputStreamImpl::isZip()
aArgs[0] <<= mxStream;
const Reference<XComponentContext> xContext(comphelper::getProcessComponentContext(), UNO_QUERY_THROW);
- mxZipStorage.set(
+ const Reference<container::XHierarchicalNameAccess> xZipStorage(
xContext->getServiceManager()->createInstanceWithArgumentsAndContext("com.sun.star.packages.Package", aArgs, xContext),
UNO_QUERY_THROW);
+ mpZipStorage.reset(new ZipStorageImpl(xZipStorage));
}
catch (const Exception &)
{
@@ -580,7 +784,7 @@ bool WPXSvInputStreamImpl::isZip()
mbCheckedZip = true;
}
- return mxZipStorage.is();
+ return bool(mpZipStorage);
}
void WPXSvInputStreamImpl::ensureOLEIsInitialized()
@@ -591,6 +795,14 @@ void WPXSvInputStreamImpl::ensureOLEIsInitialized()
mpOLEStorage->initialize(utl::UcbStreamHelper::CreateStream( mxStream ));
}
+void WPXSvInputStreamImpl::ensureZipIsInitialized()
+{
+ assert(mpZipStorage);
+
+ if (!mpZipStorage->mbInitialized)
+ mpZipStorage->initialize();
+}
+
WPXSvInputStream::WPXSvInputStream( Reference< XInputStream > xStream ) :
mpImpl(new WPXSvInputStreamImpl(xStream))
{
commit 5b2cca80eeb2c8ee210820cc8ed95e5d69214807
Author: David Tardon <dtardon at redhat.com>
Date: Wed Jan 15 15:14:04 2014 +0100
impl. enumeration for ZipPackage
Change-Id: I800d22d8ec99e943b59467cf64b96aaa1f797953
diff --git a/package/inc/ZipPackage.hxx b/package/inc/ZipPackage.hxx
index 3631799..9ee401b 100644
--- a/package/inc/ZipPackage.hxx
+++ b/package/inc/ZipPackage.hxx
@@ -19,8 +19,9 @@
#ifndef _ZIP_PACKAGE_HXX
#define _ZIP_PACKAGE_HXX
-#include <cppuhelper/implbase7.hxx>
+#include <cppuhelper/implbase8.hxx>
#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
#include <com/sun/star/lang/XSingleServiceFactory.hpp>
#include <com/sun/star/util/XChangesBatch.hpp>
@@ -63,12 +64,13 @@ enum InitialisationMode
e_IMode_XStream
};
-class ZipPackage : public cppu::WeakImplHelper7
+class ZipPackage : public cppu::WeakImplHelper8
<
com::sun::star::lang::XInitialization,
com::sun::star::lang::XSingleServiceFactory,
com::sun::star::lang::XUnoTunnel,
com::sun::star::lang::XServiceInfo,
+ com::sun::star::container::XEnumerationAccess,
com::sun::star::container::XHierarchicalNameAccess,
com::sun::star::util::XChangesBatch,
com::sun::star::beans::XPropertySet
@@ -141,6 +143,14 @@ public:
// XInitialization
virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments )
throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+ // XEnumerationAccess
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumeration > SAL_CALL createEnumeration()
+ throw(::com::sun::star::uno::RuntimeException);
+ // XElementType
+ virtual ::com::sun::star::uno::Type getElementType()
+ throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool hasElements()
+ throw(::com::sun::star::uno::RuntimeException);
// XHierarchicalNameAccess
virtual ::com::sun::star::uno::Any SAL_CALL getByHierarchicalName( const OUString& aName )
throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException);
diff --git a/package/source/zippackage/ZipPackage.cxx b/package/source/zippackage/ZipPackage.cxx
index f20b1f0..77b7862 100644
--- a/package/source/zippackage/ZipPackage.cxx
+++ b/package/source/zippackage/ZipPackage.cxx
@@ -66,6 +66,7 @@
#include <osl/time.h>
#include "com/sun/star/io/XAsyncOutputMonitor.hpp"
+#include <cassert>
#include <cstring>
#include <memory>
#include <vector>
@@ -777,6 +778,30 @@ void SAL_CALL ZipPackage::initialize( const uno::Sequence< Any >& aArguments )
}
}
+::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumeration > SAL_CALL ZipPackage::createEnumeration()
+ throw( RuntimeException )
+{
+ assert(m_pRootFolder);
+
+ return m_pRootFolder->createEnumeration();
+}
+
+::com::sun::star::uno::Type ZipPackage::getElementType()
+ throw( RuntimeException )
+{
+ assert(m_pRootFolder);
+
+ return m_pRootFolder->getElementType();
+}
+
+sal_Bool ZipPackage::hasElements()
+ throw( RuntimeException )
+{
+ assert(m_pRootFolder);
+
+ return m_pRootFolder->hasElements();
+}
+
Any SAL_CALL ZipPackage::getByHierarchicalName( const OUString& aName )
throw( NoSuchElementException, RuntimeException )
{
commit e9a036aca1062fd5512b8dbd93ef7172831b3bc4
Author: David Tardon <dtardon at redhat.com>
Date: Wed Jan 15 14:33:58 2014 +0100
add BIPU support for zip to WPXSvInputStream
Change-Id: I14d6febcff49421b6ee3f2c463e78ff98660aab5
diff --git a/writerperfect/source/common/WPXSvStream.cxx b/writerperfect/source/common/WPXSvStream.cxx
index d705ba5..9bc6984 100644
--- a/writerperfect/source/common/WPXSvStream.cxx
+++ b/writerperfect/source/common/WPXSvStream.cxx
@@ -9,6 +9,11 @@
#include "WPXSvStream.hxx"
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/uno/Any.hxx>
+
+#include <comphelper/processfactory.hxx>
+
#include <rtl/string.hxx>
#include <tools/stream.hxx>
#include <unotools/streamwrap.hxx>
@@ -23,6 +28,10 @@
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::io;
+namespace container = com::sun::star::container;
+namespace lang = com::sun::star::lang;
+namespace packages = com::sun::star::packages;
+
namespace
{
@@ -259,6 +268,8 @@ private:
bool isOLE();
void ensureOLEIsInitialized();
+ bool isZip();
+
WPXInputStream *createWPXStream(const SotStorageStreamRef &rxStorage);
private:
@@ -266,7 +277,12 @@ private:
::com::sun::star::uno::Reference< ::com::sun::star::io::XSeekable > mxSeekable;
::com::sun::star::uno::Sequence< sal_Int8 > maData;
boost::scoped_ptr< OLEStorageImpl > mpOLEStorage;
+ // TODO: this is not sufficient to implement RVNGInputStream, as
+ // packages::Package does not support any kind of enumeration of
+ // its content
+ ::com::sun::star::uno::Reference< container::XHierarchicalNameAccess > mxZipStorage;
bool mbCheckedOLE;
+ bool mbCheckedZip;
public:
sal_Int64 mnLength;
unsigned char *mpReadBuffer;
@@ -279,7 +295,9 @@ WPXSvInputStreamImpl::WPXSvInputStreamImpl( Reference< XInputStream > xStream )
mxSeekable(xStream, UNO_QUERY),
maData(0),
mpOLEStorage(0),
+ mxZipStorage(),
mbCheckedOLE(false),
+ mbCheckedZip(false),
mnLength(0),
mpReadBuffer(0),
mnReadBufferLength(0),
@@ -373,7 +391,7 @@ bool WPXSvInputStreamImpl::isStructured()
PositionHolder pos(mxSeekable);
mxSeekable->seek(0);
- return isOLE();
+ return isOLE() || isZip();
}
unsigned WPXSvInputStreamImpl::subStreamCount()
@@ -391,6 +409,8 @@ unsigned WPXSvInputStreamImpl::subStreamCount()
return mpOLEStorage->maStreams.size();
}
+ // TODO: zip impl.
+
return 0;
}
@@ -412,6 +432,8 @@ const char *WPXSvInputStreamImpl::subStreamName(const unsigned id)
return mpOLEStorage->maStreams[id].name.getStr();
}
+ // TODO: zip impl.
+
return 0;
}
@@ -426,14 +448,17 @@ bool WPXSvInputStreamImpl::existsSubStream(const char *const name)
PositionHolder pos(mxSeekable);
mxSeekable->seek(0);
+ const rtl::OUString aName(rtl::OStringToOUString(rtl::OString(name), RTL_TEXTENCODING_UTF8));
+
if (isOLE())
{
ensureOLEIsInitialized();
-
- const rtl::OUString aName(rtl::OStringToOUString(rtl::OString(name), RTL_TEXTENCODING_UTF8));
return mpOLEStorage->maNameMap.end() != mpOLEStorage->maNameMap.find(aName);
}
+ if (isZip())
+ return mxZipStorage->hasByHierarchicalName(aName);
+
return false;
}
@@ -448,14 +473,27 @@ WPXInputStream *WPXSvInputStreamImpl::getSubStreamByName(const char *const name)
PositionHolder pos(mxSeekable);
mxSeekable->seek(0);
+ const rtl::OUString aName(rtl::OStringToOUString(rtl::OString(name), RTL_TEXTENCODING_UTF8));
+
if (isOLE())
{
ensureOLEIsInitialized();
-
- const rtl::OUString aName(rtl::OStringToOUString(rtl::OString(name), RTL_TEXTENCODING_UTF8));
return createWPXStream(mpOLEStorage->getStream(aName));
}
+ if (isZip())
+ {
+ try
+ {
+ const Reference<XStream> xStream(mxZipStorage->getByHierarchicalName(aName), UNO_QUERY_THROW);
+ return new WPXSvInputStream(xStream->getInputStream());
+ }
+ catch (const Exception &)
+ {
+ // nothing needed
+ }
+ }
+
return 0;
}
@@ -477,6 +515,8 @@ WPXInputStream *WPXSvInputStreamImpl::getSubStreamById(const unsigned id)
return createWPXStream(mpOLEStorage->getStream(id));
}
+ // TODO: zip impl.
+
return 0;
}
@@ -516,6 +556,33 @@ bool WPXSvInputStreamImpl::isOLE()
return bool(mpOLEStorage);
}
+bool WPXSvInputStreamImpl::isZip()
+{
+ if (!mbCheckedZip)
+ {
+ assert(0 == mxSeekable->getPosition());
+
+ try
+ {
+ Sequence<Any> aArgs(1);
+ aArgs[0] <<= mxStream;
+
+ const Reference<XComponentContext> xContext(comphelper::getProcessComponentContext(), UNO_QUERY_THROW);
+ mxZipStorage.set(
+ xContext->getServiceManager()->createInstanceWithArgumentsAndContext("com.sun.star.packages.Package", aArgs, xContext),
+ UNO_QUERY_THROW);
+ }
+ catch (const Exception &)
+ {
+ // ignore
+ }
+
+ mbCheckedZip = true;
+ }
+
+ return mxZipStorage.is();
+}
+
void WPXSvInputStreamImpl::ensureOLEIsInitialized()
{
assert(mpOLEStorage);
More information about the Libreoffice-commits
mailing list