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
This commit is contained in:
Noel Grandin 2024-08-17 13:19:54 +02:00
parent 03b31a8ad4
commit a6ad198d09
27 changed files with 476 additions and 92 deletions

View file

@ -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 );

View file

@ -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;
}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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() );

View file

@ -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

View file

@ -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 );

View file

@ -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

View file

@ -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 );

View file

@ -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

View file

@ -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: */

View file

@ -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)

View file

@ -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: */

View file

@ -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; }

View file

@ -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 );

View file

@ -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

View file

@ -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 );

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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)
{

View file

@ -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,

View file

@ -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;

View file

@ -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;
};

View file

@ -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 );