Files
dnf-utils/sgutil/sgu_mode_rand_remove.cpp
2025-09-01 20:47:58 +08:00

124 lines
3.4 KiB
C++

#include "sgu_stdafx.h"
#include "sgu_mode_rand_remove.h"
#include "sgu_utils.h"
bool randRemovePartOfFile(const char* inputFileName, const char* outputFileName, int64_t minSize, int64_t maxSize, int32_t counts)
{
if (!inputFileName || inputFileName[0] == 0 || !outputFileName || outputFileName[0] == 0)
{
printf("Invalid input or output file name.\n");
return false;
}
if (minSize == 0 || maxSize == 0 || minSize > maxSize)
{
printf("Invalid size parameters.\n");
return false;
}
// Check if input and output file names are the same
if (compareTwoFileName(inputFileName, outputFileName) == 0)
{
printf("Input and output file names cannot be the same.\n");
return false;
}
// Open the input file in binary mode
FILE* inputFile;
fopen_s(&inputFile, inputFileName, "rb");
if (!inputFile)
{
printf("Error opening input file:%s\n", inputFileName);
return false;
}
// Open the output file in binary mode
FILE* outputFile;
fopen_s(&outputFile, outputFileName, "wb");
if (!outputFile)
{
printf("Error opening output file:%s", outputFileName);
fclose(inputFile);
return false;
}
// Get the size of the input file
fseek(inputFile, 0, SEEK_END);
int64_t inputFileSize = (int64_t)ftell(inputFile);
fseek(inputFile, 0, SEEK_SET);
if (maxSize * counts > inputFileSize)
{
printf("Error: The specified size range(%d*%lld) and count exceed the input file size[%lld].\n",
counts, maxSize, inputFileSize);
fclose(inputFile);
fclose(outputFile);
return false;
}
std::vector<std::pair< int64_t, int64_t>> segmentArray;
generateRandomSegment(inputFileSize, minSize, maxSize, counts, segmentArray);
int64_t totalSize = 0;
printf("Input file size: %lld bytes\n", inputFileSize);
printf("Remove %d segments, size range: %lld ~ %lld bytes\n", counts, minSize, maxSize);
for (auto& p : segmentArray)
{
totalSize += p.second;
printf("Remove segment: offset=%lld~%lld, size=%lld\n", p.first, p.first + p.second, p.second);
}
printf("Total size to remove: %lld bytes\n", totalSize);
//Temp memory
std::vector<uint8_t> buffer;
size_t offset = 0;
//read and modify each segment
for (const auto& segment : segmentArray)
{
size_t segmentOffset = segment.first;
size_t segmentSize = segment.second;
// Read file content before segment
buffer.resize(segmentOffset - offset);
fseek(inputFile, (long)offset, SEEK_SET);
size_t bytesRead = fread(buffer.data(), 1, segmentOffset - offset, inputFile);
if (bytesRead != segmentOffset - offset)
{
printf("Error reading segment before offset %zu, expected %zu bytes, got %zu bytes.\n",
offset, segmentOffset - offset, bytesRead);
fclose(inputFile);
fclose(outputFile);
return false;
}
//write to output file
fwrite(buffer.data(), 1, segmentOffset - offset, outputFile);
offset = segmentOffset + segmentSize;
}
//read and write the remaining part of the file
buffer.resize(inputFileSize - offset);
fseek(inputFile, (long)offset, SEEK_SET);
size_t bytesRead = fread(buffer.data(), 1, inputFileSize - offset, inputFile);
if (bytesRead != inputFileSize - offset)
{
printf("Error reading segment before offset %zu, expected %zu bytes, got %zu bytes.\n",
offset, inputFileSize - offset, bytesRead);
fclose(inputFile);
fclose(outputFile);
return false;
}
//write to output file
fwrite(buffer.data(), 1, inputFileSize - offset, outputFile);
// Close both files
fclose(inputFile);
fclose(outputFile);
return true;
}