mirror of
https://github.com/jkcoxson/idevice.git
synced 2026-03-02 06:26:15 +01:00
feat(crashreportcopymobile): ffi bindings (#71)
* feat(crashreportcopymobile): ffi bindings * chore: update readme
This commit is contained in:
50
cpp/include/idevice++/crashreportcopymobile.hpp
Normal file
50
cpp/include/idevice++/crashreportcopymobile.hpp
Normal file
@@ -0,0 +1,50 @@
|
||||
// Jackson Coxson
|
||||
|
||||
#pragma once
|
||||
#include <idevice++/bindings.hpp>
|
||||
#include <idevice++/ffi.hpp>
|
||||
#include <idevice++/provider.hpp>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace IdeviceFFI {
|
||||
|
||||
using CrashReportCopyMobilePtr =
|
||||
std::unique_ptr<CrashReportCopyMobileHandle,
|
||||
FnDeleter<CrashReportCopyMobileHandle, crash_report_client_free>>;
|
||||
|
||||
class CrashReportCopyMobile {
|
||||
public:
|
||||
// Factory: connect via Provider
|
||||
static Result<CrashReportCopyMobile, FfiError> connect(Provider& provider);
|
||||
|
||||
// Factory: wrap an existing Idevice socket (consumes it on success)
|
||||
static Result<CrashReportCopyMobile, FfiError> from_socket(Idevice&& socket);
|
||||
|
||||
// Static: flush crash reports from system storage
|
||||
static Result<void, FfiError> flush(Provider& provider);
|
||||
|
||||
// Ops
|
||||
Result<std::vector<std::string>, FfiError> ls(const char* dir_path = nullptr);
|
||||
Result<std::vector<char>, FfiError> pull(const std::string& log_name);
|
||||
Result<void, FfiError> remove(const std::string& log_name);
|
||||
|
||||
// RAII / moves
|
||||
~CrashReportCopyMobile() noexcept = default;
|
||||
CrashReportCopyMobile(CrashReportCopyMobile&&) noexcept = default;
|
||||
CrashReportCopyMobile& operator=(CrashReportCopyMobile&&) noexcept = default;
|
||||
CrashReportCopyMobile(const CrashReportCopyMobile&) = delete;
|
||||
CrashReportCopyMobile& operator=(const CrashReportCopyMobile&) = delete;
|
||||
|
||||
CrashReportCopyMobileHandle* raw() const noexcept { return handle_.get(); }
|
||||
static CrashReportCopyMobile adopt(CrashReportCopyMobileHandle* h) noexcept {
|
||||
return CrashReportCopyMobile(h);
|
||||
}
|
||||
|
||||
private:
|
||||
explicit CrashReportCopyMobile(CrashReportCopyMobileHandle* h) noexcept : handle_(h) {}
|
||||
CrashReportCopyMobilePtr handle_{};
|
||||
};
|
||||
|
||||
} // namespace IdeviceFFI
|
||||
94
cpp/src/crashreportcopymobile.cpp
Normal file
94
cpp/src/crashreportcopymobile.cpp
Normal file
@@ -0,0 +1,94 @@
|
||||
// Jackson Coxson
|
||||
|
||||
#include <cstring>
|
||||
#include <idevice++/bindings.hpp>
|
||||
#include <idevice++/crashreportcopymobile.hpp>
|
||||
#include <idevice++/ffi.hpp>
|
||||
#include <idevice++/provider.hpp>
|
||||
|
||||
namespace IdeviceFFI {
|
||||
|
||||
// -------- Factory Methods --------
|
||||
|
||||
Result<CrashReportCopyMobile, FfiError> CrashReportCopyMobile::connect(Provider& provider) {
|
||||
CrashReportCopyMobileHandle* out = nullptr;
|
||||
FfiError e(::crash_report_client_connect(provider.raw(), &out));
|
||||
if (e) {
|
||||
return Err(e);
|
||||
}
|
||||
return Ok(CrashReportCopyMobile::adopt(out));
|
||||
}
|
||||
|
||||
Result<CrashReportCopyMobile, FfiError> CrashReportCopyMobile::from_socket(Idevice&& socket) {
|
||||
CrashReportCopyMobileHandle* out = nullptr;
|
||||
FfiError e(::crash_report_client_new(socket.raw(), &out));
|
||||
if (e) {
|
||||
return Err(e);
|
||||
}
|
||||
socket.release();
|
||||
return Ok(CrashReportCopyMobile::adopt(out));
|
||||
}
|
||||
|
||||
Result<void, FfiError> CrashReportCopyMobile::flush(Provider& provider) {
|
||||
FfiError e(::crash_report_flush(provider.raw()));
|
||||
if (e) {
|
||||
return Err(e);
|
||||
}
|
||||
return Ok();
|
||||
}
|
||||
|
||||
// -------- Ops --------
|
||||
|
||||
Result<std::vector<std::string>, FfiError>
|
||||
CrashReportCopyMobile::ls(const char* dir_path) {
|
||||
char** entries_raw = nullptr;
|
||||
size_t count = 0;
|
||||
|
||||
FfiError e(::crash_report_client_ls(handle_.get(), dir_path, &entries_raw, &count));
|
||||
if (e) {
|
||||
return Err(e);
|
||||
}
|
||||
|
||||
std::vector<std::string> result;
|
||||
if (entries_raw) {
|
||||
result.reserve(count);
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
if (entries_raw[i]) {
|
||||
result.emplace_back(entries_raw[i]);
|
||||
::idevice_string_free(entries_raw[i]);
|
||||
}
|
||||
}
|
||||
std::free(entries_raw);
|
||||
}
|
||||
|
||||
return Ok(std::move(result));
|
||||
}
|
||||
|
||||
Result<std::vector<char>, FfiError>
|
||||
CrashReportCopyMobile::pull(const std::string& log_name) {
|
||||
uint8_t* data = nullptr;
|
||||
size_t length = 0;
|
||||
|
||||
FfiError e(::crash_report_client_pull(handle_.get(), log_name.c_str(), &data, &length));
|
||||
if (e) {
|
||||
return Err(e);
|
||||
}
|
||||
|
||||
std::vector<char> result;
|
||||
if (data && length > 0) {
|
||||
result.assign(reinterpret_cast<char*>(data), reinterpret_cast<char*>(data) + length);
|
||||
::idevice_data_free(data, length);
|
||||
}
|
||||
|
||||
return Ok(std::move(result));
|
||||
}
|
||||
|
||||
Result<void, FfiError> CrashReportCopyMobile::remove(const std::string& log_name) {
|
||||
FfiError e(::crash_report_client_remove(handle_.get(), log_name.c_str()));
|
||||
if (e) {
|
||||
return Err(e);
|
||||
}
|
||||
return Ok();
|
||||
}
|
||||
|
||||
} // namespace IdeviceFFI
|
||||
Reference in New Issue
Block a user