Make Buf and BufMut usable as trait objects (#186)

- All the `get_*` and `put_*` methods that take `T: ByteOrder` have
  a `where Self: Sized` bound added, so that they are only usable from
  sized types. It was impossible to make `Buf` or `BufMut` into trait
  objects before, so this change doesn't break anyone.
- Add `get_n_be`/`get_n_le`/`put_n_be`/`put_n_le` methods that can be
  used on trait objects.
- Deprecate the export of `ByteOrder` and methods generic on it.

Fixes #163
This commit is contained in:
Sean McArthur
2018-03-12 09:25:59 -07:00
committed by Carl Lerche
parent 86c83959dc
commit ce79f0a268
5 changed files with 927 additions and 284 deletions
+453 -137
View File
@@ -1,5 +1,5 @@
use super::{IntoBuf, Take, Reader, Iter, FromBuf, Chain}; use super::{IntoBuf, Take, Reader, Iter, FromBuf, Chain};
use byteorder::ByteOrder; use byteorder::{BigEndian, ByteOrder, LittleEndian};
use iovec::IoVec; use iovec::IoVec;
use std::{cmp, io, ptr}; use std::{cmp, io, ptr};
@@ -271,238 +271,550 @@ pub trait Buf {
buf[0] as i8 buf[0] as i8
} }
/// Gets an unsigned 16 bit integer from `self` in the specified byte order. #[doc(hidden)]
/// #[deprecated(note="use get_u16_be or get_u16_le")]
/// The current position is advanced by 2. fn get_u16<T: ByteOrder>(&mut self) -> u16 where Self: Sized {
///
/// # Examples
///
/// ```
/// use bytes::{Buf, BigEndian};
/// use std::io::Cursor;
///
/// let mut buf = Cursor::new(b"\x08\x09 hello");
/// assert_eq!(0x0809, buf.get_u16::<BigEndian>());
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining data in `self`.
fn get_u16<T: ByteOrder>(&mut self) -> u16 {
let mut buf = [0; 2]; let mut buf = [0; 2];
self.copy_to_slice(&mut buf); self.copy_to_slice(&mut buf);
T::read_u16(&buf) T::read_u16(&buf)
} }
/// Gets a signed 16 bit integer from `self` in the specified byte order. /// Gets an unsigned 16 bit integer from `self` in big-endian byte order.
/// ///
/// The current position is advanced by 2. /// The current position is advanced by 2.
/// ///
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use bytes::{Buf, BigEndian}; /// use bytes::Buf;
/// use std::io::Cursor; /// use std::io::Cursor;
/// ///
/// let mut buf = Cursor::new(b"\x08\x09 hello"); /// let mut buf = Cursor::new(b"\x08\x09 hello");
/// assert_eq!(0x0809, buf.get_i16::<BigEndian>()); /// assert_eq!(0x0809, buf.get_u16_be());
/// ``` /// ```
/// ///
/// # Panics /// # Panics
/// ///
/// This function panics if there is not enough remaining data in `self`. /// This function panics if there is not enough remaining data in `self`.
fn get_i16<T: ByteOrder>(&mut self) -> i16 { fn get_u16_be(&mut self) -> u16 {
let mut buf = [0; 2];
self.copy_to_slice(&mut buf);
BigEndian::read_u16(&buf)
}
/// Gets an unsigned 16 bit integer from `self` in little-endian byte order.
///
/// The current position is advanced by 2.
///
/// # Examples
///
/// ```
/// use bytes::Buf;
/// use std::io::Cursor;
///
/// let mut buf = Cursor::new(b"\x09\x08 hello");
/// assert_eq!(0x0809, buf.get_u16_le());
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining data in `self`.
fn get_u16_le(&mut self) -> u16 {
let mut buf = [0; 2];
self.copy_to_slice(&mut buf);
LittleEndian::read_u16(&buf)
}
#[doc(hidden)]
#[deprecated(note="use get_i16_be or get_i16_le")]
fn get_i16<T: ByteOrder>(&mut self) -> i16 where Self: Sized {
let mut buf = [0; 2]; let mut buf = [0; 2];
self.copy_to_slice(&mut buf); self.copy_to_slice(&mut buf);
T::read_i16(&buf) T::read_i16(&buf)
} }
/// Gets an unsigned 32 bit integer from `self` in the specified byte order. /// Gets a signed 16 bit integer from `self` in big-endian byte order.
/// ///
/// The current position is advanced by 4. /// The current position is advanced by 2.
/// ///
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use bytes::{Buf, BigEndian}; /// use bytes::Buf;
/// use std::io::Cursor; /// use std::io::Cursor;
/// ///
/// let mut buf = Cursor::new(b"\x08\x09\xA0\xA1 hello"); /// let mut buf = Cursor::new(b"\x08\x09 hello");
/// assert_eq!(0x0809A0A1, buf.get_u32::<BigEndian>()); /// assert_eq!(0x0809, buf.get_i16_be());
/// ``` /// ```
/// ///
/// # Panics /// # Panics
/// ///
/// This function panics if there is not enough remaining data in `self`. /// This function panics if there is not enough remaining data in `self`.
fn get_u32<T: ByteOrder>(&mut self) -> u32 { fn get_i16_be(&mut self) -> i16 {
let mut buf = [0; 2];
self.copy_to_slice(&mut buf);
BigEndian::read_i16(&buf)
}
/// Gets a signed 16 bit integer from `self` in little-endian byte order.
///
/// The current position is advanced by 2.
///
/// # Examples
///
/// ```
/// use bytes::Buf;
/// use std::io::Cursor;
///
/// let mut buf = Cursor::new(b"\x09\x08 hello");
/// assert_eq!(0x0809, buf.get_i16_le());
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining data in `self`.
fn get_i16_le(&mut self) -> i16 {
let mut buf = [0; 2];
self.copy_to_slice(&mut buf);
LittleEndian::read_i16(&buf)
}
#[doc(hidden)]
#[deprecated(note="use get_u32_be or get_u32_le")]
fn get_u32<T: ByteOrder>(&mut self) -> u32 where Self: Sized {
let mut buf = [0; 4]; let mut buf = [0; 4];
self.copy_to_slice(&mut buf); self.copy_to_slice(&mut buf);
T::read_u32(&buf) T::read_u32(&buf)
} }
/// Gets a signed 32 bit integer from `self` in the specified byte order. /// Gets an unsigned 32 bit integer from `self` in the big-endian byte order.
/// ///
/// The current position is advanced by 4. /// The current position is advanced by 4.
/// ///
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use bytes::{Buf, BigEndian}; /// use bytes::Buf;
/// use std::io::Cursor; /// use std::io::Cursor;
/// ///
/// let mut buf = Cursor::new(b"\x08\x09\xA0\xA1 hello"); /// let mut buf = Cursor::new(b"\x08\x09\xA0\xA1 hello");
/// assert_eq!(0x0809A0A1, buf.get_i32::<BigEndian>()); /// assert_eq!(0x0809A0A1, buf.get_u32_be());
/// ``` /// ```
/// ///
/// # Panics /// # Panics
/// ///
/// This function panics if there is not enough remaining data in `self`. /// This function panics if there is not enough remaining data in `self`.
fn get_i32<T: ByteOrder>(&mut self) -> i32 { fn get_u32_be(&mut self) -> u32 {
let mut buf = [0; 4];
self.copy_to_slice(&mut buf);
BigEndian::read_u32(&buf)
}
/// Gets an unsigned 32 bit integer from `self` in the little-endian byte order.
///
/// The current position is advanced by 4.
///
/// # Examples
///
/// ```
/// use bytes::Buf;
/// use std::io::Cursor;
///
/// let mut buf = Cursor::new(b"\xA1\xA0\x09\x08 hello");
/// assert_eq!(0x0809A0A1, buf.get_u32_le());
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining data in `self`.
fn get_u32_le(&mut self) -> u32 {
let mut buf = [0; 4];
self.copy_to_slice(&mut buf);
LittleEndian::read_u32(&buf)
}
#[doc(hidden)]
#[deprecated(note="use get_i32_be or get_i32_le")]
fn get_i32<T: ByteOrder>(&mut self) -> i32 where Self: Sized {
let mut buf = [0; 4]; let mut buf = [0; 4];
self.copy_to_slice(&mut buf); self.copy_to_slice(&mut buf);
T::read_i32(&buf) T::read_i32(&buf)
} }
/// Gets an unsigned 64 bit integer from `self` in the specified byte order. /// Gets a signed 32 bit integer from `self` in big-endian byte order.
///
/// The current position is advanced by 8.
///
/// # Examples
///
/// ```
/// use bytes::{Buf, BigEndian};
/// use std::io::Cursor;
///
/// let mut buf = Cursor::new(b"\x01\x02\x03\x04\x05\x06\x07\x08 hello");
/// assert_eq!(0x0102030405060708, buf.get_u64::<BigEndian>());
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining data in `self`.
fn get_u64<T: ByteOrder>(&mut self) -> u64 {
let mut buf = [0; 8];
self.copy_to_slice(&mut buf);
T::read_u64(&buf)
}
/// Gets a signed 64 bit integer from `self` in the specified byte order.
///
/// The current position is advanced by 8.
///
/// # Examples
///
/// ```
/// use bytes::{Buf, BigEndian};
/// use std::io::Cursor;
///
/// let mut buf = Cursor::new(b"\x01\x02\x03\x04\x05\x06\x07\x08 hello");
/// assert_eq!(0x0102030405060708, buf.get_i64::<BigEndian>());
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining data in `self`.
fn get_i64<T: ByteOrder>(&mut self) -> i64 {
let mut buf = [0; 8];
self.copy_to_slice(&mut buf);
T::read_i64(&buf)
}
/// Gets an unsigned n-byte integer from `self` in the specified byte order.
///
/// The current position is advanced by `nbytes`.
///
/// # Examples
///
/// ```
/// use bytes::{Buf, BigEndian};
/// use std::io::Cursor;
///
/// let mut buf = Cursor::new(b"\x01\x02\x03 hello");
/// assert_eq!(0x010203, buf.get_uint::<BigEndian>(3));
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining data in `self`.
fn get_uint<T: ByteOrder>(&mut self, nbytes: usize) -> u64 {
let mut buf = [0; 8];
self.copy_to_slice(&mut buf[..nbytes]);
T::read_uint(&buf[..nbytes], nbytes)
}
/// Gets a signed n-byte integer from `self` in the specified byte order.
///
/// The current position is advanced by `nbytes`.
///
/// # Examples
///
/// ```
/// use bytes::{Buf, BigEndian};
/// use std::io::Cursor;
///
/// let mut buf = Cursor::new(b"\x01\x02\x03 hello");
/// assert_eq!(0x010203, buf.get_int::<BigEndian>(3));
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining data in `self`.
fn get_int<T: ByteOrder>(&mut self, nbytes: usize) -> i64 {
let mut buf = [0; 8];
self.copy_to_slice(&mut buf[..nbytes]);
T::read_int(&buf[..nbytes], nbytes)
}
/// Gets an IEEE754 single-precision (4 bytes) floating point number from
/// `self` in the specified byte order.
/// ///
/// The current position is advanced by 4. /// The current position is advanced by 4.
/// ///
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use bytes::{Buf, BigEndian}; /// use bytes::Buf;
/// use std::io::Cursor; /// use std::io::Cursor;
/// ///
/// let mut buf = Cursor::new(b"\x3F\x99\x99\x9A hello"); /// let mut buf = Cursor::new(b"\x08\x09\xA0\xA1 hello");
/// assert_eq!(1.2f32, buf.get_f32::<BigEndian>()); /// assert_eq!(0x0809A0A1, buf.get_i32_be());
/// ``` /// ```
/// ///
/// # Panics /// # Panics
/// ///
/// This function panics if there is not enough remaining data in `self`. /// This function panics if there is not enough remaining data in `self`.
fn get_f32<T: ByteOrder>(&mut self) -> f32 { fn get_i32_be(&mut self) -> i32 {
let mut buf = [0; 4]; let mut buf = [0; 4];
self.copy_to_slice(&mut buf); self.copy_to_slice(&mut buf);
T::read_f32(&buf) BigEndian::read_i32(&buf)
} }
/// Gets an IEEE754 double-precision (8 bytes) floating point number from /// Gets a signed 32 bit integer from `self` in little-endian byte order.
/// `self` in the specified byte order. ///
/// The current position is advanced by 4.
///
/// # Examples
///
/// ```
/// use bytes::Buf;
/// use std::io::Cursor;
///
/// let mut buf = Cursor::new(b"\xA1\xA0\x09\x08 hello");
/// assert_eq!(0x0809A0A1, buf.get_i32_le());
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining data in `self`.
fn get_i32_le(&mut self) -> i32 {
let mut buf = [0; 4];
self.copy_to_slice(&mut buf);
LittleEndian::read_i32(&buf)
}
#[doc(hidden)]
#[deprecated(note="use get_u64_be or get_u64_le")]
fn get_u64<T: ByteOrder>(&mut self) -> u64 where Self: Sized {
let mut buf = [0; 8];
self.copy_to_slice(&mut buf);
T::read_u64(&buf)
}
/// Gets an unsigned 64 bit integer from `self` in big-endian byte order.
/// ///
/// The current position is advanced by 8. /// The current position is advanced by 8.
/// ///
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use bytes::Buf;
/// use std::io::Cursor;
///
/// let mut buf = Cursor::new(b"\x01\x02\x03\x04\x05\x06\x07\x08 hello");
/// assert_eq!(0x0102030405060708, buf.get_u64_be());
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining data in `self`.
fn get_u64_be(&mut self) -> u64 {
let mut buf = [0; 8];
self.copy_to_slice(&mut buf);
BigEndian::read_u64(&buf)
}
/// Gets an unsigned 64 bit integer from `self` in little-endian byte order.
///
/// The current position is advanced by 8.
///
/// # Examples
///
/// ```
/// use bytes::Buf;
/// use std::io::Cursor;
///
/// let mut buf = Cursor::new(b"\x08\x07\x06\x05\x04\x03\x02\x01 hello");
/// assert_eq!(0x0102030405060708, buf.get_u64_le());
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining data in `self`.
fn get_u64_le(&mut self) -> u64 {
let mut buf = [0; 8];
self.copy_to_slice(&mut buf);
LittleEndian::read_u64(&buf)
}
#[doc(hidden)]
#[deprecated(note="use get_i64_be or get_i64_le")]
fn get_i64<T: ByteOrder>(&mut self) -> i64 where Self: Sized {
let mut buf = [0; 8];
self.copy_to_slice(&mut buf);
T::read_i64(&buf)
}
/// Gets a signed 64 bit integer from `self` in big-endian byte order.
///
/// The current position is advanced by 8.
///
/// # Examples
///
/// ```
/// use bytes::Buf;
/// use std::io::Cursor;
///
/// let mut buf = Cursor::new(b"\x01\x02\x03\x04\x05\x06\x07\x08 hello");
/// assert_eq!(0x0102030405060708, buf.get_i64_be());
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining data in `self`.
fn get_i64_be(&mut self) -> i64 {
let mut buf = [0; 8];
self.copy_to_slice(&mut buf);
BigEndian::read_i64(&buf)
}
/// Gets a signed 64 bit integer from `self` in little-endian byte order.
///
/// The current position is advanced by 8.
///
/// # Examples
///
/// ```
/// use bytes::Buf;
/// use std::io::Cursor;
///
/// let mut buf = Cursor::new(b"\x08\x07\x06\x05\x04\x03\x02\x01 hello");
/// assert_eq!(0x0102030405060708, buf.get_i64_le());
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining data in `self`.
fn get_i64_le(&mut self) -> i64 {
let mut buf = [0; 8];
self.copy_to_slice(&mut buf);
LittleEndian::read_i64(&buf)
}
#[doc(hidden)]
#[deprecated(note="use get_uint_be or get_uint_le")]
fn get_uint<T: ByteOrder>(&mut self, nbytes: usize) -> u64 where Self: Sized {
let mut buf = [0; 8];
self.copy_to_slice(&mut buf[..nbytes]);
T::read_uint(&buf[..nbytes], nbytes)
}
/// Gets an unsigned n-byte integer from `self` in big-endian byte order.
///
/// The current position is advanced by `nbytes`.
///
/// # Examples
///
/// ```
/// use bytes::{Buf, BigEndian}; /// use bytes::{Buf, BigEndian};
/// use std::io::Cursor; /// use std::io::Cursor;
/// ///
/// let mut buf = Cursor::new(b"\x3F\xF3\x33\x33\x33\x33\x33\x33 hello"); /// let mut buf = Cursor::new(b"\x01\x02\x03 hello");
/// assert_eq!(1.2f64, buf.get_f64::<BigEndian>()); /// assert_eq!(0x010203, buf.get_uint_be(3));
/// ``` /// ```
/// ///
/// # Panics /// # Panics
/// ///
/// This function panics if there is not enough remaining data in `self`. /// This function panics if there is not enough remaining data in `self`.
fn get_f64<T: ByteOrder>(&mut self) -> f64 { fn get_uint_be(&mut self, nbytes: usize) -> u64 {
let mut buf = [0; 8];
self.copy_to_slice(&mut buf[..nbytes]);
BigEndian::read_uint(&buf[..nbytes], nbytes)
}
/// Gets an unsigned n-byte integer from `self` in little-endian byte order.
///
/// The current position is advanced by `nbytes`.
///
/// # Examples
///
/// ```
/// use bytes::Buf;
/// use std::io::Cursor;
///
/// let mut buf = Cursor::new(b"\x03\x02\x01 hello");
/// assert_eq!(0x010203, buf.get_uint_le(3));
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining data in `self`.
fn get_uint_le(&mut self, nbytes: usize) -> u64 {
let mut buf = [0; 8];
self.copy_to_slice(&mut buf[..nbytes]);
LittleEndian::read_uint(&buf[..nbytes], nbytes)
}
#[doc(hidden)]
#[deprecated(note="use get_int_be or get_int_le")]
fn get_int<T: ByteOrder>(&mut self, nbytes: usize) -> i64 where Self: Sized {
let mut buf = [0; 8];
self.copy_to_slice(&mut buf[..nbytes]);
T::read_int(&buf[..nbytes], nbytes)
}
/// Gets a signed n-byte integer from `self` in big-endian byte order.
///
/// The current position is advanced by `nbytes`.
///
/// # Examples
///
/// ```
/// use bytes::Buf;
/// use std::io::Cursor;
///
/// let mut buf = Cursor::new(b"\x01\x02\x03 hello");
/// assert_eq!(0x010203, buf.get_int_be(3));
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining data in `self`.
fn get_int_be(&mut self, nbytes: usize) -> i64 {
let mut buf = [0; 8];
self.copy_to_slice(&mut buf[..nbytes]);
BigEndian::read_int(&buf[..nbytes], nbytes)
}
/// Gets a signed n-byte integer from `self` in little-endian byte order.
///
/// The current position is advanced by `nbytes`.
///
/// # Examples
///
/// ```
/// use bytes::Buf;
/// use std::io::Cursor;
///
/// let mut buf = Cursor::new(b"\x03\x02\x01 hello");
/// assert_eq!(0x010203, buf.get_int_le(3));
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining data in `self`.
fn get_int_le(&mut self, nbytes: usize) -> i64 {
let mut buf = [0; 8];
self.copy_to_slice(&mut buf[..nbytes]);
LittleEndian::read_int(&buf[..nbytes], nbytes)
}
#[doc(hidden)]
#[deprecated(note="use get_f32_be or get_f32_le")]
fn get_f32<T: ByteOrder>(&mut self) -> f32 where Self: Sized {
let mut buf = [0; 4];
self.copy_to_slice(&mut buf);
T::read_f32(&buf)
}
/// Gets an IEEE754 single-precision (4 bytes) floating point number from
/// `self` in big-endian byte order.
///
/// The current position is advanced by 4.
///
/// # Examples
///
/// ```
/// use bytes::Buf;
/// use std::io::Cursor;
///
/// let mut buf = Cursor::new(b"\x3F\x99\x99\x9A hello");
/// assert_eq!(1.2f32, buf.get_f32_be());
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining data in `self`.
fn get_f32_be(&mut self) -> f32 {
let mut buf = [0; 4];
self.copy_to_slice(&mut buf);
BigEndian::read_f32(&buf)
}
/// Gets an IEEE754 single-precision (4 bytes) floating point number from
/// `self` in little-endian byte order.
///
/// The current position is advanced by 4.
///
/// # Examples
///
/// ```
/// use bytes::Buf;
/// use std::io::Cursor;
///
/// let mut buf = Cursor::new(b"\x9A\x99\x99\x3F hello");
/// assert_eq!(1.2f32, buf.get_f32_le());
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining data in `self`.
fn get_f32_le(&mut self) -> f32 {
let mut buf = [0; 4];
self.copy_to_slice(&mut buf);
LittleEndian::read_f32(&buf)
}
#[doc(hidden)]
#[deprecated(note="use get_f64_be or get_f64_le")]
fn get_f64<T: ByteOrder>(&mut self) -> f64 where Self: Sized {
let mut buf = [0; 8]; let mut buf = [0; 8];
self.copy_to_slice(&mut buf); self.copy_to_slice(&mut buf);
T::read_f64(&buf) T::read_f64(&buf)
} }
/// Gets an IEEE754 double-precision (8 bytes) floating point number from
/// `self` in big-endian byte order.
///
/// The current position is advanced by 8.
///
/// # Examples
///
/// ```
/// use bytes::Buf;
/// use std::io::Cursor;
///
/// let mut buf = Cursor::new(b"\x3F\xF3\x33\x33\x33\x33\x33\x33 hello");
/// assert_eq!(1.2f64, buf.get_f64_be());
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining data in `self`.
fn get_f64_be(&mut self) -> f64 {
let mut buf = [0; 8];
self.copy_to_slice(&mut buf);
BigEndian::read_f64(&buf)
}
/// Gets an IEEE754 double-precision (8 bytes) floating point number from
/// `self` in little-endian byte order.
///
/// The current position is advanced by 8.
///
/// # Examples
///
/// ```
/// use bytes::Buf;
/// use std::io::Cursor;
///
/// let mut buf = Cursor::new(b"\x33\x33\x33\x33\x33\x33\xF3\x3F hello");
/// assert_eq!(1.2f64, buf.get_f64_le());
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining data in `self`.
fn get_f64_le(&mut self) -> f64 {
let mut buf = [0; 8];
self.copy_to_slice(&mut buf);
LittleEndian::read_f64(&buf)
}
/// Transforms a `Buf` into a concrete buffer. /// Transforms a `Buf` into a concrete buffer.
/// ///
/// `collect()` can operate on any value that implements `Buf`, and turn it /// `collect()` can operate on any value that implements `Buf`, and turn it
@@ -749,3 +1061,7 @@ impl Buf for Option<[u8; 1]> {
} }
} }
} }
// The existance of this function makes the compiler catch if the Buf
// trait is "object-safe" or not.
fn _assert_trait_object(_b: &Buf) {}
+468 -142
View File
@@ -1,5 +1,5 @@
use super::{IntoBuf, Writer}; use super::{IntoBuf, Writer};
use byteorder::ByteOrder; use byteorder::{LittleEndian, ByteOrder, BigEndian};
use iovec::IoVec; use iovec::IoVec;
use std::{cmp, io, ptr, usize}; use std::{cmp, io, ptr, usize};
@@ -338,41 +338,25 @@ pub trait BufMut {
self.put_slice(&src) self.put_slice(&src)
} }
/// Writes an unsigned 16 bit integer to `self` in the specified byte order. #[doc(hidden)]
/// #[deprecated(note="use put_u16_be or put_u16_le")]
/// The current position is advanced by 2. fn put_u16<T: ByteOrder>(&mut self, n: u16) where Self: Sized {
///
/// # Examples
///
/// ```
/// use bytes::{BufMut, BigEndian};
///
/// let mut buf = vec![];
/// buf.put_u16::<BigEndian>(0x0809);
/// assert_eq!(buf, b"\x08\x09");
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining capacity in
/// `self`.
fn put_u16<T: ByteOrder>(&mut self, n: u16) {
let mut buf = [0; 2]; let mut buf = [0; 2];
T::write_u16(&mut buf, n); T::write_u16(&mut buf, n);
self.put_slice(&buf) self.put_slice(&buf)
} }
/// Writes a signed 16 bit integer to `self` in the specified byte order. /// Writes an unsigned 16 bit integer to `self` in big-endian byte order.
/// ///
/// The current position is advanced by 2. /// The current position is advanced by 2.
/// ///
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use bytes::{BufMut, BigEndian}; /// use bytes::BufMut;
/// ///
/// let mut buf = vec![]; /// let mut buf = vec![];
/// buf.put_i16::<BigEndian>(0x0809); /// buf.put_u16_be(0x0809);
/// assert_eq!(buf, b"\x08\x09"); /// assert_eq!(buf, b"\x08\x09");
/// ``` /// ```
/// ///
@@ -380,47 +364,111 @@ pub trait BufMut {
/// ///
/// This function panics if there is not enough remaining capacity in /// This function panics if there is not enough remaining capacity in
/// `self`. /// `self`.
fn put_i16<T: ByteOrder>(&mut self, n: i16) { fn put_u16_be(&mut self, n: u16) {
let mut buf = [0; 2];
BigEndian::write_u16(&mut buf, n);
self.put_slice(&buf)
}
/// Writes an unsigned 16 bit integer to `self` in little-endian byte order.
///
/// The current position is advanced by 2.
///
/// # Examples
///
/// ```
/// use bytes::BufMut;
///
/// let mut buf = vec![];
/// buf.put_u16_le(0x0809);
/// assert_eq!(buf, b"\x09\x08");
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining capacity in
/// `self`.
fn put_u16_le(&mut self, n: u16) {
let mut buf = [0; 2];
LittleEndian::write_u16(&mut buf, n);
self.put_slice(&buf)
}
#[doc(hidden)]
#[deprecated(note="use put_i16_be or put_i16_le")]
fn put_i16<T: ByteOrder>(&mut self, n: i16) where Self: Sized {
let mut buf = [0; 2]; let mut buf = [0; 2];
T::write_i16(&mut buf, n); T::write_i16(&mut buf, n);
self.put_slice(&buf) self.put_slice(&buf)
} }
/// Writes an unsigned 32 bit integer to `self` in the specified byte order. /// Writes a signed 16 bit integer to `self` in big-endian byte order.
/// ///
/// The current position is advanced by 4. /// The current position is advanced by 2.
/// ///
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use bytes::{BufMut, BigEndian}; /// use bytes::BufMut;
/// ///
/// let mut buf = vec![]; /// let mut buf = vec![];
/// buf.put_u32::<BigEndian>(0x0809A0A1); /// buf.put_i16_be(0x0809);
/// assert_eq!(buf, b"\x08\x09\xA0\xA1"); /// assert_eq!(buf, b"\x08\x09");
/// ``` /// ```
/// ///
/// # Panics /// # Panics
/// ///
/// This function panics if there is not enough remaining capacity in /// This function panics if there is not enough remaining capacity in
/// `self`. /// `self`.
fn put_u32<T: ByteOrder>(&mut self, n: u32) { fn put_i16_be(&mut self, n: i16) {
let mut buf = [0; 2];
BigEndian::write_i16(&mut buf, n);
self.put_slice(&buf)
}
/// Writes a signed 16 bit integer to `self` in little-endian byte order.
///
/// The current position is advanced by 2.
///
/// # Examples
///
/// ```
/// use bytes::BufMut;
///
/// let mut buf = vec![];
/// buf.put_i16_le(0x0809);
/// assert_eq!(buf, b"\x09\x08");
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining capacity in
/// `self`.
fn put_i16_le(&mut self, n: i16) {
let mut buf = [0; 2];
LittleEndian::write_i16(&mut buf, n);
self.put_slice(&buf)
}
#[doc(hidden)]
#[deprecated(note="use put_u32_be or put_u32_le")]
fn put_u32<T: ByteOrder>(&mut self, n: u32) where Self: Sized {
let mut buf = [0; 4]; let mut buf = [0; 4];
T::write_u32(&mut buf, n); T::write_u32(&mut buf, n);
self.put_slice(&buf) self.put_slice(&buf)
} }
/// Writes a signed 32 bit integer to `self` in the specified byte order. /// Writes an unsigned 32 bit integer to `self` in big-endian byte order.
/// ///
/// The current position is advanced by 4. /// The current position is advanced by 4.
/// ///
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use bytes::{BufMut, BigEndian}; /// use bytes::BufMut;
/// ///
/// let mut buf = vec![]; /// let mut buf = vec![];
/// buf.put_i32::<BigEndian>(0x0809A0A1); /// buf.put_u32_be(0x0809A0A1);
/// assert_eq!(buf, b"\x08\x09\xA0\xA1"); /// assert_eq!(buf, b"\x08\x09\xA0\xA1");
/// ``` /// ```
/// ///
@@ -428,120 +476,336 @@ pub trait BufMut {
/// ///
/// This function panics if there is not enough remaining capacity in /// This function panics if there is not enough remaining capacity in
/// `self`. /// `self`.
fn put_i32<T: ByteOrder>(&mut self, n: i32) { fn put_u32_be(&mut self, n: u32) {
let mut buf = [0; 4]; let mut buf = [0; 4];
T::write_i32(&mut buf, n); BigEndian::write_u32(&mut buf, n);
self.put_slice(&buf) self.put_slice(&buf)
} }
/// Writes an unsigned 64 bit integer to `self` in the specified byte order. /// Writes an unsigned 32 bit integer to `self` in little-endian byte order.
///
/// The current position is advanced by 8.
///
/// # Examples
///
/// ```
/// use bytes::{BufMut, BigEndian};
///
/// let mut buf = vec![];
/// buf.put_u64::<BigEndian>(0x0102030405060708);
/// assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08");
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining capacity in
/// `self`.
fn put_u64<T: ByteOrder>(&mut self, n: u64) {
let mut buf = [0; 8];
T::write_u64(&mut buf, n);
self.put_slice(&buf)
}
/// Writes a signed 64 bit integer to `self` in the specified byte order.
///
/// The current position is advanced by 8.
///
/// # Examples
///
/// ```
/// use bytes::{BufMut, BigEndian};
///
/// let mut buf = vec![];
/// buf.put_i64::<BigEndian>(0x0102030405060708);
/// assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08");
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining capacity in
/// `self`.
fn put_i64<T: ByteOrder>(&mut self, n: i64) {
let mut buf = [0; 8];
T::write_i64(&mut buf, n);
self.put_slice(&buf)
}
/// Writes an unsigned n-byte integer to `self` in the specified byte order.
///
/// The current position is advanced by `nbytes`.
///
/// # Examples
///
/// ```
/// use bytes::{BufMut, BigEndian};
///
/// let mut buf = vec![];
/// buf.put_uint::<BigEndian>(0x010203, 3);
/// assert_eq!(buf, b"\x01\x02\x03");
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining capacity in
/// `self`.
fn put_uint<T: ByteOrder>(&mut self, n: u64, nbytes: usize) {
let mut buf = [0; 8];
T::write_uint(&mut buf, n, nbytes);
self.put_slice(&buf[0..nbytes])
}
/// Writes a signed n-byte integer to `self` in the specified byte order.
///
/// The current position is advanced by `nbytes`.
///
/// # Examples
///
/// ```
/// use bytes::{BufMut, BigEndian};
///
/// let mut buf = vec![];
/// buf.put_int::<BigEndian>(0x010203, 3);
/// assert_eq!(buf, b"\x01\x02\x03");
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining capacity in
/// `self`.
fn put_int<T: ByteOrder>(&mut self, n: i64, nbytes: usize) {
let mut buf = [0; 8];
T::write_int(&mut buf, n, nbytes);
self.put_slice(&buf[0..nbytes])
}
/// Writes an IEEE754 single-precision (4 bytes) floating point number to
/// `self` in the specified byte order.
/// ///
/// The current position is advanced by 4. /// The current position is advanced by 4.
/// ///
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use bytes::{BufMut, BigEndian}; /// use bytes::BufMut;
/// ///
/// let mut buf = vec![]; /// let mut buf = vec![];
/// buf.put_f32::<BigEndian>(1.2f32); /// buf.put_u32_le(0x0809A0A1);
/// assert_eq!(buf, b"\xA1\xA0\x09\x08");
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining capacity in
/// `self`.
fn put_u32_le(&mut self, n: u32) {
let mut buf = [0; 4];
LittleEndian::write_u32(&mut buf, n);
self.put_slice(&buf)
}
#[doc(hidden)]
#[deprecated(note="use put_i32_be or put_i32_le")]
fn put_i32<T: ByteOrder>(&mut self, n: i32) where Self: Sized {
let mut buf = [0; 4];
T::write_i32(&mut buf, n);
self.put_slice(&buf)
}
/// Writes a signed 32 bit integer to `self` in big-endian byte order.
///
/// The current position is advanced by 4.
///
/// # Examples
///
/// ```
/// use bytes::BufMut;
///
/// let mut buf = vec![];
/// buf.put_i32_be(0x0809A0A1);
/// assert_eq!(buf, b"\x08\x09\xA0\xA1");
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining capacity in
/// `self`.
fn put_i32_be(&mut self, n: i32) {
let mut buf = [0; 4];
BigEndian::write_i32(&mut buf, n);
self.put_slice(&buf)
}
/// Writes a signed 32 bit integer to `self` in little-endian byte order.
///
/// The current position is advanced by 4.
///
/// # Examples
///
/// ```
/// use bytes::BufMut;
///
/// let mut buf = vec![];
/// buf.put_i32_le(0x0809A0A1);
/// assert_eq!(buf, b"\xA1\xA0\x09\x08");
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining capacity in
/// `self`.
fn put_i32_le(&mut self, n: i32) {
let mut buf = [0; 4];
LittleEndian::write_i32(&mut buf, n);
self.put_slice(&buf)
}
#[doc(hidden)]
#[deprecated(note="use put_u64_be or put_u64_le")]
fn put_u64<T: ByteOrder>(&mut self, n: u64) where Self: Sized {
let mut buf = [0; 8];
T::write_u64(&mut buf, n);
self.put_slice(&buf)
}
/// Writes an unsigned 64 bit integer to `self` in the big-endian byte order.
///
/// The current position is advanced by 8.
///
/// # Examples
///
/// ```
/// use bytes::BufMut;
///
/// let mut buf = vec![];
/// buf.put_u64_be(0x0102030405060708);
/// assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08");
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining capacity in
/// `self`.
fn put_u64_be(&mut self, n: u64) {
let mut buf = [0; 8];
BigEndian::write_u64(&mut buf, n);
self.put_slice(&buf)
}
/// Writes an unsigned 64 bit integer to `self` in little-endian byte order.
///
/// The current position is advanced by 8.
///
/// # Examples
///
/// ```
/// use bytes::BufMut;
///
/// let mut buf = vec![];
/// buf.put_u64_le(0x0102030405060708);
/// assert_eq!(buf, b"\x08\x07\x06\x05\x04\x03\x02\x01");
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining capacity in
/// `self`.
fn put_u64_le(&mut self, n: u64) {
let mut buf = [0; 8];
LittleEndian::write_u64(&mut buf, n);
self.put_slice(&buf)
}
#[doc(hidden)]
#[deprecated(note="use put_i64_be or put_i64_le")]
fn put_i64<T: ByteOrder>(&mut self, n: i64) where Self: Sized {
let mut buf = [0; 8];
T::write_i64(&mut buf, n);
self.put_slice(&buf)
}
/// Writes a signed 64 bit integer to `self` in the big-endian byte order.
///
/// The current position is advanced by 8.
///
/// # Examples
///
/// ```
/// use bytes::BufMut;
///
/// let mut buf = vec![];
/// buf.put_i64_be(0x0102030405060708);
/// assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08");
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining capacity in
/// `self`.
fn put_i64_be(&mut self, n: i64) {
let mut buf = [0; 8];
BigEndian::write_i64(&mut buf, n);
self.put_slice(&buf)
}
/// Writes a signed 64 bit integer to `self` in little-endian byte order.
///
/// The current position is advanced by 8.
///
/// # Examples
///
/// ```
/// use bytes::BufMut;
///
/// let mut buf = vec![];
/// buf.put_i64_le(0x0102030405060708);
/// assert_eq!(buf, b"\x08\x07\x06\x05\x04\x03\x02\x01");
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining capacity in
/// `self`.
fn put_i64_le(&mut self, n: i64) {
let mut buf = [0; 8];
LittleEndian::write_i64(&mut buf, n);
self.put_slice(&buf)
}
#[doc(hidden)]
#[deprecated(note="use put_uint_be or put_uint_le")]
fn put_uint<T: ByteOrder>(&mut self, n: u64, nbytes: usize) where Self: Sized {
let mut buf = [0; 8];
T::write_uint(&mut buf, n, nbytes);
self.put_slice(&buf[0..nbytes])
}
/// Writes an unsigned n-byte integer to `self` in big-endian byte order.
///
/// The current position is advanced by `nbytes`.
///
/// # Examples
///
/// ```
/// use bytes::BufMut;
///
/// let mut buf = vec![];
/// buf.put_uint_be(0x010203, 3);
/// assert_eq!(buf, b"\x01\x02\x03");
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining capacity in
/// `self`.
fn put_uint_be(&mut self, n: u64, nbytes: usize) {
let mut buf = [0; 8];
BigEndian::write_uint(&mut buf, n, nbytes);
self.put_slice(&buf[0..nbytes])
}
/// Writes an unsigned n-byte integer to `self` in the little-endian byte order.
///
/// The current position is advanced by `nbytes`.
///
/// # Examples
///
/// ```
/// use bytes::BufMut;
///
/// let mut buf = vec![];
/// buf.put_uint_le(0x010203, 3);
/// assert_eq!(buf, b"\x03\x02\x01");
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining capacity in
/// `self`.
fn put_uint_le(&mut self, n: u64, nbytes: usize) {
let mut buf = [0; 8];
LittleEndian::write_uint(&mut buf, n, nbytes);
self.put_slice(&buf[0..nbytes])
}
#[doc(hidden)]
#[deprecated(note="use put_int_be or put_int_le")]
fn put_int<T: ByteOrder>(&mut self, n: i64, nbytes: usize) where Self: Sized {
let mut buf = [0; 8];
T::write_int(&mut buf, n, nbytes);
self.put_slice(&buf[0..nbytes])
}
/// Writes a signed n-byte integer to `self` in big-endian byte order.
///
/// The current position is advanced by `nbytes`.
///
/// # Examples
///
/// ```
/// use bytes::BufMut;
///
/// let mut buf = vec![];
/// buf.put_int_be(0x010203, 3);
/// assert_eq!(buf, b"\x01\x02\x03");
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining capacity in
/// `self`.
fn put_int_be(&mut self, n: i64, nbytes: usize) {
let mut buf = [0; 8];
BigEndian::write_int(&mut buf, n, nbytes);
self.put_slice(&buf[0..nbytes])
}
/// Writes a signed n-byte integer to `self` in little-endian byte order.
///
/// The current position is advanced by `nbytes`.
///
/// # Examples
///
/// ```
/// use bytes::BufMut;
///
/// let mut buf = vec![];
/// buf.put_int_le(0x010203, 3);
/// assert_eq!(buf, b"\x03\x02\x01");
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining capacity in
/// `self`.
fn put_int_le(&mut self, n: i64, nbytes: usize) {
let mut buf = [0; 8];
LittleEndian::write_int(&mut buf, n, nbytes);
self.put_slice(&buf[0..nbytes])
}
#[doc(hidden)]
#[deprecated(note="use put_f32_be or put_f32_le")]
fn put_f32<T: ByteOrder>(&mut self, n: f32) where Self: Sized {
let mut buf = [0; 4];
T::write_f32(&mut buf, n);
self.put_slice(&buf)
}
/// Writes an IEEE754 single-precision (4 bytes) floating point number to
/// `self` in big-endian byte order.
///
/// The current position is advanced by 4.
///
/// # Examples
///
/// ```
/// use bytes::BufMut;
///
/// let mut buf = vec![];
/// buf.put_f32_be(1.2f32);
/// assert_eq!(buf, b"\x3F\x99\x99\x9A"); /// assert_eq!(buf, b"\x3F\x99\x99\x9A");
/// ``` /// ```
/// ///
@@ -549,24 +813,57 @@ pub trait BufMut {
/// ///
/// This function panics if there is not enough remaining capacity in /// This function panics if there is not enough remaining capacity in
/// `self`. /// `self`.
fn put_f32<T: ByteOrder>(&mut self, n: f32) { fn put_f32_be(&mut self, n: f32) {
let mut buf = [0; 4]; let mut buf = [0; 4];
T::write_f32(&mut buf, n); BigEndian::write_f32(&mut buf, n);
self.put_slice(&buf)
}
/// Writes an IEEE754 single-precision (4 bytes) floating point number to
/// `self` in little-endian byte order.
///
/// The current position is advanced by 4.
///
/// # Examples
///
/// ```
/// use bytes::BufMut;
///
/// let mut buf = vec![];
/// buf.put_f32_le(1.2f32);
/// assert_eq!(buf, b"\x9A\x99\x99\x3F");
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining capacity in
/// `self`.
fn put_f32_le(&mut self, n: f32) {
let mut buf = [0; 4];
LittleEndian::write_f32(&mut buf, n);
self.put_slice(&buf)
}
#[doc(hidden)]
#[deprecated(note="use put_f64_be or put_f64_le")]
fn put_f64<T: ByteOrder>(&mut self, n: f64) where Self: Sized {
let mut buf = [0; 8];
T::write_f64(&mut buf, n);
self.put_slice(&buf) self.put_slice(&buf)
} }
/// Writes an IEEE754 double-precision (8 bytes) floating point number to /// Writes an IEEE754 double-precision (8 bytes) floating point number to
/// `self` in the specified byte order. /// `self` in big-endian byte order.
/// ///
/// The current position is advanced by 8. /// The current position is advanced by 8.
/// ///
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use bytes::{BufMut, BigEndian}; /// use bytes::BufMut;
/// ///
/// let mut buf = vec![]; /// let mut buf = vec![];
/// buf.put_f64::<BigEndian>(1.2f64); /// buf.put_f64_be(1.2f64);
/// assert_eq!(buf, b"\x3F\xF3\x33\x33\x33\x33\x33\x33"); /// assert_eq!(buf, b"\x3F\xF3\x33\x33\x33\x33\x33\x33");
/// ``` /// ```
/// ///
@@ -574,9 +871,34 @@ pub trait BufMut {
/// ///
/// This function panics if there is not enough remaining capacity in /// This function panics if there is not enough remaining capacity in
/// `self`. /// `self`.
fn put_f64<T: ByteOrder>(&mut self, n: f64) { fn put_f64_be(&mut self, n: f64) {
let mut buf = [0; 8]; let mut buf = [0; 8];
T::write_f64(&mut buf, n); BigEndian::write_f64(&mut buf, n);
self.put_slice(&buf)
}
/// Writes an IEEE754 double-precision (8 bytes) floating point number to
/// `self` in little-endian byte order.
///
/// The current position is advanced by 8.
///
/// # Examples
///
/// ```
/// use bytes::BufMut;
///
/// let mut buf = vec![];
/// buf.put_f64_le(1.2f64);
/// assert_eq!(buf, b"\x33\x33\x33\x33\x33\x33\xF3\x3F");
/// ```
///
/// # Panics
///
/// This function panics if there is not enough remaining capacity in
/// `self`.
fn put_f64_le(&mut self, n: f64) {
let mut buf = [0; 8];
LittleEndian::write_f64(&mut buf, n);
self.put_slice(&buf) self.put_slice(&buf)
} }
@@ -734,3 +1056,7 @@ impl BufMut for Vec<u8> {
&mut slice::from_raw_parts_mut(ptr, cap)[len..] &mut slice::from_raw_parts_mut(ptr, cap)[len..]
} }
} }
// The existance of this function makes the compiler catch if the BufMut
// trait is "object-safe" or not.
fn _assert_trait_object(_b: &BufMut) {}
+1
View File
@@ -92,6 +92,7 @@ mod bytes;
mod debug; mod debug;
pub use bytes::{Bytes, BytesMut}; pub use bytes::{Bytes, BytesMut};
#[deprecated]
pub use byteorder::{ByteOrder, BigEndian, LittleEndian}; pub use byteorder::{ByteOrder, BigEndian, LittleEndian};
// Optional Serde support // Optional Serde support
+3 -3
View File
@@ -33,15 +33,15 @@ fn test_get_u8() {
#[test] #[test]
fn test_get_u16() { fn test_get_u16() {
let buf = b"\x21\x54zomg"; let buf = b"\x21\x54zomg";
assert_eq!(0x2154, Cursor::new(buf).get_u16::<byteorder::BigEndian>()); assert_eq!(0x2154, Cursor::new(buf).get_u16_be());
assert_eq!(0x5421, Cursor::new(buf).get_u16::<byteorder::LittleEndian>()); assert_eq!(0x5421, Cursor::new(buf).get_u16_le());
} }
#[test] #[test]
#[should_panic] #[should_panic]
fn test_get_u16_buffer_underflow() { fn test_get_u16_buffer_underflow() {
let mut buf = Cursor::new(b"\x21"); let mut buf = Cursor::new(b"\x21");
buf.get_u16::<byteorder::BigEndian>(); buf.get_u16_be();
} }
#[test] #[test]
+2 -2
View File
@@ -41,11 +41,11 @@ fn test_put_u8() {
#[test] #[test]
fn test_put_u16() { fn test_put_u16() {
let mut buf = Vec::with_capacity(8); let mut buf = Vec::with_capacity(8);
buf.put_u16::<byteorder::BigEndian>(8532); buf.put_u16_be(8532);
assert_eq!(b"\x21\x54", &buf[..]); assert_eq!(b"\x21\x54", &buf[..]);
buf.clear(); buf.clear();
buf.put_u16::<byteorder::LittleEndian>(8532); buf.put_u16_le(8532);
assert_eq!(b"\x54\x21", &buf[..]); assert_eq!(b"\x54\x21", &buf[..]);
} }