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}