Skip to main content

bit_buf/
read.rs

1use crate::{BitBuf, Error, Result, Storage, ensure};
2
3impl_read! {
4  u8;
5  bytes = 1;
6  bits = 8;
7  offset = 0;
8  [a];
9  [a, b];
10
11  read_u8_be_aligned_at_unchecked;
12  read_u8_be_aligned_unchecked;
13  read_u8_be_at_unchecked;
14  read_u8_be_unchecked;
15  try_read_u8_be_aligned_at;
16  try_read_u8_be_aligned;
17  try_read_u8_be_at;
18  try_read_u8_be;
19  read_u8_be_aligned_at;
20  read_u8_be_aligned;
21  read_u8_be_at;
22  read_u8_be;
23}
24
25impl_read! {
26  u16;
27  bytes = 2;
28  bits = 16;
29  offset = 1;
30  [a, b];
31  [a, [b], c];
32
33  read_u16_be_aligned_at_unchecked;
34  read_u16_be_aligned_unchecked;
35  read_u16_be_at_unchecked;
36  read_u16_be_unchecked;
37  try_read_u16_be_aligned_at;
38  try_read_u16_be_aligned;
39  try_read_u16_be_at;
40  try_read_u16_be;
41  read_u16_be_aligned_at;
42  read_u16_be_aligned;
43  read_u16_be_at;
44  read_u16_be;
45}
46
47impl_read! {
48  u32;
49  bytes = 4;
50  bits = 32;
51  offset = 3;
52  [a, b, c, d];
53  [a, [b, c, d], e];
54
55  read_u32_be_aligned_at_unchecked;
56  read_u32_be_aligned_unchecked;
57  read_u32_be_at_unchecked;
58  read_u32_be_unchecked;
59  try_read_u32_be_aligned_at;
60  try_read_u32_be_aligned;
61  try_read_u32_be_at;
62  try_read_u32_be;
63  read_u32_be_aligned_at;
64  read_u32_be_aligned;
65  read_u32_be_at;
66  read_u32_be;
67}
68
69impl_read! {
70  u64;
71  bytes = 8;
72  bits = 64;
73  offset = 7;
74  [a, b, c, d, e, f, g, h];
75  [a, [b, c, d, e, f, g, h], i];
76
77  read_u64_be_aligned_at_unchecked;
78  read_u64_be_aligned_unchecked;
79  read_u64_be_at_unchecked;
80  read_u64_be_unchecked;
81  try_read_u64_be_aligned_at;
82  try_read_u64_be_aligned;
83  try_read_u64_be_at;
84  try_read_u64_be;
85  read_u64_be_aligned_at;
86  read_u64_be_aligned;
87  read_u64_be_at;
88  read_u64_be;
89}
90
91impl_read! {
92  u128;
93  bytes = 16;
94  bits = 128;
95  offset = 15;
96  [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p];
97  [a, [b, c, d, e, f, g, h, i, j, k, l, m, n, o, p], q];
98
99  read_u128_be_aligned_at_unchecked;
100  read_u128_be_aligned_unchecked;
101  read_u128_be_at_unchecked;
102  read_u128_be_unchecked;
103  try_read_u128_be_aligned_at;
104  try_read_u128_be_aligned;
105  try_read_u128_be_at;
106  try_read_u128_be;
107  read_u128_be_aligned_at;
108  read_u128_be_aligned;
109  read_u128_be_at;
110  read_u128_be;
111}
112
113pub trait Read: Sized {
114  unsafe fn read_be_aligned_at_unchecked<S: Storage>(buf: &BitBuf<S>, byte_offset: usize) -> Self;
115
116  unsafe fn read_be_aligned_unchecked<S: Storage>(buf: &mut BitBuf<S>) -> Self;
117
118  unsafe fn read_be_at_unchecked<S: Storage>(buf: &BitBuf<S>, offset: usize) -> Self;
119
120  unsafe fn read_be_unchecked<S: Storage>(buf: &mut BitBuf<S>) -> Self;
121
122  fn try_read_be_aligned_at<S: Storage>(buf: &BitBuf<S>, byte_offset: usize) -> Result<Self>;
123
124  fn try_read_be_aligned<S: Storage>(buf: &mut BitBuf<S>) -> Result<Self>;
125
126  fn try_read_be_at<S: Storage>(buf: &BitBuf<S>, offset: usize) -> Result<Self>;
127
128  fn try_read_be<S: Storage>(buf: &mut BitBuf<S>) -> Result<Self>;
129
130  fn read_be_aligned_at<S: Storage>(buf: &BitBuf<S>, byte_offset: usize) -> Self;
131
132  fn read_be_aligned<S: Storage>(buf: &mut BitBuf<S>) -> Self;
133
134  fn read_be_at<S: Storage>(buf: &BitBuf<S>, offset: usize) -> Self;
135
136  fn read_be<S: Storage>(buf: &mut BitBuf<S>) -> Self;
137}
138
139impl<S: Storage> BitBuf<S> {
140  /// Read a `T` in [BE-bit, BE-byte] order from `byte_offset` without performing bound checks
141  ///
142  /// # Safety
143  ///
144  /// All semantics of the corresponding function for the type apply
145  ///
146  /// # Panics
147  ///
148  /// All semantics of the corresponding function for the type apply
149  #[inline(always)]
150  #[must_use]
151  pub unsafe fn read_be_aligned_at_unchecked<T: Read>(&self, byte_offset: usize) -> T {
152    unsafe { T::read_be_aligned_at_unchecked(self, byte_offset) }
153  }
154
155  /// Read the next `T` in [BE-bit, BE-byte] order without performing bound checks, advancing the internal cursor
156  ///
157  /// # Safety
158  ///
159  /// All semantics of the corresponding function for the type apply
160  ///
161  /// # Panics
162  ///
163  /// All semantics of the corresponding function for the type apply
164  #[inline(always)]
165  #[must_use]
166  pub unsafe fn read_be_aligned_unchecked<T: Read>(&mut self) -> T {
167    unsafe { T::read_be_aligned_unchecked(self) }
168  }
169
170  /// Read a `T` in [BE-bit, BE-byte] order from `offset` without performing bound checks
171  ///
172  /// # Safety
173  ///
174  /// All semantics of the corresponding function for the type apply
175  ///
176  /// # Panics
177  ///
178  /// All semantics of the corresponding function for the type apply
179  #[inline(always)]
180  #[must_use]
181  pub unsafe fn read_be_at_unchecked<T: Read>(&self, offset: usize) -> T {
182    unsafe { T::read_be_at_unchecked(self, offset) }
183  }
184
185  /// Read the next `T` in [BE-bit, BE-byte] order without performing bound checks, advancing the internal cursor
186  ///
187  /// # Safety
188  ///
189  /// All semantics of the corresponding function for the type apply
190  ///
191  /// # Panics
192  ///
193  /// All semantics of the corresponding function for the type apply
194  #[inline(always)]
195  #[must_use]
196  pub unsafe fn read_be_unchecked<T: Read>(&mut self) -> T {
197    unsafe { T::read_be_unchecked(self) }
198  }
199
200  /// Read a `T` in [BE-bit, BE-byte] order from `byte_offset` while performing bound checks
201  ///
202  /// # Errors
203  ///
204  /// All semantics of the corresponding function for the type apply
205  #[inline(always)]
206  pub fn try_read_be_aligned_at<T: Read>(&self, byte_offset: usize) -> Result<T> {
207    T::try_read_be_aligned_at(self, byte_offset)
208  }
209
210  /// Read the next `T` in [BE-bit, BE-byte] order while performing alignment and bound checks, advancing the internal cursor
211  ///
212  /// # Errors
213  ///
214  /// All semantics of the corresponding function for the type apply
215  #[inline(always)]
216  pub fn try_read_be_aligned<T: Read>(&mut self) -> Result<T> {
217    T::try_read_be_aligned(self)
218  }
219
220  /// Read a `T` in [BE-bit, BE-byte] order from `offset` while performing bound checks
221  ///
222  /// # Errors
223  ///
224  /// All semantics of the corresponding function for the type apply
225  #[inline(always)]
226  pub fn try_read_be_at<T: Read>(&self, offset: usize) -> Result<T> {
227    T::try_read_be_at(self, offset)
228  }
229
230  /// Read the next `T` in [BE-bit, BE-byte] order while performing bound checks, advancing the internal cursor
231  ///
232  /// # Errors
233  ///
234  /// All semantics of the corresponding function for the type apply
235  #[inline(always)]
236  pub fn try_read_be<T: Read>(&mut self) -> Result<T> {
237    T::try_read_be(self)
238  }
239
240  /// Read a `T` in [BE-bit, BE-byte] order from `byte_offset`, panicking on out of bounds
241  ///
242  /// # Panics
243  ///
244  /// All semantics of the corresponding function for the type apply
245  #[inline(always)]
246  #[must_use]
247  pub fn read_be_aligned_at<T: Read>(&self, byte_offset: usize) -> T {
248    T::read_be_aligned_at(self, byte_offset)
249  }
250
251  /// Read the next `T` in [BE-bit, BE-byte] order panicking on an unaligned cursor or out of bounds, advancing the internal cursor
252  ///
253  /// # Panics
254  ///
255  /// All semantics of the corresponding function for the type apply
256  #[inline(always)]
257  #[must_use]
258  pub fn read_be_aligned<T: Read>(&mut self) -> T {
259    T::read_be_aligned(self)
260  }
261
262  /// Read a `T` in [BE-bit, BE-byte] order from `offset`, panicking on out of bounds
263  ///
264  /// # Panics
265  ///
266  /// All semantics of the corresponding function for the type apply
267  #[inline(always)]
268  #[must_use]
269  pub fn read_be_at<T: Read>(&self, offset: usize) -> T {
270    T::read_be_at(self, offset)
271  }
272
273  /// Read the next `T` in [BE-bit, BE-byte] order panicking on out of bounds, advancing the internal cursor
274  ///
275  /// # Panics
276  ///
277  /// All semantics of the corresponding function for the type apply
278  #[inline(always)]
279  #[must_use]
280  pub fn read_be<T: Read>(&mut self) -> T {
281    T::read_be(self)
282  }
283}
284
285macro_rules! impl_read {
286  (
287    $ty:ident;
288    bytes = $bytes:literal;
289    bits = $bits:literal;
290    offset = $offset:literal;
291    [$($byte:ident),*];
292    [$first:ident, $([$($middle:ident),*],)? $last:ident];
293
294    $read_be_aligned_at_unchecked:ident;
295    $read_be_aligned_unchecked:ident;
296    $read_be_at_unchecked:ident;
297    $read_be_unchecked:ident;
298    $try_read_be_aligned_at:ident;
299    $try_read_be_aligned:ident;
300    $try_read_be_at:ident;
301    $try_read_be:ident;
302    $read_be_aligned_at:ident;
303    $read_be_aligned:ident;
304    $read_be_at:ident;
305    $read_be:ident;
306  ) => {
307    impl<S: Storage> BitBuf<S> {
308
309      #[doc = concat!("Read a [`", stringify!($ty), "`] in [BE-bit, BE-byte] order from `byte_offset` without performing bound checks")]
310      ///
311      /// # Safety
312      ///
313      #[doc = concat!("* This is UB if <code>byte_offset + ", stringify!($offset), " >= [self.bytes()][Self::bytes].len()</code>")]
314      ///
315      /// # Panics
316      ///
317      #[doc = concat!("* Panics in debug mode if <code>byte_offset + ", stringify!($offset), " >= [self.bytes()][Self::bytes].len()</code>")]
318      #[inline(always)]
319      #[must_use]
320      pub unsafe fn $read_be_aligned_at_unchecked(&self, byte_offset: usize) -> $ty {
321        let bytes = self.bytes();
322        let len = bytes.len();
323
324        ensure!(
325          byte_offset + $offset < len;
326
327          concat!(
328            "BitBuf::",
329            stringify!($read_be_aligned_at_unchecked),
330            ": index out of bounds! len is {}, offset is {}"
331          ),
332          len,
333          byte_offset + $offset,
334        );
335
336        unsafe {
337          $ty::from_be_bytes(
338            *bytes[byte_offset..byte_offset + $bytes]
339              .as_array()
340              .unwrap_unchecked(),
341          )
342        }
343      }
344
345      #[doc = concat!("Read the next [`", stringify!($ty), "`] in [BE-bit, BE-byte] order without performing bound checks, advancing the internal cursor")]
346      ///
347      /// # Safety
348      ///
349      /// * The internal cursor must be byte-aligned ([`self.is_aligned()`][Self::is_aligned])
350      #[doc = concat!("* This is UB if <code>[self.byte_pos()][Self::byte_pos] + ", stringify!($offset), " >= [self.bytes()][Self::bytes].len()</code>")]
351      ///
352      /// # Panics
353      ///
354      /// * Panics in debug mode if the internal cursor is not byte-aligned (<code>\![self.is_aligned()][Self::is_aligned]</code>)
355      #[doc = concat!("* Panics in debug mode if <code>[self.byte_pos()][Self::byte_pos] + ", stringify!($offset), " >= [self.bytes()][Self::bytes].len()</code>")]
356      #[inline(always)]
357      #[must_use]
358      pub unsafe fn $read_be_aligned_unchecked(&mut self) -> $ty {
359        ensure!(
360          self.is_aligned();
361
362          concat!(
363            "BitBuf::",
364            stringify!($read_be_aligned_unchecked),
365            " called at unaligned bit position: {}",
366          ),
367          self.pos(),
368        );
369
370        let v = unsafe { self.$read_be_aligned_at_unchecked(self.byte_pos()) };
371        self.advance_bytes($bytes);
372        v
373      }
374
375
376      #[doc = concat!("Read a [`", stringify!($ty), "`] in [BE-bit, BE-byte] order from `offset` without performing bound checks")]
377      ///
378      /// # Safety
379      ///
380      #[doc = concat!("* This is UB if <code>(offset / 8) + ", stringify!($offset), " >= [self.bytes()][Self::bytes].len()</code>")]
381      #[doc = concat!("* This is UB if <code>(offset % 8 != 0) && (offset / 8) + ", stringify!($bytes), " >= [self.bytes()][Self::bytes].len()</code>")]
382      ///
383      /// # Panics
384      ///
385      #[doc = concat!("* Panics in debug mode if <code>(offset / 8) + ", stringify!($offset), " >= [self.bytes()][Self::bytes].len()</code>")]
386      #[doc = concat!("* Panics in debug mode if <code>(offset % 8 != 0) && (offset / 8) + ", stringify!($bytes), " >= [self.bytes()][Self::bytes].len()</code>")]
387      #[inline(always)]
388      #[must_use]
389      pub unsafe fn $read_be_at_unchecked(&self, offset: usize) -> $ty {
390        let byte_idx = offset / 8;
391        let shift = offset % 8;
392
393        let bytes = self.bytes();
394        let len = bytes.len();
395
396        ensure!(
397          byte_idx + $offset < len;
398
399          concat!(
400            "BitBuf::",
401            stringify!($read_be_at_unchecked),
402            ": index out of bounds! len is {}, byte_idx is {}",
403          ),
404          len,
405          byte_idx + $offset,
406        );
407
408        if shift == 0 {
409          unsafe { self.$read_be_aligned_at_unchecked(byte_idx) }
410        } else {
411          ensure!(
412            byte_idx + $bytes < len;
413
414            concat!(
415              "BitBuf::",
416              stringify!($read_be_at_unchecked),
417              ": lookahead index out of bounds! len is {}, lookahead byte_idx is {}",
418            ),
419            len,
420            byte_idx + $bytes,
421          );
422
423          unsafe {
424            let ptr = bytes.as_ptr().add(byte_idx);
425            let high = $ty::from_be_bytes(*(ptr as *const [u8; $bytes]));
426            let low = *bytes.get_unchecked(byte_idx + $bytes) as $ty;
427            (high << shift) | (low >> (8 - shift))
428          }
429        }
430      }
431
432      #[doc = concat!("Read the next [`", stringify!($ty), "`] in [BE-bit, BE-byte] order without performing bound checks, advancing the internal cursor")]
433      ///
434      /// # Safety
435      ///
436      #[doc = concat!("* This is UB if <code>([self.pos()][Self::pos] / 8) + ", stringify!($offset), " >= [self.bytes()][Self::bytes].len()</code>")]
437      #[doc = concat!("* This is UB if <code>([self.pos()][Self::pos] % 8 != 0) && ([self.pos()][Self::pos] / 8) + ", stringify!($bytes), " >= [self.bytes()][Self::bytes].len()</code>")]
438      ///
439      /// # Panics
440      ///
441      #[doc = concat!("* Panics in debug mode if <code>([self.pos()][Self::pos] / 8) + ", stringify!($offset), " >= [self.bytes()][Self::bytes].len()</code>")]
442      #[doc = concat!("* Panics in debug mode if <code>([self.pos()][Self::pos] % 8 != 0) && ([self.pos()][Self::pos] / 8) + ", stringify!($bytes), " >= [self.bytes()][Self::bytes].len()</code>")]
443      #[inline(always)]
444      #[must_use]
445      pub unsafe fn $read_be_unchecked(&mut self) -> $ty {
446        let v = unsafe { self.$read_be_at_unchecked(self.pos()) };
447        self.advance_bytes($bytes);
448        v
449      }
450
451      #[doc = concat!("Read a [`", stringify!($ty), "`] in [BE-bit, BE-byte] order from `byte_offset` while performing bound checks")]
452      ///
453      /// # Errors
454      ///
455      /// * Returns [`Error::OutOfBounds`]
456      #[doc = concat!("  * if <code>byte_offset + ", stringify!($offset), " >= [self.bytes()][Self::bytes].len()</code>")]
457      #[inline(always)]
458      pub fn $try_read_be_aligned_at(&self, byte_offset: usize) -> Result<$ty> {
459        let len = self.bytes().len();
460
461        if byte_offset + $offset >= len {
462          return Err(Error::OutOfBounds);
463        }
464
465        Ok(unsafe { self.$read_be_aligned_at_unchecked(byte_offset) })
466      }
467
468      #[doc = concat!("Read the next [`", stringify!($ty), "`] in [BE-bit, BE-byte] order while performing alignment and bound checks, advancing the internal cursor")]
469      ///
470      /// # Errors
471      ///
472      /// * Returns [`Error::Unaligned`]
473      ///   * if the internal cursor is not byte-aligned (<code>\![self.is_aligned()][Self::is_aligned]</code>)
474      /// * Returns [`Error::OutOfBounds`]
475      #[doc = concat!("  * if <code>[self.byte_pos()][Self::byte_pos] + ", stringify!($offset), " >= [self.bytes()][Self::bytes].len()</code>")]
476      #[inline(always)]
477      pub fn $try_read_be_aligned(&mut self) -> Result<$ty> {
478        if !self.is_aligned() {
479          return Err(Error::Unaligned);
480        }
481
482        let v = self.$try_read_be_aligned_at(self.byte_pos())?;
483        self.advance_bytes($bytes);
484        Ok(v)
485      }
486
487      #[doc = concat!("Read a [`", stringify!($ty), "`] in [BE-bit, BE-byte] order from `offset` while performing bound checks")]
488      ///
489      /// # Errors
490      ///
491      /// * Returns [`Error::OutOfBounds`]
492      #[doc = concat!("  * if <code>(offset / 8) + ", stringify!($offset), " >= [self.bytes()][Self::bytes].len()</code>")]
493      #[doc = concat!("  * if <code>(offset % 8 != 0) && (offset / 8) + ", stringify!($bytes), " >= [self.bytes()][Self::bytes].len()</code>")]
494      #[inline(always)]
495      pub fn $try_read_be_at(&self, offset: usize) -> Result<$ty> {
496        let byte_idx = offset / 8;
497        let shift = offset % 8;
498
499        let len = self.bytes().len();
500
501        if byte_idx + $offset >= len {
502          return Err(Error::OutOfBounds);
503        }
504
505        if shift != 0 && byte_idx + $bytes >= len {
506          return Err(Error::OutOfBounds);
507        }
508
509        Ok(unsafe { self.$read_be_at_unchecked(offset) })
510      }
511
512      #[doc = concat!("Read the next [`", stringify!($ty), "`] in [BE-bit, BE-byte] order while performing bound checks, advancing the internal cursor")]
513      ///
514      /// # Errors
515      ///
516      /// * Returns [`Error::OutOfBounds`]
517      #[doc = concat!("  * if <code>([self.pos()][Self::pos] / 8) + ", stringify!($offset), " >= [self.bytes()][Self::bytes].len()</code>")]
518      #[doc = concat!("  * if <code>([self.pos()][Self::pos] % 8 != 0) && ([self.pos()][Self::pos] / 8) + ", stringify!($bytes), " >= [self.bytes()][Self::bytes].len()</code>")]
519      #[inline(always)]
520      pub fn $try_read_be(&mut self) -> Result<$ty> {
521        let v = self.$try_read_be_at(self.pos())?;
522        self.advance_bytes($bytes);
523        Ok(v)
524      }
525
526      #[doc = concat!("Read a [`", stringify!($ty), "`] in [BE-bit, BE-byte] order from `byte_offset` panicking on out of bounds")]
527      ///
528      /// # Panics
529      ///
530      #[doc = concat!("* Panics if <code>byte_offset + ", stringify!($offset), " >= [self.bytes()][Self::bytes].len()</code>")]
531      #[inline(always)]
532      #[must_use]
533      pub fn $read_be_aligned_at(&self, byte_offset: usize) -> $ty {
534        self
535          .$try_read_be_aligned_at(byte_offset)
536          .expect(concat!("BitBuf::", stringify!($read_be_aligned_at), " out of bounds"))
537      }
538
539      #[doc = concat!("Read the next [`", stringify!($ty), "`] in [BE-bit, BE-byte] order panicking on an unaligned cursor or out of bounds, advancing the internal cursor")]
540      ///
541      /// # Panics
542      ///
543      ///   * if the internal cursor is not byte-aligned (<code>\![self.is_aligned()][Self::is_aligned]</code>)
544      #[doc = concat!("  * if <code>[self.byte_pos()][Self::byte_pos] + ", stringify!($offset), " >= [self.bytes()][Self::bytes].len()</code>")]
545      #[inline(always)]
546      #[must_use]
547      pub fn $read_be_aligned(&mut self) -> $ty {
548        self
549          .$try_read_be_aligned()
550          .expect(concat!("BitBuf::", stringify!($read_be_aligned), " unaligned cursor or out of bounds"))
551      }
552
553      #[doc = concat!("Read a [`", stringify!($ty), "`] in [BE-bit, BE-byte] order from `offset` panicking on out of bounds")]
554      ///
555      /// # Panics
556      ///
557      #[doc = concat!("* Panics if <code>(offset / 8) + ", stringify!($offset), " >= [self.bytes()][Self::bytes].len()</code>")]
558      #[doc = concat!("* Panics if <code>(offset % 8 != 0) && (offset / 8) + ", stringify!($bytes), " >= [self.bytes()][Self::bytes].len()</code>")]
559      #[inline(always)]
560      #[must_use]
561      pub fn $read_be_at(&self, offset: usize) -> $ty {
562        self
563          .$try_read_be_at(offset)
564          .expect(concat!("BitBuf::", stringify!($read_be_at), " out of bounds"))
565      }
566
567      #[doc = concat!("Read the next [`", stringify!($ty), "`] in [BE-bit, BE-byte] order panicking on out of bounds, advancing the internal cursor")]
568      ///
569      /// # Panics
570      ///
571      #[doc = concat!("* Panics if <code>([self.pos()][Self::pos] / 8) + ", stringify!($offset), " >= [self.bytes()][Self::bytes].len()</code>")]
572      #[doc = concat!("* Panics if <code>([self.pos()][Self::pos] % 8 != 0) && ([self.pos()][Self::pos] / 8) + ", stringify!($bytes), " >= [self.bytes()][Self::bytes].len()</code>")]
573      #[inline(always)]
574      #[must_use]
575      pub fn $read_be(&mut self) -> $ty {
576        self
577          .$try_read_be()
578          .expect(concat!("BitBuf::", stringify!($read_be), " out of bounds"))
579      }
580    }
581
582    impl Read for $ty {
583      #[inline(always)]
584      unsafe fn read_be_aligned_at_unchecked<S: Storage>(buf: &BitBuf<S>, byte_offset: usize) -> Self {
585        unsafe { buf.$read_be_aligned_at_unchecked(byte_offset) }
586      }
587
588      #[inline(always)]
589      unsafe fn read_be_aligned_unchecked<S: Storage>(buf: &mut BitBuf<S>) -> Self {
590        unsafe { buf.$read_be_aligned_unchecked() }
591      }
592
593      #[inline(always)]
594      unsafe fn read_be_at_unchecked<S: Storage>(buf: &BitBuf<S>, offset: usize) -> Self {
595        unsafe { buf.$read_be_at_unchecked(offset) }
596      }
597
598      #[inline(always)]
599      unsafe fn read_be_unchecked<S: Storage>(buf: &mut BitBuf<S>) -> Self {
600        unsafe { buf.$read_be_unchecked() }
601      }
602
603      #[inline(always)]
604      fn try_read_be_aligned_at<S: Storage>(buf: &BitBuf<S>, byte_offset: usize) -> Result<Self> {
605        buf.$try_read_be_aligned_at(byte_offset)
606      }
607
608      #[inline(always)]
609      fn try_read_be_aligned<S: Storage>(buf: &mut BitBuf<S>) -> Result<Self> {
610        buf.$try_read_be_aligned()
611      }
612
613      #[inline(always)]
614      fn try_read_be_at<S: Storage>(buf: &BitBuf<S>, offset: usize) -> Result<Self> {
615        buf.$try_read_be_at(offset)
616      }
617
618      #[inline(always)]
619      fn try_read_be<S: Storage>(buf: &mut BitBuf<S>) -> Result<Self> {
620        buf.$try_read_be()
621      }
622
623      #[inline(always)]
624      fn read_be_aligned_at<S: Storage>(buf: &BitBuf<S>, byte_offset: usize) -> Self {
625        buf.$read_be_aligned_at(byte_offset)
626      }
627
628      #[inline(always)]
629      fn read_be_aligned<S: Storage>(buf: &mut BitBuf<S>) -> Self {
630        buf.$read_be_aligned()
631      }
632
633      #[inline(always)]
634      fn read_be_at<S: Storage>(buf: &BitBuf<S>, offset: usize) -> Self {
635        buf.$read_be_at(offset)
636      }
637
638      #[inline(always)]
639      fn read_be<S: Storage>(buf: &mut BitBuf<S>) -> Self {
640        buf.$read_be()
641      }
642    }
643  };
644}
645
646use impl_read;