LCOV - code coverage report
Current view: top level - src - zipinputstreambuf.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 28 28 100.0 %
Date: 2019-04-24 14:10:30 Functions: 6 6 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :   Zipios -- a small C++ library that provides easy access to .zip files.
       3             : 
       4             :   Copyright (C) 2000-2007  Thomas Sondergaard
       5             :   Copyright (C) 2015-2019  Made to Order Software Corporation
       6             : 
       7             :   This library is free software; you can redistribute it and/or
       8             :   modify it under the terms of the GNU Lesser General Public
       9             :   License as published by the Free Software Foundation; either
      10             :   version 2.1 of the License, or (at your option) any later version.
      11             : 
      12             :   This library is distributed in the hope that it will be useful,
      13             :   but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15             :   Lesser General Public License for more details.
      16             : 
      17             :   You should have received a copy of the GNU Lesser General Public
      18             :   License along with this library; if not, write to the Free Software
      19             :   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
      20             : */
      21             : 
      22             : /** \file
      23             :  * \brief Implementation of zipios::ZipInputStreambuf.
      24             :  *
      25             :  * This is the implementation of the Zip input std::streambuf class.
      26             :  */
      27             : 
      28             : #include "zipinputstreambuf.hpp"
      29             : 
      30             : #include "zipios/zipiosexceptions.hpp"
      31             : 
      32             : 
      33             : namespace zipios
      34             : {
      35             : 
      36             : 
      37             : /** \class ZipInputStreambuf
      38             :  * \brief An input stream buffer for Zip data.
      39             :  *
      40             :  * The ZipInputStreambuf class is a Zip input streambuf filter that
      41             :  * automatically decompresses input data that was compressed using
      42             :  * the zlib library.
      43             :  */
      44             : 
      45             : 
      46             : /** \brief Initialize a ZipInputStreambuf.
      47             :  *
      48             :  * This ZipInputStreambuf constructor initializes the buffer from the
      49             :  * user specified buffer.
      50             :  *
      51             :  * \param[in,out] inbuf  The streambuf to use for input.
      52             :  * \param[in] start_pos  A position to reset the inbuf to before reading.
      53             :  *                       Specify -1 to read from the current position.
      54             :  */
      55       96763 : ZipInputStreambuf::ZipInputStreambuf(std::streambuf *inbuf, offset_t start_pos)
      56       96783 :     : InflateInputStreambuf(inbuf, start_pos)
      57             :     //, m_current_entry() -- auto-init
      58             :     //, m_remain(0) -- auto-init
      59             : {
      60             :     // read the zip local header
      61      193526 :     std::istream is(m_inbuf); // istream does not destroy the streambuf.
      62       96763 :     is.exceptions(std::ios::eofbit | std::ios::failbit | std::ios::badbit);
      63             : 
      64             :     // if the read fails in any way it will throw
      65       96763 :     m_current_entry.read(is);
      66       96763 :     if(m_current_entry.isValid() && m_current_entry.hasTrailingDataDescriptor())
      67             :     {
      68          10 :         throw FileCollectionException("Trailing data descriptor in zip file not supported");
      69             :     }
      70             : 
      71       96753 :     switch(m_current_entry.getMethod())
      72             :     {
      73             :     case StorageMethod::DEFLATED:
      74       94668 :         reset() ; // reset inflatestream data structures
      75             : //std::cerr << "deflated" << std::endl;
      76       94668 :         break;
      77             : 
      78             :     case StorageMethod::STORED:
      79        2075 :         m_remain = m_current_entry.getSize();
      80             :         // Force underflow on first read:
      81        2075 :         setg(&m_outvec[0], &m_outvec[0] + getBufferSize(), &m_outvec[0] + getBufferSize());
      82             : //std::cerr << "stored" << std::endl;
      83        2075 :         break;
      84             : 
      85             :     default:
      86             :         // file not supported... sorry!
      87          10 :         throw FileCollectionException("Unsupported compression format");
      88             : 
      89             :     }
      90       96743 : }
      91             : 
      92             : 
      93             : /** \fn ZipInputStreambuf::ZipInputStreambuf(ZipInputStreambuf const & src);
      94             :  * \brief The copy contructor is deleted.
      95             :  *
      96             :  * ZipInputStreambuf objects cannot be copied so the copy constructor
      97             :  * is deleted.
      98             :  *
      99             :  * \param[in] src  The source to copy.
     100             :  */
     101             : 
     102             : 
     103             : 
     104             : /** \brief Clean up a ZipInputStreambuf object.
     105             :  *
     106             :  * The destructor ensures that all resources get released.
     107             :  */
     108      193486 : ZipInputStreambuf::~ZipInputStreambuf()
     109             : {
     110      193486 : }
     111             : 
     112             : 
     113             : /** \brief Called when more data is required.
     114             :  *
     115             :  * The function ensures that at least one byte is available
     116             :  * in the input area by updating the pointers to the input area
     117             :  * and reading more data in from the input sequence if required.
     118             :  *
     119             :  * \return The value of that character on success or
     120             :  *         std::streambuf::traits_type::eof() on failure.
     121             :  */
     122      773407 : std::streambuf::int_type ZipInputStreambuf::underflow()
     123             : {
     124      773407 :     switch(m_current_entry.getMethod())
     125             :     {
     126             :     case StorageMethod::DEFLATED:
     127             :         // inflate class takes care of it in this case
     128      763145 :         return InflateInputStreambuf::underflow();
     129             : 
     130             :     case StorageMethod::STORED:
     131             :     {
     132             :         // Ok, we are STORED, so we handle it ourselves.
     133       10262 :         offset_t const num_b(std::min(m_remain, static_cast<offset_t>(getBufferSize())));
     134       10262 :         std::streamsize const g(m_inbuf->sgetn(&m_outvec[0], num_b));
     135       10262 :         setg(&m_outvec[0], &m_outvec[0], &m_outvec[0] + g);
     136       10262 :         m_remain -= g;
     137       10262 :         if(g > 0)
     138             :         {
     139             :             // we got some data, return it
     140        8187 :             return traits_type::to_int_type(*gptr());
     141             :         }
     142             : 
     143             :         // documentation says to return EOF if no data available
     144        2075 :         return traits_type::eof();
     145             :     }
     146             : 
     147             :     default:
     148             :         // This should NEVER be reached or the constructor let something
     149             :         // go through that should not have gone through
     150             :         throw std::logic_error("ZipInputStreambuf::underflow(): unknown storage method"); // LCOV_EXCL_LINE
     151             : 
     152             :     }
     153             : }
     154             : 
     155             : 
     156           3 : } // namespace
     157             : 
     158             : // Local Variables:
     159             : // mode: cpp
     160             : // indent-tabs-mode: nil
     161             : // c-basic-offset: 4
     162             : // tab-width: 4
     163             : // End:
     164             : 
     165             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.12