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

@@ -40,8 +40,10 @@ class RsdHandshake {
~RsdHandshake() noexcept = default; ~RsdHandshake() noexcept = default;
RsdHandshake(RsdHandshake&&) noexcept = default; RsdHandshake(RsdHandshake&&) noexcept = default;
RsdHandshake& operator=(RsdHandshake&&) noexcept = default; RsdHandshake& operator=(RsdHandshake&&) noexcept = default;
RsdHandshake(const RsdHandshake&) = delete;
RsdHandshake& operator=(const RsdHandshake&) = delete; // Enable Copying
RsdHandshake(const RsdHandshake& other);
RsdHandshake& operator=(const RsdHandshake& other);
RsdHandshakeHandle* raw() const noexcept { return handle_.get(); } RsdHandshakeHandle* raw() const noexcept { return handle_.get(); }
static RsdHandshake adopt(RsdHandshakeHandle* h) noexcept { return RsdHandshake(h); } 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; 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 ---------- // ---------- factory ----------
std::optional<RsdHandshake> RsdHandshake::from_socket(ReadWrite&& rw, FfiError& err) { std::optional<RsdHandshake> RsdHandshake::from_socket(ReadWrite&& rw, FfiError& err) {
RsdHandshakeHandle* out = nullptr; RsdHandshakeHandle* out = nullptr;

View File

@@ -10,6 +10,7 @@ use idevice::rsd::RsdHandshake;
use crate::{IdeviceFfiError, RUNTIME, ReadWriteOpaque, ffi_err}; use crate::{IdeviceFfiError, RUNTIME, ReadWriteOpaque, ffi_err};
/// Opaque handle to an RsdHandshake /// Opaque handle to an RsdHandshake
#[derive(Clone)]
pub struct RsdHandshakeHandle(pub RsdHandshake); pub struct RsdHandshakeHandle(pub RsdHandshake);
/// C-compatible representation of an RSD service /// C-compatible representation of an RSD service
@@ -370,6 +371,22 @@ pub unsafe extern "C" fn rsd_get_service_info(
null_mut() 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 /// Frees a string returned by RSD functions
/// ///
/// # Arguments /// # Arguments

View File

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