diff options
Diffstat (limited to 'openpgp/src/types/features.rs')
-rw-r--r-- | openpgp/src/types/features.rs | 93 |
1 files changed, 15 insertions, 78 deletions
diff --git a/openpgp/src/types/features.rs b/openpgp/src/types/features.rs index f1021d2f..84badd48 100644 --- a/openpgp/src/types/features.rs +++ b/openpgp/src/types/features.rs @@ -3,6 +3,8 @@ use std::fmt; #[cfg(any(test, feature = "quickcheck"))] use quickcheck::{Arbitrary, Gen}; +use crate::types::Bitfield; + /// Describes the features supported by an OpenPGP implementation. /// /// The feature flags are defined in [Section 5.2.3.24 of RFC 4880], @@ -52,9 +54,7 @@ use quickcheck::{Arbitrary, Gen}; /// # Ok(()) } /// ``` #[derive(Clone, PartialEq, Eq, Hash)] -pub struct Features { - raw: Vec<u8>, -} +pub struct Features(Bitfield); impl fmt::Debug for Features { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { @@ -71,15 +71,7 @@ impl fmt::Debug for Features { } // Now print any unknown features. - for i in self.raw.iter() - .flat_map(|b| { - (0..8).into_iter().map(move |i| { - b & (1 << i) != 0 - }) - }) - .enumerate() - .filter_map(|(i, v)| if v { Some(i) } else { None }) - { + for i in self.0.iter() { match i { FEATURE_FLAG_MDC => (), FEATURE_FLAG_AEAD => (), @@ -92,15 +84,7 @@ impl fmt::Debug for Features { } // Mention any padding, as equality is sensitive to this. - let mut padding = 0; - for i in (0..self.raw.len()).rev() { - if self.raw[i] == 0 { - padding += 1; - } else { - break; - } - } - + let padding = self.0.padding_len(); if padding > 0 { if need_comma { f.write_str(", ")?; } write!(f, "+padding({} bytes)", padding)?; @@ -117,9 +101,7 @@ impl Features { pub fn new<B>(bytes: B) -> Self where B: AsRef<[u8]> { - Features{ - raw: bytes.as_ref().to_vec(), - } + Features(bytes.as_ref().to_vec().into()) } /// Returns an empty feature set. @@ -158,30 +140,12 @@ impl Features { /// # Ok(()) } /// ``` pub fn normalized_eq(&self, other: &Self) -> bool { - let (small, big) = if self.raw.len() < other.raw.len() { - (self, other) - } else { - (other, self) - }; - - for (s, b) in small.raw.iter().zip(big.raw.iter()) { - if s != b { - return false; - } - } - - for &b in &big.raw[small.raw.len()..] { - if b != 0 { - return false; - } - } - - true + self.0.normalized_eq(&other.0) } /// Returns a slice containing the raw values. pub(crate) fn as_slice(&self) -> &[u8] { - &self.raw + self.0.as_slice() } /// Returns whether the specified feature flag is set. @@ -208,23 +172,7 @@ impl Features { /// # Ok(()) } /// ``` pub fn check(&self, bit: usize) -> bool { - let byte = bit / 8; - - if byte >= self.raw.len() { - // Unset bits are false. - false - } else { - (self.raw[byte] & (1 << (bit % 8))) != 0 - } - } - - /// Remove any trailing padding. - fn clear_padding(mut self) -> Self { - while self.raw.len() > 0 && self.raw[self.raw.len() - 1] == 0 { - self.raw.truncate(self.raw.len() - 1); - } - - self + self.0.get(bit) } /// Sets the specified feature flag. @@ -249,14 +197,8 @@ impl Features { /// # assert!(! f.supports_aead()); /// # Ok(()) } /// ``` - pub fn set(mut self, bit: usize) -> Self { - let byte = bit / 8; - while self.raw.len() <= byte { - self.raw.push(0); - } - self.raw[byte] |= 1 << (bit % 8); - - self.clear_padding() + pub fn set(self, bit: usize) -> Self { + Self(self.0.set(bit)) } /// Clears the specified feature flag. @@ -281,13 +223,8 @@ impl Features { /// # assert!(! f.supports_aead()); /// # Ok(()) } /// ``` - pub fn clear(mut self, bit: usize) -> Self { - let byte = bit / 8; - if byte < self.raw.len() { - self.raw[byte] &= !(1 << (bit % 8)); - } - - self.clear_padding() + pub fn clear(self, bit: usize) -> Self { + Self(self.0.clear(bit)) } /// Returns whether the MDC feature flag is set. @@ -436,11 +373,11 @@ mod tests { assert!(val.normalized_eq(&q)); // Add some padding to q. Make sure they are still equal. - q.raw.push(0); + q.0.raw.push(0); assert!(val != q); assert!(val.normalized_eq(&q)); - q.raw.push(0); + q.0.raw.push(0); assert!(val != q); assert!(val.normalized_eq(&q)); |