use super::*;
pub trait Emit: HeaderLen {
fn emit_raw<V: ByteSliceMut>(&self, buf: V) -> usize;
fn needs_emit(&self) -> bool;
#[inline]
fn emit<V: ByteSliceMut>(&self, buf: V) -> ParseResult<usize> {
if buf.len() != self.packet_length() {
return Err(ParseError::TooSmall);
}
Ok(self.emit_raw(buf))
}
#[inline]
fn emit_prefix<V: SplitByteSliceMut>(&self, buf: V) -> ParseResult<V> {
let (into, out) = buf
.split_at(self.packet_length())
.map_err(|_| ParseError::TooSmall)?;
self.emit_raw(into);
Ok(out)
}
#[inline]
fn emit_suffix<V: SplitByteSliceMut>(&self, buf: V) -> ParseResult<V> {
let l = buf.len();
let (into, out) = buf
.split_at(l - self.packet_length())
.map_err(|_| ParseError::TooSmall)?;
self.emit_raw(into);
Ok(out)
}
#[inline]
fn to_vec(&self) -> Vec<u8> {
let len = self.packet_length();
let mut out = vec![0u8; len];
let o_len = self.emit(&mut out[..]).expect(
"mismatch between packet requested length and required length",
);
assert_eq!(o_len, len);
out
}
#[inline]
fn emit_uninit(&self, buf: &mut [MaybeUninit<u8>]) -> ParseResult<usize>
where
Self: EmitDoesNotRelyOnBufContents,
{
let buf = unsafe { &mut *(buf as *mut [_] as *mut [u8]) };
self.emit(buf)
}
#[inline]
fn emit_vec(&self) -> Vec<u8>
where
Self: EmitDoesNotRelyOnBufContents,
{
let len = self.packet_length();
let mut out = Vec::with_capacity(len);
let o_len = self.emit_uninit(out.spare_capacity_mut()).expect(
"mismatch between packet requested length and required length",
);
assert_eq!(o_len, len);
unsafe {
out.set_len(o_len);
}
out
}
}
impl<T: Emit> Emit for Vec<T> {
#[inline]
fn emit_raw<V: ByteSliceMut>(&self, mut buf: V) -> usize {
let mut emitted = 0;
for el in self {
emitted += el.emit_raw(&mut buf[emitted..]);
}
emitted
}
#[inline]
fn needs_emit(&self) -> bool {
true
}
}
impl Emit for &[u8] {
#[inline]
fn emit_raw<V: ByteSliceMut>(&self, mut buf: V) -> usize {
buf[..self.len()].copy_from_slice(self);
self.len()
}
#[inline]
fn needs_emit(&self) -> bool {
false
}
}
impl Emit for Vec<u8> {
#[inline]
fn emit_raw<V: ByteSliceMut>(&self, buf: V) -> usize {
self.as_slice().emit_raw(buf)
}
#[inline]
fn needs_emit(&self) -> bool {
true
}
}
impl<E: Emit> Emit for &E {
#[inline]
fn emit_raw<V: ByteSliceMut>(&self, buf: V) -> usize {
E::emit_raw(self, buf)
}
#[inline]
fn needs_emit(&self) -> bool {
E::needs_emit(self)
}
}
pub unsafe trait EmitDoesNotRelyOnBufContents {}
unsafe impl<E: Emit + EmitDoesNotRelyOnBufContents> EmitDoesNotRelyOnBufContents
for &E
{
}
unsafe impl EmitDoesNotRelyOnBufContents for &[u8] {}
unsafe impl EmitDoesNotRelyOnBufContents for Vec<u8> {}
unsafe impl<T: EmitDoesNotRelyOnBufContents> EmitDoesNotRelyOnBufContents
for Vec<T>
{
}