ntex_bytes/buf/buf_mut.rs
1use std::{cmp, mem};
2
3use super::UninitSlice;
4
5/// Generates the fixed-width integer `put_*` methods of `BufMut`, with docs.
6macro_rules! put_int_impl {
7 ($($name:ident, $ty:ty, $conv:ident, $what:literal, $order:literal, $size:literal, $val:literal, $bytes:literal;)*) => {$(
8 #[doc = concat!("Writes ", $what, " to `self` in ", $order, " byte order.")]
9 ///
10 #[doc = concat!("The current position is advanced by ", $size, ".")]
11 ///
12 /// # Examples
13 ///
14 /// ```
15 /// use ntex_bytes::BufMut;
16 ///
17 /// let mut buf = vec![];
18 #[doc = concat!("buf.", stringify!($name), "(", $val, ");")]
19 #[doc = concat!("assert_eq!(buf, b\"", $bytes, "\");")]
20 /// ```
21 ///
22 /// # Panics
23 ///
24 /// This function panics if there is not enough remaining capacity in
25 /// `self`.
26 #[inline]
27 fn $name(&mut self, n: $ty) {
28 self.put_slice(&n.$conv());
29 }
30 )*};
31}
32/// A trait for values that provide sequential write access to bytes.
33///
34/// A buffer stores bytes in memory such that write operations are infallible.
35/// The underlying storage may or may not be in contiguous memory. A `BufMut`
36/// value is a cursor into the buffer. Writing to `BufMut` advances the cursor
37/// position.
38///
39/// Fixed-size buffers such as `&mut [u8]` panic when a write does not fit.
40/// Growable buffers such as `Vec<u8>`, [`BytesMut`](crate::BytesMut) and
41/// [`BytePages`](crate::BytePages) allocate more space on demand instead, so
42/// the `put_*` methods never run out of capacity for them.
43///
44/// The simplest `BufMut` is a `Vec<u8>`.
45///
46/// ```
47/// use ntex_bytes::BufMut;
48///
49/// let mut buf = vec![];
50///
51/// buf.put("hello world");
52///
53/// assert_eq!(buf, b"hello world");
54/// ```
55pub trait BufMut {
56 /// Returns the number of bytes that can be written from the current
57 /// position until the end of the buffer is reached.
58 ///
59 /// This value is greater than or equal to the length of the slice returned
60 /// by `chunk_mut`.
61 ///
62 /// # Examples
63 ///
64 /// ```
65 /// use ntex_bytes::BufMut;
66 ///
67 /// let mut dst = [0; 10];
68 /// let mut buf = &mut dst[..];
69 ///
70 /// let original_remaining = buf.remaining_mut();
71 /// buf.put("hello");
72 ///
73 /// assert_eq!(original_remaining - 5, buf.remaining_mut());
74 /// ```
75 ///
76 /// # Implementer notes
77 ///
78 /// Implementations of `remaining_mut` should ensure that the return value
79 /// does not change unless a call is made to `advance_mut` or any other
80 /// function that is documented to change the `BufMut`'s current position.
81 fn remaining_mut(&self) -> usize;
82
83 /// Advance the internal cursor of the `BufMut`
84 ///
85 /// The next call to `chunk_mut` will return a slice starting `cnt` bytes
86 /// further into the underlying buffer.
87 ///
88 /// # Safety
89 ///
90 /// The caller must ensure that the `cnt` bytes being advanced past have
91 /// been initialized.
92 ///
93 /// # Examples
94 ///
95 /// ```
96 /// use ntex_bytes::BufMut;
97 ///
98 /// let mut buf = Vec::with_capacity(16);
99 ///
100 /// unsafe {
101 /// buf.chunk_mut()[0..2].copy_from_slice(b"he");
102 /// buf.advance_mut(2);
103 ///
104 /// buf.chunk_mut()[0..3].copy_from_slice(b"llo");
105 /// buf.advance_mut(3);
106 /// }
107 ///
108 /// assert_eq!(5, buf.len());
109 /// assert_eq!(buf, b"hello");
110 /// ```
111 ///
112 /// # Panics
113 ///
114 /// This function **may** panic if `cnt > self.remaining_mut()`.
115 ///
116 /// # Implementer notes
117 ///
118 /// It is recommended for implementations of `advance_mut` to panic if
119 /// `cnt > self.remaining_mut()`. If the implementation does not panic,
120 /// the call must behave as if `cnt == self.remaining_mut()`.
121 ///
122 /// A call with `cnt == 0` should never panic and be a no-op.
123 unsafe fn advance_mut(&mut self, cnt: usize);
124
125 /// Returns true if there is space in `self` for more bytes.
126 ///
127 /// This is equivalent to `self.remaining_mut() != 0`.
128 ///
129 /// # Examples
130 ///
131 /// ```
132 /// use ntex_bytes::BufMut;
133 ///
134 /// let mut dst = [0; 5];
135 /// let mut buf = &mut dst[..];
136 ///
137 /// assert!(buf.has_remaining_mut());
138 ///
139 /// buf.put("hello");
140 ///
141 /// assert!(!buf.has_remaining_mut());
142 /// ```
143 #[inline]
144 fn has_remaining_mut(&self) -> bool {
145 self.remaining_mut() > 0
146 }
147
148 /// Returns a mutable slice starting at the current `BufMut` position and of
149 /// length between 0 and `BufMut::remaining_mut()`. Note that this *can* be shorter than the
150 /// whole remainder of the buffer (this allows non-continuous implementation).
151 ///
152 /// This is a lower level function. Most operations are done with other
153 /// functions.
154 ///
155 /// The returned byte slice may represent uninitialized memory.
156 ///
157 /// # Examples
158 ///
159 /// ```
160 /// use ntex_bytes::BufMut;
161 ///
162 /// let mut buf = Vec::with_capacity(16);
163 ///
164 /// unsafe {
165 /// buf.chunk_mut()[0..2].copy_from_slice(b"he");
166 ///
167 /// buf.advance_mut(2);
168 ///
169 /// buf.chunk_mut()[0..3].copy_from_slice(b"llo");
170 ///
171 /// buf.advance_mut(3);
172 /// }
173 ///
174 /// assert_eq!(5, buf.len());
175 /// assert_eq!(buf, b"hello");
176 /// ```
177 ///
178 /// # Implementer notes
179 ///
180 /// This function should never panic. `chunk_mut` should return an empty
181 /// slice **if and only if** `remaining_mut` returns 0. In other words,
182 /// `chunk_mut` returning an empty slice implies that `remaining_mut` will
183 /// return 0 and `remaining_mut` returning 0 implies that `chunk_mut` will
184 /// return an empty slice.
185 fn chunk_mut(&mut self) -> &mut UninitSlice;
186
187 /// Transfer bytes into `self` from `src` and advance the cursor by the
188 /// number of bytes written.
189 ///
190 /// # Examples
191 ///
192 /// ```
193 /// use ntex_bytes::BufMut;
194 ///
195 /// let mut buf = vec![];
196 ///
197 /// buf.put_u8(b'h');
198 /// buf.put(&b"ello"[..]);
199 /// buf.put(" world");
200 ///
201 /// assert_eq!(buf, b"hello world");
202 /// ```
203 ///
204 /// # Panics
205 ///
206 /// Panics if `self` does not have enough capacity to contain `src`.
207 fn put<T: super::Buf>(&mut self, mut src: T)
208 where
209 Self: Sized,
210 {
211 while src.has_remaining() {
212 let s = src.chunk();
213 let l = s.len();
214 self.put_slice(s);
215 src.advance(l);
216 }
217 }
218
219 /// Transfer bytes into `self` from `src` and advance the cursor by the
220 /// number of bytes written.
221 ///
222 /// `self` must have enough remaining capacity to contain all of `src`.
223 ///
224 /// ```
225 /// use ntex_bytes::BufMut;
226 ///
227 /// let mut dst = [0; 6];
228 ///
229 /// {
230 /// let mut buf = &mut dst[..];
231 /// buf.put_slice(b"hello");
232 ///
233 /// assert_eq!(1, buf.remaining_mut());
234 /// }
235 ///
236 /// assert_eq!(b"hello\0", &dst);
237 /// ```
238 fn put_slice(&mut self, src: &[u8]) {
239 let mut off = 0;
240
241 assert!(self.remaining_mut() >= src.len(), "buffer overflow");
242
243 while off < src.len() {
244 let dst = self.chunk_mut();
245 let cnt = cmp::min(dst.len(), src.len() - off);
246 dst[..cnt].copy_from_slice(&src[off..off + cnt]);
247 off += cnt;
248
249 unsafe {
250 self.advance_mut(cnt);
251 }
252 }
253 }
254
255 /// Writes an unsigned 8 bit integer to `self`.
256 ///
257 /// The current position is advanced by 1.
258 ///
259 /// # Examples
260 ///
261 /// ```
262 /// use ntex_bytes::BufMut;
263 ///
264 /// let mut buf = vec![];
265 /// buf.put_u8(0x01);
266 /// assert_eq!(buf, b"\x01");
267 /// ```
268 ///
269 /// # Panics
270 ///
271 /// This function panics if there is not enough remaining capacity in
272 /// `self`.
273 #[inline]
274 fn put_u8(&mut self, n: u8) {
275 let src = [n];
276 self.put_slice(&src);
277 }
278
279 /// Writes a signed 8 bit integer to `self`.
280 ///
281 /// The current position is advanced by 1.
282 ///
283 /// # Examples
284 ///
285 /// ```
286 /// use ntex_bytes::BufMut;
287 ///
288 /// let mut buf = vec![];
289 /// buf.put_i8(0x01);
290 /// assert_eq!(buf, b"\x01");
291 /// ```
292 ///
293 /// # Panics
294 ///
295 /// This function panics if there is not enough remaining capacity in
296 /// `self`.
297 fn put_i8(&mut self, n: i8) {
298 self.put_slice(&[n as u8]);
299 }
300
301 put_int_impl! {
302 put_u16, u16, to_be_bytes, "an unsigned 16 bit integer", "big-endian", 2, "0x0809", r"\x08\x09";
303 put_u16_le, u16, to_le_bytes, "an unsigned 16 bit integer", "little-endian", 2, "0x0809", r"\x09\x08";
304 put_i16, i16, to_be_bytes, "a signed 16 bit integer", "big-endian", 2, "0x0809", r"\x08\x09";
305 put_i16_le, i16, to_le_bytes, "a signed 16 bit integer", "little-endian", 2, "0x0809", r"\x09\x08";
306 put_u32, u32, to_be_bytes, "an unsigned 32 bit integer", "big-endian", 4, "0x0809A0A1", r"\x08\x09\xA0\xA1";
307 put_u32_le, u32, to_le_bytes, "an unsigned 32 bit integer", "little-endian", 4, "0x0809A0A1", r"\xA1\xA0\x09\x08";
308 put_i32, i32, to_be_bytes, "a signed 32 bit integer", "big-endian", 4, "0x0809A0A1", r"\x08\x09\xA0\xA1";
309 put_i32_le, i32, to_le_bytes, "a signed 32 bit integer", "little-endian", 4, "0x0809A0A1", r"\xA1\xA0\x09\x08";
310 put_u64, u64, to_be_bytes, "an unsigned 64 bit integer", "big-endian", 8, "0x0102030405060708", r"\x01\x02\x03\x04\x05\x06\x07\x08";
311 put_u64_le, u64, to_le_bytes, "an unsigned 64 bit integer", "little-endian", 8, "0x0102030405060708", r"\x08\x07\x06\x05\x04\x03\x02\x01";
312 put_i64, i64, to_be_bytes, "a signed 64 bit integer", "big-endian", 8, "0x0102030405060708", r"\x01\x02\x03\x04\x05\x06\x07\x08";
313 put_i64_le, i64, to_le_bytes, "a signed 64 bit integer", "little-endian", 8, "0x0102030405060708", r"\x08\x07\x06\x05\x04\x03\x02\x01";
314 put_u128, u128, to_be_bytes, "an unsigned 128 bit integer", "big-endian", 16, "0x01020304050607080910111213141516", r"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16";
315 put_u128_le, u128, to_le_bytes, "an unsigned 128 bit integer", "little-endian", 16, "0x01020304050607080910111213141516", r"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01";
316 put_i128, i128, to_be_bytes, "a signed 128 bit integer", "big-endian", 16, "0x01020304050607080910111213141516", r"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16";
317 put_i128_le, i128, to_le_bytes, "a signed 128 bit integer", "little-endian", 16, "0x01020304050607080910111213141516", r"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01";
318 }
319
320 /// Writes an unsigned n-byte integer to `self` in big-endian byte order.
321 ///
322 /// The current position is advanced by `nbytes`.
323 ///
324 /// # Examples
325 ///
326 /// ```
327 /// use ntex_bytes::BufMut;
328 ///
329 /// let mut buf = vec![];
330 /// buf.put_uint(0x010203, 3);
331 /// assert_eq!(buf, b"\x01\x02\x03");
332 /// ```
333 ///
334 /// # Panics
335 ///
336 /// This function panics if there is not enough remaining capacity in
337 /// `self`, or if `nbytes > 8`.
338 #[inline]
339 fn put_uint(&mut self, n: u64, nbytes: usize) {
340 self.put_slice(&n.to_be_bytes()[mem::size_of_val(&n) - nbytes..]);
341 }
342
343 /// Writes an unsigned n-byte integer to `self` in the little-endian byte order.
344 ///
345 /// The current position is advanced by `nbytes`.
346 ///
347 /// # Examples
348 ///
349 /// ```
350 /// use ntex_bytes::BufMut;
351 ///
352 /// let mut buf = vec![];
353 /// buf.put_uint_le(0x010203, 3);
354 /// assert_eq!(buf, b"\x03\x02\x01");
355 /// ```
356 ///
357 /// # Panics
358 ///
359 /// This function panics if there is not enough remaining capacity in
360 /// `self`, or if `nbytes > 8`.
361 #[inline]
362 fn put_uint_le(&mut self, n: u64, nbytes: usize) {
363 self.put_slice(&n.to_le_bytes()[0..nbytes]);
364 }
365
366 /// Writes a signed n-byte integer to `self` in big-endian byte order.
367 ///
368 /// The current position is advanced by `nbytes`.
369 ///
370 /// # Examples
371 ///
372 /// ```
373 /// use ntex_bytes::BufMut;
374 ///
375 /// let mut buf = vec![];
376 /// buf.put_int(0x010203, 3);
377 /// assert_eq!(buf, b"\x01\x02\x03");
378 /// ```
379 ///
380 /// # Panics
381 ///
382 /// This function panics if there is not enough remaining capacity in
383 /// `self`, or if `nbytes > 8`.
384 #[inline]
385 fn put_int(&mut self, n: i64, nbytes: usize) {
386 self.put_slice(&n.to_be_bytes()[mem::size_of_val(&n) - nbytes..]);
387 }
388
389 /// Writes a signed n-byte integer to `self` in little-endian byte order.
390 ///
391 /// The current position is advanced by `nbytes`.
392 ///
393 /// # Examples
394 ///
395 /// ```
396 /// use ntex_bytes::BufMut;
397 ///
398 /// let mut buf = vec![];
399 /// buf.put_int_le(0x010203, 3);
400 /// assert_eq!(buf, b"\x03\x02\x01");
401 /// ```
402 ///
403 /// # Panics
404 ///
405 /// This function panics if there is not enough remaining capacity in
406 /// `self`, or if `nbytes > 8`.
407 #[inline]
408 fn put_int_le(&mut self, n: i64, nbytes: usize) {
409 self.put_slice(&n.to_le_bytes()[0..nbytes]);
410 }
411
412 /// Writes an IEEE754 single-precision (4 bytes) floating point number to
413 /// `self` in big-endian byte order.
414 ///
415 /// The current position is advanced by 4.
416 ///
417 /// # Examples
418 ///
419 /// ```
420 /// use ntex_bytes::BufMut;
421 ///
422 /// let mut buf = vec![];
423 /// buf.put_f32(1.2f32);
424 /// assert_eq!(buf, b"\x3F\x99\x99\x9A");
425 /// ```
426 ///
427 /// # Panics
428 ///
429 /// This function panics if there is not enough remaining capacity in
430 /// `self`.
431 #[inline]
432 fn put_f32(&mut self, n: f32) {
433 self.put_u32(n.to_bits());
434 }
435
436 /// Writes an IEEE754 single-precision (4 bytes) floating point number to
437 /// `self` in little-endian byte order.
438 ///
439 /// The current position is advanced by 4.
440 ///
441 /// # Examples
442 ///
443 /// ```
444 /// use ntex_bytes::BufMut;
445 ///
446 /// let mut buf = vec![];
447 /// buf.put_f32_le(1.2f32);
448 /// assert_eq!(buf, b"\x9A\x99\x99\x3F");
449 /// ```
450 ///
451 /// # Panics
452 ///
453 /// This function panics if there is not enough remaining capacity in
454 /// `self`.
455 #[inline]
456 fn put_f32_le(&mut self, n: f32) {
457 self.put_u32_le(n.to_bits());
458 }
459
460 /// Writes an IEEE754 double-precision (8 bytes) floating point number to
461 /// `self` in big-endian byte order.
462 ///
463 /// The current position is advanced by 8.
464 ///
465 /// # Examples
466 ///
467 /// ```
468 /// use ntex_bytes::BufMut;
469 ///
470 /// let mut buf = vec![];
471 /// buf.put_f64(1.2f64);
472 /// assert_eq!(buf, b"\x3F\xF3\x33\x33\x33\x33\x33\x33");
473 /// ```
474 ///
475 /// # Panics
476 ///
477 /// This function panics if there is not enough remaining capacity in
478 /// `self`.
479 #[inline]
480 fn put_f64(&mut self, n: f64) {
481 self.put_u64(n.to_bits());
482 }
483
484 /// Writes an IEEE754 double-precision (8 bytes) floating point number to
485 /// `self` in little-endian byte order.
486 ///
487 /// The current position is advanced by 8.
488 ///
489 /// # Examples
490 ///
491 /// ```
492 /// use ntex_bytes::BufMut;
493 ///
494 /// let mut buf = vec![];
495 /// buf.put_f64_le(1.2f64);
496 /// assert_eq!(buf, b"\x33\x33\x33\x33\x33\x33\xF3\x3F");
497 /// ```
498 ///
499 /// # Panics
500 ///
501 /// This function panics if there is not enough remaining capacity in
502 /// `self`.
503 #[inline]
504 fn put_f64_le(&mut self, n: f64) {
505 self.put_u64_le(n.to_bits());
506 }
507}
508
509macro_rules! deref_forward_bufmut {
510 () => {
511 fn remaining_mut(&self) -> usize {
512 (**self).remaining_mut()
513 }
514
515 fn chunk_mut(&mut self) -> &mut UninitSlice {
516 (**self).chunk_mut()
517 }
518
519 unsafe fn advance_mut(&mut self, cnt: usize) {
520 (**self).advance_mut(cnt);
521 }
522
523 fn put_slice(&mut self, src: &[u8]) {
524 (**self).put_slice(src);
525 }
526
527 fn put_u8(&mut self, n: u8) {
528 (**self).put_u8(n);
529 }
530
531 fn put_i8(&mut self, n: i8) {
532 (**self).put_i8(n);
533 }
534 };
535}
536
537impl<T: BufMut + ?Sized> BufMut for &mut T {
538 deref_forward_bufmut!();
539}
540
541impl<T: BufMut + ?Sized> BufMut for Box<T> {
542 deref_forward_bufmut!();
543}
544
545impl BufMut for Vec<u8> {
546 #[inline]
547 fn remaining_mut(&self) -> usize {
548 usize::MAX - self.len()
549 }
550
551 #[inline]
552 unsafe fn advance_mut(&mut self, cnt: usize) {
553 let len = self.len();
554 let remaining = self.capacity() - len;
555 // only the spare capacity exposed by `chunk_mut` can be initialized
556 assert!(
557 cnt <= remaining,
558 "cannot advance past the capacity of the buffer, cnt:{cnt} remaining:{remaining}"
559 );
560
561 self.set_len(len + cnt);
562 }
563
564 #[inline]
565 fn chunk_mut(&mut self) -> &mut UninitSlice {
566 if self.capacity() == self.len() {
567 self.reserve(64); // Grow the vec
568 }
569
570 let cap = self.capacity();
571 let len = self.len();
572
573 let ptr = self.as_mut_ptr();
574 unsafe { &mut UninitSlice::from_raw_parts_mut(ptr, cap)[len..] }
575 }
576}
577
578impl BufMut for &mut [u8] {
579 #[inline]
580 fn remaining_mut(&self) -> usize {
581 self.len()
582 }
583
584 #[inline]
585 fn chunk_mut(&mut self) -> &mut UninitSlice {
586 // the bytes are initialized, `UninitSlice` never reads or de-initializes them
587 unsafe { UninitSlice::from_raw_parts_mut(self.as_mut_ptr(), self.len()) }
588 }
589
590 #[inline]
591 unsafe fn advance_mut(&mut self, cnt: usize) {
592 // Lifetime dance taken from `impl Write for &mut [u8]`.
593 let (_, b) = core::mem::take(self).split_at_mut(cnt);
594 *self = b;
595 }
596
597 #[inline]
598 fn put_slice(&mut self, src: &[u8]) {
599 self[..src.len()].copy_from_slice(src);
600 unsafe {
601 self.advance_mut(src.len());
602 }
603 }
604}
605
606// The existence of this function makes the compiler catch if the BufMut
607// trait is "object-safe" or not.
608fn _assert_trait_object(_b: &dyn BufMut) {}
609
610#[cfg(test)]
611#[allow(unused_allocation, warnings)]
612mod tests {
613 use super::*;
614 use crate::BytesMut;
615
616 #[test]
617 #[allow(clippy::needless_borrow, clippy::too_many_lines)]
618 fn buf_mut_tests() {
619 let mut buf = vec![];
620 buf.put_u8(0x01);
621 assert_eq!(buf, b"\x01");
622
623 assert_eq!(buf.remaining_mut(), usize::MAX - 1);
624 assert_eq!((&buf).remaining_mut(), usize::MAX - 1);
625 assert_eq!(Box::new(buf).remaining_mut(), usize::MAX - 1);
626
627 let mut buf = [b'1'; 10];
628 let mut b = buf.as_mut();
629 assert_eq!(b.remaining_mut(), 10);
630 assert!(b.has_remaining_mut());
631 b.put_slice(b"123");
632 assert_eq!(&buf[..], b"1231111111");
633
634 let mut b: &mut [u8] = buf.as_mut();
635 let chunk = b.chunk_mut();
636 chunk.write_byte(0, b'9');
637 assert_eq!(&buf[..], b"9231111111");
638
639 let mut b = buf.as_mut();
640 let chunk = b.chunk_mut();
641 chunk.copy_from_slice(b"0000000000");
642 assert_eq!(&buf[..], b"0000000000");
643
644 let mut b = buf.as_mut();
645 assert_eq!(format!("{:?}", b.chunk_mut()), "UninitSlice[...]");
646
647 let b = buf.as_mut();
648 let mut bb = Box::new(b);
649 unsafe { bb.advance_mut(1) };
650 let chunk = bb.chunk_mut();
651 chunk.copy_from_slice(b"111111111");
652 assert_eq!(&buf[..], b"0111111111");
653
654 let mut buf = BytesMut::new();
655 buf.put_u8(0x01);
656 assert_eq!(buf, b"\x01"[..]);
657
658 let mut buf = BytesMut::new();
659 buf.put_u8(0x01);
660 assert_eq!(buf, b"\x01"[..]);
661
662 let mut buf = vec![];
663 buf.put_i8(0x01);
664 assert_eq!(buf, b"\x01");
665
666 let mut buf = BytesMut::new();
667 buf.put_i8(0x01);
668 assert_eq!(buf, b"\x01"[..]);
669
670 let mut buf = BytesMut::new();
671 buf.put_i8(0x01);
672 assert_eq!(buf, b"\x01"[..]);
673 assert_eq!((&mut buf).remaining_mut(), 111);
674 let chunk = (&mut buf).chunk_mut();
675 chunk.write_byte(0, b'9');
676 unsafe { (&mut buf).advance_mut(1) };
677 assert_eq!((&mut buf).remaining_mut(), 110);
678
679 let mut buf = vec![];
680 buf.put_i16(0x0809);
681 assert_eq!(buf, b"\x08\x09");
682
683 let mut buf = vec![];
684 buf.put_i16_le(0x0809);
685 assert_eq!(buf, b"\x09\x08");
686
687 let mut buf = vec![];
688 buf.put_u32(0x0809_A0A1);
689 assert_eq!(buf, b"\x08\x09\xA0\xA1");
690
691 let mut buf = vec![];
692 buf.put_i32(0x0809_A0A1);
693 assert_eq!(buf, b"\x08\x09\xA0\xA1");
694
695 let mut buf = vec![];
696 buf.put_i32_le(0x0809_A0A1);
697 assert_eq!(buf, b"\xA1\xA0\x09\x08");
698
699 let mut buf = vec![];
700 buf.put_u64(0x0102_0304_0506_0708);
701 assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08");
702
703 let mut buf = vec![];
704 buf.put_u64_le(0x0102_0304_0506_0708);
705 assert_eq!(buf, b"\x08\x07\x06\x05\x04\x03\x02\x01");
706
707 let mut buf = vec![];
708 buf.put_i64(0x0102_0304_0506_0708);
709 assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08");
710
711 let mut buf = vec![];
712 buf.put_i64_le(0x0102_0304_0506_0708);
713 assert_eq!(buf, b"\x08\x07\x06\x05\x04\x03\x02\x01");
714
715 let mut buf = vec![];
716 buf.put_u128(0x0102_0304_0506_0708_0910_1112_1314_1516);
717 assert_eq!(
718 buf,
719 b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16"
720 );
721
722 let mut buf = vec![];
723 buf.put_u128_le(0x0102_0304_0506_0708_0910_1112_1314_1516);
724 assert_eq!(
725 buf,
726 b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01"
727 );
728
729 let mut buf = vec![];
730 buf.put_i128(0x0102_0304_0506_0708_0910_1112_1314_1516);
731 assert_eq!(
732 buf,
733 b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16"
734 );
735
736 let mut buf = vec![];
737 buf.put_i128_le(0x0102_0304_0506_0708_0910_1112_1314_1516);
738 assert_eq!(
739 buf,
740 b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01"
741 );
742
743 let mut buf = vec![];
744 buf.put_uint(0x01_0203, 3);
745 assert_eq!(buf, b"\x01\x02\x03");
746
747 let mut buf = vec![];
748 buf.put_uint_le(0x01_0203, 3);
749 assert_eq!(buf, b"\x03\x02\x01");
750
751 let mut buf = vec![];
752 buf.put_int(0x01_0203, 3);
753 assert_eq!(buf, b"\x01\x02\x03");
754
755 let mut buf = vec![];
756 buf.put_int_le(0x01_0203, 3);
757 assert_eq!(buf, b"\x03\x02\x01");
758
759 let mut buf = vec![];
760 buf.put_f32(1.2f32);
761 assert_eq!(buf, b"\x3F\x99\x99\x9A");
762
763 let mut buf = vec![];
764 buf.put_f32_le(1.2f32);
765 assert_eq!(buf, b"\x9A\x99\x99\x3F");
766
767 let mut buf = vec![];
768 buf.put_f64(1.2f64);
769 assert_eq!(buf, b"\x3F\xF3\x33\x33\x33\x33\x33\x33");
770
771 let mut buf = vec![];
772 buf.put_f64_le(1.2f64);
773 assert_eq!(buf, b"\x33\x33\x33\x33\x33\x33\xF3\x3F");
774 }
775}