累计更新:

cos上传
补丁压缩
This commit is contained in:
2025-12-06 16:29:26 +08:00
parent 5a2211d217
commit b78ee53326
11 changed files with 483 additions and 49 deletions
+194 -15
View File
@@ -2,13 +2,14 @@
#include "sgu_mode_make_diff.h"
#include "sgu_utils.h"
#include "bzlib.h"
extern "C"
{
#include "bsdiff.h"
}
#include "bzlib.h"
#include "zstd.h"
static int bzPatchFileWriter(struct bsdiff_stream* stream, const void* buffer, int size)
{
BZFILE* bz2 = (BZFILE*)stream->opaque;
@@ -22,7 +23,143 @@ static int bzPatchFileWriter(struct bsdiff_stream* stream, const void* buffer, i
return 0;
}
bool createDiff(const char* inputFilename1, const char* inputFilename2, const char* outputFilename)
struct ZSTD_CompressContext
{
ZSTD_CCtx* cctx;
void* inputBuf;
size_t inputBufSize;
size_t inputBufDataSize;
void* outputBuf;
size_t outputBufSize;
FILE* fpOutput;
FILE* fpDebugOutput;
FILE* fpDebugOutput2;
};
ZSTD_CompressContext* createZSTDCompressContext(FILE* fpOutput)
{
ZSTD_CompressContext* ctx = new ZSTD_CompressContext();
if (ctx == nullptr)
{
return nullptr;
}
ctx->cctx = ZSTD_createCCtx();
if (ctx->cctx == nullptr)
{
return nullptr;
}
ZSTD_CCtx_setParameter(ctx->cctx, ZSTD_c_compressionLevel, ZSTD_CLEVEL_DEFAULT);
ZSTD_CCtx_setParameter(ctx->cctx, ZSTD_c_checksumFlag, 1);
ctx->inputBufSize = ZSTD_CStreamInSize();
ctx->inputBuf = malloc(ctx->inputBufSize);
if (ctx->inputBuf == nullptr)
{
return nullptr;
}
ctx->inputBufDataSize = 0;
ctx->outputBufSize = ZSTD_CStreamOutSize();
ctx->outputBuf = malloc(ctx->outputBufSize);
if (ctx->outputBuf == nullptr)
{
return nullptr;
}
ctx->fpOutput = fpOutput;
ctx->fpDebugOutput = fopen("org.patch", "wb");
ctx->fpDebugOutput2 = fopen("org.patch.2", "wb");
return ctx;
}
void destoryZSTDCompressContext(ZSTD_CompressContext* ctx)
{
fclose(ctx->fpDebugOutput);
fclose(ctx->fpDebugOutput2);
free(ctx->inputBuf);
free(ctx->outputBuf);
delete ctx;
}
void zstdCompressData(ZSTD_CompressContext* ctx, ZSTD_EndDirective mode)
{
/* Set the input buffer to what we just read.
* We compress until the input buffer is empty, each time flushing the
* output.
*/
ZSTD_inBuffer input = { ctx->inputBuf, ctx->inputBufDataSize, 0 };
bool finished;
do {
/* Compress into the output buffer and write all of the output to
* the file so we can reuse the buffer next iteration.
*/
ZSTD_outBuffer output = { ctx->outputBuf, ctx->outputBufSize, 0 };
const size_t remaining = ZSTD_compressStream2(ctx->cctx, &output, &input, mode);
//write to output file
fwrite(ctx->outputBuf, 1, output.pos, ctx->fpOutput);
fwrite(ctx->outputBuf, 1, output.pos, ctx->fpDebugOutput2);
/* If we're on the last chunk we're finished when zstd returns 0,
* which means its consumed all the input AND finished the frame.
* Otherwise, we're finished when we've consumed all the input.
*/
finished = (mode== ZSTD_e_end) ? (remaining == 0) : (input.pos == input.size);
} while (!finished);
ctx->inputBufDataSize = 0;
}
void zstdPatchFileClose(ZSTD_CompressContext* ctx)
{
zstdCompressData(ctx, ZSTD_e_end);
}
static int zstdPatchFileWriter(struct bsdiff_stream* stream, const void* inputData, int inputSize)
{
ZSTD_CompressContext* ctx = (ZSTD_CompressContext*)(stream->opaque);
fwrite(inputData, 1, inputSize, ctx->fpDebugOutput);
size_t readedSize = 0;
for (;;) {
size_t inputBufRemainSize = ctx->inputBufSize - ctx->inputBufDataSize;
size_t remainDataSize = (size_t)inputSize - readedSize;
size_t readSize = inputBufRemainSize<remainDataSize ? inputBufRemainSize : remainDataSize;
memcpy(((uint8_t*)ctx->inputBuf)+ctx->inputBufDataSize, (const uint8_t*)inputData + readedSize, readSize);
readedSize += readSize;
ctx->inputBufDataSize += readSize;
if (ctx->inputBufDataSize >= ctx->inputBufSize)
{
zstdCompressData(ctx, ZSTD_e_continue);
}
if (readedSize >= (size_t)inputSize)
{
break;
}
}
return 0;
}
static int patchFileWriter(struct bsdiff_stream* stream, const void* inputData, int inputSize)
{
FILE* fpOutput = (FILE*)(stream->opaque);
fwrite(inputData, 1, inputSize, fpOutput);
return 0;
}
bool createDiff(const char* inputFilename1, const char* inputFilename2, const char* outputFilename, int32_t compressMethod)
{
if (!inputFilename1 || inputFilename1[0] == 0 || !inputFilename2 || inputFilename2[0] == 0)
{
@@ -72,31 +209,73 @@ bool createDiff(const char* inputFilename1, const char* inputFilename2, const ch
break;
}
int bz2err;
BZFILE* bzHandle = BZ2_bzWriteOpen(&bz2err, fpOutput, 9, 0, 0);
if (bzHandle == nullptr || bz2err != BZ_OK)
BZFILE* bzHandle = nullptr;
ZSTD_CompressContext* zstdContext = nullptr;
if (compressMethod == 1)
{
printf("BZ2_bzWriteOpen failed, bz2err=%d\n", bz2err);
break;
int bz2err;
bzHandle = BZ2_bzWriteOpen(&bz2err, fpOutput, 9, 0, 0);
if (bzHandle == nullptr || bz2err != BZ_OK)
{
printf("BZ2_bzWriteOpen failed, bz2err=%d\n", bz2err);
break;
}
}
else if (compressMethod == 2)
{
zstdContext = createZSTDCompressContext(fpOutput);
if (zstdContext == nullptr)
{
printf("Failed create zstd context!");
break;
}
}
else
{
}
//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))
if (compressMethod == 1)
{
stream.write = bzPatchFileWriter;
stream.opaque = bzHandle;
}
else if (compressMethod == 2)
{
stream.write = zstdPatchFileWriter;
stream.opaque = zstdContext;
}
else
{
stream.write = patchFileWriter;
stream.opaque = fpOutput;
}
if (bsdiff(pBuffer1, fileSize1, pBuffer2, fileSize2, &stream) !=0 )
{
printf("bsdiff error!\n");
break;
}
BZ2_bzWriteClose(&bz2err, bzHandle, 0, NULL, NULL);
if (bz2err != BZ_OK)
if (compressMethod == 1)
{
printf("BZ2_bzWriteClose failed, bz2err=%d", bz2err);
break;
int bz2err;
BZ2_bzWriteClose(&bz2err, bzHandle, 0, NULL, NULL);
if (bz2err != BZ_OK)
{
printf("BZ2_bzWriteClose failed, bz2err=%d", bz2err);
break;
}
bzHandle = nullptr;
}
else if (compressMethod == 2)
{
zstdPatchFileClose(zstdContext);
destoryZSTDCompressContext(zstdContext);
zstdContext = nullptr;
}
result = true;