87 lines
3.1 KiB
C++
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
|