ring/aead/overlapping/
base.rs1pub use self::index_error::IndexError;
16use super::Array;
17use crate::error::LenMismatchError;
18use core::{mem, ops::RangeFrom};
19
20pub struct Overlapping<'o, T> {
21 in_out: &'o mut [T],
23 src: RangeFrom<usize>,
24}
25
26impl<'o, T> From<&'o mut [T]> for Overlapping<'o, T> {
27 fn from(in_out: &'o mut [T]) -> Self {
28 Self { in_out, src: 0.. }
29 }
30}
31
32impl<'o, T> Overlapping<'o, T> {
33 pub fn new(in_out: &'o mut [T], src: RangeFrom<usize>) -> Result<Self, IndexError> {
34 match in_out.get(src.clone()) {
35 Some(_) => Ok(Self { in_out, src }),
36 None => Err(IndexError::new(src.start)),
37 }
38 }
39
40 #[cfg(any(
41 all(target_arch = "arm", target_endian = "little"),
42 target_arch = "x86"
43 ))]
44 pub fn copy_within(self) -> &'o mut [T]
45 where
46 T: Copy,
47 {
48 if self.src.start == 0 {
49 self.in_out
50 } else {
51 let len = self.len();
52 self.in_out.copy_within(self.src, 0);
53 &mut self.in_out[..len]
54 }
55 }
56
57 #[cfg(any(
58 all(target_arch = "arm", target_endian = "little"),
59 target_arch = "x86"
60 ))]
61 pub fn into_slice_src_mut(self) -> (&'o mut [T], RangeFrom<usize>) {
62 (self.in_out, self.src)
63 }
64
65 pub fn into_unwritten_output(self) -> &'o mut [T] {
66 let len = self.len();
67 self.in_out.get_mut(..len).unwrap_or_else(|| {
68 unreachable!()
70 })
71 }
72}
73
74impl<T> Overlapping<'_, T> {
75 pub fn len(&self) -> usize {
76 self.input().len()
77 }
78
79 pub fn input(&self) -> &[T] {
80 self.in_out.get(self.src.clone()).unwrap_or_else(|| {
81 unreachable!()
83 })
84 }
85
86 pub fn with_input_output_len<R>(self, f: impl FnOnce(*const T, *mut T, usize) -> R) -> R {
87 let len = self.len();
88 let output = self.in_out.as_mut_ptr();
89 let output_const: *const T = output;
91 let input = if self.src.start == 0 {
98 output_const
99 } else {
100 unsafe { output_const.add(self.src.start) }
101 };
102 f(input, output, len)
103 }
104
105 #[cfg_attr(not(test), allow(dead_code))]
112 pub fn split_first_chunk<const N: usize>(
113 mut self,
114 f: impl for<'a> FnOnce(Array<'a, T, N>),
115 ) -> Result<Self, IndexError> {
116 let src = self.src.clone();
117 let end = self
118 .src
119 .start
120 .checked_add(N)
121 .ok_or_else(|| IndexError::new(N))?;
122 let first = self
123 .in_out
124 .get_mut(..end)
125 .ok_or_else(|| IndexError::new(N))?;
126 let first = Overlapping::new(first, src).unwrap_or_else(|IndexError { .. }| {
127 unreachable!()
129 });
130 let first = Array::new(first).unwrap_or_else(|LenMismatchError { .. }| {
131 unreachable!()
133 });
134 Ok({
137 f(first);
138 let tail = mem::take(&mut self.in_out).get_mut(N..).unwrap_or_else(|| {
139 unreachable!()
141 });
142 Self::new(tail, self.src).unwrap_or_else(|IndexError { .. }| {
143 unreachable!()
145 })
146 })
147 }
148}
149
150cold_exhaustive_error! {
151 struct index_error::IndexError { index: usize }
152}