#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_ZIP_ZIPPEDFILEEXTRACTIONCACHE_H #define NUCLEX_STORAGE_FILESYSTEM_ZIP_ZIPPEDFILEEXTRACTIONCACHE_H #include "Nuclex/Storage/Config.h" #include "../../Helpers/StreamingCacheContext.h" #include "ZippedFile.h" #include #include namespace Nuclex { namespace Storage { // ------------------------------------------------------------------------------------------- // class Blob; // ------------------------------------------------------------------------------------------- // }} // namespace Nuclex::Storage namespace Nuclex { namespace Storage { namespace FileSystem { namespace Zip { // ------------------------------------------------------------------------------------------- // /// Compares two meta data instances class MetaDataEqualTo { /// Determines whether two meta data instances refer to the same file /// Meta data instance that will be compared on the left side /// Meta data instance that will be compared on the right side /// True if both instances refer to the same file, false otherwise public: bool operator()( const ZippedFile::MetaData &left, const ZippedFile::MetaData &right ) { return left.CompressedDataOffset == right.CompressedDataOffset; } }; // ------------------------------------------------------------------------------------------- // /// Caches zip decoders to accelerate interleaved extraction of data class ZipReader : public Helpers::Cache { #pragma region class DeflateContext /// Maintains a ZLib decompression stream and buffers extracted data protected: class DeflateContext : public Cache::Context { /// Initializes a new zip extraction context /// Blob containing the data that will be extracted /// Meta data about the compressed file public: DeflateContext( const std::shared_ptr &blob, const ZippedFile::MetaData &metaData ); /// Frees all resources owned by the zip extraction context public: virtual ~DeflateContext(); /// Reads data from the context /// Location from which data needs to be read /// Buffer into which the data will be read /// Number of bytes that need to be read public: virtual void ReadAt( std::uint64_t location, void *buffer, std::size_t count ); /// Skips forward until the specified location is reached /// Location up to which data will be skipped private: void skipTo(std::uint64_t location); /// 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 private: void extractUsingBuffer(std::uint8_t *indexableBuffer, std::size_t count); /// 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 private: std::size_t extractDirectly(std::uint8_t *indexableBuffer, std::size_t count); /// Fills the input buffer back up private: void refillInputBuffer(); /// Blob the context is caching data for private: std::shared_ptr blob; /// Stores internal data used by ZLib private: z_stream zlibStream; /// Contains the compressed data private: std::vector compressedData; /// Contains the uncompressed data private: std::vector uncompressedData; /// Current location within the compressed data private: std::uint64_t compressedLocation; /// Number of bytes of compressed data that are remaining private: std::uint64_t compressedRemaining; }; #pragma endregion // class DeflateContext /// Initializes a new zip extraction cache /// File that will be extracted public: ZipReader(const std::shared_ptr &blob); /// Frees all resources used by the cache instance public: virtual ~ZipReader() {} /// Reads the specified number of bytes from the file /// Meta data about the file being accessed /// Absolute file position the data will be read from /// Buffer into which the data will be read /// Number of bytes that will be read public: void ReadAt( const ZippedFile::MetaData &metaData, std::uint64_t position, void *buffer, std::size_t count ); /// Creates a new context storing the state of a decompressor /// /// Informations about the compressed file for which a new context is required /// /// The new context protected: virtual Context *CreateContext(const ZippedFile::MetaData &metaData); private: ZipReader(const ZipReader &); private: ZipReader &operator =(const ZipReader &); /// File contents that will be extracted private: std::shared_ptr blob; }; // ------------------------------------------------------------------------------------------- // }}}} // namespace Nuclex::Storage::FileSystem::Zip #endif // NUCLEX_STORAGE_FILESYSTEM_ZIP_ZIPPEDFILEEXTRACTIONCACHE_H