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-2022 Made to Order Software Corp. All Rights Reserved 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::StreamEntry. 24 : * 25 : * The declaration of a simple zipios::FileEntry used when reading 26 : * from a istream. 27 : */ 28 : 29 : #include "zipios/streamentry.hpp" 30 : 31 : #include "zipios/zipiosexceptions.hpp" 32 : 33 : #include "zipios_common.hpp" 34 : 35 : #include <fstream> 36 : #include <zlib.h> 37 : 38 : 39 : namespace zipios 40 : { 41 : 42 : /** \class StreamEntry 43 : * \brief A file entry reading from a stream. 44 : * 45 : * StreamEntry is a FileEntry that is used when directly reading from a 46 : * stream instead of a file found on disk. 47 : */ 48 : 49 : 50 : /** \brief Initialize a StreamEntry object. 51 : * 52 : * This constructor initializes a StreamEntry which represents a 53 : * file in an std::istream. If the input stream is considered valid 54 : * (i.e. no error flag set), then the StreamEntry is marked as valid. 55 : * 56 : * The \p filename parameter is important since the file is to be saved 57 : * in a zip file and that feat requires a filename. 58 : * 59 : * \warning 60 : * The input \p is stream is saved as a reference in this object. The 61 : * stream must remain valid for the lifetime of this StreamEntry object. 62 : * 63 : * \param[in] is The input stream (std::istream) to read from. 64 : * \param[in] filename The filename of the entry. 65 : * \param[in] comment A comment for the entry. 66 : */ 67 0 : StreamEntry::StreamEntry( 68 : std::istream & is 69 : , FilePath const & filename 70 0 : , std::string const & comment) 71 : : FileEntry(filename, comment) 72 0 : , f_istream(is) 73 : { 74 0 : m_valid = static_cast<bool>(is); 75 0 : if(m_valid) 76 : { 77 0 : std::istream::pos_type const current(is.tellg()); 78 0 : m_uncompressed_size = is.seekg(0, std::ios::end).tellg(); 79 0 : is.seekg(current, std::ios::beg); 80 : 81 0 : m_unix_time = time(nullptr); 82 : } 83 0 : } 84 : 85 : 86 : /** \brief Create a copy of the StreamEntry. 87 : * 88 : * The clone function creates a copy of this StreamEntry object. 89 : * 90 : * In most cases, when a collection is copied, a clone of each 91 : * entry is created to avoid potential problems with sharing 92 : * the same object between various lists. 93 : * 94 : * \return A shared pointer of the new StreamEntry object. 95 : */ 96 0 : FileEntry::pointer_t StreamEntry::clone() const 97 : { 98 0 : return std::make_shared<StreamEntry>(*this); 99 : } 100 : 101 : 102 : /** \brief Clean up a StreamEntry object. 103 : * 104 : * The destructor is defined as it has to be virtual. 105 : * 106 : * It will eventually clean up resources used by the StreamEntry class. 107 : */ 108 0 : StreamEntry::~StreamEntry() 109 : { 110 0 : } 111 : 112 : 113 : /** \brief Compare two file entries for equality. 114 : * 115 : * This function compares most of the fields between two file 116 : * entries to see whether they are equal or not. 117 : * 118 : * \note 119 : * This function calls the base class isEqual() and also verifies 120 : * that the object comments are equal. 121 : * 122 : * \param[in] file_entry The file entry to compare this against. 123 : * 124 : * \return true if both FileEntry objects are considered equal. 125 : */ 126 0 : bool StreamEntry::isEqual(FileEntry const & file_entry) const 127 : { 128 0 : StreamEntry const * const se(dynamic_cast<StreamEntry const * const>(&file_entry)); 129 0 : if(se == nullptr) 130 : { 131 0 : return false; 132 : } 133 0 : return FileEntry::isEqual(file_entry); 134 : } 135 : 136 : 137 : /** \brief Compute the CRC32 of this file. 138 : * 139 : * This function computers the CRC32 of this file and returns it. 140 : * 141 : * This is only a helper function. The CRC32 for the zip file is computed 142 : * on the fly as data is being streamed. 143 : * 144 : * \warning 145 : * This function recomputes the CRC32 on each call. It doesn't get cached. 146 : * 147 : * \return The CRC32 of this file. 148 : */ 149 0 : uint32_t StreamEntry::computeCRC32() const 150 : { 151 0 : uint32_t result(crc32(0L, Z_NULL, 0)); 152 : 153 0 : if(f_istream) 154 : { 155 0 : f_istream.seekg(0, std::ios::beg); 156 : for(;;) 157 : { 158 : Bytef buf[64 * 1024]; 159 0 : f_istream.read(reinterpret_cast<char *>(buf), sizeof(buf)); 160 0 : if(f_istream.gcount() == 0) 161 : { 162 0 : break; 163 : } 164 0 : result = crc32(result, buf, f_istream.gcount()); 165 0 : } 166 : } 167 : 168 0 : return result; 169 : } 170 : 171 : 172 : /** \brief Retrieve a reference to the istream object. 173 : * 174 : * This function returns a reference to the internal istream object saved 175 : * when you constructor this object. 176 : * 177 : * \return A reference to the istream. 178 : */ 179 0 : std::istream & StreamEntry::getStream() const 180 : { 181 0 : return f_istream; 182 : } 183 : 184 : 185 : } // zipios namespace 186 : 187 : // Local Variables: 188 : // mode: cpp 189 : // indent-tabs-mode: nil 190 : // c-basic-offset: 4 191 : // tab-width: 4 192 : // End: 193 : 194 : // vim: ts=4 sw=4 et