|
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