Podmiana LZ4 na ZSTD raw block. Podmiana CompressManager na ChunkManager
This commit is contained in:
parent
00d4b00209
commit
b3c317c914
10 changed files with 244 additions and 267 deletions
177
ChunkManager.cpp
Normal file
177
ChunkManager.cpp
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
#include "ChunkManager.h"
|
||||
|
||||
ChunkManager::ChunkManager(EncryptionManager& em)
|
||||
:eman(em)
|
||||
{ }
|
||||
|
||||
ChunkManager::~ChunkManager()
|
||||
{ }
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Kompresja blokowa
|
||||
//
|
||||
// Dzielenie vectora na chunki dok³adnie po 128KB
|
||||
// Kompresowanie chunków bez nag³ówka
|
||||
//-----------------------------------------------------------------------------
|
||||
std::vector<char> ChunkManager::chunked(const std::vector<char>& raw, const bool& encrypt)
|
||||
{
|
||||
//std::vector<BlockSize> blockSizes;
|
||||
|
||||
// Maksymalny rozmiar chunka
|
||||
const size_t maxBlockSize = BLOCK_SIZE;
|
||||
const size_t rawSize = raw.size();
|
||||
|
||||
uint16_t blockLen = 0;
|
||||
uint32_t lastChunkRawSize;
|
||||
std::vector<char> compressedBlocks;
|
||||
for (size_t offset = 0; offset < rawSize; offset += maxBlockSize)
|
||||
{
|
||||
// Rozmiar chunka
|
||||
const size_t chunkSize = std::min(maxBlockSize, rawSize - offset);
|
||||
|
||||
auto begin = raw.begin() + offset;
|
||||
auto end = begin + chunkSize;
|
||||
|
||||
// Skopiuj fragment danych do chunka
|
||||
std::vector<char> chunk(begin, end);
|
||||
|
||||
std::vector<char> outChunk = encrypt ? eman.encrypt(compress_data(chunk)) : compress_data(chunk);
|
||||
|
||||
uint32_t chs = chunk.size();
|
||||
uint32_t zch = outChunk.size();
|
||||
|
||||
//addIntToVector<uint32_t>(compressedBlocks, chs);
|
||||
lastChunkRawSize = chs;
|
||||
addIntToVector<uint32_t>(compressedBlocks, zch);
|
||||
compressedBlocks.insert(compressedBlocks.end(), outChunk.begin(), outChunk.end());
|
||||
|
||||
blockLen++;
|
||||
}
|
||||
|
||||
std::vector<char> zip;
|
||||
// Wstaw liczbê o iloœci bloków do vectora;
|
||||
// Przekonpwertuj usigned int32 na ci¹g znkaów
|
||||
// uint16_t blockLen = blockSizes .size();
|
||||
addIntToVector<uint16_t>(zip, blockLen);
|
||||
addIntToVector<uint32_t>(zip, maxBlockSize);
|
||||
addIntToVector<uint32_t>(zip, lastChunkRawSize);
|
||||
|
||||
// Dodaj skompresowane dane
|
||||
zip.insert(zip.end(), compressedBlocks.begin(), compressedBlocks.end());
|
||||
|
||||
return zip;
|
||||
}
|
||||
|
||||
// Kompresja
|
||||
std::vector<char> ChunkManager::compress_data(const std::vector<char>& input)
|
||||
{
|
||||
const int level = 3;
|
||||
|
||||
// Obs³uga pustego chunku: zwracamy pusty wynik (0 bajtów).
|
||||
if (input.empty()) return {};
|
||||
|
||||
ZSTD_CCtx* cctx = ZSTD_createCCtx();
|
||||
if (!cctx) {
|
||||
std::cerr << "ZSTD_createCCtx failed\n";
|
||||
return {};
|
||||
}
|
||||
|
||||
// Ustawienia „bez ramek”
|
||||
size_t rc = 0;
|
||||
rc |= ZSTD_CCtx_setParameter(cctx, ZSTD_c_format, ZSTD_f_zstd1_magicless);
|
||||
rc |= ZSTD_CCtx_setParameter(cctx, ZSTD_c_checksumFlag, 0);
|
||||
rc |= ZSTD_CCtx_setParameter(cctx, ZSTD_c_contentSizeFlag, 0);
|
||||
rc |= ZSTD_CCtx_setParameter(cctx, ZSTD_c_dictIDFlag, 0);
|
||||
rc |= ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, level);
|
||||
|
||||
if (ZSTD_isError(rc)) {
|
||||
std::cerr << "ZSTD_CCtx_setParameter error\n";
|
||||
ZSTD_freeCCtx(cctx);
|
||||
return {};
|
||||
}
|
||||
|
||||
const size_t srcSize = input.size();
|
||||
|
||||
// Szacowanie rozmiaru skompresowanego vectoru
|
||||
const size_t maxDst = ZSTD_compressBound(srcSize);
|
||||
|
||||
std::vector<char> out(maxDst);
|
||||
|
||||
// Faktyczna kompresja
|
||||
size_t written = ZSTD_compress2(cctx, out.data(), maxDst,
|
||||
input.data(), srcSize);
|
||||
|
||||
ZSTD_freeCCtx(cctx);
|
||||
|
||||
if (ZSTD_isError(written)) {
|
||||
std::cerr << "ZSTD_compress2 error: " << ZSTD_getErrorName(written) << "\n";
|
||||
return {};
|
||||
}
|
||||
|
||||
out.resize(written);
|
||||
return out;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Dekompresja blokowa
|
||||
//-----------------------------------------------------------------------------
|
||||
std::vector<char> ChunkManager::dechunked(const std::vector<char>& zip, const bool& encrypt)
|
||||
{
|
||||
size_t offset = 0;
|
||||
const uint16_t chunkLen = getIntFromVector<uint16_t>(zip, offset);
|
||||
const uint32_t chunkBeforeSize = getIntFromVector<uint32_t>(zip, offset);
|
||||
const uint32_t chunkLastSize = getIntFromVector<uint32_t>(zip, offset);
|
||||
|
||||
std::vector<char> chunksString;
|
||||
|
||||
// Dekompresja bloków
|
||||
for (size_t i = 0; i < chunkLen; ++i)
|
||||
{
|
||||
// Pobierz rozmiar chunków przed i po skompresowaniem
|
||||
uint32_t chunkSize = i < chunkLen - 1 ? chunkBeforeSize : chunkLastSize;
|
||||
uint32_t chunkZipSize = getIntFromVector<uint32_t>(zip, offset);
|
||||
|
||||
// Pobierz blok chunka
|
||||
std::vector<char> inChunk(chunkZipSize);
|
||||
std::memcpy(inChunk.data(), zip.data() + offset, chunkZipSize);
|
||||
offset += chunkZipSize;
|
||||
|
||||
// Jeœli flaga encrypt jest aktywna najpierw zdeszyfruj blok
|
||||
std::vector<char> zipChunk = encrypt ? eman.decrypt(inChunk) : std::move(inChunk);
|
||||
|
||||
// Zdeklarój pusty chunk
|
||||
std::vector<char> chunk = decompress_data(zipChunk, chunkSize);
|
||||
|
||||
// Scal chunki
|
||||
chunksString.insert(chunksString.end(), chunk.begin(), chunk.end());
|
||||
}
|
||||
|
||||
return chunksString;
|
||||
}
|
||||
|
||||
// Dekompresja
|
||||
std::vector<char> ChunkManager::decompress_data(const std::vector<char>& input, const size_t& expected)
|
||||
{
|
||||
ZSTD_DCtx* dctx = ZSTD_createDCtx();
|
||||
size_t r = 0;
|
||||
r |= ZSTD_DCtx_setParameter(dctx, ZSTD_d_format, ZSTD_f_zstd1_magicless);
|
||||
if (ZSTD_isError(r))
|
||||
{
|
||||
std::cerr << "ZSTD_DCtx_setParameter error" << std::endl;
|
||||
ZSTD_freeDCtx(dctx);
|
||||
}
|
||||
|
||||
std::vector<char> output(expected);
|
||||
|
||||
size_t dsize = ZSTD_decompressDCtx(dctx, output.data(), expected, input.data(), input.size());
|
||||
ZSTD_freeDCtx(dctx);
|
||||
|
||||
if (ZSTD_isError(dsize)) {
|
||||
std::cerr << "ZSTD_decompressDCtx error: " << ZSTD_getErrorName(dsize) << "\n";
|
||||
return {};
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue