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