summaryrefslogtreecommitdiffstats
path: root/openpgp/src/types/features.rs
diff options
context:
space:
mode:
Diffstat (limited to 'openpgp/src/types/features.rs')
-rw-r--r--openpgp/src/types/features.rs93
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));