[Libreoffice-commits] core.git: writerperfect/source

Fridrich Å trba fridrich.strba at bluewin.ch
Fri Dec 20 06:26:04 PST 2013


 writerperfect/source/common/WPXSvStream.cxx |  157 ++++++++++++++++++++++------
 1 file changed, 125 insertions(+), 32 deletions(-)

New commits:
commit c56c2e28ff4252aa858826416a8a57cb8c2bf100
Author: Fridrich Å trba <fridrich.strba at bluewin.ch>
Date:   Fri Dec 20 14:49:06 2013 +0100

    Buffered WPXSvInputStream
    
    Change-Id: I8bb2632cb018093d02e21090e77bb48364f99268
    Reviewed-on: https://gerrit.libreoffice.org/7146
    Reviewed-by: David Tardon <dtardon at redhat.com>
    Tested-by: David Tardon <dtardon at redhat.com>

diff --git a/writerperfect/source/common/WPXSvStream.cxx b/writerperfect/source/common/WPXSvStream.cxx
index dd35311..c803632 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);
 }
 


More information about the Libreoffice-commits mailing list