コード例 #1
0
ファイル: chunk.cpp プロジェクト: felixhummel/InnoExtract
chunk_reader::pointer chunk_reader::get(slice_reader & base, const chunk & chunk) {
	
	if(!base.seek(chunk.first_slice, chunk.offset)) {
		throw chunk_error("error seeking");
	}
	
	char magic[ARRAY_SIZE(chunk_id)];
	if(base.read(magic, 4) != 4 || memcmp(magic, chunk_id, ARRAY_SIZE(chunk_id))) {
		throw chunk_error("bad chunk magic");
	}
	
	pointer result = boost::make_shared<type>();
	
	switch(chunk.compression) {
		case Stored: break;
		case Zlib:   result->push(io::zlib_decompressor(), 8192); break;
		case BZip2:  result->push(io::bzip2_decompressor(), 8192); break;
	#ifdef HAVE_LZMA
		case LZMA1:  result->push(inno_lzma1_decompressor(), 8192); break;
		case LZMA2:  result->push(inno_lzma2_decompressor(), 8192); break;
	#else
		case LZMA1: case LZMA2:
			throw chunk_error("LZMA decompression not supported by this Inno Extract build");
	#endif
		default: throw chunk_error("unknown compression");
	}
	
	result->push(io::restrict(boost::ref(base), 0, int64_t(chunk.size)));
	
	return result;
}
コード例 #2
0
ファイル: block.cpp プロジェクト: stopiccot/InnoExtract
block_reader::pointer block_reader::get(std::istream & base, const setup::version & version) {
	
	USE_ENUM_NAMES(block_compression)
	
	uint32_t expected_checksum = load_number<uint32_t>(base);
	crypto::crc32 actual_checksum;
	actual_checksum.init();
	
	uint32_t stored_size;
	block_compression compression;
	
	if(version >= INNO_VERSION(4, 0, 9)) {
		
		stored_size = actual_checksum.load_number<uint32_t>(base);
		uint8_t compressed = actual_checksum.load_number<uint8_t>(base);
		
		compression = compressed ? (version >= INNO_VERSION(4, 1, 6) ? LZMA1 : Zlib) : Stored;
		
	} else {
		
		uint32_t compressed_size = actual_checksum.load_number<uint32_t>(base);
		uint32_t uncompressed_size = actual_checksum.load_number<uint32_t>(base);
		
		if(compressed_size == uint32_t(-1)) {
			stored_size = uncompressed_size, compression = Stored;
		} else {
			stored_size = compressed_size, compression = Zlib;
		}
		
		// Add the size of a CRC32 checksum for each 4KiB subblock.
		stored_size += uint32_t(ceildiv<uint64_t>(stored_size, 4096) * 4);
	}
	
	if(actual_checksum.finalize() != expected_checksum) {
		throw block_error("block CRC32 mismatch");
	}
	
	debug("[block] size: " << stored_size << "  compression: " << compression);
	
	boost::shared_ptr<io::filtering_istream> fis = boost::make_shared<io::filtering_istream>();
	
	switch(compression) {
		case Stored: break;
		case Zlib: fis->push(io::zlib_decompressor(), 8192); break;
	#if INNOEXTRACT_HAVE_LZMA
		case LZMA1: fis->push(inno_lzma1_decompressor(), 8192); break;
	#else
		case LZMA1: throw block_error("LZMA decompression not supported by this "
			                  + std::string(innoextract_name) + " build");
	#endif
	}
	
	fis->push(inno_block_filter(), 4096);
	
	fis->push(io::restrict(base, 0, stored_size));
	
	return fis;
}