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 the zipios::ZipOutputStream class. 24 : * 25 : * The zipios::ZipOutputStream class is used as a filter to compress 26 : * data being written to a Zip archive. 27 : */ 28 : 29 : #include "zipoutputstream.hpp" 30 : #include "zipcentraldirectoryentry.hpp" 31 : 32 : #include <fstream> 33 : 34 : 35 : namespace zipios 36 : { 37 : 38 : /** \class ZipOutputStream 39 : * \brief A ZipOutputStream to allow for data to be compressed with zlib. 40 : * 41 : * ZipOutputStream is an internal ostream implementation used to save a 42 : * collection of files to a Zip archive file. 43 : */ 44 : 45 : 46 : 47 : /** \brief Initialize a ZipOutputStream object. 48 : * 49 : * The ZipOutputStream constructor create an output stream that will 50 : * be used to save Zip data to a file. 51 : * 52 : * \param[in] os The output stream to use to write the Zip archive. 53 : */ 54 257 : ZipOutputStream::ZipOutputStream(std::ostream & os) 55 257 : : m_ozf(std::make_unique<ZipOutputStreambuf>(os.rdbuf())) 56 : { 57 257 : init(m_ozf.get()); 58 257 : } 59 : 60 : 61 : /** \brief Clean up a ZipOutputStream object. 62 : * 63 : * The destructor makes sure that all resources allocated by the 64 : * ZipOutputStream object. 65 : */ 66 257 : ZipOutputStream::~ZipOutputStream() 67 : { 68 257 : } 69 : 70 : 71 : /** Closes the current entry updates its header with the relevant 72 : size information and positions the stream write pointer for the 73 : next entry header. Puts the stream in EOF state. Call 74 : putNextEntry() to clear the EOF stream state flag. */ 75 256 : void ZipOutputStream::closeEntry() 76 : { 77 256 : m_ozf->closeEntry(); 78 256 : } 79 : 80 : 81 : /** \brief Close the current stream. 82 : * 83 : * This function calls close() on the internal stream. After this 84 : * call any attempt in writing to the file will fail. 85 : * 86 : * The result is to ensure that the Zip archive file is complete 87 : * and all buffers flushed to file. 88 : */ 89 253 : void ZipOutputStream::close() 90 : { 91 253 : m_ozf->close(); 92 253 : } 93 : 94 : 95 : /** \brief Finish up the output by flushing anything left. 96 : * 97 : * This function closes the current entry (if one is open) by writing 98 : * the Zip Central Directory Structure closing the ZipOutputStream. 99 : * The output stream that the zip archive is being written to is 100 : * not closed. 101 : */ 102 256 : void ZipOutputStream::finish() 103 : { 104 256 : m_ozf->finish(); 105 253 : } 106 : 107 : 108 : /** \brief Add an entry to the output stream. 109 : * 110 : * This function saves the header of the entry and returns. The caller 111 : * is expected to save the actual data of the file. 112 : * 113 : * \code 114 : * os.putNextEntry(entry); 115 : * FileCollection::stream_pointer_t is(collection->getInputEntry(entry->getName())); 116 : * os << is->rdbuf(); 117 : * \endcode 118 : * 119 : * \warning 120 : * The internal class keeps a copy of the shared pointer so changing 121 : * the entry from the outside may affect the results and invalidate 122 : * the resulting Zip archive file. Since this class is now internal, 123 : * it should not be a major problem since it is created and destroyed 124 : * before the user would have a chance from doing anything to the file. 125 : * 126 : * \param[in] entry The FileEntry to add to the output stream. 127 : */ 128 121751 : void ZipOutputStream::putNextEntry(FileEntry::pointer_t entry) 129 : { 130 : // if we do not yet have a ZipCentralDirectoryEntry object, create 131 : // one from the input entry (the input entry is actually expected 132 : // to be a DirectoryEntry!) 133 121751 : ZipCentralDirectoryEntry * central_directory_entry(dynamic_cast<ZipCentralDirectoryEntry *>(entry.get())); 134 121751 : if(central_directory_entry == nullptr) 135 : { 136 121751 : entry = std::make_shared<ZipCentralDirectoryEntry>(*entry); 137 : } 138 : 139 121751 : m_ozf->putNextEntry(entry); 140 121750 : } 141 : 142 : 143 : /** \brief Set the global comment. 144 : * 145 : * This function is used to setup the Global Comment of the Zip archive 146 : * file. 147 : * 148 : * This comment is saved at the very end of the file, attached to the 149 : * EndOfCentralDirectory block. 150 : * 151 : * \param[in] comment The global comment to save in the Zip archive. 152 : */ 153 257 : void ZipOutputStream::setComment(std::string const & comment) 154 : { 155 257 : m_ozf->setComment(comment); 156 257 : } 157 : 158 : 159 : } // zipios namespace 160 : 161 : // Local Variables: 162 : // mode: cpp 163 : // indent-tabs-mode: nil 164 : // c-basic-offset: 4 165 : // tab-width: 4 166 : // End: 167 : 168 : // vim: ts=4 sw=4 et