fixed_bigint/heapless/
bytes.rs1use super::HeaplessBigInt;
17use crate::MachineWord;
18use crate::fixeduint::{impl_from_be_bytes_slice, impl_from_le_bytes_slice};
19use const_num_traits::{ByteSliceError, ByteSliceErrorKind, FromByteSlice, Personality};
20use core::marker::PhantomData;
21
22impl<T: MachineWord, const CAP: usize, P: Personality> HeaplessBigInt<T, CAP, P> {
23 pub fn to_be_bytes<'a>(&self, out: &'a mut [u8]) -> &'a [u8] {
27 let word_size = core::mem::size_of::<T>();
28 let byte_count = self.len as usize * word_size;
29 assert!(
30 out.len() >= byte_count,
31 "HeaplessBigInt::to_be_bytes: out.len() < required ({byte_count} bytes)"
32 );
33 let mut dst = out[..byte_count].iter_mut();
37 for word in self.limbs[..self.len as usize].iter().rev() {
38 let word_bytes = word.to_be_bytes();
39 for (&src, slot) in word_bytes.as_ref().iter().zip(dst.by_ref()) {
40 *slot = src;
41 }
42 }
43 &out[..byte_count]
44 }
45
46 pub fn to_le_bytes<'a>(&self, out: &'a mut [u8]) -> &'a [u8] {
49 let word_size = core::mem::size_of::<T>();
50 let byte_count = self.len as usize * word_size;
51 assert!(
52 out.len() >= byte_count,
53 "HeaplessBigInt::to_le_bytes: out.len() < required ({byte_count} bytes)"
54 );
55 let mut dst = out[..byte_count].iter_mut();
57 for word in self.limbs[..self.len as usize].iter() {
58 let word_bytes = word.to_le_bytes();
59 for (&src, slot) in word_bytes.as_ref().iter().zip(dst.by_ref()) {
60 *slot = src;
61 }
62 }
63 &out[..byte_count]
64 }
65
66 pub fn from_be_bytes(bytes: &[u8]) -> Self {
72 let word_size = core::mem::size_of::<T>();
73 let max_bytes = CAP * word_size;
74 assert!(
75 bytes.len() <= max_bytes,
76 "HeaplessBigInt::from_be_bytes: input {} bytes > CAP * word_size ({max_bytes})",
77 bytes.len()
78 );
79 let out_len = bytes.len().div_ceil(word_size);
80 Self {
83 limbs: impl_from_be_bytes_slice::<T, CAP>(bytes),
84 len: out_len as u16,
85 _p: PhantomData,
86 }
87 }
88
89 pub fn from_le_bytes(bytes: &[u8]) -> Self {
92 let word_size = core::mem::size_of::<T>();
93 let max_bytes = CAP * word_size;
94 assert!(
95 bytes.len() <= max_bytes,
96 "HeaplessBigInt::from_le_bytes: input {} bytes > CAP * word_size ({max_bytes})",
97 bytes.len()
98 );
99 let out_len = bytes.len().div_ceil(word_size);
100 Self {
101 limbs: impl_from_le_bytes_slice::<T, CAP>(bytes),
102 len: out_len as u16,
103 _p: PhantomData,
104 }
105 }
106}
107
108impl<T: MachineWord, const CAP: usize, P: Personality> HeaplessBigInt<T, CAP, P> {
116 #[inline]
117 fn check_slice_len(len: usize) -> Result<(), ByteSliceError> {
118 if len == 0 {
119 return Err(ByteSliceError {
120 kind: ByteSliceErrorKind::Empty,
121 });
122 }
123 if len > CAP * core::mem::size_of::<T>() {
124 return Err(ByteSliceError {
125 kind: ByteSliceErrorKind::Overflow,
126 });
127 }
128 Ok(())
129 }
130}
131
132impl<T: MachineWord, const CAP: usize, P: Personality> FromByteSlice for HeaplessBigInt<T, CAP, P> {
133 fn from_be_slice(bytes: &[u8]) -> Result<Self, ByteSliceError> {
134 Self::check_slice_len(bytes.len())?;
135 Ok(Self::from_be_bytes(bytes))
136 }
137
138 fn from_le_slice(bytes: &[u8]) -> Result<Self, ByteSliceError> {
139 Self::check_slice_len(bytes.len())?;
140 Ok(Self::from_le_bytes(bytes))
141 }
142}