use core::fmt;
use core::fmt::Display;
use core::marker::Sized;
#[cfg(feature = "std")]
use std::error;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum EndianOrder {
Big,
Little,
}
#[cfg(target_endian = "big")]
pub const ENDIAN_ORDER_NATIVE: EndianOrder = EndianOrder::Big;
#[cfg(target_endian = "little")]
pub const ENDIAN_ORDER_NATIVE: EndianOrder = EndianOrder::Little;
#[cfg(target_endian = "big")]
pub const ENDIAN_ORDER_SWAP: EndianOrder = EndianOrder::Little;
#[cfg(target_endian = "little")]
pub const ENDIAN_ORDER_SWAP: EndianOrder = EndianOrder::Big;
impl Display for EndianOrder {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
EndianOrder::Big => write!(f, "Big"),
EndianOrder::Little => write!(f, "Little"),
}
}
}
#[derive(Clone, Copy, Debug)]
pub enum BinaryDecodeError {
EndOfInput {
offset: usize,
max_offset: usize,
capacity: usize,
count: usize,
},
I32toI8Conversion {
offset: usize,
value: i32,
},
I32toI16Conversion {
offset: usize,
value: i32,
},
InvalidBoolean {
offset: usize,
value: u64,
},
InvalidClamp {
capacity: usize,
offset: usize,
length: usize,
},
InvalidU64Magic {
expected: u64,
actual: [u8; 8],
},
InvalidStr {
offset: usize,
length: usize,
err: core::str::Utf8Error,
},
NonZero {
offset: usize,
count: usize,
},
NotSupported {
operation: &'static str,
},
MissingNull {
offset: usize,
},
RewindAlignment {
count: usize,
alignment: usize,
},
RewindPastStart {
offset: usize,
min_offset: usize,
count: usize,
},
SeekAlignment {
offset: usize,
alignment: usize,
},
SeekPastEnd {
offset: usize,
max_offset: usize,
capacity: usize,
},
SeekPastStart {
offset: usize,
min_offset: usize,
capacity: usize,
},
SkipAlignment {
count: usize,
alignment: usize,
},
U32toU8Conversion {
offset: usize,
value: u32,
},
U32toU16Conversion {
offset: usize,
value: u32,
},
UsizeConversion {
offset: usize,
value: u64,
},
}
impl fmt::Display for BinaryDecodeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
BinaryDecodeError::EndOfInput {
offset,
max_offset,
capacity,
count,
} => {
write!(
f,
"BinaryDecoder error, end of input at offset {offset} max_offset {max_offset} capacity {capacity} count {count}"
)
}
BinaryDecodeError::I32toI8Conversion { offset, value } => {
write!(
f,
"BinaryDecoder error, i32 to i8 conversion at offset {offset}, value {value}"
)
}
BinaryDecodeError::I32toI16Conversion { offset, value } => {
write!(
f,
"BinaryDecoder error, i32 to i16 conversion at offset {offset}, value {value}"
)
}
BinaryDecodeError::InvalidBoolean { offset, value } => {
write!(
f,
"BinaryDecoder error, invalid boolean at offset {offset} value {value}"
)
}
BinaryDecodeError::InvalidClamp {
capacity,
offset,
length,
} => {
write!(
f,
"BinaryDecoder error, invalid clamp offset {offset} length {length}) for capacity {capacity}"
)
}
BinaryDecodeError::InvalidU64Magic { expected, actual } => {
write!(
f,
"BinaryDecoder error, invalid u64 magic, expected 0x{expected:016x} actual {actual:#02x?}"
)
}
BinaryDecodeError::InvalidStr {
offset,
length,
err,
} => {
write!(
f,
"BinaryDecoder error, invalid UTF8 str of length {length} at offset {offset} | {err}"
)
}
BinaryDecodeError::NonZero { offset, count } => {
write!(
f,
"BinaryDecoder error, found non-zero in offset {offset} length {count}"
)
}
BinaryDecodeError::NotSupported { operation } => write!(
f,
"BinaryDecoder error, operation {operation} not supported"
),
BinaryDecodeError::MissingNull { offset } => {
write!(
f,
"BinaryDecoder error, did not find NULL byte after offset {offset}"
)
}
BinaryDecodeError::RewindAlignment { count, alignment } => {
write!(
f,
"BinaryDecoder error, rewind {count} is not a multiple of {alignment}"
)
}
BinaryDecodeError::RewindPastStart {
offset,
min_offset,
count,
} => {
write!(f, "BinaryDecoder error, rewind past start at offset {offset} min_offset {min_offset} count {count}")
}
BinaryDecodeError::SeekAlignment { offset, alignment } => {
write!(
f,
"BinaryDecoder error, seek {offset} is not a multiple of {alignment}"
)
}
BinaryDecodeError::SeekPastEnd {
offset,
max_offset,
capacity,
} => {
write!(
f,
"BinaryDecoder error, seek past end to offset {offset} max_offset {max_offset} capacity {capacity}"
)
}
BinaryDecodeError::SeekPastStart {
offset,
min_offset,
capacity,
} => {
write!(
f,
"BinaryDecoder error, seek past end to offset {offset} min_offset {min_offset} capacity {capacity}"
)
}
BinaryDecodeError::SkipAlignment { count, alignment } => {
write!(
f,
"BinaryDecoder error, skip {count} is not a multiple of {alignment}"
)
}
BinaryDecodeError::U32toU8Conversion { offset, value } => {
write!(
f,
"BinaryDecoder error, u32 to u8 conversion at offset {offset}, value {value}"
)
}
BinaryDecodeError::U32toU16Conversion { offset, value } => {
write!(
f,
"BinaryDecoder error, u32 to u16 conversion at offset {offset}, value {value}"
)
}
BinaryDecodeError::UsizeConversion { offset, value } => {
write!(
f,
"BinaryDecoder error, usize conversion at offset {offset}, value {value}"
)
}
}
}
}
#[cfg(feature = "std")]
impl error::Error for BinaryDecodeError {
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match self {
BinaryDecodeError::InvalidStr {
offset: _,
length: _,
err,
} => Some(err),
_ => None,
}
}
}
pub struct BinaryDecoderBuffer<'a> {
data: &'a [u8],
offset: usize,
min_offset: usize,
max_offset: usize,
}
impl fmt::Debug for BinaryDecoderBuffer<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("BinaryDecoderBuffer")
.field("length", &self.data.len())
.field("offset", &self.offset)
.field("min_offset", &self.min_offset)
.field("max_offset", &self.max_offset)
.finish()
}
}
impl BinaryDecoderBuffer<'_> {
fn from_bytes(data: &[u8]) -> BinaryDecoderBuffer<'_> {
BinaryDecoderBuffer {
data,
offset: 0,
min_offset: 0,
max_offset: data.len(),
}
}
fn from_bytes_clamped(
data: &[u8],
offset: usize,
length: usize,
) -> Result<BinaryDecoderBuffer<'_>, BinaryDecodeError> {
if offset > data.len() || data.len() - offset < length {
return Err(BinaryDecodeError::InvalidClamp {
capacity: data.len(),
offset,
length,
});
}
Ok(BinaryDecoderBuffer {
data,
offset,
min_offset: offset,
max_offset: offset + length,
})
}
fn capacity(&self) -> usize {
self.max_offset.saturating_sub(self.min_offset)
}
fn check_need(&self, count: usize) -> Result<(), BinaryDecodeError> {
if self.len() >= count {
Ok(())
} else {
Err(BinaryDecodeError::EndOfInput {
offset: self.offset,
max_offset: self.max_offset,
capacity: self.capacity(),
count,
})
}
}
fn is_empty(&self) -> bool {
self.len() == 0
}
fn len(&self) -> usize {
self.max_offset.saturating_sub(self.offset)
}
fn offset(&self) -> usize {
self.offset
}
fn reset(&mut self) {
self.offset = self.min_offset;
}
fn rewind(&mut self, count: usize) -> Result<(), BinaryDecodeError> {
let offset = self.offset;
let min_offset = self.min_offset;
if count > offset || offset - count < self.min_offset {
return Err(BinaryDecodeError::RewindPastStart {
offset,
min_offset,
count,
});
}
self.offset -= count;
Ok(())
}
fn seek(&mut self, offset: usize) -> Result<(), BinaryDecodeError> {
let capacity = self.capacity();
let min_offset = self.min_offset;
if offset < min_offset {
return Err(BinaryDecodeError::SeekPastStart {
offset,
min_offset,
capacity,
});
}
let max_offset = self.max_offset;
if offset > max_offset {
return Err(BinaryDecodeError::SeekPastEnd {
offset,
max_offset,
capacity,
});
}
self.offset = offset;
Ok(())
}
fn skip(&mut self, count: usize) -> Result<(), BinaryDecodeError> {
self.check_need(count)?;
self.offset += count;
Ok(())
}
fn skip_zeros(&mut self, count: usize) -> Result<(), BinaryDecodeError> {
let offset = self.offset;
let bytes = self.get_bytes(count)?;
for b in bytes {
if *b != 0 {
return Err(BinaryDecodeError::NonZero { offset, count });
}
}
Ok(())
}
fn is_skip_zeros(&mut self, count: usize) -> Result<bool, BinaryDecodeError> {
let offset = self.offset;
let bytes = self.get_bytes(count)?;
for b in bytes {
if *b != 0 {
self.offset = offset;
return Ok(false);
}
}
Ok(true)
}
fn get_1_byte(&mut self) -> Result<u8, BinaryDecodeError> {
self.check_need(1)?;
let offset = self.offset;
let value = self.data[offset];
self.offset += 1;
Ok(value)
}
fn get_2_bytes(&mut self) -> Result<[u8; 2], BinaryDecodeError> {
self.check_need(2)?;
let start = self.offset;
let end = start + 2;
self.offset = end;
Ok(<[u8; 2]>::try_from(&self.data[start..end]).unwrap())
}
fn get_4_bytes(&mut self) -> Result<[u8; 4], BinaryDecodeError> {
self.check_need(4)?;
let start = self.offset;
let end = start + 4;
self.offset = end;
Ok(<[u8; 4]>::try_from(&self.data[start..end]).unwrap())
}
fn get_8_bytes(&mut self) -> Result<[u8; 8], BinaryDecodeError> {
self.check_need(8)?;
let start = self.offset;
let end = start + 8;
self.offset = end;
Ok(<[u8; 8]>::try_from(&self.data[start..end]).unwrap())
}
}
impl<'a> BinaryDecoderBuffer<'a> {
fn data(&self) -> &'a [u8] {
self.data
}
fn get_bytes(&mut self, length: usize) -> Result<&'a [u8], BinaryDecodeError> {
self.check_need(length)?;
let start = self.offset;
let end = start + length;
let value = &self.data[start..end];
self.offset = end;
Ok(value)
}
fn get_str(&mut self, length: usize) -> Result<&'a str, BinaryDecodeError> {
let offset = self.offset;
let bytes = self.get_bytes(length)?;
match core::str::from_utf8(bytes) {
Ok(v) => Ok(v),
Err(err) => {
self.offset = offset;
Err(BinaryDecodeError::InvalidStr {
offset,
length,
err,
})
}
}
}
fn get_str_null(&mut self) -> Result<&'a str, BinaryDecodeError> {
let mut null_offset = self.offset;
while null_offset < self.max_offset {
if self.data[null_offset] == 0 {
let start = self.offset;
let end = null_offset;
let bytes = &self.data[start..end];
let value = match core::str::from_utf8(bytes) {
Ok(v) => v,
Err(err) => {
return Err(BinaryDecodeError::InvalidStr {
offset: self.offset,
length: end - start,
err,
})
}
};
self.offset = null_offset + 1;
return Ok(value);
}
null_offset += 1;
}
Err(BinaryDecodeError::MissingNull {
offset: self.offset,
})
}
}
pub trait BinaryDecoder<'a> {
fn capacity(&self) -> usize;
fn data(&self) -> &'a [u8];
fn is_empty(&self) -> bool;
fn len(&self) -> usize;
fn offset(&self) -> usize;
fn reset(&mut self);
fn rewind(&mut self, count: usize) -> Result<(), BinaryDecodeError>;
fn seek(&mut self, offset: usize) -> Result<(), BinaryDecodeError>;
fn skip(&mut self, count: usize) -> Result<(), BinaryDecodeError>;
fn skip_zeros(&mut self, count: usize) -> Result<(), BinaryDecodeError>;
fn is_skip_zeros(&mut self, count: usize) -> Result<bool, BinaryDecodeError>;
fn get_bool(&mut self) -> Result<bool, BinaryDecodeError>;
fn get_bytes(&mut self) -> Result<&'a [u8], BinaryDecodeError>;
fn get_bytes_n(&mut self, length: usize) -> Result<&'a [u8], BinaryDecodeError>;
fn get_str(&mut self) -> Result<&'a str, BinaryDecodeError>;
fn get_str_n(&mut self, length: usize) -> Result<&'a str, BinaryDecodeError>;
fn get_f32(&mut self) -> Result<f32, BinaryDecodeError>;
fn get_f64(&mut self) -> Result<f64, BinaryDecodeError>;
fn get_i8(&mut self) -> Result<i8, BinaryDecodeError>;
fn get_i16(&mut self) -> Result<i16, BinaryDecodeError>;
fn get_i32(&mut self) -> Result<i32, BinaryDecodeError>;
fn get_i64(&mut self) -> Result<i64, BinaryDecodeError>;
fn get_u8(&mut self) -> Result<u8, BinaryDecodeError>;
fn get_u16(&mut self) -> Result<u16, BinaryDecodeError>;
fn get_u32(&mut self) -> Result<u32, BinaryDecodeError>;
fn get_u64(&mut self) -> Result<u64, BinaryDecodeError>;
fn get_usize_16(&mut self) -> Result<usize, BinaryDecodeError> {
let value = self.get_u16()?;
Ok(usize::from(value))
}
fn get_usize_32(&mut self) -> Result<usize, BinaryDecodeError> {
let offset = self.offset();
let value = self.get_u32()?;
match usize::try_from(value) {
Ok(v) => Ok(v),
Err(_) => Err(BinaryDecodeError::UsizeConversion {
offset,
value: value.into(),
}),
}
}
fn get_usize_64(&mut self) -> Result<usize, BinaryDecodeError> {
let offset = self.offset();
let value = self.get_u64()?;
match usize::try_from(value) {
Ok(v) => Ok(v),
Err(_) => Err(BinaryDecodeError::UsizeConversion { offset, value }),
}
}
fn get<F: GetValueFromBinaryDecoder<'a>>(&mut self) -> Result<F, BinaryDecodeError>
where
Self: Sized,
{
GetValueFromBinaryDecoder::get_from_decoder(self)
}
fn get_n<F: GetNValueFromBinaryDecoder<'a>>(
&mut self,
length: usize,
) -> Result<F, BinaryDecodeError>
where
Self: Sized,
{
GetNValueFromBinaryDecoder::get_from_decoder_n(self, length)
}
}
pub trait EndianDecoder<'a>: BinaryDecoder<'a> {
fn order(&self) -> EndianOrder;
}
pub trait GetValueFromBinaryDecoder<'a>: Sized {
fn get_from_decoder(decoder: &mut dyn BinaryDecoder<'a>) -> Result<Self, BinaryDecodeError>;
}
impl GetValueFromBinaryDecoder<'_> for bool {
fn get_from_decoder(decoder: &mut dyn BinaryDecoder<'_>) -> Result<Self, BinaryDecodeError> {
decoder.get_bool()
}
}
impl<'a> GetValueFromBinaryDecoder<'a> for &'a [u8] {
fn get_from_decoder(decoder: &mut dyn BinaryDecoder<'a>) -> Result<Self, BinaryDecodeError> {
decoder.get_bytes()
}
}
impl<'a> GetValueFromBinaryDecoder<'a> for &'a str {
fn get_from_decoder(decoder: &mut dyn BinaryDecoder<'a>) -> Result<Self, BinaryDecodeError> {
decoder.get_str()
}
}
impl GetValueFromBinaryDecoder<'_> for f32 {
fn get_from_decoder(decoder: &mut dyn BinaryDecoder<'_>) -> Result<Self, BinaryDecodeError> {
decoder.get_f32()
}
}
impl GetValueFromBinaryDecoder<'_> for f64 {
fn get_from_decoder(decoder: &mut dyn BinaryDecoder<'_>) -> Result<Self, BinaryDecodeError> {
decoder.get_f64()
}
}
impl GetValueFromBinaryDecoder<'_> for i8 {
fn get_from_decoder(decoder: &mut dyn BinaryDecoder<'_>) -> Result<Self, BinaryDecodeError> {
decoder.get_i8()
}
}
impl GetValueFromBinaryDecoder<'_> for i16 {
fn get_from_decoder(decoder: &mut dyn BinaryDecoder<'_>) -> Result<Self, BinaryDecodeError> {
decoder.get_i16()
}
}
impl GetValueFromBinaryDecoder<'_> for i32 {
fn get_from_decoder(decoder: &mut dyn BinaryDecoder<'_>) -> Result<Self, BinaryDecodeError> {
decoder.get_i32()
}
}
impl GetValueFromBinaryDecoder<'_> for i64 {
fn get_from_decoder(decoder: &mut dyn BinaryDecoder<'_>) -> Result<Self, BinaryDecodeError> {
decoder.get_i64()
}
}
impl GetValueFromBinaryDecoder<'_> for u8 {
fn get_from_decoder(decoder: &mut dyn BinaryDecoder<'_>) -> Result<Self, BinaryDecodeError> {
decoder.get_u8()
}
}
impl GetValueFromBinaryDecoder<'_> for u16 {
fn get_from_decoder(decoder: &mut dyn BinaryDecoder<'_>) -> Result<Self, BinaryDecodeError> {
decoder.get_u16()
}
}
impl GetValueFromBinaryDecoder<'_> for u32 {
fn get_from_decoder(decoder: &mut dyn BinaryDecoder<'_>) -> Result<Self, BinaryDecodeError> {
decoder.get_u32()
}
}
impl GetValueFromBinaryDecoder<'_> for u64 {
fn get_from_decoder(decoder: &mut dyn BinaryDecoder<'_>) -> Result<Self, BinaryDecodeError> {
decoder.get_u64()
}
}
pub trait GetNValueFromBinaryDecoder<'a>: Sized {
fn get_from_decoder_n(
decoder: &mut dyn BinaryDecoder<'a>,
length: usize,
) -> Result<Self, BinaryDecodeError>;
}
impl<'a> GetNValueFromBinaryDecoder<'a> for &'a [u8] {
fn get_from_decoder_n(
decoder: &mut dyn BinaryDecoder<'a>,
length: usize,
) -> Result<Self, BinaryDecodeError> {
decoder.get_bytes_n(length)
}
}
impl<'a> GetNValueFromBinaryDecoder<'a> for &'a str {
fn get_from_decoder_n(
decoder: &mut dyn BinaryDecoder<'a>,
length: usize,
) -> Result<Self, BinaryDecodeError> {
decoder.get_str_n(length)
}
}
#[derive(Debug)]
pub struct BigEndianDecoder<'a> {
buffer: BinaryDecoderBuffer<'a>,
}
impl BigEndianDecoder<'_> {
pub fn from_bytes(data: &[u8]) -> BigEndianDecoder<'_> {
BigEndianDecoder {
buffer: BinaryDecoderBuffer::from_bytes(data),
}
}
pub fn from_bytes_clamped(
data: &[u8],
offset: usize,
length: usize,
) -> Result<BigEndianDecoder<'_>, BinaryDecodeError> {
Ok(BigEndianDecoder {
buffer: BinaryDecoderBuffer::from_bytes_clamped(data, offset, length)?,
})
}
}
impl<'a> BinaryDecoder<'a> for BigEndianDecoder<'a> {
fn capacity(&self) -> usize {
self.buffer.capacity()
}
fn data(&self) -> &'a [u8] {
self.buffer.data()
}
fn len(&self) -> usize {
self.buffer.len()
}
fn is_empty(&self) -> bool {
self.buffer.is_empty()
}
fn offset(&self) -> usize {
self.buffer.offset()
}
fn reset(&mut self) {
self.buffer.reset()
}
fn rewind(&mut self, count: usize) -> Result<(), BinaryDecodeError> {
self.buffer.rewind(count)
}
fn seek(&mut self, offset: usize) -> Result<(), BinaryDecodeError> {
self.buffer.seek(offset)
}
fn skip(&mut self, count: usize) -> Result<(), BinaryDecodeError> {
self.buffer.skip(count)
}
fn skip_zeros(&mut self, count: usize) -> Result<(), BinaryDecodeError> {
self.buffer.skip_zeros(count)
}
fn is_skip_zeros(&mut self, count: usize) -> Result<bool, BinaryDecodeError> {
self.buffer.is_skip_zeros(count)
}
fn get_bool(&mut self) -> Result<bool, BinaryDecodeError> {
let offset = self.buffer.offset;
let value = self.get_u32()?;
match value {
0 => Ok(false),
1 => Ok(true),
_ => Err(BinaryDecodeError::InvalidBoolean {
offset,
value: value.into(),
}),
}
}
fn get_bytes(&mut self) -> Result<&'a [u8], BinaryDecodeError> {
Err(BinaryDecodeError::NotSupported {
operation: "get_bytes",
})
}
fn get_bytes_n(&mut self, length: usize) -> Result<&'a [u8], BinaryDecodeError> {
self.buffer.get_bytes(length)
}
fn get_str(&mut self) -> Result<&'a str, BinaryDecodeError> {
self.buffer.get_str_null()
}
fn get_str_n(&mut self, length: usize) -> Result<&'a str, BinaryDecodeError> {
self.buffer.get_str(length)
}
fn get_f32(&mut self) -> Result<f32, BinaryDecodeError> {
Ok(f32::from_be_bytes(self.buffer.get_4_bytes()?))
}
fn get_f64(&mut self) -> Result<f64, BinaryDecodeError> {
Ok(f64::from_be_bytes(self.buffer.get_8_bytes()?))
}
fn get_i8(&mut self) -> Result<i8, BinaryDecodeError> {
let value = self.buffer.get_1_byte()?;
Ok(value as i8)
}
fn get_i16(&mut self) -> Result<i16, BinaryDecodeError> {
Ok(i16::from_be_bytes(self.buffer.get_2_bytes()?))
}
fn get_i32(&mut self) -> Result<i32, BinaryDecodeError> {
Ok(i32::from_be_bytes(self.buffer.get_4_bytes()?))
}
fn get_i64(&mut self) -> Result<i64, BinaryDecodeError> {
Ok(i64::from_be_bytes(self.buffer.get_8_bytes()?))
}
fn get_u8(&mut self) -> Result<u8, BinaryDecodeError> {
self.buffer.get_1_byte()
}
fn get_u16(&mut self) -> Result<u16, BinaryDecodeError> {
Ok(u16::from_be_bytes(self.buffer.get_2_bytes()?))
}
fn get_u32(&mut self) -> Result<u32, BinaryDecodeError> {
Ok(u32::from_be_bytes(self.buffer.get_4_bytes()?))
}
fn get_u64(&mut self) -> Result<u64, BinaryDecodeError> {
Ok(u64::from_be_bytes(self.buffer.get_8_bytes()?))
}
}
impl<'a> EndianDecoder<'a> for BigEndianDecoder<'a> {
fn order(&self) -> EndianOrder {
EndianOrder::Big
}
}
#[derive(Debug)]
pub struct LittleEndianDecoder<'a> {
buffer: BinaryDecoderBuffer<'a>,
}
impl LittleEndianDecoder<'_> {
pub fn from_bytes(data: &[u8]) -> LittleEndianDecoder<'_> {
LittleEndianDecoder {
buffer: BinaryDecoderBuffer::from_bytes(data),
}
}
pub fn from_bytes_clamped(
data: &[u8],
offset: usize,
length: usize,
) -> Result<LittleEndianDecoder<'_>, BinaryDecodeError> {
Ok(LittleEndianDecoder {
buffer: BinaryDecoderBuffer::from_bytes_clamped(data, offset, length)?,
})
}
}
impl<'a> BinaryDecoder<'a> for LittleEndianDecoder<'a> {
fn capacity(&self) -> usize {
self.buffer.capacity()
}
fn data(&self) -> &'a [u8] {
self.buffer.data()
}
fn len(&self) -> usize {
self.buffer.len()
}
fn is_empty(&self) -> bool {
self.buffer.is_empty()
}
fn offset(&self) -> usize {
self.buffer.offset()
}
fn reset(&mut self) {
self.buffer.reset()
}
fn rewind(&mut self, count: usize) -> Result<(), BinaryDecodeError> {
self.buffer.rewind(count)
}
fn seek(&mut self, offset: usize) -> Result<(), BinaryDecodeError> {
self.buffer.seek(offset)
}
fn skip(&mut self, count: usize) -> Result<(), BinaryDecodeError> {
self.buffer.skip(count)
}
fn skip_zeros(&mut self, count: usize) -> Result<(), BinaryDecodeError> {
self.buffer.skip_zeros(count)
}
fn is_skip_zeros(&mut self, count: usize) -> Result<bool, BinaryDecodeError> {
self.buffer.is_skip_zeros(count)
}
fn get_bool(&mut self) -> Result<bool, BinaryDecodeError> {
let offset = self.buffer.offset;
let value = self.get_u32()?;
match value {
0 => Ok(false),
1 => Ok(true),
_ => Err(BinaryDecodeError::InvalidBoolean {
offset,
value: value.into(),
}),
}
}
fn get_bytes(&mut self) -> Result<&'a [u8], BinaryDecodeError> {
Err(BinaryDecodeError::NotSupported {
operation: "get_bytes",
})
}
fn get_bytes_n(&mut self, length: usize) -> Result<&'a [u8], BinaryDecodeError> {
self.buffer.get_bytes(length)
}
fn get_str(&mut self) -> Result<&'a str, BinaryDecodeError> {
self.buffer.get_str_null()
}
fn get_str_n(&mut self, length: usize) -> Result<&'a str, BinaryDecodeError> {
self.buffer.get_str(length)
}
fn get_f32(&mut self) -> Result<f32, BinaryDecodeError> {
Ok(f32::from_le_bytes(self.buffer.get_4_bytes()?))
}
fn get_f64(&mut self) -> Result<f64, BinaryDecodeError> {
Ok(f64::from_le_bytes(self.buffer.get_8_bytes()?))
}
fn get_i8(&mut self) -> Result<i8, BinaryDecodeError> {
let value = self.buffer.get_1_byte()?;
Ok(value as i8)
}
fn get_i16(&mut self) -> Result<i16, BinaryDecodeError> {
Ok(i16::from_le_bytes(self.buffer.get_2_bytes()?))
}
fn get_i32(&mut self) -> Result<i32, BinaryDecodeError> {
Ok(i32::from_le_bytes(self.buffer.get_4_bytes()?))
}
fn get_i64(&mut self) -> Result<i64, BinaryDecodeError> {
Ok(i64::from_le_bytes(self.buffer.get_8_bytes()?))
}
fn get_u8(&mut self) -> Result<u8, BinaryDecodeError> {
self.buffer.get_1_byte()
}
fn get_u16(&mut self) -> Result<u16, BinaryDecodeError> {
Ok(u16::from_le_bytes(self.buffer.get_2_bytes()?))
}
fn get_u32(&mut self) -> Result<u32, BinaryDecodeError> {
Ok(u32::from_le_bytes(self.buffer.get_4_bytes()?))
}
fn get_u64(&mut self) -> Result<u64, BinaryDecodeError> {
Ok(u64::from_le_bytes(self.buffer.get_8_bytes()?))
}
}
impl<'a> EndianDecoder<'a> for LittleEndianDecoder<'a> {
fn order(&self) -> EndianOrder {
EndianOrder::Little
}
}
#[derive(Debug)]
pub enum BigLittleEndianDecoder<'a> {
Big(BigEndianDecoder<'a>),
Little(LittleEndianDecoder<'a>),
}
impl BigLittleEndianDecoder<'_> {
pub fn from_bytes(data: &[u8], order: EndianOrder) -> BigLittleEndianDecoder<'_> {
match order {
EndianOrder::Big => BigLittleEndianDecoder::Big(BigEndianDecoder::from_bytes(data)),
EndianOrder::Little => {
BigLittleEndianDecoder::Little(LittleEndianDecoder::from_bytes(data))
}
}
}
pub fn from_bytes_clamped(
data: &[u8],
offset: usize,
length: usize,
order: EndianOrder,
) -> Result<BigLittleEndianDecoder<'_>, BinaryDecodeError> {
match order {
EndianOrder::Big => Ok(BigLittleEndianDecoder::Big(
BigEndianDecoder::from_bytes_clamped(data, offset, length)?,
)),
EndianOrder::Little => Ok(BigLittleEndianDecoder::Little(
LittleEndianDecoder::from_bytes_clamped(data, offset, length)?,
)),
}
}
pub fn from_u64_magic(
data: &[u8],
magic: u64,
) -> Result<BigLittleEndianDecoder<'_>, BinaryDecodeError> {
let mut decoder = LittleEndianDecoder::from_bytes(data);
let data_magic = decoder.get_u64()?;
if data_magic == magic {
return Ok(BigLittleEndianDecoder::Little(decoder));
}
let mut decoder = BigEndianDecoder::from_bytes(data);
let data_magic = decoder.get_u64()?;
if data_magic == magic {
return Ok(BigLittleEndianDecoder::Big(decoder));
}
Err(BinaryDecodeError::InvalidU64Magic {
expected: magic,
actual: data_magic.to_le_bytes(),
})
}
}
impl<'a, 'b> BigLittleEndianDecoder<'a> {
pub fn decoder_as_mut(&'b mut self) -> &'b mut dyn EndianDecoder<'a> {
match self {
BigLittleEndianDecoder::Big(decoder) => decoder,
BigLittleEndianDecoder::Little(decoder) => decoder,
}
}
pub fn decoder_as_ref(&'b self) -> &'b dyn EndianDecoder<'a> {
match self {
BigLittleEndianDecoder::Big(decoder) => decoder,
BigLittleEndianDecoder::Little(decoder) => decoder,
}
}
}
#[derive(Debug)]
pub enum BigLittleXdrEndianDecoder<'a> {
BigLittle(BigLittleEndianDecoder<'a>),
Xdr(XdrDecoder<'a>),
}
impl<'a, 'b> BigLittleXdrEndianDecoder<'a> {
pub fn decoder_as_mut(&'b mut self) -> &'b mut dyn BinaryDecoder<'a> {
match self {
BigLittleXdrEndianDecoder::BigLittle(decoder) => decoder.decoder_as_mut(),
BigLittleXdrEndianDecoder::Xdr(decoder) => decoder,
}
}
pub fn decoder_as_ref(&'b self) -> &'b dyn BinaryDecoder<'a> {
match self {
BigLittleXdrEndianDecoder::BigLittle(decoder) => decoder.decoder_as_ref(),
BigLittleXdrEndianDecoder::Xdr(decoder) => decoder,
}
}
}
#[derive(Debug)]
pub struct XdrDecoder<'a> {
buffer: BinaryDecoderBuffer<'a>,
}
impl XdrDecoder<'_> {
const ALIGNMENT: usize = 4;
}
impl XdrDecoder<'_> {
fn consume_padding(&mut self, length: usize) -> Result<(), BinaryDecodeError> {
let remainder = length % Self::ALIGNMENT;
if remainder != 0 {
let padding = Self::ALIGNMENT - remainder;
self.buffer.skip_zeros(padding)?;
}
Ok(())
}
pub fn from_bytes(data: &[u8]) -> XdrDecoder<'_> {
XdrDecoder {
buffer: BinaryDecoderBuffer::from_bytes(data),
}
}
pub fn from_bytes_clamped(
data: &[u8],
offset: usize,
length: usize,
) -> Result<XdrDecoder<'_>, BinaryDecodeError> {
Ok(XdrDecoder {
buffer: BinaryDecoderBuffer::from_bytes_clamped(data, offset, length)?,
})
}
}
impl<'a> BinaryDecoder<'a> for XdrDecoder<'a> {
fn capacity(&self) -> usize {
self.buffer.capacity()
}
fn data(&self) -> &'a [u8] {
self.buffer.data()
}
fn len(&self) -> usize {
self.buffer.len()
}
fn is_empty(&self) -> bool {
self.buffer.is_empty()
}
fn offset(&self) -> usize {
self.buffer.offset()
}
fn reset(&mut self) {
self.buffer.reset()
}
fn rewind(&mut self, count: usize) -> Result<(), BinaryDecodeError> {
if !count.is_multiple_of(Self::ALIGNMENT) {
return Err(BinaryDecodeError::RewindAlignment {
count,
alignment: Self::ALIGNMENT,
});
}
self.buffer.rewind(count)
}
fn seek(&mut self, offset: usize) -> Result<(), BinaryDecodeError> {
if !offset.is_multiple_of(Self::ALIGNMENT) {
return Err(BinaryDecodeError::SeekAlignment {
offset,
alignment: Self::ALIGNMENT,
});
}
self.buffer.seek(offset)
}
fn skip(&mut self, count: usize) -> Result<(), BinaryDecodeError> {
if !count.is_multiple_of(Self::ALIGNMENT) {
return Err(BinaryDecodeError::SkipAlignment {
count,
alignment: Self::ALIGNMENT,
});
}
self.buffer.skip(count)
}
fn skip_zeros(&mut self, count: usize) -> Result<(), BinaryDecodeError> {
if !count.is_multiple_of(Self::ALIGNMENT) {
return Err(BinaryDecodeError::SkipAlignment {
count,
alignment: Self::ALIGNMENT,
});
}
self.buffer.skip_zeros(count)
}
fn is_skip_zeros(&mut self, count: usize) -> Result<bool, BinaryDecodeError> {
if !count.is_multiple_of(Self::ALIGNMENT) {
return Err(BinaryDecodeError::SkipAlignment {
count,
alignment: Self::ALIGNMENT,
});
}
self.buffer.is_skip_zeros(count)
}
fn get_bool(&mut self) -> Result<bool, BinaryDecodeError> {
let offset = self.buffer.offset;
let value = self.get_u32()?;
match value {
0 => Ok(false),
1 => Ok(true),
_ => Err(BinaryDecodeError::InvalidBoolean {
offset,
value: value.into(),
}),
}
}
fn get_bytes(&mut self) -> Result<&'a [u8], BinaryDecodeError> {
let length = self.get_usize_32()?;
self.get_bytes_n(length)
}
fn get_bytes_n(&mut self, length: usize) -> Result<&'a [u8], BinaryDecodeError> {
let value = self.buffer.get_bytes(length)?;
self.consume_padding(length)?;
Ok(value)
}
fn get_str(&mut self) -> Result<&'a str, BinaryDecodeError> {
let length = self.get_usize_32()?;
self.get_str_n(length)
}
fn get_str_n(&mut self, length: usize) -> Result<&'a str, BinaryDecodeError> {
let value = self.buffer.get_str(length)?;
self.consume_padding(length)?;
Ok(value)
}
fn get_f32(&mut self) -> Result<f32, BinaryDecodeError> {
Ok(f32::from_be_bytes(self.buffer.get_4_bytes()?))
}
fn get_f64(&mut self) -> Result<f64, BinaryDecodeError> {
Ok(f64::from_be_bytes(self.buffer.get_8_bytes()?))
}
fn get_i8(&mut self) -> Result<i8, BinaryDecodeError> {
let offset = self.buffer.offset;
let value = self.get_i32()?;
match i8::try_from(value) {
Ok(v) => Ok(v),
Err(_) => Err(BinaryDecodeError::I32toI8Conversion { offset, value }),
}
}
fn get_i16(&mut self) -> Result<i16, BinaryDecodeError> {
let offset = self.buffer.offset;
let value = self.get_i32()?;
match i16::try_from(value) {
Ok(v) => Ok(v),
Err(_) => Err(BinaryDecodeError::I32toI16Conversion { offset, value }),
}
}
fn get_i32(&mut self) -> Result<i32, BinaryDecodeError> {
Ok(i32::from_be_bytes(self.buffer.get_4_bytes()?))
}
fn get_i64(&mut self) -> Result<i64, BinaryDecodeError> {
Ok(i64::from_be_bytes(self.buffer.get_8_bytes()?))
}
fn get_u8(&mut self) -> Result<u8, BinaryDecodeError> {
let offset = self.buffer.offset;
let mut value = self.get_u32()?;
if value >= 0xffffff80 {
value -= 0xffffff00;
}
match u8::try_from(value) {
Ok(v) => Ok(v),
Err(_) => Err(BinaryDecodeError::U32toU8Conversion { offset, value }),
}
}
fn get_u16(&mut self) -> Result<u16, BinaryDecodeError> {
let offset = self.buffer.offset;
let value = self.get_u32()?;
match u16::try_from(value) {
Ok(v) => Ok(v),
Err(_) => Err(BinaryDecodeError::U32toU16Conversion { offset, value }),
}
}
fn get_u32(&mut self) -> Result<u32, BinaryDecodeError> {
Ok(u32::from_be_bytes(self.buffer.get_4_bytes()?))
}
fn get_u64(&mut self) -> Result<u64, BinaryDecodeError> {
Ok(u64::from_be_bytes(self.buffer.get_8_bytes()?))
}
}
#[derive(Debug)]
pub enum BinaryEncodeError {
EndOfOutput {
offset: usize,
capacity: usize,
count: usize,
},
NotSupported {
operation: &'static str,
},
RewindPastStart {
offset: usize,
count: usize,
},
SeekPastEnd {
offset: usize,
capacity: usize,
},
UsizeConversion {
offset: usize,
value: usize,
},
}
impl fmt::Display for BinaryEncodeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
BinaryEncodeError::EndOfOutput {
offset,
capacity,
count,
} => {
write!(
f,
"BinaryEncoder error, end of output at offset {offset} capacity {capacity} count {count}"
)
}
BinaryEncodeError::NotSupported { operation } => write!(
f,
"BinaryEncoder error, operation {operation} not supported"
),
BinaryEncodeError::RewindPastStart { offset, count } => {
write!(
f,
"BinaryEncoder error, rewind past start at offset {offset} count {count}"
)
}
BinaryEncodeError::SeekPastEnd { offset, capacity } => {
write!(
f,
"BinaryEncoder error, seek past end to offset {offset} capacity {capacity}"
)
}
BinaryEncodeError::UsizeConversion { offset, value } => {
write!(
f,
"BinaryEncoder error, usize conversion at offset {offset}, value {value}"
)
}
}
}
}
#[cfg(feature = "std")]
impl error::Error for BinaryEncodeError {
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
None
}
}
pub struct BinaryEncoderBuffer<'a> {
data: &'a mut [u8],
offset: usize,
}
impl fmt::Debug for BinaryEncoderBuffer<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("BinaryEncoderBuffer")
.field("length", &self.data.len())
.field("offset", &self.offset)
.finish()
}
}
impl<'a> BinaryEncoderBuffer<'a> {
fn check_need(&self, count: usize) -> Result<(), BinaryEncodeError> {
if self.available() >= count {
Ok(())
} else {
Err(BinaryEncodeError::EndOfOutput {
offset: self.offset,
capacity: self.capacity(),
count,
})
}
}
fn available(&self) -> usize {
self.data.len().saturating_sub(self.offset)
}
fn capacity(&self) -> usize {
self.data.len()
}
fn finish(self) -> &'a [u8] {
&self.data[0..self.offset]
}
fn is_empty(&self) -> bool {
self.offset == 0
}
fn is_full(&self) -> bool {
self.offset >= self.data.len()
}
fn len(&self) -> usize {
self.offset
}
fn offset(&self) -> usize {
self.offset
}
fn reset(&mut self) {
self.offset = 0;
}
fn rewind(&mut self, count: usize) -> Result<(), BinaryEncodeError> {
let offset = self.offset;
if count > offset {
return Err(BinaryEncodeError::RewindPastStart { offset, count });
}
self.offset -= count;
Ok(())
}
fn seek(&mut self, offset: usize) -> Result<(), BinaryEncodeError> {
let capacity = self.capacity();
if offset > capacity {
return Err(BinaryEncodeError::SeekPastEnd { offset, capacity });
}
self.offset = offset;
Ok(())
}
fn skip(&mut self, count: usize) -> Result<(), BinaryEncodeError> {
self.check_need(count)?;
self.offset += count;
Ok(())
}
fn put_zeros(&mut self, count: usize) -> Result<(), BinaryEncodeError> {
self.check_need(count)?;
let start = self.offset;
let end = start + count;
self.offset = end;
self.data[start..end].fill(0);
Ok(())
}
fn put_1_byte(&mut self, value: u8) -> Result<(), BinaryEncodeError> {
self.check_need(1)?;
self.data[self.offset] = value;
self.offset += 1;
Ok(())
}
fn put_2_bytes(&mut self, data: [u8; 2]) -> Result<(), BinaryEncodeError> {
self.check_need(2)?;
let start = self.offset;
let end = start + 2;
self.offset = end;
self.data[start..end].copy_from_slice(&data);
Ok(())
}
fn put_4_bytes(&mut self, data: [u8; 4]) -> Result<(), BinaryEncodeError> {
self.check_need(4)?;
let start = self.offset;
let end = start + 4;
self.offset = end;
self.data[start..end].copy_from_slice(&data);
Ok(())
}
fn put_8_bytes(&mut self, data: [u8; 8]) -> Result<(), BinaryEncodeError> {
self.check_need(8)?;
let start = self.offset;
let end = start + 8;
self.offset = end;
self.data[start..end].copy_from_slice(&data);
Ok(())
}
fn put_bytes(&mut self, data: &[u8]) -> Result<(), BinaryEncodeError> {
let length = data.len();
self.check_need(length)?;
let start = self.offset;
let end = start + length;
self.offset = end;
self.data[start..end].copy_from_slice(data);
Ok(())
}
}
pub trait BinaryEncoder<'a> {
fn available(&self) -> usize;
fn capacity(&self) -> usize;
fn finish(self) -> &'a [u8];
fn is_empty(&self) -> bool;
fn is_full(&self) -> bool;
fn len(&self) -> usize;
fn offset(&self) -> usize;
fn reset(&mut self);
fn rewind(&mut self, count: usize) -> Result<(), BinaryEncodeError>;
fn seek(&mut self, offset: usize) -> Result<(), BinaryEncodeError>;
fn skip(&mut self, count: usize) -> Result<(), BinaryEncodeError>;
fn put_bool(&mut self, value: bool) -> Result<(), BinaryEncodeError>;
fn put_bytes(&mut self, value: &[u8]) -> Result<(), BinaryEncodeError>;
fn put_bytes_n(&mut self, value: &[u8]) -> Result<(), BinaryEncodeError>;
fn put_str(&mut self, value: &str) -> Result<(), BinaryEncodeError>;
fn put_str_n(&mut self, value: &str) -> Result<(), BinaryEncodeError>;
fn put_f32(&mut self, value: f32) -> Result<(), BinaryEncodeError>;
fn put_f64(&mut self, value: f64) -> Result<(), BinaryEncodeError>;
fn put_i8(&mut self, value: i8) -> Result<(), BinaryEncodeError>;
fn put_i16(&mut self, value: i16) -> Result<(), BinaryEncodeError>;
fn put_i32(&mut self, value: i32) -> Result<(), BinaryEncodeError>;
fn put_i64(&mut self, value: i64) -> Result<(), BinaryEncodeError>;
fn put_u8(&mut self, value: u8) -> Result<(), BinaryEncodeError>;
fn put_u16(&mut self, value: u16) -> Result<(), BinaryEncodeError>;
fn put_u32(&mut self, value: u32) -> Result<(), BinaryEncodeError>;
fn put_u64(&mut self, value: u64) -> Result<(), BinaryEncodeError>;
fn put_usize_32(&mut self, value: usize) -> Result<(), BinaryEncodeError> {
let offset = self.offset();
match u32::try_from(value) {
Ok(v) => self.put_u32(v),
Err(_) => Err(BinaryEncodeError::UsizeConversion { offset, value }),
}
}
fn put_usize_64(&mut self, value: usize) -> Result<(), BinaryEncodeError> {
let offset = self.offset();
match u64::try_from(value) {
Ok(v) => self.put_u64(v),
Err(_) => Err(BinaryEncodeError::UsizeConversion { offset, value }),
}
}
fn put_zeros(&mut self, count: usize) -> Result<(), BinaryEncodeError>;
fn put<F: PutValueIntoBinaryEncode<'a>>(&mut self, value: F) -> Result<(), BinaryEncodeError>
where
Self: Sized,
{
PutValueIntoBinaryEncode::put_into_encoder(self, value)
}
fn put_n<F: PutNValueIntoBinaryEncoder<'a>>(
&mut self,
value: F,
) -> Result<(), BinaryEncodeError>
where
Self: Sized,
{
PutNValueIntoBinaryEncoder::put_into_encoder(self, value)
}
}
pub trait EndianEncoder<'a>: BinaryEncoder<'a> {
fn order(&self) -> EndianOrder;
}
pub trait PutValueIntoBinaryEncode<'a>: Sized {
fn put_into_encoder(
encoder: &mut dyn BinaryEncoder<'_>,
value: Self,
) -> Result<(), BinaryEncodeError>;
}
impl PutValueIntoBinaryEncode<'_> for bool {
fn put_into_encoder(
encoder: &mut dyn BinaryEncoder<'_>,
value: bool,
) -> Result<(), BinaryEncodeError> {
encoder.put_bool(value)
}
}
impl PutValueIntoBinaryEncode<'_> for &[u8] {
fn put_into_encoder(
encoder: &mut dyn BinaryEncoder<'_>,
value: &[u8],
) -> Result<(), BinaryEncodeError> {
encoder.put_bytes(value)
}
}
impl PutValueIntoBinaryEncode<'_> for &str {
fn put_into_encoder(
encoder: &mut dyn BinaryEncoder<'_>,
value: &str,
) -> Result<(), BinaryEncodeError> {
encoder.put_str(value)
}
}
impl PutValueIntoBinaryEncode<'_> for f32 {
fn put_into_encoder(
encoder: &mut dyn BinaryEncoder<'_>,
value: f32,
) -> Result<(), BinaryEncodeError> {
encoder.put_f32(value)
}
}
impl PutValueIntoBinaryEncode<'_> for f64 {
fn put_into_encoder(
encoder: &mut dyn BinaryEncoder<'_>,
value: f64,
) -> Result<(), BinaryEncodeError> {
encoder.put_f64(value)
}
}
impl PutValueIntoBinaryEncode<'_> for i8 {
fn put_into_encoder(
encoder: &mut dyn BinaryEncoder<'_>,
value: i8,
) -> Result<(), BinaryEncodeError> {
encoder.put_i8(value)
}
}
impl PutValueIntoBinaryEncode<'_> for i16 {
fn put_into_encoder(
encoder: &mut dyn BinaryEncoder<'_>,
value: i16,
) -> Result<(), BinaryEncodeError> {
encoder.put_i16(value)
}
}
impl PutValueIntoBinaryEncode<'_> for i32 {
fn put_into_encoder(
encoder: &mut dyn BinaryEncoder<'_>,
value: i32,
) -> Result<(), BinaryEncodeError> {
encoder.put_i32(value)
}
}
impl PutValueIntoBinaryEncode<'_> for i64 {
fn put_into_encoder(
encoder: &mut dyn BinaryEncoder<'_>,
value: i64,
) -> Result<(), BinaryEncodeError> {
encoder.put_i64(value)
}
}
impl PutValueIntoBinaryEncode<'_> for u8 {
fn put_into_encoder(
encoder: &mut dyn BinaryEncoder<'_>,
value: u8,
) -> Result<(), BinaryEncodeError> {
encoder.put_u8(value)
}
}
impl PutValueIntoBinaryEncode<'_> for u16 {
fn put_into_encoder(
encoder: &mut dyn BinaryEncoder<'_>,
value: u16,
) -> Result<(), BinaryEncodeError> {
encoder.put_u16(value)
}
}
impl PutValueIntoBinaryEncode<'_> for u32 {
fn put_into_encoder(
encoder: &mut dyn BinaryEncoder<'_>,
value: u32,
) -> Result<(), BinaryEncodeError> {
encoder.put_u32(value)
}
}
impl PutValueIntoBinaryEncode<'_> for u64 {
fn put_into_encoder(
encoder: &mut dyn BinaryEncoder<'_>,
value: u64,
) -> Result<(), BinaryEncodeError> {
encoder.put_u64(value)
}
}
pub trait PutNValueIntoBinaryEncoder<'a>: Sized {
fn put_into_encoder(
encoder: &mut dyn BinaryEncoder<'_>,
value: Self,
) -> Result<(), BinaryEncodeError>;
}
impl PutNValueIntoBinaryEncoder<'_> for &[u8] {
fn put_into_encoder(
encoder: &mut dyn BinaryEncoder<'_>,
value: &[u8],
) -> Result<(), BinaryEncodeError> {
encoder.put_bytes_n(value)
}
}
impl PutNValueIntoBinaryEncoder<'_> for &str {
fn put_into_encoder(
encoder: &mut dyn BinaryEncoder<'_>,
value: &str,
) -> Result<(), BinaryEncodeError> {
encoder.put_str_n(value)
}
}
pub struct BigEndianEncoder<'a> {
buffer: BinaryEncoderBuffer<'a>,
}
impl<'a> BinaryEncoder<'a> for BigEndianEncoder<'a> {
fn available(&self) -> usize {
self.buffer.available()
}
fn capacity(&self) -> usize {
self.buffer.capacity()
}
fn finish(self) -> &'a [u8] {
self.buffer.finish()
}
fn is_empty(&self) -> bool {
self.buffer.is_empty()
}
fn is_full(&self) -> bool {
self.buffer.is_full()
}
fn len(&self) -> usize {
self.buffer.len()
}
fn offset(&self) -> usize {
self.buffer.offset()
}
fn reset(&mut self) {
self.buffer.reset()
}
fn rewind(&mut self, count: usize) -> Result<(), BinaryEncodeError> {
self.buffer.rewind(count)
}
fn seek(&mut self, offset: usize) -> Result<(), BinaryEncodeError> {
self.buffer.seek(offset)
}
fn skip(&mut self, count: usize) -> Result<(), BinaryEncodeError> {
self.buffer.skip(count)
}
fn put_bool(&mut self, value: bool) -> Result<(), BinaryEncodeError> {
self.put_u32(match value {
false => 0,
true => 1,
})
}
fn put_bytes(&mut self, _value: &[u8]) -> Result<(), BinaryEncodeError> {
Err(BinaryEncodeError::NotSupported {
operation: "put_bytes",
})
}
fn put_bytes_n(&mut self, value: &[u8]) -> Result<(), BinaryEncodeError> {
self.buffer.put_bytes(value)
}
fn put_str(&mut self, value: &str) -> Result<(), BinaryEncodeError> {
self.put_str_n(value)?;
self.buffer.put_1_byte(0)
}
fn put_str_n(&mut self, value: &str) -> Result<(), BinaryEncodeError> {
self.buffer.put_bytes(value.as_bytes())
}
fn put_f32(&mut self, value: f32) -> Result<(), BinaryEncodeError> {
self.buffer.put_4_bytes(f32::to_be_bytes(value))
}
fn put_f64(&mut self, value: f64) -> Result<(), BinaryEncodeError> {
self.buffer.put_8_bytes(f64::to_be_bytes(value))
}
fn put_i8(&mut self, value: i8) -> Result<(), BinaryEncodeError> {
self.buffer.put_1_byte(value as u8)
}
fn put_i16(&mut self, value: i16) -> Result<(), BinaryEncodeError> {
self.buffer.put_2_bytes(i16::to_be_bytes(value))
}
fn put_i32(&mut self, value: i32) -> Result<(), BinaryEncodeError> {
self.buffer.put_4_bytes(i32::to_be_bytes(value))
}
fn put_i64(&mut self, value: i64) -> Result<(), BinaryEncodeError> {
self.buffer.put_8_bytes(i64::to_be_bytes(value))
}
fn put_u8(&mut self, value: u8) -> Result<(), BinaryEncodeError> {
self.buffer.put_1_byte(value)
}
fn put_u16(&mut self, value: u16) -> Result<(), BinaryEncodeError> {
self.buffer.put_2_bytes(u16::to_be_bytes(value))
}
fn put_u32(&mut self, value: u32) -> Result<(), BinaryEncodeError> {
self.buffer.put_4_bytes(u32::to_be_bytes(value))
}
fn put_u64(&mut self, value: u64) -> Result<(), BinaryEncodeError> {
self.buffer.put_8_bytes(u64::to_be_bytes(value))
}
fn put_zeros(&mut self, count: usize) -> Result<(), BinaryEncodeError> {
self.buffer.put_zeros(count)
}
}
impl<'a> EndianEncoder<'a> for BigEndianEncoder<'a> {
fn order(&self) -> EndianOrder {
EndianOrder::Big
}
}
pub struct LittleEndianEncoder<'a> {
buffer: BinaryEncoderBuffer<'a>,
}
impl<'a> BinaryEncoder<'a> for LittleEndianEncoder<'a> {
fn available(&self) -> usize {
self.buffer.available()
}
fn capacity(&self) -> usize {
self.buffer.capacity()
}
fn finish(self) -> &'a [u8] {
self.buffer.finish()
}
fn is_empty(&self) -> bool {
self.buffer.is_empty()
}
fn is_full(&self) -> bool {
self.buffer.is_full()
}
fn len(&self) -> usize {
self.buffer.len()
}
fn offset(&self) -> usize {
self.buffer.offset()
}
fn reset(&mut self) {
self.buffer.reset()
}
fn rewind(&mut self, count: usize) -> Result<(), BinaryEncodeError> {
self.buffer.rewind(count)
}
fn seek(&mut self, offset: usize) -> Result<(), BinaryEncodeError> {
self.buffer.seek(offset)
}
fn skip(&mut self, count: usize) -> Result<(), BinaryEncodeError> {
self.buffer.skip(count)
}
fn put_bool(&mut self, value: bool) -> Result<(), BinaryEncodeError> {
self.put_u32(match value {
false => 0,
true => 1,
})
}
fn put_bytes(&mut self, _value: &[u8]) -> Result<(), BinaryEncodeError> {
Err(BinaryEncodeError::NotSupported {
operation: "put_bytes",
})
}
fn put_bytes_n(&mut self, value: &[u8]) -> Result<(), BinaryEncodeError> {
self.buffer.put_bytes(value)
}
fn put_str(&mut self, value: &str) -> Result<(), BinaryEncodeError> {
self.put_str_n(value)?;
self.buffer.put_1_byte(0)
}
fn put_str_n(&mut self, value: &str) -> Result<(), BinaryEncodeError> {
self.buffer.put_bytes(value.as_bytes())
}
fn put_f32(&mut self, value: f32) -> Result<(), BinaryEncodeError> {
self.buffer.put_4_bytes(f32::to_le_bytes(value))
}
fn put_f64(&mut self, value: f64) -> Result<(), BinaryEncodeError> {
self.buffer.put_8_bytes(f64::to_le_bytes(value))
}
fn put_i8(&mut self, value: i8) -> Result<(), BinaryEncodeError> {
self.buffer.put_1_byte(value as u8)
}
fn put_i16(&mut self, value: i16) -> Result<(), BinaryEncodeError> {
self.buffer.put_2_bytes(i16::to_le_bytes(value))
}
fn put_i32(&mut self, value: i32) -> Result<(), BinaryEncodeError> {
self.buffer.put_4_bytes(i32::to_le_bytes(value))
}
fn put_i64(&mut self, value: i64) -> Result<(), BinaryEncodeError> {
self.buffer.put_8_bytes(i64::to_le_bytes(value))
}
fn put_u8(&mut self, value: u8) -> Result<(), BinaryEncodeError> {
self.buffer.put_1_byte(value)
}
fn put_u16(&mut self, value: u16) -> Result<(), BinaryEncodeError> {
self.buffer.put_2_bytes(u16::to_le_bytes(value))
}
fn put_u32(&mut self, value: u32) -> Result<(), BinaryEncodeError> {
self.buffer.put_4_bytes(u32::to_le_bytes(value))
}
fn put_u64(&mut self, value: u64) -> Result<(), BinaryEncodeError> {
self.buffer.put_8_bytes(u64::to_le_bytes(value))
}
fn put_zeros(&mut self, count: usize) -> Result<(), BinaryEncodeError> {
self.buffer.put_zeros(count)
}
}
impl<'a> EndianEncoder<'a> for LittleEndianEncoder<'a> {
fn order(&self) -> EndianOrder {
EndianOrder::Little
}
}
pub enum BigLittleEndianEncoder<'a> {
Big(BigEndianEncoder<'a>),
Little(LittleEndianEncoder<'a>),
}
impl BigLittleEndianEncoder<'_> {
pub fn to_bytes(data: &mut [u8], order: EndianOrder) -> BigLittleEndianEncoder<'_> {
let buffer = BinaryEncoderBuffer { data, offset: 0 };
match order {
EndianOrder::Big => BigLittleEndianEncoder::Big(BigEndianEncoder { buffer }),
EndianOrder::Little => BigLittleEndianEncoder::Little(LittleEndianEncoder { buffer }),
}
}
}
impl<'a, 'b> BigLittleEndianEncoder<'a> {
pub fn encoder(&'b mut self) -> &'b mut dyn EndianEncoder<'a> {
match self {
BigLittleEndianEncoder::Big(encoder) => encoder,
BigLittleEndianEncoder::Little(encoder) => encoder,
}
}
}
pub struct XdrEncoder<'a> {
buffer: BinaryEncoderBuffer<'a>,
}
impl XdrEncoder<'_> {
const ALIGNMENT: usize = 4;
}
impl XdrEncoder<'_> {
fn produce_padding(&mut self, length: usize) -> Result<(), BinaryEncodeError> {
let remainder = length % Self::ALIGNMENT;
if remainder != 0 {
let padding = Self::ALIGNMENT - remainder;
self.buffer.put_zeros(padding)?;
}
Ok(())
}
}
impl<'a> BinaryEncoder<'a> for XdrEncoder<'a> {
fn available(&self) -> usize {
self.buffer.available()
}
fn capacity(&self) -> usize {
self.buffer.capacity()
}
fn finish(self) -> &'a [u8] {
self.buffer.finish()
}
fn is_empty(&self) -> bool {
self.buffer.is_empty()
}
fn is_full(&self) -> bool {
self.buffer.is_full()
}
fn len(&self) -> usize {
self.buffer.len()
}
fn offset(&self) -> usize {
self.buffer.offset()
}
fn reset(&mut self) {
self.buffer.reset()
}
fn rewind(&mut self, count: usize) -> Result<(), BinaryEncodeError> {
self.buffer.rewind(count)
}
fn seek(&mut self, offset: usize) -> Result<(), BinaryEncodeError> {
self.buffer.seek(offset)
}
fn skip(&mut self, count: usize) -> Result<(), BinaryEncodeError> {
self.buffer.skip(count)
}
fn put_bool(&mut self, value: bool) -> Result<(), BinaryEncodeError> {
self.put_u32(match value {
false => 0,
true => 1,
})
}
fn put_bytes(&mut self, value: &[u8]) -> Result<(), BinaryEncodeError> {
self.put_usize_32(value.len())?;
self.put_bytes_n(value)
}
fn put_bytes_n(&mut self, value: &[u8]) -> Result<(), BinaryEncodeError> {
self.buffer.put_bytes(value)?;
self.produce_padding(value.len())
}
fn put_str(&mut self, value: &str) -> Result<(), BinaryEncodeError> {
self.put_bytes(value.as_bytes())
}
fn put_str_n(&mut self, value: &str) -> Result<(), BinaryEncodeError> {
self.put_bytes_n(value.as_bytes())
}
fn put_f32(&mut self, value: f32) -> Result<(), BinaryEncodeError> {
self.buffer.put_4_bytes(f32::to_be_bytes(value))
}
fn put_f64(&mut self, value: f64) -> Result<(), BinaryEncodeError> {
self.buffer.put_8_bytes(f64::to_be_bytes(value))
}
fn put_i8(&mut self, value: i8) -> Result<(), BinaryEncodeError> {
self.put_i32(i32::from(value))
}
fn put_i16(&mut self, value: i16) -> Result<(), BinaryEncodeError> {
self.put_i32(i32::from(value))
}
fn put_i32(&mut self, value: i32) -> Result<(), BinaryEncodeError> {
self.buffer.put_4_bytes(i32::to_be_bytes(value))
}
fn put_i64(&mut self, value: i64) -> Result<(), BinaryEncodeError> {
self.buffer.put_8_bytes(i64::to_be_bytes(value))
}
fn put_u8(&mut self, value: u8) -> Result<(), BinaryEncodeError> {
let mut value = u32::from(value);
if value > 127 {
value += 0xffffff00;
}
self.put_u32(value)
}
fn put_u16(&mut self, value: u16) -> Result<(), BinaryEncodeError> {
self.put_u32(u32::from(value))
}
fn put_u32(&mut self, value: u32) -> Result<(), BinaryEncodeError> {
self.buffer.put_4_bytes(u32::to_be_bytes(value))
}
fn put_u64(&mut self, value: u64) -> Result<(), BinaryEncodeError> {
self.buffer.put_8_bytes(u64::to_be_bytes(value))
}
fn put_zeros(&mut self, count: usize) -> Result<(), BinaryEncodeError> {
self.buffer.put_zeros(count)
}
}