1 use crate::error::Result; 2 3 use byteorder::{ReadBytesExt, WriteBytesExt}; 4 use std::io::{Read, Write}; 5 6 #[derive(Copy, Clone, Debug, PartialEq, Eq)] 7 pub enum CompressionMethodId { 8 Null = 0, 9 Unsupported, 10 } 11 12 impl From<u8> for CompressionMethodId { 13 fn from(val: u8) -> Self { 14 match val { 15 0 => CompressionMethodId::Null, 16 _ => CompressionMethodId::Unsupported, 17 } 18 } 19 } 20 21 #[derive(Clone, Debug, PartialEq, Eq)] 22 pub struct CompressionMethods { 23 pub ids: Vec<CompressionMethodId>, 24 } 25 26 impl CompressionMethods { 27 pub fn size(&self) -> usize { 28 1 + self.ids.len() 29 } 30 31 pub fn marshal<W: Write>(&self, writer: &mut W) -> Result<()> { 32 writer.write_u8(self.ids.len() as u8)?; 33 34 for id in &self.ids { 35 writer.write_u8(*id as u8)?; 36 } 37 38 Ok(writer.flush()?) 39 } 40 41 pub fn unmarshal<R: Read>(reader: &mut R) -> Result<Self> { 42 let compression_methods_count = reader.read_u8()? as usize; 43 let mut ids = vec![]; 44 for _ in 0..compression_methods_count { 45 let id = reader.read_u8()?.into(); 46 if id != CompressionMethodId::Unsupported { 47 ids.push(id); 48 } 49 } 50 51 Ok(CompressionMethods { ids }) 52 } 53 } 54 55 pub fn default_compression_methods() -> CompressionMethods { 56 CompressionMethods { 57 ids: vec![CompressionMethodId::Null], 58 } 59 } 60