#pragma region CPL License
/*
Nuclex Native Framework
Copyright (C) 2002-2021 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_COMPRESSION_ZPAQ_ZPAQDECOMPRESSOR_H
#define NUCLEX_STORAGE_COMPRESSION_ZPAQ_ZPAQDECOMPRESSOR_H
#include "Nuclex/Storage/Config.h"
#if defined(NUCLEX_STORAGE_HAVE_ZPAQ)
#include "Nuclex/Storage/Compression/Decompressor.h"
#include "ZPaqHelper.h"
namespace Nuclex { namespace Storage { namespace Compression { namespace ZPaq {
// ------------------------------------------------------------------------------------------- //
/// Decompresses data using the ZPaq library and algorithm
class ZPaqDecompressor : public Decompressor {
/// Initializes a new ZPaq decompressor
public: ZPaqDecompressor();
/// Frees all resources owned by the instance
public: ~ZPaqDecompressor() override;
///
/// Decompresses the data in the input buffer and writes it to the output buffer
///
/// Buffer containing the compressed data
///
/// Number of compressed bytes in the compressed buffer. Will be set to
/// the number of remaining bytes when the method returns
///
/// Buffer in which the uncompressed data will be stored
///
/// Available space in the output buffer. Will be set to the bytes actually stored
/// in the output buffer when the method returns
///
///
/// The reason why the method stopped processing data. This may either be because
/// all available input was decompressed, or because the decompressor ran out of
/// space in the output buffer.
///
public: StopReason Process(
const std::uint8_t *compressedBuffer, std::size_t &compressedByteCount,
std::uint8_t *outputBuffer, std::size_t &outputByteCount
) override;
/// Finishes decompressing and writes any remaining output bytes
/// Buffer in which the decompressed data will be stored
///
/// Available space in the output buffer. Will be set to the bytes actually stored
/// in the output buffer when the method returns.
///
///
/// The reason why the method stopped processing. This should normally be the
/// value but may also be
/// if the output buffer was insufficient
/// to output all data (in which case you need to call Finish() another time).
///
public: StopReason Finish(
std::uint8_t *outputBuffer, std::size_t &outputByteCount
) override;
/// Maintains the ZPAQ decompressor's state
private: libzpaq::Decompresser decompressor;
/// Whether the ZPaq decompressor has found the block yet
private: bool hasFoundBlock;
/// Whether the ZPaq decompressor has found the filename yet
private: bool hasFoundFilename;
/// Whether the compressor is in finishing mode
///
/// This is set when endSegment() and endBlock() have been called on the ZPaq compressor
/// to avoid called those methods multiple times.
///
private: bool isFinishing;
///
/// Holds output data that didn't fit into the output buffer but had to be
/// produced because the decompressor cannot be stopped when the output buffer is full
///
private: SplitBufferWriter writer;
/// Reader that will be provide data from the buffers to libzpaq
private: FixedBufferReader reader;
};
// ------------------------------------------------------------------------------------------- //
}}}} // namespace Nuclex::Storage::Compression::ZPaq
#endif // defined(NUCLEX_STORAGE_HAVE_ZPAQ)
#endif // NUCLEX_STORAGE_COMPRESSION_ZPAQ_ZPAQDECOMPRESSOR_H