#include "llvm/Support/Compression.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Config/config.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
#if LLVM_ENABLE_ZLIB
#include <zlib.h>
#endif
#if LLVM_ENABLE_ZSTD
#include <zstd.h>
#endif
usingnamespacellvm;
usingnamespacellvm::compression;
const char *compression::getReasonIfUnsupported(compression::Format F) { … }
void compression::compress(Params P, ArrayRef<uint8_t> Input,
SmallVectorImpl<uint8_t> &Output) { … }
Error compression::decompress(DebugCompressionType T, ArrayRef<uint8_t> Input,
uint8_t *Output, size_t UncompressedSize) { … }
Error compression::decompress(compression::Format F, ArrayRef<uint8_t> Input,
SmallVectorImpl<uint8_t> &Output,
size_t UncompressedSize) { … }
Error compression::decompress(DebugCompressionType T, ArrayRef<uint8_t> Input,
SmallVectorImpl<uint8_t> &Output,
size_t UncompressedSize) { … }
#if LLVM_ENABLE_ZLIB
static StringRef convertZlibCodeToString(int Code) { … }
bool zlib::isAvailable() { … }
void zlib::compress(ArrayRef<uint8_t> Input,
SmallVectorImpl<uint8_t> &CompressedBuffer, int Level) { … }
Error zlib::decompress(ArrayRef<uint8_t> Input, uint8_t *Output,
size_t &UncompressedSize) { … }
Error zlib::decompress(ArrayRef<uint8_t> Input,
SmallVectorImpl<uint8_t> &Output,
size_t UncompressedSize) { … }
#else
bool zlib::isAvailable() { return false; }
void zlib::compress(ArrayRef<uint8_t> Input,
SmallVectorImpl<uint8_t> &CompressedBuffer, int Level) {
llvm_unreachable("zlib::compress is unavailable");
}
Error zlib::decompress(ArrayRef<uint8_t> Input, uint8_t *UncompressedBuffer,
size_t &UncompressedSize) {
llvm_unreachable("zlib::decompress is unavailable");
}
Error zlib::decompress(ArrayRef<uint8_t> Input,
SmallVectorImpl<uint8_t> &UncompressedBuffer,
size_t UncompressedSize) {
llvm_unreachable("zlib::decompress is unavailable");
}
#endif
#if LLVM_ENABLE_ZSTD
bool zstd::isAvailable() { return true; }
#include <zstd.h>
void zstd::compress(ArrayRef<uint8_t> Input,
SmallVectorImpl<uint8_t> &CompressedBuffer, int Level,
bool EnableLdm) {
ZSTD_CCtx *Cctx = ZSTD_createCCtx();
if (!Cctx)
report_bad_alloc_error("Failed to create ZSTD_CCtx");
if (ZSTD_isError(ZSTD_CCtx_setParameter(
Cctx, ZSTD_c_enableLongDistanceMatching, EnableLdm ? 1 : 0))) {
ZSTD_freeCCtx(Cctx);
report_bad_alloc_error("Failed to set ZSTD_c_enableLongDistanceMatching");
}
if (ZSTD_isError(
ZSTD_CCtx_setParameter(Cctx, ZSTD_c_compressionLevel, Level))) {
ZSTD_freeCCtx(Cctx);
report_bad_alloc_error("Failed to set ZSTD_c_compressionLevel");
}
unsigned long CompressedBufferSize = ZSTD_compressBound(Input.size());
CompressedBuffer.resize_for_overwrite(CompressedBufferSize);
size_t const CompressedSize =
ZSTD_compress2(Cctx, CompressedBuffer.data(), CompressedBufferSize,
Input.data(), Input.size());
ZSTD_freeCCtx(Cctx);
if (ZSTD_isError(CompressedSize))
report_bad_alloc_error("Compression failed");
__msan_unpoison(CompressedBuffer.data(), CompressedSize);
if (CompressedSize < CompressedBuffer.size())
CompressedBuffer.truncate(CompressedSize);
}
Error zstd::decompress(ArrayRef<uint8_t> Input, uint8_t *Output,
size_t &UncompressedSize) {
const size_t Res = ::ZSTD_decompress(
Output, UncompressedSize, (const uint8_t *)Input.data(), Input.size());
UncompressedSize = Res;
__msan_unpoison(Output, UncompressedSize);
return ZSTD_isError(Res) ? make_error<StringError>(ZSTD_getErrorName(Res),
inconvertibleErrorCode())
: Error::success();
}
Error zstd::decompress(ArrayRef<uint8_t> Input,
SmallVectorImpl<uint8_t> &Output,
size_t UncompressedSize) {
Output.resize_for_overwrite(UncompressedSize);
Error E = zstd::decompress(Input, Output.data(), UncompressedSize);
if (UncompressedSize < Output.size())
Output.truncate(UncompressedSize);
return E;
}
#else
bool zstd::isAvailable() { … }
void zstd::compress(ArrayRef<uint8_t> Input,
SmallVectorImpl<uint8_t> &CompressedBuffer, int Level,
bool EnableLdm) { … }
Error zstd::decompress(ArrayRef<uint8_t> Input, uint8_t *Output,
size_t &UncompressedSize) { … }
Error zstd::decompress(ArrayRef<uint8_t> Input,
SmallVectorImpl<uint8_t> &Output,
size_t UncompressedSize) { … }
#endif