use core;
use super::super::alloc::SliceWrapper;
use super::super::alloc::SliceWrapperMut;
use super::interface::Freezable;
#[derive(Copy,Clone,Default,Debug)]
pub struct InputReference<'a> {
pub data: &'a [u8],
pub orig_offset: usize, }
impl<'a> SliceWrapper<u8> for InputReference<'a> {
fn slice(&self) -> & [u8] {
self.data
}
}
impl<'a> Freezable for InputReference<'a> {
fn freeze(&self) -> super::interface::SliceOffset {
debug_assert!(self.data.len() <= 0xffffffff);
super::interface::SliceOffset(self.orig_offset, self.data.len() as u32)
}
}
pub struct InputReferenceMut<'a> {
pub data: &'a mut [u8],
pub orig_offset: usize, }
impl<'a> SliceWrapper<u8> for InputReferenceMut<'a> {
fn slice(&self) -> & [u8] {
self.data
}
}
impl<'a> SliceWrapperMut<u8> for InputReferenceMut<'a> {
fn slice_mut(&mut self) -> &mut [u8] {
self.data
}
}
impl <'a> Default for InputReferenceMut<'a> {
fn default() -> Self {
InputReferenceMut {
data:&mut[],
orig_offset:0,
}
}
}
impl <'a> From<InputReferenceMut<'a>> for InputReference<'a> {
fn from(val: InputReferenceMut<'a>) -> InputReference<'a> {
InputReference{
data: val.data,
orig_offset: val.orig_offset,
}
}
}
impl <'a> From<&'a InputReferenceMut<'a>> for InputReference<'a> {
fn from(val: &'a InputReferenceMut<'a>) -> InputReference<'a> {
InputReference{
data: val.data,
orig_offset: val.orig_offset,
}
}
}
#[derive(Clone, Debug,Copy)]
pub struct InputPair<'a>(pub InputReference<'a>, pub InputReference<'a>);
impl<'a> core::cmp::PartialEq for InputPair<'a> {
fn eq<'b>(&self, other: &InputPair<'b>) -> bool {
if self.0.len() + self.1.len() != other.0.len() + other.1.len() {
return false;
}
for (a_iter, b_iter) in self.0.data.iter().chain(self.1.data.iter()).zip(other.0.data.iter().chain(other.1.data.iter())) {
if *a_iter != *b_iter {
return false;
}
}
return true;
}
}
impl<'a> core::ops::Index<usize> for InputPair<'a> {
type Output = u8;
fn index(&self, index:usize) -> &u8 {
if index >= self.0.len() {
&self.1.data[index - self.0.len()]
} else {
&self.0.data[index]
}
}
}
impl<'a> core::fmt::LowerHex for InputPair<'a> {
fn fmt(&self, fmtr: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
for item in self.0.data {
if let Err(e) = fmtr.write_fmt(format_args!("{:02x}", item)) {
return Err(e)
}
}
for item in self.1.data {
if let Err(e) = fmtr.write_fmt(format_args!("{:02x}", item)) {
return Err(e);
}
}
Ok(())
}
}
impl<'a> InputPair<'a> {
pub fn split_at(&self, loc : usize) -> (InputPair<'a>, InputPair<'a>) {
if loc >= self.0.len() {
let offset_from_self_1 = loc - self.0.len();
let (first, second) = self.1.data.split_at(core::cmp::min(offset_from_self_1,
self.1.len()));
return (InputPair::<'a>(self.0,
InputReference::<'a>{data:first,
orig_offset:self.1.orig_offset}),
InputPair::<'a>(InputReference::<'a>::default(),
InputReference::<'a>{data:second,
orig_offset:offset_from_self_1 + self.1.orig_offset,
}),
);
}
let (first, second) = self.0.data.split_at(core::cmp::min(loc,
self.0.len()));
(InputPair::<'a>(InputReference::<'a>{data:first,
orig_offset:self.0.orig_offset},
InputReference::<'a>::default()),
InputPair::<'a>(InputReference::<'a>{data:second,
orig_offset:self.0.orig_offset + loc},
self.1))
}
pub fn len(&self) -> usize {
self.0.len() + self.1.len()
}
}