Skip to main content

ntex_bytes/buf/
buf_impl.rs

1use std::{cmp, mem};
2
3macro_rules! buf_get_impl {
4    ($this:ident, $typ:tt::$conv:tt) => {{
5        const SIZE: usize = mem::size_of::<$typ>();
6        // try to convert directly from the bytes
7        // this Option<ret> trick is to avoid keeping a borrow on self
8        // when advance() is called (mut borrow) and to call chunk() only once
9        #[allow(clippy::ptr_as_ptr)]
10        let ret = $this.chunk().get(..SIZE).map(|src| {
11            // SAFETY: `get(..SIZE)` yields exactly `SIZE` initialized bytes, aligned for a byte
12            // array.
13            unsafe { $typ::$conv(*(std::ptr::from_ref(src) as *const [_; SIZE])) }
14        });
15
16        if let Some(ret) = ret {
17            // if the direct conversion was possible, advance and return
18            $this.advance(SIZE);
19            return ret;
20        }
21        // if not we copy the bytes in a temp buffer then convert
22        let mut buf = [0; SIZE];
23        $this.copy_to_slice(&mut buf); // (do the advance)
24        return $typ::$conv(buf);
25    }};
26    (le => $this:ident, $typ:tt, $len_to_read:expr) => {{
27        debug_assert!(mem::size_of::<$typ>() >= $len_to_read);
28
29        // The same trick as above does not improve the best case speed.
30        // It seems to be linked to the way the method is optimised by the compiler
31        let mut buf = [0; (mem::size_of::<$typ>())];
32        $this.copy_to_slice(&mut buf[..($len_to_read)]);
33        return $typ::from_le_bytes(buf);
34    }};
35    (be => $this:ident, $typ:tt, $len_to_read:expr) => {{
36        debug_assert!(mem::size_of::<$typ>() >= $len_to_read);
37
38        let mut buf = [0; (mem::size_of::<$typ>())];
39        $this.copy_to_slice(&mut buf[mem::size_of::<$typ>() - ($len_to_read)..]);
40        return $typ::from_be_bytes(buf);
41    }};
42}
43
44/// Interprets the low `nbytes` bytes of `val` as a two's complement integer.
45fn sign_extend(val: u64, nbytes: usize) -> i64 {
46    if nbytes == 0 {
47        0
48    } else {
49        let shift = (8 - nbytes) * 8;
50        ((val << shift).cast_signed()) >> shift
51    }
52}
53
54/// Read bytes from a buffer.
55///
56/// A buffer stores bytes in memory such that read operations are infallible.
57/// The underlying storage may or may not be in contiguous memory. A `Buf` value
58/// is a cursor into the buffer. Reading from `Buf` advances the cursor
59/// position. It can be thought of as an efficient `Iterator` for collections of
60/// bytes.
61///
62/// The simplest `Buf` is a `&[u8]`.
63///
64/// ```
65/// use ntex_bytes::Buf;
66///
67/// let mut buf = &b"hello world"[..];
68///
69/// assert_eq!(b'h', buf.get_u8());
70/// assert_eq!(b'e', buf.get_u8());
71/// assert_eq!(b'l', buf.get_u8());
72///
73/// let mut rest = [0; 8];
74/// buf.copy_to_slice(&mut rest);
75///
76/// assert_eq!(&rest[..], &b"lo world"[..]);
77/// ```
78pub trait Buf {
79    /// Returns the number of bytes between the current position and the end of
80    /// the buffer.
81    ///
82    /// This value is greater than or equal to the length of the slice returned
83    /// by `chunk`.
84    ///
85    /// # Examples
86    ///
87    /// ```
88    /// use ntex_bytes::Buf;
89    ///
90    /// let mut buf = &b"hello world"[..];
91    ///
92    /// assert_eq!(buf.remaining(), 11);
93    ///
94    /// buf.get_u8();
95    ///
96    /// assert_eq!(buf.remaining(), 10);
97    /// ```
98    ///
99    /// # Implementer notes
100    ///
101    /// Implementations of `remaining` should ensure that the return value does
102    /// not change unless a call is made to `advance` or any other function that
103    /// is documented to change the `Buf`'s current position.
104    fn remaining(&self) -> usize;
105
106    /// Returns a slice starting at the current position and of length between 0
107    /// and `Buf::remaining()`. Note that this *can* return shorter slice (this allows
108    /// non-continuous internal representation).
109    ///
110    /// This is a lower level function. Most operations are done with other
111    /// functions.
112    ///
113    /// # Examples
114    ///
115    /// ```
116    /// use ntex_bytes::Buf;
117    ///
118    /// let mut buf = &b"hello world"[..];
119    ///
120    /// assert_eq!(buf.chunk(), &b"hello world"[..]);
121    ///
122    /// buf.advance(6);
123    ///
124    /// assert_eq!(buf.chunk(), &b"world"[..]);
125    /// ```
126    ///
127    /// # Implementer notes
128    ///
129    /// This function should never panic. Once the end of the buffer is reached,
130    /// i.e., `Buf::remaining` returns 0, calls to `chunk` should return an
131    /// empty slice.
132    fn chunk(&self) -> &[u8];
133
134    /// Advance the internal cursor of the Buf
135    ///
136    /// The next call to `chunk` will return a slice starting `cnt` bytes
137    /// further into the underlying buffer.
138    ///
139    /// # Examples
140    ///
141    /// ```
142    /// use ntex_bytes::Buf;
143    ///
144    /// let mut buf = &b"hello world"[..];
145    ///
146    /// assert_eq!(buf.chunk(), &b"hello world"[..]);
147    ///
148    /// buf.advance(6);
149    ///
150    /// assert_eq!(buf.chunk(), &b"world"[..]);
151    /// ```
152    ///
153    /// # Panics
154    ///
155    /// This function **may** panic if `cnt > self.remaining()`.
156    ///
157    /// # Implementer notes
158    ///
159    /// It is recommended for implementations of `advance` to panic if `cnt >
160    /// self.remaining()`. If the implementation does not panic, the call must
161    /// behave as if `cnt == self.remaining()`.
162    ///
163    /// A call with `cnt == 0` should never panic and be a no-op.
164    fn advance(&mut self, cnt: usize);
165
166    /// Returns true if there are any more bytes to consume
167    ///
168    /// This is equivalent to `self.remaining() != 0`.
169    ///
170    /// # Examples
171    ///
172    /// ```
173    /// use ntex_bytes::Buf;
174    ///
175    /// let mut buf = &b"a"[..];
176    ///
177    /// assert!(buf.has_remaining());
178    ///
179    /// buf.get_u8();
180    ///
181    /// assert!(!buf.has_remaining());
182    /// ```
183    fn has_remaining(&self) -> bool {
184        self.remaining() > 0
185    }
186
187    /// Copies bytes from `self` into `dst`.
188    ///
189    /// The cursor is advanced by the number of bytes copied. `self` must have
190    /// enough remaining bytes to fill `dst`.
191    ///
192    /// # Examples
193    ///
194    /// ```
195    /// use ntex_bytes::Buf;
196    ///
197    /// let mut buf = &b"hello world"[..];
198    /// let mut dst = [0; 5];
199    ///
200    /// buf.copy_to_slice(&mut dst);
201    /// assert_eq!(&b"hello"[..], &dst);
202    /// assert_eq!(6, buf.remaining());
203    /// ```
204    ///
205    /// # Panics
206    ///
207    /// This function panics if `self.remaining() < dst.len()`
208    fn copy_to_slice(&mut self, dst: &mut [u8]) {
209        let mut off = 0;
210
211        assert!(self.remaining() >= dst.len());
212
213        while off < dst.len() {
214            let src = self.chunk();
215            let cnt = cmp::min(src.len(), dst.len() - off);
216            dst[off..off + cnt].copy_from_slice(&src[..cnt]);
217            off += cnt;
218
219            self.advance(cnt);
220        }
221    }
222
223    /// Gets an unsigned 8 bit integer from `self`.
224    ///
225    /// The current position is advanced by 1.
226    ///
227    /// # Examples
228    ///
229    /// ```
230    /// use ntex_bytes::Buf;
231    ///
232    /// let mut buf = &b"\x08 hello"[..];
233    /// assert_eq!(8, buf.get_u8());
234    /// ```
235    ///
236    /// # Panics
237    ///
238    /// This function panics if there is no more remaining data in `self`.
239    #[inline]
240    fn get_u8(&mut self) -> u8 {
241        assert!(self.remaining() >= 1);
242        let ret = self.chunk()[0];
243        self.advance(1);
244        ret
245    }
246
247    /// Gets a signed 8 bit integer from `self`.
248    ///
249    /// The current position is advanced by 1.
250    ///
251    /// # Examples
252    ///
253    /// ```
254    /// use ntex_bytes::Buf;
255    ///
256    /// let mut buf = &b"\x08 hello"[..];
257    /// assert_eq!(8, buf.get_i8());
258    /// ```
259    ///
260    /// # Panics
261    ///
262    /// This function panics if there is no more remaining data in `self`.
263    #[inline]
264    fn get_i8(&mut self) -> i8 {
265        self.get_u8() as i8
266    }
267
268    /// Gets an unsigned 16 bit integer from `self` in big-endian byte order.
269    ///
270    /// The current position is advanced by 2.
271    ///
272    /// # Examples
273    ///
274    /// ```
275    /// use ntex_bytes::Buf;
276    ///
277    /// let mut buf = &b"\x08\x09 hello"[..];
278    /// assert_eq!(0x0809, buf.get_u16());
279    /// ```
280    ///
281    /// # Panics
282    ///
283    /// This function panics if there is not enough remaining data in `self`.
284    #[inline]
285    fn get_u16(&mut self) -> u16 {
286        buf_get_impl!(self, u16::from_be_bytes);
287    }
288
289    /// Gets an unsigned 16 bit integer from `self` in little-endian byte order.
290    ///
291    /// The current position is advanced by 2.
292    ///
293    /// # Examples
294    ///
295    /// ```
296    /// use ntex_bytes::Buf;
297    ///
298    /// let mut buf = &b"\x09\x08 hello"[..];
299    /// assert_eq!(0x0809, buf.get_u16_le());
300    /// ```
301    ///
302    /// # Panics
303    ///
304    /// This function panics if there is not enough remaining data in `self`.
305    #[inline]
306    fn get_u16_le(&mut self) -> u16 {
307        buf_get_impl!(self, u16::from_le_bytes);
308    }
309
310    /// Gets a signed 16 bit integer from `self` in big-endian byte order.
311    ///
312    /// The current position is advanced by 2.
313    ///
314    /// # Examples
315    ///
316    /// ```
317    /// use ntex_bytes::Buf;
318    ///
319    /// let mut buf = &b"\x08\x09 hello"[..];
320    /// assert_eq!(0x0809, buf.get_i16());
321    /// ```
322    ///
323    /// # Panics
324    ///
325    /// This function panics if there is not enough remaining data in `self`.
326    #[inline]
327    fn get_i16(&mut self) -> i16 {
328        buf_get_impl!(self, i16::from_be_bytes);
329    }
330
331    /// Gets a signed 16 bit integer from `self` in little-endian byte order.
332    ///
333    /// The current position is advanced by 2.
334    ///
335    /// # Examples
336    ///
337    /// ```
338    /// use ntex_bytes::Buf;
339    ///
340    /// let mut buf = &b"\x09\x08 hello"[..];
341    /// assert_eq!(0x0809, buf.get_i16_le());
342    /// ```
343    ///
344    /// # Panics
345    ///
346    /// This function panics if there is not enough remaining data in `self`.
347    #[inline]
348    fn get_i16_le(&mut self) -> i16 {
349        buf_get_impl!(self, i16::from_le_bytes);
350    }
351
352    /// Gets an unsigned 32 bit integer from `self` in the big-endian byte order.
353    ///
354    /// The current position is advanced by 4.
355    ///
356    /// # Examples
357    ///
358    /// ```
359    /// use ntex_bytes::Buf;
360    ///
361    /// let mut buf = &b"\x08\x09\xA0\xA1 hello"[..];
362    /// assert_eq!(0x0809A0A1, buf.get_u32());
363    /// ```
364    ///
365    /// # Panics
366    ///
367    /// This function panics if there is not enough remaining data in `self`.
368    #[inline]
369    fn get_u32(&mut self) -> u32 {
370        buf_get_impl!(self, u32::from_be_bytes);
371    }
372
373    /// Gets an unsigned 32 bit integer from `self` in the little-endian byte order.
374    ///
375    /// The current position is advanced by 4.
376    ///
377    /// # Examples
378    ///
379    /// ```
380    /// use ntex_bytes::Buf;
381    ///
382    /// let mut buf = &b"\xA1\xA0\x09\x08 hello"[..];
383    /// assert_eq!(0x0809A0A1, buf.get_u32_le());
384    /// ```
385    ///
386    /// # Panics
387    ///
388    /// This function panics if there is not enough remaining data in `self`.
389    #[inline]
390    fn get_u32_le(&mut self) -> u32 {
391        buf_get_impl!(self, u32::from_le_bytes);
392    }
393
394    /// Gets a signed 32 bit integer from `self` in big-endian byte order.
395    ///
396    /// The current position is advanced by 4.
397    ///
398    /// # Examples
399    ///
400    /// ```
401    /// use ntex_bytes::Buf;
402    ///
403    /// let mut buf = &b"\x08\x09\xA0\xA1 hello"[..];
404    /// assert_eq!(0x0809A0A1, buf.get_i32());
405    /// ```
406    ///
407    /// # Panics
408    ///
409    /// This function panics if there is not enough remaining data in `self`.
410    #[inline]
411    fn get_i32(&mut self) -> i32 {
412        buf_get_impl!(self, i32::from_be_bytes);
413    }
414
415    /// Gets a signed 32 bit integer from `self` in little-endian byte order.
416    ///
417    /// The current position is advanced by 4.
418    ///
419    /// # Examples
420    ///
421    /// ```
422    /// use ntex_bytes::Buf;
423    ///
424    /// let mut buf = &b"\xA1\xA0\x09\x08 hello"[..];
425    /// assert_eq!(0x0809A0A1, buf.get_i32_le());
426    /// ```
427    ///
428    /// # Panics
429    ///
430    /// This function panics if there is not enough remaining data in `self`.
431    #[inline]
432    fn get_i32_le(&mut self) -> i32 {
433        buf_get_impl!(self, i32::from_le_bytes);
434    }
435
436    /// Gets an unsigned 64 bit integer from `self` in big-endian byte order.
437    ///
438    /// The current position is advanced by 8.
439    ///
440    /// # Examples
441    ///
442    /// ```
443    /// use ntex_bytes::Buf;
444    ///
445    /// let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07\x08 hello"[..];
446    /// assert_eq!(0x0102030405060708, buf.get_u64());
447    /// ```
448    ///
449    /// # Panics
450    ///
451    /// This function panics if there is not enough remaining data in `self`.
452    #[inline]
453    fn get_u64(&mut self) -> u64 {
454        buf_get_impl!(self, u64::from_be_bytes);
455    }
456
457    /// Gets an unsigned 64 bit integer from `self` in little-endian byte order.
458    ///
459    /// The current position is advanced by 8.
460    ///
461    /// # Examples
462    ///
463    /// ```
464    /// use ntex_bytes::Buf;
465    ///
466    /// let mut buf = &b"\x08\x07\x06\x05\x04\x03\x02\x01 hello"[..];
467    /// assert_eq!(0x0102030405060708, buf.get_u64_le());
468    /// ```
469    ///
470    /// # Panics
471    ///
472    /// This function panics if there is not enough remaining data in `self`.
473    #[inline]
474    fn get_u64_le(&mut self) -> u64 {
475        buf_get_impl!(self, u64::from_le_bytes);
476    }
477
478    /// Gets a signed 64 bit integer from `self` in big-endian byte order.
479    ///
480    /// The current position is advanced by 8.
481    ///
482    /// # Examples
483    ///
484    /// ```
485    /// use ntex_bytes::Buf;
486    ///
487    /// let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07\x08 hello"[..];
488    /// assert_eq!(0x0102030405060708, buf.get_i64());
489    /// ```
490    ///
491    /// # Panics
492    ///
493    /// This function panics if there is not enough remaining data in `self`.
494    #[inline]
495    fn get_i64(&mut self) -> i64 {
496        buf_get_impl!(self, i64::from_be_bytes);
497    }
498
499    /// Gets a signed 64 bit integer from `self` in little-endian byte order.
500    ///
501    /// The current position is advanced by 8.
502    ///
503    /// # Examples
504    ///
505    /// ```
506    /// use ntex_bytes::Buf;
507    ///
508    /// let mut buf = &b"\x08\x07\x06\x05\x04\x03\x02\x01 hello"[..];
509    /// assert_eq!(0x0102030405060708, buf.get_i64_le());
510    /// ```
511    ///
512    /// # Panics
513    ///
514    /// This function panics if there is not enough remaining data in `self`.
515    #[inline]
516    fn get_i64_le(&mut self) -> i64 {
517        buf_get_impl!(self, i64::from_le_bytes);
518    }
519
520    /// Gets an unsigned 128 bit integer from `self` in big-endian byte order.
521    ///
522    /// The current position is advanced by 16.
523    ///
524    /// # Examples
525    ///
526    /// ```
527    /// use ntex_bytes::Buf;
528    ///
529    /// let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16 hello"[..];
530    /// assert_eq!(0x01020304050607080910111213141516, buf.get_u128());
531    /// ```
532    ///
533    /// # Panics
534    ///
535    /// This function panics if there is not enough remaining data in `self`.
536    #[inline]
537    fn get_u128(&mut self) -> u128 {
538        buf_get_impl!(self, u128::from_be_bytes);
539    }
540
541    /// Gets an unsigned 128 bit integer from `self` in little-endian byte order.
542    ///
543    /// The current position is advanced by 16.
544    ///
545    /// # Examples
546    ///
547    /// ```
548    /// use ntex_bytes::Buf;
549    ///
550    /// let mut buf = &b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01 hello"[..];
551    /// assert_eq!(0x01020304050607080910111213141516, buf.get_u128_le());
552    /// ```
553    ///
554    /// # Panics
555    ///
556    /// This function panics if there is not enough remaining data in `self`.
557    #[inline]
558    fn get_u128_le(&mut self) -> u128 {
559        buf_get_impl!(self, u128::from_le_bytes);
560    }
561
562    /// Gets a signed 128 bit integer from `self` in big-endian byte order.
563    ///
564    /// The current position is advanced by 16.
565    ///
566    /// # Examples
567    ///
568    /// ```
569    /// use ntex_bytes::Buf;
570    ///
571    /// let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16 hello"[..];
572    /// assert_eq!(0x01020304050607080910111213141516, buf.get_i128());
573    /// ```
574    ///
575    /// # Panics
576    ///
577    /// This function panics if there is not enough remaining data in `self`.
578    #[inline]
579    fn get_i128(&mut self) -> i128 {
580        buf_get_impl!(self, i128::from_be_bytes);
581    }
582
583    /// Gets a signed 128 bit integer from `self` in little-endian byte order.
584    ///
585    /// The current position is advanced by 16.
586    ///
587    /// # Examples
588    ///
589    /// ```
590    /// use ntex_bytes::Buf;
591    ///
592    /// let mut buf = &b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01 hello"[..];
593    /// assert_eq!(0x01020304050607080910111213141516, buf.get_i128_le());
594    /// ```
595    ///
596    /// # Panics
597    ///
598    /// This function panics if there is not enough remaining data in `self`.
599    #[inline]
600    fn get_i128_le(&mut self) -> i128 {
601        buf_get_impl!(self, i128::from_le_bytes);
602    }
603
604    /// Gets an unsigned n-byte integer from `self` in big-endian byte order.
605    ///
606    /// The current position is advanced by `nbytes`.
607    ///
608    /// # Examples
609    ///
610    /// ```
611    /// use ntex_bytes::Buf;
612    ///
613    /// let mut buf = &b"\x01\x02\x03 hello"[..];
614    /// assert_eq!(0x010203, buf.get_uint(3));
615    /// ```
616    ///
617    /// # Panics
618    ///
619    /// This function panics if there is not enough remaining data in `self`,
620    /// or if `nbytes > 8`.
621    #[inline]
622    fn get_uint(&mut self, nbytes: usize) -> u64 {
623        buf_get_impl!(be => self, u64, nbytes);
624    }
625
626    /// Gets an unsigned n-byte integer from `self` in little-endian byte order.
627    ///
628    /// The current position is advanced by `nbytes`.
629    ///
630    /// # Examples
631    ///
632    /// ```
633    /// use ntex_bytes::Buf;
634    ///
635    /// let mut buf = &b"\x03\x02\x01 hello"[..];
636    /// assert_eq!(0x010203, buf.get_uint_le(3));
637    /// ```
638    ///
639    /// # Panics
640    ///
641    /// This function panics if there is not enough remaining data in `self`,
642    /// or if `nbytes > 8`.
643    #[inline]
644    fn get_uint_le(&mut self, nbytes: usize) -> u64 {
645        buf_get_impl!(le => self, u64, nbytes);
646    }
647
648    /// Gets a signed n-byte integer from `self` in big-endian byte order.
649    ///
650    /// The current position is advanced by `nbytes`.
651    ///
652    /// # Examples
653    ///
654    /// ```
655    /// use ntex_bytes::Buf;
656    ///
657    /// let mut buf = &b"\x01\x02\x03\xff\xfe"[..];
658    /// assert_eq!(0x010203, buf.get_int(3));
659    /// assert_eq!(-2, buf.get_int(2));
660    /// ```
661    ///
662    /// # Panics
663    ///
664    /// This function panics if there is not enough remaining data in `self`,
665    /// or if `nbytes > 8`.
666    #[inline]
667    fn get_int(&mut self, nbytes: usize) -> i64 {
668        sign_extend(self.get_uint(nbytes), nbytes)
669    }
670
671    /// Gets a signed n-byte integer from `self` in little-endian byte order.
672    ///
673    /// The current position is advanced by `nbytes`.
674    ///
675    /// # Examples
676    ///
677    /// ```
678    /// use ntex_bytes::Buf;
679    ///
680    /// let mut buf = &b"\x03\x02\x01\xfe\xff"[..];
681    /// assert_eq!(0x010203, buf.get_int_le(3));
682    /// assert_eq!(-2, buf.get_int_le(2));
683    /// ```
684    ///
685    /// # Panics
686    ///
687    /// This function panics if there is not enough remaining data in `self`,
688    /// or if `nbytes > 8`.
689    #[inline]
690    fn get_int_le(&mut self, nbytes: usize) -> i64 {
691        sign_extend(self.get_uint_le(nbytes), nbytes)
692    }
693
694    /// Gets an IEEE754 single-precision (4 bytes) floating point number from
695    /// `self` in big-endian byte order.
696    ///
697    /// The current position is advanced by 4.
698    ///
699    /// # Examples
700    ///
701    /// ```
702    /// use ntex_bytes::Buf;
703    ///
704    /// let mut buf = &b"\x3F\x99\x99\x9A hello"[..];
705    /// assert_eq!(1.2f32, buf.get_f32());
706    /// ```
707    ///
708    /// # Panics
709    ///
710    /// This function panics if there is not enough remaining data in `self`.
711    #[inline]
712    fn get_f32(&mut self) -> f32 {
713        f32::from_bits(Self::get_u32(self))
714    }
715
716    /// Gets an IEEE754 single-precision (4 bytes) floating point number from
717    /// `self` in little-endian byte order.
718    ///
719    /// The current position is advanced by 4.
720    ///
721    /// # Examples
722    ///
723    /// ```
724    /// use ntex_bytes::Buf;
725    ///
726    /// let mut buf = &b"\x9A\x99\x99\x3F hello"[..];
727    /// assert_eq!(1.2f32, buf.get_f32_le());
728    /// ```
729    ///
730    /// # Panics
731    ///
732    /// This function panics if there is not enough remaining data in `self`.
733    #[inline]
734    fn get_f32_le(&mut self) -> f32 {
735        f32::from_bits(Self::get_u32_le(self))
736    }
737
738    /// Gets an IEEE754 double-precision (8 bytes) floating point number from
739    /// `self` in big-endian byte order.
740    ///
741    /// The current position is advanced by 8.
742    ///
743    /// # Examples
744    ///
745    /// ```
746    /// use ntex_bytes::Buf;
747    ///
748    /// let mut buf = &b"\x3F\xF3\x33\x33\x33\x33\x33\x33 hello"[..];
749    /// assert_eq!(1.2f64, buf.get_f64());
750    /// ```
751    ///
752    /// # Panics
753    ///
754    /// This function panics if there is not enough remaining data in `self`.
755    #[inline]
756    fn get_f64(&mut self) -> f64 {
757        f64::from_bits(Self::get_u64(self))
758    }
759
760    /// Gets an IEEE754 double-precision (8 bytes) floating point number from
761    /// `self` in little-endian byte order.
762    ///
763    /// The current position is advanced by 8.
764    ///
765    /// # Examples
766    ///
767    /// ```
768    /// use ntex_bytes::Buf;
769    ///
770    /// let mut buf = &b"\x33\x33\x33\x33\x33\x33\xF3\x3F hello"[..];
771    /// assert_eq!(1.2f64, buf.get_f64_le());
772    /// ```
773    ///
774    /// # Panics
775    ///
776    /// This function panics if there is not enough remaining data in `self`.
777    #[inline]
778    fn get_f64_le(&mut self) -> f64 {
779        f64::from_bits(Self::get_u64_le(self))
780    }
781
782    /// Consumes remaining bytes inside self and returns new instance of `Bytes`
783    ///
784    /// # Examples
785    ///
786    /// ```
787    /// use ntex_bytes::{Buf};
788    ///
789    /// let bytes = (&b"hello world"[..]).to_bytes();
790    /// assert_eq!(&bytes[..], &b"hello world"[..]);
791    /// ```
792    #[inline]
793    #[allow(clippy::wrong_self_convention)]
794    fn to_bytes(&mut self) -> crate::Bytes {
795        use super::BufMut;
796        let mut ret = crate::BytesMut::with_capacity(self.remaining());
797        ret.put(self);
798        ret.freeze()
799    }
800}
801
802impl<T: Buf + ?Sized> Buf for &mut T {
803    #[inline]
804    fn remaining(&self) -> usize {
805        (**self).remaining()
806    }
807
808    #[inline]
809    fn chunk(&self) -> &[u8] {
810        (**self).chunk()
811    }
812
813    #[inline]
814    fn advance(&mut self, cnt: usize) {
815        (**self).advance(cnt);
816    }
817}
818
819impl<T: Buf + ?Sized> Buf for Box<T> {
820    #[inline]
821    fn remaining(&self) -> usize {
822        (**self).remaining()
823    }
824
825    #[inline]
826    fn chunk(&self) -> &[u8] {
827        (**self).chunk()
828    }
829
830    fn advance(&mut self, cnt: usize) {
831        (**self).advance(cnt);
832    }
833}
834
835impl Buf for &[u8] {
836    #[inline]
837    fn remaining(&self) -> usize {
838        self.len()
839    }
840
841    #[inline]
842    fn chunk(&self) -> &[u8] {
843        self
844    }
845
846    #[inline]
847    fn advance(&mut self, cnt: usize) {
848        *self = &self[cnt..];
849    }
850
851    #[inline]
852    fn get_u8(&mut self) -> u8 {
853        let ret = self[0];
854        self.advance(1);
855        ret
856    }
857}
858
859impl<T: AsRef<[u8]>> Buf for std::io::Cursor<T> {
860    fn remaining(&self) -> usize {
861        let len = self.get_ref().as_ref().len();
862        let pos = self.position();
863
864        if pos >= len as u64 {
865            return 0;
866        }
867
868        len - pos as usize
869    }
870
871    fn chunk(&self) -> &[u8] {
872        let len = self.get_ref().as_ref().len();
873        let pos = self.position();
874
875        if pos >= len as u64 {
876            return &[];
877        }
878
879        &self.get_ref().as_ref()[pos as usize..]
880    }
881
882    fn advance(&mut self, cnt: usize) {
883        if cnt == 0 {
884            return;
885        }
886        let pos = self.position().checked_add(cnt as u64).expect("overflow");
887
888        assert!(pos <= self.get_ref().as_ref().len() as u64);
889        self.set_position(pos);
890    }
891}
892
893// The existence of this function makes the compiler catch if the Buf
894// trait is "object-safe" or not.
895fn _assert_trait_object(_b: &dyn Buf) {}
896
897#[cfg(test)]
898#[allow(clippy::float_cmp)]
899mod tests {
900    use super::*;
901
902    /// STATEMENT: `Buf` reads consume the expected bytes and decode numeric values in the requested byte order.
903    ///
904    /// HOW:
905    /// - Copy and advance slices, boxed slices, and cursors, checking remaining chunks and exhausted states.
906    /// - Decode signed and unsigned integers, variable-width integers, and floats in both byte orders and convert a slice to `Bytes`.
907    #[test]
908    fn buf_tests() {
909        let mut buf = &b"a"[..];
910        assert!(buf.has_remaining());
911        buf.get_u8();
912        assert!(!buf.has_remaining());
913
914        let mut buf = &b"hello world"[..];
915        let mut dst = [0; 5];
916        buf.copy_to_slice(&mut dst);
917        assert_eq!(&b"hello"[..], &dst);
918        assert_eq!(6, buf.remaining());
919        buf.advance(1);
920        assert_eq!(Buf::chunk(&buf), &b"world"[..]);
921        assert_eq!(buf.get_u8(), b'w');
922        assert_eq!(Buf::chunk(&buf), &b"orld"[..]);
923
924        let mut buf = &b"hello world"[..];
925        buf.advance(5);
926        let mut buf = Box::new(buf);
927        assert_eq!(buf.remaining(), 6);
928        assert_eq!(buf.chunk(), b" world");
929        buf.advance(1);
930        assert_eq!(buf.chunk(), b"world");
931
932        let mut buf = std::io::Cursor::new(b" world");
933        assert_eq!(buf.remaining(), 6);
934        assert_eq!(buf.chunk(), b" world");
935        buf.advance(1);
936        assert_eq!(buf.chunk(), b"world");
937        buf.advance(5);
938        assert_eq!(buf.remaining(), 0);
939        assert_eq!(buf.chunk(), b"");
940
941        let mut buf = &b"\x08 hello"[..];
942        assert_eq!(8, buf.get_u8());
943
944        let mut buf = &b"\x08 hello"[..];
945        assert_eq!(8, buf.get_i8());
946
947        let mut buf = &b"\x08\x09 hello"[..];
948        assert_eq!(0x0809, buf.get_u16());
949
950        let mut buf = &b"\x09\x08 hello"[..];
951        assert_eq!(0x0809, buf.get_u16_le());
952
953        let mut buf = &b"\x08\x09 hello"[..];
954        assert_eq!(0x0809, buf.get_i16());
955
956        let mut buf = &b"\x09\x08 hello"[..];
957        assert_eq!(0x0809, buf.get_i16_le());
958
959        let mut buf = &b"\x08\x09\xA0\xA1 hello"[..];
960        assert_eq!(0x0809_A0A1, buf.get_u32());
961
962        let mut buf = &b"\xA1\xA0\x09\x08 hello"[..];
963        assert_eq!(0x0809_A0A1, buf.get_u32_le());
964
965        let mut buf = &b"\x08\x09\xA0\xA1 hello"[..];
966        assert_eq!(0x0809_A0A1, buf.get_i32());
967
968        let mut buf = &b"\xA1\xA0\x09\x08 hello"[..];
969        assert_eq!(0x0809_A0A1, buf.get_i32_le());
970
971        let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07\x08 hello"[..];
972        assert_eq!(0x0102_0304_0506_0708, buf.get_u64());
973
974        let mut buf = &b"\x08\x07\x06\x05\x04\x03\x02\x01 hello"[..];
975        assert_eq!(0x0102_0304_0506_0708, buf.get_u64_le());
976
977        let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07\x08 hello"[..];
978        assert_eq!(0x0102_0304_0506_0708, buf.get_i64());
979
980        let mut buf = &b"\x08\x07\x06\x05\x04\x03\x02\x01 hello"[..];
981        assert_eq!(0x0102_0304_0506_0708, buf.get_i64_le());
982
983        let mut buf =
984            &b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16 hello"[..];
985        assert_eq!(0x0102_0304_0506_0708_0910_1112_1314_1516, buf.get_u128());
986
987        let mut buf =
988            &b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01 hello"[..];
989        assert_eq!(0x0102_0304_0506_0708_0910_1112_1314_1516, buf.get_u128_le());
990
991        let mut buf =
992            &b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16 hello"[..];
993        assert_eq!(0x0102_0304_0506_0708_0910_1112_1314_1516, buf.get_i128());
994
995        let mut buf =
996            &b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01 hello"[..];
997        assert_eq!(0x0102_0304_0506_0708_0910_1112_1314_1516, buf.get_i128_le());
998
999        let mut buf = &b"\x01\x02\x03 hello"[..];
1000        assert_eq!(0x01_0203, buf.get_uint(3));
1001
1002        let mut buf = &b"\x03\x02\x01 hello"[..];
1003        assert_eq!(0x01_0203, buf.get_uint_le(3));
1004
1005        let mut buf = &b"\x01\x02\x03 hello"[..];
1006        assert_eq!(0x01_0203, buf.get_int(3));
1007
1008        let mut buf = &b"\x03\x02\x01 hello"[..];
1009        assert_eq!(0x01_0203, buf.get_int_le(3));
1010
1011        let mut buf = &b"\x3F\x99\x99\x9A hello"[..];
1012        assert_eq!(1.2f32, buf.get_f32());
1013
1014        let mut buf = &b"\x9A\x99\x99\x3F hello"[..];
1015        assert_eq!(1.2f32, buf.get_f32_le());
1016
1017        let mut buf = &b"\x3F\xF3\x33\x33\x33\x33\x33\x33 hello"[..];
1018        assert_eq!(1.2f64, buf.get_f64());
1019
1020        let mut buf = &b"\x33\x33\x33\x33\x33\x33\xF3\x3F hello"[..];
1021        assert_eq!(1.2f64, buf.get_f64_le());
1022
1023        let bytes = (&b"hello world"[..]).to_bytes();
1024        assert_eq!(&bytes[..], &b"hello world"[..]);
1025    }
1026
1027    /// STATEMENT: A cursor positioned beyond its input is empty and permits zero advancement without moving.
1028    ///
1029    /// HOW:
1030    /// - Set a cursor over `abc` to position ten, check empty remaining data, advance zero, and verify position ten remains.
1031    #[test]
1032    fn cursor_advance_past_end() {
1033        let mut buf = std::io::Cursor::new(b"abc");
1034        buf.set_position(10);
1035        assert_eq!(buf.remaining(), 0);
1036        assert_eq!(buf.chunk(), b"");
1037        buf.advance(0);
1038        assert_eq!(buf.position(), 10);
1039    }
1040
1041    /// STATEMENT: Advancing an out-of-range high cursor position panics instead of wrapping to a valid offset.
1042    ///
1043    /// HOW:
1044    /// - Position a cursor over `abc` at `(1u64 << 32) + 1`, advance one, and expect an assertion failure.
1045    #[test]
1046    #[should_panic(expected = "assertion failed")]
1047    fn cursor_advance_high_position() {
1048        // must not wrap to a valid offset on 32-bit targets
1049        let mut buf = std::io::Cursor::new(b"abc");
1050        buf.set_position((1u64 << 32) + 1);
1051        buf.advance(1);
1052    }
1053
1054    struct Chunks(Vec<&'static [u8]>);
1055
1056    impl Buf for Chunks {
1057        fn remaining(&self) -> usize {
1058            self.0.iter().map(|c| c.len()).sum()
1059        }
1060
1061        fn chunk(&self) -> &[u8] {
1062            self.0.first().copied().unwrap_or_default()
1063        }
1064
1065        fn advance(&mut self, mut cnt: usize) {
1066            while cnt > 0 {
1067                let n = cnt.min(self.0[0].len());
1068                self.0[0] = &self.0[0][n..];
1069                if self.0[0].is_empty() {
1070                    self.0.remove(0);
1071                }
1072                cnt -= n;
1073            }
1074        }
1075    }
1076
1077    /// STATEMENT: Default `Buf` byte reads work across separate chunks and report exhaustion.
1078    ///
1079    /// HOW:
1080    /// - Read `a`, `b`, and `c` from `Chunks` containing `a` and `bc`, then verify `has_remaining` is false.
1081    #[test]
1082    fn default_methods() {
1083        let mut buf = Chunks(vec![b"a", b"bc"]);
1084        assert_eq!(buf.get_u8(), b'a');
1085        assert_eq!(buf.get_u8(), b'b');
1086        assert_eq!(buf.get_u8(), b'c');
1087        assert!(!buf.has_remaining());
1088    }
1089}