累计更新:
cos上传 补丁压缩
This commit is contained in:
Binary file not shown.
@@ -42,12 +42,14 @@ PRIVATE
|
|||||||
../libTinyEncrypt
|
../libTinyEncrypt
|
||||||
../lua/src
|
../lua/src
|
||||||
../luatinker
|
../luatinker
|
||||||
|
../zstd/lib
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_directories(sgutil
|
target_link_directories(sgutil
|
||||||
PRIVATE
|
PRIVATE
|
||||||
../cos-cpp-sdk/libs/x64
|
../cos-cpp-sdk/libs/x64
|
||||||
../cos-cpp-sdk/third_party/lib/x64/poco
|
../cos-cpp-sdk/third_party/lib/x64/poco
|
||||||
|
../zstd/precompiled/x64
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(sgutil
|
target_link_libraries(sgutil
|
||||||
@@ -58,10 +60,11 @@ PRIVATE
|
|||||||
libTinyEncrypt
|
libTinyEncrypt
|
||||||
LuaTinker
|
LuaTinker
|
||||||
lua
|
lua
|
||||||
|
zstd_static.lib
|
||||||
shlwapi.lib
|
shlwapi.lib
|
||||||
wininet.lib
|
wininet.lib
|
||||||
# cossdk.lib
|
cossdk.lib
|
||||||
# PocoFoundation.lib
|
PocoFoundation.lib
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#include "sgu_stdafx.h"
|
#include "sgu_stdafx.h"
|
||||||
#include "sgu_download_cos.h"
|
#include "sgu_download_cos.h"
|
||||||
|
|
||||||
#if 1
|
#if 0
|
||||||
bool downloadFileFromCOS(const char* cosFilePathName, const char* localFilePath)
|
bool downloadFileFromCOS(const char* cosFilePathName, const char* localFilePath)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
@@ -19,15 +19,21 @@ static void TestLogCallback(const std::string& log)
|
|||||||
//
|
//
|
||||||
// https://console.cloud.tencent.com/cam/capi
|
// https://console.cloud.tencent.com/cam/capi
|
||||||
//
|
//
|
||||||
const uint64_t gAppID = 1313389434ULL;
|
//const uint64_t gAppID = 1313389434ULL;
|
||||||
const std::string gSecretId = "AKIDGMFKI2av3g6JPTKzRffS1NWR9eXDgwym";
|
//const std::string gSecretId = "AKIDGMFKI2av3g6JPTKzRffS1NWR9eXDgwym";
|
||||||
const std::string gSecretKey = "f7LMDtNdnlXDpEQRGxVqxrbBYjlcbP2U";
|
//const std::string gSecretKey = "f7LMDtNdnlXDpEQRGxVqxrbBYjlcbP2U";
|
||||||
const std::string gRegion = "ap-shanghai";
|
//const std::string gRegion = "ap-shanghai";
|
||||||
const std::string gBucketName = "dnftest-1313389434";
|
//const std::string gBucketName = "dnftest-1313389434";
|
||||||
|
|
||||||
|
|
||||||
|
const std::string gSecretId = "AKIDfBzQo25vgJl170rV1LRNLExTp27GZhho";
|
||||||
|
const std::string gSecretKey = "2qvqX0FKCrHkBQehYDe2JaggePA4nLir";
|
||||||
|
const std::string gRegion = "ap-nanjing";
|
||||||
|
const std::string gBucketName = "client-fwf-1258765125";
|
||||||
|
|
||||||
bool downloadFileFromCOS(const char* cosFilePathName, const char* localFilePath)
|
bool downloadFileFromCOS(const char* cosFilePathName, const char* localFilePath)
|
||||||
{
|
{
|
||||||
qcloud_cos::CosConfig config(gAppID, gSecretId, gSecretKey, gRegion);
|
qcloud_cos::CosConfig config(0, gSecretId, gSecretKey, gRegion);
|
||||||
config.SetLogCallback(&TestLogCallback);
|
config.SetLogCallback(&TestLogCallback);
|
||||||
qcloud_cos::CosAPI cos(config);
|
qcloud_cos::CosAPI cos(config);
|
||||||
|
|
||||||
@@ -57,4 +63,35 @@ bool downloadFileFromCOS(const char* cosFilePathName, const char* localFilePath)
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool uploadFileToCos(const char* localFilePath, const char* cosFilePath)
|
||||||
|
{
|
||||||
|
qcloud_cos::CosConfig config(0, gSecretId, gSecretKey, gRegion);
|
||||||
|
config.SetLogCallback(&TestLogCallback);
|
||||||
|
qcloud_cos::CosAPI cos(config);
|
||||||
|
|
||||||
|
// 构造下载对象的请求
|
||||||
|
std::string objectName = cosFilePath;
|
||||||
|
std::string localPath = localFilePath;
|
||||||
|
|
||||||
|
// 上传对象构造
|
||||||
|
qcloud_cos::PutObjectByFileReq req(gBucketName, objectName, localPath);
|
||||||
|
qcloud_cos::PutObjectByFileResp resp;
|
||||||
|
qcloud_cos::CosResult result = cos.PutObject(req, &resp);
|
||||||
|
if (result.IsSucc()) {
|
||||||
|
// 上传文件成功
|
||||||
|
std::cout << "Upload file success!" << std::endl;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// 上传文件失败,可以调用 CosResult 的成员函数输出错误信息,例如 requestID 等
|
||||||
|
std::cout << "HttpStatus=" << result.GetHttpStatus() << std::endl;
|
||||||
|
std::cout << "ErrorCode=" << result.GetErrorCode() << std::endl;
|
||||||
|
std::cout << "ErrorMsg=" << result.GetErrorMsg() << std::endl;
|
||||||
|
std::cout << "ResourceAddr=" << result.GetResourceAddr() << std::endl;
|
||||||
|
std::cout << "XCosRequestId=" << result.GetXCosRequestId() << std::endl;
|
||||||
|
std::cout << "XCosTraceId=" << result.GetXCosTraceId() << std::endl;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
bool downloadFileFromCOS(const char* cosFilePath, const char* localFilePath);
|
bool downloadFileFromCOS(const char* cosFilePath, const char* localFilePath);
|
||||||
|
|
||||||
|
bool uploadFileToCos(const char* localFilePath, const char* cosFilePath);
|
||||||
|
|||||||
+33
-8
@@ -60,7 +60,8 @@ static void printUsage(const char* moduleName)
|
|||||||
printf(" MakeDiff\tCreates a binary diff patch file between two input files using BSDIFF43.\n");
|
printf(" MakeDiff\tCreates a binary diff patch file between two input files using BSDIFF43.\n");
|
||||||
printf(" ApplyPatch\tApplies a BSDIFF43 binary patch to an input file and writes the patched result to an output file.\n");
|
printf(" ApplyPatch\tApplies a BSDIFF43 binary patch to an input file and writes the patched result to an output file.\n");
|
||||||
printf(" HashFile\tCalculates the hash(MD5|SHA256) of the contents of a specified file.\n");
|
printf(" HashFile\tCalculates the hash(MD5|SHA256) of the contents of a specified file.\n");
|
||||||
printf(" HttpDownload\tDownloads a file from a specified URL and saves it to a local file.\n");
|
printf(" Download\tDownloads a file from a specified URL and saves it to a local file.\n");
|
||||||
|
printf(" Upload\tUpload a local file to a specified cos server.\n");
|
||||||
printf(" RunLuaFile\t xxxx \n");
|
printf(" RunLuaFile\t xxxx \n");
|
||||||
printf("\nSample:\n");
|
printf("\nSample:\n");
|
||||||
printf(" -m GenRandFile -min 500 -max 1k -o rand.bin\n");
|
printf(" -m GenRandFile -min 500 -max 1k -o rand.bin\n");
|
||||||
@@ -71,7 +72,8 @@ static void printUsage(const char* moduleName)
|
|||||||
printf(" -m ApplyPatch -i ver01.bin -i2 patch_ver01_ver02.diff -o ver02.bin\n");
|
printf(" -m ApplyPatch -i ver01.bin -i2 patch_ver01_ver02.diff -o ver02.bin\n");
|
||||||
printf(" -m HashFile -t md5 -i ver01.bin\n");
|
printf(" -m HashFile -t md5 -i ver01.bin\n");
|
||||||
printf(" -m HashFile -t sha256 -i ver01.bin\n");
|
printf(" -m HashFile -t sha256 -i ver01.bin\n");
|
||||||
printf(" -m HttpDownload -i http://download.com/file.txt -o file.txt\n");
|
printf(" -m Download -i http://download.com/file.txt -o file.txt\n");
|
||||||
|
printf(" -m Upload -i file.txt -o cos:\\path\file.txt \n");
|
||||||
printf(" -m RunLuaFile -i script.lua\n");
|
printf(" -m RunLuaFile -i script.lua\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,7 +87,8 @@ enum WorkMode {
|
|||||||
WM_MAKE_DIFF,
|
WM_MAKE_DIFF,
|
||||||
WM_APPLY_PATCH,
|
WM_APPLY_PATCH,
|
||||||
WM_HASH_FILE,
|
WM_HASH_FILE,
|
||||||
WM_HTTP_DOWNLOAD,
|
WM_DOWNLOAD,
|
||||||
|
WM_UPLOAD,
|
||||||
WM_RUN_LUA_FILE,
|
WM_RUN_LUA_FILE,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -124,8 +127,11 @@ WorkMode parserWorkMode(const char* modeStr)
|
|||||||
else if (_stricmp(modeStr, "HashFile") == 0) {
|
else if (_stricmp(modeStr, "HashFile") == 0) {
|
||||||
return WM_HASH_FILE;
|
return WM_HASH_FILE;
|
||||||
}
|
}
|
||||||
else if (_stricmp(modeStr, "HttpDownload") == 0) {
|
else if (_stricmp(modeStr, "Download") == 0) {
|
||||||
return WM_HTTP_DOWNLOAD;
|
return WM_DOWNLOAD;
|
||||||
|
}
|
||||||
|
else if (_stricmp(modeStr, "Upload") == 0) {
|
||||||
|
return WM_UPLOAD;
|
||||||
}
|
}
|
||||||
else if (_stricmp(modeStr, "RunLuaFile") == 0) {
|
else if (_stricmp(modeStr, "RunLuaFile") == 0) {
|
||||||
return WM_RUN_LUA_FILE;
|
return WM_RUN_LUA_FILE;
|
||||||
@@ -151,6 +157,8 @@ HashType parserHashType(const char* typeStr)
|
|||||||
return HT_NONE; // default to HT_NONE
|
return HT_NONE; // default to HT_NONE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const int kDiffCompressMethod = 2;
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
CSimpleOptA args(argc, argv, g_rgOptions);
|
CSimpleOptA args(argc, argv, g_rgOptions);
|
||||||
@@ -336,7 +344,7 @@ int main(int argc, char* argv[])
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
printf("Creating diff between %s and %s, output: %s\n", inputFilename, inputFilename2, outputFilename);
|
printf("Creating diff between %s and %s, output: %s\n", inputFilename, inputFilename2, outputFilename);
|
||||||
if (!createDiff(inputFilename, inputFilename2, outputFilename))
|
if (!createDiff(inputFilename, inputFilename2, outputFilename, kDiffCompressMethod))
|
||||||
{
|
{
|
||||||
printf("Error: Failed to create diff file.\n");
|
printf("Error: Failed to create diff file.\n");
|
||||||
return 1;
|
return 1;
|
||||||
@@ -353,14 +361,14 @@ int main(int argc, char* argv[])
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
printf("Applying patch from %s with patch %s, output: %s\n", inputFilename, inputFilename2, outputFilename);
|
printf("Applying patch from %s with patch %s, output: %s\n", inputFilename, inputFilename2, outputFilename);
|
||||||
if (!applyPatch(inputFilename, inputFilename2, outputFilename))
|
if (!applyPatch(inputFilename, inputFilename2, outputFilename, kDiffCompressMethod))
|
||||||
{
|
{
|
||||||
printf("Error: Failed to apply patch.\n");
|
printf("Error: Failed to apply patch.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WM_HTTP_DOWNLOAD:
|
case WM_DOWNLOAD:
|
||||||
{
|
{
|
||||||
if (inputFilename == nullptr || outputFilename == nullptr)
|
if (inputFilename == nullptr || outputFilename == nullptr)
|
||||||
{
|
{
|
||||||
@@ -377,6 +385,23 @@ int main(int argc, char* argv[])
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case WM_UPLOAD:
|
||||||
|
{
|
||||||
|
if (inputFilename == nullptr || outputFilename == nullptr)
|
||||||
|
{
|
||||||
|
printf("Error: For 'upload' mode, you must specify input local file and output cos path.\n");
|
||||||
|
printUsage(::PathFindFileNameA(argv[0]));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
printf("Uploading from %s to %s\n", inputFilename, outputFilename);
|
||||||
|
if(!uploadFile(inputFilename, outputFilename))
|
||||||
|
{
|
||||||
|
printf("Error: Failed to upload file.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case WM_RUN_LUA_FILE:
|
case WM_RUN_LUA_FILE:
|
||||||
{
|
{
|
||||||
if (inputFilename == nullptr)
|
if (inputFilename == nullptr)
|
||||||
|
|||||||
+178
-15
@@ -2,14 +2,16 @@
|
|||||||
#include "sgu_mode_apply_patch.h"
|
#include "sgu_mode_apply_patch.h"
|
||||||
#include "sgu_utils.h"
|
#include "sgu_utils.h"
|
||||||
|
|
||||||
#include "bzlib.h"
|
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
#include "bspatch.h"
|
#include "bspatch.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "bzlib.h"
|
||||||
|
#include "zstd.h"
|
||||||
|
|
||||||
|
|
||||||
|
//--------------------------- Not Compress-----------------------------------
|
||||||
static int patchFileReader(const struct bspatch_stream* stream, void* buffer, int length)
|
static int patchFileReader(const struct bspatch_stream* stream, void* buffer, int length)
|
||||||
{
|
{
|
||||||
FILE* fp = (FILE*)stream->opaque;
|
FILE* fp = (FILE*)stream->opaque;
|
||||||
@@ -20,6 +22,7 @@ static int patchFileReader(const struct bspatch_stream* stream, void* buffer, in
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------- BZ2 -----------------------------------
|
||||||
static int bzPatchFileReader(const struct bspatch_stream* stream, void* buffer, int length)
|
static int bzPatchFileReader(const struct bspatch_stream* stream, void* buffer, int length)
|
||||||
{
|
{
|
||||||
BZFILE* bz2 = (BZFILE*)stream->opaque;
|
BZFILE* bz2 = (BZFILE*)stream->opaque;
|
||||||
@@ -32,7 +35,117 @@ static int bzPatchFileReader(const struct bspatch_stream* stream, void* buffer,
|
|||||||
return 0;
|
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)
|
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
|
// Read output file lengths from header
|
||||||
int64_t outputFileSize = *(int64_t*)(header + 16);
|
int64_t outputFileSize = *(int64_t*)(header + 16);
|
||||||
pOutputBuffer = new uint8_t[outputFileSize + 1];
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
int bz2err;
|
BZFILE* bzHandle = nullptr;
|
||||||
BZFILE* bzHandle = BZ2_bzReadOpen(&bz2err, patchFile, 0, 0, NULL, 0);
|
ZSTD_DecompressContext* zstdCtx = nullptr;
|
||||||
if (bzHandle == nullptr)
|
if (compressMethod == 1)
|
||||||
{
|
{
|
||||||
printf("BZ2_bzReadOpen, bz2err=%d", bz2err);
|
int bz2err;
|
||||||
break;
|
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
|
// Apply the patch
|
||||||
struct bspatch_stream stream;
|
struct bspatch_stream stream;
|
||||||
stream.read = bzPatchFileReader;
|
if (compressMethod == 1)
|
||||||
stream.opaque = bzHandle;
|
{
|
||||||
if (bspatch(pInputBuffer, inputFileSize, pOutputBuffer, outputFileSize, &stream))
|
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");
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean up the bzip2 reads
|
if (compressMethod == 1)
|
||||||
BZ2_bzReadClose(&bz2err, bzHandle);
|
{
|
||||||
|
// 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
|
// Write the output buffer to the output file
|
||||||
if (outputFileSize != fwrite(pOutputBuffer, 1, outputFileSize, outputFile))
|
if (outputFileSize != fwrite(pOutputBuffer, 1, outputFileSize, outputFile))
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
* @param inputFilename The path to the original input file to be patched.
|
* @param inputFilename The path to the original input file to be patched.
|
||||||
* @param patchFilename The path to the BSDIFF43 patch file (bzip2-compressed).
|
* @param patchFilename The path to the BSDIFF43 patch file (bzip2-compressed).
|
||||||
* @param outputFilename The path to the output file where the patched result will be written.
|
* @param outputFilename The path to the output file where the patched result will be written.
|
||||||
|
* @param compressMethod 0:Not compress 1: bzip 2:zstd
|
||||||
* @return true if the patch is applied successfully; false otherwise.
|
* @return true if the patch is applied successfully; false otherwise.
|
||||||
*
|
*
|
||||||
* The function performs the following steps:
|
* The function performs the following steps:
|
||||||
@@ -18,4 +19,4 @@
|
|||||||
* 7. Writes the patched data to the output file.
|
* 7. Writes the patched data to the output file.
|
||||||
* 8. Cleans up all resources and returns true on success, or false if any error occurs.
|
* 8. Cleans up all resources and returns true on success, or false if any error occurs.
|
||||||
*/
|
*/
|
||||||
bool applyPatch(const char* inputFilename, const char* patchFilename, const char* outputFilename);
|
bool applyPatch(const char* inputFilename, const char* patchFilename, const char* outputFilename, int32_t compressMethod);
|
||||||
|
|||||||
@@ -30,3 +30,25 @@ bool downloadFile(const char* szDownloadUrl, const char* szLocalFile)
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool uploadFile(const char* szLocalFile, const char* szUploadUrl)
|
||||||
|
{
|
||||||
|
if (szLocalFile == nullptr || szUploadUrl == nullptr)
|
||||||
|
{
|
||||||
|
printf("Error: upload url or local file is null.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string urlStr = szUploadUrl;
|
||||||
|
|
||||||
|
if (_stricmp(urlStr.substr(0, 6).c_str(), "cos://") == 0)
|
||||||
|
{
|
||||||
|
uploadFileToCos(szLocalFile, urlStr.substr(6).c_str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Error: unsupported upload url scheme: %s\n", szUploadUrl);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
bool downloadFile(const char* szDownloadUrl, const char* szLocalFile);
|
bool downloadFile(const char* szDownloadUrl, const char* szLocalFile);
|
||||||
|
bool uploadFile(const char* szLocalFile, const char* szUploadUrl);
|
||||||
|
|||||||
+194
-15
@@ -2,13 +2,14 @@
|
|||||||
#include "sgu_mode_make_diff.h"
|
#include "sgu_mode_make_diff.h"
|
||||||
#include "sgu_utils.h"
|
#include "sgu_utils.h"
|
||||||
|
|
||||||
#include "bzlib.h"
|
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
#include "bsdiff.h"
|
#include "bsdiff.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "bzlib.h"
|
||||||
|
#include "zstd.h"
|
||||||
|
|
||||||
static int bzPatchFileWriter(struct bsdiff_stream* stream, const void* buffer, int size)
|
static int bzPatchFileWriter(struct bsdiff_stream* stream, const void* buffer, int size)
|
||||||
{
|
{
|
||||||
BZFILE* bz2 = (BZFILE*)stream->opaque;
|
BZFILE* bz2 = (BZFILE*)stream->opaque;
|
||||||
@@ -22,7 +23,143 @@ static int bzPatchFileWriter(struct bsdiff_stream* stream, const void* buffer, i
|
|||||||
return 0;
|
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)
|
if (!inputFilename1 || inputFilename1[0] == 0 || !inputFilename2 || inputFilename2[0] == 0)
|
||||||
{
|
{
|
||||||
@@ -72,31 +209,73 @@ bool createDiff(const char* inputFilename1, const char* inputFilename2, const ch
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
int bz2err;
|
BZFILE* bzHandle = nullptr;
|
||||||
BZFILE* bzHandle = BZ2_bzWriteOpen(&bz2err, fpOutput, 9, 0, 0);
|
ZSTD_CompressContext* zstdContext = nullptr;
|
||||||
if (bzHandle == nullptr || bz2err != BZ_OK)
|
if (compressMethod == 1)
|
||||||
{
|
{
|
||||||
printf("BZ2_bzWriteOpen failed, bz2err=%d\n", bz2err);
|
int bz2err;
|
||||||
break;
|
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
|
//generate diff
|
||||||
struct bsdiff_stream stream;
|
struct bsdiff_stream stream;
|
||||||
stream.malloc = malloc;
|
stream.malloc = malloc;
|
||||||
stream.free = free;
|
stream.free = free;
|
||||||
stream.write = bzPatchFileWriter;
|
if (compressMethod == 1)
|
||||||
stream.opaque = bzHandle;
|
{
|
||||||
if (bsdiff(pBuffer1, fileSize1, pBuffer2, fileSize2, &stream))
|
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");
|
printf("bsdiff error!\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
BZ2_bzWriteClose(&bz2err, bzHandle, 0, NULL, NULL);
|
if (compressMethod == 1)
|
||||||
if (bz2err != BZ_OK)
|
|
||||||
{
|
{
|
||||||
printf("BZ2_bzWriteClose failed, bz2err=%d", bz2err);
|
int bz2err;
|
||||||
break;
|
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;
|
result = true;
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
* @param inputFilename1 The path to the original (old) input file.
|
* @param inputFilename1 The path to the original (old) input file.
|
||||||
* @param inputFilename2 The path to the new input file to compare against.
|
* @param inputFilename2 The path to the new input file to compare against.
|
||||||
* @param outputFilename The path to the output file where the diff patch will be written.
|
* @param outputFilename The path to the output file where the diff patch will be written.
|
||||||
|
* @param compressMethod 0:Not compress 1: bzip 2:zstd
|
||||||
* @return true if the diff file is created successfully; false otherwise.
|
* @return true if the diff file is created successfully; false otherwise.
|
||||||
*
|
*
|
||||||
* The function performs the following steps:
|
* The function performs the following steps:
|
||||||
@@ -17,4 +18,4 @@
|
|||||||
* 6. Finalizes the bzip2 stream and closes all files and buffers.
|
* 6. Finalizes the bzip2 stream and closes all files and buffers.
|
||||||
* 7. Returns true on success, or false if any error occurs during processing.
|
* 7. Returns true on success, or false if any error occurs during processing.
|
||||||
*/
|
*/
|
||||||
bool createDiff(const char* inputFilename, const char* inputFilename2, const char* outputFilename);
|
bool createDiff(const char* inputFilename, const char* inputFilename2, const char* outputFilename, int32_t compressMethod);
|
||||||
|
|||||||
Reference in New Issue
Block a user