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

128 lines
2.8 KiB
C++

#include "sgu_stdafx.h"
#include "sgu_mode_make_diff.h"
#include "sgu_utils.h"
#include "bzlib.h"
extern "C"
{
#include "bsdiff.h"
}
static int diffFileWriter(struct bsdiff_stream* stream, const void* buffer, int size)
{
FILE* fp = (FILE*)stream->opaque;
if (size != fwrite(buffer, 1, size, fp))
{
return -1;
}
return 0;
}
static int bzPatchFileWriter(struct bsdiff_stream* stream, const void* buffer, int size)
{
BZFILE* bz2 = (BZFILE*)stream->opaque;
int bz2err;
BZ2_bzWrite(&bz2err, bz2, (void*)buffer, size);
if (bz2err != BZ_STREAM_END && bz2err != BZ_OK)
return -1;
return 0;
}
bool createDiff(const char* inputFilename1, const char* inputFilename2, const char* outputFilename)
{
if (!inputFilename1 || inputFilename1[0] == 0 || !inputFilename2 || inputFilename2[0] == 0)
{
printf("Error: Input filename is not specified.\n");
return false;
}
if (!outputFilename || outputFilename[0] == 0)
{
printf("Error: Output filename is not specified.\n");
return false;
}
bool result = false;
uint8_t* pBuffer1 = nullptr;
uint8_t* pBuffer2 = nullptr;
FILE* fpOutput = nullptr;
do {
int64_t fileSize1;
pBuffer1 = readFileToBuffer(inputFilename1, fileSize1);
if (pBuffer1 == nullptr)
{
printf("Error: Failed to read input file 1: %s\n", inputFilename1);
break;
}
int64_t fileSize2;
pBuffer2 = readFileToBuffer(inputFilename2, fileSize2);
if (pBuffer2 == nullptr)
{
printf("Error: Failed to read input file 2: %s\n", inputFilename2);
break;
}
// Open the output file
fopen_s(&fpOutput, outputFilename, "wb");
if (fpOutput == nullptr)
{
printf("Error: Failed to open output file: %s\n", outputFilename);
break;
}
// Write the header
if (fwrite("ENDSLEY/BSDIFF43", 16, 1, fpOutput) != 1 ||
fwrite(&fileSize2, sizeof(fileSize2), 1, fpOutput) != 1)
{
printf("Failed to write header\n");
break;
}
int bz2err;
BZFILE* bzHandle = BZ2_bzWriteOpen(&bz2err, fpOutput, 9, 0, 0);
if (bzHandle == nullptr || bz2err != BZ_OK)
{
printf("BZ2_bzWriteOpen failed, bz2err=%d\n", bz2err);
break;
}
//generate diff
struct bsdiff_stream stream;
stream.malloc = malloc;
stream.free = free;
stream.write = bzPatchFileWriter;
stream.opaque = bzHandle;
if (bsdiff(pBuffer1, fileSize1, pBuffer2, fileSize2, &stream))
{
printf("bsdiff error!\n");
break;
}
BZ2_bzWriteClose(&bz2err, bzHandle, 0, NULL, NULL);
if (bz2err != BZ_OK)
{
printf("BZ2_bzWriteClose failed, bz2err=%d", bz2err);
break;
}
result = true;
printf("Diff file created successfully: %s\n", outputFilename);
} while (false);
if (fpOutput != nullptr)
{
fclose(fpOutput);
fpOutput = nullptr;
}
freeFileBuffer(pBuffer1);
pBuffer1 = nullptr;
freeFileBuffer(pBuffer2);
pBuffer2 = nullptr;
return result;
}