累计更新:

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
+178 -15
View File
@@ -2,14 +2,16 @@
#include "sgu_mode_apply_patch.h"
#include "sgu_utils.h"
#include "bzlib.h"
extern "C"
{
#include "bspatch.h"
}
#include "bzlib.h"
#include "zstd.h"
//--------------------------- Not Compress-----------------------------------
static int patchFileReader(const struct bspatch_stream* stream, void* buffer, int length)
{
FILE* fp = (FILE*)stream->opaque;
@@ -20,6 +22,7 @@ static int patchFileReader(const struct bspatch_stream* stream, void* buffer, in
return 0;
}
//--------------------------- BZ2 -----------------------------------
static int bzPatchFileReader(const struct bspatch_stream* stream, void* buffer, int length)
{
BZFILE* bz2 = (BZFILE*)stream->opaque;
@@ -32,7 +35,117 @@ static int bzPatchFileReader(const struct bspatch_stream* stream, void* buffer,
return 0;
}
bool applyPatch(const char* inputFilename, const char* patchFilename, const char* outputFilename)
//--------------------------- ZSTD -----------------------------------
struct ZSTD_DecompressContext
{
ZSTD_DCtx* dctx;
FILE* fpInput;
void* inputBuf;
size_t inputBufSize;
size_t inputBufDataSize;
size_t inputBufDataReadedPos;
void* outputBuf;
size_t outputBufSize;
size_t outputBufDataSize;
size_t outputBufDataUploadedPos;
};
ZSTD_DecompressContext* createZSTDDecompressContext(FILE* fpInput)
{
ZSTD_DecompressContext* ctx = new ZSTD_DecompressContext();
ctx->dctx = ZSTD_createDCtx();
ctx->fpInput = fpInput;
ctx->inputBufSize = ZSTD_DStreamInSize();
ctx->inputBuf = malloc(ctx->inputBufSize);
ctx->inputBufDataSize = 0;
ctx->inputBufDataReadedPos = 0;
ctx->outputBufSize = ZSTD_DStreamOutSize();
ctx->outputBuf = malloc(ctx->outputBufSize);
ctx->outputBufDataSize = 0;
ctx->outputBufDataUploadedPos = 0;
return ctx;
}
void destoryZSTDDecompressContext(ZSTD_DecompressContext* ctx)
{
free(ctx->inputBuf);
free(ctx->outputBuf);
delete ctx;
}
static int zstdPatchFileReader(const struct bspatch_stream* stream, void* buffer, int length)
{
ZSTD_DecompressContext* ctx = (ZSTD_DecompressContext*)(stream->opaque);
if (length == 0)
{
return 0;
}
//total uploaded size
size_t uploadedSize = 0;
do {
//upload all decompressed data
if (ctx->outputBufDataSize > ctx->outputBufDataUploadedPos)
{
size_t remainDecompressedDataSize = ctx->outputBufDataSize - ctx->outputBufDataUploadedPos;
size_t remainNotUploadedSize = (size_t)length - uploadedSize;
size_t uploadSize = remainNotUploadedSize < remainDecompressedDataSize ? remainNotUploadedSize : remainDecompressedDataSize;
if (uploadSize > 0)
{
memcpy((uint8_t*)buffer + uploadedSize, ((uint8_t*)ctx->outputBuf) + ctx->outputBufDataUploadedPos, uploadSize);
uploadedSize += uploadSize;
ctx->outputBufDataUploadedPos += uploadSize;
}
}
if (uploadedSize >= length)
{
return 0;
}
//compressed data empty
if (ctx->inputBufDataSize == ctx->inputBufDataReadedPos)
{
//read file
ctx->inputBufDataSize = fread(ctx->inputBuf, 1, ctx->inputBufSize, ctx->fpInput);
ctx->inputBufDataReadedPos = 0;
if (ctx->inputBufDataSize == 0)
{
//TODO:
return -1;
}
}
//decompress data
ZSTD_inBuffer input = { ctx->inputBuf, ctx->inputBufDataSize, ctx->inputBufDataReadedPos };
ZSTD_outBuffer output = { ctx->outputBuf, ctx->outputBufSize, 0 };
const size_t ret = ZSTD_decompressStream(ctx->dctx, &output, &input);
if (ZSTD_isError(ret))
{
//TODO:
return -1;
}
ctx->inputBufDataReadedPos = input.pos;
ctx->outputBufDataUploadedPos = 0;
ctx->outputBufDataSize = output.pos;
} while (true);
return 0;
}
bool applyPatch(const char* inputFilename, const char* patchFilename, const char* outputFilename, int32_t compressMethod)
{
if (!inputFilename || inputFilename[0] == 0 || !patchFilename || patchFilename[0] == 0)
{
@@ -88,32 +201,82 @@ bool applyPatch(const char* inputFilename, const char* patchFilename, const char
// Read output file lengths from header
int64_t outputFileSize = *(int64_t*)(header + 16);
pOutputBuffer = new uint8_t[outputFileSize + 1];
if(pOutputBuffer == nullptr)
if (pOutputBuffer == nullptr)
{
printf("Error: Failed to allocate memory[%lld] for output buffer\n", outputFileSize+1);
printf("Error: Failed to allocate memory[%lld] for output buffer\n", outputFileSize + 1);
break;
}
int bz2err;
BZFILE* bzHandle = BZ2_bzReadOpen(&bz2err, patchFile, 0, 0, NULL, 0);
if (bzHandle == nullptr)
BZFILE* bzHandle = nullptr;
ZSTD_DecompressContext* zstdCtx = nullptr;
if (compressMethod == 1)
{
printf("BZ2_bzReadOpen, bz2err=%d", bz2err);
break;
int bz2err;
bzHandle = BZ2_bzReadOpen(&bz2err, patchFile, 0, 0, NULL, 0);
if (bzHandle == nullptr)
{
printf("BZ2_bzReadOpen, bz2err=%d", bz2err);
break;
}
}
else if(compressMethod==2)
{
zstdCtx = createZSTDDecompressContext(patchFile);
if (zstdCtx == 0)
{
printf("create zstd context failed!");
break;
}
}
// Apply the patch
struct bspatch_stream stream;
stream.read = bzPatchFileReader;
stream.opaque = bzHandle;
if (bspatch(pInputBuffer, inputFileSize, pOutputBuffer, outputFileSize, &stream))
if (compressMethod == 1)
{
stream.read = bzPatchFileReader;
stream.opaque = bzHandle;
}
else if (compressMethod == 2)
{
stream.read = zstdPatchFileReader;
stream.opaque = zstdCtx;
}
else
{
stream.read = patchFileReader;
stream.opaque = patchFile;
}
if (bspatch(pInputBuffer, inputFileSize, pOutputBuffer, outputFileSize, &stream) !=0 )
{
printf("Error: Failed to apply patch\n");
if (compressMethod == 1)
{
// Clean up the bzip2 reads
int bz2err;
BZ2_bzReadClose(&bz2err, bzHandle);
bzHandle = nullptr;
}
else if (compressMethod == 2)
{
destoryZSTDDecompressContext(zstdCtx);
zstdCtx = nullptr;
}
break;
}
// Clean up the bzip2 reads
BZ2_bzReadClose(&bz2err, bzHandle);
if (compressMethod == 1)
{
// Clean up the bzip2 reads
int bz2err;
BZ2_bzReadClose(&bz2err, bzHandle);
bzHandle = nullptr;
}
else if (compressMethod == 2)
{
destoryZSTDDecompressContext(zstdCtx);
zstdCtx = nullptr;
}
// Write the output buffer to the output file
if (outputFileSize != fwrite(pOutputBuffer, 1, outputFileSize, outputFile))