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