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

142 lines
3.9 KiB
C++

#include "sgu_stdafx.h"
#include "sgu_mode_rand_insert.h"
#include "sgu_utils.h"
bool insertRandomDataInFile(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);
std::vector<int64_t> insertOffsets;
generateRandomPointsInSegment(inputFileSize, counts, insertOffsets);
printf("Input file size: %lld bytes\n", inputFileSize);
printf("Insert %d segments, size range: %lld ~ %lld bytes\n", counts, minSize, maxSize);
int64_t totalSize = 0;
//Temp memory
std::vector<uint8_t> buffer;
int64_t offset = 0;
for (int64_t insertOffset : insertOffsets)
{
int64_t dataSize = insertOffset - offset;
// Read file content before segment
if (dataSize > 0)
{
buffer.resize(dataSize);
int64_t bytesRead = fread(buffer.data(), 1, dataSize, inputFile);
if (bytesRead != dataSize)
{
printf("Error reading segment before offset %lld, expected %lld bytes, got %lld bytes.\n",
offset, dataSize, bytesRead);
fclose(inputFile);
fclose(outputFile);
return false;
}
offset += dataSize;
// Write the readed content to the output file
int64_t bytesWrite = fwrite(buffer.data(), 1, dataSize, outputFile);
if (bytesWrite != dataSize)
{
printf("Error writing segment before offset %lld, expected %lld bytes, wrote %lld bytes.\n",
offset, dataSize, bytesWrite);
fclose(inputFile);
fclose(outputFile);
return false;
}
}
int64_t segmentSize = randomInRange(minSize, maxSize);
totalSize += segmentSize;
printf("Insert segment: offset=%lld, size=%lld\n", insertOffset, segmentSize);
// create random segment (fill with random data)
buffer.resize(segmentSize);
fillRandomData(buffer.data(), segmentSize);
// Write the random segment to the output file
if (segmentSize != fwrite(buffer.data(), 1, segmentSize, outputFile))
{
printf("Error writing random segment size %lld bytes.\n", segmentSize);
fclose(inputFile);
fclose(outputFile);
return false;
}
}
printf("Total insert size: %lld bytes\n", totalSize);
// Read and write remain data
int64_t remainDataSize = inputFileSize - offset;
if (remainDataSize > 0)
{
buffer.resize(remainDataSize);
int64_t bytesRead = fread(buffer.data(), 1, remainDataSize, inputFile);
if (bytesRead != remainDataSize)
{
printf("Error reading remain data offset %lld, expected %lld bytes, got %lld bytes.\n",
offset, remainDataSize, bytesRead);
fclose(inputFile);
fclose(outputFile);
return false;
}
// Write the readed content to the output file
int64_t bytesWrite = fwrite(buffer.data(), 1, remainDataSize, outputFile);
if (bytesWrite != remainDataSize)
{
printf("Error writing remain data offset %lld, expected %lld bytes, wrote %lld bytes.\n",
offset, remainDataSize, bytesWrite);
fclose(inputFile);
fclose(outputFile);
return false;
}
}
fclose(inputFile);
fclose(outputFile);
return true;
}