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
|