mirror of
https://github.com/velopack/velopack.git
synced 2025-10-25 15:19:22 +00:00
Update C++ header to align with new C functions
This commit is contained in:
@@ -35,7 +35,12 @@ typedef void vpkc_update_source_t;
|
||||
/**
|
||||
* User delegate for to fetch a release feed. This function should return the raw JSON string of the release.json feed.
|
||||
*/
|
||||
typedef const char *(*vpkc_release_feed_delegate_t)(void *p_user_data, const char *psz_releases_name);
|
||||
typedef char *(*vpkc_release_feed_delegate_t)(void *p_user_data, const char *psz_releases_name);
|
||||
|
||||
/**
|
||||
* User delegate for freeing a release feed. This function should free the feed string returned by `vpkc_release_feed_delegate_t`.
|
||||
*/
|
||||
typedef void (*vpkc_free_release_feed_t)(void *p_user_data, char *psz_feed);
|
||||
|
||||
/**
|
||||
* An individual Velopack asset, could refer to an asset on-disk or in a remote package feed.
|
||||
@@ -203,6 +208,7 @@ vpkc_update_source_t *vpkc_new_source_http_url(const char *psz_http_url);
|
||||
* Therefore to avoid possible issues, it is recommended to create this type of source once for the lifetime of your application.
|
||||
*/
|
||||
vpkc_update_source_t *vpkc_new_source_custom_callback(vpkc_release_feed_delegate_t cb_release_feed,
|
||||
vpkc_free_release_feed_t cb_free_release_feed,
|
||||
vpkc_download_asset_delegate_t cb_download_entry,
|
||||
void *p_user_data);
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <vector>
|
||||
#include <stdexcept>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
|
||||
#include "Velopack.h"
|
||||
|
||||
@@ -192,23 +193,32 @@ static inline UpdateOptions to_cpp(const vpkc_update_options_t& dto) {
|
||||
}
|
||||
// !! AUTO-GENERATED-END CPP_TYPES
|
||||
|
||||
static inline char** to_cstring_array(const std::vector<std::string>& vec) {
|
||||
static inline char* allocate_cstring(const std::string& str) {
|
||||
char* result = new char[str.size() + 1]; // +1 for null-terminator
|
||||
#ifdef _WIN32
|
||||
strcpy_s(result, str.size() + 1, str.c_str()); // Copy string content
|
||||
#else
|
||||
strcpy(result, str.c_str()); // Copy string content
|
||||
#endif
|
||||
result[str.size()] = '\0'; // Null-terminate the string
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline void free_cstring(char* str) {
|
||||
delete[] str;
|
||||
}
|
||||
|
||||
static inline char** allocate_cstring_array(const std::vector<std::string>& vec) {
|
||||
char** result = new char*[vec.size()];
|
||||
for (size_t i = 0; i < vec.size(); ++i) {
|
||||
result[i] = new char[vec[i].size() + 1]; // +1 for null-terminator
|
||||
#ifdef _WIN32
|
||||
strcpy_s(result[i], vec[i].size() + 1, vec[i].c_str()); // Copy string content
|
||||
#else
|
||||
strcpy(result[i], vec[i].c_str()); // Copy string content
|
||||
#endif
|
||||
result[i][vec[i].size()] = '\0'; // Null-terminate the string
|
||||
result[i] = allocate_cstring(vec[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline void free_cstring_array(char** arr, size_t size) {
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
delete[] arr[i];
|
||||
free_cstring(arr[i]);
|
||||
arr[i] = nullptr;
|
||||
}
|
||||
delete[] arr;
|
||||
@@ -250,7 +260,7 @@ public:
|
||||
* Override the command line arguments used by VelopackApp. (by default this is env::args().skip(1))
|
||||
*/
|
||||
VelopackApp& SetArgs(const std::vector<std::string>& args) {
|
||||
char** pArgs = to_cstring_array(args);
|
||||
char** pArgs = allocate_cstring_array(args);
|
||||
vpkc_app_set_args(pArgs, args.size());
|
||||
free_cstring_array(pArgs, args.size());
|
||||
return *this;
|
||||
@@ -335,20 +345,65 @@ public:
|
||||
};
|
||||
|
||||
/**
|
||||
* Implement this interface override the default update source
|
||||
* (AutoSource)
|
||||
* Progress callback function. Call with values between 0 and 100 inclusive.
|
||||
*/
|
||||
typedef std::function<void(size_t)> vpkc_progress_send_t;
|
||||
|
||||
/**
|
||||
* Abstract class for retrieving release feeds and downloading assets. You should subclass this and
|
||||
* implement/override the GetReleaseFeed and DownloadReleaseEntry methods.
|
||||
* This class is used by the UpdateManager to fetch release feeds and download assets in a custom way.
|
||||
*/
|
||||
class IUpdateSource {
|
||||
friend class UpdateManager;
|
||||
friend class FileSource;
|
||||
friend class HttpSource;
|
||||
private:
|
||||
IUpdateSource(vpkc_update_source_t* pSource) : m_pSource(pSource) {}
|
||||
vpkc_update_source_t* m_pSource = 0;
|
||||
public:
|
||||
/** @param Retrieve the list of available remote releases from
|
||||
* the package source. These releases can subsequently be downloaded
|
||||
* with DownloadReleaseEntry().
|
||||
*/
|
||||
virtual const char* GetReleaseFeed(const char* releasesName) = 0;
|
||||
~IUpdateSource() {
|
||||
vpkc_free_source(m_pSource);
|
||||
}
|
||||
IUpdateSource() {
|
||||
m_pSource = vpkc_new_source_custom_callback(
|
||||
[](void* userData, const char* releasesName) {
|
||||
IUpdateSource* source = reinterpret_cast<IUpdateSource*>(userData);
|
||||
std::string json = source->GetReleaseFeed(releasesName);
|
||||
return allocate_cstring(json);
|
||||
},
|
||||
[](void* userData, char* pszFeed) {
|
||||
free_cstring(pszFeed);
|
||||
},
|
||||
[](void* userData, const struct vpkc_asset_t *pAsset, const char* pszLocalPath, size_t progressCallbackId) {
|
||||
IUpdateSource* source = reinterpret_cast<IUpdateSource*>(userData);
|
||||
VelopackAsset asset = to_cpp(*pAsset);
|
||||
std::string localPath = to_cppstring(pszLocalPath);
|
||||
std::function<void(size_t)> progress_callback = [progressCallbackId](size_t progress) {
|
||||
vpkc_source_report_progress(progressCallbackId, progress);
|
||||
};
|
||||
return source->DownloadReleaseEntry(asset, localPath, progress_callback);
|
||||
},
|
||||
this);
|
||||
}
|
||||
virtual const std::string GetReleaseFeed(const std::string releasesName) = 0;
|
||||
virtual bool DownloadReleaseEntry(const VelopackAsset& asset, const std::string localFilePath, vpkc_progress_send_t progress) = 0;
|
||||
};
|
||||
|
||||
/** @param Download the specified VelopackAsset to the provided local file path.
|
||||
*/
|
||||
virtual bool DownloadReleaseEntry(const char* assetFileName, const char* localFilePath) = 0;
|
||||
/**
|
||||
* A simple update source that reads release feeds and downloads assets from a local file path.
|
||||
*/
|
||||
class FileSource : public IUpdateSource {
|
||||
public:
|
||||
FileSource(const std::string& filePath) : IUpdateSource(vpkc_new_source_file(filePath.c_str())) { }
|
||||
};
|
||||
|
||||
/**
|
||||
* A simple update source that reads release feeds and downloads assets from an remote http url.
|
||||
*/
|
||||
class HttpSource : public IUpdateSource {
|
||||
public:
|
||||
HttpSource(const std::string& httpUrl) : IUpdateSource(vpkc_new_source_http_url(httpUrl.c_str())) { }
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -362,7 +417,7 @@ private:
|
||||
public:
|
||||
/**
|
||||
* Create a new UpdateManager instance.
|
||||
* @param urlOrPath Location of the update server or path to the local update directory.
|
||||
* @param urlOrPath Location of the http update server or the local update directory path containing releases.
|
||||
* @param options Optional extra configuration for update manager.
|
||||
* @param locator Override the default locator configuration (usually used for testing / mocks).
|
||||
*/
|
||||
@@ -388,36 +443,28 @@ public:
|
||||
|
||||
/**
|
||||
* Create a new UpdateManager instance.
|
||||
* @param pUpdateSource Custom update source implementation.
|
||||
* @param updateSource The source to use for retrieving feed and downloading assets.
|
||||
* @param options Optional extra configuration for update manager.
|
||||
* @param locator Override the default locator configuration (usually used for testing / mocks).
|
||||
*/
|
||||
UpdateManager(std::unique_ptr<IUpdateSource> pUpdateSource, const UpdateOptions* options = nullptr, const VelopackLocatorConfig* locator = nullptr) {
|
||||
vpkc_update_options_t vpkc_options;
|
||||
vpkc_update_options_t* pOptions = nullptr;
|
||||
if (options != nullptr) {
|
||||
vpkc_update_options_t vpkc_options = to_c(*options);
|
||||
vpkc_options = to_c(*options);
|
||||
pOptions = &vpkc_options;
|
||||
}
|
||||
|
||||
|
||||
vpkc_locator_config_t vpkc_locator;
|
||||
vpkc_locator_config_t* pLocator = nullptr;
|
||||
if (locator != nullptr) {
|
||||
vpkc_locator_config_t vpkc_locator = to_c(*locator);
|
||||
vpkc_locator = to_c(*locator);
|
||||
pLocator = &vpkc_locator;
|
||||
}
|
||||
|
||||
auto cbGetReleaseFeed = [](const char* releasesName, void* userData) {
|
||||
IUpdateSource* source = reinterpret_cast<IUpdateSource*>(userData);
|
||||
return source->GetReleaseFeed(releasesName);
|
||||
};
|
||||
|
||||
auto cbDownloadReleaseEntry = [](const char* assetFileName, const char* localFilePath, void* userData) {
|
||||
IUpdateSource* source = reinterpret_cast<IUpdateSource*>(userData);
|
||||
return source->DownloadReleaseEntry(assetFileName, localFilePath);
|
||||
};
|
||||
|
||||
m_pUpdateSource.swap(pUpdateSource);
|
||||
|
||||
if (!vpkc_new_custom_update_manager(cbGetReleaseFeed, cbDownloadReleaseEntry, m_pUpdateSource.get(), pOptions, pLocator, &m_pManager)) {
|
||||
vpkc_update_source_t* pSource = m_pUpdateSource->m_pSource;
|
||||
if (!vpkc_new_update_manager_with_source(pSource, pOptions, pLocator, &m_pManager)) {
|
||||
throw_last_error();
|
||||
}
|
||||
};
|
||||
@@ -514,7 +561,7 @@ public:
|
||||
* optionally restart your app. The updater will only wait for 60 seconds before giving up.
|
||||
*/
|
||||
void WaitExitThenApplyUpdate(const VelopackAsset& asset, bool silent = false, bool restart = true, std::vector<std::string> restartArgs = {}) {
|
||||
char** pRestartArgs = to_cstring_array(restartArgs);
|
||||
char** pRestartArgs = allocate_cstring_array(restartArgs);
|
||||
vpkc_asset_t vpkc_asset = to_c(asset);
|
||||
bool result = vpkc_wait_exit_then_apply_update(m_pManager, &vpkc_asset, silent, restart, pRestartArgs, restartArgs.size());
|
||||
free_cstring_array(pRestartArgs, restartArgs.size());
|
||||
|
||||
@@ -28,6 +28,7 @@ pub fn report_csource_progress(callback_id: size_t, progress: i16) {
|
||||
pub struct CCallbackUpdateSource {
|
||||
pub p_user_data: *mut c_void,
|
||||
pub cb_get_release_feed: vpkc_release_feed_delegate_t,
|
||||
pub cb_free_release_feed: vpkc_free_release_feed_t,
|
||||
pub cb_download_release_entry: vpkc_download_asset_delegate_t,
|
||||
}
|
||||
|
||||
@@ -41,6 +42,7 @@ impl UpdateSource for CCallbackUpdateSource {
|
||||
let json_cstr_ptr = (self.cb_get_release_feed)(self.p_user_data, releases_name_cstr.as_ptr());
|
||||
let json = c_to_string_opt(json_cstr_ptr)
|
||||
.ok_or(Error::Generic("User vpkc_release_feed_delegate_t returned a null pointer instead of an asset feed".to_string()))?;
|
||||
(self.cb_free_release_feed)(self.p_user_data, json_cstr_ptr); // Free the C string returned by the callback
|
||||
let feed: VelopackAssetFeed = serde_json::from_str(&json)?;
|
||||
Ok(feed)
|
||||
}
|
||||
|
||||
@@ -44,12 +44,14 @@ pub extern "C" fn vpkc_new_source_http_url(psz_http_url: *const c_char) -> *mut
|
||||
#[no_mangle]
|
||||
pub extern "C" fn vpkc_new_source_custom_callback(
|
||||
cb_release_feed: vpkc_release_feed_delegate_t,
|
||||
cb_free_release_feed: vpkc_free_release_feed_t,
|
||||
cb_download_entry: vpkc_download_asset_delegate_t,
|
||||
p_user_data: *mut c_void,
|
||||
) -> *mut vpkc_update_source_t {
|
||||
let cb_release_feed = cb_release_feed.to_option();
|
||||
let cb_download_entry = cb_download_entry.to_option();
|
||||
if cb_release_feed.is_none() || cb_download_entry.is_none() {
|
||||
let cb_free_release_feed = cb_free_release_feed.to_option();
|
||||
if cb_release_feed.is_none() || cb_download_entry.is_none() || cb_free_release_feed.is_none() {
|
||||
return ptr::null_mut();
|
||||
}
|
||||
|
||||
@@ -57,6 +59,7 @@ pub extern "C" fn vpkc_new_source_custom_callback(
|
||||
p_user_data,
|
||||
cb_get_release_feed: cb_release_feed.unwrap(),
|
||||
cb_download_release_entry: cb_download_entry.unwrap(),
|
||||
cb_free_release_feed: cb_free_release_feed.unwrap(),
|
||||
};
|
||||
|
||||
UpdateSourceRawPtr::new(Box::new(source))
|
||||
|
||||
@@ -35,6 +35,12 @@ impl CallbackExt for vpkc_download_asset_delegate_t {
|
||||
}
|
||||
}
|
||||
|
||||
impl CallbackExt for vpkc_free_release_feed_t {
|
||||
fn to_option(self) -> Option<Self> {
|
||||
unsafe { std::mem::transmute::<Self, Option<Self>>(self) }
|
||||
}
|
||||
}
|
||||
|
||||
pub trait RawPtrExt<'a, T>: Sized {
|
||||
fn to_opaque_ref(self) -> Option<&'a T>;
|
||||
}
|
||||
|
||||
@@ -28,7 +28,10 @@ pub type vpkc_log_callback_t = extern "C" fn(p_user_data: *mut c_void, psz_level
|
||||
pub type vpkc_hook_callback_t = extern "C" fn(p_user_data: *mut c_void, psz_app_version: *const c_char);
|
||||
|
||||
/// User delegate for to fetch a release feed. This function should return the raw JSON string of the release.json feed.
|
||||
pub type vpkc_release_feed_delegate_t = extern "C" fn(p_user_data: *mut c_void, psz_releases_name: *const c_char) -> *const c_char;
|
||||
pub type vpkc_release_feed_delegate_t = extern "C" fn(p_user_data: *mut c_void, psz_releases_name: *const c_char) -> *mut c_char;
|
||||
|
||||
/// User delegate for freeing a release feed. This function should free the feed string returned by `vpkc_release_feed_delegate_t`.
|
||||
pub type vpkc_free_release_feed_t = extern "C" fn(p_user_data: *mut c_void, psz_feed: *mut c_char);
|
||||
|
||||
/// User delegate for downloading an asset file. This function is expected to download the provided asset
|
||||
/// to the provided local file path. Througout, you can use the progress callback to write progress reports.
|
||||
|
||||
Reference in New Issue
Block a user