diff options
author | Dennis Francis <dennisfrancis.in@gmail.com> | 2015-04-15 22:22:16 +0530 |
---|---|---|
committer | Kohei Yoshida <libreoffice@kohei.us> | 2015-04-27 00:33:57 +0000 |
commit | f0edb677f09ad338e22ac3b5d91497b4479e0b3c (patch) | |
tree | bbd2b4a48538b3b019108460309be52724005022 | |
parent | 89aee8b17f8dd4eb2213a7844a9ef26951e39775 (diff) |
enhancement : tdf#90225 Cannot open compressed csv files from calc
Change-Id: I5098fd25f1747b49e47e360f017ee1112a242771
Reviewed-on: https://gerrit.libreoffice.org/15108
Reviewed-by: Kohei Yoshida <libreoffice@kohei.us>
Tested-by: Kohei Yoshida <libreoffice@kohei.us>
-rw-r--r-- | filter/source/textfilterdetect/filterdetect.cxx | 28 | ||||
-rw-r--r-- | include/tools/zcodec.hxx | 1 | ||||
-rw-r--r-- | tools/source/zcodec/zcodec.cxx | 26 |
3 files changed, 54 insertions, 1 deletions
diff --git a/filter/source/textfilterdetect/filterdetect.cxx b/filter/source/textfilterdetect/filterdetect.cxx index aff31263c6c0..3ce15394a502 100644 --- a/filter/source/textfilterdetect/filterdetect.cxx +++ b/filter/source/textfilterdetect/filterdetect.cxx @@ -11,8 +11,10 @@ #include <svtools/htmltokn.h> #include <tools/urlobj.hxx> +#include <tools/zcodec.hxx> #include <ucbhelper/content.hxx> #include <unotools/mediadescriptor.hxx> +#include <unotools/streamwrap.hxx> #include <unotools/ucbstreamhelper.hxx> #include <com/sun/star/lang/XMultiServiceFactory.hpp> @@ -142,10 +144,34 @@ OUString SAL_CALL PlainTextFilterDetect::detect(uno::Sequence<beans::PropertyVal else if (aType == "generic_Text") { + uno::Reference<io::XStream> xStream(aMediaDesc[MediaDescriptor::PROP_STREAM()], uno::UNO_QUERY); + uno::Reference<io::XInputStream> xInStream(aMediaDesc[MediaDescriptor::PROP_INPUTSTREAM()], uno::UNO_QUERY); + if (xStream.is() || xInStream.is()) + { + ZCodec aCodecGZ; + std::unique_ptr<SvStream> pInStream; + if (xStream.is()) + pInStream.reset(utl::UcbStreamHelper::CreateStream(xStream)); + else + pInStream.reset(utl::UcbStreamHelper::CreateStream(xInStream)); + std::unique_ptr<SvMemoryStream> pDecompressedStream(new SvMemoryStream()); + if (aCodecGZ.AttemptDecompression(*pInStream, *pDecompressedStream, false, true)) + { + uno::Reference<io::XStream> xStreamDecompressed(new utl::OStreamWrapper(*pDecompressedStream)); + pDecompressedStream.release(); + aMediaDesc[MediaDescriptor::PROP_STREAM()] <<= xStreamDecompressed; + aMediaDesc[MediaDescriptor::PROP_INPUTSTREAM()] <<= xStreamDecompressed->getInputStream(); + OUString aURL = aMediaDesc.getUnpackedValueOrDefault(MediaDescriptor::PROP_URL(), OUString() ); + sal_Int32 nIdx = aURL.lastIndexOf(".gz"); + if (nIdx != -1) + aMediaDesc[MediaDescriptor::PROP_URL()] <<= aURL.copy(0, nIdx); + } + } // Get the file name extension. INetURLObject aParser(aMediaDesc.getUnpackedValueOrDefault(MediaDescriptor::PROP_URL(), OUString() ) ); OUString aExt = aParser.getExtension(INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET); aExt = aExt.toAsciiLowerCase(); + OUString aName = aParser.getName().toAsciiLowerCase(); // Decide which filter to use based on the document service first, // then on extension if that's not available. @@ -153,7 +179,7 @@ OUString SAL_CALL PlainTextFilterDetect::detect(uno::Sequence<beans::PropertyVal aMediaDesc[MediaDescriptor::PROP_FILTERNAME()] <<= OUString(CALC_TEXT_FILTER); else if (aDocService == WRITER_DOCSERVICE) aMediaDesc[MediaDescriptor::PROP_FILTERNAME()] <<= OUString(WRITER_TEXT_FILTER); - else if (aExt == "csv" || aExt == "tsv" || aExt == "tab" || aExt == "xls") + else if (aExt == "csv" || aExt == "tsv" || aExt == "tab" || aExt == "xls" || aName.endsWith(".csv.gz")) aMediaDesc[MediaDescriptor::PROP_FILTERNAME()] <<= OUString(CALC_TEXT_FILTER); else aMediaDesc[MediaDescriptor::PROP_FILTERNAME()] <<= OUString(WRITER_TEXT_FILTER); diff --git a/include/tools/zcodec.hxx b/include/tools/zcodec.hxx index 8d393265f82f..ac389ae12f2b 100644 --- a/include/tools/zcodec.hxx +++ b/include/tools/zcodec.hxx @@ -67,6 +67,7 @@ public: long Compress( SvStream& rIStm, SvStream& rOStm ); long Decompress( SvStream& rIStm, SvStream& rOStm ); + bool AttemptDecompression( SvStream& rIStm, SvStream& rOStm, bool updateCrc = false, bool gzLib = false ); long Write( SvStream& rOStm, const sal_uInt8* pData, sal_uIntPtr nSize ); long Read( SvStream& rIStm, sal_uInt8* pData, sal_uIntPtr nSize ); diff --git a/tools/source/zcodec/zcodec.cxx b/tools/source/zcodec/zcodec.cxx index d6bce145a188..b5c645ac92e2 100644 --- a/tools/source/zcodec/zcodec.cxx +++ b/tools/source/zcodec/zcodec.cxx @@ -394,4 +394,30 @@ void ZCodec::UpdateCRC ( sal_uInt8* pSource, long nDatSize) mnCRC = rtl_crc32( mnCRC, pSource, nDatSize ); } +bool ZCodec::AttemptDecompression(SvStream& rIStm, SvStream& rOStm, bool updateCrc, bool gzLib) +{ + assert(meState == STATE_INIT); + sal_uLong nStreamPos = rIStm.Tell(); + BeginCompression(ZCODEC_DEFAULT_COMPRESSION, updateCrc, gzLib); + InitDecompress(rIStm); + EndCompression(); + if ( !mbStatus || rIStm.GetError() ) + { + rIStm.Seek(nStreamPos); + return false; + } + rIStm.Seek(nStreamPos); + BeginCompression(ZCODEC_DEFAULT_COMPRESSION, updateCrc, gzLib); + Decompress(rIStm, rOStm); + EndCompression(); + if( !mbStatus || rIStm.GetError() || rOStm.GetError() ) + { + rIStm.Seek(nStreamPos); + return false; + } + rIStm.Seek(nStreamPos); + rOStm.Seek(0); + return true; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |