tdf#97597: Ensure that each parsing thread has its own buffer.
Change-Id: I93077f954a49b3922930e4fc86c80228be0f4dd2 Reviewed-on: https://gerrit.libreoffice.org/33069 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Kohei Yoshida <libreoffice@kohei.us>
This commit is contained in:
parent
efce216ca5
commit
4ae705d02d
@ -317,17 +317,28 @@ uno::Reference< embed::XStorage > OStorageHelper::GetStorageOfFormatFromInputStr
|
||||
const OUString& aFormat,
|
||||
const uno::Reference < io::XInputStream >& xStream,
|
||||
const uno::Reference< uno::XComponentContext >& rxContext,
|
||||
bool bRepairStorage )
|
||||
bool bRepairStorage, bool bUseBufferedStream )
|
||||
throw ( uno::Exception )
|
||||
{
|
||||
uno::Sequence< beans::PropertyValue > aProps( 1 );
|
||||
aProps[0].Name = "StorageFormat";
|
||||
aProps[0].Value <<= aFormat;
|
||||
sal_Int32 nPos = 0;
|
||||
aProps[nPos].Name = "StorageFormat";
|
||||
aProps[nPos].Value <<= aFormat;
|
||||
++nPos;
|
||||
if ( bRepairStorage )
|
||||
{
|
||||
aProps.realloc( 2 );
|
||||
aProps[1].Name = "RepairPackage";
|
||||
aProps[1].Value <<= bRepairStorage;
|
||||
aProps.realloc(nPos+1);
|
||||
aProps[nPos].Name = "RepairPackage";
|
||||
aProps[nPos].Value <<= bRepairStorage;
|
||||
++nPos;
|
||||
}
|
||||
|
||||
if (bUseBufferedStream)
|
||||
{
|
||||
aProps.realloc(nPos+1);
|
||||
aProps[nPos].Name = "UseBufferedStream";
|
||||
aProps[nPos].Value <<= bUseBufferedStream;
|
||||
++nPos;
|
||||
}
|
||||
|
||||
uno::Sequence< uno::Any > aArgs( 3 );
|
||||
@ -349,17 +360,28 @@ uno::Reference< embed::XStorage > OStorageHelper::GetStorageOfFormatFromStream(
|
||||
const uno::Reference < io::XStream >& xStream,
|
||||
sal_Int32 nStorageMode,
|
||||
const uno::Reference< uno::XComponentContext >& rxContext,
|
||||
bool bRepairStorage )
|
||||
bool bRepairStorage, bool bUseBufferedStream )
|
||||
throw ( uno::Exception )
|
||||
{
|
||||
uno::Sequence< beans::PropertyValue > aProps( 1 );
|
||||
aProps[0].Name = "StorageFormat";
|
||||
aProps[0].Value <<= aFormat;
|
||||
sal_Int32 nPos = 0;
|
||||
aProps[nPos].Name = "StorageFormat";
|
||||
aProps[nPos].Value <<= aFormat;
|
||||
++nPos;
|
||||
if ( bRepairStorage )
|
||||
{
|
||||
aProps.realloc( 2 );
|
||||
aProps[1].Name = "RepairPackage";
|
||||
aProps[1].Value <<= bRepairStorage;
|
||||
aProps.realloc(nPos+1);
|
||||
aProps[nPos].Name = "RepairPackage";
|
||||
aProps[nPos].Value <<= bRepairStorage;
|
||||
++nPos;
|
||||
}
|
||||
|
||||
if (bUseBufferedStream)
|
||||
{
|
||||
aProps.realloc(nPos+1);
|
||||
aProps[nPos].Name = "UseBufferedStream";
|
||||
aProps[nPos].Value <<= bUseBufferedStream;
|
||||
++nPos;
|
||||
}
|
||||
|
||||
uno::Sequence< uno::Any > aArgs( 3 );
|
||||
|
@ -154,7 +154,8 @@ public:
|
||||
const css::uno::Reference < css::io::XInputStream >& xStream,
|
||||
const css::uno::Reference< css::uno::XComponentContext >& rxContext
|
||||
= css::uno::Reference< css::uno::XComponentContext >(),
|
||||
bool bRepairStorage = false )
|
||||
bool bRepairStorage = false,
|
||||
bool bUseBufferedStream = false )
|
||||
throw ( css::uno::Exception );
|
||||
|
||||
static css::uno::Reference< css::embed::XStorage >
|
||||
@ -164,7 +165,8 @@ public:
|
||||
sal_Int32 nStorageMode = css::embed::ElementModes::READWRITE,
|
||||
const css::uno::Reference< css::uno::XComponentContext >& rxContext
|
||||
= css::uno::Reference< css::uno::XComponentContext >(),
|
||||
bool bRepairStorage = false )
|
||||
bool bRepairStorage = false,
|
||||
bool bUseBufferedStream = false )
|
||||
throw ( css::uno::Exception );
|
||||
|
||||
static css::uno::Sequence< css::beans::NamedValue >
|
||||
|
@ -58,7 +58,7 @@ ZipStorage::ZipStorage( const Reference< XComponentContext >& rxContext, const R
|
||||
implementation of relations handling.
|
||||
*/
|
||||
mxStorage = ::comphelper::OStorageHelper::GetStorageOfFormatFromInputStream(
|
||||
ZIP_STORAGE_FORMAT_STRING, rxInStream, rxContext );
|
||||
ZIP_STORAGE_FORMAT_STRING, rxInStream, rxContext, false, true);
|
||||
}
|
||||
catch (Exception const& e)
|
||||
{
|
||||
@ -76,7 +76,7 @@ ZipStorage::ZipStorage( const Reference< XComponentContext >& rxContext, const R
|
||||
{
|
||||
const sal_Int32 nOpenMode = ElementModes::READWRITE | ElementModes::TRUNCATE;
|
||||
mxStorage = ::comphelper::OStorageHelper::GetStorageOfFormatFromStream(
|
||||
OFOPXML_STORAGE_FORMAT_STRING, rxStream, nOpenMode, rxContext, true );
|
||||
OFOPXML_STORAGE_FORMAT_STRING, rxStream, nOpenMode, rxContext, true, true);
|
||||
}
|
||||
catch (Exception const& e)
|
||||
{
|
||||
|
@ -64,9 +64,10 @@ class ZipFile
|
||||
const css::uno::Reference < css::uno::XComponentContext > m_xContext;
|
||||
|
||||
bool bRecoveryMode;
|
||||
bool mbUseBufferedStream;
|
||||
|
||||
// aMediaType parameter is used only for raw stream header creation
|
||||
css::uno::Reference < css::io::XInputStream > createUnbufferedStream(
|
||||
css::uno::Reference < css::io::XInputStream > createStreamForZipEntry(
|
||||
const rtl::Reference<SotMutexHolder>& aMutexHolder,
|
||||
ZipEntry & rEntry,
|
||||
const ::rtl::Reference < EncryptionData > &rData,
|
||||
@ -102,6 +103,8 @@ public:
|
||||
|
||||
EntryHash& GetEntryHash() { return aEntries; }
|
||||
|
||||
void setUseBufferedStream( bool b );
|
||||
|
||||
void setInputStream ( const css::uno::Reference < css::io::XInputStream >& xNewStream );
|
||||
css::uno::Reference< css::io::XInputStream > getRawData(
|
||||
ZipEntry& rEntry,
|
||||
|
@ -193,8 +193,8 @@ uno::Reference< uno::XInterface > SAL_CALL OStorageFactory::createInstanceWithAr
|
||||
if ( aDescr[nInd].Name == "InteractionHandler"
|
||||
|| aDescr[nInd].Name == "Password"
|
||||
|| aDescr[nInd].Name == "RepairPackage"
|
||||
|| aDescr[nInd].Name == "StatusIndicator" )
|
||||
// || aDescr[nInd].Name == "Unpacked" ) // TODO:
|
||||
|| aDescr[nInd].Name == "StatusIndicator"
|
||||
|| aDescr[nInd].Name == "UseBufferedStream" )
|
||||
{
|
||||
aPropsToSet.realloc( ++nNumArgs );
|
||||
aPropsToSet[nNumArgs-1].Name = aDescr[nInd].Name;
|
||||
|
@ -467,7 +467,8 @@ void OStorage_Impl::OpenOwnPackage()
|
||||
for ( sal_Int32 aInd = 0; aInd < m_xProperties.getLength(); aInd++ )
|
||||
{
|
||||
if ( m_xProperties[aInd].Name == "RepairPackage"
|
||||
|| m_xProperties[aInd].Name == "ProgressHandler" )
|
||||
|| m_xProperties[aInd].Name == "ProgressHandler"
|
||||
|| m_xProperties[aInd].Name == "UseBufferedStream" )
|
||||
{
|
||||
beans::NamedValue aNamedValue( m_xProperties[aInd].Name,
|
||||
m_xProperties[aInd].Value );
|
||||
|
@ -74,6 +74,7 @@ ZipFile::ZipFile( uno::Reference < XInputStream > &xInput, const uno::Reference
|
||||
, xStream(xInput)
|
||||
, m_xContext ( rxContext )
|
||||
, bRecoveryMode( false )
|
||||
, mbUseBufferedStream(false)
|
||||
{
|
||||
if (bInitialise)
|
||||
{
|
||||
@ -91,6 +92,7 @@ ZipFile::ZipFile( uno::Reference < XInputStream > &xInput, const uno::Reference
|
||||
, xStream(xInput)
|
||||
, m_xContext ( rxContext )
|
||||
, bRecoveryMode( bForceRecovery )
|
||||
, mbUseBufferedStream(false)
|
||||
{
|
||||
if (bInitialise)
|
||||
{
|
||||
@ -111,6 +113,11 @@ ZipFile::~ZipFile()
|
||||
aEntries.clear();
|
||||
}
|
||||
|
||||
void ZipFile::setUseBufferedStream( bool b )
|
||||
{
|
||||
mbUseBufferedStream = b;
|
||||
}
|
||||
|
||||
void ZipFile::setInputStream ( const uno::Reference < XInputStream >& xNewStream )
|
||||
{
|
||||
::osl::MutexGuard aGuard( m_aMutex );
|
||||
@ -504,7 +511,99 @@ bool ZipFile::hasValidPassword ( ZipEntry & rEntry, const ::rtl::Reference< Encr
|
||||
return bRet;
|
||||
}
|
||||
|
||||
uno::Reference< XInputStream > ZipFile::createUnbufferedStream(
|
||||
namespace {
|
||||
|
||||
class XBufferedStream : public cppu::WeakImplHelper<css::io::XInputStream>
|
||||
{
|
||||
std::vector<sal_Int8> maBytes;
|
||||
size_t mnPos;
|
||||
|
||||
size_t remainingSize() const
|
||||
{
|
||||
return maBytes.size() - mnPos;
|
||||
}
|
||||
|
||||
bool hasBytes() const
|
||||
{
|
||||
return mnPos < maBytes.size();
|
||||
}
|
||||
|
||||
public:
|
||||
XBufferedStream( const uno::Reference<XInputStream>& xSrcStream ) : mnPos(0)
|
||||
{
|
||||
const sal_Int32 nBufSize = 8192;
|
||||
|
||||
sal_Int32 nRemaining = xSrcStream->available();
|
||||
maBytes.reserve(nRemaining);
|
||||
uno::Sequence<sal_Int8> aBuf(nBufSize);
|
||||
|
||||
auto readAndCopy = [&]( sal_Int32 nReadSize ) -> sal_Int32
|
||||
{
|
||||
sal_Int32 nBytes = xSrcStream->readBytes(aBuf, nReadSize);
|
||||
const sal_Int8* p = aBuf.getArray();
|
||||
const sal_Int8* pEnd = p + nBytes;
|
||||
std::copy(p, pEnd, std::back_inserter(maBytes));
|
||||
return nBytes;
|
||||
};
|
||||
|
||||
while (nRemaining > nBufSize)
|
||||
nRemaining -= readAndCopy(nBufSize);
|
||||
|
||||
if (nRemaining)
|
||||
readAndCopy(nRemaining);
|
||||
}
|
||||
|
||||
virtual sal_Int32 SAL_CALL readBytes( uno::Sequence<sal_Int8>& rData, sal_Int32 nBytesToRead )
|
||||
throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException, std::exception) override
|
||||
{
|
||||
if (!hasBytes())
|
||||
return 0;
|
||||
|
||||
sal_Int32 nReadSize = std::min<sal_Int32>(nBytesToRead, remainingSize());
|
||||
rData.realloc(nReadSize);
|
||||
std::vector<sal_Int8>::const_iterator it = maBytes.cbegin();
|
||||
std::advance(it, mnPos);
|
||||
for (sal_Int32 i = 0; i < nReadSize; ++i, ++it)
|
||||
rData[i] = *it;
|
||||
|
||||
mnPos += nReadSize;
|
||||
|
||||
return nReadSize;
|
||||
}
|
||||
|
||||
virtual sal_Int32 SAL_CALL readSomeBytes( ::css::uno::Sequence<sal_Int8>& rData, sal_Int32 nMaxBytesToRead )
|
||||
throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException, std::exception) override
|
||||
{
|
||||
return readBytes(rData, nMaxBytesToRead);
|
||||
}
|
||||
|
||||
virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip )
|
||||
throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException, std::exception) override
|
||||
{
|
||||
if (!hasBytes())
|
||||
return;
|
||||
|
||||
mnPos += nBytesToSkip;
|
||||
}
|
||||
|
||||
virtual sal_Int32 SAL_CALL available()
|
||||
throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException, std::exception) override
|
||||
{
|
||||
if (!hasBytes())
|
||||
return 0;
|
||||
|
||||
return remainingSize();
|
||||
}
|
||||
|
||||
virtual void SAL_CALL closeInput()
|
||||
throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException, std::exception) override
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
uno::Reference< XInputStream > ZipFile::createStreamForZipEntry(
|
||||
const rtl::Reference<SotMutexHolder>& aMutexHolder,
|
||||
ZipEntry & rEntry,
|
||||
const ::rtl::Reference< EncryptionData > &rData,
|
||||
@ -514,7 +613,14 @@ uno::Reference< XInputStream > ZipFile::createUnbufferedStream(
|
||||
{
|
||||
::osl::MutexGuard aGuard( m_aMutex );
|
||||
|
||||
return new XUnbufferedStream ( m_xContext, aMutexHolder, rEntry, xStream, rData, nStreamMode, bIsEncrypted, aMediaType, bRecoveryMode );
|
||||
uno::Reference<io::XInputStream> xSrcStream = new XUnbufferedStream(
|
||||
m_xContext, aMutexHolder, rEntry, xStream, rData, nStreamMode, bIsEncrypted, aMediaType, bRecoveryMode);
|
||||
|
||||
if (!mbUseBufferedStream)
|
||||
return xSrcStream;
|
||||
|
||||
uno::Reference<io::XInputStream> xBufStream(new XBufferedStream(xSrcStream));
|
||||
return xBufStream;
|
||||
}
|
||||
|
||||
std::unique_ptr<ZipEnumeration> ZipFile::entries()
|
||||
@ -542,7 +648,7 @@ uno::Reference< XInputStream > ZipFile::getInputStream( ZipEntry& rEntry,
|
||||
if ( bIsEncrypted && rData.is() && rData->m_aDigest.getLength() )
|
||||
bNeedRawStream = !hasValidPassword ( rEntry, rData );
|
||||
|
||||
return createUnbufferedStream ( aMutexHolder,
|
||||
return createStreamForZipEntry ( aMutexHolder,
|
||||
rEntry,
|
||||
rData,
|
||||
bNeedRawStream ? UNBUFF_STREAM_RAW : UNBUFF_STREAM_DATA,
|
||||
@ -578,7 +684,7 @@ uno::Reference< XInputStream > ZipFile::getDataStream( ZipEntry& rEntry,
|
||||
else
|
||||
bNeedRawStream = ( rEntry.nMethod == STORED );
|
||||
|
||||
return createUnbufferedStream ( aMutexHolder,
|
||||
return createStreamForZipEntry ( aMutexHolder,
|
||||
rEntry,
|
||||
rData,
|
||||
bNeedRawStream ? UNBUFF_STREAM_RAW : UNBUFF_STREAM_DATA,
|
||||
@ -595,7 +701,7 @@ uno::Reference< XInputStream > ZipFile::getRawData( ZipEntry& rEntry,
|
||||
if ( rEntry.nOffset <= 0 )
|
||||
readLOC( rEntry );
|
||||
|
||||
return createUnbufferedStream ( aMutexHolder, rEntry, rData, UNBUFF_STREAM_RAW, bIsEncrypted );
|
||||
return createStreamForZipEntry ( aMutexHolder, rEntry, rData, UNBUFF_STREAM_RAW, bIsEncrypted );
|
||||
}
|
||||
|
||||
uno::Reference< XInputStream > ZipFile::getWrappedRawStream(
|
||||
@ -612,7 +718,7 @@ uno::Reference< XInputStream > ZipFile::getWrappedRawStream(
|
||||
if ( rEntry.nOffset <= 0 )
|
||||
readLOC( rEntry );
|
||||
|
||||
return createUnbufferedStream ( aMutexHolder, rEntry, rData, UNBUFF_STREAM_WRAPPEDRAW, true, aMediaType );
|
||||
return createStreamForZipEntry ( aMutexHolder, rEntry, rData, UNBUFF_STREAM_WRAPPEDRAW, true, aMediaType );
|
||||
}
|
||||
|
||||
bool ZipFile::readLOC( ZipEntry &rEntry )
|
||||
|
@ -563,6 +563,7 @@ void SAL_CALL ZipPackage::initialize( const uno::Sequence< Any >& aArguments )
|
||||
if ( aArguments.getLength() )
|
||||
{
|
||||
bool bHaveZipFile = true;
|
||||
bool bUseBufferedStream = false;
|
||||
|
||||
for( int ind = 0; ind < aArguments.getLength(); ind++ )
|
||||
{
|
||||
@ -690,6 +691,10 @@ void SAL_CALL ZipPackage::initialize( const uno::Sequence< Any >& aArguments )
|
||||
aNamedValue.Value >>= m_bAllowRemoveOnInsert;
|
||||
m_xRootFolder->setRemoveOnInsertMode_Impl( m_bAllowRemoveOnInsert );
|
||||
}
|
||||
else if (aNamedValue.Name == "UseBufferedStream")
|
||||
{
|
||||
aNamedValue.Value >>= bUseBufferedStream;
|
||||
}
|
||||
|
||||
// for now the progress handler is not used, probably it will never be
|
||||
// if ( aNamedValue.Name == "ProgressHandler" )
|
||||
@ -733,6 +738,7 @@ void SAL_CALL ZipPackage::initialize( const uno::Sequence< Any >& aArguments )
|
||||
try
|
||||
{
|
||||
m_pZipFile = o3tl::make_unique<ZipFile>(m_xContentStream, m_xContext, true, m_bForceRecovery);
|
||||
m_pZipFile->setUseBufferedStream(bUseBufferedStream);
|
||||
getZipFileContents();
|
||||
}
|
||||
catch ( IOException & e )
|
||||
|
Loading…
x
Reference in New Issue
Block a user