133 lines
No EOL
4.3 KiB
C++
133 lines
No EOL
4.3 KiB
C++
/*
|
|
* 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 <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#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& compress, const bool& encrypt)
|
|
{
|
|
//std::vector<BlockSize> blockSizes;
|
|
|
|
// Maksymalny rozmiar chunka
|
|
const size_t maxBlockSize = BLOCK_SIZE;
|
|
const size_t rawSize = raw.size();
|
|
|
|
uint32_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;
|
|
|
|
// 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 = static_cast<uint32_t>(chunk.size());
|
|
uint32_t zch = static_cast<uint32_t>(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<uint32_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;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Dekompresja blokowa
|
|
//-----------------------------------------------------------------------------
|
|
std::vector<char> ChunkManager::dechunked(const std::vector<char>& zip, const bool& compress, const bool& encrypt)
|
|
{
|
|
size_t offset = 0;
|
|
const uint32_t chunkLen = getIntFromVector<uint32_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 = compress ? cman.decompress(zipChunk, chunkSize) : std::move(zipChunk);
|
|
|
|
// Scal chunki
|
|
chunksString.insert(chunksString.end(), chunk.begin(), chunk.end());
|
|
}
|
|
|
|
return chunksString;
|
|
} |