1 /*
2  * Copyright (C) 2011-2018 Daniel Scharrer
3  *
4  * This software is provided 'as-is', without any express or implied
5  * warranty.  In no event will the author(s) be held liable for any damages
6  * arising from the use of this software.
7  *
8  * Permission is granted to anyone to use this software for any purpose,
9  * including commercial applications, and to alter it and redistribute it
10  * freely, subject to the following restrictions:
11  *
12  * 1. The origin of this software must not be misrepresented; you must not
13  *    claim that you wrote the original software. If you use this software
14  *    in a product, an acknowledgment in the product documentation would be
15  *    appreciated but is not required.
16  * 2. Altered source versions must be plainly marked as such, and must not be
17  *    misrepresented as being the original software.
18  * 3. This notice may not be removed or altered from any source distribution.
19  */
20 
21 /*!
22  * \file
23  *
24  * Wrapper to read a single file from a chunk (\ref stream::chunk_reader).
25  */
26 #ifndef INNOEXTRACT_STREAM_FILE_HPP
27 #define INNOEXTRACT_STREAM_FILE_HPP
28 
29 #include <istream>
30 
31 #include <boost/iostreams/chain.hpp>
32 
33 #include "crypto/checksum.hpp"
34 #include "util/unique_ptr.hpp"
35 
36 namespace stream {
37 
38 enum compression_filter {
39 	NoFilter,
40 	InstructionFilter4108,
41 	InstructionFilter5200,
42 	InstructionFilter5309,
43 	ZlibFilter,
44 };
45 
46 /*!
47  * Information specifying a single file inside a compressed chunk.
48  *
49  * This data is stored in \ref setup::data_entry "data entries".
50  *
51  * Files specified by this struct can be read using \ref file_reader.
52  */
53 struct file {
54 
55 	boost::uint64_t    offset;   //!< Offset of this file within the decompressed chunk.
56 	boost::uint64_t    size;     //!< Pre-filter size of this file in the decompressed chunk.
57 
58 	crypto::checksum   checksum; //!< Checksum for the file.
59 
60 	compression_filter filter;   //!< Additional filter used before compression.
61 
62 	bool operator<(const file & o) const;
63 	bool operator==(const file & o) const;
64 
65 };
66 
67 /*!
68  * Wrapper to read a single file from a \ref chunk_reader.
69  * Restrics the stream to the file size and applies the appropriate filters.
70  */
71 class file_reader {
72 
73 	typedef boost::iostreams::chain<boost::iostreams::input> base_type;
74 
75 public:
76 
77 	typedef std::istream                 type;
78 	typedef util::unique_ptr<type>::type pointer;
79 	typedef file                         file_t;
80 
81 	/*!
82 	 * Wrap a \ref chunk_reader to read a single file.
83 	 *
84 	 * Only one wrapper can be used at the same time for each \c base.
85 	 *
86 	 * \param base     The chunk reader containing the file.
87 	 *                 It must already be positioned at the file's offset.
88 	 * \param file     Information specifying the file to read.
89 	 * \param checksum Optional pointer to a checksum that is updated as the file is read.
90 	 *                 The type of the checksum will be the same as that stored in the file
91 	 *                 struct.
92 	 *
93 	 * \return a pointer to a non-seekable input stream for the requested file.
94 	 */
95 	static pointer get(base_type & base, const file_t & file, crypto::checksum * checksum);
96 
97 };
98 
99 } // namespace stream
100 
101 #endif // INNOEXTRACT_STREAM_FILE_HPP
102