/*
* This file is part of VoidArchiveTool.
*
* Copyright (C) 2025 Yanczi
*
* Void Archive Toolis free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see .
*/
#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& compress, 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;
// Przetwórz chunki i przetwórz
if (compress)
{
// Zaszyfruj i skompresuj lub tylko skompresuj
outChunk = encrypt ? eman.encrypt(cman.compress(chunk)) : cman.compress(chunk);
}
else
{
// Zaszyfruj lub skopiuj
outChunk = encrypt ? eman.encrypt(chunk) : std::move(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;
}
//////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
// Dekompresja blokowa
//-----------------------------------------------------------------------------
std::vector ChunkManager::dechunked(const std::vector& zip, const bool& compress, 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 = compress ? cman.decompress(zipChunk, chunkSize) : std::move(zipChunk);
// Scal chunki
chunksString.insert(chunksString.end(), chunk.begin(), chunk.end());
}
return chunksString;
}