累计更新:

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
Binary file not shown.
+5 -2
View File
@@ -42,12 +42,14 @@ PRIVATE
../libTinyEncrypt
../lua/src
../luatinker
../zstd/lib
)
target_link_directories(sgutil
PRIVATE
../cos-cpp-sdk/libs/x64
../cos-cpp-sdk/third_party/lib/x64/poco
../zstd/precompiled/x64
)
target_link_libraries(sgutil
@@ -58,10 +60,11 @@ PRIVATE
libTinyEncrypt
LuaTinker
lua
zstd_static.lib
shlwapi.lib
wininet.lib
# cossdk.lib
# PocoFoundation.lib
cossdk.lib
PocoFoundation.lib
)
+44 -7
View File
@@ -1,7 +1,7 @@
#include "sgu_stdafx.h"
#include "sgu_download_cos.h"
#if 1
#if 0
bool downloadFileFromCOS(const char* cosFilePathName, const char* localFilePath)
{
return true;
@@ -19,15 +19,21 @@ static void TestLogCallback(const std::string& log)
//
// https://console.cloud.tencent.com/cam/capi
//
const uint64_t gAppID = 1313389434ULL;
const std::string gSecretId = "AKIDGMFKI2av3g6JPTKzRffS1NWR9eXDgwym";
const std::string gSecretKey = "f7LMDtNdnlXDpEQRGxVqxrbBYjlcbP2U";
const std::string gRegion = "ap-shanghai";
const std::string gBucketName = "dnftest-1313389434";
//const uint64_t gAppID = 1313389434ULL;
//const std::string gSecretId = "AKIDGMFKI2av3g6JPTKzRffS1NWR9eXDgwym";
//const std::string gSecretKey = "f7LMDtNdnlXDpEQRGxVqxrbBYjlcbP2U";
//const std::string gRegion = "ap-shanghai";
//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)
{
qcloud_cos::CosConfig config(gAppID, gSecretId, gSecretKey, gRegion);
qcloud_cos::CosConfig config(0, gSecretId, gSecretKey, gRegion);
config.SetLogCallback(&TestLogCallback);
qcloud_cos::CosAPI cos(config);
@@ -57,4 +63,35 @@ bool downloadFileFromCOS(const char* cosFilePathName, const char* localFilePath)
}
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
+2
View File
@@ -1,3 +1,5 @@
#pragma once
bool downloadFileFromCOS(const char* cosFilePath, const char* localFilePath);
bool uploadFileToCos(const char* localFilePath, const char* cosFilePath);
+33 -8
View File
@@ -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(" 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(" 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("\nSample:\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 HashFile -t md5 -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");
}
@@ -85,7 +87,8 @@ enum WorkMode {
WM_MAKE_DIFF,
WM_APPLY_PATCH,
WM_HASH_FILE,
WM_HTTP_DOWNLOAD,
WM_DOWNLOAD,
WM_UPLOAD,
WM_RUN_LUA_FILE,
};
@@ -124,8 +127,11 @@ WorkMode parserWorkMode(const char* modeStr)
else if (_stricmp(modeStr, "HashFile") == 0) {
return WM_HASH_FILE;
}
else if (_stricmp(modeStr, "HttpDownload") == 0) {
return WM_HTTP_DOWNLOAD;
else if (_stricmp(modeStr, "Download") == 0) {
return WM_DOWNLOAD;
}
else if (_stricmp(modeStr, "Upload") == 0) {
return WM_UPLOAD;
}
else if (_stricmp(modeStr, "RunLuaFile") == 0) {
return WM_RUN_LUA_FILE;
@@ -151,6 +157,8 @@ HashType parserHashType(const char* typeStr)
return HT_NONE; // default to HT_NONE
}
const int kDiffCompressMethod = 2;
int main(int argc, char* argv[])
{
CSimpleOptA args(argc, argv, g_rgOptions);
@@ -336,7 +344,7 @@ int main(int argc, char* argv[])
return 1;
}
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");
return 1;
@@ -353,14 +361,14 @@ int main(int argc, char* argv[])
return 1;
}
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");
return 1;
}
}
break;
case WM_HTTP_DOWNLOAD:
case WM_DOWNLOAD:
{
if (inputFilename == nullptr || outputFilename == nullptr)
{
@@ -377,6 +385,23 @@ int main(int argc, char* argv[])
}
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:
{
if (inputFilename == nullptr)
+168 -5
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)
{
@@ -94,26 +207,76 @@ bool applyPatch(const char* inputFilename, const char* patchFilename, const char
break;
}
BZFILE* bzHandle = nullptr;
ZSTD_DecompressContext* zstdCtx = nullptr;
if (compressMethod == 1)
{
int bz2err;
BZFILE* bzHandle = BZ2_bzReadOpen(&bz2err, patchFile, 0, 0, NULL, 0);
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;
if (compressMethod == 1)
{
stream.read = bzPatchFileReader;
stream.opaque = bzHandle;
if (bspatch(pInputBuffer, inputFileSize, pOutputBuffer, outputFileSize, &stream))
}
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;
}
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))
+2 -1
View File
@@ -6,6 +6,7 @@
* @param inputFilename The path to the original input file to be patched.
* @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 compressMethod 0:Not compress 1: bzip 2:zstd
* @return true if the patch is applied successfully; false otherwise.
*
* The function performs the following steps:
@@ -18,4 +19,4 @@
* 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.
*/
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);
+22
View File
@@ -30,3 +30,25 @@ bool downloadFile(const char* szDownloadUrl, const char* szLocalFile)
}
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
View File
@@ -1,3 +1,4 @@
#pragma once
bool downloadFile(const char* szDownloadUrl, const char* szLocalFile);
bool uploadFile(const char* szLocalFile, const char* szUploadUrl);
+184 -5
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,32 +209,74 @@ bool createDiff(const char* inputFilename1, const char* inputFilename2, const ch
break;
}
BZFILE* bzHandle = nullptr;
ZSTD_CompressContext* zstdContext = nullptr;
if (compressMethod == 1)
{
int bz2err;
BZFILE* bzHandle = BZ2_bzWriteOpen(&bz2err, fpOutput, 9, 0, 0);
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;
if (compressMethod == 1)
{
stream.write = bzPatchFileWriter;
stream.opaque = bzHandle;
if (bsdiff(pBuffer1, fileSize1, pBuffer2, fileSize2, &stream))
}
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;
}
if (compressMethod == 1)
{
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;
printf("Diff file created successfully: %s\n", outputFilename);
+2 -1
View File
@@ -6,6 +6,7 @@
* @param inputFilename1 The path to the original (old) input file.
* @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 compressMethod 0:Not compress 1: bzip 2:zstd
* @return true if the diff file is created successfully; false otherwise.
*
* The function performs the following steps:
@@ -17,4 +18,4 @@
* 6. Finalizes the bzip2 stream and closes all files and buffers.
* 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);