#pragma region CPL License /* Nuclex Native Framework Copyright (C) 2002-2013 Nuclex Development Labs This library is free software; you can redistribute it and/or modify it under the terms of the IBM Common Public License as published by the IBM Corporation; either version 1.0 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the IBM Common Public License for more details. You should have received a copy of the IBM Common Public License along with this library */ #pragma endregion // CPL License #ifndef NUCLEX_STORAGE_FILESYSTEM_SEVENZIP_DECODER_MULTIDECODERCONTEXT_H #define NUCLEX_STORAGE_FILESYSTEM_SEVENZIP_DECODER_MULTIDECODERCONTEXT_H #include "Nuclex/Storage/Config.h" #include "../SevenZipArchive.h" #include "../../../Helpers/StreamingCacheContext.h" #include "lzma/LzmaDec.h" namespace Nuclex { namespace Storage { namespace FileSystem { namespace SevenZip { // ------------------------------------------------------------------------------------------- // class StreamProcessor; // ------------------------------------------------------------------------------------------- // }}}} // namespace Nuclex::Storage::FileSystem::SevenZip namespace Nuclex { namespace Storage { namespace FileSystem { namespace SevenZip { // ------------------------------------------------------------------------------------------- // /// /// Maintains the decompression states and buffers for multiple chained decoders /// /// /// /// Currently this context is designed to assume one main input stream (containing /// the data to be decompressed) and any number of control streams that are extracted /// in full upfront (as they might contain data needed for decompression of the main /// stream - like dictionaries, seek offsets or compression settings). /// /// /// This assumption works for all current 7-Zip compression methods. All but one /// operate in a single stream and the one that does not - BCJ2 - still uses /// one main stream, one control stream and two supplemental streams that could /// perhaps be streamed, but in practice are so small that the overhead would likely /// offset any gain. /// /// class MultiDecoderContext : public Helpers::StreamingCacheContext { // LZMA requires a certain input length or there's no guarantee it can extract // anything from the buffer (LZMA_REQUIRED_INPUT_MAX is the number of bytes the worst-case // atomic chunk of compressed data can be long). static_assert( (BufferRefillSize >= LZMA_REQUIRED_INPUT_MAX), "Low water mark for input buffer must be more than the minimum LZMA input length" ); /// /// Initializes a new context for decoding data with multiple filters and/or /// decompressors chained together /// /// Archive the decoder context will work on /// /// Index of the solid block this context will decode /// public: MultiDecoderContext( const std::shared_ptr &sevenZipArchive, std::size_t solidBlockIndex ); /// Adds a stream processor through which data will be processed /// /// Stream processor that will be applied to data read from the context /// public: void AddStreamProcessor(const std::shared_ptr &streamProcessor); /// Skips forward until the specified location is reached /// Location up to which data will be skipped protected: void SkipTo(std::uint64_t location); /// Extracts data directly into the caller-provided memory block /// Location from which on extraction should begin /// Buffer into which the data will be read /// Number of bytes the caller wants to read /// The number of bytes remaining to be extracted protected: std::size_t ExtractDirectly( std::uint8_t *indexableBuffer, std::size_t count ); /// Extracts data using the decompression buffer and provides it /// Location from which on extraction should begin /// Buffer into which the data will be read /// Number of bytes the caller wants to read protected: void ExtractUsingBuffer( std::uint8_t *indexableBuffer, std::size_t count ); /// 7-zip archive the context is extracting private: std::shared_ptr sevenZipArchive; /// Current location within the compressed data private: std::size_t inputBufferLocation; /// Stream processors used by the reader to uncompress data private: std::vector< std::shared_ptr > streamProcessors; }; // ------------------------------------------------------------------------------------------- // }}}} // namespace Nuclex::Storage::FileSystem::SevenZip #endif // NUCLEX_STORAGE_FILESYSTEM_SEVENZIP_DECODER_MULTIDECODERCONTEXT_H