vcdiff_common/
lib.rs

1
2
3pub const MAGIC:[u8;4] = [b'V'|0x80, b'C'|0x80, b'D'|0x80, 0];
4
5
6#[derive(Clone, Debug, Default, PartialEq, Eq)]
7pub struct Header{
8    pub hdr_indicator: u8,
9    pub secondary_compressor_id: Option<u8>,
10    pub code_table_data: Option<CodeTableData>,
11}
12impl Header{
13    pub fn encoded_size(&self)->usize{
14        let mut size = 4 + 1; // Fixed part of the header
15        if self.secondary_compressor_id.is_some(){
16            size += 1;
17        }
18        if let Some(code_table_data) = &self.code_table_data{
19            let integer = code_table_data.compressed_code_table_data.len();
20            let int_size = integer_encoded_size(integer as u64);
21            size += 1 + 1 + integer + int_size;
22        }
23        size
24    }
25}
26
27/// Encapsulates the code table data found in the VCDIFF patch header.
28#[derive(Clone, Debug, Default, PartialEq, Eq)]
29pub struct CodeTableData {
30    pub size_of_near_cache: u8,
31    pub size_of_same_cache: u8,
32    pub compressed_code_table_data: Vec<u8>,
33}
34
35
36
37/// Represents a summary of a window in a VCDIFF patch, including the positions of different sections within the window.
38#[derive(Clone, Debug, Default, PartialEq, Eq)]
39pub struct WindowSummary {
40    pub win_start_pos:u64,
41    pub win_indicator: WinIndicator,
42    pub source_segment_size: Option<u64>,
43    pub source_segment_position: Option<u64>,
44    pub length_of_the_delta_encoding: u64,
45    pub size_of_the_target_window: u64,
46    pub delta_indicator: DeltaIndicator,
47    pub length_of_data_for_adds_and_runs: u64,
48    pub length_of_instructions_and_sizes: u64,
49    pub length_of_addresses_for_copys: u64,
50}
51impl WindowSummary{
52    pub fn win_hdr_len(&self)->usize{
53        let mut size = 1;
54        if let Some(s) = self.source_segment_size{
55            size += integer_encoded_size(s);
56        }
57        if let Some(s) = self.source_segment_position{
58            size += integer_encoded_size(s);
59        }
60        size += integer_encoded_size(self.length_of_the_delta_encoding);
61        size += integer_encoded_size(self.size_of_the_target_window);
62        size += 1; //delta_indicator
63        size += integer_encoded_size(self.length_of_data_for_adds_and_runs);
64        size += integer_encoded_size(self.length_of_instructions_and_sizes);
65        size += integer_encoded_size(self.length_of_addresses_for_copys);
66        size
67    }
68    pub fn data_sec_start(&self)->u64{
69        self.win_start_pos + self.win_hdr_len() as u64
70    }
71    pub fn inst_sec_start(&self)->u64{
72        self.data_sec_start() + self.length_of_data_for_adds_and_runs
73    }
74    pub fn addr_sec_start(&self)->u64{
75        self.inst_sec_start() + self.length_of_instructions_and_sizes
76    }
77    pub fn end_of_window(&self)->u64{
78        self.addr_sec_start() + self.length_of_addresses_for_copys
79    }
80    pub fn is_vcd_target(&self)->bool{
81        self.win_indicator == WinIndicator::VCD_TARGET
82    }
83    pub fn has_reference_data(&self)->bool{
84        self.win_indicator != WinIndicator::Neither
85    }
86}
87
88#[repr(u8)]
89#[derive(Copy,Clone, Debug, PartialEq, Eq)]
90#[allow(non_camel_case_types)]
91pub enum WinIndicator {
92    Neither = 0,
93    VCD_SOURCE = 1 << 0,
94    VCD_TARGET = 1 << 1,
95}
96impl Default for WinIndicator {
97    fn default() -> Self {
98        Self::Neither
99    }
100}
101impl WinIndicator {
102    pub fn from_u8(byte: u8) -> Self {
103        match byte {
104            0 => Self::Neither,
105            1 => Self::VCD_SOURCE,
106            2 => Self::VCD_TARGET,
107            _ => panic!("Invalid WinIndicator byte: {}", byte),
108        }
109    }
110
111    pub fn to_u8(self) -> u8 {
112        self as u8
113    }
114}
115
116#[repr(transparent)]
117#[derive(Clone, Debug, Default, PartialEq, Eq)]
118pub struct DeltaIndicator(pub u8);
119
120impl DeltaIndicator {
121    pub fn from_u8(byte: u8) -> Self {
122        Self(byte)
123    }
124
125    pub fn to_u8(&self) -> u8 {
126        self.0
127    }
128
129    pub fn is_datacomp(&self) -> bool {
130        self.0 & 0x01 != 0
131    }
132
133    pub fn is_instcomp(&self) -> bool {
134        self.0 & 0x02 != 0
135    }
136
137    pub fn is_addrcomp(&self) -> bool {
138        self.0 & 0x04 != 0
139    }
140}
141
142
143///Basic instruction
144#[derive(Clone, Debug, PartialEq, Eq)]
145pub enum Inst{
146    Add(ADD),
147    Copy(COPY),
148    Run(RUN)
149}
150impl Instruction for Inst{
151    fn len_in_u(&self)->u32{
152        match self{
153            Inst::Add(a) => a.len,
154            Inst::Copy(c) => c.len,
155            Inst::Run(r) => r.len
156        }
157    }
158
159    fn inst_type(&self)->InstType {
160        match self{
161            Inst::Add(_) => InstType::Add,
162            Inst::Run(_) => InstType::Run,
163            Inst::Copy(COPY { copy_type, .. }) => InstType::Copy (*copy_type),
164        }
165    }
166}
167///Decoded ADD instruction
168#[derive(Copy, Clone, Debug, PartialEq, Eq)]
169pub struct ADD{
170    ///Length of the data in the data section
171    pub len:u32,
172    ///Absolute position in the Patch file where the data starts (in the data section for this window)
173    pub p_pos:u64,
174}
175///Decoded COPY instruction
176#[derive(Copy, Clone, Debug, PartialEq, Eq)]
177pub struct COPY{
178    pub len:u32,
179    ///Decoded start position in window string U
180    pub u_pos:u32,
181    pub copy_type:CopyType,
182}
183impl Instruction for COPY{
184    fn len_in_u(&self)->u32{
185        self.len
186    }
187    fn inst_type(&self)->InstType{
188        InstType::Copy(self.copy_type)
189    }
190}
191///Inlined of Decoded RUN instruction
192#[derive(Copy, Clone, Debug, PartialEq, Eq)]
193pub struct RUN{
194    pub len: u32,
195    pub byte: u8
196}
197impl Instruction for RUN{
198    fn len_in_u(&self)->u32{
199        self.len
200    }
201    fn inst_type(&self)->InstType{
202        InstType::Run
203    }
204}
205
206pub trait Instruction:Clone{
207    fn len_in_u(&self)->u32;
208    fn inst_type(&self)->InstType;
209    fn len_in_o(&self)->u32{
210        match self.inst_type(){
211            InstType::Add => self.len_in_u(),
212            InstType::Run => self.len_in_u(),
213            InstType::Copy(copy_type) => match copy_type{
214                CopyType::CopyS => self.len_in_u(),
215                CopyType::CopyT{..} => self.len_in_u(),
216                CopyType::CopyQ{len_o} => len_o,
217            }
218        }
219    }
220    fn is_implicit_seq(&self)->bool{
221        matches!(self.inst_type(), InstType::Copy(CopyType::CopyQ{..}))
222    }
223    fn copy_in_s(&self)->bool{
224        matches!(self.inst_type(), InstType::Copy(CopyType::CopyS))
225    }
226    fn copy_in_t(&self)->bool{
227        matches!(self.inst_type(), InstType::Copy(CopyType::CopyT{..}))
228    }
229}
230#[derive(Copy, Clone, Debug, PartialEq, Eq)]
231pub enum InstType{
232    Add,
233    Run,
234    Copy(CopyType),
235}
236
237impl InstType {
238    pub fn is_copy(&self)->bool{
239        matches!(self, InstType::Copy{..})
240    }
241}
242
243#[derive(Copy, Clone, Debug, PartialEq, Eq)]
244pub enum CopyType{
245    CopyS,
246    CopyT{inst_u_pos_start:u32},
247    CopyQ{len_o:u32}
248}
249
250impl CopyType {
251    pub fn in_s(&self)->bool{
252        matches!(self, CopyType::CopyS)
253    }
254    pub fn in_t(&self)->bool{
255        matches!(self, CopyType::CopyT{..})
256    }
257    pub fn is_seq(&self)->bool{
258        matches!(self, CopyType::CopyQ{..})
259    }
260}
261///Currently this is only a static implementation of the cache. We cannot handle different S_NEAR or S_SAME parameters.
262#[derive(Clone,Debug)]
263pub struct Cache {
264    near: [usize; Self::S_NEAR], // Fixed array size of 4
265    next_slot: usize,
266    same: [usize; Self::S_SAME * 256], // Fixed array size of 3 * 256
267}
268impl Cache {
269    pub const S_NEAR: usize = 4;
270    pub const S_SAME: usize = 3;
271    pub const SAME_START: usize = Self::S_NEAR + 2;
272    pub fn new() -> Self {
273        Cache {
274            near: [0; Self::S_NEAR],
275            next_slot: 0,
276            same: [0; Self::S_SAME * 256],
277        }
278    }
279    fn update(&mut self, address: usize) {
280        // Update near cache
281        self.near[self.next_slot] = address;
282        self.next_slot = (self.next_slot + 1) % Self::S_NEAR; // Modulus for circular buffer within array
283
284        // Update same cache
285        let same_index = address % (Self::S_SAME * 256); // Modulus for same cache addressing
286        self.same[same_index] = address;
287    }
288    /// **read_value** is the value read from the address section
289    /// **here** is the current position in the target output
290    /// **mode** is the mode of the address
291    /// returns (address, bytes_read_from_addr_section)
292    pub fn addr_decode(&mut self, read_value:u64, here: u64, mode: usize) -> u64 {
293        let addr;
294        if mode < Self::SAME_START{
295            match mode {
296                0 => {
297                    addr = read_value
298                },
299                1 => {
300                    addr = here - read_value;
301                },
302                m => {
303                    let near_index = m - 2;
304                    addr = self.near[near_index] as u64 + read_value;
305                }
306            }
307        }else{// Same cache
308            let m = mode - Self::SAME_START;
309            assert!(read_value <= u8::MAX as u64,"read value is too large");
310            let same_index = m * 256 + read_value as usize;
311            addr = self.same[same_index] as u64;
312        }
313        self.update(addr as usize);
314        addr
315    }
316    pub fn addr_encode(&mut self, addr: usize, here: usize) -> (u32, u8) { // Return encoded address and mode
317        let res = self.peek_addr_encode(addr, here);
318        self.update(addr);
319        res
320    }
321    //TODO: Fix this, or where it is called in merger.
322    pub fn peek_addr_encode(&self, addr: usize, here: usize) -> (u32, u8){
323        assert!(addr < here,"addr can not be ahead of cur pos");
324        return (addr as u32,0);
325        //There is an error either here in this code, or somewhere in the writer/encoder code.
326        // let mut best_distance = addr;
327        // let mut best_mode = 0; // VCD_SELF
328        // // VCD_HERE
329        // let distance = here - addr;
330        // if distance < best_distance {
331        //     best_distance = distance;
332        //     best_mode = 1;
333        // }
334
335        // // Near cache
336        // for (i, &near_addr) in self.near.iter().enumerate() {
337        //     if addr >= near_addr && addr - near_addr < best_distance {
338        //         best_distance = addr - near_addr;
339        //         best_mode = i + 2;
340        //     }
341        // }
342
343        // // Same cache
344        // let distance = addr % (Self::S_SAME * 256);
345        // if self.same[distance] == addr {
346        //     best_distance = distance % 256;
347        //     best_mode = Self::SAME_START + distance / 256;
348        // }
349        // (best_distance as u32, best_mode as u8)
350    }
351}
352
353// Define the Instruction enum with associated data for size and mode.
354#[derive(Copy, Clone, Debug, PartialEq, Eq)]
355pub enum TableInst {
356    NoOp,
357    Add { size: u8 },
358    Run ,
359    Copy { size: u8, mode: u8 },
360}
361
362impl TableInst {
363    pub fn size(&self) -> u8 {
364        match self {
365            TableInst::Add { size } => *size,
366            TableInst::Run => 0,
367            TableInst::Copy { size, .. } => *size,
368            TableInst::NoOp => 0,//ambiguous
369        }
370    }
371}
372
373// Define a struct for a code table entry that can represent up to two instructions.
374#[derive(Copy, Clone, Debug, PartialEq, Eq)]
375pub struct CodeTableEntry {
376    pub first: TableInst,
377    pub second: TableInst,
378}
379impl CodeTableEntry{
380    pub fn sec_is_noop(&self) -> bool {
381        self.second == TableInst::NoOp
382    }
383
384}
385
386// Implement the function to generate the default VCDIFF code table.
387pub fn generate_default_code_table() -> [CodeTableEntry; 256] {
388    let mut table: [CodeTableEntry; 256] = [CodeTableEntry { first: TableInst::NoOp, second: TableInst::NoOp }; 256];
389
390    // Entry 0: RUN 0 NOOP 0
391    table[0] = CodeTableEntry { first: TableInst::Run , second: TableInst::NoOp };
392
393    // Entries for ADD instructions with sizes 0 and [1-17]
394    for i in 1..=18 {
395        table[i] = CodeTableEntry { first: TableInst::Add { size: i as u8 - 1 }, second: TableInst::NoOp };
396    }
397
398    // Entries for COPY instructions with modes [0-8] and sizes 0 and [4-18]
399    for mode in 0..=8u8 {
400        for size in 0..=15 {
401            let index = 19 + mode * 16 + size;
402            table[index as usize] = CodeTableEntry { first: TableInst::Copy { size: if size == 0 { 0 } else { size + 3 }, mode }, second: TableInst::NoOp };
403        }
404    }
405
406    // Combined ADD and COPY instructions
407    let mut index = 163;
408    for add_size in 1..=4 {
409        for copy_mode in 0..=5 {
410            for copy_size in 4..=6 {
411                table[index] = CodeTableEntry {
412                    first: TableInst::Add { size: add_size },
413                    second: TableInst::Copy { size: copy_size, mode: copy_mode },
414                };
415                index += 1;
416            }
417        }
418    }
419
420    // Combined ADD and COPY instructions with specific sizes for COPY
421    for add_size in 1..=4 {
422        for copy_mode in 6..=8 {
423            table[index] = CodeTableEntry {
424                first: TableInst::Add { size: add_size },
425                second: TableInst::Copy { size: 4, mode: copy_mode },
426            };
427            index += 1;
428        }
429    }
430
431    // The last line for COPY ADD combinations
432    for mode in 0..=8 {
433        table[index] = CodeTableEntry {
434            first: TableInst::Copy { size: 4, mode },
435            second: TableInst::Add { size: 1 },
436        };
437        index += 1;
438    }
439
440    table
441}
442
443pub fn decode_integer<R: std::io::Read>(source: &mut R) -> std::io::Result<(u64,usize)> {
444    let mut value = 0u64;
445    let mut byte_count = 0; // To keep track of the number of bytes read
446
447    loop {
448        let mut byte = [0u8; 1];
449        source.read_exact(&mut byte)?;
450
451        // Calculate the shift for this byte. Initial bytes are maximally shifted
452        // and the adjustment is made later.
453        byte_count += 1;
454        let shift = 63 - (byte_count * 7); // Adjust shift based on byte count
455        let bits = (byte[0] & 0x7F) as u64;
456        value = value.checked_add(bits << shift).expect("Overflow");
457
458        if byte[0] & 0x80 == 0 { // If this is the last byte
459            break;
460        }
461    }
462    //each byte is 7 bits
463    //we stored the first bit in position 63
464    //once we know how many bytes we read, we can shift the value to the right
465    //we need the first bit to be byte_count * 7 position
466    //so if it is 4 bytes, we need to shift right 63 - 4 * 7 = 35 for the first bit to be in position 28
467    value >>= 63 - byte_count * 7;
468
469    Ok((value,byte_count))
470}
471
472/// Encodes a u64 value into a variable-length base 128 integer per RFC 3284.
473/// The value is written to the provided sink.
474pub fn encode_integer<W: std::io::Write>(mut sink: W, mut value: u64) -> std::io::Result<()> {
475    let mut bytes = [0u8; 10]; // Maximum size needed for a u64 value in base 128 encoding
476    let mut index = bytes.len(); // Start from the end of the array
477
478    if value == 0 {
479        return sink.write_all(&[0]);
480    }
481
482    while value > 0 {
483        index -= 1; // Move towards the front of the array
484        let digit = if index == bytes.len() - 1 {
485            // If it's the first byte, do not set the MSB
486            value % 128
487        } else {
488            // Otherwise, set the MSB
489            (value % 128) | 128
490        };
491        bytes[index] = digit as u8;
492        value /= 128;
493    }
494
495    // Write all the bytes at once, starting from the first used byte in the array
496    sink.write_all(&bytes[index..])
497}
498/// The length of the give value when encoded as a base 128 integer per RFC 3284.
499pub fn integer_encoded_size(value: u64) -> usize {
500    if value == 0 {
501        return 1;
502    }
503
504    let mut byte_count = 0;
505    let mut value = value;
506    while value > 0 {
507        byte_count += 1;
508        value /= 128;
509    }
510    byte_count
511}
512
513/// Length in the output stream that the list of instructions will produce.
514pub fn sum_len_in_o<I:Instruction>(insts:&[I])->u64{
515    insts.iter().map(|i| i.len_in_o() as u64).sum()
516}
517
518
519
520#[cfg(test)]
521mod test_super {
522    use super::*;
523    // As given in RFC 3284, pg 4.
524    const CORRECT_ENCODING: [u8; 4] = [58 | 0x80, 111 | 0x80, 26 | 0x80, 21];
525    const TEST_VALUE: u64 = 123456789;
526
527
528    #[test]
529    fn test_encode_specific_value() -> std::io::Result<()> {
530        // Encode the value
531        let mut buffer = Vec::new();
532        encode_integer(&mut buffer, TEST_VALUE)?;
533
534        // Check that the encoded bytes match the expected sequence
535        assert_eq!(buffer, CORRECT_ENCODING, "Encoding mismatch");
536
537        Ok(())
538    }
539
540    #[test]
541    fn test_decode_specific_value() -> std::io::Result<()> {
542        // Decode the bytes back to a u64
543        let mut cursor = std::io::Cursor::new(&CORRECT_ENCODING);
544        let (decoded,_) = decode_integer(&mut cursor)?;
545
546        // Verify the decoded value matches the original
547        assert_eq!(decoded, TEST_VALUE, "Decoding mismatch");
548
549        Ok(())
550    }
551    #[test]
552    fn test_len() -> () {
553        assert_eq!(integer_encoded_size(TEST_VALUE), CORRECT_ENCODING.len(), "Length mismatch");
554    }
555
556}
557
558use TableInst::*;
559pub const VCD_C_TABLE: [CodeTableEntry;256] = [
560    CodeTableEntry { first: Run , second: NoOp },
561    CodeTableEntry { first: Add { size: 0 }, second: NoOp },
562    CodeTableEntry { first: Add { size: 1 }, second: NoOp },
563    CodeTableEntry { first: Add { size: 2 }, second: NoOp },
564    CodeTableEntry { first: Add { size: 3 }, second: NoOp },
565    CodeTableEntry { first: Add { size: 4 }, second: NoOp },
566    CodeTableEntry { first: Add { size: 5 }, second: NoOp },
567    CodeTableEntry { first: Add { size: 6 }, second: NoOp },
568    CodeTableEntry { first: Add { size: 7 }, second: NoOp },
569    CodeTableEntry { first: Add { size: 8 }, second: NoOp },
570    CodeTableEntry { first: Add { size: 9 }, second: NoOp },
571    CodeTableEntry { first: Add { size: 10 }, second: NoOp },
572    CodeTableEntry { first: Add { size: 11 }, second: NoOp },
573    CodeTableEntry { first: Add { size: 12 }, second: NoOp },
574    CodeTableEntry { first: Add { size: 13 }, second: NoOp },
575    CodeTableEntry { first: Add { size: 14 }, second: NoOp },
576    CodeTableEntry { first: Add { size: 15 }, second: NoOp },
577    CodeTableEntry { first: Add { size: 16 }, second: NoOp },
578    CodeTableEntry { first: Add { size: 17 }, second: NoOp },
579    CodeTableEntry { first: Copy { size: 0, mode: 0 }, second: NoOp },
580    CodeTableEntry { first: Copy { size: 4, mode: 0 }, second: NoOp },
581    CodeTableEntry { first: Copy { size: 5, mode: 0 }, second: NoOp },
582    CodeTableEntry { first: Copy { size: 6, mode: 0 }, second: NoOp },
583    CodeTableEntry { first: Copy { size: 7, mode: 0 }, second: NoOp },
584    CodeTableEntry { first: Copy { size: 8, mode: 0 }, second: NoOp },
585    CodeTableEntry { first: Copy { size: 9, mode: 0 }, second: NoOp },
586    CodeTableEntry { first: Copy { size: 10, mode: 0 }, second: NoOp },
587    CodeTableEntry { first: Copy { size: 11, mode: 0 }, second: NoOp },
588    CodeTableEntry { first: Copy { size: 12, mode: 0 }, second: NoOp },
589    CodeTableEntry { first: Copy { size: 13, mode: 0 }, second: NoOp },
590    CodeTableEntry { first: Copy { size: 14, mode: 0 }, second: NoOp },
591    CodeTableEntry { first: Copy { size: 15, mode: 0 }, second: NoOp },
592    CodeTableEntry { first: Copy { size: 16, mode: 0 }, second: NoOp },
593    CodeTableEntry { first: Copy { size: 17, mode: 0 }, second: NoOp },
594    CodeTableEntry { first: Copy { size: 18, mode: 0 }, second: NoOp },
595    CodeTableEntry { first: Copy { size: 0, mode: 1 }, second: NoOp },
596    CodeTableEntry { first: Copy { size: 4, mode: 1 }, second: NoOp },
597    CodeTableEntry { first: Copy { size: 5, mode: 1 }, second: NoOp },
598    CodeTableEntry { first: Copy { size: 6, mode: 1 }, second: NoOp },
599    CodeTableEntry { first: Copy { size: 7, mode: 1 }, second: NoOp },
600    CodeTableEntry { first: Copy { size: 8, mode: 1 }, second: NoOp },
601    CodeTableEntry { first: Copy { size: 9, mode: 1 }, second: NoOp },
602    CodeTableEntry { first: Copy { size: 10, mode: 1 }, second: NoOp },
603    CodeTableEntry { first: Copy { size: 11, mode: 1 }, second: NoOp },
604    CodeTableEntry { first: Copy { size: 12, mode: 1 }, second: NoOp },
605    CodeTableEntry { first: Copy { size: 13, mode: 1 }, second: NoOp },
606    CodeTableEntry { first: Copy { size: 14, mode: 1 }, second: NoOp },
607    CodeTableEntry { first: Copy { size: 15, mode: 1 }, second: NoOp },
608    CodeTableEntry { first: Copy { size: 16, mode: 1 }, second: NoOp },
609    CodeTableEntry { first: Copy { size: 17, mode: 1 }, second: NoOp },
610    CodeTableEntry { first: Copy { size: 18, mode: 1 }, second: NoOp },
611    CodeTableEntry { first: Copy { size: 0, mode: 2 }, second: NoOp },
612    CodeTableEntry { first: Copy { size: 4, mode: 2 }, second: NoOp },
613    CodeTableEntry { first: Copy { size: 5, mode: 2 }, second: NoOp },
614    CodeTableEntry { first: Copy { size: 6, mode: 2 }, second: NoOp },
615    CodeTableEntry { first: Copy { size: 7, mode: 2 }, second: NoOp },
616    CodeTableEntry { first: Copy { size: 8, mode: 2 }, second: NoOp },
617    CodeTableEntry { first: Copy { size: 9, mode: 2 }, second: NoOp },
618    CodeTableEntry { first: Copy { size: 10, mode: 2 }, second: NoOp },
619    CodeTableEntry { first: Copy { size: 11, mode: 2 }, second: NoOp },
620    CodeTableEntry { first: Copy { size: 12, mode: 2 }, second: NoOp },
621    CodeTableEntry { first: Copy { size: 13, mode: 2 }, second: NoOp },
622    CodeTableEntry { first: Copy { size: 14, mode: 2 }, second: NoOp },
623    CodeTableEntry { first: Copy { size: 15, mode: 2 }, second: NoOp },
624    CodeTableEntry { first: Copy { size: 16, mode: 2 }, second: NoOp },
625    CodeTableEntry { first: Copy { size: 17, mode: 2 }, second: NoOp },
626    CodeTableEntry { first: Copy { size: 18, mode: 2 }, second: NoOp },
627    CodeTableEntry { first: Copy { size: 0, mode: 3 }, second: NoOp },
628    CodeTableEntry { first: Copy { size: 4, mode: 3 }, second: NoOp },
629    CodeTableEntry { first: Copy { size: 5, mode: 3 }, second: NoOp },
630    CodeTableEntry { first: Copy { size: 6, mode: 3 }, second: NoOp },
631    CodeTableEntry { first: Copy { size: 7, mode: 3 }, second: NoOp },
632    CodeTableEntry { first: Copy { size: 8, mode: 3 }, second: NoOp },
633    CodeTableEntry { first: Copy { size: 9, mode: 3 }, second: NoOp },
634    CodeTableEntry { first: Copy { size: 10, mode: 3 }, second: NoOp },
635    CodeTableEntry { first: Copy { size: 11, mode: 3 }, second: NoOp },
636    CodeTableEntry { first: Copy { size: 12, mode: 3 }, second: NoOp },
637    CodeTableEntry { first: Copy { size: 13, mode: 3 }, second: NoOp },
638    CodeTableEntry { first: Copy { size: 14, mode: 3 }, second: NoOp },
639    CodeTableEntry { first: Copy { size: 15, mode: 3 }, second: NoOp },
640    CodeTableEntry { first: Copy { size: 16, mode: 3 }, second: NoOp },
641    CodeTableEntry { first: Copy { size: 17, mode: 3 }, second: NoOp },
642    CodeTableEntry { first: Copy { size: 18, mode: 3 }, second: NoOp },
643    CodeTableEntry { first: Copy { size: 0, mode: 4 }, second: NoOp },
644    CodeTableEntry { first: Copy { size: 4, mode: 4 }, second: NoOp },
645    CodeTableEntry { first: Copy { size: 5, mode: 4 }, second: NoOp },
646    CodeTableEntry { first: Copy { size: 6, mode: 4 }, second: NoOp },
647    CodeTableEntry { first: Copy { size: 7, mode: 4 }, second: NoOp },
648    CodeTableEntry { first: Copy { size: 8, mode: 4 }, second: NoOp },
649    CodeTableEntry { first: Copy { size: 9, mode: 4 }, second: NoOp },
650    CodeTableEntry { first: Copy { size: 10, mode: 4 }, second: NoOp },
651    CodeTableEntry { first: Copy { size: 11, mode: 4 }, second: NoOp },
652    CodeTableEntry { first: Copy { size: 12, mode: 4 }, second: NoOp },
653    CodeTableEntry { first: Copy { size: 13, mode: 4 }, second: NoOp },
654    CodeTableEntry { first: Copy { size: 14, mode: 4 }, second: NoOp },
655    CodeTableEntry { first: Copy { size: 15, mode: 4 }, second: NoOp },
656    CodeTableEntry { first: Copy { size: 16, mode: 4 }, second: NoOp },
657    CodeTableEntry { first: Copy { size: 17, mode: 4 }, second: NoOp },
658    CodeTableEntry { first: Copy { size: 18, mode: 4 }, second: NoOp },
659    CodeTableEntry { first: Copy { size: 0, mode: 5 }, second: NoOp },
660    CodeTableEntry { first: Copy { size: 4, mode: 5 }, second: NoOp },
661    CodeTableEntry { first: Copy { size: 5, mode: 5 }, second: NoOp },
662    CodeTableEntry { first: Copy { size: 6, mode: 5 }, second: NoOp },
663    CodeTableEntry { first: Copy { size: 7, mode: 5 }, second: NoOp },
664    CodeTableEntry { first: Copy { size: 8, mode: 5 }, second: NoOp },
665    CodeTableEntry { first: Copy { size: 9, mode: 5 }, second: NoOp },
666    CodeTableEntry { first: Copy { size: 10, mode: 5 }, second: NoOp },
667    CodeTableEntry { first: Copy { size: 11, mode: 5 }, second: NoOp },
668    CodeTableEntry { first: Copy { size: 12, mode: 5 }, second: NoOp },
669    CodeTableEntry { first: Copy { size: 13, mode: 5 }, second: NoOp },
670    CodeTableEntry { first: Copy { size: 14, mode: 5 }, second: NoOp },
671    CodeTableEntry { first: Copy { size: 15, mode: 5 }, second: NoOp },
672    CodeTableEntry { first: Copy { size: 16, mode: 5 }, second: NoOp },
673    CodeTableEntry { first: Copy { size: 17, mode: 5 }, second: NoOp },
674    CodeTableEntry { first: Copy { size: 18, mode: 5 }, second: NoOp },
675    CodeTableEntry { first: Copy { size: 0, mode: 6 }, second: NoOp },
676    CodeTableEntry { first: Copy { size: 4, mode: 6 }, second: NoOp },
677    CodeTableEntry { first: Copy { size: 5, mode: 6 }, second: NoOp },
678    CodeTableEntry { first: Copy { size: 6, mode: 6 }, second: NoOp }, //118
679    CodeTableEntry { first: Copy { size: 7, mode: 6 }, second: NoOp },
680    CodeTableEntry { first: Copy { size: 8, mode: 6 }, second: NoOp },
681    CodeTableEntry { first: Copy { size: 9, mode: 6 }, second: NoOp },
682    CodeTableEntry { first: Copy { size: 10, mode: 6 }, second: NoOp },
683    CodeTableEntry { first: Copy { size: 11, mode: 6 }, second: NoOp },
684    CodeTableEntry { first: Copy { size: 12, mode: 6 }, second: NoOp },
685    CodeTableEntry { first: Copy { size: 13, mode: 6 }, second: NoOp },
686    CodeTableEntry { first: Copy { size: 14, mode: 6 }, second: NoOp },
687    CodeTableEntry { first: Copy { size: 15, mode: 6 }, second: NoOp },
688    CodeTableEntry { first: Copy { size: 16, mode: 6 }, second: NoOp },
689    CodeTableEntry { first: Copy { size: 17, mode: 6 }, second: NoOp },
690    CodeTableEntry { first: Copy { size: 18, mode: 6 }, second: NoOp },
691    CodeTableEntry { first: Copy { size: 0, mode: 7 }, second: NoOp },
692    CodeTableEntry { first: Copy { size: 4, mode: 7 }, second: NoOp },
693    CodeTableEntry { first: Copy { size: 5, mode: 7 }, second: NoOp },
694    CodeTableEntry { first: Copy { size: 6, mode: 7 }, second: NoOp },
695    CodeTableEntry { first: Copy { size: 7, mode: 7 }, second: NoOp },
696    CodeTableEntry { first: Copy { size: 8, mode: 7 }, second: NoOp },
697    CodeTableEntry { first: Copy { size: 9, mode: 7 }, second: NoOp },
698    CodeTableEntry { first: Copy { size: 10, mode: 7 }, second: NoOp },
699    CodeTableEntry { first: Copy { size: 11, mode: 7 }, second: NoOp },
700    CodeTableEntry { first: Copy { size: 12, mode: 7 }, second: NoOp },
701    CodeTableEntry { first: Copy { size: 13, mode: 7 }, second: NoOp },
702    CodeTableEntry { first: Copy { size: 14, mode: 7 }, second: NoOp },
703    CodeTableEntry { first: Copy { size: 15, mode: 7 }, second: NoOp },
704    CodeTableEntry { first: Copy { size: 16, mode: 7 }, second: NoOp },
705    CodeTableEntry { first: Copy { size: 17, mode: 7 }, second: NoOp },
706    CodeTableEntry { first: Copy { size: 18, mode: 7 }, second: NoOp },
707    CodeTableEntry { first: Copy { size: 0, mode: 8 }, second: NoOp },
708    CodeTableEntry { first: Copy { size: 4, mode: 8 }, second: NoOp },
709    CodeTableEntry { first: Copy { size: 5, mode: 8 }, second: NoOp },
710    CodeTableEntry { first: Copy { size: 6, mode: 8 }, second: NoOp },
711    CodeTableEntry { first: Copy { size: 7, mode: 8 }, second: NoOp },
712    CodeTableEntry { first: Copy { size: 8, mode: 8 }, second: NoOp },
713    CodeTableEntry { first: Copy { size: 9, mode: 8 }, second: NoOp },
714    CodeTableEntry { first: Copy { size: 10, mode: 8 }, second: NoOp },
715    CodeTableEntry { first: Copy { size: 11, mode: 8 }, second: NoOp },
716    CodeTableEntry { first: Copy { size: 12, mode: 8 }, second: NoOp },
717    CodeTableEntry { first: Copy { size: 13, mode: 8 }, second: NoOp },
718    CodeTableEntry { first: Copy { size: 14, mode: 8 }, second: NoOp },
719    CodeTableEntry { first: Copy { size: 15, mode: 8 }, second: NoOp },
720    CodeTableEntry { first: Copy { size: 16, mode: 8 }, second: NoOp },
721    CodeTableEntry { first: Copy { size: 17, mode: 8 }, second: NoOp },
722    CodeTableEntry { first: Copy { size: 18, mode: 8 }, second: NoOp },
723    CodeTableEntry { first: Add { size: 1 }, second: Copy { size: 4, mode: 0 } }, //163
724    CodeTableEntry { first: Add { size: 1 }, second: Copy { size: 5, mode: 0 } },
725    CodeTableEntry { first: Add { size: 1 }, second: Copy { size: 6, mode: 0 } },
726    CodeTableEntry { first: Add { size: 1 }, second: Copy { size: 4, mode: 1 } },
727    CodeTableEntry { first: Add { size: 1 }, second: Copy { size: 5, mode: 1 } },
728    CodeTableEntry { first: Add { size: 1 }, second: Copy { size: 6, mode: 1 } },
729    CodeTableEntry { first: Add { size: 1 }, second: Copy { size: 4, mode: 2 } },
730    CodeTableEntry { first: Add { size: 1 }, second: Copy { size: 5, mode: 2 } },
731    CodeTableEntry { first: Add { size: 1 }, second: Copy { size: 6, mode: 2 } },
732    CodeTableEntry { first: Add { size: 1 }, second: Copy { size: 4, mode: 3 } },
733    CodeTableEntry { first: Add { size: 1 }, second: Copy { size: 5, mode: 3 } }, //173
734    CodeTableEntry { first: Add { size: 1 }, second: Copy { size: 6, mode: 3 } },
735    CodeTableEntry { first: Add { size: 1 }, second: Copy { size: 4, mode: 4 } },
736    CodeTableEntry { first: Add { size: 1 }, second: Copy { size: 5, mode: 4 } },
737    CodeTableEntry { first: Add { size: 1 }, second: Copy { size: 6, mode: 4 } },
738    CodeTableEntry { first: Add { size: 1 }, second: Copy { size: 4, mode: 5 } },
739    CodeTableEntry { first: Add { size: 1 }, second: Copy { size: 5, mode: 5 } },
740    CodeTableEntry { first: Add { size: 1 }, second: Copy { size: 6, mode: 5 } },
741    CodeTableEntry { first: Add { size: 2 }, second: Copy { size: 4, mode: 0 } },
742    CodeTableEntry { first: Add { size: 2 }, second: Copy { size: 5, mode: 0 } },
743    CodeTableEntry { first: Add { size: 2 }, second: Copy { size: 6, mode: 0 } }, //183
744    CodeTableEntry { first: Add { size: 2 }, second: Copy { size: 4, mode: 1 } },
745    CodeTableEntry { first: Add { size: 2 }, second: Copy { size: 5, mode: 1 } },
746    CodeTableEntry { first: Add { size: 2 }, second: Copy { size: 6, mode: 1 } },
747    CodeTableEntry { first: Add { size: 2 }, second: Copy { size: 4, mode: 2 } },
748    CodeTableEntry { first: Add { size: 2 }, second: Copy { size: 5, mode: 2 } },
749    CodeTableEntry { first: Add { size: 2 }, second: Copy { size: 6, mode: 2 } }, //189
750    CodeTableEntry { first: Add { size: 2 }, second: Copy { size: 4, mode: 3 } },
751    CodeTableEntry { first: Add { size: 2 }, second: Copy { size: 5, mode: 3 } },
752    CodeTableEntry { first: Add { size: 2 }, second: Copy { size: 6, mode: 3 } },
753    CodeTableEntry { first: Add { size: 2 }, second: Copy { size: 4, mode: 4 } }, //193
754    CodeTableEntry { first: Add { size: 2 }, second: Copy { size: 5, mode: 4 } },
755    CodeTableEntry { first: Add { size: 2 }, second: Copy { size: 6, mode: 4 } },
756    CodeTableEntry { first: Add { size: 2 }, second: Copy { size: 4, mode: 5 } },
757    CodeTableEntry { first: Add { size: 2 }, second: Copy { size: 5, mode: 5 } },
758    CodeTableEntry { first: Add { size: 2 }, second: Copy { size: 6, mode: 5 } },
759    CodeTableEntry { first: Add { size: 3 }, second: Copy { size: 4, mode: 0 } },
760    CodeTableEntry { first: Add { size: 3 }, second: Copy { size: 5, mode: 0 } },
761    CodeTableEntry { first: Add { size: 3 }, second: Copy { size: 6, mode: 0 } },
762    CodeTableEntry { first: Add { size: 3 }, second: Copy { size: 4, mode: 1 } },
763    CodeTableEntry { first: Add { size: 3 }, second: Copy { size: 5, mode: 1 } }, //203
764    CodeTableEntry { first: Add { size: 3 }, second: Copy { size: 6, mode: 1 } },
765    CodeTableEntry { first: Add { size: 3 }, second: Copy { size: 4, mode: 2 } },
766    CodeTableEntry { first: Add { size: 3 }, second: Copy { size: 5, mode: 2 } },
767    CodeTableEntry { first: Add { size: 3 }, second: Copy { size: 6, mode: 2 } },
768    CodeTableEntry { first: Add { size: 3 }, second: Copy { size: 4, mode: 3 } },
769    CodeTableEntry { first: Add { size: 3 }, second: Copy { size: 5, mode: 3 } },
770    CodeTableEntry { first: Add { size: 3 }, second: Copy { size: 6, mode: 3 } },
771    CodeTableEntry { first: Add { size: 3 }, second: Copy { size: 4, mode: 4 } },
772    CodeTableEntry { first: Add { size: 3 }, second: Copy { size: 5, mode: 4 } },
773    CodeTableEntry { first: Add { size: 3 }, second: Copy { size: 6, mode: 4 } }, //213
774    CodeTableEntry { first: Add { size: 3 }, second: Copy { size: 4, mode: 5 } },
775    CodeTableEntry { first: Add { size: 3 }, second: Copy { size: 5, mode: 5 } },
776    CodeTableEntry { first: Add { size: 3 }, second: Copy { size: 6, mode: 5 } },
777    CodeTableEntry { first: Add { size: 4 }, second: Copy { size: 4, mode: 0 } },
778    CodeTableEntry { first: Add { size: 4 }, second: Copy { size: 5, mode: 0 } },
779    CodeTableEntry { first: Add { size: 4 }, second: Copy { size: 6, mode: 0 } },
780    CodeTableEntry { first: Add { size: 4 }, second: Copy { size: 4, mode: 1 } },
781    CodeTableEntry { first: Add { size: 4 }, second: Copy { size: 5, mode: 1 } },
782    CodeTableEntry { first: Add { size: 4 }, second: Copy { size: 6, mode: 1 } },
783    CodeTableEntry { first: Add { size: 4 }, second: Copy { size: 4, mode: 2 } }, //223
784    CodeTableEntry { first: Add { size: 4 }, second: Copy { size: 5, mode: 2 } },
785    CodeTableEntry { first: Add { size: 4 }, second: Copy { size: 6, mode: 2 } },
786    CodeTableEntry { first: Add { size: 4 }, second: Copy { size: 4, mode: 3 } },
787    CodeTableEntry { first: Add { size: 4 }, second: Copy { size: 5, mode: 3 } },
788    CodeTableEntry { first: Add { size: 4 }, second: Copy { size: 6, mode: 3 } },
789    CodeTableEntry { first: Add { size: 4 }, second: Copy { size: 4, mode: 4 } },
790    CodeTableEntry { first: Add { size: 4 }, second: Copy { size: 5, mode: 4 } },
791    CodeTableEntry { first: Add { size: 4 }, second: Copy { size: 6, mode: 4 } },
792    CodeTableEntry { first: Add { size: 4 }, second: Copy { size: 4, mode: 5 } },
793    CodeTableEntry { first: Add { size: 4 }, second: Copy { size: 5, mode: 5 } }, //233
794    CodeTableEntry { first: Add { size: 4 }, second: Copy { size: 6, mode: 5 } },
795    CodeTableEntry { first: Add { size: 1 }, second: Copy { size: 4, mode: 6 } }, //235
796    CodeTableEntry { first: Add { size: 1 }, second: Copy { size: 4, mode: 7 } },
797    CodeTableEntry { first: Add { size: 1 }, second: Copy { size: 4, mode: 8 } },
798    CodeTableEntry { first: Add { size: 2 }, second: Copy { size: 4, mode: 6 } },
799    CodeTableEntry { first: Add { size: 2 }, second: Copy { size: 4, mode: 7 } },
800    CodeTableEntry { first: Add { size: 2 }, second: Copy { size: 4, mode: 8 } },
801    CodeTableEntry { first: Add { size: 3 }, second: Copy { size: 4, mode: 6 } },
802    CodeTableEntry { first: Add { size: 3 }, second: Copy { size: 4, mode: 7 } },
803    CodeTableEntry { first: Add { size: 3 }, second: Copy { size: 4, mode: 8 } }, //243
804    CodeTableEntry { first: Add { size: 4 }, second: Copy { size: 4, mode: 6 } },
805    CodeTableEntry { first: Add { size: 4 }, second: Copy { size: 4, mode: 7 } },
806    CodeTableEntry { first: Add { size: 4 }, second: Copy { size: 4, mode: 8 } },
807    CodeTableEntry { first: Copy { size: 4, mode: 0 }, second: Add { size: 1 } },
808    CodeTableEntry { first: Copy { size: 4, mode: 1 }, second: Add { size: 1 } },
809    CodeTableEntry { first: Copy { size: 4, mode: 2 }, second: Add { size: 1 } },
810    CodeTableEntry { first: Copy { size: 4, mode: 3 }, second: Add { size: 1 } },
811    CodeTableEntry { first: Copy { size: 4, mode: 4 }, second: Add { size: 1 } },
812    CodeTableEntry { first: Copy { size: 4, mode: 5 }, second: Add { size: 1 } }, //253
813    CodeTableEntry { first: Copy { size: 4, mode: 6 }, second: Add { size: 1 } },
814    CodeTableEntry { first: Copy { size: 4, mode: 7 }, second: Add { size: 1 } },
815    CodeTableEntry { first: Copy { size: 4, mode: 8 }, second: Add { size: 1 } }
816];