| 100 | /// If `read_len` is bigger than block size. |
| 101 | #[inline(always)] |
| 102 | pub fn write_block( |
| 103 | &mut self, |
| 104 | read_len: usize, |
| 105 | gen_block: impl FnOnce(&mut Array<u8, BS>), |
| 106 | read_fn: impl FnOnce(&[u8]), |
| 107 | ) { |
| 108 | if read_len == 0 { |
| 109 | return; |
| 110 | } |
| 111 | assert!(read_len < BS::USIZE); |
| 112 | |
| 113 | let g = ResetGuard(self); |
| 114 | let buf = &mut g.0.buffer; |
| 115 | |
| 116 | // Note that generated block is likely to break the `ReadBuffer` invariant. |
| 117 | // We restore it using `set_pos_unchecked` below and in case if one of the closures |
| 118 | // panic the buffer gets reset by the guard. |
| 119 | gen_block(buf); |
| 120 | read_fn(&buf[..read_len]); |
| 121 | |
| 122 | core::mem::forget(g); |
| 123 | |
| 124 | // We checked that `read_len` satisfies the `set_pos_unchecked` safety contract |
| 125 | unsafe { self.set_pos_unchecked(read_len) }; |
| 126 | } |
| 127 | |
| 128 | /// Reset buffer into exhausted state. |
| 129 | pub fn reset(&mut self) { |