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 #include "stream/file.hpp"
22
23 #include <boost/iostreams/filtering_stream.hpp>
24 #include <boost/iostreams/filter/zlib.hpp>
25
26 #include "stream/checksum.hpp"
27 #include "stream/exefilter.hpp"
28 #include "stream/restrict.hpp"
29
30 namespace io = boost::iostreams;
31
32 namespace stream {
33
operator <(const stream::file & o) const34 bool file::operator<(const stream::file & o) const {
35
36 if(offset != o.offset) {
37 return (offset < o.offset);
38 } else if(size != o.size) {
39 return (size < o.size);
40 } else if(filter != o.filter) {
41 return (filter < o.filter);
42 }
43
44 return false;
45 }
46
operator ==(const file & o) const47 bool file::operator==(const file & o) const {
48 return (offset == o.offset
49 && size == o.size
50 && filter == o.filter);
51 }
52
53
get(base_type & base,const file & file,crypto::checksum * checksum)54 file_reader::pointer file_reader::get(base_type & base, const file & file,
55 crypto::checksum * checksum) {
56
57 util::unique_ptr<io::filtering_istream>::type result(new io::filtering_istream);
58
59 if(file.filter == ZlibFilter) {
60 result->push(io::zlib_decompressor(), 8192);
61 }
62
63 if(checksum) {
64 result->push(stream::checksum_filter(checksum, file.checksum.type), 8192);
65 }
66
67 switch(file.filter) {
68 case NoFilter: break;
69 case InstructionFilter4108: result->push(stream::inno_exe_decoder_4108(), 8192); break;
70 case InstructionFilter5200: result->push(stream::inno_exe_decoder_5200(false), 8192); break;
71 case InstructionFilter5309: result->push(stream::inno_exe_decoder_5200(true), 8192); break;
72 case ZlibFilter: /* applied *after* calculating the checksum */ break;
73 }
74
75 result->push(stream::restrict(base, file.size));
76
77 result->exceptions(std::ios_base::badbit);
78
79 return pointer(result.release());
80 }
81
82 } // namespace stream
83