have: usize, // number of bytes logically written to the window. this can be higher than // buf.len() if we run out of space in the window
next: usize, // write head
}
pubfn size(&self) -> usize { ifself.buf.is_empty() { // an empty `buf` is used when the window has not yet been allocated, // or when it has been deallocated. 0
} else { self.buf.len() - Self::padding()
}
}
/// number of bytes in the window. Saturates at `Self::capacity`. pubfn have(&self) -> usize { self.have
}
/// Position where the next byte will be written pubfn next(&self) -> usize { self.next
}
pubfn as_slice(&self) -> &[u8] { // safety: the slice is always from the initialized part of buf unsafe { slice_assume_init(&self.buf[..self.have]) }
}
pubfn extend(
&mutself,
slice: &[u8],
flags: i32,
update_checksum: bool,
checksum: &mut u32,
crc_fold: &mut Crc32Fold,
) { let len = slice.len(); let wsize = self.size();
if len >= wsize { // We have to split the checksum over non-copied and copied bytes let pos = len.saturating_sub(self.size()); let (non_window_slice, window_slice) = slice.split_at(pos);
// the end part goes onto the end of the window. The start part wraps around and is // written to the start of the window. let (end_part, start_part) = slice.split_at(dist);
if update_checksum { let dst = &mutself.buf[self.next..][..end_part.len()]; if flags != 0 {
crc_fold.fold_copy(dst, end_part);
} else {
*checksum = adler32_fold_copy(*checksum, dst, end_part);
}
} else { let end_part = unsafe { slice_to_uninit(end_part) }; self.buf[self.next..][..end_part.len()].copy_from_slice(end_part);
}
if !start_part.is_empty() { if update_checksum { let dst = &mutself.buf[..start_part.len()]; if flags != 0 {
crc_fold.fold_copy(dst, start_part);
} else {
*checksum = adler32_fold_copy(*checksum, dst, start_part);
}
} else { let start_part = unsafe { slice_to_uninit(start_part) }; self.buf[..start_part.len()].copy_from_slice(start_part);
}
// padding required so that SIMD operations going out-of-bounds are not a problem pubfn padding() -> usize { 64// very conservative
}
}
unsafefn slice_to_uninit(slice: &[u8]) -> &[MaybeUninit<u8>] {
&*(slice as *const [u8] as *const [MaybeUninit<u8>])
}
// TODO: This could use `MaybeUninit::slice_assume_init` when it is stable. unsafefn slice_assume_init(slice: &[MaybeUninit<u8>]) -> &[u8] {
&*(slice as *const [MaybeUninit<u8>] as *const [u8])
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.