summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoel Grandin <noel.grandin@collabora.co.uk>2024-08-17 13:19:54 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2024-08-27 09:10:04 +0200
commita6ad198d097fb4a503c8d5831d484ff46721134b (patch)
treee82ca01e800c5f50ce8db7bd8eb610790ee13c8d
parent03b31a8ad48e3b8a9e54203ff3856702557757b5 (diff)
tdf#158556 use more comphelper::ByteReader
which avoids a ton of temporary uno::Sequence being created Change-Id: I237bb69395f692bb0272ca0daec05b81af828e01 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/171968 Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk> Tested-by: Jenkins
-rw-r--r--comphelper/source/streaming/memorystream.cxx25
-rw-r--r--comphelper/source/streaming/seekableinput.cxx17
-rw-r--r--include/comphelper/seekableinput.hxx6
-rw-r--r--include/package/Inflater.hxx22
-rw-r--r--package/inc/ByteGrabber.hxx7
-rw-r--r--package/inc/CRC32.hxx1
-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
-rw-r--r--sot/source/sdstor/ucbstorage.cxx21
-rw-r--r--ucb/source/ucp/file/filinpstr.cxx18
-rw-r--r--ucb/source/ucp/file/filinpstr.hxx7
-rw-r--r--unotools/source/ucbhelper/XTempFile.hxx3
-rw-r--r--unotools/source/ucbhelper/xtempfile.cxx15
27 files changed, 476 insertions, 92 deletions
diff --git a/comphelper/source/streaming/memorystream.cxx b/comphelper/source/streaming/memorystream.cxx
index b457f4b42ca8..39ae66b51d07 100644
--- a/comphelper/source/streaming/memorystream.cxx
+++ b/comphelper/source/streaming/memorystream.cxx
@@ -55,7 +55,7 @@ namespace {
class UNOMemoryStream :
public WeakImplHelper<XServiceInfo, XStream, XSeekableInputStream, XOutputStream, XTruncate>,
- public comphelper::ByteWriter
+ public comphelper::ByteWriter, public comphelper::ByteReader
{
public:
UNOMemoryStream();
@@ -92,6 +92,9 @@ public:
// comphelper::ByteWriter
virtual void writeBytes(const sal_Int8* aData, sal_Int32 nBytesToWrite) override;
+ // comphelper::ByteReader
+ virtual sal_Int32 readSomeBytes(sal_Int8* aData, sal_Int32 nBytesToRead) override;
+
private:
std::vector< sal_Int8, boost::noinit_adaptor<std::allocator<sal_Int8>> > maData;
sal_Int32 mnCursor;
@@ -153,6 +156,26 @@ sal_Int32 SAL_CALL UNOMemoryStream::readBytes( Sequence< sal_Int8 >& aData, sal_
return nBytesToRead;
}
+// ByteReader
+sal_Int32 UNOMemoryStream::readSomeBytes( sal_Int8* aData, sal_Int32 nBytesToRead )
+{
+ if( nBytesToRead < 0 )
+ throw IOException(u"nBytesToRead < 0"_ustr);
+
+ nBytesToRead = std::min( nBytesToRead, available() );
+
+ if( nBytesToRead )
+ {
+ sal_Int8* pData = &(*maData.begin());
+ sal_Int8* pCursor = &(pData[mnCursor]);
+ memcpy( aData, pCursor, nBytesToRead );
+
+ mnCursor += nBytesToRead;
+ }
+
+ return nBytesToRead;
+}
+
sal_Int32 SAL_CALL UNOMemoryStream::readSomeBytes( Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
{
return readBytes( aData, nMaxBytesToRead );
diff --git a/comphelper/source/streaming/seekableinput.cxx b/comphelper/source/streaming/seekableinput.cxx
index 6fd418df36ca..dceb16824c58 100644
--- a/comphelper/source/streaming/seekableinput.cxx
+++ b/comphelper/source/streaming/seekableinput.cxx
@@ -107,7 +107,11 @@ void OSeekableInputWrapper::PrepareCopy_Impl()
xTempSeek->seek( 0 );
m_xCopyInput.set( xTempOut, uno::UNO_QUERY );
if ( m_xCopyInput.is() )
+ {
m_xCopySeek = xTempSeek;
+ m_pCopyByteReader = dynamic_cast<comphelper::ByteReader*>(xTempOut.get());
+ assert(m_pCopyByteReader);
+ }
}
}
@@ -142,6 +146,18 @@ sal_Int32 SAL_CALL OSeekableInputWrapper::readSomeBytes( uno::Sequence< sal_Int8
return m_xCopyInput->readSomeBytes( aData, nMaxBytesToRead );
}
+sal_Int32 OSeekableInputWrapper::readSomeBytes( sal_Int8* aData, sal_Int32 nMaxBytesToRead )
+{
+ std::scoped_lock aGuard( m_aMutex );
+
+ if ( !m_xOriginalStream.is() )
+ throw io::NotConnectedException();
+
+ PrepareCopy_Impl();
+
+ return m_pCopyByteReader->readSomeBytes( aData, nMaxBytesToRead );
+}
+
void SAL_CALL OSeekableInputWrapper::skipBytes( sal_Int32 nBytesToSkip )
{
@@ -186,6 +202,7 @@ void SAL_CALL OSeekableInputWrapper::closeInput()
}
m_xCopySeek.clear();
+ m_pCopyByteReader = nullptr;
}
diff --git a/include/comphelper/seekableinput.hxx b/include/comphelper/seekableinput.hxx
index 0c2092f7b849..2287b506e9e2 100644
--- a/include/comphelper/seekableinput.hxx
+++ b/include/comphelper/seekableinput.hxx
@@ -23,6 +23,7 @@
#include <com/sun/star/io/XInputStream.hpp>
#include <com/sun/star/io/XSeekable.hpp>
#include <cppuhelper/implbase.hxx>
+#include <comphelper/bytereader.hxx>
#include <comphelper/comphelperdllapi.h>
#include <mutex>
@@ -37,7 +38,7 @@ class SAL_DLLPUBLIC_TEMPLATE OSeekableInputWrapper_BASE
{};
class COMPHELPER_DLLPUBLIC OSeekableInputWrapper final
- : public OSeekableInputWrapper_BASE
+ : public OSeekableInputWrapper_BASE, public comphelper::ByteReader
{
std::mutex m_aMutex;
@@ -47,6 +48,7 @@ class COMPHELPER_DLLPUBLIC OSeekableInputWrapper final
css::uno::Reference< css::io::XInputStream > m_xCopyInput;
css::uno::Reference< css::io::XSeekable > m_xCopySeek;
+ comphelper::ByteReader* m_pCopyByteReader { nullptr };
private:
COMPHELPER_DLLPRIVATE void PrepareCopy_Impl();
@@ -74,6 +76,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;
};
} // namespace comphelper
diff --git a/include/package/Inflater.hxx b/include/package/Inflater.hxx
index e0d44d21d6f6..d59d220acfc4 100644
--- a/include/package/Inflater.hxx
+++ b/include/package/Inflater.hxx
@@ -51,6 +51,28 @@ public:
sal_Int32 getLastInflateError() const { return nLastInflateError; }
};
+class UNLESS_MERGELIBS(DLLPUBLIC_PACKAGE) InflaterBytes final
+{
+ typedef struct z_stream_s z_stream;
+
+ bool bFinished, bNeedDict;
+ sal_Int32 nOffset, nLength, nLastInflateError;
+ std::unique_ptr<z_stream> pStream;
+ const sal_Int8* sInBuffer;
+ sal_Int32 doInflateBytes (sal_Int8* pOutBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength);
+
+public:
+ InflaterBytes(bool bNoWrap);
+ ~InflaterBytes();
+ void setInput( const sal_Int8* pBuffer, sal_Int32 nLen );
+ bool needsDictionary() const { return bNeedDict; }
+ bool finished() const { return bFinished; }
+ sal_Int32 doInflateSegment( sal_Int8* pOutBuffer, sal_Int32 nBufLen, sal_Int32 nNewOffset, sal_Int32 nNewLength );
+ void end( );
+
+ sal_Int32 getLastInflateError() const { return nLastInflateError; }
+};
+
}
#endif
diff --git a/package/inc/ByteGrabber.hxx b/package/inc/ByteGrabber.hxx
index 04a5b35f3547..8a695338563e 100644
--- a/package/inc/ByteGrabber.hxx
+++ b/package/inc/ByteGrabber.hxx
@@ -21,6 +21,8 @@
#include <com/sun/star/uno/Sequence.h>
#include <com/sun/star/uno/Reference.h>
+#include <comphelper/bytereader.hxx>
+#include <array>
namespace com::sun::star {
namespace io { class XSeekable; class XInputStream; }
@@ -29,8 +31,8 @@ class ByteGrabber final
{
css::uno::Reference < css::io::XInputStream > xStream;
css::uno::Reference < css::io::XSeekable > xSeek;
- css::uno::Sequence < sal_Int8 > aSequence;
- const sal_Int8 *pSequence;
+ comphelper::ByteReader* mpByteReader;
+ std::array<sal_Int8, 8> maBuffer;
public:
ByteGrabber (css::uno::Reference < css::io::XInputStream > const & xIstream);
@@ -43,6 +45,7 @@ public:
/// @throws css::io::IOException
/// @throws css::uno::RuntimeException
sal_Int32 readBytes( css::uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead );
+ sal_Int32 readBytes( sal_Int8* aData, sal_Int32 nBytesToRead );
// XSeekable
/// @throws css::lang::IllegalArgumentException
/// @throws css::io::IOException
diff --git a/package/inc/CRC32.hxx b/package/inc/CRC32.hxx
index a2ca1b435e0e..c96a48a00f60 100644
--- a/package/inc/CRC32.hxx
+++ b/package/inc/CRC32.hxx
@@ -35,6 +35,7 @@ public:
sal_Int64 updateStream (css::uno::Reference < css::io::XInputStream > const & xStream);
/// @throws css::uno::RuntimeException
void updateSegment(const css::uno::Sequence< sal_Int8 > &b, sal_Int32 len);
+ void updateSegment(const sal_Int8* b, sal_Int32 len);
/// @throws css::uno::RuntimeException
void update(const css::uno::Sequence< sal_Int8 > &b);
/// @throws css::uno::RuntimeException
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
diff --git a/sot/source/sdstor/ucbstorage.cxx b/sot/source/sdstor/ucbstorage.cxx
index a6aa800e2436..51c43bb290e3 100644
--- a/sot/source/sdstor/ucbstorage.cxx
+++ b/sot/source/sdstor/ucbstorage.cxx
@@ -87,7 +87,7 @@ typedef ::cppu::WeakImplHelper < XInputStream, XSeekable > FileInputStreamWrappe
namespace {
-class FileStreamWrapper_Impl : public FileInputStreamWrapper_Base
+class FileStreamWrapper_Impl : public FileInputStreamWrapper_Base, public comphelper::ByteReader
{
protected:
std::mutex m_aMutex;
@@ -107,6 +107,8 @@ public:
virtual sal_Int32 SAL_CALL available() override;
virtual void SAL_CALL closeInput() override;
+ virtual sal_Int32 readSomeBytes(sal_Int8* aData, sal_Int32 nBytesToRead) override;
+
protected:
void checkConnected();
void checkError();
@@ -164,6 +166,23 @@ sal_Int32 SAL_CALL FileStreamWrapper_Impl::readBytes(Sequence< sal_Int8 >& aData
return nRead;
}
+sal_Int32 FileStreamWrapper_Impl::readSomeBytes(sal_Int8* aData, sal_Int32 nBytesToRead)
+{
+ if ( m_aURL.isEmpty() )
+ return 0;
+
+ checkConnected();
+
+ if (nBytesToRead < 0)
+ throw BufferSizeExceededException(OUString(), getXWeak());
+
+ std::scoped_lock aGuard( m_aMutex );
+
+ sal_uInt32 nRead = m_pSvStream->ReadBytes(static_cast<void*>(aData), nBytesToRead);
+ checkError();
+
+ return nRead;
+}
sal_Int32 SAL_CALL FileStreamWrapper_Impl::readSomeBytes(Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead)
{
diff --git a/ucb/source/ucp/file/filinpstr.cxx b/ucb/source/ucp/file/filinpstr.cxx
index 70e80e384d2b..33cbf32d1df6 100644
--- a/ucb/source/ucp/file/filinpstr.cxx
+++ b/ucb/source/ucp/file/filinpstr.cxx
@@ -99,6 +99,24 @@ XInputStream_impl::readBytes(
return static_cast<sal_Int32>(nrc);
}
+sal_Int32
+XInputStream_impl::readSomeBytes(
+ sal_Int8* aData,
+ sal_Int32 nBytesToRead )
+{
+ if( ! m_nIsOpen ) throw io::IOException( THROW_WHERE );
+
+ //TODO! translate memory exhaustion (if it were detectable...) into
+ // io::BufferSizeExceededException
+
+ sal_uInt64 nrc(0);
+ if(m_aFile.read( aData, sal_uInt64(nBytesToRead),nrc )
+ != osl::FileBase::E_None)
+ throw io::IOException( THROW_WHERE );
+
+ return static_cast<sal_Int32>(nrc);
+}
+
sal_Int32 SAL_CALL
XInputStream_impl::readSomeBytes(
uno::Sequence< sal_Int8 >& aData,
diff --git a/ucb/source/ucp/file/filinpstr.hxx b/ucb/source/ucp/file/filinpstr.hxx
index f62fe4741170..d43cd2871bd6 100644
--- a/ucb/source/ucp/file/filinpstr.hxx
+++ b/ucb/source/ucp/file/filinpstr.hxx
@@ -22,7 +22,7 @@
#include <cppuhelper/implbase.hxx>
#include <com/sun/star/io/XSeekable.hpp>
#include <com/sun/star/io/XInputStream.hpp>
-
+#include <comphelper/bytereader.hxx>
#include "filrec.hxx"
enum class TaskHandlerErr;
@@ -32,7 +32,8 @@ namespace fileaccess {
class TaskManager;
class XInputStream_impl final
- : public cppu::WeakImplHelper<css::io::XInputStream, css::io::XSeekable>
+ : public cppu::WeakImplHelper<css::io::XInputStream, css::io::XSeekable>,
+ public comphelper::ByteReader
{
public:
@@ -75,6 +76,8 @@ namespace fileaccess {
virtual sal_Int64 SAL_CALL
getLength() override;
+ virtual sal_Int32 readSomeBytes(sal_Int8* aData, sal_Int32 nBytesToRead) override;
+
private:
bool m_nIsOpen;
diff --git a/unotools/source/ucbhelper/XTempFile.hxx b/unotools/source/ucbhelper/XTempFile.hxx
index 2b0ec33cb42a..456dd7da186e 100644
--- a/unotools/source/ucbhelper/XTempFile.hxx
+++ b/unotools/source/ucbhelper/XTempFile.hxx
@@ -46,7 +46,7 @@ typedef ::cppu::WeakImplHelper< css::io::XTempFile
, css::beans::XPropertyAccess
, css::lang::XServiceInfo> OTempFileBase;
-class OTempFileService : public OTempFileBase
+class OTempFileService : public OTempFileBase, public comphelper::ByteReader
{
std::optional<utl::TempFileNamed> mpTempFile;
std::mutex maMutex;
@@ -112,6 +112,7 @@ public:
virtual ::css::uno::Sequence< ::css::beans::PropertyValue > SAL_CALL getPropertyValues() override;
virtual void SAL_CALL setPropertyValues( const ::css::uno::Sequence< ::css::beans::PropertyValue >& aProps ) override;
+ virtual sal_Int32 readSomeBytes(sal_Int8* aData, sal_Int32 nBytesToRead) override;
virtual ~OTempFileService () override;
};
diff --git a/unotools/source/ucbhelper/xtempfile.cxx b/unotools/source/ucbhelper/xtempfile.cxx
index 35462587ff84..7e27b7f4d24f 100644
--- a/unotools/source/ucbhelper/xtempfile.cxx
+++ b/unotools/source/ucbhelper/xtempfile.cxx
@@ -147,6 +147,21 @@ sal_Int32 SAL_CALL OTempFileService::readSomeBytes( css::uno::Sequence< sal_Int8
}
return readBytes(aData, nMaxBytesToRead);
}
+sal_Int32 OTempFileService::readSomeBytes( sal_Int8* aData, sal_Int32 nBytesToRead )
+{
+ std::unique_lock aGuard( maMutex );
+ if ( mbInClosed )
+ throw css::io::NotConnectedException ( OUString(), getXWeak() );
+
+ checkConnected();
+ if (nBytesToRead < 0)
+ throw css::io::BufferSizeExceededException( OUString(), getXWeak());
+
+ sal_uInt32 nRead = mpStream->ReadBytes(static_cast<void*>(aData), nBytesToRead);
+ checkError();
+
+ return nRead;
+}
void SAL_CALL OTempFileService::skipBytes( sal_Int32 nBytesToSkip )
{
std::unique_lock aGuard( maMutex );