1use crate::{
7 InvalidIntegerLength, TryGetIntegerError, TryPutIntegerCheckedError, TryPutIntegerError,
8};
9
10use super::{Buffer, InlineSize, TryGetError, TryPutError, panic_advance, panic_does_not_fit};
11
12pub(crate) const fn sign_extend(val: u64, nbytes: usize) -> i64 {
14 if nbytes == 0 {
15 return 0;
16 }
17
18 let shift = (8 - nbytes) * 8;
19 (val << shift) as i64 >> shift
20}
21
22#[cold]
23fn panic_try_get_integer<T>(error: TryGetIntegerError) -> T {
24 match error {
25 TryGetIntegerError::NotEnoughBytes(error) => panic_advance(error.available, error.requested),
26 TryGetIntegerError::InvalidLength(error) => panic_does_not_fit(8, error.0),
27 }
28}
29
30pub(crate) fn checked_unsigned_range(
31 n: u64,
32 nbytes: usize,
33) -> Result<(), TryPutIntegerCheckedError> {
34 if nbytes > 8 {
35 return Err(InvalidIntegerLength(nbytes).into());
36 }
37
38 let max = if nbytes == 8 {
39 u64::MAX as i128
40 } else {
41 (1_i128 << (nbytes * 8)) - 1
42 };
43 let value = n as i128;
44 if value > max {
45 return Err(TryPutIntegerCheckedError::OutOfRange {
46 value,
47 min: 0,
48 max,
49 nbytes,
50 });
51 }
52
53 Ok(())
54}
55
56pub(crate) fn checked_signed_range(n: i64, nbytes: usize) -> Result<(), TryPutIntegerCheckedError> {
57 if nbytes > 8 {
58 return Err(InvalidIntegerLength(nbytes).into());
59 }
60
61 let (min, max) = if nbytes == 0 {
62 (0, 0)
63 } else {
64 let shift = nbytes * 8 - 1;
65 let limit = 1_i128 << shift;
66 (-limit, limit - 1)
67 };
68 let value = n as i128;
69 if value < min || value > max {
70 return Err(TryPutIntegerCheckedError::OutOfRange {
71 value,
72 min,
73 max,
74 nbytes,
75 });
76 }
77
78 Ok(())
79}
80
81macro_rules! impl_try_get {
82 ($this:ident, $typ:tt::$conv:tt) => {{
83 const SIZE: usize = core::mem::size_of::<$typ>();
84
85 let remaining = $this.remaining();
86
87 if remaining < SIZE {
88 return Err(TryGetError {
89 requested: SIZE,
90 available: remaining,
91 });
92 }
93
94 unsafe {
95 let ptr = $this.buf.as_ptr().add($this.cur.to_usize());
96 let val = $typ::$conv(*(ptr as *const _ as *const [_; SIZE]));
97
98 $this.cur = InlineSize::from_u8($this.cur.to_u8() + SIZE as u8);
99 Ok(val)
100 }
101 }};
102 (le($this:ident, $typ:tt, $len_to_read:expr)) => {{
103 const SIZE: usize = core::mem::size_of::<$typ>();
104
105 if $len_to_read > 8 {
106 return Err(TryGetIntegerError::InvalidLength(InvalidIntegerLength(
107 $len_to_read,
108 )));
109 }
110
111 let remaining = $this.remaining();
112 if remaining < $len_to_read {
113 return Err(TryGetIntegerError::NotEnoughBytes(TryGetError {
114 requested: $len_to_read,
115 available: remaining,
116 }));
117 }
118
119 let mut buf = [0u8; SIZE];
120
121 unsafe {
122 core::ptr::copy_nonoverlapping(
125 $this.buf.as_ptr().add($this.cur.to_usize()).cast::<u8>(),
126 buf.as_mut_ptr(),
127 $len_to_read,
128 );
129 let val = $typ::from_le_bytes(buf);
130
131 $this.cur = InlineSize::from_u8($this.cur.to_u8() + $len_to_read as u8);
132 Ok(val)
133 }
134 }};
135 (be($this:ident, $typ:tt, $len_to_read:expr)) => {{
136 const SIZE: usize = core::mem::size_of::<$typ>();
137
138 if $len_to_read > 8 {
139 return Err(TryGetIntegerError::InvalidLength(InvalidIntegerLength(
140 $len_to_read,
141 )));
142 }
143
144 let remaining = $this.remaining();
145 if remaining < $len_to_read {
146 return Err(TryGetIntegerError::NotEnoughBytes(TryGetError {
147 requested: $len_to_read,
148 available: remaining,
149 }));
150 }
151
152 let slice_at = SIZE - $len_to_read;
153 let mut buf = [0u8; SIZE];
154
155 unsafe {
156 core::ptr::copy_nonoverlapping(
159 $this.buf.as_ptr().add($this.cur.to_usize()).cast::<u8>(),
160 buf.as_mut_ptr().add(slice_at),
161 $len_to_read,
162 );
163 let val = $typ::from_be_bytes(buf);
164
165 $this.cur = InlineSize::from_u8($this.cur.to_u8() + $len_to_read as u8);
166 Ok(val)
167 }
168 }};
169}
170
171macro_rules! try_get_and_get {
172 ($long:literal: { $($typ:ident::$conv:ident$(::$order:ident)?),+$(,)? }) => {
173 paste::paste! {
174 $(
175 #[doc = "Gets a `" $typ "` from `self` in " $long " byte order."]
176 #[inline]
183 pub fn [<get_ $typ:lower $(_ $order)?>](&mut self) -> $typ {
184 self.[<try_get_ $typ:lower $(_ $order)?>]().unwrap_or_else(|e| panic_advance(e.available, e.requested))
185 }
186
187 #[doc = "Tries to get a `" $typ "` from `self` in " $long " byte order."]
188 #[inline]
195 pub const fn [<try_get_ $typ:lower $(_ $order)?>](&mut self) -> Result<$typ, TryGetError> {
196 impl_try_get!(self, $typ::$conv)
197 }
198 )*
199 }
200 };
201}
202
203macro_rules! try_put_and_put {
204 ($long:literal: { $($typ:ident::$conv:ident$(::$order:ident)?),+$(,)? }) => {
205 paste::paste! {
206 $(
207 #[doc = "Puts a `" $typ "` to `self` in " $long " byte order."]
208 #[inline]
215 pub fn [<put_ $typ:lower $(_ $order)?>](&mut self, val: $typ) {
216 self.[<try_put_ $typ:lower $(_ $order)?>](val)
217 .unwrap_or_else(|e| panic_advance(e.available, e.requested))
218 }
219
220 #[doc = "Tries to put a `" $typ "` to `self` in " $long " byte order."]
221 #[inline]
228 pub const fn [<try_put_ $typ:lower $(_ $order)?>](&mut self, val: $typ) -> Result<(), TryPutError> {
229 self.try_put_slice(val.$conv().as_slice())
230 }
231 )*
232 }
233 };
234}
235
236impl Buffer {
237 try_get_and_get!(
238 "little-endian": {
239 u16::from_le_bytes::le,
240 i16::from_le_bytes::le,
241 u32::from_le_bytes::le,
242 i32::from_le_bytes::le,
243 u64::from_le_bytes::le,
244 i64::from_le_bytes::le,
245 u128::from_le_bytes::le,
246 i128::from_le_bytes::le,
247 }
248 );
249
250 try_get_and_get!(
251 "big-endian": {
252 u16::from_be_bytes,
253 i16::from_be_bytes,
254 u32::from_be_bytes,
255 i32::from_be_bytes,
256 u64::from_be_bytes,
257 i64::from_be_bytes,
258 u128::from_be_bytes,
259 i128::from_be_bytes,
260 }
261 );
262
263 try_get_and_get!(
264 "native-endian": {
265 u16::from_ne_bytes::ne,
266 i16::from_ne_bytes::ne,
267 u32::from_ne_bytes::ne,
268 i32::from_ne_bytes::ne,
269 u64::from_ne_bytes::ne,
270 i64::from_ne_bytes::ne,
271 u128::from_ne_bytes::ne,
272 i128::from_ne_bytes::ne,
273 }
274 );
275
276 #[inline]
294 pub fn get_u8(&mut self) -> u8 {
295 match self.try_get_u8() {
296 Ok(v) => v,
297 Err(e) => panic_advance(e.available, e.requested),
298 }
299 }
300
301 #[inline]
319 pub const fn try_get_u8(&mut self) -> Result<u8, TryGetError> {
320 if self.remaining() < 1 {
321 return Err(TryGetError {
322 requested: 1,
323 available: self.remaining(),
324 });
325 }
326
327 let ret = unsafe { self.buf[self.cur.to_usize()].assume_init_read() };
329 self.cur = unsafe { InlineSize::from_u8(self.cur.to_u8() + 1) };
330 Ok(ret)
331 }
332
333 #[inline]
341 pub fn get_i8(&mut self) -> i8 {
342 Self::get_u8(self) as i8
343 }
344
345 #[inline]
353 pub const fn try_get_i8(&mut self) -> Result<i8, TryGetError> {
354 match Self::try_get_u8(self) {
355 Ok(v) => Ok(v as i8),
356 Err(e) => Err(e),
357 }
358 }
359
360 #[inline]
378 pub fn get_f32(&mut self) -> f32 {
379 f32::from_bits(self.get_u32())
380 }
381
382 #[inline]
391 pub const fn try_get_f32(&mut self) -> Result<f32, TryGetError> {
392 match self.try_get_u32() {
393 Ok(bits) => Ok(f32::from_bits(bits)),
394 Err(e) => Err(e),
395 }
396 }
397
398 #[inline]
407 pub fn get_f32_le(&mut self) -> f32 {
408 f32::from_bits(self.get_u32_le())
409 }
410
411 #[inline]
420 pub const fn try_get_f32_le(&mut self) -> Result<f32, TryGetError> {
421 match self.try_get_u32_le() {
422 Ok(bits) => Ok(f32::from_bits(bits)),
423 Err(e) => Err(e),
424 }
425 }
426
427 #[inline]
436 pub fn get_f32_ne(&mut self) -> f32 {
437 f32::from_bits(self.get_u32_ne())
438 }
439
440 #[inline]
449 pub const fn try_get_f32_ne(&mut self) -> Result<f32, TryGetError> {
450 match self.try_get_u32_ne() {
451 Ok(bits) => Ok(f32::from_bits(bits)),
452 Err(e) => Err(e),
453 }
454 }
455
456 #[inline]
465 pub fn get_f64(&mut self) -> f64 {
466 f64::from_bits(self.get_u64())
467 }
468
469 #[inline]
478 pub const fn try_get_f64(&mut self) -> Result<f64, TryGetError> {
479 match self.try_get_u64() {
480 Ok(bits) => Ok(f64::from_bits(bits)),
481 Err(e) => Err(e),
482 }
483 }
484
485 #[inline]
494 pub fn get_f64_le(&mut self) -> f64 {
495 f64::from_bits(self.get_u64_le())
496 }
497
498 #[inline]
507 pub const fn try_get_f64_le(&mut self) -> Result<f64, TryGetError> {
508 match self.try_get_u64_le() {
509 Ok(bits) => Ok(f64::from_bits(bits)),
510 Err(e) => Err(e),
511 }
512 }
513
514 #[inline]
523 pub fn get_f64_ne(&mut self) -> f64 {
524 f64::from_bits(self.get_u64_ne())
525 }
526
527 #[inline]
536 pub const fn try_get_f64_ne(&mut self) -> Result<f64, TryGetError> {
537 match self.try_get_u64_ne() {
538 Ok(bits) => Ok(f64::from_bits(bits)),
539 Err(e) => Err(e),
540 }
541 }
542
543 #[inline]
561 pub fn get_uint(&mut self, nbytes: usize) -> u64 {
562 self
563 .try_get_uint(nbytes)
564 .unwrap_or_else(panic_try_get_integer)
565 }
566
567 #[inline]
577 pub fn try_get_uint(&mut self, nbytes: usize) -> Result<u64, TryGetIntegerError> {
578 impl_try_get!(be(self, u64, nbytes))
579 }
580
581 #[inline]
590 pub fn get_uint_le(&mut self, nbytes: usize) -> u64 {
591 self
592 .try_get_uint_le(nbytes)
593 .unwrap_or_else(panic_try_get_integer)
594 }
595
596 #[inline]
606 pub fn try_get_uint_le(&mut self, nbytes: usize) -> Result<u64, TryGetIntegerError> {
607 impl_try_get!(le(self, u64, nbytes))
608 }
609
610 #[inline]
619 pub fn get_uint_ne(&mut self, nbytes: usize) -> u64 {
620 self
621 .try_get_uint_ne(nbytes)
622 .unwrap_or_else(panic_try_get_integer)
623 }
624
625 #[inline]
635 pub fn try_get_uint_ne(&mut self, nbytes: usize) -> Result<u64, TryGetIntegerError> {
636 if cfg!(target_endian = "big") {
637 self.try_get_uint(nbytes)
638 } else {
639 self.try_get_uint_le(nbytes)
640 }
641 }
642
643 #[inline]
652 pub fn get_int(&mut self, nbytes: usize) -> i64 {
653 sign_extend(self.get_uint(nbytes), nbytes)
654 }
655
656 #[inline]
666 pub fn try_get_int(&mut self, nbytes: usize) -> Result<i64, TryGetIntegerError> {
667 self
668 .try_get_uint(nbytes)
669 .map(|value| sign_extend(value, nbytes))
670 }
671
672 #[inline]
681 pub fn get_int_le(&mut self, nbytes: usize) -> i64 {
682 sign_extend(self.get_uint_le(nbytes), nbytes)
683 }
684
685 #[inline]
695 pub fn try_get_int_le(&mut self, nbytes: usize) -> Result<i64, TryGetIntegerError> {
696 self
697 .try_get_uint_le(nbytes)
698 .map(|value| sign_extend(value, nbytes))
699 }
700
701 #[inline]
710 pub fn get_int_ne(&mut self, nbytes: usize) -> i64 {
711 if cfg!(target_endian = "big") {
712 self.get_int(nbytes)
713 } else {
714 self.get_int_le(nbytes)
715 }
716 }
717
718 #[inline]
728 pub fn try_get_int_ne(&mut self, nbytes: usize) -> Result<i64, TryGetIntegerError> {
729 if cfg!(target_endian = "big") {
730 self.try_get_int(nbytes)
731 } else {
732 self.try_get_int_le(nbytes)
733 }
734 }
735}
736
737impl Buffer {
738 try_put_and_put!(
739 "little-endian": {
740 u16::to_le_bytes::le,
741 i16::to_le_bytes::le,
742 u32::to_le_bytes::le,
743 i32::to_le_bytes::le,
744 u64::to_le_bytes::le,
745 i64::to_le_bytes::le,
746 u128::to_le_bytes::le,
747 i128::to_le_bytes::le,
748 }
749 );
750
751 try_put_and_put!(
752 "big-endian": {
753 u16::to_be_bytes,
754 i16::to_be_bytes,
755 u32::to_be_bytes,
756 i32::to_be_bytes,
757 u64::to_be_bytes,
758 i64::to_be_bytes,
759 u128::to_be_bytes,
760 i128::to_be_bytes,
761 }
762 );
763
764 try_put_and_put!(
765 "native-endian": {
766 u16::to_ne_bytes::ne,
767 i16::to_ne_bytes::ne,
768 u32::to_ne_bytes::ne,
769 i32::to_ne_bytes::ne,
770 u64::to_ne_bytes::ne,
771 i64::to_ne_bytes::ne,
772 u128::to_ne_bytes::ne,
773 i128::to_ne_bytes::ne,
774 }
775 );
776
777 #[inline]
795 pub fn put_i8(&mut self, n: i8) {
796 self
797 .try_put_i8(n)
798 .unwrap_or_else(|e| panic_advance(e.available, e.requested))
799 }
800
801 #[inline]
809 pub const fn try_put_i8(&mut self, n: i8) -> Result<(), TryPutError> {
810 self.try_put_u8(n as u8)
811 }
812
813 #[inline]
822 pub fn put_uint(&mut self, n: u64, nbytes: usize) {
823 self
824 .try_put_uint(n, nbytes)
825 .unwrap_or_else(|e| panic!("{e}"));
826 }
827
828 #[inline]
836 pub const fn try_put_uint(&mut self, n: u64, nbytes: usize) -> Result<(), TryPutIntegerError> {
837 if nbytes > 8 {
838 return Err(TryPutIntegerError::InvalidLength(InvalidIntegerLength(
839 nbytes,
840 )));
841 }
842
843 let available = self.remaining_mut();
844 if available < nbytes {
845 return Err(TryPutIntegerError::NotEnoughSpace(TryPutError {
846 requested: nbytes,
847 available,
848 }));
849 }
850
851 let bytes = n.to_be_bytes();
852 let mut i = 0;
853 while i < nbytes {
854 unsafe {
857 *self
858 .buf
859 .as_mut_ptr()
860 .add(self.end.to_usize() + i)
861 .cast::<u8>() = bytes[8 - nbytes + i];
862 }
863 i += 1;
864 }
865 self.end = unsafe { InlineSize::from_u8(self.end.to_u8() + nbytes as u8) };
868 Ok(())
869 }
870
871 #[inline]
880 pub fn put_uint_le(&mut self, n: u64, nbytes: usize) {
881 self
882 .try_put_uint_le(n, nbytes)
883 .unwrap_or_else(|e| panic!("{e}"))
884 }
885
886 #[inline]
894 pub const fn try_put_uint_le(&mut self, n: u64, nbytes: usize) -> Result<(), TryPutIntegerError> {
895 if nbytes > 8 {
896 return Err(TryPutIntegerError::InvalidLength(InvalidIntegerLength(
897 nbytes,
898 )));
899 }
900
901 let available = self.remaining_mut();
902 if available < nbytes {
903 return Err(TryPutIntegerError::NotEnoughSpace(TryPutError {
904 requested: nbytes,
905 available,
906 }));
907 }
908
909 let bytes = n.to_le_bytes();
910 let mut i = 0;
911 while i < nbytes {
912 unsafe {
915 *self
916 .buf
917 .as_mut_ptr()
918 .add(self.end.to_usize() + i)
919 .cast::<u8>() = bytes[i];
920 }
921 i += 1;
922 }
923 self.end = unsafe { InlineSize::from_u8(self.end.to_u8() + nbytes as u8) };
926 Ok(())
927 }
928
929 #[inline]
938 pub fn put_uint_ne(&mut self, n: u64, nbytes: usize) {
939 self
940 .try_put_uint_ne(n, nbytes)
941 .unwrap_or_else(|e| panic!("{e}"))
942 }
943
944 #[inline]
956 pub const fn try_put_uint_ne(&mut self, n: u64, nbytes: usize) -> Result<(), TryPutIntegerError> {
957 if cfg!(target_endian = "big") {
958 self.try_put_uint(n, nbytes)
959 } else {
960 self.try_put_uint_le(n, nbytes)
961 }
962 }
963
964 #[inline]
973 pub fn put_int(&mut self, n: i64, nbytes: usize) {
974 self
975 .try_put_int(n, nbytes)
976 .unwrap_or_else(|e| panic!("{e}"));
977 }
978
979 #[inline]
991 pub const fn try_put_int(&mut self, n: i64, nbytes: usize) -> Result<(), TryPutIntegerError> {
992 self.try_put_uint(n as u64, nbytes)
993 }
994
995 #[inline]
1004 pub fn put_int_le(&mut self, n: i64, nbytes: usize) {
1005 self
1006 .try_put_int_le(n, nbytes)
1007 .unwrap_or_else(|e| panic!("{e}"));
1008 }
1009
1010 #[inline]
1022 pub const fn try_put_int_le(&mut self, n: i64, nbytes: usize) -> Result<(), TryPutIntegerError> {
1023 self.try_put_uint_le(n as u64, nbytes)
1024 }
1025
1026 #[inline]
1035 pub fn put_int_ne(&mut self, n: i64, nbytes: usize) {
1036 self
1037 .try_put_int_ne(n, nbytes)
1038 .unwrap_or_else(|e| panic!("{e}"));
1039 }
1040
1041 #[inline]
1053 pub const fn try_put_int_ne(&mut self, n: i64, nbytes: usize) -> Result<(), TryPutIntegerError> {
1054 if cfg!(target_endian = "big") {
1055 self.try_put_int(n, nbytes)
1056 } else {
1057 self.try_put_int_le(n, nbytes)
1058 }
1059 }
1060
1061 pub fn try_put_uint_checked(
1067 &mut self,
1068 n: u64,
1069 nbytes: usize,
1070 ) -> Result<(), TryPutIntegerCheckedError> {
1071 checked_unsigned_range(n, nbytes)?;
1072 match self.try_put_uint(n, nbytes) {
1073 Ok(()) => Ok(()),
1074 Err(TryPutIntegerError::InvalidLength(error)) => Err(error.into()),
1075 Err(TryPutIntegerError::NotEnoughSpace(error)) => Err(error.into()),
1076 }
1077 }
1078
1079 pub fn try_put_uint_checked_le(
1085 &mut self,
1086 n: u64,
1087 nbytes: usize,
1088 ) -> Result<(), TryPutIntegerCheckedError> {
1089 checked_unsigned_range(n, nbytes)?;
1090 match self.try_put_uint_le(n, nbytes) {
1091 Ok(()) => Ok(()),
1092 Err(TryPutIntegerError::InvalidLength(error)) => Err(error.into()),
1093 Err(TryPutIntegerError::NotEnoughSpace(error)) => Err(error.into()),
1094 }
1095 }
1096
1097 pub fn try_put_uint_checked_ne(
1100 &mut self,
1101 n: u64,
1102 nbytes: usize,
1103 ) -> Result<(), TryPutIntegerCheckedError> {
1104 if cfg!(target_endian = "big") {
1105 self.try_put_uint_checked(n, nbytes)
1106 } else {
1107 self.try_put_uint_checked_le(n, nbytes)
1108 }
1109 }
1110
1111 pub fn try_put_int_checked(
1117 &mut self,
1118 n: i64,
1119 nbytes: usize,
1120 ) -> Result<(), TryPutIntegerCheckedError> {
1121 checked_signed_range(n, nbytes)?;
1122 match self.try_put_int(n, nbytes) {
1123 Ok(()) => Ok(()),
1124 Err(TryPutIntegerError::InvalidLength(error)) => Err(error.into()),
1125 Err(TryPutIntegerError::NotEnoughSpace(error)) => Err(error.into()),
1126 }
1127 }
1128
1129 pub fn try_put_int_checked_le(
1135 &mut self,
1136 n: i64,
1137 nbytes: usize,
1138 ) -> Result<(), TryPutIntegerCheckedError> {
1139 checked_signed_range(n, nbytes)?;
1140 match self.try_put_int_le(n, nbytes) {
1141 Ok(()) => Ok(()),
1142 Err(TryPutIntegerError::InvalidLength(error)) => Err(error.into()),
1143 Err(TryPutIntegerError::NotEnoughSpace(error)) => Err(error.into()),
1144 }
1145 }
1146
1147 pub fn try_put_int_checked_ne(
1150 &mut self,
1151 n: i64,
1152 nbytes: usize,
1153 ) -> Result<(), TryPutIntegerCheckedError> {
1154 if cfg!(target_endian = "big") {
1155 self.try_put_int_checked(n, nbytes)
1156 } else {
1157 self.try_put_int_checked_le(n, nbytes)
1158 }
1159 }
1160
1161 #[inline]
1170 pub fn put_f32(&mut self, n: f32) {
1171 self.put_u32(n.to_bits())
1172 }
1173
1174 #[inline]
1183 pub const fn try_put_f32(&mut self, n: f32) -> Result<(), TryPutError> {
1184 self.try_put_u32(n.to_bits())
1185 }
1186
1187 #[inline]
1196 pub fn put_f32_le(&mut self, n: f32) {
1197 self.put_u32_le(n.to_bits())
1198 }
1199
1200 #[inline]
1209 pub const fn try_put_f32_le(&mut self, n: f32) -> Result<(), TryPutError> {
1210 self.try_put_u32_le(n.to_bits())
1211 }
1212
1213 #[inline]
1222 pub fn put_f32_ne(&mut self, n: f32) {
1223 self.put_u32_ne(n.to_bits())
1224 }
1225
1226 #[inline]
1235 pub const fn try_put_f32_ne(&mut self, n: f32) -> Result<(), TryPutError> {
1236 self.try_put_u32_ne(n.to_bits())
1237 }
1238
1239 #[inline]
1248 pub fn put_f64(&mut self, n: f64) {
1249 self.put_u64(n.to_bits())
1250 }
1251
1252 #[inline]
1261 pub const fn try_put_f64(&mut self, n: f64) -> Result<(), TryPutError> {
1262 self.try_put_u64(n.to_bits())
1263 }
1264
1265 #[inline]
1274 pub fn put_f64_le(&mut self, n: f64) {
1275 self.put_u64_le(n.to_bits())
1276 }
1277
1278 #[inline]
1287 pub const fn try_put_f64_le(&mut self, n: f64) -> Result<(), TryPutError> {
1288 self.try_put_u64_le(n.to_bits())
1289 }
1290
1291 #[inline]
1300 pub fn put_f64_ne(&mut self, n: f64) {
1301 self.put_u64_ne(n.to_bits())
1302 }
1303
1304 #[inline]
1313 pub const fn try_put_f64_ne(&mut self, n: f64) -> Result<(), TryPutError> {
1314 self.try_put_u64_ne(n.to_bits())
1315 }
1316}
1317
1318#[cfg(test)]
1319mod tests {
1320 #[cfg(not(feature = "std"))]
1321 extern crate std;
1322
1323 use super::*;
1324
1325 #[test]
1326 fn test_get_u8() {
1327 let mut buf = Buffer::try_from(&[0x01, 0x02, 0x03][..]).unwrap();
1328 assert_eq!(buf.get_u8(), 0x01);
1329 assert_eq!(buf.get_u8(), 0x02);
1330 assert_eq!(buf.get_u8(), 0x03);
1331 assert_eq!(buf.remaining(), 0);
1332 }
1333
1334 #[test]
1335 fn test_try_get_u8_error() {
1336 let mut buf = Buffer::new();
1337 assert!(buf.try_get_u8().is_err());
1338 }
1339
1340 #[test]
1341 fn test_get_i8() {
1342 let mut buf = Buffer::try_from(&[0xFF, 0x7F, 0x80][..]).unwrap();
1343 assert_eq!(buf.get_i8(), -1);
1344 assert_eq!(buf.get_i8(), 127);
1345 assert_eq!(buf.get_i8(), -128);
1346 }
1347
1348 #[test]
1349 fn test_get_u16() {
1350 let mut buf = Buffer::try_from(&[0x01, 0x02, 0x03, 0x04][..]).unwrap();
1351 assert_eq!(buf.get_u16(), 0x0102);
1352 assert_eq!(buf.get_u16(), 0x0304);
1353 }
1354
1355 #[test]
1356 fn test_get_u16_le() {
1357 let mut buf = Buffer::try_from(&[0x01, 0x02, 0x03, 0x04][..]).unwrap();
1358 assert_eq!(buf.get_u16_le(), 0x0201);
1359 assert_eq!(buf.get_u16_le(), 0x0403);
1360 }
1361
1362 #[test]
1363 fn test_get_i16() {
1364 let mut buf = Buffer::try_from(&[0xFF, 0xFF, 0x7F, 0xFF][..]).unwrap();
1365 assert_eq!(buf.get_i16(), -1);
1366 assert_eq!(buf.get_i16(), 32767);
1367 }
1368
1369 #[test]
1370 fn test_get_u32() {
1371 let mut buf = Buffer::try_from(&[0x01, 0x02, 0x03, 0x04][..]).unwrap();
1372 assert_eq!(buf.get_u32(), 0x01020304);
1373 }
1374
1375 #[test]
1376 fn test_get_u32_le() {
1377 let mut buf = Buffer::try_from(&[0x01, 0x02, 0x03, 0x04][..]).unwrap();
1378 assert_eq!(buf.get_u32_le(), 0x04030201);
1379 }
1380
1381 #[test]
1382 fn test_get_i32() {
1383 let mut buf = Buffer::try_from(&[0xFF, 0xFF, 0xFF, 0xFF][..]).unwrap();
1384 assert_eq!(buf.get_i32(), -1);
1385 }
1386
1387 #[test]
1388 fn test_get_u64() {
1389 let mut buf = Buffer::try_from(&[0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08][..]).unwrap();
1390 assert_eq!(buf.get_u64(), 0x0102030405060708);
1391 }
1392
1393 #[test]
1394 fn test_get_u64_le() {
1395 let mut buf = Buffer::try_from(&[0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08][..]).unwrap();
1396 assert_eq!(buf.get_u64_le(), 0x0807060504030201);
1397 }
1398
1399 #[test]
1400 fn test_get_i64() {
1401 let mut buf = Buffer::try_from(&[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF][..]).unwrap();
1402 assert_eq!(buf.get_i64(), -1);
1403 }
1404
1405 #[test]
1406 fn test_get_u128() {
1407 let mut buf = Buffer::try_from(
1408 &[
1409 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1410 0x10,
1411 ][..],
1412 )
1413 .unwrap();
1414 assert_eq!(buf.get_u128(), 0x0102030405060708090A0B0C0D0E0F10);
1415 }
1416
1417 #[test]
1418 fn test_get_u128_le() {
1419 let mut buf = Buffer::try_from(
1420 &[
1421 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1422 0x10,
1423 ][..],
1424 )
1425 .unwrap();
1426 assert_eq!(buf.get_u128_le(), 0x100F0E0D0C0B0A090807060504030201);
1427 }
1428
1429 #[test]
1430 fn test_get_i128() {
1431 let mut buf = Buffer::try_from(
1432 &[
1433 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1434 0xFF,
1435 ][..],
1436 )
1437 .unwrap();
1438 assert_eq!(buf.get_i128(), -1);
1439 }
1440
1441 #[test]
1442 fn test_get_f32() {
1443 let mut buf = Buffer::try_from(&[0x41, 0x48, 0x00, 0x00][..]).unwrap();
1444 assert_eq!(buf.get_f32(), 12.5);
1445 }
1446
1447 #[test]
1448 fn test_get_f32_le() {
1449 let mut buf = Buffer::try_from(&[0x00, 0x00, 0x48, 0x41][..]).unwrap();
1450 assert_eq!(buf.get_f32_le(), 12.5);
1451 }
1452
1453 #[test]
1454 fn test_get_f64() {
1455 let mut buf = Buffer::try_from(&[0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..]).unwrap();
1456 assert_eq!(buf.get_f64(), 12.5);
1457 }
1458
1459 #[test]
1460 fn test_get_f64_le() {
1461 let mut buf = Buffer::try_from(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x40][..]).unwrap();
1462 assert_eq!(buf.get_f64_le(), 12.5);
1463 }
1464
1465 #[test]
1466 fn test_get_uint() {
1467 let mut buf = Buffer::try_from(&[0x01, 0x02, 0x03][..]).unwrap();
1468 assert_eq!(buf.get_uint(3), 0x010203);
1469 assert_eq!(buf.remaining(), 0);
1470 }
1471
1472 #[test]
1473 fn test_get_uint_le() {
1474 let mut buf = Buffer::try_from(&[0x01, 0x02, 0x03][..]).unwrap();
1475 assert_eq!(buf.get_uint_le(3), 0x030201);
1476 assert_eq!(buf.remaining(), 0);
1477 }
1478
1479 #[test]
1480 fn test_get_int() {
1481 let mut buf = Buffer::try_from(&[0xFF, 0xFF, 0xFF][..]).unwrap();
1482 assert_eq!(buf.get_int(3), -1);
1483 }
1484
1485 #[test]
1486 fn test_get_int_le() {
1487 let mut buf = Buffer::try_from(&[0xFF, 0xFF, 0xFF][..]).unwrap();
1488 assert_eq!(buf.get_int_le(3), -1);
1489 }
1490
1491 #[test]
1493 fn test_put_u8() {
1494 let mut buf = Buffer::new();
1495 buf.put_u8(0x01);
1496 buf.put_u8(0x02);
1497 assert_eq!(&buf[..], &[0x01, 0x02]);
1498 }
1499
1500 #[test]
1501 fn test_try_put_u8_error() {
1502 let mut buf = Buffer::try_from(&[0u8; 62][..]).unwrap();
1503 assert!(buf.try_put_u8(0xFF).is_err());
1504 }
1505
1506 #[test]
1507 fn test_put_i8() {
1508 let mut buf = Buffer::new();
1509 buf.put_i8(-1);
1510 buf.put_i8(127);
1511 assert_eq!(&buf[..], &[0xFF, 0x7F]);
1512 }
1513
1514 #[test]
1515 fn test_put_u16() {
1516 let mut buf = Buffer::new();
1517 buf.put_u16(0x0102);
1518 assert_eq!(&buf[..], &[0x01, 0x02]);
1519 }
1520
1521 #[test]
1522 fn test_put_u16_le() {
1523 let mut buf = Buffer::new();
1524 buf.put_u16_le(0x0102);
1525 assert_eq!(&buf[..], &[0x02, 0x01]);
1526 }
1527
1528 #[test]
1529 fn test_put_i16() {
1530 let mut buf = Buffer::new();
1531 buf.put_i16(-1);
1532 assert_eq!(&buf[..], &[0xFF, 0xFF]);
1533 }
1534
1535 #[test]
1536 fn test_put_u32() {
1537 let mut buf = Buffer::new();
1538 buf.put_u32(0x01020304);
1539 assert_eq!(&buf[..], &[0x01, 0x02, 0x03, 0x04]);
1540 }
1541
1542 #[test]
1543 fn test_put_u32_le() {
1544 let mut buf = Buffer::new();
1545 buf.put_u32_le(0x01020304);
1546 assert_eq!(&buf[..], &[0x04, 0x03, 0x02, 0x01]);
1547 }
1548
1549 #[test]
1550 fn test_put_i32() {
1551 let mut buf = Buffer::new();
1552 buf.put_i32(-1);
1553 assert_eq!(&buf[..], &[0xFF, 0xFF, 0xFF, 0xFF]);
1554 }
1555
1556 #[test]
1557 fn test_put_u64() {
1558 let mut buf = Buffer::new();
1559 buf.put_u64(0x0102030405060708);
1560 assert_eq!(&buf[..], &[0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]);
1561 }
1562
1563 #[test]
1564 fn test_put_u64_le() {
1565 let mut buf = Buffer::new();
1566 buf.put_u64_le(0x0102030405060708);
1567 assert_eq!(&buf[..], &[0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01]);
1568 }
1569
1570 #[test]
1571 fn test_put_i64() {
1572 let mut buf = Buffer::new();
1573 buf.put_i64(-1);
1574 assert_eq!(&buf[..], &[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]);
1575 }
1576
1577 #[test]
1578 fn test_put_u128() {
1579 let mut buf = Buffer::new();
1580 buf.put_u128(0x0102030405060708090A0B0C0D0E0F10);
1581 assert_eq!(
1582 &buf[..],
1583 &[
1584 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1585 0x10
1586 ]
1587 );
1588 }
1589
1590 #[test]
1591 fn test_put_u128_le() {
1592 let mut buf = Buffer::new();
1593 buf.put_u128_le(0x0102030405060708090A0B0C0D0E0F10);
1594 assert_eq!(
1595 &buf[..],
1596 &[
1597 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02,
1598 0x01
1599 ]
1600 );
1601 }
1602
1603 #[test]
1604 fn test_put_i128() {
1605 let mut buf = Buffer::new();
1606 buf.put_i128(-1);
1607 assert_eq!(
1608 &buf[..],
1609 &[
1610 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1611 0xFF
1612 ]
1613 );
1614 }
1615
1616 #[test]
1617 fn test_put_f32() {
1618 let mut buf = Buffer::new();
1619 buf.put_f32(12.5);
1620 assert_eq!(&buf[..], &[0x41, 0x48, 0x00, 0x00]);
1621 }
1622
1623 #[test]
1624 fn test_put_f32_le() {
1625 let mut buf = Buffer::new();
1626 buf.put_f32_le(12.5);
1627 assert_eq!(&buf[..], &[0x00, 0x00, 0x48, 0x41]);
1628 }
1629
1630 #[test]
1631 fn test_put_f64() {
1632 let mut buf = Buffer::new();
1633 buf.put_f64(12.5);
1634 assert_eq!(&buf[..], &[0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
1635 }
1636
1637 #[test]
1638 fn test_put_f64_le() {
1639 let mut buf = Buffer::new();
1640 buf.put_f64_le(12.5);
1641 assert_eq!(&buf[..], &[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x40]);
1642 }
1643
1644 #[test]
1645 fn test_put_uint() {
1646 let mut buf = Buffer::new();
1647 buf.put_uint(0x010203, 3);
1648 assert_eq!(&buf[..], &[0x01, 0x02, 0x03]);
1649 }
1650
1651 #[test]
1652 fn test_put_uint_le() {
1653 let mut buf = Buffer::new();
1654 buf.put_uint_le(0x010203, 3);
1655 assert_eq!(&buf[..], &[0x03, 0x02, 0x01]);
1656 }
1657
1658 #[test]
1659 fn test_put_int() {
1660 let mut buf = Buffer::new();
1661 buf.put_int(-1, 3);
1662 assert_eq!(&buf[..], &[0xFF, 0xFF, 0xFF]);
1663 }
1664
1665 #[test]
1666 fn test_put_int_le() {
1667 let mut buf = Buffer::new();
1668 buf.put_int_le(-1, 3);
1669 assert_eq!(&buf[..], &[0xFF, 0xFF, 0xFF]);
1670 }
1671
1672 #[test]
1673 fn test_roundtrip_u16() {
1674 let mut buf = Buffer::new();
1675 let value: u16 = 0x1234;
1676 buf.put_u16(value);
1677 buf.advance(0);
1678 assert_eq!(buf.get_u16(), value);
1679 }
1680
1681 #[test]
1682 fn test_roundtrip_u32() {
1683 let mut buf = Buffer::new();
1684 let value: u32 = 0x12345678;
1685 buf.put_u32(value);
1686 buf.advance(0);
1687 assert_eq!(buf.get_u32(), value);
1688 }
1689
1690 #[test]
1691 fn test_roundtrip_u64() {
1692 let mut buf = Buffer::new();
1693 let value: u64 = 0x123456789ABCDEF0;
1694 buf.put_u64(value);
1695 buf.advance(0);
1696 assert_eq!(buf.get_u64(), value);
1697 }
1698
1699 #[test]
1700 fn test_roundtrip_u128() {
1701 let mut buf = Buffer::new();
1702 let value: u128 = 0x123456789ABCDEF0FEDCBA9876543210;
1703 buf.put_u128(value);
1704 buf.advance(0);
1705 assert_eq!(buf.get_u128(), value);
1706 }
1707
1708 #[test]
1709 fn test_roundtrip_f32() {
1710 let mut buf = Buffer::new();
1711 let value: f32 = core::f32::consts::PI;
1712 buf.put_f32(value);
1713 buf.advance(0);
1714 assert_eq!(buf.get_f32(), value);
1715 }
1716
1717 #[test]
1718 fn test_roundtrip_f64() {
1719 let mut buf = Buffer::new();
1720 let value: f64 = core::f64::consts::PI;
1721 buf.put_f64(value);
1722 buf.advance(0);
1723 assert_eq!(buf.get_f64(), value);
1724 }
1725
1726 #[test]
1727 fn test_mixed_operations() {
1728 let mut buf = Buffer::new();
1729 buf.put_u8(0x01);
1730 buf.put_u16(0x0203);
1731 buf.put_u32(0x04050607);
1732 buf.advance(0);
1733
1734 assert_eq!(buf.get_u8(), 0x01);
1735 assert_eq!(buf.get_u16(), 0x0203);
1736 assert_eq!(buf.get_u32(), 0x04050607);
1737 assert_eq!(buf.remaining(), 0);
1738 }
1739
1740 #[test]
1741 fn test_native_endian_consistency() {
1742 let mut buf = Buffer::new();
1743 let value: u32 = 0x12345678;
1744 buf.put_u32_ne(value);
1745 buf.advance(0);
1746 assert_eq!(buf.get_u32_ne(), value);
1747 }
1748
1749 #[test]
1750 #[should_panic]
1751 fn test_get_u8_panic() {
1752 let mut buf = Buffer::new();
1753 buf.get_u8(); }
1755
1756 #[test]
1757 #[should_panic]
1758 fn test_put_u8_panic() {
1759 let mut buf = Buffer::try_from(&[0u8; 62][..]).unwrap();
1760 buf.put_u8(0xFF); }
1762
1763 #[test]
1764 fn test_try_methods_errors() {
1765 let mut empty_buf = Buffer::new();
1766 assert!(empty_buf.try_get_u8().is_err());
1767 assert!(empty_buf.try_get_i8().is_err());
1768 assert!(empty_buf.try_get_u16().is_err());
1769 assert!(empty_buf.try_get_i16().is_err());
1770 assert!(empty_buf.try_get_u32().is_err());
1771 assert!(empty_buf.try_get_i32().is_err());
1772 assert!(empty_buf.try_get_u64().is_err());
1773 assert!(empty_buf.try_get_i64().is_err());
1774 assert!(empty_buf.try_get_u128().is_err());
1775 assert!(empty_buf.try_get_i128().is_err());
1776 assert!(empty_buf.try_get_f32().is_err());
1777 assert!(empty_buf.try_get_f64().is_err());
1778 assert!(empty_buf.try_get_uint(3).is_err());
1779 assert!(empty_buf.try_get_int(3).is_err());
1780
1781 let mut full_buf = Buffer::try_from(&[0u8; 62][..]).unwrap();
1782 assert!(full_buf.try_put_u8(0).is_err());
1783 assert!(full_buf.try_put_i8(0).is_err());
1784 }
1785
1786 #[test]
1787 fn variable_width_panics_before_availability_checks_and_preserves_cursor() {
1788 for operation in [
1789 |buffer: &mut Buffer| buffer.get_uint(9),
1790 |buffer: &mut Buffer| buffer.get_uint_le(9),
1791 |buffer: &mut Buffer| buffer.get_uint_ne(9),
1792 ] {
1793 let mut buffer = Buffer::try_from(&b"abc"[..]).unwrap();
1794 let panic = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| operation(&mut buffer)));
1795 assert!(panic.is_err());
1796 assert_eq!(buffer.as_slice(), b"abc");
1797 }
1798
1799 for operation in [
1800 |buffer: &mut Buffer| buffer.get_int(9),
1801 |buffer: &mut Buffer| buffer.get_int_le(9),
1802 |buffer: &mut Buffer| buffer.get_int_ne(9),
1803 ] {
1804 let mut buffer = Buffer::try_from(&b"abc"[..]).unwrap();
1805 let panic = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| operation(&mut buffer)));
1806 assert!(panic.is_err());
1807 assert_eq!(buffer.as_slice(), b"abc");
1808 }
1809 }
1810}