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

Generated by: LCOV version 1.12