summaryrefslogtreecommitdiff
path: root/writerperfect/source/common/WPXSvStream.cxx
diff options
context:
space:
mode:
authorFridrich Štrba <fridrich.strba@bluewin.ch>2013-12-20 14:49:06 +0100
committerDavid Tardon <dtardon@redhat.com>2013-12-20 14:25:43 +0000
commitc56c2e28ff4252aa858826416a8a57cb8c2bf100 (patch)
tree4961c3425885feb7e33f5fb8bf5595e580283699 /writerperfect/source/common/WPXSvStream.cxx
parent3843a568fd11ed0f2dac20d6c5e4f9feb7232f2e (diff)
Buffered WPXSvInputStream
Change-Id: I8bb2632cb018093d02e21090e77bb48364f99268 Reviewed-on: https://gerrit.libreoffice.org/7146 Reviewed-by: David Tardon <dtardon@redhat.com> Tested-by: David Tardon <dtardon@redhat.com>
Diffstat (limited to 'writerperfect/source/common/WPXSvStream.cxx')
-rw-r--r--writerperfect/source/common/WPXSvStream.cxx157
1 files changed, 125 insertions, 32 deletions
diff --git a/writerperfect/source/common/WPXSvStream.cxx b/writerperfect/source/common/WPXSvStream.cxx
index dd353119953f..c8036327791b 100644
--- a/writerperfect/source/common/WPXSvStream.cxx
+++ b/writerperfect/source/common/WPXSvStream.cxx
@@ -37,7 +37,7 @@ typedef struct
SotStorageStreamRef ref;
} SotStorageStreamRefWrapper;
-class WPXSvInputStreamImpl : public WPXInputStream
+class WPXSvInputStreamImpl
{
public :
WPXSvInputStreamImpl( ::com::sun::star::uno::Reference<
@@ -48,27 +48,35 @@ public :
WPXInputStream * getDocumentOLEStream(const char *name);
const unsigned char *read(unsigned long numBytes, unsigned long &numBytesRead);
- int seek(long offset, WPX_SEEK_TYPE seekType);
+ int seek(long offset);
long tell();
bool atEOS();
+ void invalidateReadBuffer();
private:
::std::vector< SotStorageRefWrapper > mxChildrenStorages;
::std::vector< SotStorageStreamRefWrapper > mxChildrenStreams;
::com::sun::star::uno::Reference<
- ::com::sun::star::io::XInputStream > mxStream;
+ ::com::sun::star::io::XInputStream > mxStream;
::com::sun::star::uno::Reference<
- ::com::sun::star::io::XSeekable > mxSeekable;
+ ::com::sun::star::io::XSeekable > mxSeekable;
::com::sun::star::uno::Sequence< sal_Int8 > maData;
+public:
sal_Int64 mnLength;
+ unsigned char *mpReadBuffer;
+ unsigned long mnReadBufferLength;
+ unsigned long mnReadBufferPos;
};
WPXSvInputStreamImpl::WPXSvInputStreamImpl( Reference< XInputStream > xStream ) :
- WPXInputStream(),
mxChildrenStorages(),
mxChildrenStreams(),
mxStream(xStream),
mxSeekable(xStream, UNO_QUERY),
- maData(0)
+ maData(0),
+ mnLength(0),
+ mpReadBuffer(0),
+ mnReadBufferLength(0),
+ mnReadBufferPos(0)
{
if (!xStream.is() || !mxStream.is())
mnLength = 0;
@@ -93,6 +101,8 @@ WPXSvInputStreamImpl::WPXSvInputStreamImpl( Reference< XInputStream > xStream )
WPXSvInputStreamImpl::~WPXSvInputStreamImpl()
{
+ if (mpReadBuffer)
+ delete [] mpReadBuffer;
}
const unsigned char *WPXSvInputStreamImpl::read(unsigned long numBytes, unsigned long &numBytesRead)
@@ -122,7 +132,7 @@ long WPXSvInputStreamImpl::tell()
}
}
-int WPXSvInputStreamImpl::seek(long offset, WPX_SEEK_TYPE seekType)
+int WPXSvInputStreamImpl::seek(long offset)
{
if ((mnLength == 0) || !mxStream.is() || !mxSeekable.is())
return -1;
@@ -131,28 +141,10 @@ int WPXSvInputStreamImpl::seek(long offset, WPX_SEEK_TYPE seekType)
if ((tmpPosition < 0) || (tmpPosition > (std::numeric_limits<long>::max)()))
return -1;
- sal_Int64 tmpOffset = offset;
- if (seekType == WPX_SEEK_CUR)
- tmpOffset += tmpPosition;
- if (seekType == WPX_SEEK_END)
- tmpOffset += mnLength;
-
- int retVal = 0;
- if (tmpOffset < 0)
- {
- tmpOffset = 0;
- retVal = -1;
- }
- if (tmpOffset > mnLength)
- {
- tmpOffset = mnLength;
- retVal = -1;
- }
-
try
{
- mxSeekable->seek(tmpOffset);
- return retVal;
+ mxSeekable->seek(offset);
+ return 0;
}
catch (...)
{
@@ -255,6 +247,18 @@ WPXInputStream *WPXSvInputStreamImpl::getDocumentOLEStream(const char *name)
}
+void WPXSvInputStreamImpl::invalidateReadBuffer()
+{
+ if (mpReadBuffer)
+ {
+ seek((long) tell() + (long)mnReadBufferPos - (long)mnReadBufferLength);
+ delete [] mpReadBuffer;
+ mpReadBuffer = 0;
+ mnReadBufferPos = 0;
+ mnReadBufferLength = 0;
+ }
+}
+
WPXSvInputStream::WPXSvInputStream( Reference< XInputStream > xStream ) :
mpImpl(new WPXSvInputStreamImpl(xStream))
{
@@ -262,36 +266,125 @@ WPXSvInputStream::WPXSvInputStream( Reference< XInputStream > xStream ) :
WPXSvInputStream::~WPXSvInputStream()
{
- delete mpImpl;
+ if (mpImpl)
+ delete mpImpl;
}
+#define BUFFER_MAX 65536
+
const unsigned char *WPXSvInputStream::read(unsigned long numBytes, unsigned long &numBytesRead)
{
- return mpImpl->read(numBytes, numBytesRead);
+ numBytesRead = 0;
+
+ if (numBytes == 0 || numBytes > (std::numeric_limits<unsigned long>::max)()/2)
+ return 0;
+
+ if (mpImpl->mpReadBuffer)
+ {
+ if ((mpImpl->mnReadBufferPos + numBytes > mpImpl->mnReadBufferPos) && (mpImpl->mnReadBufferPos + numBytes <= mpImpl->mnReadBufferLength))
+ {
+ const unsigned char *pTmp = mpImpl->mpReadBuffer + mpImpl->mnReadBufferPos;
+ mpImpl->mnReadBufferPos += numBytes;
+ numBytesRead = numBytes;
+ return pTmp;
+ }
+
+ mpImpl->invalidateReadBuffer();
+ }
+
+ unsigned long curpos = (unsigned long) mpImpl->tell();
+ if (curpos == (unsigned long)-1) // returned ERROR
+ return 0;
+
+ if ((curpos + numBytes < curpos) /*overflow*/ ||
+ (curpos + numBytes >= (sal_uInt64)mpImpl->mnLength)) /*reading more than available*/
+ {
+ numBytes = mpImpl->mnLength - curpos;
+ }
+
+ if (numBytes < BUFFER_MAX)
+ {
+ if (BUFFER_MAX < mpImpl->mnLength - curpos)
+ mpImpl->mnReadBufferLength = BUFFER_MAX;
+ else /* BUFFER_MAX >= mpImpl->mnLength - curpos */
+ mpImpl->mnReadBufferLength = mpImpl->mnLength - curpos;
+ }
+ else
+ mpImpl->mnReadBufferLength = numBytes;
+
+ mpImpl->seek((long) curpos);
+
+ mpImpl->mpReadBuffer = new unsigned char[mpImpl->mnReadBufferLength];
+ unsigned long tmpNumBytes(0);
+ const unsigned char *pTmp = mpImpl->read(mpImpl->mnReadBufferLength, tmpNumBytes);
+ if (tmpNumBytes != mpImpl->mnReadBufferLength)
+ mpImpl->mnReadBufferLength = tmpNumBytes;
+
+ mpImpl->mnReadBufferPos = 0;
+ if (!mpImpl->mnReadBufferLength)
+ return 0;
+
+ numBytesRead = numBytes;
+
+ mpImpl->mnReadBufferPos += numBytesRead;
+ memcpy(mpImpl->mpReadBuffer, pTmp, mpImpl->mnReadBufferLength);
+ return const_cast<const unsigned char *>(mpImpl->mpReadBuffer);
}
long WPXSvInputStream::tell()
{
- return mpImpl->tell();
+ long retVal = mpImpl->tell();
+ return retVal - (long)mpImpl->mnReadBufferLength + (long)mpImpl->mnReadBufferPos;
}
int WPXSvInputStream::seek(long offset, WPX_SEEK_TYPE seekType)
{
- return mpImpl->seek(offset, seekType);
+ sal_Int64 tmpOffset = offset;
+ if (seekType == WPX_SEEK_CUR)
+ tmpOffset += tell();
+ if (seekType == WPX_SEEK_END)
+ tmpOffset += mpImpl->mnLength;
+
+ int retVal = 0;
+ if (tmpOffset < 0)
+ {
+ tmpOffset = 0;
+ retVal = -1;
+ }
+ if (tmpOffset > mpImpl->mnLength)
+ {
+ tmpOffset = mpImpl->mnLength;
+ retVal = -1;
+ }
+
+ if (tmpOffset < mpImpl->tell() && (unsigned long)tmpOffset >= (unsigned long)mpImpl->tell() - mpImpl->mnReadBufferLength)
+ {
+ mpImpl->mnReadBufferPos = (unsigned long)(tmpOffset + (long) mpImpl->mnReadBufferLength - (long) mpImpl->tell());
+ return 0;
+ }
+
+ mpImpl->invalidateReadBuffer();
+
+ int retVal2 = mpImpl->seek(tmpOffset);
+ if (retVal)
+ return retVal;
+ return retVal2;
}
bool WPXSvInputStream::atEOS()
{
- return mpImpl->atEOS();
+ return mpImpl->atEOS() && mpImpl->mnReadBufferPos == mpImpl->mnReadBufferLength;
}
bool WPXSvInputStream::isOLEStream()
{
+ mpImpl->invalidateReadBuffer();
return mpImpl->isOLEStream();
}
WPXInputStream *WPXSvInputStream::getDocumentOLEStream(const char *name)
{
+ mpImpl->invalidateReadBuffer();
return mpImpl->getDocumentOLEStream(name);
}