1
2pub const OP_MASK: u8 = 0b11000000;
4pub const COPY_D: u8 = 0b00000000;
6pub const COPY_O: u8 = 0b01000000;
8pub const ADD: u8 = 0b10000000;
10pub const RUN: u8 = 0b11000000;
12pub const SIZE_MASK: u8 = 0b00111111;
14pub const MAX_RUN_LEN:u8 = 62;
16pub const MAX_INST_SIZE:usize = u16::MAX as usize;
18pub const MAX_WIN_SIZE:usize = (1<<24) - 1; pub const SECTION_CONTINUE_BIT: u8 = 0b10000000;
23pub const SECTION_FORMAT_BIT: u8 = 0b01000000;
25pub const SECTION_COMPRESSION_MASK: u8 = 0b00111000;
27pub const SECTION_COMPRESSION_RSHIFT: u8 = 3;
29pub const VERSION_MASK: u8 = 0b00000111;
31
32#[derive(Copy,Clone,Debug, PartialEq, Eq)]
37pub enum Format {
38 Interleaved,
40 Segregated,
42}
43impl Default for Format {
44 fn default() -> Self {
45 Format::Interleaved
46 }
47}
48
49impl Format {
50 pub fn is_interleaved(&self) -> bool {
51 matches!(self, Format::Interleaved{..})
52 }
53 pub fn is_segregated(&self) -> bool {
54 matches!(self, Format::Segregated)
55 }
56}
57#[derive(Copy,Clone,Debug,Default, PartialEq)]
59pub struct SectionHeader {
60 pub compression_algo: u8,
62 pub format: Format,
63 pub more_sections: bool,
67 pub num_operations: u32,
69 pub num_add_bytes: u32,
71 pub output_size: u32,
74}
75
76impl SectionHeader {
77 pub fn new(num_operations: u32, num_add_bytes: u32, output_size: u32) -> Self {
82 Self { num_operations, num_add_bytes, output_size, ..Default::default() }
83 }
84 pub fn set_compression_algo(mut self, compression_algo: u8) -> Self {
87 self.compression_algo = compression_algo.clamp(0, 7);
88 self
89 }
90 pub fn set_format(mut self, format: Format) -> Self {
91 self.format = format;
92 self
93 }
94 pub fn set_more_sections(mut self, more_sections: bool) -> Self {
96 self.more_sections = more_sections;
97 self
98 }
99
100 pub fn is_compressed(&self) -> bool {
101 self.compression_algo != 0
102 }
103 pub fn is_interleaved(&self) -> bool {
104 self.format.is_interleaved()
105 }
106}
107
108pub trait AddOp{
112 fn bytes(&self) -> &[u8];
114}
115
116#[derive(Clone, Debug, PartialEq, Eq)]
120pub struct Run{
121 pub byte: u8,
122 pub len: u8,
123}
124#[derive(Copy, Clone, Debug, PartialEq, Eq)]
129pub struct Copy{
130 pub src: CopySrc,
131 pub addr: u64,
132 pub len: u16,
133}
134
135#[derive(Copy, Clone, Debug, PartialEq, Eq)]
139pub enum CopySrc{
140 Dict,
141 Output,
142}
143#[derive(Clone, Debug, PartialEq, Eq)]
148pub enum Op<A>{
149 Run(Run),
150 Copy(Copy),
151 Add(A),
152}
153impl<A> Op<A> {
154 pub fn bit_flag(&self) -> u8 {
157 match self {
158 Op::Run(_) => RUN,
159 Op::Copy(copy) => match copy.src {
160 CopySrc::Dict => COPY_D,
161 CopySrc::Output => COPY_O,
162 },
163 Op::Add(_) => ADD,
164 }
165 }
166 pub fn is_add(&self) -> bool {
167 matches!(self, Op::Add(_))
168 }
169 pub fn is_run(&self) -> bool {
170 matches!(self, Op::Run(_))
171 }
172 pub fn is_copy(&self) -> bool {
173 matches!(self, Op::Copy(_))
174 }
175 pub fn take_copy(&self) -> Option<Copy> {
176 if let Op::Copy(copy) = self {
177 Some(*copy)
178 } else {
179 None
180 }
181 }
182}
183impl<A:AddOp> Op<A> {
184 pub fn oal(&self) -> u16 {
186 match &self {
187 Op::Add(add) => add.bytes().len() as u16,
188 Op::Copy(copy) => copy.len,
189 Op::Run(run) => run.len as u16,
190 }
191 }
192}
193
194
195#[derive(Copy, Clone, Debug, PartialEq, Eq)]
199pub enum Size{
200 Done(u8),
201 U8And62,
202 U16
203}
204
205impl Size {
206 pub fn size_overhead(&self) -> usize {
209 match self {
210 Size::Done(_) => 0,
211 Size::U8And62 => 1,
212 Size::U16 => 2,
213 }
214 }
215}
216#[inline]
218pub fn size_routine(size: u16)->Size{
219 match size {
220 1..=62 => Size::Done(size as u8),
221 63 => Size::U8And62,
222 _ => Size::U16,
223 }
224}
225
226#[inline]
228pub fn zigzag_encode(n: i64) -> u64 {
229 ((n << 1) ^ (n >> 63)) as u64
230}
231
232#[inline]
234pub fn zigzag_decode(z: u64) -> i64 {
235 ((z >> 1) as i64) ^ -((z & 1) as i64)
236}
237
238pub fn write_u_varint<W: std::io::Write>(writer: &mut W, mut n: u64) -> std::io::Result<()> {
240 let mut buf = [0u8; 10]; let mut i = 0;
242 while n >= 0x80 {
243 buf[i] = ((n & 0x7F) | 0x80) as u8;
244 n >>= 7;
245 i += 1;
246 }
247 buf[i] = n as u8;
248 writer.write_all(&buf[..=i])
249}
250
251pub fn read_u_varint<R: std::io::Read>(reader: &mut R) -> std::io::Result<u64> {
253 let mut result = 0u64;
254 let mut shift = 0;
255 let mut b = [0u8; 1];
256 loop {
257 reader.read_exact(&mut b)?;
258 let byte = b[0];
259 result |= ((byte & 0x7F) as u64) << shift;
260 if byte & 0x80 == 0 {
261 break;
262 }
263 shift += 7;
264 }
265 Ok(result)
266}
267
268pub fn write_i_varint<W: std::io::Write>(writer: &mut W, n: i64) -> std::io::Result<()> {
270 write_u_varint(writer, zigzag_encode(n as i64))
271}
272
273pub fn read_i_varint<R: std::io::Read>(reader: &mut R) -> std::io::Result<i64> {
275 Ok(zigzag_decode(read_u_varint(reader)?))
276}
277
278pub fn read_u8<R: std::io::Read>(reader: &mut R) -> std::io::Result<u8> {
280 let mut buf = [0u8; 1];
281 reader.read_exact(&mut buf)?;
282 Ok(buf[0])
283}
284
285pub fn write_u8<W: std::io::Write>(writer: &mut W, n: u8) -> std::io::Result<()> {
287 writer.write_all(&[n])
288}
289
290pub fn read_u16<R: std::io::Read>(reader: &mut R) -> std::io::Result<u16> {
292 let mut buf = [0u8; 2];
293 reader.read_exact(&mut buf)?;
294 Ok(u16::from_le_bytes(buf))
295}
296
297pub fn write_u16<W: std::io::Write>(writer: &mut W, n: u16) -> std::io::Result<()> {
299 writer.write_all(&n.to_le_bytes())
300}
301
302#[inline]
304pub fn u_varint_encode_size(n: u64) -> usize {
305 let mut size = 1;
306 let mut n = n >> 7;
307 while n > 0 {
308 size += 1;
309 n >>= 7;
310 }
311 size
312}
313
314#[inline]
316pub fn diff_addresses_to_u64(cur: u64, input: i64) -> u64 {
317 if input >= 0 {
318 cur.wrapping_add(input as u64)
320 } else {
321 let positive_i = input.abs() as u64; cur.wrapping_sub(positive_i)
324 }
325}
326
327#[inline]
329pub fn diff_addresses_to_i64(cur: u64, target: u64) -> i64 {
330 if target > cur {
331 (target - cur) as i64
332 } else {
333 (cur - target) as i64 * -1
334 }
335}
336
337#[cfg(test)]
338mod tests {
339 use super::*;
340 use std::io::Cursor;
341
342 #[test]
343 fn test_ivarint() {
344 let mut buffer = Vec::new();
345 let values = [0, -1, 1, -2, 2, 1024, -1025, i64::MAX, i64::MIN];
346 for &val in &values {
347 buffer.clear();
348 write_i_varint(&mut buffer, val).unwrap();
349 let mut cursor = Cursor::new(&buffer);
350 let decoded = read_i_varint(&mut cursor).unwrap();
351 assert_eq!(val, decoded, "Failed encoding/decoding {}", val);
352 }
353 }
354 #[test]
355 fn test_ivarint_vals() {
356 let mut buffer = Vec::new();
357 let values = [
358 -64,63, -8192,8191, -1048576,1048575, -134217728,134217727, -123456789
363 ];
364 for &val in &values {
365 buffer.clear();
366 let zigged = zigzag_encode(val);
367 write_i_varint(&mut buffer, val).unwrap();
368 println!("i64: {} buffer:{:?} zigzagged: {}",val,buffer,zigged);
369 let mut cursor = Cursor::new(&buffer);
370 let decoded = read_i_varint(&mut cursor).unwrap();
371 assert_eq!(val, decoded, "Failed encoding/decoding {}", val);
372 }
373 }
374 #[test]
375 fn test_add_i64_to_u64() {
376 assert_eq!(diff_addresses_to_u64(10, 5), 15);
378 assert_eq!(diff_addresses_to_u64(0, i64::MAX), i64::MAX as u64);
379
380 assert_eq!(diff_addresses_to_u64(20, -5), 15);
382 assert_eq!(diff_addresses_to_u64(10, -15), 0xFFFFFFFFFFFFFFFB); assert_eq!(diff_addresses_to_u64(0, -1), 0xFFFFFFFFFFFFFFFF);
386 assert_eq!(diff_addresses_to_u64(u64::MAX, 1), 0); }
388
389 #[test]
390 fn test_u64_to_i64_diff() {
391 assert_eq!(diff_addresses_to_i64(5, 10), 5);
393
394 assert_eq!(diff_addresses_to_i64(10, 5), -5);
396
397 assert_eq!(diff_addresses_to_i64(20, 20), 0);
399 }
400}