-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Issue 313 - Use bsdiff library instead of managed implementation (#314)
* Add pal_bsdiff / pal_bspatch. * R# * Refactor: corerun / libcorerun is no longer embedded inside Snap but assets are instead copied to runtimes/$Rid/native directory. This means that snapx can now support native AOT compiled executables and we use bsdiff C library in CoreRunLib class. * Use bsdiff library instead of our own implementation. * Try fixing linking error on windows. * Try fixing build error on windows. * Move bsdiff code to Snap.Bsdiff in order to avoid increasing corerun executable binary size. * Add missing cmake configuration. * Windows build fix. * Fix copying bsdiff library on Windows. * Bugfix: Incorrect os platform. * Bugfix: Collect bsdiff libary. * Renaming in order to make the code easier to reason about. * Bugfix: Create relative directory. * Add support for reading patch from memory. I fixed the bug in the bsdiff library in the following commit: fintermobilityas/bsdiff@6ba6b5d * Enable nupkg workflow But only publish nupkgs if branch is master. * Fix clang-tidy warnings. * Fix nupkg.
- Loading branch information
Showing
46 changed files
with
1,383 additions
and
2,125 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
cmake_minimum_required (VERSION 3.10 FATAL_ERROR) | ||
|
||
project(snap_bsdiff CXX) | ||
|
||
set(snap_bsdiff_SOURCES | ||
src/lib.cpp | ||
) | ||
|
||
set(snap_bsdiff_INCLUDE_DIRS PRIVATE | ||
../Vendor/bsdiff/include | ||
src/include) | ||
|
||
|
||
set(snap_bsdiff_static_LIBS ) | ||
|
||
if(WIN32) | ||
list(APPEND snap_bsdiff_DEFINES SNAP_PLATFORM_WINDOWS) | ||
elseif(UNIX) | ||
list(APPEND snap_bsdiff_DEFINES SNAP_PLATFORM_LINUX) | ||
list(APPEND snap_bsdiff_static_LIBS libstdc++.a) | ||
else() | ||
message(FATAL_ERROR "Error: Unsupported platform") | ||
endif() | ||
|
||
add_library(snap_bsdiff SHARED ${snap_bsdiff_SOURCES}) | ||
|
||
target_link_libraries(snap_bsdiff PUBLIC bsdiff ${snap_bsdiff_static_LIBS}) | ||
target_include_directories(snap_bsdiff PUBLIC ${snap_bsdiff_INCLUDE_DIRS}) | ||
target_compile_definitions(snap_bsdiff PRIVATE ${snap_bsdiff_DEFINES}) | ||
|
||
set_property(TARGET snap_bsdiff PROPERTY CXX_STANDARD 17) | ||
set_property(TARGET snap_bsdiff PROPERTY CXX_STANDARD_REQUIRED ON) | ||
set_property(TARGET snap_bsdiff PROPERTY POSITION_INDEPENDENT_CODE ON) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
#pragma once | ||
|
||
#include <bsdiff.h> | ||
#include <cstdint> | ||
|
||
#ifdef SNAP_PLATFORM_WINDOWS | ||
#define SNAP_API __declspec( dllexport ) | ||
#define SNAP_CALLING_CONVENTION __cdecl | ||
#elif SNAP_PLATFORM_LINUX | ||
#if defined(__GNUC__) | ||
#define SNAP_API __attribute__((visibility("default"))) | ||
#define SNAP_CALLING_CONVENTION | ||
#endif | ||
#endif | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
typedef void (*snap_bsdiff_error_logger_t)(void *opaque, const char *errmsg); | ||
|
||
typedef enum _snap_bsdiff_status_type { | ||
bsdiff_status_type_success = 0, | ||
bsdiff_status_type_error = 1, | ||
bsdiff_status_type_invalid_arg = 2, | ||
bsdiff_status_type_out_of_memory = 3, | ||
bsdiff_status_type_file_error = 4, | ||
bsdiff_status_type_end_of_file = 5, | ||
bsdiff_status_type_corrupt_patch = 6, | ||
bsdiff_status_type_size_too_large = 7 | ||
} snap_bsdiff_status_type; | ||
|
||
typedef struct _snap_bsdiff_patch_ctx { | ||
snap_bsdiff_error_logger_t error_logger; | ||
const void *older; | ||
size_t older_size; | ||
uint8_t **newer; | ||
size_t newer_size; | ||
const void *patch; | ||
const size_t patch_size; | ||
snap_bsdiff_status_type status; | ||
} snap_bsdiff_patch_ctx; | ||
|
||
typedef struct _snap_bsdiff_diff_ctx { | ||
snap_bsdiff_error_logger_t error_logger; | ||
const void *older; | ||
size_t older_size; | ||
const void *newer; | ||
size_t newer_size; | ||
uint8_t **patch; | ||
size_t patch_size; | ||
snap_bsdiff_status_type status; | ||
} snap_bsdiff_diff_ctx; | ||
|
||
SNAP_API int32_t SNAP_CALLING_CONVENTION snap_bsdiff_patch(snap_bsdiff_patch_ctx *p_ctx); | ||
SNAP_API int32_t SNAP_CALLING_CONVENTION snap_bsdiff_patch_free(snap_bsdiff_patch_ctx* p_ctx); | ||
SNAP_API int32_t SNAP_CALLING_CONVENTION snap_bsdiff_diff(snap_bsdiff_diff_ctx* p_ctx); | ||
SNAP_API int32_t SNAP_CALLING_CONVENTION snap_bsdiff_diff_free(snap_bsdiff_diff_ctx* p_ctx); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
#include "bsdiff/lib.hpp" | ||
#include <cstring> | ||
|
||
SNAP_API int32_t SNAP_CALLING_CONVENTION snap_bsdiff_patch(snap_bsdiff_patch_ctx* p_ctx) { | ||
if(p_ctx == nullptr || | ||
p_ctx->older == nullptr || | ||
p_ctx->older_size <= 0 || | ||
p_ctx->newer != nullptr || | ||
p_ctx->newer_size != 0 || | ||
p_ctx->patch == nullptr || | ||
p_ctx->patch_size <= 0) { | ||
return 0; | ||
} | ||
|
||
int ret; | ||
struct bsdiff_stream oldfile = { nullptr }, newfile = { nullptr }, patchfile = { nullptr }; | ||
struct bsdiff_ctx ctx = { nullptr }; | ||
struct bsdiff_patch_packer packer = { nullptr }; | ||
|
||
if ((ret = bsdiff_open_memory_stream(BSDIFF_MODE_READ, p_ctx->older, p_ctx->older_size, &oldfile)) != BSDIFF_SUCCESS) { | ||
goto cleanup; | ||
} | ||
|
||
if ((ret = bsdiff_open_memory_stream(BSDIFF_MODE_WRITE, nullptr, 0, &newfile)) != BSDIFF_SUCCESS) { | ||
goto cleanup; | ||
} | ||
|
||
if ((ret = bsdiff_open_memory_stream(BSDIFF_MODE_READ, p_ctx->patch, p_ctx->patch_size, &patchfile)) != BSDIFF_SUCCESS) { | ||
goto cleanup; | ||
} | ||
|
||
if ((ret = bsdiff_open_bz2_patch_packer(BSDIFF_MODE_READ, &patchfile, &packer)) != BSDIFF_SUCCESS) { | ||
goto cleanup; | ||
} | ||
|
||
ctx.log_error = p_ctx->error_logger; | ||
|
||
if ((ret = bspatch(&ctx, &oldfile, &newfile, &packer)) != BSDIFF_SUCCESS) { | ||
goto cleanup; | ||
} | ||
|
||
cleanup: | ||
p_ctx->status = static_cast<snap_bsdiff_status_type>(ret); | ||
|
||
if(p_ctx->status == bsdiff_status_type_success) { | ||
const void* newer_buffer = nullptr; | ||
size_t newer_buffer_len = 0; | ||
newfile.get_buffer(newfile.state, &newer_buffer, &newer_buffer_len); | ||
|
||
p_ctx->newer_size = static_cast<int64_t>(newer_buffer_len); | ||
p_ctx->newer = new uint8_t*[newer_buffer_len]; | ||
std::memcpy(p_ctx->newer, newer_buffer, newer_buffer_len); | ||
} | ||
|
||
bsdiff_close_patch_packer(&packer); | ||
bsdiff_close_stream(&patchfile); | ||
bsdiff_close_stream(&newfile); | ||
bsdiff_close_stream(&oldfile); | ||
|
||
return p_ctx->status == bsdiff_status_type_success ? 1 : 0; | ||
} | ||
|
||
SNAP_API int32_t SNAP_CALLING_CONVENTION snap_bsdiff_patch_free(snap_bsdiff_patch_ctx* p_ctx) { | ||
if(p_ctx == nullptr) { | ||
return 0; | ||
} | ||
|
||
if(p_ctx->newer != nullptr) { | ||
delete[] p_ctx->newer; | ||
p_ctx->newer = nullptr; | ||
p_ctx->newer_size = 0; | ||
} | ||
|
||
return 1; | ||
} | ||
|
||
SNAP_API int32_t SNAP_CALLING_CONVENTION snap_bsdiff_diff(snap_bsdiff_diff_ctx* p_ctx) { | ||
if(p_ctx == nullptr || | ||
p_ctx->older == nullptr || | ||
p_ctx->older_size <= 0 || | ||
p_ctx->newer == nullptr || | ||
p_ctx->newer_size <= 0) { | ||
return 0; | ||
} | ||
|
||
int ret; | ||
struct bsdiff_stream oldfile = { nullptr }, newfile = { nullptr }, patchfile = { nullptr }; | ||
struct bsdiff_ctx ctx = { nullptr }; | ||
struct bsdiff_patch_packer packer = { nullptr }; | ||
|
||
if ((ret = bsdiff_open_memory_stream(BSDIFF_MODE_READ, p_ctx->older, p_ctx->older_size, &oldfile)) != BSDIFF_SUCCESS) { | ||
goto cleanup; | ||
} | ||
|
||
if ((ret = bsdiff_open_memory_stream(BSDIFF_MODE_READ, p_ctx->newer, p_ctx->newer_size, &newfile)) != BSDIFF_SUCCESS) { | ||
goto cleanup; | ||
} | ||
|
||
if ((ret = bsdiff_open_memory_stream(BSDIFF_MODE_WRITE, nullptr, 0, &patchfile)) != BSDIFF_SUCCESS) { | ||
goto cleanup; | ||
} | ||
|
||
if ((ret = bsdiff_open_bz2_patch_packer(BSDIFF_MODE_WRITE, &patchfile, &packer)) != BSDIFF_SUCCESS) { | ||
goto cleanup; | ||
} | ||
|
||
ctx.log_error = p_ctx->error_logger; | ||
|
||
if ((ret = bsdiff(&ctx, &oldfile, &newfile, &packer)) != BSDIFF_SUCCESS) { | ||
goto cleanup; | ||
} | ||
|
||
cleanup: | ||
p_ctx->status = static_cast<snap_bsdiff_status_type>(ret); | ||
|
||
if(p_ctx->status == bsdiff_status_type_success) { | ||
const void* patch_buffer = nullptr; | ||
size_t patch_buffer_len = 0; | ||
patchfile.get_buffer(patchfile.state, &patch_buffer, &patch_buffer_len); | ||
|
||
p_ctx->patch_size = static_cast<int64_t>(patch_buffer_len); | ||
p_ctx->patch = new uint8_t*[patch_buffer_len]; | ||
std::memcpy(p_ctx->patch, patch_buffer, patch_buffer_len); | ||
} | ||
|
||
bsdiff_close_patch_packer(&packer); | ||
bsdiff_close_stream(&patchfile); | ||
bsdiff_close_stream(&newfile); | ||
bsdiff_close_stream(&oldfile); | ||
|
||
return p_ctx->status == bsdiff_status_type_success ? 1 : 0; | ||
} | ||
|
||
SNAP_API int32_t SNAP_CALLING_CONVENTION snap_bsdiff_diff_free(snap_bsdiff_diff_ctx* p_ctx) { | ||
if(p_ctx == nullptr) { | ||
return 0; | ||
} | ||
|
||
if(p_ctx->patch != nullptr) { | ||
delete[] p_ctx->patch; | ||
p_ctx->patch = nullptr; | ||
p_ctx->patch_size = 0; | ||
} | ||
|
||
return 1; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.