1use crate::check::Check;
8use crate::error::{Error, Result};
9
10#[derive(Debug, Clone)]
12pub struct Reader<'a> {
13 buf: &'a [u8],
14 pos: usize,
15 check: Check,
16}
17
18impl<'a> Reader<'a> {
19 pub fn new(buf: &'a [u8]) -> Self {
23 Reader {
24 buf,
25 pos: 0,
26 check: Check::DirChunkExtent,
27 }
28 }
29
30 pub fn checked(buf: &'a [u8], check: Check) -> Self {
32 Reader { buf, pos: 0, check }
33 }
34
35 pub fn with_check(mut self, check: Check) -> Self {
37 self.check = check;
38 self
39 }
40
41 pub fn check(&self) -> Check {
43 self.check
44 }
45
46 pub fn pos(&self) -> usize {
48 self.pos
49 }
50
51 pub fn remaining(&self) -> usize {
53 self.buf.len() - self.pos
54 }
55
56 pub fn is_empty(&self) -> bool {
58 self.pos == self.buf.len()
59 }
60
61 pub fn buffer(&self) -> &'a [u8] {
63 self.buf
64 }
65
66 pub fn tail(&self) -> &'a [u8] {
68 &self.buf[self.pos..]
69 }
70
71 fn truncate(&self, want: usize) -> Result<()> {
72 if self.remaining() < want {
73 return Err(Error::new(
74 self.check,
75 format!(
76 "truncated: need {want} byte(s) at offset {}, {} remaining",
77 self.pos,
78 self.remaining()
79 ),
80 ));
81 }
82 Ok(())
83 }
84
85 pub fn u8(&mut self) -> Result<u8> {
87 self.truncate(1)?;
88 let v = self.buf[self.pos];
89 self.pos += 1;
90 Ok(v)
91 }
92
93 pub fn u16(&mut self) -> Result<u16> {
95 Ok(u16::from_le_bytes(self.array::<2>()?))
96 }
97
98 pub fn u32(&mut self) -> Result<u32> {
100 Ok(u32::from_le_bytes(self.array::<4>()?))
101 }
102
103 pub fn u64(&mut self) -> Result<u64> {
105 Ok(u64::from_le_bytes(self.array::<8>()?))
106 }
107
108 pub fn array<const N: usize>(&mut self) -> Result<[u8; N]> {
110 self.truncate(N)?;
111 let mut out = [0u8; N];
112 out.copy_from_slice(&self.buf[self.pos..self.pos + N]);
113 self.pos += N;
114 Ok(out)
115 }
116
117 pub fn bytes(&mut self, n: usize) -> Result<&'a [u8]> {
119 self.truncate(n)?;
120 let out = &self.buf[self.pos..self.pos + n];
121 self.pos += n;
122 Ok(out)
123 }
124
125 pub fn rest(&mut self) -> &'a [u8] {
127 let out = &self.buf[self.pos..];
128 self.pos = self.buf.len();
129 out
130 }
131
132 pub fn skip(&mut self, n: usize) -> Result<()> {
134 self.truncate(n)?;
135 self.pos += n;
136 Ok(())
137 }
138
139 pub fn varint(&mut self) -> Result<u64> {
141 crate::varint::decode(self)
142 }
143
144 pub fn varint_bounded(&mut self, max: u64) -> Result<u64> {
146 let v = self.varint()?;
147 if v > max {
148 return Err(Error::new(
149 self.check,
150 format!("varint value {v} exceeds the bound {max}"),
151 ));
152 }
153 Ok(v)
154 }
155
156 pub fn utf8(&mut self, n: usize) -> Result<&'a str> {
158 let bytes = self.bytes(n)?;
159 core::str::from_utf8(bytes).map_err(|e| {
160 Error::new(
161 self.check,
162 format!("invalid UTF-8 at offset {}: {e}", self.pos - n),
163 )
164 })
165 }
166}
167
168#[derive(Debug, Default, Clone)]
170pub struct Writer {
171 buf: Vec<u8>,
172}
173
174impl Writer {
175 pub fn new() -> Self {
177 Writer { buf: Vec::new() }
178 }
179
180 pub fn with_capacity(capacity: usize) -> Self {
182 Writer {
183 buf: Vec::with_capacity(capacity),
184 }
185 }
186
187 pub fn len(&self) -> usize {
189 self.buf.len()
190 }
191
192 pub fn is_empty(&self) -> bool {
194 self.buf.is_empty()
195 }
196
197 pub fn as_slice(&self) -> &[u8] {
199 &self.buf
200 }
201
202 pub fn into_vec(self) -> Vec<u8> {
204 self.buf
205 }
206
207 pub fn u8(&mut self, v: u8) {
209 self.buf.push(v);
210 }
211
212 pub fn u16(&mut self, v: u16) {
214 self.buf.extend_from_slice(&v.to_le_bytes());
215 }
216
217 pub fn u32(&mut self, v: u32) {
219 self.buf.extend_from_slice(&v.to_le_bytes());
220 }
221
222 pub fn u64(&mut self, v: u64) {
224 self.buf.extend_from_slice(&v.to_le_bytes());
225 }
226
227 pub fn bytes(&mut self, v: &[u8]) {
229 self.buf.extend_from_slice(v);
230 }
231
232 pub fn varint(&mut self, v: u64) {
234 crate::varint::encode(self, v);
235 }
236
237 pub fn pad_to(&mut self, align: usize) {
239 debug_assert!(align.is_power_of_two());
240 while self.buf.len() % align != 0 {
241 self.buf.push(0);
242 }
243 }
244
245 pub fn patch_u32(&mut self, at: usize, v: u32) {
249 self.buf[at..at + 4].copy_from_slice(&v.to_le_bytes());
250 }
251
252 pub fn patch_u64(&mut self, at: usize, v: u64) {
254 self.buf[at..at + 8].copy_from_slice(&v.to_le_bytes());
255 }
256
257 pub fn patch_bytes(&mut self, at: usize, v: &[u8]) {
259 self.buf[at..at + v.len()].copy_from_slice(v);
260 }
261}