summaryrefslogtreecommitdiff
path: root/package/source
diff options
context:
space:
mode:
Diffstat (limited to 'package/source')
-rw-r--r--package/source/xstor/ocompinstream.cxx17
-rw-r--r--package/source/xstor/ocompinstream.hxx7
-rw-r--r--package/source/xstor/selfterminatefilestream.cxx5
-rw-r--r--package/source/xstor/selfterminatefilestream.hxx6
-rw-r--r--package/source/xstor/switchpersistencestream.cxx16
-rw-r--r--package/source/xstor/switchpersistencestream.hxx6
-rw-r--r--package/source/zipapi/ByteGrabber.cxx49
-rw-r--r--package/source/zipapi/CRC32.cxx4
-rw-r--r--package/source/zipapi/Inflater.cxx108
-rw-r--r--package/source/zipapi/MemoryByteGrabber.hxx6
-rw-r--r--package/source/zipapi/XBufferedThreadedStream.cxx26
-rw-r--r--package/source/zipapi/XBufferedThreadedStream.hxx7
-rw-r--r--package/source/zipapi/ZipFile.cxx145
-rw-r--r--package/source/zippackage/ZipPackage.cxx1
-rw-r--r--package/source/zippackage/wrapstreamforshare.cxx16
-rw-r--r--package/source/zippackage/wrapstreamforshare.hxx7
16 files changed, 342 insertions, 84 deletions
diff --git a/package/source/xstor/ocompinstream.cxx b/package/source/xstor/ocompinstream.cxx
index 8a23169f6814..b71b8ef99697 100644
--- a/package/source/xstor/ocompinstream.cxx
+++ b/package/source/xstor/ocompinstream.cxx
@@ -38,6 +38,7 @@ OInputCompStream::OInputCompStream( OWriteStream_Impl& aImpl,
: m_pImpl( &aImpl )
, m_xMutex( m_pImpl->m_xMutex )
, m_xStream(std::move( xStream ))
+, m_pByteReader( dynamic_cast<comphelper::ByteReader*>(m_xStream.get()) )
, m_aProperties( aProps )
, m_bDisposed( false )
, m_nStorageType( nStorageType )
@@ -47,6 +48,7 @@ OInputCompStream::OInputCompStream( OWriteStream_Impl& aImpl,
throw uno::RuntimeException(); // just a disaster
assert(m_xStream.is());
+ assert(m_pByteReader);
}
OInputCompStream::OInputCompStream( uno::Reference < io::XInputStream > xStream,
@@ -55,11 +57,13 @@ OInputCompStream::OInputCompStream( uno::Reference < io::XInputStream > xStream,
: m_pImpl( nullptr )
, m_xMutex( new comphelper::RefCountedMutex )
, m_xStream(std::move( xStream ))
+, m_pByteReader( dynamic_cast<comphelper::ByteReader*>(m_xStream.get()) )
, m_aProperties( aProps )
, m_bDisposed( false )
, m_nStorageType( nStorageType )
{
assert(m_xStream.is());
+ assert(m_pByteReader);
}
OInputCompStream::~OInputCompStream()
@@ -125,6 +129,19 @@ sal_Int32 SAL_CALL OInputCompStream::readSomeBytes( uno::Sequence< sal_Int8 >& a
}
+sal_Int32 OInputCompStream::readSomeBytes( sal_Int8* aData, sal_Int32 nMaxBytesToRead )
+{
+ ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
+ if ( m_bDisposed )
+ {
+ SAL_INFO("package.xstor", "Disposed!");
+ throw lang::DisposedException();
+ }
+
+ return m_pByteReader->readSomeBytes( aData, nMaxBytesToRead );
+
+}
+
void SAL_CALL OInputCompStream::skipBytes( sal_Int32 nBytesToSkip )
{
::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
diff --git a/package/source/xstor/ocompinstream.hxx b/package/source/xstor/ocompinstream.hxx
index effbc4be2fb8..54fc7dc19308 100644
--- a/package/source/xstor/ocompinstream.hxx
+++ b/package/source/xstor/ocompinstream.hxx
@@ -28,6 +28,7 @@
#include <cppuhelper/implbase.hxx>
#include <comphelper/interfacecontainer3.hxx>
#include <comphelper/refcountedmutex.hxx>
+#include <comphelper/bytereader.hxx>
#include <rtl/ref.hxx>
#include <memory>
@@ -37,12 +38,14 @@ struct OWriteStream_Impl;
class OInputCompStream : public cppu::WeakImplHelper < css::io::XInputStream
,css::embed::XExtendedStorageStream
,css::embed::XRelationshipAccess
- ,css::beans::XPropertySet >
+ ,css::beans::XPropertySet >,
+ public comphelper::ByteReader
{
protected:
OWriteStream_Impl* m_pImpl;
rtl::Reference<comphelper::RefCountedMutex> m_xMutex;
css::uno::Reference < css::io::XInputStream > m_xStream;
+ comphelper::ByteReader* m_pByteReader;
std::unique_ptr<::comphelper::OInterfaceContainerHelper3<css::lang::XEventListener>> m_pInterfaceContainer;
css::uno::Sequence < css::beans::PropertyValue > m_aProperties;
bool m_bDisposed;
@@ -102,6 +105,8 @@ public:
virtual void SAL_CALL addVetoableChangeListener( const OUString& PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override;
virtual void SAL_CALL removeVetoableChangeListener( const OUString& PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override;
+ // comphelper::ByteReader
+ virtual sal_Int32 readSomeBytes(sal_Int8* aData, sal_Int32 nBytesToRead) override;
};
#endif
diff --git a/package/source/xstor/selfterminatefilestream.cxx b/package/source/xstor/selfterminatefilestream.cxx
index f3fe79439781..80d21dd3bee5 100644
--- a/package/source/xstor/selfterminatefilestream.cxx
+++ b/package/source/xstor/selfterminatefilestream.cxx
@@ -62,6 +62,11 @@ sal_Int32 SAL_CALL OSelfTerminateFileStream::readSomeBytes( uno::Sequence< sal_I
return m_xStreamWrapper->readSomeBytes( aData, nMaxBytesToRead );
}
+sal_Int32 OSelfTerminateFileStream::readSomeBytes( sal_Int8* aData, sal_Int32 nMaxBytesToRead )
+{
+ return m_xStreamWrapper->readSomeBytes( aData, nMaxBytesToRead );
+}
+
void SAL_CALL OSelfTerminateFileStream::skipBytes( sal_Int32 nBytesToSkip )
{
return m_xStreamWrapper->skipBytes( nBytesToSkip );
diff --git a/package/source/xstor/selfterminatefilestream.hxx b/package/source/xstor/selfterminatefilestream.hxx
index f8cedcb64c46..4520552956c5 100644
--- a/package/source/xstor/selfterminatefilestream.hxx
+++ b/package/source/xstor/selfterminatefilestream.hxx
@@ -24,6 +24,7 @@
#include <com/sun/star/io/XSeekable.hpp>
#include <com/sun/star/ucb/XSimpleFileAccess3.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>
+#include <comphelper/bytereader.hxx>
#include <cppuhelper/implbase.hxx>
#include <unotools/streamwrap.hxx>
#include <unotools/tempfile.hxx>
@@ -33,7 +34,8 @@
struct OWriteStream_Impl;
class OSelfTerminateFileStream final : public cppu::WeakImplHelper< css::io::XInputStream,
- css::io::XSeekable >
+ css::io::XSeekable >,
+ public comphelper::ByteReader
{
std::optional<utl::TempFileFast> m_oTempFile;
rtl::Reference< utl::OSeekableInputStreamWrapper > m_xStreamWrapper;
@@ -57,6 +59,8 @@ public:
virtual sal_Int64 SAL_CALL getPosition() override;
virtual sal_Int64 SAL_CALL getLength() override;
+ // comphelper::ByteReader
+ virtual sal_Int32 readSomeBytes(sal_Int8* aData, sal_Int32 nBytesToRead) override;
};
#endif
diff --git a/package/source/xstor/switchpersistencestream.cxx b/package/source/xstor/switchpersistencestream.cxx
index ef07966f09d0..6613b8b046b1 100644
--- a/package/source/xstor/switchpersistencestream.cxx
+++ b/package/source/xstor/switchpersistencestream.cxx
@@ -39,6 +39,7 @@ struct SPStreamData_Impl
uno::Reference< io::XSeekable > m_xOrigSeekable;
uno::Reference< io::XInputStream > m_xOrigInStream;
uno::Reference< io::XOutputStream > m_xOrigOutStream;
+ comphelper::ByteReader* m_pByteReader;
bool m_bInOpen;
bool m_bOutOpen;
@@ -56,6 +57,7 @@ struct SPStreamData_Impl
, m_xOrigSeekable(std::move( xOrigSeekable ))
, m_xOrigInStream(std::move( xOrigInStream ))
, m_xOrigOutStream(std::move( xOrigOutStream ))
+ , m_pByteReader(dynamic_cast<comphelper::ByteReader*>(m_xOrigInStream.get()))
, m_bInOpen( bInOpen )
, m_bOutOpen( bOutOpen )
{
@@ -243,6 +245,20 @@ uno::Reference< io::XOutputStream > SAL_CALL SwitchablePersistenceStream::getOut
return m_pStreamData->m_xOrigInStream->readBytes( aData, nMaxBytesToRead );
}
+::sal_Int32 SwitchablePersistenceStream::readSomeBytes( sal_Int8* aData, sal_Int32 nBytesToRead)
+{
+ std::scoped_lock aGuard( m_aMutex );
+
+ if ( !m_pStreamData )
+ throw io::NotConnectedException();
+
+ // the original stream data should be provided
+ if ( !m_pStreamData->m_xOrigInStream.is() )
+ throw uno::RuntimeException();
+
+ return m_pStreamData->m_pByteReader->readSomeBytes( aData, nBytesToRead );
+}
+
void SAL_CALL SwitchablePersistenceStream::skipBytes( ::sal_Int32 nBytesToSkip )
{
std::scoped_lock aGuard( m_aMutex );
diff --git a/package/source/xstor/switchpersistencestream.hxx b/package/source/xstor/switchpersistencestream.hxx
index 64d4e37fd025..657ed3e98949 100644
--- a/package/source/xstor/switchpersistencestream.hxx
+++ b/package/source/xstor/switchpersistencestream.hxx
@@ -29,6 +29,7 @@
#include <com/sun/star/io/XStream.hpp>
#include <com/sun/star/io/XAsyncOutputMonitor.hpp>
#include <mutex>
+#include <comphelper/bytereader.hxx>
#include <cppuhelper/implbase.hxx>
// SwitchablePersistenceStream
@@ -45,7 +46,8 @@ class SwitchablePersistenceStream
css::io::XOutputStream,
css::io::XTruncate,
css::io::XSeekable,
- css::io::XAsyncOutputMonitor >
+ css::io::XAsyncOutputMonitor >,
+ public comphelper::ByteReader
{
std::mutex m_aMutex;
@@ -96,6 +98,8 @@ public:
// css::io::XAsyncOutputMonitor
virtual void SAL_CALL waitForCompletion( ) override;
+ // comphelper::ByteReader
+ virtual sal_Int32 readSomeBytes(sal_Int8* aData, sal_Int32 nBytesToRead) override;
};
#endif // INCLUDED_PACKAGE_SOURCE_XSTOR_SWITCHPERSISTENCESTREAM_HXX
diff --git a/package/source/zipapi/ByteGrabber.cxx b/package/source/zipapi/ByteGrabber.cxx
index 50083b4dafc2..cd9e201dba0b 100644
--- a/package/source/zipapi/ByteGrabber.cxx
+++ b/package/source/zipapi/ByteGrabber.cxx
@@ -39,9 +39,9 @@ using namespace ::com::sun::star;
ByteGrabber::ByteGrabber(uno::Reference < io::XInputStream > const & xIstream)
: xStream(xIstream)
, xSeek (xIstream, uno::UNO_QUERY )
-, aSequence ( 4 )
{
- pSequence = aSequence.getArray();
+ mpByteReader = dynamic_cast<comphelper::ByteReader*>(xStream.get());
+ assert(mpByteReader);
}
ByteGrabber::~ByteGrabber()
@@ -52,6 +52,8 @@ void ByteGrabber::setInputStream (const uno::Reference < io::XInputStream >& xNe
{
xStream = xNewStream;
xSeek.set(xNewStream, uno::UNO_QUERY);
+ mpByteReader = dynamic_cast<comphelper::ByteReader*>(xStream.get());
+ assert(mpByteReader);
}
// XInputStream chained
@@ -61,6 +63,12 @@ sal_Int32 ByteGrabber::readBytes( uno::Sequence< sal_Int8 >& aData,
return xStream->readBytes(aData, nBytesToRead );
}
+sal_Int32 ByteGrabber::readBytes( sal_Int8* aData,
+ sal_Int32 nBytesToRead )
+{
+ return mpByteReader->readSomeBytes(aData, nBytesToRead );
+}
+
// XSeekable chained...
void ByteGrabber::seek( sal_Int64 location )
{
@@ -88,42 +96,39 @@ sal_Int64 ByteGrabber::getLength( )
sal_uInt16 ByteGrabber::ReadUInt16()
{
- if (xStream->readBytes(aSequence, 2) != 2)
+ if (mpByteReader->readSomeBytes(maBuffer.data(), 2) != 2)
return 0;
- pSequence = aSequence.getConstArray();
return static_cast <sal_uInt16>
- ( (pSequence[0] & 0xFF)
- | (pSequence[1] & 0xFF) << 8);
+ ( (maBuffer[0] & 0xFF)
+ | (maBuffer[1] & 0xFF) << 8);
}
sal_uInt32 ByteGrabber::ReadUInt32()
{
- if (xStream->readBytes(aSequence, 4) != 4)
+ if (mpByteReader->readSomeBytes(maBuffer.data(), 4) != 4)
return 0;
- pSequence = aSequence.getConstArray();
return static_cast < sal_uInt32 >
- ( (pSequence[0] & 0xFF)
- | ( pSequence[1] & 0xFF ) << 8
- | ( pSequence[2] & 0xFF ) << 16
- | ( pSequence[3] & 0xFF ) << 24 );
+ ( (maBuffer[0] & 0xFF)
+ | ( maBuffer[1] & 0xFF ) << 8
+ | ( maBuffer[2] & 0xFF ) << 16
+ | ( maBuffer[3] & 0xFF ) << 24 );
}
sal_uInt64 ByteGrabber::ReadUInt64()
{
- if (xStream->readBytes(aSequence, 8) != 8)
+ if (mpByteReader->readSomeBytes(maBuffer.data(), 8) != 8)
return 0;
- pSequence = aSequence.getConstArray();
- return static_cast<sal_uInt64>(pSequence[0] & 0xFF)
- | static_cast<sal_uInt64>(pSequence[1] & 0xFF) << 8
- | static_cast<sal_uInt64>(pSequence[2] & 0xFF) << 16
- | static_cast<sal_uInt64>(pSequence[3] & 0xFF) << 24
- | static_cast<sal_uInt64>(pSequence[4] & 0xFF) << 32
- | static_cast<sal_uInt64>(pSequence[5] & 0xFF) << 40
- | static_cast<sal_uInt64>(pSequence[6] & 0xFF) << 48
- | static_cast<sal_uInt64>(pSequence[7] & 0xFF) << 56;
+ return static_cast<sal_uInt64>(maBuffer[0] & 0xFF)
+ | static_cast<sal_uInt64>(maBuffer[1] & 0xFF) << 8
+ | static_cast<sal_uInt64>(maBuffer[2] & 0xFF) << 16
+ | static_cast<sal_uInt64>(maBuffer[3] & 0xFF) << 24
+ | static_cast<sal_uInt64>(maBuffer[4] & 0xFF) << 32
+ | static_cast<sal_uInt64>(maBuffer[5] & 0xFF) << 40
+ | static_cast<sal_uInt64>(maBuffer[6] & 0xFF) << 48
+ | static_cast<sal_uInt64>(maBuffer[7] & 0xFF) << 56;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/package/source/zipapi/CRC32.cxx b/package/source/zipapi/CRC32.cxx
index bd06822486b3..b6415efbf2f8 100644
--- a/package/source/zipapi/CRC32.cxx
+++ b/package/source/zipapi/CRC32.cxx
@@ -46,6 +46,10 @@ void CRC32::updateSegment(const Sequence< sal_Int8 > &b, sal_Int32 len)
{
nCRC = rtl_crc32(nCRC, b.getConstArray(), len );
}
+void CRC32::updateSegment(const sal_Int8* b, sal_Int32 len)
+{
+ nCRC = rtl_crc32(nCRC, b, len );
+}
/** Update CRC32 with specified sequence of bytes
*/
void CRC32::update(const Sequence< sal_Int8 > &b)
diff --git a/package/source/zipapi/Inflater.cxx b/package/source/zipapi/Inflater.cxx
index d03fed8c0968..7867259aa764 100644
--- a/package/source/zipapi/Inflater.cxx
+++ b/package/source/zipapi/Inflater.cxx
@@ -134,4 +134,112 @@ sal_Int32 Inflater::doInflateBytes (Sequence < sal_Int8 > &rBuffer, sal_Int32 n
return 0;
}
+InflaterBytes::InflaterBytes(bool bNoWrap)
+: bFinished(false),
+ bNeedDict(false),
+ nOffset(0),
+ nLength(0),
+ nLastInflateError(0)
+{
+ pStream.reset(new z_stream);
+ /* memset to 0 to set zalloc/opaque etc */
+ memset (pStream.get(), 0, sizeof(*pStream));
+ sal_Int32 nRes;
+ nRes = inflateInit2(pStream.get(), bNoWrap ? -MAX_WBITS : MAX_WBITS);
+ switch (nRes)
+ {
+ case Z_OK:
+ break;
+ case Z_MEM_ERROR:
+ pStream.reset();
+ break;
+ case Z_STREAM_ERROR:
+ pStream.reset();
+ break;
+ default:
+ break;
+ }
+}
+
+InflaterBytes::~InflaterBytes()
+{
+ end();
+}
+
+void InflaterBytes::setInput( const sal_Int8* rBuffer, sal_Int32 nBufLen )
+{
+ sInBuffer = rBuffer;
+ nOffset = 0;
+ nLength = nBufLen;
+}
+
+
+sal_Int32 InflaterBytes::doInflateSegment( sal_Int8* pOutBuffer, sal_Int32 nBufLen, sal_Int32 nNewOffset, sal_Int32 nNewLength )
+{
+ if (nNewOffset < 0 || nNewLength < 0 || nNewOffset + nNewLength > nBufLen)
+ {
+ // do error handling
+ }
+ return doInflateBytes(pOutBuffer, nNewOffset, nNewLength);
+}
+
+void InflaterBytes::end( )
+{
+ if (pStream)
+ {
+#if !defined Z_PREFIX
+ inflateEnd(pStream.get());
+#else
+ z_inflateEnd(pStream.get());
+#endif
+ pStream.reset();
+ }
+}
+
+sal_Int32 InflaterBytes::doInflateBytes (sal_Int8* pOutBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength)
+{
+ if ( !pStream )
+ {
+ nLastInflateError = Z_STREAM_ERROR;
+ return 0;
+ }
+
+ nLastInflateError = 0;
+
+ pStream->next_in = reinterpret_cast<const unsigned char*>( sInBuffer + nOffset );
+ pStream->avail_in = nLength;
+ pStream->next_out = reinterpret_cast < unsigned char* > ( pOutBuffer + nNewOffset );
+ pStream->avail_out = nNewLength;
+
+#if !defined Z_PREFIX
+ sal_Int32 nResult = ::inflate(pStream.get(), Z_PARTIAL_FLUSH);
+#else
+ sal_Int32 nResult = ::z_inflate(pStream.get(), Z_PARTIAL_FLUSH);
+#endif
+
+ switch (nResult)
+ {
+ case Z_STREAM_END:
+ bFinished = true;
+ [[fallthrough]];
+ case Z_OK:
+ nOffset += nLength - pStream->avail_in;
+ nLength = pStream->avail_in;
+ return nNewLength - pStream->avail_out;
+
+ case Z_NEED_DICT:
+ bNeedDict = true;
+ nOffset += nLength - pStream->avail_in;
+ nLength = pStream->avail_in;
+ return 0;
+
+ default:
+ // it is no error, if there is no input or no output
+ if ( nLength && nNewLength )
+ nLastInflateError = nResult;
+ }
+
+ return 0;
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/package/source/zipapi/MemoryByteGrabber.hxx b/package/source/zipapi/MemoryByteGrabber.hxx
index dd876d66ebfa..f9076067cd91 100644
--- a/package/source/zipapi/MemoryByteGrabber.hxx
+++ b/package/source/zipapi/MemoryByteGrabber.hxx
@@ -32,6 +32,12 @@ public:
, mnEnd ( rBuffer.getLength() )
{
}
+ MemoryByteGrabber ( const sal_Int8* pBuffer, sal_Int32 nBufLen )
+ : mpBuffer ( pBuffer )
+ , mnCurrent ( 0 )
+ , mnEnd ( nBufLen )
+ {
+ }
MemoryByteGrabber(css::uno::Sequence<sal_Int8> &&) = delete;
const sal_Int8 * getCurrentPos () const { return mpBuffer + mnCurrent; }
diff --git a/package/source/zipapi/XBufferedThreadedStream.cxx b/package/source/zipapi/XBufferedThreadedStream.cxx
index d3bf995d9073..ea7c270ebea6 100644
--- a/package/source/zipapi/XBufferedThreadedStream.cxx
+++ b/package/source/zipapi/XBufferedThreadedStream.cxx
@@ -158,6 +158,32 @@ sal_Int32 SAL_CALL XBufferedThreadedStream::readBytes( Sequence< sal_Int8 >& rDa
return nAvailableSize;
}
+sal_Int32 XBufferedThreadedStream::readSomeBytes( sal_Int8* pData, sal_Int32 nBytesToRead )
+{
+ if( !hasBytes() )
+ return 0;
+
+ const sal_Int32 nAvailableSize = static_cast< sal_Int32 > ( std::min< sal_Int64 >( nBytesToRead, remainingSize() ) );
+ sal_Int32 i = 0, nPendingBytes = nAvailableSize;
+
+ while( nPendingBytes )
+ {
+ const Buffer &pBuffer = getNextBlock();
+ if( !pBuffer.hasElements() )
+ return nAvailableSize - nPendingBytes;
+ const sal_Int32 limit = std::min<sal_Int32>( nPendingBytes, pBuffer.getLength() - mnOffset );
+
+ memcpy( &pData[i], &pBuffer[mnOffset], limit );
+
+ nPendingBytes -= limit;
+ mnOffset += limit;
+ mnPos += limit;
+ i += limit;
+ }
+
+ return nAvailableSize;
+}
+
sal_Int32 SAL_CALL XBufferedThreadedStream::readSomeBytes( Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
{
return readBytes( aData, nMaxBytesToRead );
diff --git a/package/source/zipapi/XBufferedThreadedStream.hxx b/package/source/zipapi/XBufferedThreadedStream.hxx
index beb1cd33c700..c3243f4f1326 100644
--- a/package/source/zipapi/XBufferedThreadedStream.hxx
+++ b/package/source/zipapi/XBufferedThreadedStream.hxx
@@ -12,6 +12,7 @@
#include <com/sun/star/io/XInputStream.hpp>
+#include <comphelper/bytereader.hxx>
#include <cppuhelper/implbase.hxx>
#include <rtl/ref.hxx>
#include <salhelper/thread.hxx>
@@ -23,7 +24,8 @@
typedef css::uno::Sequence< sal_Int8 > Buffer;
-class XBufferedThreadedStream : public cppu::WeakImplHelper< css::io::XInputStream >
+class XBufferedThreadedStream : public cppu::WeakImplHelper< css::io::XInputStream >,
+ public comphelper::ByteReader
{
private:
const css::uno::Reference<XInputStream> mxSrcStream;
@@ -78,6 +80,9 @@ public:
virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip ) override;
virtual sal_Int32 SAL_CALL available( ) override;
virtual void SAL_CALL closeInput( ) override;
+
+ // comphelper::ByteReader
+ virtual sal_Int32 readSomeBytes(sal_Int8* aData, sal_Int32 nBytesToRead) override;
};
#endif
diff --git a/package/source/zipapi/ZipFile.cxx b/package/source/zipapi/ZipFile.cxx
index 2d8d69c853c7..37907647711b 100644
--- a/package/source/zipapi/ZipFile.cxx
+++ b/package/source/zipapi/ZipFile.cxx
@@ -590,7 +590,8 @@ uno::Reference<io::XInputStream> ZipFile::checkValidPassword(
namespace {
-class XBufferedStream : public cppu::WeakImplHelper<css::io::XInputStream, css::io::XSeekable>
+class XBufferedStream : public cppu::WeakImplHelper<css::io::XInputStream, css::io::XSeekable>,
+ public comphelper::ByteReader
{
std::vector<sal_Int8> maBytes;
size_t mnPos;
@@ -655,6 +656,22 @@ public:
return nReadSize;
}
+ virtual sal_Int32 readSomeBytes(sal_Int8* pData, sal_Int32 nBytesToRead) override
+ {
+ if (!hasBytes())
+ return 0;
+
+ sal_Int32 nReadSize = std::min<sal_Int32>(nBytesToRead, remainingSize());
+ std::vector<sal_Int8>::const_iterator it = maBytes.cbegin();
+ std::advance(it, mnPos);
+ for (sal_Int32 i = 0; i < nReadSize; ++i, ++it)
+ pData[i] = *it;
+
+ mnPos += nReadSize;
+
+ return nReadSize;
+ }
+
virtual sal_Int32 SAL_CALL readSomeBytes( ::css::uno::Sequence<sal_Int8>& rData, sal_Int32 nMaxBytesToRead ) override
{
return readBytes(rData, nMaxBytesToRead);
@@ -918,7 +935,12 @@ sal_uInt64 ZipFile::readLOC(ZipEntry &rEntry)
sal_Int64 nPos = -rEntry.nOffset;
aGrabber.seek(nPos);
- sal_Int32 nTestSig = aGrabber.ReadInt32();
+ std::array<sal_Int8, 30> aHeader;
+ if (aGrabber.readBytes(aHeader.data(), 30) != 30)
+ throw new uno::RuntimeException();
+ MemoryByteGrabber headerMemGrabber(aHeader.data(), 30);
+
+ sal_Int32 nTestSig = headerMemGrabber.ReadInt32();
if (nTestSig != LOCSIG)
throw ZipIOException(u"Invalid LOC header (bad signature)"_ustr );
@@ -927,18 +949,18 @@ sal_uInt64 ZipFile::readLOC(ZipEntry &rEntry)
// Just verify the path and calculate the data offset and otherwise
// rely on the central directory info.
- aGrabber.ReadInt16(); // version - ignore any mismatch (Maven created JARs)
- sal_uInt16 const nLocFlag = aGrabber.ReadUInt16(); // general purpose bit flag
- sal_uInt16 const nLocMethod = aGrabber.ReadUInt16(); // compression method
+ headerMemGrabber.ReadInt16(); // version - ignore any mismatch (Maven created JARs)
+ sal_uInt16 const nLocFlag = headerMemGrabber.ReadUInt16(); // general purpose bit flag
+ sal_uInt16 const nLocMethod = headerMemGrabber.ReadUInt16(); // compression method
// Do *not* compare timestamps, since MSO 2010 can produce documents
// with timestamp difference in the central directory entry and local
// file header.
- aGrabber.ReadInt32(); //time
- sal_uInt32 nLocCrc = aGrabber.ReadUInt32(); //crc
- sal_uInt64 nLocCompressedSize = aGrabber.ReadUInt32(); //compressed size
- sal_uInt64 nLocSize = aGrabber.ReadUInt32(); //size
- sal_Int16 nPathLen = aGrabber.ReadInt16();
- sal_Int16 nExtraLen = aGrabber.ReadInt16();
+ headerMemGrabber.ReadInt32(); //time
+ sal_uInt32 nLocCrc = headerMemGrabber.ReadUInt32(); //crc
+ sal_uInt64 nLocCompressedSize = headerMemGrabber.ReadUInt32(); //compressed size
+ sal_uInt64 nLocSize = headerMemGrabber.ReadUInt32(); //size
+ sal_Int16 nPathLen = headerMemGrabber.ReadInt16();
+ sal_Int16 nExtraLen = headerMemGrabber.ReadInt16();
if (nPathLen < 0)
{
@@ -955,13 +977,13 @@ sal_uInt64 ZipFile::readLOC(ZipEntry &rEntry)
{
// read always in UTF8, some tools seem not to set UTF8 bit
// coverity[tainted_data] - we've checked negative lens, and up to max short is ok here
- uno::Sequence<sal_Int8> aNameBuffer(nPathLen);
- sal_Int32 nRead = aGrabber.readBytes(aNameBuffer, nPathLen);
- if (nRead < aNameBuffer.getLength())
- aNameBuffer.realloc(nRead);
+ std::vector<sal_Int8> aNameBuffer(nPathLen);
+ sal_Int32 nRead = aGrabber.readBytes(aNameBuffer.data(), nPathLen);
+ if (nRead < nPathLen)
+ aNameBuffer.resize(nRead);
- OUString sLOCPath( reinterpret_cast<const char *>(aNameBuffer.getConstArray()),
- aNameBuffer.getLength(),
+ OUString sLOCPath( reinterpret_cast<const char *>(aNameBuffer.data()),
+ nRead,
RTL_TEXTENCODING_UTF8 );
if ( rEntry.nPathLen == -1 ) // the file was created
@@ -980,9 +1002,9 @@ sal_uInt64 ZipFile::readLOC(ZipEntry &rEntry)
::std::optional<sal_uInt64> oOffset64;
if (nExtraLen != 0)
{
- Sequence<sal_Int8> aExtraBuffer;
- aGrabber.readBytes(aExtraBuffer, nExtraLen);
- MemoryByteGrabber extraMemGrabber(aExtraBuffer);
+ std::vector<sal_Int8> aExtraBuffer(nExtraLen);
+ aGrabber.readBytes(aExtraBuffer.data(), nExtraLen);
+ MemoryByteGrabber extraMemGrabber(aExtraBuffer.data(), nExtraLen);
isZip64 = readExtraFields(extraMemGrabber, nExtraLen,
nLocSize, nLocCompressedSize, oOffset64, &sLOCPath);
@@ -1116,7 +1138,7 @@ sal_uInt64 ZipFile::readLOC(ZipEntry &rEntry)
std::tuple<sal_Int64, sal_Int64, sal_Int64> ZipFile::findCentralDirectory()
{
// this method is called in constructor only, no need for mutex
- Sequence < sal_Int8 > aBuffer;
+ std::vector < sal_Int8 > aBuffer;
try
{
sal_Int64 const nLength = aGrabber.getLength();
@@ -1130,10 +1152,11 @@ std::tuple<sal_Int64, sal_Int64, sal_Int64> ZipFile::findCentralDirectory()
aGrabber.seek( nEnd );
auto nSize = nLength - nEnd;
- if (nSize != aGrabber.readBytes(aBuffer, nSize))
+ aBuffer.reserve(nSize);
+ if (nSize != aGrabber.readBytes(aBuffer.data(), nSize))
throw ZipException(u"Zip END signature not found!"_ustr );
- const sal_Int8 *pBuffer = aBuffer.getConstArray();
+ const sal_Int8 *pBuffer = aBuffer.data();
sal_Int64 nEndPos = {};
nPos = nSize - ENDHDR;
@@ -1176,9 +1199,10 @@ std::tuple<sal_Int64, sal_Int64, sal_Int64> ZipFile::findCentralDirectory()
if (20 <= nEndPos)
{
aGrabber.seek(nEndPos - 20);
- Sequence<sal_Int8> aZip64EndLocator;
- aGrabber.readBytes(aZip64EndLocator, 20);
- MemoryByteGrabber loc64Grabber(aZip64EndLocator);
+ std::array<sal_Int8, 20> aZip64EndLocator;
+ if (20 != aGrabber.readBytes(aZip64EndLocator.data(), 20))
+ throw uno::RuntimeException();
+ MemoryByteGrabber loc64Grabber(aZip64EndLocator.data(), 20);
if (loc64Grabber.ReadUInt8() == 'P'
&& loc64Grabber.ReadUInt8() == 'K'
&& loc64Grabber.ReadUInt8() == 6
@@ -1201,9 +1225,9 @@ std::tuple<sal_Int64, sal_Int64, sal_Int64> ZipFile::findCentralDirectory()
throw ZipException(u"invalid Zip64 end locator (number of disks)"_ustr);
}
aGrabber.seek(nLoc64End64Offset);
- Sequence<sal_Int8> aZip64EndDirectory;
- aGrabber.readBytes(aZip64EndDirectory, nEndPos - 20 - nLoc64End64Offset);
- MemoryByteGrabber end64Grabber(aZip64EndDirectory);
+ std::vector<sal_Int8> aZip64EndDirectory(nEndPos - 20 - nLoc64End64Offset);
+ aGrabber.readBytes(aZip64EndDirectory.data(), nEndPos - 20 - nLoc64End64Offset);
+ MemoryByteGrabber end64Grabber(aZip64EndDirectory.data(), nEndPos - 20 - nLoc64End64Offset);
if (end64Grabber.ReadUInt8() != 'P'
|| end64Grabber.ReadUInt8() != 'K'
|| end64Grabber.ReadUInt8() != 6
@@ -1309,12 +1333,12 @@ sal_Int32 ZipFile::readCEN()
throw ZipException(u"central directory too big"_ustr);
aGrabber.seek(nCenPos);
- Sequence<sal_Int8> aCENBuffer(nCenLen);
- sal_Int64 nRead = aGrabber.readBytes ( aCENBuffer, nCenLen );
+ std::vector<sal_Int8> aCENBuffer(nCenLen);
+ sal_Int64 nRead = aGrabber.readBytes ( aCENBuffer.data(), nCenLen );
if (nCenLen != nRead)
throw ZipException (u"Error reading CEN into memory buffer!"_ustr );
- MemoryByteGrabber aMemGrabber(aCENBuffer);
+ MemoryByteGrabber aMemGrabber(aCENBuffer.data(), nCenLen);
ZipEntry aEntry;
sal_Int16 nCommentLen;
@@ -1590,29 +1614,30 @@ void ZipFile::HandlePK34(std::span<const sal_Int8> data, sal_Int64 dataOffset, s
RTL_TEXTENCODING_UTF8);
else
{
- Sequence<sal_Int8> aFileName;
+ std::vector<sal_Int8> aFileName(aEntry.nPathLen);
aGrabber.seek(dataOffset + 30);
- aGrabber.readBytes(aFileName, aEntry.nPathLen);
- aEntry.sPath = OUString(reinterpret_cast<const char*>(aFileName.getConstArray()),
- aFileName.getLength(), RTL_TEXTENCODING_UTF8);
- aEntry.nPathLen = static_cast<sal_Int16>(aFileName.getLength());
+ aGrabber.readBytes(aFileName.data(), aEntry.nPathLen);
+ aEntry.sPath = OUString(reinterpret_cast<const char*>(aFileName.data()),
+ aEntry.nPathLen, RTL_TEXTENCODING_UTF8);
+ aEntry.nPathLen = aEntry.nPathLen;
}
aEntry.sPath = aEntry.sPath.replace('\\', '/');
// read 64bit header
if (aEntry.nExtraLen > 0)
{
- Sequence<sal_Int8> aExtraBuffer;
+ std::vector<sal_Int8> aExtraBuffer(aEntry.nExtraLen);
if (o3tl::make_unsigned(30 + aEntry.nPathLen) + aEntry.nExtraLen <= data.size())
{
- aExtraBuffer = Sequence<sal_Int8>(data.data() + 30 + aEntry.nPathLen, aEntry.nExtraLen);
+ auto it = data.begin() + 30 + aEntry.nPathLen;
+ std::copy(it, it + aEntry.nExtraLen, aExtraBuffer.begin());
}
else
{
aGrabber.seek(dataOffset + 30 + aEntry.nExtraLen);
- aGrabber.readBytes(aExtraBuffer, aEntry.nExtraLen);
+ aGrabber.readBytes(aExtraBuffer.data(), aEntry.nExtraLen);
}
- MemoryByteGrabber aMemGrabberExtra(aExtraBuffer);
+ MemoryByteGrabber aMemGrabberExtra(aExtraBuffer.data(), aEntry.nExtraLen);
if (aEntry.nExtraLen > 0)
{
::std::optional<sal_uInt64> oOffset64;
@@ -1743,7 +1768,9 @@ void ZipFile::recover()
{
::osl::MutexGuard aGuard( m_aMutexHolder->GetMutex() );
- Sequence < sal_Int8 > aBuffer;
+ std::vector < sal_Int8 > aBuffer;
+ const sal_Int64 nToRead = 32000;
+ aBuffer.reserve(nToRead);
try
{
@@ -1753,11 +1780,11 @@ void ZipFile::recover()
aGrabber.seek( 0 );
- const sal_Int64 nToRead = 32000;
- for( sal_Int64 nGenPos = 0; aGrabber.readBytes( aBuffer, nToRead ) && aBuffer.getLength() > 16; )
+ sal_Int32 nRead;
+ for( sal_Int64 nGenPos = 0; (nRead = aGrabber.readBytes( aBuffer.data(), nToRead )) && nRead > 16; )
{
- const sal_Int8 *pBuffer = aBuffer.getConstArray();
- const sal_Int32 nBufSize = aBuffer.getLength();
+ const sal_Int8 *pBuffer = aBuffer.data();
+ const sal_Int32 nBufSize = nRead;
sal_Int64 nPos = 0;
// the buffer should contain at least one header,
@@ -1822,17 +1849,18 @@ sal_Int32 ZipFile::getCRC( sal_Int64 nOffset, sal_Int64 nSize )
{
::osl::MutexGuard aGuard( m_aMutexHolder->GetMutex() );
- Sequence < sal_Int8 > aBuffer;
CRC32 aCRC;
sal_Int64 nBlockSize = ::std::min(nSize, static_cast< sal_Int64 >(32000));
+ std::vector < sal_Int8 > aBuffer;
+ aBuffer.reserve(nBlockSize);
aGrabber.seek( nOffset );
+ sal_Int32 nRead;
for (sal_Int64 ind = 0;
- aGrabber.readBytes( aBuffer, nBlockSize ) && ind * nBlockSize < nSize;
+ (nRead = aGrabber.readBytes( aBuffer.data(), nBlockSize )) && ind * nBlockSize < nSize;
++ind)
{
- sal_Int64 nLen = ::std::min(nBlockSize, nSize - ind * nBlockSize);
- aCRC.updateSegment(aBuffer, static_cast<sal_Int32>(nLen));
+ aCRC.updateSegment(aBuffer.data(), nRead);
}
return aCRC.getValue();
@@ -1842,26 +1870,29 @@ void ZipFile::getSizeAndCRC( sal_Int64 nOffset, sal_Int64 nCompressedSize, sal_I
{
::osl::MutexGuard aGuard( m_aMutexHolder->GetMutex() );
- Sequence < sal_Int8 > aBuffer;
CRC32 aCRC;
sal_Int64 nRealSize = 0;
- Inflater aInflaterLocal( true );
+ ZipUtils::InflaterBytes aInflaterLocal( true );
sal_Int32 nBlockSize = static_cast< sal_Int32 > (::std::min( nCompressedSize, static_cast< sal_Int64 >( 32000 ) ) );
+ std::vector < sal_Int8 > aBuffer(nBlockSize);
+ std::vector< sal_Int8 > aData( nBlockSize );
aGrabber.seek( nOffset );
+ sal_Int32 nRead;
for ( sal_Int64 ind = 0;
- !aInflaterLocal.finished() && aGrabber.readBytes( aBuffer, nBlockSize ) && ind * nBlockSize < nCompressedSize;
+ !aInflaterLocal.finished()
+ && (nRead = aGrabber.readBytes( aBuffer.data(), nBlockSize ))
+ && ind * nBlockSize < nCompressedSize;
ind++ )
{
- Sequence < sal_Int8 > aData( nBlockSize );
sal_Int32 nLastInflated = 0;
sal_Int64 nInBlock = 0;
- aInflaterLocal.setInput( aBuffer );
+ aInflaterLocal.setInput( aBuffer.data(), nRead );
do
{
- nLastInflated = aInflaterLocal.doInflateSegment( aData, 0, nBlockSize );
- aCRC.updateSegment( aData, nLastInflated );
+ nLastInflated = aInflaterLocal.doInflateSegment( aData.data(), nBlockSize, 0, nBlockSize );
+ aCRC.updateSegment( aData.data(), nLastInflated );
nInBlock += nLastInflated;
} while( !aInflater.finished() && nLastInflated );
diff --git a/package/source/zippackage/ZipPackage.cxx b/package/source/zippackage/ZipPackage.cxx
index 1b129362b4a4..0b6b1ee0503f 100644
--- a/package/source/zippackage/ZipPackage.cxx
+++ b/package/source/zippackage/ZipPackage.cxx
@@ -1241,6 +1241,7 @@ void ZipPackage::WriteContentTypes( ZipOutputStream& aZipOut, const std::vector<
void ZipPackage::ConnectTo( const uno::Reference< io::XInputStream >& xInStream )
{
+ assert(dynamic_cast<comphelper::ByteReader*>(xInStream.get()));
m_xContentSeek.set( xInStream, uno::UNO_QUERY_THROW );
m_xContentStream = xInStream;
diff --git a/package/source/zippackage/wrapstreamforshare.cxx b/package/source/zippackage/wrapstreamforshare.cxx
index 250ccb4ba5ce..026aee989b01 100644
--- a/package/source/zippackage/wrapstreamforshare.cxx
+++ b/package/source/zippackage/wrapstreamforshare.cxx
@@ -46,6 +46,8 @@ WrapStreamForShare::WrapStreamForShare( uno::Reference< io::XInputStream > xInSt
throw uno::RuntimeException(THROW_WHERE );
}
m_xSeekable.set( m_xInStream, uno::UNO_QUERY_THROW );
+ mpByteReader = dynamic_cast<comphelper::ByteReader*>(m_xInStream.get());
+ assert(mpByteReader);
}
WrapStreamForShare::~WrapStreamForShare()
@@ -79,6 +81,19 @@ sal_Int32 SAL_CALL WrapStreamForShare::readSomeBytes( uno::Sequence< sal_Int8 >&
return nRead;
}
+sal_Int32 WrapStreamForShare::readSomeBytes( sal_Int8* aData, sal_Int32 nMaxBytesToRead )
+{
+ if ( !m_xInStream.is() )
+ throw io::IOException(THROW_WHERE );
+
+ m_xSeekable->seek( m_nCurPos );
+
+ sal_Int32 nRead = mpByteReader->readSomeBytes( aData, nMaxBytesToRead );
+ m_nCurPos += nRead;
+
+ return nRead;
+}
+
void SAL_CALL WrapStreamForShare::skipBytes( sal_Int32 nBytesToSkip )
{
::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
@@ -113,6 +128,7 @@ void SAL_CALL WrapStreamForShare::closeInput()
// m_xInStream->closeInput();
m_xInStream.clear();
m_xSeekable.clear();
+ mpByteReader = nullptr;
}
// XSeekable
diff --git a/package/source/zippackage/wrapstreamforshare.hxx b/package/source/zippackage/wrapstreamforshare.hxx
index ac8de258842f..adc57862d4ea 100644
--- a/package/source/zippackage/wrapstreamforshare.hxx
+++ b/package/source/zippackage/wrapstreamforshare.hxx
@@ -22,15 +22,18 @@
#include <com/sun/star/io/XInputStream.hpp>
#include <com/sun/star/io/XSeekable.hpp>
+#include <comphelper/bytereader.hxx>
#include <comphelper/refcountedmutex.hxx>
#include <cppuhelper/implbase.hxx>
#include <rtl/ref.hxx>
class WrapStreamForShare final : public cppu::WeakImplHelper < css::io::XInputStream
- , css::io::XSeekable >
+ , css::io::XSeekable >,
+ public comphelper::ByteReader
{
rtl::Reference< comphelper::RefCountedMutex > m_xMutex;
css::uno::Reference < css::io::XInputStream > m_xInStream;
+ comphelper::ByteReader* mpByteReader;
css::uno::Reference < css::io::XSeekable > m_xSeekable;
sal_Int64 m_nCurPos;
@@ -52,6 +55,8 @@ public:
virtual sal_Int64 SAL_CALL getPosition() override;
virtual sal_Int64 SAL_CALL getLength() override;
+ // comphelper::ByteReader
+ virtual sal_Int32 readSomeBytes(sal_Int8* aData, sal_Int32 nBytesToRead) override;
};
#endif