/*** Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: Compression.cpp Date: 2021-6-17 Author: Reece ***/ #include #include "Compression.hpp" #include "zstd.h" namespace Aurora::Compression { AUKN_SYM bool Compress(const Memory::MemoryViewRead &source, Memory::ByteBuffer &out, int uCompressionLevel) { if (!out.GetOrAllocateLinearWriteable(source.length)) { SysPushErrorMemory(); return {}; } auto ret = ZSTD_compress(out.writePtr, source.length, source.ptr, source.length, uCompressionLevel); if (ZSTD_isError(ret)) { return false; } out.writePtr += ret; if (!out.flagCircular && out.flagExpandable) { if (!AuTryDownsize(out, out.writePtr - out.base)) { SysPushErrorMemory(); return false; } } return true; } AUKN_SYM bool Decompress(const Memory::MemoryViewRead &source, AuByteBuffer &out) { AuUInt32 read = 0; while (read != source.length) { auto startPtr = reinterpret_cast(source.ptr) + read; auto deflatedLength = ZSTD_findFrameCompressedSize(startPtr, source.length - read); auto inflatedLength = ZSTD_getFrameContentSize(startPtr, source.length - read); if (inflatedLength == ZSTD_CONTENTSIZE_ERROR) { return false; } if (inflatedLength == ZSTD_CONTENTSIZE_UNKNOWN) { return false; } if (ZSTD_isError(inflatedLength)) { return false; } auto view = out.GetOrAllocateLinearWriteable(inflatedLength); if (!view) { SysPushErrorMemory(); return false; } auto ret = ZSTD_decompress(view.ptr, inflatedLength, source.ptr, source.length); if (ZSTD_isError(ret)) { return false; } out.writePtr = (AuUInt8 *)view.ptr + ret; read += AuUInt32(deflatedLength); } return true; } }