|
18 | 18 | use std::collections::{HashMap, HashSet}; |
19 | 19 |
|
20 | 20 | use bytes::Bytes; |
21 | | -use once_cell::sync::Lazy; |
22 | 21 | use serde::{Deserialize, Serialize}; |
23 | 22 |
|
24 | 23 | use crate::io::{FileRead, InputFile}; |
@@ -56,44 +55,36 @@ pub(crate) struct BlobMetadata { |
56 | 55 | pub(crate) properties: HashMap<String, String>, |
57 | 56 | } |
58 | 57 |
|
59 | | -#[derive(Clone, PartialEq, Eq, Hash, Debug)] |
| 58 | +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] |
60 | 59 | pub(crate) enum Flag { |
61 | | - FooterPayloadCompressed, |
| 60 | + FooterPayloadCompressed = 0, |
62 | 61 | } |
63 | 62 |
|
64 | | -#[derive(PartialEq, Eq, Hash)] |
65 | | -pub(crate) struct ByteNumber(pub u8); |
66 | | - |
67 | | -#[derive(PartialEq, Eq, Hash)] |
68 | | -pub(crate) struct BitNumber(pub u8); |
69 | | - |
70 | | -static FLAGS_BY_BYTE_AND_BIT: Lazy<HashMap<(ByteNumber, BitNumber), Flag>> = Lazy::new(|| { |
71 | | - let mut m = HashMap::new(); |
72 | | - m.insert( |
73 | | - ( |
74 | | - Flag::FooterPayloadCompressed.byte_number(), |
75 | | - Flag::FooterPayloadCompressed.bit_number(), |
76 | | - ), |
77 | | - Flag::FooterPayloadCompressed, |
78 | | - ); |
79 | | - m |
80 | | -}); |
81 | | - |
82 | 63 | impl Flag { |
83 | | - pub(crate) fn byte_number(&self) -> ByteNumber { |
84 | | - match self { |
85 | | - Flag::FooterPayloadCompressed => ByteNumber(0), |
86 | | - } |
| 64 | + pub(crate) fn byte_idx(self) -> u8 { |
| 65 | + (self as u8) / 8 |
87 | 66 | } |
88 | 67 |
|
89 | | - pub(crate) fn bit_number(&self) -> BitNumber { |
90 | | - match self { |
91 | | - Flag::FooterPayloadCompressed => BitNumber(0), |
92 | | - } |
| 68 | + pub(crate) fn bit_idx(self) -> u8 { |
| 69 | + (self as u8) % 8 |
93 | 70 | } |
94 | 71 |
|
95 | | - fn from(byte_and_bit: &(ByteNumber, BitNumber)) -> Option<Flag> { |
96 | | - FLAGS_BY_BYTE_AND_BIT.get(byte_and_bit).cloned() |
| 72 | + fn matches(self, byte_idx: &u8, bit_idx: &u8) -> bool { |
| 73 | + &self.byte_idx() == byte_idx && &self.bit_idx() == bit_idx |
| 74 | + } |
| 75 | + |
| 76 | + fn from(byte_idx: &u8, bit_idx: &u8) -> Result<Flag> { |
| 77 | + if Flag::FooterPayloadCompressed.matches(byte_idx, bit_idx) { |
| 78 | + Ok(Flag::FooterPayloadCompressed) |
| 79 | + } else { |
| 80 | + Err(Error::new( |
| 81 | + ErrorKind::DataInvalid, |
| 82 | + format!( |
| 83 | + "Unknown flag byte {} and bit {} combination", |
| 84 | + byte_idx, bit_idx |
| 85 | + ), |
| 86 | + )) |
| 87 | + } |
97 | 88 | } |
98 | 89 | } |
99 | 90 |
|
@@ -178,35 +169,25 @@ impl FileMetadata { |
178 | 169 |
|
179 | 170 | fn decode_flags(footer_bytes: &[u8]) -> Result<HashSet<Flag>> { |
180 | 171 | let mut flags = HashSet::new(); |
181 | | - for byte_number in 0..FileMetadata::FOOTER_STRUCT_FLAGS_LENGTH { |
| 172 | + |
| 173 | + for byte_idx in 0..FileMetadata::FOOTER_STRUCT_FLAGS_LENGTH { |
182 | 174 | let byte_offset = footer_bytes.len() |
183 | 175 | - usize::from(FileMetadata::MAGIC_LENGTH) |
184 | 176 | - usize::from(FileMetadata::FOOTER_STRUCT_FLAGS_LENGTH) |
185 | | - + usize::from(byte_number); |
| 177 | + + usize::from(byte_idx); |
186 | 178 |
|
187 | | - let mut flag_byte = *footer_bytes.get(byte_offset).ok_or_else(|| { |
| 179 | + let flag_byte = *footer_bytes.get(byte_offset).ok_or_else(|| { |
188 | 180 | Error::new(ErrorKind::DataInvalid, "Index range is out of bounds.") |
189 | 181 | })?; |
190 | | - let mut bit_number = 0; |
191 | | - while flag_byte != 0 { |
192 | | - if flag_byte & 0x1 != 0 { |
193 | | - match Flag::from(&(ByteNumber(byte_number), BitNumber(bit_number))) { |
194 | | - Some(flag) => flags.insert(flag), |
195 | | - None => { |
196 | | - return Err(Error::new( |
197 | | - ErrorKind::DataInvalid, |
198 | | - format!( |
199 | | - "Unknown flag byte {} and bit {} combination", |
200 | | - byte_number, bit_number |
201 | | - ), |
202 | | - )) |
203 | | - } |
204 | | - }; |
| 182 | + |
| 183 | + for bit_idx in 0..8 { |
| 184 | + if ((flag_byte >> bit_idx) & 1) != 0 { |
| 185 | + let flag = Flag::from(&byte_idx, &bit_idx)?; |
| 186 | + flags.insert(flag); |
205 | 187 | } |
206 | | - flag_byte >>= 1; |
207 | | - bit_number += 1; |
208 | 188 | } |
209 | 189 | } |
| 190 | + |
210 | 191 | Ok(flags) |
211 | 192 | } |
212 | 193 |
|
|
0 commit comments