brotli/enc/
input_pair.rs

1use core;
2use core::cmp::min;
3
4use super::super::alloc::{SliceWrapper, SliceWrapperMut};
5use super::interface::Freezable;
6#[derive(Copy, Clone, Default, Debug)]
7pub struct InputReference<'a> {
8    pub data: &'a [u8],
9    pub orig_offset: usize, // offset into the original slice of data
10}
11impl<'a> SliceWrapper<u8> for InputReference<'a> {
12    fn slice(&self) -> &[u8] {
13        self.data
14    }
15}
16
17impl<'a> Freezable for InputReference<'a> {
18    fn freeze(&self) -> super::interface::SliceOffset {
19        debug_assert!(self.data.len() <= 0xffff_ffff);
20        super::interface::SliceOffset(self.orig_offset, self.data.len() as u32)
21    }
22}
23
24#[derive(Default)]
25pub struct InputReferenceMut<'a> {
26    pub data: &'a mut [u8],
27    pub orig_offset: usize, // offset into the original slice of data
28}
29
30impl<'a> SliceWrapper<u8> for InputReferenceMut<'a> {
31    fn slice(&self) -> &[u8] {
32        self.data
33    }
34}
35impl<'a> SliceWrapperMut<u8> for InputReferenceMut<'a> {
36    fn slice_mut(&mut self) -> &mut [u8] {
37        self.data
38    }
39}
40
41impl<'a> From<InputReferenceMut<'a>> for InputReference<'a> {
42    fn from(val: InputReferenceMut<'a>) -> InputReference<'a> {
43        InputReference {
44            data: val.data,
45            orig_offset: val.orig_offset,
46        }
47    }
48}
49
50impl<'a> From<&'a InputReferenceMut<'a>> for InputReference<'a> {
51    fn from(val: &'a InputReferenceMut<'a>) -> InputReference<'a> {
52        InputReference {
53            data: val.data,
54            orig_offset: val.orig_offset,
55        }
56    }
57}
58
59#[derive(Clone, Debug, Copy)]
60pub struct InputPair<'a>(pub InputReference<'a>, pub InputReference<'a>);
61
62impl<'a> PartialEq for InputPair<'a> {
63    fn eq(&self, other: &InputPair<'_>) -> bool {
64        if self.0.len() + self.1.len() != other.0.len() + other.1.len() {
65            return false;
66        }
67        for (a_iter, b_iter) in self
68            .0
69            .data
70            .iter()
71            .chain(self.1.data.iter())
72            .zip(other.0.data.iter().chain(other.1.data.iter()))
73        {
74            if *a_iter != *b_iter {
75                return false;
76            }
77        }
78        true
79    }
80}
81impl<'a> core::ops::Index<usize> for InputPair<'a> {
82    type Output = u8;
83    fn index(&self, index: usize) -> &u8 {
84        if index >= self.0.len() {
85            &self.1.data[index - self.0.len()]
86        } else {
87            &self.0.data[index]
88        }
89    }
90}
91impl<'a> core::fmt::LowerHex for InputPair<'a> {
92    fn fmt(&self, fmtr: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
93        for item in self.0.data {
94            fmtr.write_fmt(format_args!("{:02x}", item))?
95        }
96        for item in self.1.data {
97            fmtr.write_fmt(format_args!("{:02x}", item))?
98        }
99        Ok(())
100    }
101}
102
103impl<'a> InputPair<'a> {
104    pub fn split_at(&self, loc: usize) -> (InputPair<'a>, InputPair<'a>) {
105        if loc >= self.0.len() {
106            let offset_from_self_1 = loc - self.0.len();
107            let (first, second) = self.1.data.split_at(min(offset_from_self_1, self.1.len()));
108            return (
109                InputPair::<'a>(
110                    self.0,
111                    InputReference::<'a> {
112                        data: first,
113                        orig_offset: self.1.orig_offset,
114                    },
115                ),
116                InputPair::<'a>(
117                    InputReference::<'a>::default(),
118                    InputReference::<'a> {
119                        data: second,
120                        orig_offset: offset_from_self_1 + self.1.orig_offset,
121                    },
122                ),
123            );
124        }
125        let (first, second) = self.0.data.split_at(min(loc, self.0.len()));
126        (
127            InputPair::<'a>(
128                InputReference::<'a> {
129                    data: first,
130                    orig_offset: self.0.orig_offset,
131                },
132                InputReference::<'a>::default(),
133            ),
134            InputPair::<'a>(
135                InputReference::<'a> {
136                    data: second,
137                    orig_offset: self.0.orig_offset + loc,
138                },
139                self.1,
140            ),
141        )
142    }
143    pub fn len(&self) -> usize {
144        self.0.len() + self.1.len()
145    }
146}