Implement clone for RsdHandshake

This commit is contained in:
Jackson Coxson
2025-08-20 18:27:38 -06:00
parent b772a2eeae
commit 6d90879096
4 changed files with 43 additions and 5 deletions

View File

@@ -37,11 +37,13 @@ class RsdHandshake {
std::optional<RsdService> service_info(const std::string& name, FfiError& err) const;
// RAII / moves
~RsdHandshake() noexcept = default;
RsdHandshake(RsdHandshake&&) noexcept = default;
RsdHandshake& operator=(RsdHandshake&&) noexcept = default;
RsdHandshake(const RsdHandshake&) = delete;
RsdHandshake& operator=(const RsdHandshake&) = delete;
~RsdHandshake() noexcept = default;
RsdHandshake(RsdHandshake&&) noexcept = default;
RsdHandshake& operator=(RsdHandshake&&) noexcept = default;
// Enable Copying
RsdHandshake(const RsdHandshake& other);
RsdHandshake& operator=(const RsdHandshake& other);
RsdHandshakeHandle* raw() const noexcept { return handle_.get(); }
static RsdHandshake adopt(RsdHandshakeHandle* h) noexcept { return RsdHandshake(h); }

View File

@@ -61,6 +61,24 @@ static std::vector<RsdService> to_cpp_and_free(CRsdServiceArray* arr) {
return out;
}
RsdHandshake::RsdHandshake(const RsdHandshake& other) {
if (other.handle_) {
// Call the Rust FFI to clone the underlying handle
handle_.reset(rsd_handshake_clone(other.handle_.get()));
}
// If other.handle_ is null, our new handle_ will also be null, which is correct.
}
RsdHandshake& RsdHandshake::operator=(const RsdHandshake& other) {
// Check for self-assignment
if (this != &other) {
// Create a temporary copy, then swap ownership
RsdHandshake temp(other);
std::swap(handle_, temp.handle_);
}
return *this;
}
// ---------- factory ----------
std::optional<RsdHandshake> RsdHandshake::from_socket(ReadWrite&& rw, FfiError& err) {
RsdHandshakeHandle* out = nullptr;

View File

@@ -10,6 +10,7 @@ use idevice::rsd::RsdHandshake;
use crate::{IdeviceFfiError, RUNTIME, ReadWriteOpaque, ffi_err};
/// Opaque handle to an RsdHandshake
#[derive(Clone)]
pub struct RsdHandshakeHandle(pub RsdHandshake);
/// C-compatible representation of an RSD service
@@ -370,6 +371,22 @@ pub unsafe extern "C" fn rsd_get_service_info(
null_mut()
}
/// Clones an RSD handshake
///
/// # Safety
/// Pass a valid pointer allocated by this library
#[unsafe(no_mangle)]
pub unsafe extern "C" fn rsd_handshake_clone(
handshake: *mut RsdHandshakeHandle,
) -> *mut RsdHandshakeHandle {
if handshake.is_null() {
return null_mut();
}
let handshake = unsafe { &mut *handshake };
let new_handshake = handshake.clone();
Box::into_raw(Box::new(new_handshake))
}
/// Frees a string returned by RSD functions
///
/// # Arguments

View File

@@ -23,6 +23,7 @@ pub struct RsdService {
pub service_version: Option<i64>,
}
#[derive(Debug, Clone)]
pub struct RsdHandshake {
pub services: HashMap<String, RsdService>,
pub protocol_version: usize,