1use super::{
21 align_to,
22 borrowed::BorrowedBytesBlockIterator,
23 error::Infallible,
24 padding::{PaddedBlock, TwoSidesPaddedInput},
25 Input, SliceSeekable as _, MAX_BLOCK_SIZE,
26};
27use crate::{result::InputRecorder, string_pattern::StringPattern};
28use std::borrow::Borrow;
29
30pub struct OwnedBytes<B> {
32 bytes: B,
33 middle_len: usize,
34 first_block: PaddedBlock,
35 last_block: PaddedBlock,
36}
37
38impl<B> OwnedBytes<B>
39where
40 B: Borrow<[u8]>,
41{
42 #[inline(always)]
47 pub fn new(bytes: B) -> Self {
48 let (first, middle, last) = align_to::<MAX_BLOCK_SIZE>(bytes.borrow());
49 let first_block = PaddedBlock::pad_first_block(first);
50 let last_block = PaddedBlock::pad_last_block(last);
51
52 Self {
53 middle_len: middle.len(),
54 bytes,
55 first_block,
56 last_block,
57 }
58 }
59}
60
61impl<B> From<B> for OwnedBytes<B>
62where
63 B: Borrow<[u8]>,
64{
65 #[inline(always)]
66 fn from(value: B) -> Self {
67 Self::new(value)
68 }
69}
70
71impl From<String> for OwnedBytes<Vec<u8>> {
72 #[inline(always)]
73 fn from(value: String) -> Self {
74 Self::new(value.into_bytes())
75 }
76}
77
78impl<B> Input for OwnedBytes<B>
79where
80 B: Borrow<[u8]>,
81{
82 type BlockIterator<'i, 'r, R, const N: usize>
83 = BorrowedBytesBlockIterator<'r, TwoSidesPaddedInput<'i>, R, N>
84 where
85 Self: 'i,
86 R: InputRecorder<Self::Block<'i, N>> + 'r;
87
88 type Error = Infallible;
89
90 type Block<'i, const N: usize>
91 = &'i [u8]
92 where
93 Self: 'i;
94
95 #[inline(always)]
96 fn leading_padding_len(&self) -> usize {
97 self.first_block.padding_len()
98 }
99
100 #[inline(always)]
101 fn trailing_padding_len(&self) -> usize {
102 self.last_block.padding_len()
103 }
104
105 #[inline]
106 fn iter_blocks<'i, 'r, R, const N: usize>(&'i self, recorder: &'r R) -> Self::BlockIterator<'i, 'r, R, N>
107 where
108 R: InputRecorder<Self::Block<'i, N>>,
109 {
110 let (_, middle, _) = align_to::<MAX_BLOCK_SIZE>(self.bytes.borrow());
111 assert_eq!(
112 middle.len(),
113 self.middle_len,
114 "it is impossible for alignment to change after construction"
115 );
116
117 let padded = TwoSidesPaddedInput::new(&self.first_block, middle, &self.last_block);
118
119 BorrowedBytesBlockIterator::new(padded, recorder)
120 }
121
122 #[inline]
123 fn seek_backward(&self, from: usize, needle: u8) -> Option<usize> {
124 let offset = self.leading_padding_len();
125 let from = from.checked_sub(offset)?;
126
127 self.bytes.borrow().seek_backward(from, needle).map(|x| x + offset)
128 }
129
130 #[inline]
131 fn seek_forward<const N: usize>(&self, from: usize, needles: [u8; N]) -> Result<Option<(usize, u8)>, Self::Error> {
132 let offset = self.leading_padding_len();
133 let from = from.saturating_sub(offset);
134
135 Ok(self
136 .bytes
137 .borrow()
138 .seek_forward(from, needles)
139 .map(|(x, y)| (x + self.leading_padding_len(), y)))
140 }
141
142 #[inline]
143 fn seek_non_whitespace_forward(&self, from: usize) -> Result<Option<(usize, u8)>, Self::Error> {
144 let offset = self.leading_padding_len();
145 let from = from.saturating_sub(offset);
146
147 Ok(self
148 .bytes
149 .borrow()
150 .seek_non_whitespace_forward(from)
151 .map(|(x, y)| (x + self.leading_padding_len(), y)))
152 }
153
154 #[inline]
155 fn seek_non_whitespace_backward(&self, from: usize) -> Option<(usize, u8)> {
156 let offset = self.leading_padding_len();
157 let from = from.checked_sub(offset)?;
158
159 self.bytes
160 .borrow()
161 .seek_non_whitespace_backward(from)
162 .map(|(x, y)| (x + self.leading_padding_len(), y))
163 }
164
165 #[inline]
166 fn is_member_match(&self, from: usize, to: usize, member: &StringPattern) -> Result<bool, Self::Error> {
167 let offset = self.leading_padding_len();
168 let Some(from) = from.checked_sub(offset) else {
169 return Ok(false);
170 };
171
172 Ok(self.bytes.borrow().is_member_match(from, to - offset, member))
173 }
174}