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 assert!(self.remaining() >= 1);
260 let ret = self.chunk()[0] as i8;
261 self.advance(1);
262 ret
263 }
264
265 /// Gets an unsigned 16 bit integer from `self` in big-endian byte order.
266 ///
267 /// The current position is advanced by 2.
268 ///
269 /// # Examples
270 ///
271 /// ```
272 /// use ntex_bytes::Buf;
273 ///
274 /// let mut buf = &b"\x08\x09 hello"[..];
275 /// assert_eq!(0x0809, buf.get_u16());
276 /// ```
277 ///
278 /// # Panics
279 ///
280 /// This function panics if there is not enough remaining data in `self`.
281 #[inline]
282 fn get_u16(&mut self) -> u16 {
283 buf_get_impl!(self, u16::from_be_bytes);
284 }
285
286 /// Gets an unsigned 16 bit integer from `self` in little-endian byte order.
287 ///
288 /// The current position is advanced by 2.
289 ///
290 /// # Examples
291 ///
292 /// ```
293 /// use ntex_bytes::Buf;
294 ///
295 /// let mut buf = &b"\x09\x08 hello"[..];
296 /// assert_eq!(0x0809, buf.get_u16_le());
297 /// ```
298 ///
299 /// # Panics
300 ///
301 /// This function panics if there is not enough remaining data in `self`.
302 #[inline]
303 fn get_u16_le(&mut self) -> u16 {
304 buf_get_impl!(self, u16::from_le_bytes);
305 }
306
307 /// Gets a signed 16 bit integer from `self` in big-endian byte order.
308 ///
309 /// The current position is advanced by 2.
310 ///
311 /// # Examples
312 ///
313 /// ```
314 /// use ntex_bytes::Buf;
315 ///
316 /// let mut buf = &b"\x08\x09 hello"[..];
317 /// assert_eq!(0x0809, buf.get_i16());
318 /// ```
319 ///
320 /// # Panics
321 ///
322 /// This function panics if there is not enough remaining data in `self`.
323 #[inline]
324 fn get_i16(&mut self) -> i16 {
325 buf_get_impl!(self, i16::from_be_bytes);
326 }
327
328 /// Gets a signed 16 bit integer from `self` in little-endian byte order.
329 ///
330 /// The current position is advanced by 2.
331 ///
332 /// # Examples
333 ///
334 /// ```
335 /// use ntex_bytes::Buf;
336 ///
337 /// let mut buf = &b"\x09\x08 hello"[..];
338 /// assert_eq!(0x0809, buf.get_i16_le());
339 /// ```
340 ///
341 /// # Panics
342 ///
343 /// This function panics if there is not enough remaining data in `self`.
344 #[inline]
345 fn get_i16_le(&mut self) -> i16 {
346 buf_get_impl!(self, i16::from_le_bytes);
347 }
348
349 /// Gets an unsigned 32 bit integer from `self` in the big-endian byte order.
350 ///
351 /// The current position is advanced by 4.
352 ///
353 /// # Examples
354 ///
355 /// ```
356 /// use ntex_bytes::Buf;
357 ///
358 /// let mut buf = &b"\x08\x09\xA0\xA1 hello"[..];
359 /// assert_eq!(0x0809A0A1, buf.get_u32());
360 /// ```
361 ///
362 /// # Panics
363 ///
364 /// This function panics if there is not enough remaining data in `self`.
365 #[inline]
366 fn get_u32(&mut self) -> u32 {
367 buf_get_impl!(self, u32::from_be_bytes);
368 }
369
370 /// Gets an unsigned 32 bit integer from `self` in the little-endian byte order.
371 ///
372 /// The current position is advanced by 4.
373 ///
374 /// # Examples
375 ///
376 /// ```
377 /// use ntex_bytes::Buf;
378 ///
379 /// let mut buf = &b"\xA1\xA0\x09\x08 hello"[..];
380 /// assert_eq!(0x0809A0A1, buf.get_u32_le());
381 /// ```
382 ///
383 /// # Panics
384 ///
385 /// This function panics if there is not enough remaining data in `self`.
386 #[inline]
387 fn get_u32_le(&mut self) -> u32 {
388 buf_get_impl!(self, u32::from_le_bytes);
389 }
390
391 /// Gets a signed 32 bit integer from `self` in big-endian byte order.
392 ///
393 /// The current position is advanced by 4.
394 ///
395 /// # Examples
396 ///
397 /// ```
398 /// use ntex_bytes::Buf;
399 ///
400 /// let mut buf = &b"\x08\x09\xA0\xA1 hello"[..];
401 /// assert_eq!(0x0809A0A1, buf.get_i32());
402 /// ```
403 ///
404 /// # Panics
405 ///
406 /// This function panics if there is not enough remaining data in `self`.
407 #[inline]
408 fn get_i32(&mut self) -> i32 {
409 buf_get_impl!(self, i32::from_be_bytes);
410 }
411
412 /// Gets a signed 32 bit integer from `self` in little-endian byte order.
413 ///
414 /// The current position is advanced by 4.
415 ///
416 /// # Examples
417 ///
418 /// ```
419 /// use ntex_bytes::Buf;
420 ///
421 /// let mut buf = &b"\xA1\xA0\x09\x08 hello"[..];
422 /// assert_eq!(0x0809A0A1, buf.get_i32_le());
423 /// ```
424 ///
425 /// # Panics
426 ///
427 /// This function panics if there is not enough remaining data in `self`.
428 #[inline]
429 fn get_i32_le(&mut self) -> i32 {
430 buf_get_impl!(self, i32::from_le_bytes);
431 }
432
433 /// Gets an unsigned 64 bit integer from `self` in big-endian byte order.
434 ///
435 /// The current position is advanced by 8.
436 ///
437 /// # Examples
438 ///
439 /// ```
440 /// use ntex_bytes::Buf;
441 ///
442 /// let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07\x08 hello"[..];
443 /// assert_eq!(0x0102030405060708, buf.get_u64());
444 /// ```
445 ///
446 /// # Panics
447 ///
448 /// This function panics if there is not enough remaining data in `self`.
449 #[inline]
450 fn get_u64(&mut self) -> u64 {
451 buf_get_impl!(self, u64::from_be_bytes);
452 }
453
454 /// Gets an unsigned 64 bit integer from `self` in little-endian byte order.
455 ///
456 /// The current position is advanced by 8.
457 ///
458 /// # Examples
459 ///
460 /// ```
461 /// use ntex_bytes::Buf;
462 ///
463 /// let mut buf = &b"\x08\x07\x06\x05\x04\x03\x02\x01 hello"[..];
464 /// assert_eq!(0x0102030405060708, buf.get_u64_le());
465 /// ```
466 ///
467 /// # Panics
468 ///
469 /// This function panics if there is not enough remaining data in `self`.
470 #[inline]
471 fn get_u64_le(&mut self) -> u64 {
472 buf_get_impl!(self, u64::from_le_bytes);
473 }
474
475 /// Gets a signed 64 bit integer from `self` in big-endian byte order.
476 ///
477 /// The current position is advanced by 8.
478 ///
479 /// # Examples
480 ///
481 /// ```
482 /// use ntex_bytes::Buf;
483 ///
484 /// let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07\x08 hello"[..];
485 /// assert_eq!(0x0102030405060708, buf.get_i64());
486 /// ```
487 ///
488 /// # Panics
489 ///
490 /// This function panics if there is not enough remaining data in `self`.
491 #[inline]
492 fn get_i64(&mut self) -> i64 {
493 buf_get_impl!(self, i64::from_be_bytes);
494 }
495
496 /// Gets a signed 64 bit integer from `self` in little-endian byte order.
497 ///
498 /// The current position is advanced by 8.
499 ///
500 /// # Examples
501 ///
502 /// ```
503 /// use ntex_bytes::Buf;
504 ///
505 /// let mut buf = &b"\x08\x07\x06\x05\x04\x03\x02\x01 hello"[..];
506 /// assert_eq!(0x0102030405060708, buf.get_i64_le());
507 /// ```
508 ///
509 /// # Panics
510 ///
511 /// This function panics if there is not enough remaining data in `self`.
512 #[inline]
513 fn get_i64_le(&mut self) -> i64 {
514 buf_get_impl!(self, i64::from_le_bytes);
515 }
516
517 /// Gets an unsigned 128 bit integer from `self` in big-endian byte order.
518 ///
519 /// The current position is advanced by 16.
520 ///
521 /// # Examples
522 ///
523 /// ```
524 /// use ntex_bytes::Buf;
525 ///
526 /// let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16 hello"[..];
527 /// assert_eq!(0x01020304050607080910111213141516, buf.get_u128());
528 /// ```
529 ///
530 /// # Panics
531 ///
532 /// This function panics if there is not enough remaining data in `self`.
533 #[inline]
534 fn get_u128(&mut self) -> u128 {
535 buf_get_impl!(self, u128::from_be_bytes);
536 }
537
538 /// Gets an unsigned 128 bit integer from `self` in little-endian byte order.
539 ///
540 /// The current position is advanced by 16.
541 ///
542 /// # Examples
543 ///
544 /// ```
545 /// use ntex_bytes::Buf;
546 ///
547 /// let mut buf = &b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01 hello"[..];
548 /// assert_eq!(0x01020304050607080910111213141516, buf.get_u128_le());
549 /// ```
550 ///
551 /// # Panics
552 ///
553 /// This function panics if there is not enough remaining data in `self`.
554 #[inline]
555 fn get_u128_le(&mut self) -> u128 {
556 buf_get_impl!(self, u128::from_le_bytes);
557 }
558
559 /// Gets a signed 128 bit integer from `self` in big-endian byte order.
560 ///
561 /// The current position is advanced by 16.
562 ///
563 /// # Examples
564 ///
565 /// ```
566 /// use ntex_bytes::Buf;
567 ///
568 /// let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16 hello"[..];
569 /// assert_eq!(0x01020304050607080910111213141516, buf.get_i128());
570 /// ```
571 ///
572 /// # Panics
573 ///
574 /// This function panics if there is not enough remaining data in `self`.
575 #[inline]
576 fn get_i128(&mut self) -> i128 {
577 buf_get_impl!(self, i128::from_be_bytes);
578 }
579
580 /// Gets a signed 128 bit integer from `self` in little-endian byte order.
581 ///
582 /// The current position is advanced by 16.
583 ///
584 /// # Examples
585 ///
586 /// ```
587 /// use ntex_bytes::Buf;
588 ///
589 /// let mut buf = &b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01 hello"[..];
590 /// assert_eq!(0x01020304050607080910111213141516, buf.get_i128_le());
591 /// ```
592 ///
593 /// # Panics
594 ///
595 /// This function panics if there is not enough remaining data in `self`.
596 #[inline]
597 fn get_i128_le(&mut self) -> i128 {
598 buf_get_impl!(self, i128::from_le_bytes);
599 }
600
601 /// Gets an unsigned n-byte integer from `self` in big-endian byte order.
602 ///
603 /// The current position is advanced by `nbytes`.
604 ///
605 /// # Examples
606 ///
607 /// ```
608 /// use ntex_bytes::Buf;
609 ///
610 /// let mut buf = &b"\x01\x02\x03 hello"[..];
611 /// assert_eq!(0x010203, buf.get_uint(3));
612 /// ```
613 ///
614 /// # Panics
615 ///
616 /// This function panics if there is not enough remaining data in `self`.
617 #[inline]
618 fn get_uint(&mut self, nbytes: usize) -> u64 {
619 buf_get_impl!(be => self, u64, nbytes);
620 }
621
622 /// Gets an unsigned n-byte integer from `self` in little-endian byte order.
623 ///
624 /// The current position is advanced by `nbytes`.
625 ///
626 /// # Examples
627 ///
628 /// ```
629 /// use ntex_bytes::Buf;
630 ///
631 /// let mut buf = &b"\x03\x02\x01 hello"[..];
632 /// assert_eq!(0x010203, buf.get_uint_le(3));
633 /// ```
634 ///
635 /// # Panics
636 ///
637 /// This function panics if there is not enough remaining data in `self`.
638 #[inline]
639 fn get_uint_le(&mut self, nbytes: usize) -> u64 {
640 buf_get_impl!(le => self, u64, nbytes);
641 }
642
643 /// Gets a signed n-byte integer from `self` in big-endian byte order.
644 ///
645 /// The current position is advanced by `nbytes`.
646 ///
647 /// # Examples
648 ///
649 /// ```
650 /// use ntex_bytes::Buf;
651 ///
652 /// let mut buf = &b"\x01\x02\x03 hello"[..];
653 /// assert_eq!(0x010203, buf.get_int(3));
654 /// ```
655 ///
656 /// # Panics
657 ///
658 /// This function panics if there is not enough remaining data in `self`.
659 #[inline]
660 fn get_int(&mut self, nbytes: usize) -> i64 {
661 buf_get_impl!(be => self, i64, nbytes);
662 }
663
664 /// Gets a signed n-byte integer from `self` in little-endian byte order.
665 ///
666 /// The current position is advanced by `nbytes`.
667 ///
668 /// # Examples
669 ///
670 /// ```
671 /// use ntex_bytes::Buf;
672 ///
673 /// let mut buf = &b"\x03\x02\x01 hello"[..];
674 /// assert_eq!(0x010203, buf.get_int_le(3));
675 /// ```
676 ///
677 /// # Panics
678 ///
679 /// This function panics if there is not enough remaining data in `self`.
680 #[inline]
681 fn get_int_le(&mut self, nbytes: usize) -> i64 {
682 buf_get_impl!(le => self, i64, nbytes);
683 }
684
685 /// Gets an IEEE754 single-precision (4 bytes) floating point number from
686 /// `self` in big-endian byte order.
687 ///
688 /// The current position is advanced by 4.
689 ///
690 /// # Examples
691 ///
692 /// ```
693 /// use ntex_bytes::Buf;
694 ///
695 /// let mut buf = &b"\x3F\x99\x99\x9A hello"[..];
696 /// assert_eq!(1.2f32, buf.get_f32());
697 /// ```
698 ///
699 /// # Panics
700 ///
701 /// This function panics if there is not enough remaining data in `self`.
702 #[inline]
703 fn get_f32(&mut self) -> f32 {
704 f32::from_bits(Self::get_u32(self))
705 }
706
707 /// Gets an IEEE754 single-precision (4 bytes) floating point number from
708 /// `self` in little-endian byte order.
709 ///
710 /// The current position is advanced by 4.
711 ///
712 /// # Examples
713 ///
714 /// ```
715 /// use ntex_bytes::Buf;
716 ///
717 /// let mut buf = &b"\x9A\x99\x99\x3F hello"[..];
718 /// assert_eq!(1.2f32, buf.get_f32_le());
719 /// ```
720 ///
721 /// # Panics
722 ///
723 /// This function panics if there is not enough remaining data in `self`.
724 #[inline]
725 fn get_f32_le(&mut self) -> f32 {
726 f32::from_bits(Self::get_u32_le(self))
727 }
728
729 /// Gets an IEEE754 double-precision (8 bytes) floating point number from
730 /// `self` in big-endian byte order.
731 ///
732 /// The current position is advanced by 8.
733 ///
734 /// # Examples
735 ///
736 /// ```
737 /// use ntex_bytes::Buf;
738 ///
739 /// let mut buf = &b"\x3F\xF3\x33\x33\x33\x33\x33\x33 hello"[..];
740 /// assert_eq!(1.2f64, buf.get_f64());
741 /// ```
742 ///
743 /// # Panics
744 ///
745 /// This function panics if there is not enough remaining data in `self`.
746 #[inline]
747 fn get_f64(&mut self) -> f64 {
748 f64::from_bits(Self::get_u64(self))
749 }
750
751 /// Gets an IEEE754 double-precision (8 bytes) floating point number from
752 /// `self` in little-endian byte order.
753 ///
754 /// The current position is advanced by 8.
755 ///
756 /// # Examples
757 ///
758 /// ```
759 /// use ntex_bytes::Buf;
760 ///
761 /// let mut buf = &b"\x33\x33\x33\x33\x33\x33\xF3\x3F hello"[..];
762 /// assert_eq!(1.2f64, buf.get_f64_le());
763 /// ```
764 ///
765 /// # Panics
766 ///
767 /// This function panics if there is not enough remaining data in `self`.
768 #[inline]
769 fn get_f64_le(&mut self) -> f64 {
770 f64::from_bits(Self::get_u64_le(self))
771 }
772
773 /// Consumes remaining bytes inside self and returns new instance of `Bytes`
774 ///
775 /// # Examples
776 ///
777 /// ```
778 /// use ntex_bytes::{Buf};
779 ///
780 /// let bytes = "hello world".to_bytes();
781 /// assert_eq!(&bytes[..], &b"hello world"[..]);
782 /// ```
783 #[inline]
784 #[allow(clippy::wrong_self_convention)]
785 fn to_bytes(&mut self) -> crate::Bytes {
786 use super::BufMut;
787 let mut ret = crate::BytesMut::with_capacity(self.remaining());
788 ret.put(self);
789 ret.freeze()
790 }
791}
792
793impl<T: Buf + ?Sized> Buf for &mut T {
794 #[inline]
795 fn remaining(&self) -> usize {
796 (**self).remaining()
797 }
798
799 #[inline]
800 fn chunk(&self) -> &[u8] {
801 (**self).chunk()
802 }
803
804 #[inline]
805 fn advance(&mut self, cnt: usize) {
806 (**self).advance(cnt);
807 }
808}
809
810impl<T: Buf + ?Sized> Buf for Box<T> {
811 #[inline]
812 fn remaining(&self) -> usize {
813 (**self).remaining()
814 }
815
816 #[inline]
817 fn chunk(&self) -> &[u8] {
818 (**self).chunk()
819 }
820
821 fn advance(&mut self, cnt: usize) {
822 (**self).advance(cnt);
823 }
824}
825
826impl Buf for &[u8] {
827 #[inline]
828 fn remaining(&self) -> usize {
829 self.len()
830 }
831
832 #[inline]
833 fn chunk(&self) -> &[u8] {
834 self
835 }
836
837 #[inline]
838 fn advance(&mut self, cnt: usize) {
839 *self = &self[cnt..];
840 }
841}
842
843impl Buf for &str {
844 #[inline]
845 fn remaining(&self) -> usize {
846 self.len()
847 }
848
849 #[inline]
850 fn chunk(&self) -> &[u8] {
851 self.as_bytes()
852 }
853
854 #[inline]
855 fn advance(&mut self, cnt: usize) {
856 *self = &self[cnt..];
857 }
858}
859
860impl<T: AsRef<[u8]>> Buf for std::io::Cursor<T> {
861 fn remaining(&self) -> usize {
862 let len = self.get_ref().as_ref().len();
863 let pos = self.position();
864
865 if pos >= len as u64 {
866 return 0;
867 }
868
869 len - pos as usize
870 }
871
872 fn chunk(&self) -> &[u8] {
873 let len = self.get_ref().as_ref().len();
874 let pos = self.position();
875
876 if pos >= len as u64 {
877 return &[];
878 }
879
880 &self.get_ref().as_ref()[pos as usize..]
881 }
882
883 fn advance(&mut self, cnt: usize) {
884 let pos = (self.position() as usize)
885 .checked_add(cnt)
886 .expect("overflow");
887
888 assert!(pos <= self.get_ref().as_ref().len());
889 self.set_position(pos as u64);
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 #[test]
903 fn buf_tests() {
904 let mut buf = &b"a"[..];
905 assert!(buf.has_remaining());
906 buf.get_u8();
907 assert!(!buf.has_remaining());
908
909 let mut buf = &b"hello world"[..];
910 let mut dst = [0; 5];
911 buf.copy_to_slice(&mut dst);
912 assert_eq!(&b"hello"[..], &dst);
913 assert_eq!(6, buf.remaining());
914 buf.advance(1);
915 assert_eq!(Buf::chunk(&buf), &b"world"[..]);
916
917 let mut buf = &b"hello world"[..];
918 buf.advance(5);
919 let mut buf = Box::new(buf);
920 assert_eq!(buf.remaining(), 6);
921 assert_eq!(buf.chunk(), b" world");
922 buf.advance(1);
923 assert_eq!(buf.chunk(), b"world");
924
925 let mut buf = std::io::Cursor::new(b" world");
926 assert_eq!(buf.remaining(), 6);
927 assert_eq!(buf.chunk(), b" world");
928 buf.advance(1);
929 assert_eq!(buf.chunk(), b"world");
930 buf.advance(5);
931 assert_eq!(buf.remaining(), 0);
932 assert_eq!(buf.chunk(), b"");
933
934 let mut buf = &b"\x08 hello"[..];
935 assert_eq!(8, buf.get_u8());
936
937 let mut buf = &b"\x08 hello"[..];
938 assert_eq!(8, buf.get_i8());
939
940 let mut buf = &b"\x08\x09 hello"[..];
941 assert_eq!(0x0809, buf.get_u16());
942
943 let mut buf = &b"\x09\x08 hello"[..];
944 assert_eq!(0x0809, buf.get_u16_le());
945
946 let mut buf = &b"\x08\x09 hello"[..];
947 assert_eq!(0x0809, buf.get_i16());
948
949 let mut buf = &b"\x09\x08 hello"[..];
950 assert_eq!(0x0809, buf.get_i16_le());
951
952 let mut buf = &b"\x08\x09\xA0\xA1 hello"[..];
953 assert_eq!(0x0809_A0A1, buf.get_u32());
954
955 let mut buf = &b"\xA1\xA0\x09\x08 hello"[..];
956 assert_eq!(0x0809_A0A1, buf.get_u32_le());
957
958 let mut buf = &b"\x08\x09\xA0\xA1 hello"[..];
959 assert_eq!(0x0809_A0A1, buf.get_i32());
960
961 let mut buf = &b"\xA1\xA0\x09\x08 hello"[..];
962 assert_eq!(0x0809_A0A1, buf.get_i32_le());
963
964 let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07\x08 hello"[..];
965 assert_eq!(0x0102_0304_0506_0708, buf.get_u64());
966
967 let mut buf = &b"\x08\x07\x06\x05\x04\x03\x02\x01 hello"[..];
968 assert_eq!(0x0102_0304_0506_0708, buf.get_u64_le());
969
970 let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07\x08 hello"[..];
971 assert_eq!(0x0102_0304_0506_0708, buf.get_i64());
972
973 let mut buf = &b"\x08\x07\x06\x05\x04\x03\x02\x01 hello"[..];
974 assert_eq!(0x0102_0304_0506_0708, buf.get_i64_le());
975
976 let mut buf =
977 &b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16 hello"[..];
978 assert_eq!(0x0102_0304_0506_0708_0910_1112_1314_1516, buf.get_u128());
979
980 let mut buf =
981 &b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01 hello"[..];
982 assert_eq!(0x0102_0304_0506_0708_0910_1112_1314_1516, buf.get_u128_le());
983
984 let mut buf =
985 &b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16 hello"[..];
986 assert_eq!(0x0102_0304_0506_0708_0910_1112_1314_1516, buf.get_i128());
987
988 let mut buf =
989 &b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01 hello"[..];
990 assert_eq!(0x0102_0304_0506_0708_0910_1112_1314_1516, buf.get_i128_le());
991
992 let mut buf = &b"\x01\x02\x03 hello"[..];
993 assert_eq!(0x01_0203, buf.get_uint(3));
994
995 let mut buf = &b"\x03\x02\x01 hello"[..];
996 assert_eq!(0x01_0203, buf.get_uint_le(3));
997
998 let mut buf = &b"\x01\x02\x03 hello"[..];
999 assert_eq!(0x01_0203, buf.get_int(3));
1000
1001 let mut buf = &b"\x03\x02\x01 hello"[..];
1002 assert_eq!(0x01_0203, buf.get_int_le(3));
1003
1004 let mut buf = &b"\x3F\x99\x99\x9A hello"[..];
1005 assert_eq!(1.2f32, buf.get_f32());
1006
1007 let mut buf = &b"\x9A\x99\x99\x3F hello"[..];
1008 assert_eq!(1.2f32, buf.get_f32_le());
1009
1010 let mut buf = &b"\x3F\xF3\x33\x33\x33\x33\x33\x33 hello"[..];
1011 assert_eq!(1.2f64, buf.get_f64());
1012
1013 let mut buf = &b"\x33\x33\x33\x33\x33\x33\xF3\x3F hello"[..];
1014 assert_eq!(1.2f64, buf.get_f64_le());
1015
1016 let bytes = "hello world".to_bytes();
1017 assert_eq!(&bytes[..], &b"hello world"[..]);
1018 }
1019}