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