LCOV - code coverage report
Current view: top level - libreoffice/svl/source/misc - strmadpt.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 435 0.0 %
Date: 2012-12-27 Functions: 0 58 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : 
      21             : #include <functional> // needed under Solaris when including <algorithm>...
      22             : 
      23             : #include <algorithm>
      24             : #include <limits>
      25             : #include <set>
      26             : #include <string.h>
      27             : 
      28             : #include <rtl/alloc.h>
      29             : #include <svl/instrm.hxx>
      30             : #include <svl/outstrm.hxx>
      31             : #include <svl/strmadpt.hxx>
      32             : 
      33             : using namespace com::sun::star;
      34             : 
      35             : //============================================================================
      36             : class SvDataPipe_Impl
      37             : {
      38             : public:
      39             :     enum SeekResult { SEEK_BEFORE_MARKED, SEEK_OK, SEEK_PAST_END };
      40             : 
      41             : private:
      42             :     struct Page
      43             :     {
      44             :         Page * m_pPrev;
      45             :         Page * m_pNext;
      46             :         sal_Int8 * m_pStart;
      47             :         sal_Int8 * m_pRead;
      48             :         sal_Int8 * m_pEnd;
      49             :         sal_uInt32 m_nOffset;
      50             :         sal_Int8 m_aBuffer[1];
      51             :     };
      52             : 
      53             :     std::multiset< sal_uInt32 > m_aMarks;
      54             :     Page * m_pFirstPage;
      55             :     Page * m_pReadPage;
      56             :     Page * m_pWritePage;
      57             :     sal_Int8 * m_pReadBuffer;
      58             :     sal_uInt32 m_nReadBufferSize;
      59             :     sal_uInt32 m_nReadBufferFilled;
      60             :     sal_uInt32 m_nPageSize;
      61             :     sal_uInt32 m_nMinPages;
      62             :     sal_uInt32 m_nMaxPages;
      63             :     sal_uInt32 m_nPages;
      64             :     bool m_bEOF;
      65             : 
      66             :     bool remove(Page * pPage);
      67             : 
      68             : public:
      69             :     inline SvDataPipe_Impl(sal_uInt32 nThePageSize = 1000,
      70             :                            sal_uInt32 nTheMinPages = 100,
      71             :                            sal_uInt32 nTheMaxPages
      72             :                                = std::numeric_limits< sal_uInt32 >::max());
      73             : 
      74             :     ~SvDataPipe_Impl();
      75             : 
      76             :     inline void setReadBuffer(sal_Int8 * pBuffer, sal_uInt32 nSize);
      77             : 
      78             :     sal_uInt32 read();
      79             : 
      80           0 :     void clearReadBuffer() { m_pReadBuffer = 0; }
      81             : 
      82             :     sal_uInt32 write(sal_Int8 const * pBuffer, sal_uInt32 nSize);
      83             : 
      84           0 :     void setEOF() { m_bEOF = true; }
      85             : 
      86             :     inline bool isEOF() const;
      87             : 
      88             :     bool addMark(sal_uInt32 nPosition);
      89             :     bool removeMark(sal_uInt32 nPosition);
      90             : 
      91             :     inline sal_uInt32 getReadPosition() const;
      92             : 
      93             :     SeekResult setReadPosition(sal_uInt32 nPosition);
      94             : };
      95             : 
      96           0 : SvDataPipe_Impl::SvDataPipe_Impl(sal_uInt32 nThePageSize,
      97             :                                  sal_uInt32 nTheMinPages,
      98             :                                  sal_uInt32 nTheMaxPages):
      99             :     m_pFirstPage(0),
     100             :     m_pReadPage(0),
     101             :     m_pWritePage(0),
     102             :     m_pReadBuffer(0),
     103             :     m_nPageSize(std::min< sal_uInt32 >(
     104           0 :                     std::max< sal_uInt32 >(nThePageSize, sal_uInt32(1)),
     105           0 :                     sal_uInt32(std::numeric_limits< sal_uInt32 >::max()
     106           0 :                                    - sizeof (Page) + 1))),
     107           0 :     m_nMinPages(std::max< sal_uInt32 >(nTheMinPages, sal_uInt32(1))),
     108           0 :     m_nMaxPages(std::max< sal_uInt32 >(nTheMaxPages, sal_uInt32(1))),
     109             :     m_nPages(0),
     110           0 :     m_bEOF(false)
     111           0 : {}
     112             : 
     113           0 : inline void SvDataPipe_Impl::setReadBuffer(sal_Int8 * pBuffer,
     114             :                                            sal_uInt32 nSize)
     115             : {
     116           0 :     m_pReadBuffer = pBuffer;
     117           0 :     m_nReadBufferSize = nSize;
     118           0 :     m_nReadBufferFilled = 0;
     119           0 : }
     120             : 
     121           0 : inline bool SvDataPipe_Impl::isEOF() const
     122             : {
     123             :     return m_bEOF && m_pReadPage == m_pWritePage
     124           0 :            && (!m_pReadPage || m_pReadPage->m_pRead == m_pReadPage->m_pEnd);
     125             : }
     126             : 
     127             : inline sal_uInt32 SvDataPipe_Impl::getReadPosition() const
     128             : {
     129             :     return m_pReadPage == 0 ? 0 :
     130             :                               m_pReadPage->m_nOffset
     131             :                                   + (m_pReadPage->m_pRead
     132             :                                          - m_pReadPage->m_aBuffer);
     133             : }
     134             : 
     135             : //============================================================================
     136             : //
     137             : //  SvOutputStreamOpenLockBytes
     138             : //
     139             : //============================================================================
     140             : 
     141           0 : TYPEINIT1(SvOutputStreamOpenLockBytes, SvOpenLockBytes)
     142             : 
     143             : //============================================================================
     144             : // virtual
     145           0 : ErrCode SvOutputStreamOpenLockBytes::ReadAt(sal_uLong, void *, sal_uLong, sal_uLong *)
     146             :     const
     147             : {
     148           0 :     return ERRCODE_IO_CANTREAD;
     149             : }
     150             : 
     151             : //============================================================================
     152             : // virtual
     153           0 : ErrCode SvOutputStreamOpenLockBytes::WriteAt(sal_uLong nPos, void const * pBuffer,
     154             :                                              sal_uLong nCount, sal_uLong * pWritten)
     155             : {
     156           0 :     if (nPos != m_nPosition)
     157           0 :         return ERRCODE_IO_CANTWRITE;
     158           0 :     return FillAppend(pBuffer, nCount, pWritten);
     159             : }
     160             : 
     161             : //============================================================================
     162             : // virtual
     163           0 : ErrCode SvOutputStreamOpenLockBytes::Flush() const
     164             : {
     165           0 :     if (!m_xOutputStream.is())
     166           0 :         return ERRCODE_IO_CANTWRITE;
     167             :     try
     168             :     {
     169           0 :         m_xOutputStream->flush();
     170             :     }
     171           0 :     catch (const io::IOException&)
     172             :     {
     173           0 :         return ERRCODE_IO_CANTWRITE;
     174             :     }
     175           0 :     return ERRCODE_NONE;
     176             : }
     177             : 
     178             : //============================================================================
     179             : // virtual
     180           0 : ErrCode SvOutputStreamOpenLockBytes::SetSize(sal_uLong)
     181             : {
     182           0 :     return ERRCODE_IO_NOTSUPPORTED;
     183             : }
     184             : 
     185             : //============================================================================
     186             : // virtual
     187           0 : ErrCode SvOutputStreamOpenLockBytes::Stat(SvLockBytesStat * pStat,
     188             :                                           SvLockBytesStatFlag) const
     189             : {
     190           0 :     if (pStat)
     191           0 :         pStat->nSize = m_nPosition;
     192           0 :     return ERRCODE_NONE;
     193             : }
     194             : 
     195             : //============================================================================
     196             : // virtual
     197           0 : ErrCode SvOutputStreamOpenLockBytes::FillAppend(void const * pBuffer,
     198             :                                                 sal_uLong nCount,
     199             :                                                 sal_uLong * pWritten)
     200             : {
     201           0 :     if (!m_xOutputStream.is())
     202           0 :         return ERRCODE_IO_CANTWRITE;
     203           0 :     if (nCount > 0
     204           0 :         && nCount > std::numeric_limits< sal_uLong >::max() - m_nPosition)
     205             :     {
     206           0 :         nCount = std::numeric_limits< sal_uLong >::max() - m_nPosition;
     207           0 :         if (nCount == 0)
     208           0 :             return ERRCODE_IO_CANTWRITE;
     209             :     }
     210             :     try
     211             :     {
     212           0 :         m_xOutputStream->
     213             :             writeBytes(uno::Sequence< sal_Int8 >(
     214           0 :                            static_cast< sal_Int8 const * >(pBuffer), nCount));
     215             :     }
     216           0 :     catch (const io::IOException&)
     217             :     {
     218           0 :         return ERRCODE_IO_CANTWRITE;
     219             :     }
     220           0 :     m_nPosition += nCount;
     221           0 :     if (pWritten)
     222           0 :         *pWritten = nCount;
     223           0 :     return ERRCODE_NONE;
     224             : }
     225             : 
     226             : //============================================================================
     227             : // virtual
     228           0 : sal_uLong SvOutputStreamOpenLockBytes::Tell() const
     229             : {
     230           0 :     return m_nPosition;
     231             : }
     232             : 
     233             : //============================================================================
     234             : // virtual
     235           0 : sal_uLong SvOutputStreamOpenLockBytes::Seek(sal_uLong)
     236             : {
     237           0 :     return m_nPosition;
     238             : }
     239             : 
     240             : //============================================================================
     241             : // virtual
     242           0 : void SvOutputStreamOpenLockBytes::Terminate()
     243             : {
     244           0 :     if (m_xOutputStream.is())
     245             :     {
     246             :         try
     247             :         {
     248           0 :             m_xOutputStream->closeOutput();
     249             :         }
     250           0 :         catch (const io::IOException&)
     251             :         {
     252             :         }
     253             :     }
     254           0 : }
     255             : 
     256             : //============================================================================
     257             : //
     258             : //  SvLockBytesInputStream
     259             : //
     260             : //============================================================================
     261             : 
     262             : // virtual
     263           0 : uno::Any SAL_CALL SvLockBytesInputStream::queryInterface(uno::Type const &
     264             :                                                              rType)
     265             :     throw (uno::RuntimeException)
     266             : {
     267             :     uno::Any
     268             :         aReturn(cppu::queryInterface(rType,
     269             :                                      static_cast< io::XInputStream * >(this),
     270           0 :                                      static_cast< io::XSeekable * >(this)));
     271           0 :     return aReturn.hasValue() ? aReturn : OWeakObject::queryInterface(rType);
     272             : }
     273             : 
     274             : //============================================================================
     275             : // virtual
     276           0 : void SAL_CALL SvLockBytesInputStream::acquire() throw ()
     277             : {
     278           0 :     OWeakObject::acquire();
     279           0 : }
     280             : 
     281             : //============================================================================
     282             : // virtual
     283           0 : void SAL_CALL SvLockBytesInputStream::release() throw ()
     284             : {
     285           0 :     OWeakObject::release();
     286           0 : }
     287             : 
     288             : //============================================================================
     289             : // virtual
     290             : sal_Int32 SAL_CALL
     291           0 : SvLockBytesInputStream::readBytes(uno::Sequence< sal_Int8 > & rData,
     292             :                                   sal_Int32 nBytesToRead)
     293             :     throw (io::IOException, uno::RuntimeException)
     294             : {
     295             :     OSL_ASSERT(m_nPosition >= 0);
     296           0 :     if (!m_xLockBytes.Is())
     297           0 :         throw io::NotConnectedException();
     298           0 :     if (
     299             :          nBytesToRead < 0 ||
     300             :          (
     301             :           static_cast<sal_uInt64>(m_nPosition) > SAL_MAX_SIZE &&
     302             :           nBytesToRead > 0
     303             :          )
     304             :        )
     305             :     {
     306           0 :         throw io::IOException();
     307             :     }
     308           0 :     rData.realloc(nBytesToRead);
     309           0 :     sal_Int32 nSize = 0;
     310           0 :     while (nSize < nBytesToRead)
     311             :     {
     312             :         sal_Size nCount;
     313           0 :         ErrCode nError = m_xLockBytes->ReadAt(static_cast<sal_Size>(
     314             :                                                   m_nPosition),
     315           0 :                                               rData.getArray() + nSize,
     316           0 :                                               nBytesToRead - nSize, &nCount);
     317           0 :         if (nError != ERRCODE_NONE && nError != ERRCODE_IO_PENDING)
     318           0 :             throw io::IOException();
     319           0 :         m_nPosition += nCount;
     320           0 :         nSize += nCount;
     321           0 :         if (nError == ERRCODE_NONE && nCount == 0)
     322             :             break;
     323             :     }
     324           0 :     rData.realloc(nSize);
     325           0 :     return nSize;
     326             : }
     327             : 
     328             : //============================================================================
     329             : // virtual
     330             : sal_Int32 SAL_CALL
     331           0 : SvLockBytesInputStream::readSomeBytes(uno::Sequence< sal_Int8 > & rData,
     332             :                                       sal_Int32 nMaxBytesToRead)
     333             :     throw (io::IOException, uno::RuntimeException)
     334             : {
     335             :     OSL_ASSERT(m_nPosition >= 0);
     336           0 :     if (!m_xLockBytes.Is())
     337           0 :         throw io::NotConnectedException();
     338           0 :     if (static_cast<sal_uInt64>(m_nPosition) > SAL_MAX_SIZE
     339             :         && nMaxBytesToRead > 0)
     340           0 :         throw io::IOException();
     341           0 :     rData.realloc(nMaxBytesToRead);
     342           0 :     sal_Size nCount = 0;
     343           0 :     if (nMaxBytesToRead > 0)
     344             :     {
     345             :         ErrCode nError;
     346           0 :         do
     347             :         {
     348           0 :             nError = m_xLockBytes->ReadAt(static_cast<sal_Size>(m_nPosition),
     349           0 :                                           rData.getArray(),
     350             :                                           nMaxBytesToRead < 0 ?
     351             :                                               0 : nMaxBytesToRead,
     352           0 :                                           &nCount);
     353           0 :             if (nError != ERRCODE_NONE && nError != ERRCODE_IO_PENDING)
     354           0 :                 throw io::IOException();
     355           0 :             m_nPosition += nCount;
     356             :         }
     357             :         while (nCount == 0 && nError == ERRCODE_IO_PENDING);
     358             :     }
     359           0 :     rData.realloc(sal_Int32(nCount));
     360           0 :     return sal_Int32(nCount);
     361             : }
     362             : 
     363             : //============================================================================
     364             : // virtual
     365           0 : void SAL_CALL SvLockBytesInputStream::skipBytes(sal_Int32 nBytesToSkip)
     366             :     throw (io::IOException, uno::RuntimeException)
     367             : {
     368           0 :     if (!m_xLockBytes.Is())
     369           0 :         throw io::NotConnectedException();
     370           0 :     if (nBytesToSkip < 0)
     371           0 :         throw io::IOException();
     372           0 :     if (nBytesToSkip > SAL_MAX_INT64 - m_nPosition)
     373           0 :         throw io::BufferSizeExceededException();
     374           0 :     m_nPosition += nBytesToSkip;
     375           0 : }
     376             : 
     377             : //============================================================================
     378             : // virtual
     379           0 : sal_Int32 SAL_CALL SvLockBytesInputStream::available()
     380             :     throw (io::IOException, uno::RuntimeException)
     381             : {
     382             :     OSL_ASSERT(m_nPosition >= 0);
     383           0 :     if (!m_xLockBytes.Is())
     384           0 :         throw io::NotConnectedException();
     385           0 :     SvLockBytesStat aStat;
     386           0 :     if (m_xLockBytes->Stat(&aStat, SVSTATFLAG_DEFAULT) != ERRCODE_NONE)
     387           0 :         throw io::IOException();
     388             :     return aStat.nSize <= static_cast<sal_uInt64>(m_nPosition) ?
     389             :                0 :
     390             :            static_cast<sal_Size>(aStat.nSize - m_nPosition) <=
     391             :                    static_cast<sal_uInt32>(SAL_MAX_INT32) ?
     392             :                static_cast<sal_Int32>(aStat.nSize - m_nPosition) :
     393           0 :                SAL_MAX_INT32;
     394             : }
     395             : 
     396             : //============================================================================
     397             : // virtual
     398           0 : void SAL_CALL SvLockBytesInputStream::closeInput()
     399             :     throw (io::IOException, uno::RuntimeException)
     400             : {
     401           0 :     if (!m_xLockBytes.Is())
     402           0 :         throw io::NotConnectedException();
     403           0 :     m_xLockBytes = 0;
     404           0 : }
     405             : 
     406             : //============================================================================
     407             : // virtual
     408           0 : void SAL_CALL SvLockBytesInputStream::seek(sal_Int64 nLocation)
     409             :     throw (lang::IllegalArgumentException, io::IOException,
     410             :            uno::RuntimeException)
     411             : {
     412           0 :     if (nLocation < 0)
     413           0 :         throw lang::IllegalArgumentException();
     414           0 :     if (!m_xLockBytes.Is())
     415           0 :         throw io::NotConnectedException();
     416           0 :     m_nPosition = nLocation;
     417           0 : }
     418             : 
     419             : //============================================================================
     420             : // virtual
     421           0 : sal_Int64 SAL_CALL SvLockBytesInputStream::getPosition()
     422             :     throw (io::IOException, uno::RuntimeException)
     423             : {
     424           0 :     if (!m_xLockBytes.Is())
     425           0 :         throw io::NotConnectedException();
     426           0 :     return m_nPosition;
     427             : }
     428             : 
     429             : //============================================================================
     430             : // virtual
     431           0 : sal_Int64 SAL_CALL SvLockBytesInputStream::getLength()
     432             :     throw (io::IOException, uno::RuntimeException)
     433             : {
     434           0 :     if (!m_xLockBytes.Is())
     435           0 :         throw io::NotConnectedException();
     436           0 :     SvLockBytesStat aStat;
     437           0 :     if (m_xLockBytes->Stat(&aStat, SVSTATFLAG_DEFAULT) != ERRCODE_NONE)
     438           0 :         throw io::IOException();
     439             : #if SAL_TYPES_SIZEOFPOINTER > 4 // avoid warnings if sal_Size < sal_Int64
     440             :     if (aStat.nSize > static_cast<sal_uInt64>(SAL_MAX_INT64))
     441             :         throw io::IOException();
     442             : #endif
     443           0 :     return aStat.nSize;
     444             : }
     445             : 
     446             : //============================================================================
     447             : //
     448             : //  SvInputStream
     449             : //
     450             : //============================================================================
     451             : 
     452           0 : bool SvInputStream::open()
     453             : {
     454           0 :     if (GetError() != ERRCODE_NONE)
     455           0 :         return false;
     456           0 :     if (!(m_xSeekable.is() || m_pPipe))
     457             :     {
     458           0 :         if (!m_xStream.is())
     459             :         {
     460           0 :             SetError(ERRCODE_IO_INVALIDDEVICE);
     461           0 :             return false;
     462             :         }
     463             :         m_xSeekable
     464           0 :             = uno::Reference< io::XSeekable >(m_xStream, uno::UNO_QUERY);
     465           0 :         if (!m_xSeekable.is())
     466           0 :             m_pPipe = new SvDataPipe_Impl;
     467             :     }
     468           0 :     return true;
     469             : }
     470             : 
     471             : //============================================================================
     472             : // virtual
     473           0 : sal_uLong SvInputStream::GetData(void * pData, sal_uLong nSize)
     474             : {
     475           0 :     if (!open())
     476             :     {
     477           0 :         SetError(ERRCODE_IO_CANTREAD);
     478           0 :         return 0;
     479             :     }
     480           0 :     sal_uInt32 nRead = 0;
     481           0 :     if (m_xSeekable.is())
     482             :     {
     483           0 :         if (m_nSeekedFrom != STREAM_SEEK_TO_END)
     484             :         {
     485             :             try
     486             :             {
     487           0 :                 m_xSeekable->seek(m_nSeekedFrom);
     488             :             }
     489           0 :             catch (const io::IOException&)
     490             :             {
     491           0 :                 SetError(ERRCODE_IO_CANTREAD);
     492           0 :                 return 0;
     493             :             }
     494           0 :             m_nSeekedFrom = STREAM_SEEK_TO_END;
     495             :         }
     496           0 :         for (;;)
     497             :         {
     498             :             sal_Int32 nRemain
     499             :                 = sal_Int32(
     500             :                     std::min(sal_uLong(nSize - nRead),
     501           0 :                              sal_uLong(std::numeric_limits< sal_Int32 >::max())));
     502           0 :             if (nRemain == 0)
     503             :                 break;
     504           0 :             uno::Sequence< sal_Int8 > aBuffer;
     505             :             sal_Int32 nCount;
     506             :             try
     507             :             {
     508           0 :                 nCount = m_xStream->readBytes(aBuffer, nRemain);
     509             :             }
     510           0 :             catch (const io::IOException&)
     511             :             {
     512           0 :                 SetError(ERRCODE_IO_CANTREAD);
     513           0 :                 return nRead;
     514             :             }
     515           0 :             memcpy(static_cast< sal_Int8 * >(pData) + nRead,
     516           0 :                            aBuffer.getConstArray(), sal_uInt32(nCount));
     517           0 :             nRead += nCount;
     518           0 :             if (nCount < nRemain)
     519             :                 break;
     520           0 :         }
     521             :     }
     522             :     else
     523             :     {
     524           0 :         if (m_nSeekedFrom != STREAM_SEEK_TO_END)
     525             :         {
     526           0 :             SetError(ERRCODE_IO_CANTREAD);
     527           0 :             return 0;
     528             :         }
     529           0 :         m_pPipe->setReadBuffer(static_cast< sal_Int8 * >(pData), nSize);
     530           0 :         nRead = m_pPipe->read();
     531           0 :         if (nRead < nSize && !m_pPipe->isEOF())
     532           0 :             for (;;)
     533             :             {
     534             :                 sal_Int32 nRemain
     535             :                     = sal_Int32(
     536             :                         std::min(
     537             :                             sal_uLong(nSize - nRead),
     538           0 :                             sal_uLong(std::numeric_limits< sal_Int32 >::max())));
     539           0 :                 if (nRemain == 0)
     540             :                     break;
     541           0 :                 uno::Sequence< sal_Int8 > aBuffer;
     542             :                 sal_Int32 nCount;
     543             :                 try
     544             :                 {
     545           0 :                     nCount = m_xStream->readBytes(aBuffer, nRemain);
     546             :                 }
     547           0 :                 catch (const io::IOException&)
     548             :                 {
     549           0 :                     SetError(ERRCODE_IO_CANTREAD);
     550             :                     break;
     551             :                 }
     552           0 :                 m_pPipe->write(aBuffer.getConstArray(), sal_uInt32(nCount));
     553           0 :                 nRead += m_pPipe->read();
     554           0 :                 if (nCount < nRemain)
     555             :                 {
     556           0 :                     m_xStream->closeInput();
     557           0 :                     m_pPipe->setEOF();
     558             :                     break;
     559             :                 }
     560           0 :             }
     561           0 :         m_pPipe->clearReadBuffer();
     562             :     }
     563           0 :     return nRead;
     564             : }
     565             : 
     566             : //============================================================================
     567             : // virtual
     568           0 : sal_uLong SvInputStream::PutData(void const *, sal_uLong)
     569             : {
     570           0 :     SetError(ERRCODE_IO_NOTSUPPORTED);
     571           0 :     return 0;
     572             : }
     573             : 
     574             : //============================================================================
     575             : // virtual
     576           0 : void SvInputStream::FlushData()
     577           0 : {}
     578             : 
     579             : //============================================================================
     580             : // virtual
     581           0 : sal_uLong SvInputStream::SeekPos(sal_uLong nPos)
     582             : {
     583           0 :     if (open())
     584             :     {
     585           0 :         if (nPos == STREAM_SEEK_TO_END)
     586             :         {
     587           0 :             if (m_nSeekedFrom == STREAM_SEEK_TO_END)
     588             :             {
     589           0 :                 if (m_xSeekable.is())
     590             :                     try
     591             :                     {
     592           0 :                         sal_Int64 nLength = m_xSeekable->getLength();
     593             :                         OSL_ASSERT(nLength >= 0);
     594           0 :                         if (static_cast<sal_uInt64>(nLength)
     595             :                             < STREAM_SEEK_TO_END)
     596             :                         {
     597           0 :                             m_nSeekedFrom = Tell();
     598           0 :                             return sal_uLong(nLength);
     599             :                         }
     600             :                     }
     601           0 :                     catch (const io::IOException&)
     602             :                     {
     603             :                     }
     604             :                 else
     605           0 :                     return Tell(); //@@@
     606             :             }
     607             :             else
     608           0 :                 return Tell();
     609             :         }
     610           0 :         else if (nPos == m_nSeekedFrom)
     611             :         {
     612           0 :             m_nSeekedFrom = STREAM_SEEK_TO_END;
     613           0 :             return nPos;
     614             :         }
     615           0 :         else if (m_xSeekable.is())
     616             :         {
     617             :             try
     618             :             {
     619           0 :                 m_xSeekable->seek(nPos);
     620           0 :                 m_nSeekedFrom = STREAM_SEEK_TO_END;
     621           0 :                 return nPos;
     622             :             }
     623           0 :             catch (const io::IOException&)
     624             :             {
     625             :             }
     626             :         }
     627           0 :         else if (m_pPipe->setReadPosition(nPos) == SvDataPipe_Impl::SEEK_OK)
     628             :         {
     629           0 :             m_nSeekedFrom = STREAM_SEEK_TO_END;
     630           0 :             return nPos;
     631             :         }
     632           0 :         else if ( nPos > Tell() )
     633             :         {
     634             :             // Read out the bytes
     635           0 :             sal_Int32 nRead = nPos - Tell();
     636           0 :             uno::Sequence< sal_Int8 > aBuffer;
     637           0 :             m_xStream->readBytes( aBuffer, nRead );
     638           0 :             return nPos;
     639             :         }
     640           0 :         else if ( nPos == Tell() )
     641           0 :             return nPos;
     642             :     }
     643           0 :     SetError(ERRCODE_IO_CANTSEEK);
     644           0 :     return Tell();
     645             : }
     646             : 
     647             : //============================================================================
     648             : // virtual
     649           0 : void SvInputStream::SetSize(sal_uLong)
     650             : {
     651           0 :     SetError(ERRCODE_IO_NOTSUPPORTED);
     652           0 : }
     653             : 
     654             : //============================================================================
     655           0 : SvInputStream::SvInputStream(
     656             :         com::sun::star::uno::Reference< com::sun::star::io::XInputStream >
     657             :                 const &
     658             :             rTheStream):
     659             :     m_xStream(rTheStream),
     660             :     m_pPipe(0),
     661           0 :     m_nSeekedFrom(STREAM_SEEK_TO_END)
     662             : {
     663           0 :     SetBufferSize(0);
     664           0 : }
     665             : 
     666             : //============================================================================
     667             : // virtual
     668           0 : SvInputStream::~SvInputStream()
     669             : {
     670           0 :     if (m_xStream.is())
     671             :     {
     672             :         try
     673             :         {
     674           0 :             m_xStream->closeInput();
     675             :         }
     676           0 :         catch (const io::IOException&)
     677             :         {
     678             :         }
     679             :     }
     680           0 :     delete m_pPipe;
     681           0 : }
     682             : 
     683             : //============================================================================
     684             : // virtual
     685           0 : sal_uInt16 SvInputStream::IsA() const
     686             : {
     687           0 :     return 0;
     688             : }
     689             : 
     690             : //============================================================================
     691             : // virtual
     692           0 : void SvInputStream::AddMark(sal_uLong nPos)
     693             : {
     694           0 :     if (open() && m_pPipe)
     695           0 :         m_pPipe->addMark(nPos);
     696           0 : }
     697             : 
     698             : //============================================================================
     699             : // virtual
     700           0 : void SvInputStream::RemoveMark(sal_uLong nPos)
     701             : {
     702           0 :     if (open() && m_pPipe)
     703           0 :         m_pPipe->removeMark(nPos);
     704           0 : }
     705             : 
     706             : //============================================================================
     707             : //
     708             : //  SvOutputStream
     709             : //
     710             : //============================================================================
     711             : 
     712             : // virtual
     713           0 : sal_uLong SvOutputStream::GetData(void *, sal_uLong)
     714             : {
     715           0 :     SetError(ERRCODE_IO_NOTSUPPORTED);
     716           0 :     return 0;
     717             : }
     718             : 
     719             : //============================================================================
     720             : // virtual
     721           0 : sal_uLong SvOutputStream::PutData(void const * pData, sal_uLong nSize)
     722             : {
     723           0 :     if (!m_xStream.is())
     724             :     {
     725           0 :         SetError(ERRCODE_IO_CANTWRITE);
     726           0 :         return 0;
     727             :     }
     728           0 :     sal_uLong nWritten = 0;
     729           0 :     for (;;)
     730             :     {
     731             :         sal_Int32 nRemain
     732             :             = sal_Int32(
     733             :                 std::min(sal_uLong(nSize - nWritten),
     734           0 :                          sal_uLong(std::numeric_limits< sal_Int32 >::max())));
     735           0 :         if (nRemain == 0)
     736           0 :             break;
     737             :         try
     738             :         {
     739           0 :             m_xStream->writeBytes(uno::Sequence< sal_Int8 >(
     740             :                                       static_cast<const sal_Int8 * >(pData)
     741             :                                           + nWritten,
     742           0 :                                       nRemain));
     743             :         }
     744           0 :         catch (const io::IOException&)
     745             :         {
     746           0 :             SetError(ERRCODE_IO_CANTWRITE);
     747             :             break;
     748             :         }
     749           0 :         nWritten += nRemain;
     750             :     }
     751           0 :     return nWritten;
     752             : }
     753             : 
     754             : //============================================================================
     755             : // virtual
     756           0 : sal_uLong SvOutputStream::SeekPos(sal_uLong)
     757             : {
     758           0 :     SetError(ERRCODE_IO_NOTSUPPORTED);
     759           0 :     return 0;
     760             : }
     761             : 
     762             : //============================================================================
     763             : // virtual
     764           0 : void SvOutputStream::FlushData()
     765             : {
     766           0 :     if (!m_xStream.is())
     767             :     {
     768           0 :         SetError(ERRCODE_IO_INVALIDDEVICE);
     769           0 :         return;
     770             :     }
     771             :     try
     772             :     {
     773           0 :         m_xStream->flush();
     774             :     }
     775           0 :     catch (const io::IOException&)
     776             :     {
     777             :     }
     778             : }
     779             : 
     780             : //============================================================================
     781             : // virtual
     782           0 : void SvOutputStream::SetSize(sal_uLong)
     783             : {
     784           0 :     SetError(ERRCODE_IO_NOTSUPPORTED);
     785           0 : }
     786             : 
     787             : //============================================================================
     788           0 : SvOutputStream::SvOutputStream(uno::Reference< io::XOutputStream > const &
     789             :                                    rTheStream):
     790           0 :     m_xStream(rTheStream)
     791             : {
     792           0 :     SetBufferSize(0);
     793           0 : }
     794             : 
     795             : //============================================================================
     796             : // virtual
     797           0 : SvOutputStream::~SvOutputStream()
     798             : {
     799           0 :     if (m_xStream.is())
     800             :     {
     801             :         try
     802             :         {
     803           0 :             m_xStream->closeOutput();
     804             :         }
     805           0 :         catch (const io::IOException&)
     806             :         {
     807             :         }
     808             :     }
     809           0 : }
     810             : 
     811             : //============================================================================
     812             : // virtual
     813           0 : sal_uInt16 SvOutputStream::IsA() const
     814             : {
     815           0 :     return 0;
     816             : }
     817             : 
     818             : //============================================================================
     819             : //
     820             : //  SvDataPipe_Impl
     821             : //
     822             : //============================================================================
     823             : 
     824           0 : bool SvDataPipe_Impl::remove(Page * pPage)
     825             : {
     826           0 :     if (
     827             :         pPage != m_pFirstPage ||
     828             :         m_pReadPage == m_pFirstPage ||
     829             :         (
     830           0 :          !m_aMarks.empty() &&
     831           0 :          *m_aMarks.begin() < m_pFirstPage->m_nOffset + m_nPageSize
     832             :         )
     833             :        )
     834             :     {
     835           0 :         return false;
     836             :     }
     837             : 
     838           0 :     m_pFirstPage = m_pFirstPage->m_pNext;
     839             : 
     840           0 :     if (m_nPages <= m_nMinPages)
     841           0 :         return true;
     842             : 
     843           0 :     pPage->m_pPrev->m_pNext = pPage->m_pNext;
     844           0 :     pPage->m_pNext->m_pPrev = pPage->m_pPrev;
     845           0 :     rtl_freeMemory(pPage);
     846           0 :     --m_nPages;
     847             : 
     848           0 :     return true;
     849             : }
     850             : 
     851             : //============================================================================
     852           0 : SvDataPipe_Impl::~SvDataPipe_Impl()
     853             : {
     854           0 :     if (m_pFirstPage != 0)
     855           0 :         for (Page * pPage = m_pFirstPage;;)
     856             :         {
     857           0 :             Page * pNext = pPage->m_pNext;
     858           0 :             rtl_freeMemory(pPage);
     859           0 :             if (pNext == m_pFirstPage)
     860           0 :                 break;
     861           0 :             pPage = pNext;
     862             :         }
     863           0 : }
     864             : 
     865             : //============================================================================
     866           0 : sal_uInt32 SvDataPipe_Impl::read()
     867             : {
     868           0 :     if (m_pReadBuffer == 0 || m_nReadBufferSize == 0 || m_pReadPage == 0)
     869           0 :         return 0;
     870             : 
     871           0 :     sal_uInt32 nSize = m_nReadBufferSize;
     872           0 :     sal_uInt32 nRemain = m_nReadBufferSize - m_nReadBufferFilled;
     873             : 
     874           0 :     m_pReadBuffer += m_nReadBufferFilled;
     875           0 :     m_nReadBufferSize -= m_nReadBufferFilled;
     876           0 :     m_nReadBufferFilled = 0;
     877             : 
     878           0 :     while (nRemain > 0)
     879             :     {
     880             :         sal_uInt32 nBlock = std::min(sal_uInt32(m_pReadPage->m_pEnd
     881             :                                                     - m_pReadPage->m_pRead),
     882           0 :                                      nRemain);
     883           0 :         memcpy(m_pReadBuffer, m_pReadPage->m_pRead, nBlock);
     884           0 :         m_pReadPage->m_pRead += nBlock;
     885           0 :         m_pReadBuffer += nBlock;
     886           0 :         m_nReadBufferSize -= nBlock;
     887           0 :         m_nReadBufferFilled = 0;
     888           0 :         nRemain -= nBlock;
     889             : 
     890           0 :         if (m_pReadPage == m_pWritePage)
     891           0 :             break;
     892             : 
     893           0 :         if (m_pReadPage->m_pRead == m_pReadPage->m_pEnd)
     894             :         {
     895           0 :             Page * pRemove = m_pReadPage;
     896           0 :             m_pReadPage = pRemove->m_pNext;
     897           0 :             remove(pRemove);
     898             :         }
     899             :     }
     900             : 
     901           0 :     return nSize - nRemain;
     902             : }
     903             : 
     904             : //============================================================================
     905           0 : sal_uInt32 SvDataPipe_Impl::write(sal_Int8 const * pBuffer, sal_uInt32 nSize)
     906             : {
     907           0 :     if (nSize == 0)
     908           0 :         return 0;
     909             : 
     910           0 :     if (m_pWritePage == 0)
     911             :     {
     912             :         m_pFirstPage
     913             :             = static_cast< Page * >(rtl_allocateMemory(sizeof (Page)
     914             :                                                            + m_nPageSize
     915           0 :                                                            - 1));
     916           0 :         m_pFirstPage->m_pPrev = m_pFirstPage;
     917           0 :         m_pFirstPage->m_pNext = m_pFirstPage;
     918           0 :         m_pFirstPage->m_pStart = m_pFirstPage->m_aBuffer;
     919           0 :         m_pFirstPage->m_pRead = m_pFirstPage->m_aBuffer;
     920           0 :         m_pFirstPage->m_pEnd = m_pFirstPage->m_aBuffer;
     921           0 :         m_pFirstPage->m_nOffset = 0;
     922           0 :         m_pReadPage = m_pFirstPage;
     923           0 :         m_pWritePage = m_pFirstPage;
     924           0 :         ++m_nPages;
     925             :     }
     926             : 
     927           0 :     sal_uInt32 nRemain = nSize;
     928             : 
     929           0 :     if (m_pReadBuffer != 0 && m_pReadPage == m_pWritePage
     930             :         && m_pReadPage->m_pRead == m_pWritePage->m_pEnd)
     931             :     {
     932             :         sal_uInt32 nBlock = std::min(nRemain,
     933             :                                      sal_uInt32(m_nReadBufferSize
     934           0 :                                                     - m_nReadBufferFilled));
     935             :         sal_uInt32 nPosition = m_pWritePage->m_nOffset
     936             :                                    + (m_pWritePage->m_pEnd
     937           0 :                                           - m_pWritePage->m_aBuffer);
     938           0 :         if (!m_aMarks.empty())
     939           0 :             nBlock = *m_aMarks.begin() > nPosition ?
     940           0 :                          std::min(nBlock, sal_uInt32(*m_aMarks.begin()
     941           0 :                                                          - nPosition)) :
     942           0 :                          0;
     943             : 
     944           0 :         if (nBlock > 0)
     945             :         {
     946           0 :             memcpy(m_pReadBuffer + m_nReadBufferFilled, pBuffer,
     947           0 :                            nBlock);
     948           0 :             m_nReadBufferFilled += nBlock;
     949           0 :             nRemain -= nBlock;
     950             : 
     951           0 :             nPosition += nBlock;
     952           0 :             m_pWritePage->m_nOffset = (nPosition / m_nPageSize) * m_nPageSize;
     953             :             m_pWritePage->m_pStart = m_pWritePage->m_aBuffer
     954           0 :                                          + nPosition % m_nPageSize;
     955           0 :             m_pWritePage->m_pRead = m_pWritePage->m_pStart;
     956           0 :             m_pWritePage->m_pEnd = m_pWritePage->m_pStart;
     957             :         }
     958             :     }
     959             : 
     960           0 :     if (nRemain > 0)
     961           0 :         for (;;)
     962             :         {
     963             :             sal_uInt32 nBlock
     964           0 :                 = std::min(sal_uInt32(m_pWritePage->m_aBuffer + m_nPageSize
     965             :                                           - m_pWritePage->m_pEnd),
     966           0 :                            nRemain);
     967           0 :             memcpy(m_pWritePage->m_pEnd, pBuffer, nBlock);
     968           0 :             m_pWritePage->m_pEnd += nBlock;
     969           0 :             pBuffer += nBlock;
     970           0 :             nRemain -= nBlock;
     971             : 
     972           0 :             if (nRemain == 0)
     973           0 :                 break;
     974             : 
     975           0 :             if (m_pWritePage->m_pNext == m_pFirstPage)
     976             :             {
     977           0 :                 if (m_nPages == m_nMaxPages)
     978           0 :                     break;
     979             : 
     980             :                 Page * pNew
     981             :                     = static_cast< Page * >(rtl_allocateMemory(
     982             :                                                 sizeof (Page) + m_nPageSize
     983           0 :                                                     - 1));
     984           0 :                 pNew->m_pPrev = m_pWritePage;
     985           0 :                 pNew->m_pNext = m_pWritePage->m_pNext;
     986             : 
     987           0 :                 m_pWritePage->m_pNext->m_pPrev = pNew;
     988           0 :                 m_pWritePage->m_pNext = pNew;
     989           0 :                 ++m_nPages;
     990             :             }
     991             : 
     992             :             m_pWritePage->m_pNext->m_nOffset = m_pWritePage->m_nOffset
     993           0 :                                                    + m_nPageSize;
     994           0 :             m_pWritePage = m_pWritePage->m_pNext;
     995           0 :             m_pWritePage->m_pStart = m_pWritePage->m_aBuffer;
     996           0 :             m_pWritePage->m_pRead = m_pWritePage->m_aBuffer;
     997           0 :             m_pWritePage->m_pEnd = m_pWritePage->m_aBuffer;
     998             :         }
     999             : 
    1000           0 :     return nSize - nRemain;
    1001             : }
    1002             : 
    1003             : //============================================================================
    1004           0 : bool SvDataPipe_Impl::addMark(sal_uInt32 nPosition)
    1005             : {
    1006           0 :     if (m_pFirstPage != 0 && m_pFirstPage->m_nOffset > nPosition)
    1007           0 :         return false;
    1008           0 :     m_aMarks.insert(nPosition);
    1009           0 :     return true;
    1010             : }
    1011             : 
    1012             : //============================================================================
    1013           0 : bool SvDataPipe_Impl::removeMark(sal_uInt32 nPosition)
    1014             : {
    1015           0 :     std::multiset< sal_uInt32 >::iterator t = m_aMarks.find(nPosition);
    1016           0 :     if (t == m_aMarks.end())
    1017           0 :         return false;
    1018           0 :     m_aMarks.erase(t);
    1019           0 :     while (remove(m_pFirstPage)) ;
    1020           0 :     return true;
    1021             : }
    1022             : 
    1023             : //============================================================================
    1024           0 : SvDataPipe_Impl::SeekResult SvDataPipe_Impl::setReadPosition(sal_uInt32
    1025             :                                                                  nPosition)
    1026             : {
    1027           0 :     if (m_pFirstPage == 0)
    1028           0 :         return nPosition == 0 ? SEEK_OK : SEEK_PAST_END;
    1029             : 
    1030           0 :     if (nPosition
    1031             :             <= m_pReadPage->m_nOffset
    1032             :                    + (m_pReadPage->m_pRead - m_pReadPage->m_aBuffer))
    1033             :     {
    1034           0 :         if (nPosition
    1035             :                 < m_pFirstPage->m_nOffset
    1036             :                       + (m_pFirstPage->m_pStart - m_pFirstPage->m_aBuffer))
    1037           0 :             return SEEK_BEFORE_MARKED;
    1038             : 
    1039           0 :         while (nPosition < m_pReadPage->m_nOffset)
    1040             :         {
    1041           0 :             m_pReadPage->m_pRead = m_pReadPage->m_pStart;
    1042           0 :             m_pReadPage = m_pReadPage->m_pPrev;
    1043             :         }
    1044             :     }
    1045             :     else
    1046             :     {
    1047           0 :         if (nPosition
    1048             :                 > m_pWritePage->m_nOffset
    1049             :                       + (m_pWritePage->m_pEnd - m_pWritePage->m_aBuffer))
    1050           0 :             return SEEK_PAST_END;
    1051             : 
    1052           0 :         while (m_pReadPage != m_pWritePage
    1053             :                && nPosition >= m_pReadPage->m_nOffset + m_nPageSize)
    1054             :         {
    1055           0 :             Page * pRemove = m_pReadPage;
    1056           0 :             m_pReadPage = pRemove->m_pNext;
    1057           0 :             remove(pRemove);
    1058             :         }
    1059             :     }
    1060             : 
    1061             :     m_pReadPage->m_pRead = m_pReadPage->m_aBuffer
    1062           0 :                                + (nPosition - m_pReadPage->m_nOffset);
    1063           0 :     return SEEK_OK;
    1064             : }
    1065             : 
    1066             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10