1use amplify_num::{u2, u3, u4, u5, u6, u7};
12use core::convert::TryInto;
13use core::fmt::{self, Debug, Display, Formatter};
14
15use super::{Read, Write};
16use crate::reg::{Reg, Value};
17
18#[derive(Clone, Copy, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Display)]
25#[display(doc_comments)]
26#[cfg_attr(feature = "std", derive(Error))]
27#[allow(clippy::branches_sharing_code)]
28pub enum CursorError {
29 Eof,
31
32 OutOfBoundaries(usize),
34}
35
36pub struct Cursor<T>
38where
39 T: AsRef<[u8]>,
40{
41 bytecode: T,
42 byte_pos: u16,
43 bit_pos: u3,
44 eof: bool,
45}
46
47impl<T> Debug for Cursor<T>
48where
49 T: AsRef<[u8]>,
50{
51 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
52 use bitcoin_hashes::hex::ToHex;
53 f.debug_struct("Cursor")
54 .field("bytecode", &self.bytecode.as_ref().to_hex())
55 .field("byte_pos", &self.byte_pos)
56 .field("bit_pos", &self.bit_pos)
57 .field("eof", &self.eof)
58 .finish()
59 }
60}
61
62impl<T> Display for Cursor<T>
63where
64 T: AsRef<[u8]>,
65{
66 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
67 use bitcoin_hashes::hex::ToHex;
68 write!(f, "{}:{} @ ", self.byte_pos, self.bit_pos)?;
69 let hex = self.bytecode.as_ref().to_hex();
70 if f.alternate() {
71 write!(f, "{}..{}", &hex[..4], &hex[hex.len() - 4..])
72 } else {
73 f.write_str(&hex)
74 }
75 }
76}
77
78impl<T> Cursor<T>
79where
80 T: AsRef<[u8]>,
81{
82 pub fn with(bytecode: T) -> Cursor<T> {
84 Cursor {
85 bytecode,
86 byte_pos: 0,
87 bit_pos: u3::MIN,
88 eof: false,
89 }
90 }
91
92 pub fn is_eof(&self) -> bool {
95 self.eof
96 }
97
98 pub fn pos(&self) -> u16 {
100 self.byte_pos
101 }
102
103 pub fn seek(&mut self, byte_pos: u16) {
105 self.byte_pos = byte_pos;
106 }
107
108 fn extract(&mut self, bit_count: u3) -> Result<u8, CursorError> {
109 if self.eof {
110 return Err(CursorError::Eof);
111 }
112 let byte = self.bytecode.as_ref()[self.byte_pos as usize];
113 let mut mask = 0x00u8;
114 let mut cnt = bit_count.as_u8();
115 while cnt > 0 {
116 mask <<= 1;
117 mask |= 0x01;
118 cnt -= 1;
119 }
120 mask <<= self.bit_pos.as_u8();
121 let val = (byte & mask) >> self.bit_pos.as_u8();
122 self.inc_bits(bit_count).map(|_| val)
123 }
124
125 fn inc_bits(&mut self, bit_count: u3) -> Result<(), CursorError> {
126 if self.eof {
127 return Err(CursorError::Eof);
128 }
129 let pos = self.bit_pos.as_u8() + bit_count.as_u8();
130 self.bit_pos = u3::with(pos % 8);
131 self._inc_bytes_inner(pos as u16 / 8)
132 }
133
134 fn inc_bytes(&mut self, byte_count: u16) -> Result<(), CursorError> {
135 assert_eq!(
136 self.bit_pos.as_u8(),
137 0,
138 "attempt to access (multiple) bytes at a non-byte aligned position"
139 );
140 if self.eof {
141 return Err(CursorError::Eof);
142 }
143 self._inc_bytes_inner(byte_count)
144 }
145
146 fn _inc_bytes_inner(&mut self, byte_count: u16) -> Result<(), CursorError> {
147 if byte_count == 1 && self.byte_pos == u16::MAX {
148 self.eof = true
149 } else {
150 self.byte_pos =
151 self.byte_pos
152 .checked_add(byte_count)
153 .ok_or(CursorError::OutOfBoundaries(
154 self.byte_pos as usize + byte_count as usize,
155 ))?;
156 }
157 Ok(())
158 }
159}
160
161impl Read for Cursor<&[u8]> {
162 type Error = CursorError;
163
164 fn is_end(&self) -> bool {
165 self.byte_pos as usize >= self.bytecode.len()
166 }
167
168 fn peek_u8(&self) -> Result<u8, CursorError> {
169 if self.eof {
170 return Err(CursorError::Eof);
171 }
172 Ok(self.bytecode[self.byte_pos as usize])
173 }
174
175 fn read_bool(&mut self) -> Result<bool, CursorError> {
176 if self.eof {
177 return Err(CursorError::Eof);
178 }
179 let byte = self.extract(u3::with(1))?;
180 Ok(byte == 0x01)
181 }
182
183 fn read_u2(&mut self) -> Result<u2, CursorError> {
184 Ok(self
185 .extract(u3::with(2))?
186 .try_into()
187 .expect("bit extractor failure"))
188 }
189
190 fn read_u3(&mut self) -> Result<u3, CursorError> {
191 Ok(self
192 .extract(u3::with(3))?
193 .try_into()
194 .expect("bit extractor failure"))
195 }
196
197 fn read_u4(&mut self) -> Result<u4, CursorError> {
198 Ok(self
199 .extract(u3::with(4))?
200 .try_into()
201 .expect("bit extractor failure"))
202 }
203
204 fn read_u5(&mut self) -> Result<u5, CursorError> {
205 Ok(self
206 .extract(u3::with(5))?
207 .try_into()
208 .expect("bit extractor failure"))
209 }
210
211 fn read_u6(&mut self) -> Result<u6, CursorError> {
212 Ok(self
213 .extract(u3::with(6))?
214 .try_into()
215 .expect("bit extractor failure"))
216 }
217
218 fn read_u7(&mut self) -> Result<u7, CursorError> {
219 Ok(self
220 .extract(u3::with(7))?
221 .try_into()
222 .expect("bit extractor failure"))
223 }
224
225 fn read_u8(&mut self) -> Result<u8, CursorError> {
226 if self.eof {
227 return Err(CursorError::Eof);
228 }
229 let byte = self.bytecode[self.byte_pos as usize];
230 self.inc_bytes(1).map(|_| byte)
231 }
232
233 fn read_u16(&mut self) -> Result<u16, CursorError> {
234 if self.eof {
235 return Err(CursorError::Eof);
236 }
237 let pos = self.byte_pos as usize;
238 let mut buf = [0u8; 2];
239 buf.copy_from_slice(&self.bytecode[pos..pos + 2]);
240 let word = u16::from_le_bytes(buf);
241 self.inc_bytes(2).map(|_| word)
242 }
243
244 fn read_bytes32(&mut self) -> Result<[u8; 32], CursorError> {
245 if self.eof {
246 return Err(CursorError::Eof);
247 }
248 let pos = self.byte_pos as usize;
249 let mut buf = [0u8; 32];
250 buf.copy_from_slice(&self.bytecode[pos..pos + 32]);
251 self.inc_bytes(32).map(|_| buf)
252 }
253
254 fn read_slice(&mut self) -> Result<&[u8], CursorError> {
255 if self.eof {
256 return Err(CursorError::Eof);
257 }
258 let len = self.read_u16()? as usize;
259 let pos = self.byte_pos as usize;
260 self.inc_bytes(2u16 + len as u16)
261 .map(|_| &self.bytecode[pos..pos + len])
262 }
263
264 fn read_value(&mut self, reg: Reg) -> Result<Value, CursorError> {
265 if self.eof {
266 return Err(CursorError::Eof);
267 }
268 let len = match reg.bits() {
269 Some(bits) => bits / 8,
270 None => self.read_u16()?,
271 } as usize;
272 let pos = self.byte_pos as usize;
273 let value = Value::with(&self.bytecode[pos..pos + len]);
274 self.inc_bytes(len as u16).map(|_| value)
275 }
276}
277
278impl Write for Cursor<&mut [u8]> {
279 type Error = CursorError;
280
281 fn write_bool(&mut self, data: bool) -> Result<(), CursorError> {
282 let data = if data { 1u8 } else { 0u8 } << self.bit_pos.as_u8();
283 self.bytecode[self.byte_pos as usize] |= data;
284 self.inc_bits(u3::with(1))
285 }
286
287 fn write_u2(&mut self, data: impl Into<u2>) -> Result<(), CursorError> {
288 let data = data.into().as_u8() << self.bit_pos.as_u8();
289 self.bytecode[self.byte_pos as usize] |= data;
290 self.inc_bits(u3::with(2))
291 }
292
293 fn write_u3(&mut self, data: impl Into<u3>) -> Result<(), CursorError> {
294 let data = data.into().as_u8() << self.bit_pos.as_u8();
295 self.bytecode[self.byte_pos as usize] |= data;
296 self.inc_bits(u3::with(3))
297 }
298
299 fn write_u4(&mut self, data: impl Into<u4>) -> Result<(), CursorError> {
300 let data = data.into().as_u8() << self.bit_pos.as_u8();
301 self.bytecode[self.byte_pos as usize] |= data;
302 self.inc_bits(u3::with(4))
303 }
304
305 fn write_u5(&mut self, data: impl Into<u5>) -> Result<(), CursorError> {
306 let data = data.into().as_u8() << self.bit_pos.as_u8();
307 self.bytecode[self.byte_pos as usize] |= data;
308 self.inc_bits(u3::with(5))
309 }
310
311 fn write_u6(&mut self, data: impl Into<u6>) -> Result<(), CursorError> {
312 let data = data.into().as_u8() << self.bit_pos.as_u8();
313 self.bytecode[self.byte_pos as usize] |= data;
314 self.inc_bits(u3::with(6))
315 }
316
317 fn write_u7(&mut self, data: impl Into<u7>) -> Result<(), CursorError> {
318 let data = data.into().as_u8() << self.bit_pos.as_u8();
319 self.bytecode[self.byte_pos as usize] |= data;
320 self.inc_bits(u3::with(7))
321 }
322
323 fn write_u8(&mut self, data: impl Into<u8>) -> Result<(), CursorError> {
324 self.bytecode[self.byte_pos as usize] = data.into();
325 self.inc_bytes(1)
326 }
327
328 fn write_u16(&mut self, data: impl Into<u16>) -> Result<(), CursorError> {
329 let data = data.into().to_le_bytes();
330 self.bytecode[self.byte_pos as usize] = data[0];
331 self.bytecode[self.byte_pos as usize + 1] = data[1];
332 self.inc_bytes(2)
333 }
334
335 fn write_bytes32(&mut self, data: [u8; 32]) -> Result<(), CursorError> {
336 let from = self.byte_pos as usize;
337 let to = from + 32;
338 self.bytecode[from..to].copy_from_slice(&data);
339 self.inc_bytes(32)
340 }
341
342 fn write_slice(&mut self, bytes: impl AsRef<[u8]>) -> Result<(), CursorError> {
343 let len = bytes.as_ref().len();
347 if len >= u16::MAX as usize {
348 return Err(CursorError::OutOfBoundaries(len));
349 }
350 self.write_u16(len as u16)?;
351 let from = self.byte_pos as usize;
352 let to = from + len;
353 self.bytecode[from..to].copy_from_slice(bytes.as_ref());
354 self.inc_bytes(2u16 + len as u16)
355 }
356
357 fn write_value(&mut self, reg: Reg, value: &Value) -> Result<(), CursorError> {
358 let len = match reg.bits() {
359 Some(bits) => bits / 8,
360 None => {
361 self.write_u16(value.len)?;
362 value.len
363 }
364 };
365 assert!(
366 len >= value.len,
367 "value for the register has larger bit length than the register"
368 );
369 let value_len = value.len as usize;
370 let from = self.byte_pos as usize;
371 let to = from + value_len;
372 self.bytecode[from..to].copy_from_slice(&value.bytes[0..value_len]);
373 self.inc_bytes(len as u16)
374 }
375}