146 lines
4.1 KiB
C++
146 lines
4.1 KiB
C++
#include "sgu_stdafx.h"
|
|
#include "sgu_mode_rand_modify.h"
|
|
#include "sgu_utils.h"
|
|
|
|
|
|
bool randomModifyFile(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;
|
|
}
|
|
|
|
FILE* inputFile = nullptr;
|
|
FILE* outputFile = nullptr;
|
|
|
|
// Open the input file in binary mode
|
|
fopen_s(&inputFile, inputFileName, "rb");
|
|
if (!inputFile)
|
|
{
|
|
printf("Error opening input file:%s\n", inputFileName);
|
|
return false;
|
|
}
|
|
|
|
// Open the output file in binary mode
|
|
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);
|
|
|
|
printf("Input file size: %lld bytes\n", inputFileSize);
|
|
printf("Modify %d segments, size range: %lld ~ %lld bytes\n", counts, minSize, maxSize);
|
|
int64_t totalSize = 0;
|
|
for (auto& p : segmentArray)
|
|
{
|
|
totalSize += p.second;
|
|
printf("Modify segment: offset=%lld~%lld, size=%lld\n", p.first, p.first+p.second, p.second);
|
|
}
|
|
printf("Total modified size: %lld bytes\n", totalSize);
|
|
|
|
//Temp memory
|
|
std::vector<uint8_t> buffer;
|
|
|
|
int64_t offset = 0;
|
|
|
|
//read and modify each segment
|
|
for(const auto& segment : segmentArray)
|
|
{
|
|
int64_t segmentOffset = segment.first;
|
|
int64_t segmentSize = segment.second;
|
|
int64_t dataSize = segmentOffset - offset;
|
|
// Read file content before segment
|
|
buffer.resize(dataSize);
|
|
fseek(inputFile, (long)offset, SEEK_SET);
|
|
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;
|
|
}
|
|
|
|
//write to 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;
|
|
}
|
|
|
|
// create random segment (fill with random data)
|
|
buffer.resize(segmentSize);
|
|
fillRandomData(buffer.data(), segmentSize);
|
|
|
|
// Write the modified segment to the output file
|
|
if (segmentSize != fwrite(buffer.data(), 1, segmentSize, outputFile))
|
|
{
|
|
printf("Error writing modified segment at offset %lld, size %lld bytes.\n",
|
|
segmentOffset, segmentSize);
|
|
fclose(inputFile);
|
|
fclose(outputFile);
|
|
return false;
|
|
}
|
|
|
|
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;
|
|
} |