LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/writerperfect/source/common - WPXSvStream.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 49 128 38.3 %
Date: 2013-07-09 Functions: 13 25 52.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             : 
      10             : #include "WPXSvStream.hxx"
      11             : #include <tools/stream.hxx>
      12             : #include <unotools/streamwrap.hxx>
      13             : #include <unotools/ucbstreamhelper.hxx>
      14             : #include <limits>
      15             : #include <vector>
      16             : 
      17             : using namespace ::com::sun::star::uno;
      18             : using namespace ::com::sun::star::io;
      19             : 
      20             : namespace
      21             : {
      22           0 : static void splitPath( std::vector<OUString> &rElems, const OUString &rPath )
      23             : {
      24           0 :     for (sal_Int32 i = 0; i >= 0;)
      25           0 :         rElems.push_back( rPath.getToken( 0, '/', i ) );
      26           0 : }
      27             : 
      28             : } // anonymous namespace
      29             : 
      30             : typedef struct
      31           0 : {
      32             :     SotStorageRef ref;
      33           0 : } SotStorageRefWrapper;
      34             : 
      35             : typedef struct
      36           0 : {
      37             :     SotStorageStreamRef ref;
      38           0 : } SotStorageStreamRefWrapper;
      39             : 
      40             : class WPXSvInputStreamImpl : public WPXInputStream
      41             : {
      42             : public :
      43             :     WPXSvInputStreamImpl( ::com::sun::star::uno::Reference<
      44             :                       ::com::sun::star::io::XInputStream > xStream );
      45             :     ~WPXSvInputStreamImpl();
      46             : 
      47             :     bool isOLEStream();
      48             :     WPXInputStream * getDocumentOLEStream(const char *name);
      49             : 
      50             :     const unsigned char *read(unsigned long numBytes, unsigned long &numBytesRead);
      51             :     int seek(long offset, WPX_SEEK_TYPE seekType);
      52             :     long tell();
      53             :     bool atEOS();
      54             : private:
      55             :     ::std::vector< SotStorageRefWrapper > mxChildrenStorages;
      56             :     ::std::vector< SotStorageStreamRefWrapper > mxChildrenStreams;
      57             :     ::com::sun::star::uno::Reference<
      58             :             ::com::sun::star::io::XInputStream > mxStream;
      59             :     ::com::sun::star::uno::Reference<
      60             :             ::com::sun::star::io::XSeekable > mxSeekable;
      61             :     ::com::sun::star::uno::Sequence< sal_Int8 > maData;
      62             :     sal_Int64 mnLength;
      63             : };
      64             : 
      65          72 : WPXSvInputStreamImpl::WPXSvInputStreamImpl( Reference< XInputStream > xStream ) :
      66             :     WPXInputStream(),
      67             :     mxChildrenStorages(),
      68             :     mxChildrenStreams(),
      69             :     mxStream(xStream),
      70             :     mxSeekable(xStream, UNO_QUERY),
      71          72 :     maData(0)
      72             : {
      73          72 :     if (!xStream.is() || !mxStream.is())
      74           0 :         mnLength = 0;
      75             :     else
      76             :     {
      77          72 :         if (!mxSeekable.is())
      78           0 :             mnLength = 0;
      79             :         else
      80             :         {
      81             :             try
      82             :             {
      83          72 :                 mnLength = mxSeekable->getLength();
      84             :             }
      85           0 :             catch ( ... )
      86             :             {
      87             :                 SAL_WARN("writerperfect", "mnLength = mxSeekable->getLength() threw exception");
      88           0 :                 mnLength = 0;
      89             :             }
      90             :         }
      91             :     }
      92          72 : }
      93             : 
      94         144 : WPXSvInputStreamImpl::~WPXSvInputStreamImpl()
      95             : {
      96         144 : }
      97             : 
      98        1584 : const unsigned char *WPXSvInputStreamImpl::read(unsigned long numBytes, unsigned long &numBytesRead)
      99             : {
     100        1584 :     numBytesRead = 0;
     101             : 
     102        1584 :     if (numBytes == 0 || atEOS())
     103           0 :         return 0;
     104             : 
     105        1584 :     numBytesRead = mxStream->readSomeBytes (maData, numBytes);
     106        1584 :     if (numBytesRead == 0)
     107           0 :         return 0;
     108             : 
     109        1584 :     return (const unsigned char *)maData.getConstArray();
     110             : }
     111             : 
     112        1494 : long WPXSvInputStreamImpl::tell()
     113             : {
     114        1494 :     if ((mnLength == 0) || !mxStream.is() || !mxSeekable.is())
     115           0 :         return -1L;
     116             :     else
     117             :     {
     118        1494 :         sal_Int64 tmpPosition = mxSeekable->getPosition();
     119        1494 :         if ((tmpPosition < 0) || (tmpPosition > (std::numeric_limits<long>::max)()))
     120           0 :             return -1L;
     121        1494 :         return (long)tmpPosition;
     122             :     }
     123             : }
     124             : 
     125        2070 : int WPXSvInputStreamImpl::seek(long offset, WPX_SEEK_TYPE seekType)
     126             : {
     127        2070 :     if ((mnLength == 0) || !mxStream.is() || !mxSeekable.is())
     128           0 :         return -1;
     129             : 
     130        2070 :     sal_Int64 tmpPosition = mxSeekable->getPosition();
     131        2070 :     if ((tmpPosition < 0) || (tmpPosition > (std::numeric_limits<long>::max)()))
     132           0 :         return -1;
     133             : 
     134        2070 :     sal_Int64 tmpOffset = offset;
     135        2070 :     if (seekType == WPX_SEEK_CUR)
     136           0 :         tmpOffset += tmpPosition;
     137             : #if defined(LIBWPD_STREAM_VERSION_MAJOR) && defined(LIBWPD_STREAM_VERSION_MINOR) && defined(LIBWPD_STREAM_VERSION_REVISION) \
     138             :     && (LIBWPD_STREAM_VERSION_MAJOR > 0 || (LIBWPD_STREAM_VERSION_MAJOR == 0 && (LIBWPD_STREAM_VERSION_MINOR > 9 \
     139             :     || (LIBWPD_STREAM_VERSION_MINOR == 9 && LIBWPD_STREAM_VERSION_REVISION >= 5))))
     140             :     if (seekType == WPX_SEEK_END)
     141             :         tmpOffset += mnLength;
     142             : #endif
     143             : 
     144        2070 :     int retVal = 0;
     145        2070 :     if (tmpOffset < 0)
     146             :     {
     147           0 :         tmpOffset = 0;
     148           0 :         retVal = -1;
     149             :     }
     150        2070 :     if (offset > mnLength)
     151             :     {
     152          72 :         tmpOffset = mnLength;
     153          72 :         retVal = -1;
     154             :     }
     155             : 
     156             :     try
     157             :     {
     158        2070 :         mxSeekable->seek(tmpOffset);
     159        2070 :         return retVal;
     160             :     }
     161           0 :     catch (...)
     162             :     {
     163             :         SAL_WARN("writerperfect", "mxSeekable->seek(offset) threw exception");
     164           0 :         return -1;
     165             :     }
     166             : }
     167             : 
     168        4590 : bool WPXSvInputStreamImpl::atEOS()
     169             : {
     170        4590 :     if ((mnLength == 0) || !mxStream.is() || !mxSeekable.is())
     171           0 :         return true;
     172        4590 :     return (mxSeekable->getPosition() >= mnLength);
     173             : }
     174             : 
     175           0 : bool WPXSvInputStreamImpl::isOLEStream()
     176             : {
     177           0 :     if ((mnLength == 0) || !mxStream.is() || !mxSeekable.is())
     178           0 :         return false;
     179             : 
     180           0 :     sal_Int64 tmpPosition = mxSeekable->getPosition();
     181           0 :     mxSeekable->seek(0);
     182             : 
     183           0 :     SvStream *pStream = utl::UcbStreamHelper::CreateStream( mxStream );
     184           0 :     bool bAns = pStream && SotStorage::IsOLEStorage( pStream );
     185           0 :     if (pStream)
     186           0 :         delete pStream;
     187             : 
     188           0 :     mxSeekable->seek(tmpPosition);
     189             : 
     190           0 :     return bAns;
     191             : }
     192             : 
     193           0 : WPXInputStream *WPXSvInputStreamImpl::getDocumentOLEStream(const char *name)
     194             : {
     195           0 :     if (!name)
     196           0 :         return 0;
     197           0 :     OUString rPath(name,strlen(name),RTL_TEXTENCODING_UTF8);
     198           0 :     std::vector<OUString> aElems;
     199           0 :     splitPath( aElems, rPath );
     200             : 
     201           0 :     if ((mnLength == 0) || !mxStream.is() || !mxSeekable.is())
     202           0 :         return 0;
     203             : 
     204           0 :     sal_Int64 tmpPosition = mxSeekable->getPosition();
     205           0 :     mxSeekable->seek(0);
     206             : 
     207           0 :     SvStream *pStream = utl::UcbStreamHelper::CreateStream( mxStream );
     208             : 
     209           0 :     if (!pStream || !SotStorage::IsOLEStorage( pStream ))
     210             :     {
     211           0 :         mxSeekable->seek(tmpPosition);
     212           0 :         return 0;
     213             :     }
     214             : 
     215           0 :     SotStorageRefWrapper storageRefWrapper;
     216           0 :     storageRefWrapper.ref = new SotStorage( pStream, sal_True );
     217           0 :     mxChildrenStorages.push_back( storageRefWrapper );
     218             : 
     219           0 :     unsigned i = 0;
     220           0 :     while (i < aElems.size())
     221             :     {
     222           0 :         if( mxChildrenStorages.back().ref->IsStream(aElems[i]))
     223           0 :             break;
     224           0 :         else if (mxChildrenStorages.back().ref->IsStorage(aElems[i]))
     225             :         {
     226           0 :             SotStorageRef tmpParent(mxChildrenStorages.back().ref);
     227           0 :             storageRefWrapper.ref = tmpParent->OpenSotStorage(aElems[i++], STREAM_STD_READ);
     228           0 :             mxChildrenStorages.push_back(storageRefWrapper);
     229             :         }
     230             :         else
     231             :             // should not happen
     232           0 :             return 0;
     233             :     }
     234             : 
     235             :     // For the while don't return stream in this situation.
     236             :     // Later, given how libcdr's zip stream implementation behaves,
     237             :     // return the first stream in the storage if there is one.
     238           0 :     if (i >= aElems.size())
     239           0 :         return 0;
     240             : 
     241           0 :     SotStorageStreamRefWrapper storageStreamRefWrapper;
     242           0 :     storageStreamRefWrapper.ref = mxChildrenStorages.back().ref->OpenSotStream( aElems[i], STREAM_STD_READ );
     243           0 :     mxChildrenStreams.push_back( storageStreamRefWrapper );
     244             : 
     245           0 :     mxSeekable->seek(tmpPosition);
     246             : 
     247           0 :     if ( !mxChildrenStreams.back().ref.Is() || mxChildrenStreams.back().ref->GetError() )
     248             :     {
     249           0 :         mxSeekable->seek(tmpPosition);
     250           0 :         return 0;
     251             :     }
     252             : 
     253           0 :     Reference < XInputStream > xContents(new utl::OSeekableInputStreamWrapper( mxChildrenStreams.back().ref ));
     254           0 :     mxSeekable->seek(tmpPosition);
     255           0 :     if (xContents.is())
     256           0 :         return new WPXSvInputStream( xContents );
     257             :     else
     258           0 :         return 0;
     259             : }
     260             : 
     261             : 
     262          72 : WPXSvInputStream::WPXSvInputStream( Reference< XInputStream > xStream ) :
     263          72 :     mpImpl(new WPXSvInputStreamImpl(xStream))
     264             : {
     265          72 : }
     266             : 
     267         144 : WPXSvInputStream::~WPXSvInputStream()
     268             : {
     269          72 :    delete mpImpl;
     270          72 : }
     271             : 
     272        1584 : const unsigned char *WPXSvInputStream::read(unsigned long numBytes, unsigned long &numBytesRead)
     273             : {
     274        1584 :     return mpImpl->read(numBytes, numBytesRead);
     275             : }
     276             : 
     277        1494 : long WPXSvInputStream::tell()
     278             : {
     279        1494 :     return mpImpl->tell();
     280             : }
     281             : 
     282        2070 : int WPXSvInputStream::seek(long offset, WPX_SEEK_TYPE seekType)
     283             : {
     284        2070 :     return mpImpl->seek(offset, seekType);
     285             : }
     286             : 
     287        3006 : bool WPXSvInputStream::atEOS()
     288             : {
     289        3006 :     return mpImpl->atEOS();
     290             : }
     291             : 
     292           0 : bool WPXSvInputStream::isOLEStream()
     293             : {
     294           0 :     return mpImpl->isOLEStream();
     295             : }
     296             : 
     297           0 : WPXInputStream *WPXSvInputStream::getDocumentOLEStream(const char *name)
     298             : {
     299           0 :     return mpImpl->getDocumentOLEStream(name);
     300             : }
     301             : 
     302             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10