Skip to main content

ntex_bytes/buf/
buf_impl.rs

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