LCOV - code coverage report
Current view: top level - src - fileentry.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 118 118 100.0 %
Date: 2024-06-15 08:26:09 Functions: 33 34 97.1 %
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-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::FileEntry.
      24             :  *
      25             :  * This file includes the implementation of the zipios::FileEntry.
      26             :  * Many of the functions in zipios::FileEntry are pure virtual so
      27             :  * only their documentation appears here.
      28             :  *
      29             :  * zipios::FileEntry is used to build collections of files.
      30             :  */
      31             : 
      32             : #include "zipios/fileentry.hpp"
      33             : 
      34             : #include "zipios/zipiosexceptions.hpp"
      35             : 
      36             : #include "zipios_common.hpp"
      37             : 
      38             : 
      39             : namespace zipios
      40             : {
      41             : 
      42             : /** \enum StorageMethod
      43             :  * \brief The types used with FileEntry::setMethod and FileEntry::getMethod.
      44             :  *
      45             :  * The current entries are the types supported by the zip format. The
      46             :  * numbering matches one to one the numbering used in the zip file format,
      47             :  * i.e. STORED is indicated by a 0 in the method field in a zip file and
      48             :  * so on.
      49             :  *
      50             :  * The zipios library only support STORED and DEFLATED at this time.
      51             :  */
      52             : 
      53             : 
      54             : /** \class FileEntry
      55             :  * \brief A FileEntry represents an entry in a FileCollection.
      56             :  *
      57             :  * The interface is a copy of the ZipEntry interface from the java.util.zip
      58             :  * package. The name has been changed to FileEntry, as FileCollection
      59             :  * is a more general abstraction, that covers other types of file
      60             :  * collections than just zip files.
      61             :  *
      62             :  * \note
      63             :  * The hashCode() supported in Java is not included as we do not have an
      64             :  * equivalent in this library.
      65             :  */
      66             : 
      67             : 
      68             : /** \typedef int FileEntry::CompressionLevel
      69             :  * \brief The compression level to be used to save an entry.
      70             :  *
      71             :  * Values defined using this time represent the compression level to
      72             :  * be used when compressing an entry.
      73             :  *
      74             :  * If unchanged, use the DEFAULT_COMPRESSION value.
      75             :  *
      76             :  * It is possible to change the compression level to NO_COMPRESSION or
      77             :  * use the setMethod() with STORED to avoid any compression (i.e. create
      78             :  * a zip file which awfully looks like a tarball).
      79             :  *
      80             :  * \todo
      81             :  * These values are one to one mapped to zlib compression values. This
      82             :  * is likely to change once we start offering other compression scheme
      83             :  * for a number defined between 0 and 100 instead.
      84             :  */
      85             : 
      86             : 
      87             : /** \brief Initialize a FileEntry object.
      88             :  *
      89             :  * This function initializes a FileEntry object. By default you may define
      90             :  * the filename of the FileEntry object.
      91             :  *
      92             :  * In case of an on disk directory, the filename should be the path to the
      93             :  * file that can be read from disk, otherwise the FileEntry object will be
      94             :  * viewed as invalid. There is, otherwise, no restriction to the filename.
      95             :  *
      96             :  * \param[in] filename  The file entry filename.
      97             :  * \param[in] comment  The comment attached to the file.
      98             :  */
      99      247249 : FileEntry::FileEntry(FilePath const & filename, std::string const & comment)
     100      247249 :     : m_filename(filename)
     101      247249 :     , m_comment(comment)
     102             : {
     103      247249 : }
     104             : 
     105             : 
     106             : /** \fn FileEntry::pointer_t FileEntry::clone() const;
     107             :  * \brief Create a clone of a file entry.
     108             :  *
     109             :  * This function creates a heap allocated clone of the object
     110             :  * this method is called for.
     111             :  *
     112             :  * Note that the object is expected to overload this function in
     113             :  * order to create a clone of the correct type.
     114             :  *
     115             :  * \return A smart pointer to the clone.
     116             :  */
     117             : 
     118             : 
     119             : /** \brief Clean up a FileEntry object.
     120             :  *
     121             :  * The destructor is defined as it has to be virtual.
     122             :  *
     123             :  * It will eventually clean up resources used by the FileEntry class.
     124             :  */
     125      459819 : FileEntry::~FileEntry()
     126             : {
     127      459819 : }
     128             : 
     129             : 
     130             : /** \brief Retrieve the comment of the file entry.
     131             :  *
     132             :  * This function returns the comment of this entry.
     133             :  *
     134             :  * If the entry was not assigned a comment, this function returns
     135             :  * an empty string. All entries can be given a comment, although
     136             :  * for most it will be ignored unless you save the file to a Zip
     137             :  * archive.
     138             :  *
     139             :  * \return The comment associated with this entry, if there is one.
     140             :  */
     141       89767 : std::string FileEntry::getComment() const
     142             : {
     143       89767 :     return m_comment;
     144             : }
     145             : 
     146             : 
     147             : /** \brief Retrieve the size of the file when compressed.
     148             :  *
     149             :  * This function returns the compressed size of the entry. If the
     150             :  * entry is not stored in a compressed format, the uncompressed
     151             :  * size is returned.
     152             :  *
     153             :  * \return The compressed size of the entry.
     154             :  */
     155       32183 : size_t FileEntry::getCompressedSize() const
     156             : {
     157       32183 :     return getSize();
     158             : }
     159             : 
     160             : 
     161             : 
     162             : 
     163             : /** \brief Return the CRC of the entry.
     164             :  *
     165             :  * This function returns the CRC 32 of this entry, if it has one.
     166             :  *
     167             :  * The CRC is set only after the file is compressed so it may
     168             :  * not always be available. The hasCrc() function can be used
     169             :  * to know whether it was set before.
     170             :  *
     171             :  * \return The CRC32 for the entry, if it has one.
     172             :  */
     173       31671 : FileEntry::crc32_t FileEntry::getCrc() const
     174             : {
     175             :     /** \FIXME
     176             :      * Should we throw if m_has_crc_32 is false?
     177             :      */
     178       31671 :     return m_crc_32;
     179             : }
     180             : 
     181             : 
     182             : /** \brief Get the offset of this entry in a Zip archive.
     183             :  *
     184             :  * This function retrieves the offset at which this FileEntry
     185             :  * resides in the Zip archive it is attached to.
     186             :  *
     187             :  * Note that in case of a Zip archive embedded in another file,
     188             :  * the offset is virtual (relative to the start of the Zip archive
     189             :  * in the larger file.)
     190             :  *
     191             :  * \return The position in the Zip archive.
     192             :  */
     193      387413 : std::streampos FileEntry::getEntryOffset() const
     194             : {
     195      387413 :     return m_entry_offset;
     196             : }
     197             : 
     198             : 
     199             : /** \brief Some extra data to be stored along the entry.
     200             :  *
     201             :  * This function returns a copy of the vector of bytes of extra data
     202             :  * that are stored with the entry.
     203             :  *
     204             :  * This buffer should be generated using the still non-existent
     205             :  * ZipExtra class. This includes definitions of additional meta
     206             :  * data necessary on various operating systems. For example, Linux
     207             :  * makes use of the "UT" (Universal Time) to save the atime, ctime,
     208             :  * and mtime parameters, and "ux" (Unix) to save the Unix permissions
     209             :  * and user identifier (uid) and group identifier (gid).
     210             :  *
     211             :  * \return A buffer_t of extra bytes that are associated with this entry.
     212             :  */
     213       31695 : FileEntry::buffer_t FileEntry::getExtra() const
     214             : {
     215       31695 :     return m_extra_field;
     216             : }
     217             : 
     218             : 
     219             : /** \brief Retrieve the size of the header.
     220             :  *
     221             :  * This function determines the size of the Zip archive header necessary
     222             :  * for that file.
     223             :  *
     224             :  * By default the function returns zero meaning that no header is defined.
     225             :  *
     226             :  * \return The size of the header in bytes.
     227             :  */
     228       31671 : size_t FileEntry::getHeaderSize() const
     229             : {
     230       31671 :     return 0;
     231             : }
     232             : 
     233             : 
     234             : /** \brief Retrieve the compression level.
     235             :  *
     236             :  * Use this function to read the compression level to use to compress
     237             :  * a file.
     238             :  *
     239             :  * Note that the compression level is rarely saved in the
     240             :  * destination file, so after reading a file from a Zip archive this
     241             :  * parameter is set to the default compression level which does not
     242             :  * represent the level used to create the file.
     243             :  *
     244             :  * The compression level is a number between 1 and 100 if compression
     245             :  * is wanted. 0 for no compression. A few negative numbers represent
     246             :  * various default compression levels.
     247             :  *
     248             :  * \return The compression level to use to write this entry to a Zip archive.
     249             :  *
     250             :  * \sa CompressionLevel
     251             :  * \sa setLevel()
     252             :  */
     253       50567 : FileEntry::CompressionLevel FileEntry::getLevel() const
     254             : {
     255       50567 :     if(isDirectory())
     256             :     {
     257          22 :         return COMPRESSION_LEVEL_NONE;
     258             :     }
     259       50545 :     return m_compression_level;
     260             : }
     261             : 
     262             : 
     263             : /** \brief Return the method used to create this entry.
     264             :  *
     265             :  * This function returns the method used to store the entry data in
     266             :  * the FileCollection it is attached to.
     267             :  *
     268             :  * \return the storage method used to store the entry in a collection.
     269             :  *
     270             :  * \sa StorageMethod
     271             :  * \sa setMethod()
     272             :  */
     273      672583 : StorageMethod FileEntry::getMethod() const
     274             : {
     275      672583 :     if(isDirectory())
     276             :     {
     277             :         // make sure we do not return anything else than STORED
     278             :         // for a directory
     279       13139 :         return StorageMethod::STORED;
     280             :     }
     281      659444 :     return m_compress_method;
     282             : }
     283             : 
     284             : 
     285             : 
     286             : 
     287             : /** \brief Return the filename of the entry.
     288             :  *
     289             :  * The function returns the full filename of the entry, including
     290             :  * a path if the entry is stored in a sub-folder.
     291             :  *
     292             :  * \return The filename of the entry including its path.
     293             :  */
     294    39520131 : std::string FileEntry::getName() const
     295             : {
     296    39520131 :     return m_filename;
     297             : }
     298             : 
     299             : 
     300             : /** \brief Return the basename of this entry.
     301             :  *
     302             :  * This function returns the filename only of the entry.
     303             :  *
     304             :  * \warning
     305             :  * The function returns the last segment of the filename whether it is
     306             :  * a regular file or a directory so one can search for a directory with
     307             :  * the MATCH or IGNORE search options.
     308             :  *
     309             :  * \return The filename of the entry.
     310             :  */
     311     4806024 : std::string FileEntry::getFileName() const
     312             : {
     313     4806024 :     return m_filename.filename();
     314             : }
     315             : 
     316             : 
     317             : /** \brief Retrieve the size of the file when uncompressed.
     318             :  *
     319             :  * This function returns the uncompressed size of the entry data.
     320             :  *
     321             :  * \return Returns the uncompressed size of the entry.
     322             :  */
     323      391351 : std::size_t FileEntry::getSize() const
     324             : {
     325      391351 :     return m_uncompressed_size;
     326             : }
     327             : 
     328             : 
     329             : /** \brief Get the MS-DOS date/time of this entry.
     330             :  *
     331             :  * This function returns the date and time of the entry in MS-DOS
     332             :  * date/time format.
     333             :  *
     334             :  * \note
     335             :  * An MS-DOS date is limited to 127 years starting on 1980.
     336             :  * So it will be over after Dec 31, 2107.
     337             :  *
     338             :  * \note
     339             :  * In 32 bits, the Unix date is limited to 03:14:07 on Tuesday,
     340             :  * 19 January 2038. Please switch to a 64 bit OS soon.
     341             :  *
     342             :  * \return The date and time of the entry in MS-DOS format.
     343             :  */
     344       89767 : DOSDateTime::dosdatetime_t FileEntry::getTime() const
     345             : {
     346       89767 :     if(m_unix_time == 0)
     347             :     {
     348         224 :         return 0;
     349             :     }
     350             : 
     351       89543 :     DOSDateTime t;
     352       89543 :     t.setUnixTimestamp(m_unix_time);
     353       89543 :     return t.getDOSDateTime();
     354             : }
     355             : 
     356             : 
     357             : /** \brief Get the Unix date/time of this entry.
     358             :  *
     359             :  * This function returns the date and time of the entry in Unix
     360             :  * date/time format (see time()).
     361             :  *
     362             :  * \note
     363             :  * The FileEntry object saves the time as a Unix time_t value,
     364             :  * however, the Zip file format uses the DOS time format. So
     365             :  * for a Zip file, the precision of the date is to the next
     366             :  * even second. Yet, this function may return a value which
     367             :  * is odd when the time comes from a file on disk.
     368             :  *
     369             :  * \note
     370             :  * Unless you have an old 32 bit system that defines time_t
     371             :  * as a 32 bit value, a Unix date can be considered infinite.
     372             :  * Otherwise it is limited to some time in 2038.
     373             :  *
     374             :  * \return The date and time of the entry as a time_t value.
     375             :  */
     376       89767 : std::time_t FileEntry::getUnixTime() const
     377             : {
     378       89767 :     return m_unix_time;
     379             : }
     380             : 
     381             : 
     382             : /** \brief Check whether the CRC32 was defined.
     383             :  *
     384             :  * This function returns true if the setCrc() function was called earlier
     385             :  * with a valid CRC32 and the FileEntry implementation supports a CRC (i.e.
     386             :  * a DirectoryEntry does not have a CRC).
     387             :  *
     388             :  * \return true if a CRC32 is defined in this class.
     389             :  */
     390       89767 : bool FileEntry::hasCrc() const
     391             : {
     392       89767 :     return m_has_crc_32;
     393             : }
     394             : 
     395             : 
     396             : /** \brief Check whether the filename represents a directory.
     397             :  *
     398             :  * This function checks the last character of the filename, if it
     399             :  * is a separator ('/') then the function returns true meaning
     400             :  * that the file represents a directory.
     401             :  *
     402             :  * \return true if the entry represents a directory.
     403             :  */
     404      554121 : bool FileEntry::isDirectory() const
     405             : {
     406      554121 :     return m_filename.isDirectory();
     407             : }
     408             : 
     409             : 
     410             : /** \brief Compare two file entries for equality.
     411             :  *
     412             :  * This function compares most of the fields between two file
     413             :  * entries to see whether they are equal or not.
     414             :  *
     415             :  * Note that this does not compare the file contents, only the
     416             :  * file entry meta data.
     417             :  *
     418             :  * \warning
     419             :  * The Extra buffer is ignored in the comparison. There are two
     420             :  * reasons for this: (1) it is unlikely that such a parameter
     421             :  * should count in the comparison (just like the compressed
     422             :  * size of the file) and (2) the comparison is not trivial as
     423             :  * each chunk in the buffer needs to be separately compared
     424             :  * (we may offer that capability once we have a ZipExtra class.)
     425             :  *
     426             :  * \param[in] file_entry  The file entry to compare this against.
     427             :  *
     428             :  * \return true if both FileEntry objects are considered equal.
     429             :  */
     430       59630 : bool FileEntry::isEqual(FileEntry const & file_entry) const
     431             : {
     432       59630 :     return m_filename          == file_entry.m_filename
     433       59402 :         && m_comment           == file_entry.m_comment
     434       59402 :         && m_uncompressed_size == file_entry.m_uncompressed_size
     435       59402 :         && m_unix_time         == file_entry.m_unix_time
     436       59402 :         && m_compress_method   == file_entry.m_compress_method
     437       59392 :         && m_crc_32            == file_entry.m_crc_32
     438       59392 :         && m_has_crc_32        == file_entry.m_has_crc_32
     439      119032 :         && m_valid             == file_entry.m_valid;
     440             :         //&& m_extra_field       == file_entry.m_extra_field -- ignored in comparison
     441             : }
     442             : 
     443             : 
     444             : /** \brief Check whether this entry is valid.
     445             :  *
     446             :  * Any method or operator that initializes a FileEntry may set a
     447             :  * flag that specifies whether the file entry is valid or not. If
     448             :  * it is not this method returns false.
     449             :  *
     450             :  * \return true if the FileEntry has been parsed successfully.
     451             :  */
     452      142828 : bool FileEntry::isValid() const
     453             : {
     454      142828 :     return m_valid;
     455             : }
     456             : 
     457             : 
     458             : /** \brief Set the comment field for the FileEntry.
     459             :  *
     460             :  * This function sets the comment of this FileEntry. Note that
     461             :  * all implementations of the FileEntry may not include support
     462             :  * for a comment. In that case this function does nothing.
     463             :  *
     464             :  * \param[in] comment  A string with the new comment.
     465             :  */
     466          23 : void FileEntry::setComment(std::string const & comment)
     467             : {
     468             :     // WARNING: we do NOT check the maximum size here because it can depend
     469             :     //          on the output format which is just zip now but could be a
     470             :     //          bit extended later (i.e. Zip64)
     471          23 :     m_comment = comment;
     472          23 : }
     473             : 
     474             : 
     475             : /** \brief Set the size when the file is compressed.
     476             :  *
     477             :  * This function saves the compressed size of the entry in this object.
     478             :  *
     479             :  * By default the compressed size is viewed as the same as the
     480             :  * uncompressed size (i.e. as if STORED was used for the compression
     481             :  * method.)
     482             :  *
     483             :  * \param[in] size  Value to set the compressed size field of the entry to.
     484             :  */
     485          12 : void FileEntry::setCompressedSize(size_t size)
     486             : {
     487             :     static_cast<void>(size);
     488          12 : }
     489             : 
     490             : 
     491             : /** \brief Save the CRC of the entry.
     492             :  *
     493             :  * This function saves the CRC field in this FileEntry field.
     494             :  *
     495             :  * \param crc value to set the crc field to.
     496             :  */
     497          12 : void FileEntry::setCrc(crc32_t crc)
     498             : {
     499             :     static_cast<void>(crc);
     500          12 : }
     501             : 
     502             : 
     503             : /** \brief Defines the position of the entry in a Zip archive.
     504             :  *
     505             :  * This function defines the position of the FileEntry in a
     506             :  * Zip archive. By default the position is set to zero.
     507             :  *
     508             :  * The offset is generally read from a Zip directory entry.
     509             :  *
     510             :  * When used to seek in a file, the FileCollection will add
     511             :  * the start offset defined in the VirtualSeeker. In other words
     512             :  * this is the position in the Zip archive itself, not the final
     513             :  * position in the file you are reading the archive from.
     514             :  *
     515             :  * \param[in] offset  The new archive entry offset.
     516             :  */
     517      121752 : void FileEntry::setEntryOffset(std::streampos offset)
     518             : {
     519      121752 :     m_entry_offset = offset;
     520      121752 : }
     521             : 
     522             : 
     523             : /** \brief Set the extra field buffer.
     524             :  *
     525             :  * This function is used to set the extra field.
     526             :  *
     527             :  * Only one type of file entry supports an extra field buffer.
     528             :  * The others do nothing when this function is called.
     529             :  *
     530             :  * \param[in] extra  The extra field is set to this value.
     531             :  */
     532          23 : void FileEntry::setExtra(buffer_t const & extra)
     533             : {
     534          23 :     m_extra_field = extra;
     535          23 : }
     536             : 
     537             : 
     538             : /** \brief Define the level of compression to use by this FileEntry.
     539             :  *
     540             :  * This function saves the level of compression the library should use
     541             :  * to compress the file before saving it in the output file.
     542             :  *
     543             :  * \note
     544             :  * If the StorageMethod is set to STORED, then the compression level is
     545             :  * ignored, but it is left unchanged.
     546             :  *
     547             :  * \exception InvalidStateException
     548             :  * This function raises this exception if the specified level is out of
     549             :  * the allowed range.
     550             :  *
     551             :  * \param[in] level  The compression level to use to compress the file data.
     552             :  */
     553       61999 : void FileEntry::setLevel(CompressionLevel level)
     554             : {
     555       61999 :     if(level < COMPRESSION_LEVEL_DEFAULT || level > COMPRESSION_LEVEL_MAXIMUM)
     556             :     {
     557        5691 :         throw InvalidStateException("level must be between COMPRESSION_LEVEL_DEFAULT and COMPRESSION_LEVEL_MAXIMUM inclusive");
     558             :     }
     559       56308 :     if(isDirectory())
     560             :     {
     561        4916 :         if(level >= COMPRESSION_LEVEL_MINIMUM)
     562             :         {
     563         100 :             throw InvalidStateException("directories cannot be marked with a compression level other than COMPRESSION_LEVEL_NONE (defaults will also work");
     564             :         }
     565        4816 :         m_compression_level = COMPRESSION_LEVEL_NONE;
     566             :     }
     567             :     else
     568             :     {
     569       51392 :         m_compression_level = level;
     570             :     }
     571       56208 : }
     572             : 
     573             : 
     574             : /** \brief Sets the storage method field for the entry.
     575             :  *
     576             :  * This function sets the method with which the file data is to
     577             :  * be compressed.
     578             :  *
     579             :  * The method is ignored in a file entry which cannot be compressed.
     580             :  * (or more precisely, the method is forced as STORED.)
     581             :  *
     582             :  * \exception InvalidStateException
     583             :  * This exception is raised if the \p method parameter does not represent
     584             :  * a supported method. At this time the library only supports STORED and
     585             :  * DEFLATED. The getMethod() may return more types as read from a Zip
     586             :  * archive, but it is not possible to set such types using this function.
     587             :  *
     588             :  * \param[in] method  The method field is set to the specified value.
     589             :  */
     590       56260 : void FileEntry::setMethod(StorageMethod method)
     591             : {
     592       56260 :     switch(method)
     593             :     {
     594       56006 :     case StorageMethod::STORED:
     595             :     //case StorageMethod::SHRUNK:
     596             :     //case StorageMethod::REDUCED1:
     597             :     //case StorageMethod::REDUCED2:
     598             :     //case StorageMethod::REDUCED3:
     599             :     //case StorageMethod::REDUCED4:
     600             :     //case StorageMethod::IMPLODED:
     601             :     //case StorageMethod::TOKENIZED:
     602             :     case StorageMethod::DEFLATED:
     603             :     //case StorageMethod::DEFLATED64:
     604             :     //case StorageMethod::OLD_TERSE:
     605             :     //case StorageMethod::RESERVED11:
     606             :     //case StorageMethod::BZIP2:
     607             :     //case StorageMethod::REVERVED13:
     608             :     //case StorageMethod::LZMA:
     609             :     //case StorageMethod::RESERVED15:
     610             :     //case StorageMethod::RESERVED16:
     611             :     //case StorageMethod::RESERVED17:
     612             :     //case StorageMethod::NEW_TERSE:
     613             :     //case StorageMethod::LZ77:
     614             :     //case StorageMethod::WAVPACK:
     615             :     //case StorageMethod::PPMD_I_1:
     616       56006 :         break;
     617             : 
     618         254 :     default:
     619         254 :         throw InvalidStateException("unknown method");
     620             : 
     621             :     }
     622             : 
     623       56006 :     if(isDirectory())
     624             :     {
     625             :         // never compress directories
     626        4812 :         m_compress_method = StorageMethod::STORED;
     627             :     }
     628             :     else
     629             :     {
     630       51194 :         m_compress_method = method;
     631             :     }
     632       56006 : }
     633             : 
     634             : 
     635             : /** \brief Sets the size field for the entry.
     636             :  *
     637             :  * This function is used to save the size of this file on disk
     638             :  * when uncompressed.
     639             :  *
     640             :  * \param[in] size  The size field is set to this value.
     641             :  */
     642      121772 : void FileEntry::setSize(size_t size)
     643             : {
     644      121772 :     m_uncompressed_size = size;
     645      121772 : }
     646             : 
     647             : 
     648             : /** \brief Set the FileEntry time using a DOS time.
     649             :  *
     650             :  * This function saves the specified \p dosdatetime value as the last modification
     651             :  * date and time of this entry. This is generally used when reading that
     652             :  * information * from a Zip archive. Otherwise you probably want to use
     653             :  * the setUnixTime() instead since it is one to one compatible with the
     654             :  * value handle by time(), stat(), and other OS functions.
     655             :  *
     656             :  * \param[in] dosdatetime  Set time field as is using this MS-DOS date/time value.
     657             :  */
     658          12 : void FileEntry::setTime(DOSDateTime::dosdatetime_t dosdatetime)
     659             : {
     660          12 :     DOSDateTime t;
     661          12 :     t.setDOSDateTime(dosdatetime);
     662          12 :     setUnixTime(t.getUnixTimestamp());
     663          12 : }
     664             : 
     665             : 
     666             : /** \brief Sets the time field in Unix time format for the entry.
     667             :  *
     668             :  * This function is used to set the last modification time of this
     669             :  * entry. In most cases this comes from the stat structure field
     670             :  * named st_mtime. If you are creating a file directly in memory,
     671             :  * you may use the return value of <code>time(nullptr);</code>.
     672             :  *
     673             :  * \param[in] time  The time field is set to the specified value.
     674             :  */
     675          24 : void FileEntry::setUnixTime(std::time_t time)
     676             : {
     677          24 :     m_unix_time = time;
     678          24 : }
     679             : 
     680             : 
     681             : /** \brief Returns a human-readable string representation of the entry.
     682             :  *
     683             :  * This function transforms the basic information of the entry in a
     684             :  * string. Note that most of the information is lost as the function
     685             :  * is likely to only display the filename and the size of the file,
     686             :  * nothing more.
     687             :  *
     688             :  * \return A human-readable string representation of the entry.
     689             :  */
     690         536 : std::string FileEntry::toString() const
     691             : {
     692         536 :     OutputStringStream sout;
     693         536 :     sout << m_filename;
     694         536 :     if(isDirectory())
     695             :     {
     696          24 :         sout << " (directory)";
     697             :     }
     698             :     else
     699             :     {
     700         512 :         sout << " ("
     701         512 :              << m_uncompressed_size << " byte"
     702         512 :              << (m_uncompressed_size == 1 ? "" : "s");
     703         512 :         size_t const compressed_size(getCompressedSize());
     704         512 :         if(compressed_size != m_uncompressed_size)
     705             :         {
     706             :              // this is not currently accessible since only the
     707             :              // ZipLocalEntry and ZipCentralDirectoryEntry have
     708             :              // a compressed size
     709             :              sout << ",  " // LCOV_EXCL_LINE
     710             :                   << compressed_size << " byte" // LCOV_EXCL_LINE
     711             :                   << (compressed_size == 1 ? "" : "s") // LCOV_EXCL_LINE
     712             :                   << " compressed"; // LCOV_EXCL_LINE
     713             :         }
     714         512 :         sout << ")";
     715             :     }
     716        1072 :     return sout.str();
     717         536 : }
     718             : 
     719             : 
     720             : /** \brief Read this FileEntry from the input stream.
     721             :  *
     722             :  * This function is called when the FileEntry should be initialized from
     723             :  * the specified input stream.
     724             :  *
     725             :  * \exception IOException
     726             :  * The default implementation raise an IOException error because there is
     727             :  * no reading the FileEntry from anywhere.
     728             :  *
     729             :  * \param[in,out] is  The input stream.
     730             :  */
     731       31138 : void FileEntry::read(std::istream & is)
     732             : {
     733             :     static_cast<void>(is);
     734       31138 :     throw IOException("FileEntry::read(): read not available with this type of FileEntry.");
     735             : }
     736             : 
     737             : 
     738             : /** \brief Write this FileEntry to the output stream.
     739             :  *
     740             :  * This function is called when the FileEntry should be saved in the
     741             :  * specified output stream.
     742             :  *
     743             :  * \exception IOException
     744             :  * The default implementation raise an IOException error because there is
     745             :  * no writing the FileEntry anywhere.
     746             :  *
     747             :  * \param[in,out] os  The output stream.
     748             :  */
     749       31138 : void FileEntry::write(std::ostream & os)
     750             : {
     751             :     static_cast<void>(os);
     752       31138 :     throw IOException("FileEntry::write(): write not available with this type of FileEntry.");
     753             : }
     754             : 
     755             : 
     756             : /** \brief Output an entry as a string to a stream.
     757             :  *
     758             :  * This function transforms the FileEntry basic information into a string
     759             :  * and prints the result to the specified output stream.
     760             :  *
     761             :  * \param[in,out] os  The output stream.
     762             :  * \param[in] entry  The entry to print out.
     763             :  *
     764             :  * \return A reference to the output stream.
     765             :  *
     766             :  * \sa FileEntry::toString()
     767             :  */
     768           1 : std::ostream & operator << (std::ostream & os, FileEntry const & entry)
     769             : {
     770           1 :     os << entry.toString();
     771           1 :     return os;
     772             : }
     773             : 
     774             : 
     775             : } // namespace
     776             : 
     777             : // Local Variables:
     778             : // mode: cpp
     779             : // indent-tabs-mode: nil
     780             : // c-basic-offset: 4
     781             : // tab-width: 4
     782             : // End:
     783             : 
     784             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.14

Snap C++ | List of projects | List of versions