/* * Copyright (C) 2011-2013 Daniel Scharrer * * This software is provided 'as-is', without any express or implied * warranty. In no event will the author(s) be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. */ #include "chunk.hpp" #include #include #include #include #include "release.hpp" #include "stream/lzma.hpp" #include "stream/restrict.hpp" #include "stream/slice.hpp" #include "util/log.hpp" namespace io = boost::iostreams; namespace stream { static const char chunk_id[4] = { 'z', 'l', 'b', 0x1a }; bool chunk::operator<(const chunk & o) const { if(first_slice != o.first_slice) { return (first_slice < o.first_slice); } else if(offset != o.offset) { return (offset < o.offset); } else if(size != o.size) { return (size < o.size); } else if(compression != o.compression) { return (compression < o.compression); } else if(encrypted != o.encrypted) { return (encrypted < o.encrypted); } return false; } bool chunk::operator==(const chunk & o) const { return (first_slice == o.first_slice && offset == o.offset && size == o.size && compression == o.compression && encrypted == o.encrypted); } chunk_reader::pointer chunk_reader::get(slice_reader & base, const chunk & chunk) { if(!base.seek(chunk.first_slice, chunk.offset)) { throw chunk_error("could not seek to chunk start"); } char magic[sizeof(chunk_id)]; if(base.read(magic, 4) != 4 || memcmp(magic, chunk_id, sizeof(chunk_id))) { throw chunk_error("bad chunk magic"); } pointer result(new boost::iostreams::chain); switch(chunk.compression) { case Stored: break; case Zlib: result->push(io::zlib_decompressor(), 8192); break; case BZip2: result->push(io::bzip2_decompressor(), 8192); break; #if INNOEXTRACT_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 " + std::string(innoextract_name) + " build"); #endif default: throw chunk_error("unknown chunk compression"); } result->push(restrict(base, chunk.size)); return result; } } // namespace stream NAMES(stream::compression_method, "Compression Method", "stored", "zlib", "bzip2", "lzma1", "lzma2", "unknown", )