#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 ChunkManager::chunked(const std::vector& raw, const bool& encrypt) { //std::vector 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 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 chunk(begin, end); std::vector outChunk = encrypt ? eman.encrypt(compress_data(chunk)) : compress_data(chunk); uint32_t chs = chunk.size(); uint32_t zch = outChunk.size(); //addIntToVector(compressedBlocks, chs); lastChunkRawSize = chs; addIntToVector(compressedBlocks, zch); compressedBlocks.insert(compressedBlocks.end(), outChunk.begin(), outChunk.end()); blockLen++; } std::vector zip; // Wstaw liczbę o ilości bloków do vectora; // Przekonpwertuj usigned int32 na ciąg znkaów // uint16_t blockLen = blockSizes .size(); addIntToVector(zip, blockLen); addIntToVector(zip, maxBlockSize); addIntToVector(zip, lastChunkRawSize); // Dodaj skompresowane dane zip.insert(zip.end(), compressedBlocks.begin(), compressedBlocks.end()); return zip; } // Kompresja std::vector ChunkManager::compress_data(const std::vector& 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 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 ChunkManager::dechunked(const std::vector& zip, const bool& encrypt) { size_t offset = 0; const uint16_t chunkLen = getIntFromVector(zip, offset); const uint32_t chunkBeforeSize = getIntFromVector(zip, offset); const uint32_t chunkLastSize = getIntFromVector(zip, offset); std::vector 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(zip, offset); // Pobierz blok chunka std::vector inChunk(chunkZipSize); std::memcpy(inChunk.data(), zip.data() + offset, chunkZipSize); offset += chunkZipSize; // Jeśli flaga encrypt jest aktywna najpierw zdeszyfruj blok std::vector zipChunk = encrypt ? eman.decrypt(inChunk) : std::move(inChunk); // Zdeklarój pusty chunk std::vector chunk = decompress_data(zipChunk, chunkSize); // Scal chunki chunksString.insert(chunksString.end(), chunk.begin(), chunk.end()); } return chunksString; } // Dekompresja std::vector ChunkManager::decompress_data(const std::vector& 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 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; }