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
|