The following code produces the desired results. However, I've heard that some types of unsafe code, in the future, may be optimized-away and no longer produce the desired results. As such, I'd like to convert the following code from unsafe to safe (with the exception of the set_len function):
fn scramble_next_group(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Option<GroupSender>> {
//println!("[G{}] {} / {}", self.groups_rendered, self.read_cursor, self.file_len);
let ptr = &mut *self as *mut Self;
if self.read_cursor != self.file_len {
//log::info!("Polling to create group {}", self.groups_rendered);
let pqc = AssertSendSyncSafe::wrap(self.pqc.clone());
let pqc = pqc.for_ref();
let fx = unsafe { &(*ptr).header_inscriber };
let this = &mut *self;
let remaining = this.file_len - this.read_cursor;
let poll_amt = std::cmp::min(remaining, MAX_BYTES_PER_GROUP);
unsafe { this.buffer.set_len(poll_amt) };
let bytes = unsafe { &mut (*ptr).buffer[..poll_amt] };
if let Ok(_) = this.reader.read_exact(bytes) {
let group_id_input = this.group_id + (this.groups_rendered as u64);
if let Ok(sender) = par_scramble_encrypt_group(bytes, this.security_level, &this.drill, pqc, this.header_size_bytes, this.target_cid, this.object_id, group_id_input, |a, b, c, d, e| {
(fx)(a, b, c, d, e)
}) {
this.groups_rendered += 1;
this.read_cursor += poll_amt;
Poll::Ready(Some(sender))
} else {
println!("Error parallel scrambling file");
Poll::Ready(None)
}
} else {
println!("Error polling exact amt {}", poll_amt);
Poll::Ready(None)
}
} else {
println!("Done rendering all groups!");
Poll::Ready(None)
}
}
I need to use a pointer because I mix mutable and immutable borrows in the same closure. I need to pass a mutable reference of buffer
into the read_exact function, and thereafter, process its bytes in par_scramble_encrypt_group
. Further, a function labelled fx
needs to be immutably borrowed for the par_scramble_encrypt_group
.