xref: /haiku/src/kits/support/ZstdCompressionAlgorithm.cpp (revision b3731f13abd12c63cf626cfa8138943f500e1471)
16ac3a280SJérôme Duval /*
26ac3a280SJérôme Duval  * Copyright 2017, Jérôme Duval.
36ac3a280SJérôme Duval  * Copyright 2014, Ingo Weinhold, ingo_weinhold@gmx.de.
46ac3a280SJérôme Duval  * Distributed under the terms of the MIT License.
56ac3a280SJérôme Duval  */
66ac3a280SJérôme Duval 
76ac3a280SJérôme Duval 
86ac3a280SJérôme Duval #include <ZstdCompressionAlgorithm.h>
96ac3a280SJérôme Duval 
106ac3a280SJérôme Duval #include <errno.h>
116ac3a280SJérôme Duval #include <string.h>
126ac3a280SJérôme Duval 
136ac3a280SJérôme Duval #include <algorithm>
146ac3a280SJérôme Duval #include <new>
156ac3a280SJérôme Duval 
166ac3a280SJérôme Duval #ifdef ZSTD_ENABLED
176ac3a280SJérôme Duval   #include <zstd.h>
186ac3a280SJérôme Duval   #include <zstd_errors.h>
196ac3a280SJérôme Duval #endif
206ac3a280SJérôme Duval 
216ac3a280SJérôme Duval #include <DataIO.h>
226ac3a280SJérôme Duval 
236ac3a280SJérôme Duval 
246ac3a280SJérôme Duval // build compression support only for userland
256ac3a280SJérôme Duval #if defined(ZSTD_ENABLED) && !defined(_KERNEL_MODE) && !defined(_BOOT_MODE)
266ac3a280SJérôme Duval #	define B_ZSTD_COMPRESSION_SUPPORT 1
276ac3a280SJérôme Duval #endif
286ac3a280SJérôme Duval 
296ac3a280SJérôme Duval 
306ac3a280SJérôme Duval static const size_t kMinBufferSize		= 1024;
316ac3a280SJérôme Duval static const size_t kMaxBufferSize		= 1024 * 1024;
326ac3a280SJérôme Duval static const size_t kDefaultBufferSize	= 4 * 1024;
336ac3a280SJérôme Duval 
346ac3a280SJérôme Duval 
356ac3a280SJérôme Duval static size_t
sanitize_buffer_size(size_t size)366ac3a280SJérôme Duval sanitize_buffer_size(size_t size)
376ac3a280SJérôme Duval {
386ac3a280SJérôme Duval 	if (size < kMinBufferSize)
396ac3a280SJérôme Duval 		return kMinBufferSize;
406ac3a280SJérôme Duval 	return std::min(size, kMaxBufferSize);
416ac3a280SJérôme Duval }
426ac3a280SJérôme Duval 
436ac3a280SJérôme Duval 
446ac3a280SJérôme Duval // #pragma mark - BZstdCompressionParameters
456ac3a280SJérôme Duval 
466ac3a280SJérôme Duval 
BZstdCompressionParameters(int compressionLevel)476ac3a280SJérôme Duval BZstdCompressionParameters::BZstdCompressionParameters(
486ac3a280SJérôme Duval 	int compressionLevel)
496ac3a280SJérôme Duval 	:
506ac3a280SJérôme Duval 	BCompressionParameters(),
516ac3a280SJérôme Duval 	fCompressionLevel(compressionLevel),
526ac3a280SJérôme Duval 	fBufferSize(kDefaultBufferSize)
536ac3a280SJérôme Duval {
546ac3a280SJérôme Duval }
556ac3a280SJérôme Duval 
566ac3a280SJérôme Duval 
~BZstdCompressionParameters()576ac3a280SJérôme Duval BZstdCompressionParameters::~BZstdCompressionParameters()
586ac3a280SJérôme Duval {
596ac3a280SJérôme Duval }
606ac3a280SJérôme Duval 
616ac3a280SJérôme Duval 
626ac3a280SJérôme Duval int32
CompressionLevel() const636ac3a280SJérôme Duval BZstdCompressionParameters::CompressionLevel() const
646ac3a280SJérôme Duval {
656ac3a280SJérôme Duval 	return fCompressionLevel;
666ac3a280SJérôme Duval }
676ac3a280SJérôme Duval 
686ac3a280SJérôme Duval 
696ac3a280SJérôme Duval void
SetCompressionLevel(int32 level)706ac3a280SJérôme Duval BZstdCompressionParameters::SetCompressionLevel(int32 level)
716ac3a280SJérôme Duval {
726ac3a280SJérôme Duval 	fCompressionLevel = level;
736ac3a280SJérôme Duval }
746ac3a280SJérôme Duval 
756ac3a280SJérôme Duval 
766ac3a280SJérôme Duval size_t
BufferSize() const776ac3a280SJérôme Duval BZstdCompressionParameters::BufferSize() const
786ac3a280SJérôme Duval {
796ac3a280SJérôme Duval 	return fBufferSize;
806ac3a280SJérôme Duval }
816ac3a280SJérôme Duval 
826ac3a280SJérôme Duval 
836ac3a280SJérôme Duval void
SetBufferSize(size_t size)846ac3a280SJérôme Duval BZstdCompressionParameters::SetBufferSize(size_t size)
856ac3a280SJérôme Duval {
866ac3a280SJérôme Duval 	fBufferSize = sanitize_buffer_size(size);
876ac3a280SJérôme Duval }
886ac3a280SJérôme Duval 
896ac3a280SJérôme Duval 
906ac3a280SJérôme Duval // #pragma mark - BZstdDecompressionParameters
916ac3a280SJérôme Duval 
926ac3a280SJérôme Duval 
BZstdDecompressionParameters()936ac3a280SJérôme Duval BZstdDecompressionParameters::BZstdDecompressionParameters()
946ac3a280SJérôme Duval 	:
956ac3a280SJérôme Duval 	BDecompressionParameters(),
966ac3a280SJérôme Duval 	fBufferSize(kDefaultBufferSize)
976ac3a280SJérôme Duval {
986ac3a280SJérôme Duval }
996ac3a280SJérôme Duval 
1006ac3a280SJérôme Duval 
~BZstdDecompressionParameters()1016ac3a280SJérôme Duval BZstdDecompressionParameters::~BZstdDecompressionParameters()
1026ac3a280SJérôme Duval {
1036ac3a280SJérôme Duval }
1046ac3a280SJérôme Duval 
1056ac3a280SJérôme Duval 
1066ac3a280SJérôme Duval size_t
BufferSize() const1076ac3a280SJérôme Duval BZstdDecompressionParameters::BufferSize() const
1086ac3a280SJérôme Duval {
1096ac3a280SJérôme Duval 	return fBufferSize;
1106ac3a280SJérôme Duval }
1116ac3a280SJérôme Duval 
1126ac3a280SJérôme Duval 
1136ac3a280SJérôme Duval void
SetBufferSize(size_t size)1146ac3a280SJérôme Duval BZstdDecompressionParameters::SetBufferSize(size_t size)
1156ac3a280SJérôme Duval {
1166ac3a280SJérôme Duval 	fBufferSize = sanitize_buffer_size(size);
1176ac3a280SJérôme Duval }
1186ac3a280SJérôme Duval 
1196ac3a280SJérôme Duval 
1206ac3a280SJérôme Duval // #pragma mark - CompressionStrategy
1216ac3a280SJérôme Duval 
1226ac3a280SJérôme Duval 
1236ac3a280SJérôme Duval #ifdef B_ZSTD_COMPRESSION_SUPPORT
1246ac3a280SJérôme Duval 
1256ac3a280SJérôme Duval 
1266ac3a280SJérôme Duval struct BZstdCompressionAlgorithm::CompressionStrategy {
1276ac3a280SJérôme Duval 	typedef BZstdCompressionParameters Parameters;
1286ac3a280SJérôme Duval 
1296ac3a280SJérôme Duval 	static const bool kNeedsFinalFlush = true;
1306ac3a280SJérôme Duval 
InitBZstdCompressionAlgorithm::CompressionStrategy1316ac3a280SJérôme Duval 	static size_t Init(ZSTD_CStream **stream,
1326ac3a280SJérôme Duval 		const BZstdCompressionParameters* parameters)
1336ac3a280SJérôme Duval 	{
1346ac3a280SJérôme Duval 		int32 compressionLevel = B_ZSTD_COMPRESSION_DEFAULT;
1356ac3a280SJérôme Duval 		if (parameters != NULL) {
1366ac3a280SJérôme Duval 			compressionLevel = parameters->CompressionLevel();
1376ac3a280SJérôme Duval 		}
1386ac3a280SJérôme Duval 
1396ac3a280SJérôme Duval 		*stream = ZSTD_createCStream();
1406ac3a280SJérôme Duval 		return ZSTD_initCStream(*stream, compressionLevel);
1416ac3a280SJérôme Duval 	}
1426ac3a280SJérôme Duval 
UninitBZstdCompressionAlgorithm::CompressionStrategy1436ac3a280SJérôme Duval 	static void Uninit(ZSTD_CStream *stream)
1446ac3a280SJérôme Duval 	{
1456ac3a280SJérôme Duval 		ZSTD_freeCStream(stream);
1466ac3a280SJérôme Duval 	}
1476ac3a280SJérôme Duval 
ProcessBZstdCompressionAlgorithm::CompressionStrategy1486ac3a280SJérôme Duval 	static size_t Process(ZSTD_CStream *stream, ZSTD_inBuffer *input,
1496ac3a280SJérôme Duval 		ZSTD_outBuffer *output, bool flush)
1506ac3a280SJérôme Duval 	{
1516ac3a280SJérôme Duval 		if (flush)
1526ac3a280SJérôme Duval 			return ZSTD_flushStream(stream, output);
1536ac3a280SJérôme Duval 		else
1546ac3a280SJérôme Duval 			return ZSTD_compressStream(stream, output, input);
1556ac3a280SJérôme Duval 	}
1566ac3a280SJérôme Duval };
1576ac3a280SJérôme Duval 
1586ac3a280SJérôme Duval 
1596ac3a280SJérôme Duval #endif	// B_ZSTD_COMPRESSION_SUPPORT
1606ac3a280SJérôme Duval 
1616ac3a280SJérôme Duval 
1626ac3a280SJérôme Duval // #pragma mark - DecompressionStrategy
1636ac3a280SJérôme Duval 
1646ac3a280SJérôme Duval 
1656ac3a280SJérôme Duval #ifdef ZSTD_ENABLED
1666ac3a280SJérôme Duval 
1676ac3a280SJérôme Duval 
1686ac3a280SJérôme Duval struct BZstdCompressionAlgorithm::DecompressionStrategy {
1696ac3a280SJérôme Duval 	typedef BZstdDecompressionParameters Parameters;
1706ac3a280SJérôme Duval 
1716ac3a280SJérôme Duval 	static const bool kNeedsFinalFlush = false;
1726ac3a280SJérôme Duval 
InitBZstdCompressionAlgorithm::DecompressionStrategy1736ac3a280SJérôme Duval 	static size_t Init(ZSTD_DStream **stream,
1746ac3a280SJérôme Duval 		const BZstdDecompressionParameters* /*parameters*/)
1756ac3a280SJérôme Duval 	{
1766ac3a280SJérôme Duval 		*stream = ZSTD_createDStream();
1776ac3a280SJérôme Duval 		return ZSTD_initDStream(*stream);
1786ac3a280SJérôme Duval 	}
1796ac3a280SJérôme Duval 
UninitBZstdCompressionAlgorithm::DecompressionStrategy1806ac3a280SJérôme Duval 	static void Uninit(ZSTD_DStream *stream)
1816ac3a280SJérôme Duval 	{
1826ac3a280SJérôme Duval 		ZSTD_freeDStream(stream);
1836ac3a280SJérôme Duval 	}
1846ac3a280SJérôme Duval 
ProcessBZstdCompressionAlgorithm::DecompressionStrategy1856ac3a280SJérôme Duval 	static size_t Process(ZSTD_DStream *stream, ZSTD_inBuffer *input,
1866ac3a280SJérôme Duval 		ZSTD_outBuffer *output, bool flush)
1876ac3a280SJérôme Duval 	{
1886ac3a280SJérôme Duval 		return ZSTD_decompressStream(stream, output, input);
1896ac3a280SJérôme Duval 	}
1906ac3a280SJérôme Duval 
1916ac3a280SJérôme Duval };
1926ac3a280SJérôme Duval 
1936ac3a280SJérôme Duval 
1946ac3a280SJérôme Duval // #pragma mark - Stream
1956ac3a280SJérôme Duval 
1966ac3a280SJérôme Duval 
1976ac3a280SJérôme Duval template<typename BaseClass, typename Strategy, typename StreamType>
1986ac3a280SJérôme Duval struct BZstdCompressionAlgorithm::Stream : BaseClass {
StreamBZstdCompressionAlgorithm::Stream1996ac3a280SJérôme Duval 	Stream(BDataIO* io)
2006ac3a280SJérôme Duval 		:
2016ac3a280SJérôme Duval 		BaseClass(io),
2026ac3a280SJérôme Duval 		fStreamInitialized(false)
2036ac3a280SJérôme Duval 	{
2046ac3a280SJérôme Duval 	}
2056ac3a280SJérôme Duval 
~StreamBZstdCompressionAlgorithm::Stream2066ac3a280SJérôme Duval 	~Stream()
2076ac3a280SJérôme Duval 	{
2086ac3a280SJérôme Duval 		if (fStreamInitialized) {
2096ac3a280SJérôme Duval 			if (Strategy::kNeedsFinalFlush)
2106ac3a280SJérôme Duval 				this->Flush();
2116ac3a280SJérôme Duval 			Strategy::Uninit(fStream);
2126ac3a280SJérôme Duval 		}
2136ac3a280SJérôme Duval 	}
2146ac3a280SJérôme Duval 
InitBZstdCompressionAlgorithm::Stream2156ac3a280SJérôme Duval 	status_t Init(const typename Strategy::Parameters* parameters)
2166ac3a280SJérôme Duval 	{
2176ac3a280SJérôme Duval 		status_t error = this->BaseClass::Init(
2186ac3a280SJérôme Duval 			parameters != NULL ? parameters->BufferSize() : kDefaultBufferSize);
2196ac3a280SJérôme Duval 		if (error != B_OK)
2206ac3a280SJérôme Duval 			return error;
2216ac3a280SJérôme Duval 
2226ac3a280SJérôme Duval 		size_t zstdError = Strategy::Init(&fStream, parameters);
2236ac3a280SJérôme Duval 		if (ZSTD_getErrorCode(zstdError) != ZSTD_error_no_error)
2246ac3a280SJérôme Duval 			return _TranslateZstdError(zstdError);
2256ac3a280SJérôme Duval 
2266ac3a280SJérôme Duval 		fStreamInitialized = true;
2276ac3a280SJérôme Duval 		return B_OK;
2286ac3a280SJérôme Duval 	}
2296ac3a280SJérôme Duval 
ProcessDataBZstdCompressionAlgorithm::Stream2306ac3a280SJérôme Duval 	virtual status_t ProcessData(const void* input, size_t inputSize,
2316ac3a280SJérôme Duval 		void* output, size_t outputSize, size_t& bytesConsumed,
2326ac3a280SJérôme Duval 		size_t& bytesProduced)
2336ac3a280SJérôme Duval 	{
2346ac3a280SJérôme Duval 		return _ProcessData(input, inputSize, output, outputSize,
2356ac3a280SJérôme Duval 			bytesConsumed, bytesProduced, false);
2366ac3a280SJérôme Duval 	}
2376ac3a280SJérôme Duval 
FlushPendingDataBZstdCompressionAlgorithm::Stream2386ac3a280SJérôme Duval 	virtual status_t FlushPendingData(void* output, size_t outputSize,
2396ac3a280SJérôme Duval 		size_t& bytesProduced)
2406ac3a280SJérôme Duval 	{
2416ac3a280SJérôme Duval 		size_t bytesConsumed;
2426ac3a280SJérôme Duval 		return _ProcessData(NULL, 0, output, outputSize,
2436ac3a280SJérôme Duval 			bytesConsumed, bytesProduced, true);
2446ac3a280SJérôme Duval 	}
2456ac3a280SJérôme Duval 
2466ac3a280SJérôme Duval 	template<typename BaseParameters>
CreateBZstdCompressionAlgorithm::Stream2476ac3a280SJérôme Duval 	static status_t Create(BDataIO* io, BaseParameters* _parameters,
2486ac3a280SJérôme Duval 		BDataIO*& _stream)
2496ac3a280SJérôme Duval 	{
2506ac3a280SJérôme Duval 		const typename Strategy::Parameters* parameters
2516ac3a280SJérôme Duval #ifdef _BOOT_MODE
2526ac3a280SJérôme Duval 			= static_cast<const typename Strategy::Parameters*>(_parameters);
2536ac3a280SJérôme Duval #else
2546ac3a280SJérôme Duval 			= dynamic_cast<const typename Strategy::Parameters*>(_parameters);
2556ac3a280SJérôme Duval #endif
2566ac3a280SJérôme Duval 		Stream* stream = new(std::nothrow) Stream(io);
2576ac3a280SJérôme Duval 		if (stream == NULL)
2586ac3a280SJérôme Duval 			return B_NO_MEMORY;
2596ac3a280SJérôme Duval 
2606ac3a280SJérôme Duval 		status_t error = stream->Init(parameters);
2616ac3a280SJérôme Duval 		if (error != B_OK) {
2626ac3a280SJérôme Duval 			delete stream;
2636ac3a280SJérôme Duval 			return error;
2646ac3a280SJérôme Duval 		}
2656ac3a280SJérôme Duval 
2666ac3a280SJérôme Duval 		_stream = stream;
2676ac3a280SJérôme Duval 		return B_OK;
2686ac3a280SJérôme Duval 	}
2696ac3a280SJérôme Duval 
2706ac3a280SJérôme Duval private:
_ProcessDataBZstdCompressionAlgorithm::Stream2716ac3a280SJérôme Duval 	status_t _ProcessData(const void* input, size_t inputSize,
2726ac3a280SJérôme Duval 		void* output, size_t outputSize, size_t& bytesConsumed,
2736ac3a280SJérôme Duval 		size_t& bytesProduced, bool flush)
2746ac3a280SJérôme Duval 	{
2756ac3a280SJérôme Duval 		inBuffer.src = input;
2766ac3a280SJérôme Duval 		inBuffer.pos = 0;
2776ac3a280SJérôme Duval 		inBuffer.size = inputSize;
2786ac3a280SJérôme Duval 		outBuffer.dst = output;
2796ac3a280SJérôme Duval 		outBuffer.pos = 0;
2806ac3a280SJérôme Duval 		outBuffer.size = outputSize;
2816ac3a280SJérôme Duval 
2826ac3a280SJérôme Duval 		size_t zstdError = Strategy::Process(fStream, &inBuffer, &outBuffer, flush);
2836ac3a280SJérôme Duval 		if (ZSTD_getErrorCode(zstdError) != ZSTD_error_no_error)
2846ac3a280SJérôme Duval 			return _TranslateZstdError(zstdError);
2856ac3a280SJérôme Duval 
2866ac3a280SJérôme Duval 		bytesConsumed = inBuffer.pos;
2876ac3a280SJérôme Duval 		bytesProduced = outBuffer.pos;
2886ac3a280SJérôme Duval 		return B_OK;
2896ac3a280SJérôme Duval 	}
2906ac3a280SJérôme Duval 
2916ac3a280SJérôme Duval private:
2926ac3a280SJérôme Duval 	bool		fStreamInitialized;
2936ac3a280SJérôme Duval 	StreamType	*fStream;
2946ac3a280SJérôme Duval 	ZSTD_inBuffer inBuffer;
2956ac3a280SJérôme Duval 	ZSTD_outBuffer outBuffer;
2966ac3a280SJérôme Duval };
2976ac3a280SJérôme Duval 
2986ac3a280SJérôme Duval 
2996ac3a280SJérôme Duval #endif	// ZSTD_ENABLED
3006ac3a280SJérôme Duval 
3016ac3a280SJérôme Duval 
3026ac3a280SJérôme Duval // #pragma mark - BZstdCompressionAlgorithm
3036ac3a280SJérôme Duval 
3046ac3a280SJérôme Duval 
BZstdCompressionAlgorithm()3056ac3a280SJérôme Duval BZstdCompressionAlgorithm::BZstdCompressionAlgorithm()
3066ac3a280SJérôme Duval 	:
3076ac3a280SJérôme Duval 	BCompressionAlgorithm()
3086ac3a280SJérôme Duval {
3096ac3a280SJérôme Duval }
3106ac3a280SJérôme Duval 
3116ac3a280SJérôme Duval 
~BZstdCompressionAlgorithm()3126ac3a280SJérôme Duval BZstdCompressionAlgorithm::~BZstdCompressionAlgorithm()
3136ac3a280SJérôme Duval {
3146ac3a280SJérôme Duval }
3156ac3a280SJérôme Duval 
3166ac3a280SJérôme Duval 
3176ac3a280SJérôme Duval status_t
CreateCompressingInputStream(BDataIO * input,const BCompressionParameters * parameters,BDataIO * & _stream)3186ac3a280SJérôme Duval BZstdCompressionAlgorithm::CreateCompressingInputStream(BDataIO* input,
3196ac3a280SJérôme Duval 	const BCompressionParameters* parameters, BDataIO*& _stream)
3206ac3a280SJérôme Duval {
3216ac3a280SJérôme Duval #ifdef B_ZSTD_COMPRESSION_SUPPORT
3226ac3a280SJérôme Duval 	return Stream<BAbstractInputStream, CompressionStrategy, ZSTD_CStream>::Create(
3236ac3a280SJérôme Duval 		input, parameters, _stream);
3246ac3a280SJérôme Duval #else
3256ac3a280SJérôme Duval 	return B_NOT_SUPPORTED;
3266ac3a280SJérôme Duval #endif
3276ac3a280SJérôme Duval }
3286ac3a280SJérôme Duval 
3296ac3a280SJérôme Duval 
3306ac3a280SJérôme Duval status_t
CreateCompressingOutputStream(BDataIO * output,const BCompressionParameters * parameters,BDataIO * & _stream)3316ac3a280SJérôme Duval BZstdCompressionAlgorithm::CreateCompressingOutputStream(BDataIO* output,
3326ac3a280SJérôme Duval 	const BCompressionParameters* parameters, BDataIO*& _stream)
3336ac3a280SJérôme Duval {
3346ac3a280SJérôme Duval #ifdef B_ZSTD_COMPRESSION_SUPPORT
3356ac3a280SJérôme Duval 	return Stream<BAbstractOutputStream, CompressionStrategy, ZSTD_CStream>::Create(
3366ac3a280SJérôme Duval 		output, parameters, _stream);
3376ac3a280SJérôme Duval #else
3386ac3a280SJérôme Duval 	return B_NOT_SUPPORTED;
3396ac3a280SJérôme Duval #endif
3406ac3a280SJérôme Duval }
3416ac3a280SJérôme Duval 
3426ac3a280SJérôme Duval 
3436ac3a280SJérôme Duval status_t
CreateDecompressingInputStream(BDataIO * input,const BDecompressionParameters * parameters,BDataIO * & _stream)3446ac3a280SJérôme Duval BZstdCompressionAlgorithm::CreateDecompressingInputStream(BDataIO* input,
3456ac3a280SJérôme Duval 	const BDecompressionParameters* parameters, BDataIO*& _stream)
3466ac3a280SJérôme Duval {
3476ac3a280SJérôme Duval #ifdef ZSTD_ENABLED
3486ac3a280SJérôme Duval 	return Stream<BAbstractInputStream, DecompressionStrategy, ZSTD_DStream>::Create(
3496ac3a280SJérôme Duval 		input, parameters, _stream);
3506ac3a280SJérôme Duval #else
3516ac3a280SJérôme Duval 	return B_NOT_SUPPORTED;
3526ac3a280SJérôme Duval #endif
3536ac3a280SJérôme Duval }
3546ac3a280SJérôme Duval 
3556ac3a280SJérôme Duval 
3566ac3a280SJérôme Duval status_t
CreateDecompressingOutputStream(BDataIO * output,const BDecompressionParameters * parameters,BDataIO * & _stream)3576ac3a280SJérôme Duval BZstdCompressionAlgorithm::CreateDecompressingOutputStream(BDataIO* output,
3586ac3a280SJérôme Duval 	const BDecompressionParameters* parameters, BDataIO*& _stream)
3596ac3a280SJérôme Duval {
3606ac3a280SJérôme Duval #ifdef ZSTD_ENABLED
3616ac3a280SJérôme Duval 	return Stream<BAbstractOutputStream, DecompressionStrategy, ZSTD_DStream>::Create(
3626ac3a280SJérôme Duval 		output, parameters, _stream);
3636ac3a280SJérôme Duval #else
3646ac3a280SJérôme Duval 	return B_NOT_SUPPORTED;
3656ac3a280SJérôme Duval #endif
3666ac3a280SJérôme Duval }
3676ac3a280SJérôme Duval 
3686ac3a280SJérôme Duval 
3696ac3a280SJérôme Duval status_t
CompressBuffer(const void * input,size_t inputSize,void * output,size_t outputSize,size_t & _compressedSize,const BCompressionParameters * parameters)3706ac3a280SJérôme Duval BZstdCompressionAlgorithm::CompressBuffer(const void* input,
3716ac3a280SJérôme Duval 	size_t inputSize, void* output, size_t outputSize, size_t& _compressedSize,
3726ac3a280SJérôme Duval 	const BCompressionParameters* parameters)
3736ac3a280SJérôme Duval {
3746ac3a280SJérôme Duval #ifdef B_ZSTD_COMPRESSION_SUPPORT
3756ac3a280SJérôme Duval 	const BZstdCompressionParameters* zstdParameters
3766ac3a280SJérôme Duval 		= dynamic_cast<const BZstdCompressionParameters*>(parameters);
3776ac3a280SJérôme Duval 	int compressionLevel = zstdParameters != NULL
3786ac3a280SJérôme Duval 		? zstdParameters->CompressionLevel()
3796ac3a280SJérôme Duval 		: B_ZSTD_COMPRESSION_DEFAULT;
3806ac3a280SJérôme Duval 
3816ac3a280SJérôme Duval 	size_t zstdError = ZSTD_compress(output, outputSize, input,
3826ac3a280SJérôme Duval 		inputSize, compressionLevel);
3836ac3a280SJérôme Duval 	if (ZSTD_isError(zstdError))
3846ac3a280SJérôme Duval 		return _TranslateZstdError(zstdError);
3856ac3a280SJérôme Duval 
3866ac3a280SJérôme Duval 	_compressedSize = zstdError;
3876ac3a280SJérôme Duval 	return B_OK;
3886ac3a280SJérôme Duval #else
3896ac3a280SJérôme Duval 	return B_NOT_SUPPORTED;
3906ac3a280SJérôme Duval #endif
3916ac3a280SJérôme Duval }
3926ac3a280SJérôme Duval 
3936ac3a280SJérôme Duval 
3946ac3a280SJérôme Duval status_t
DecompressBuffer(const void * input,size_t inputSize,void * output,size_t outputSize,size_t & _uncompressedSize,const BDecompressionParameters * parameters)3956ac3a280SJérôme Duval BZstdCompressionAlgorithm::DecompressBuffer(const void* input,
3966ac3a280SJérôme Duval 	size_t inputSize, void* output, size_t outputSize,
3976ac3a280SJérôme Duval 	size_t& _uncompressedSize, const BDecompressionParameters* parameters)
3986ac3a280SJérôme Duval {
3996ac3a280SJérôme Duval #ifdef ZSTD_ENABLED
4006ac3a280SJérôme Duval 	size_t zstdError = ZSTD_decompress(output, outputSize, input,
4016ac3a280SJérôme Duval 		inputSize);
4026ac3a280SJérôme Duval 	if (ZSTD_isError(zstdError))
4036ac3a280SJérôme Duval 		return _TranslateZstdError(zstdError);
4046ac3a280SJérôme Duval 
4056ac3a280SJérôme Duval 	_uncompressedSize = zstdError;
4066ac3a280SJérôme Duval 	return B_OK;
4076ac3a280SJérôme Duval #else
4086ac3a280SJérôme Duval 	return B_NOT_SUPPORTED;
4096ac3a280SJérôme Duval #endif
4106ac3a280SJérôme Duval }
4116ac3a280SJérôme Duval 
4126ac3a280SJérôme Duval 
4136ac3a280SJérôme Duval /*static*/ status_t
_TranslateZstdError(size_t error)4146ac3a280SJérôme Duval BZstdCompressionAlgorithm::_TranslateZstdError(size_t error)
4156ac3a280SJérôme Duval {
4166ac3a280SJérôme Duval #ifdef ZSTD_ENABLED
4176ac3a280SJérôme Duval 	switch (ZSTD_getErrorCode(error)) {
4186ac3a280SJérôme Duval 		case ZSTD_error_no_error:
4196ac3a280SJérôme Duval 			return B_OK;
4206ac3a280SJérôme Duval 		case ZSTD_error_seekableIO:
4216ac3a280SJérôme Duval 			return B_BAD_VALUE;
4226ac3a280SJérôme Duval 		case ZSTD_error_corruption_detected:
4236ac3a280SJérôme Duval 		case ZSTD_error_checksum_wrong:
4246ac3a280SJérôme Duval 			return B_BAD_DATA;
4256ac3a280SJérôme Duval 		case ZSTD_error_version_unsupported:
4266ac3a280SJérôme Duval 			return B_BAD_VALUE;
427*b3731f13SAugustin Cavalier 		case ZSTD_error_memory_allocation:
428*b3731f13SAugustin Cavalier 			return B_NO_MEMORY;
42989780a09SJérôme Duval 		case ZSTD_error_dstSize_tooSmall:
43089780a09SJérôme Duval 			return B_BUFFER_OVERFLOW;
4316ac3a280SJérôme Duval 		default:
4326ac3a280SJérôme Duval 			return B_ERROR;
4336ac3a280SJérôme Duval 	}
4346ac3a280SJérôme Duval #else
4356ac3a280SJérôme Duval 	return B_NOT_SUPPORTED;
4366ac3a280SJérôme Duval #endif
4376ac3a280SJérôme Duval }
438