winamp/Src/external_dependencies/openmpt-trunk/include/ancient/src/Decompressor.hpp

87 lines
3.1 KiB
C++

/* Copyright (C) Teemu Suutari */
#ifndef DECOMPRESSOR_HPP
#define DECOMPRESSOR_HPP
#include <cstddef>
#include <cstdint>
#include <memory>
#include <string>
#include "common/Buffer.hpp"
#include "ancient.hpp"
namespace ancient::internal
{
class Decompressor
{
protected:
Decompressor() noexcept;
public:
using Error = ancient::Error;
using InvalidFormatError = ancient::InvalidFormatError;
using DecompressionError = ancient::DecompressionError;
using VerificationError = ancient::VerificationError;
Decompressor(const Decompressor&)=delete;
Decompressor& operator=(const Decompressor&)=delete;
virtual ~Decompressor();
// Name returned is human readable long name
virtual const std::string &getName() const noexcept=0;
// PackedSize or RawSize are taken from the stream if available, 0 otherwise.
// for those compressors having 0 sizes, running decompression will update
// the values. (make sure to allocate big-enough buffer for decompression)
// There are exceptions: Some decompressors need to exact size of the packed data
// in order to decompress. For those providing a indefinitely size packed stream
// will not work
// use the "exactSizeKnown" flag for create to tell whether you know the size or not
virtual size_t getPackedSize() const noexcept=0;
virtual size_t getRawSize() const noexcept=0;
// Actual decompression.
// verify checksum if verify==true
// can throw DecompressionError if stream cant be unpacked
// can throw VerificationError if verify enabled and checksum does not match
void decompress(Buffer &rawData,bool verify);
// in case of disk image based formats the data does not necessarily start
// from logical beginnig of the image but it is offsetted inside the logical image
// (f.e. DMS). getDataOffset will return the offset (or 0 if not relevant or if offset does not exist)
// getImageSize will return the size of the the logical image, or 0 if not image-based format
virtual size_t getImageSize() const noexcept;
virtual size_t getImageOffset() const noexcept;
// the functions are there to protect against "accidental" large files when parsing headers
// a.k.a. 16M should be enough for everybody (sizes do not have to accurate i.e.
// compressors can exclude header content for simplification)
// This entirely ok for the context of "old computers" and their files,
// for other usages these need to be tuned up
static size_t getMaxPackedSize() noexcept;
static size_t getMaxRawSize() noexcept;
// Main entrypoint
// if verify=true then check the packedData for errors: CRC or other checksum if available
// check exactSizeKnown from size documentation
// can throw InvalidFormatError if stream is not recognized or it is invalid
// can throw VerificationError if verify enabled and checksum does not match
static std::shared_ptr<Decompressor> create(const Buffer &packedData,bool exactSizeKnown,bool verify);
// Detect signature whether it matches to any known compressor
// This does not guarantee the data is decompressable though, only signature is read
static bool detect(const Buffer &packedData) noexcept;
protected:
virtual void decompressImpl(Buffer &rawData,bool verify)=0;
};
}
#endif