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