picky_asn1/bit_string.rs
1use core::fmt;
2use serde::{de, ser};
3
4/// A bit string.
5///
6/// Rewrite based on [this implementation](https://melvinw.github.io/rust-asn1/asn1/struct.BitString.html) by Melvin Walls Jr.
7/// licensed with
8///
9/// > The MIT License (MIT)
10/// >
11/// > Copyright (c) 2016 Melvin Walls Jr.
12/// >
13/// > Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
14/// >
15/// > The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
16/// >
17/// > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18///
19/// # Examples
20///
21/// ```
22/// use picky_asn1::bit_string::BitString;
23///
24/// let mut b = BitString::with_len(60);
25///
26/// b.set(0, true);
27/// assert_eq!(b.is_set(0), true);
28///
29/// b.set(59, true);
30/// assert_eq!(b.is_set(59), true);
31///
32/// // because len is 60, attempts at setting anything greater than 59 won't change anything
33/// b.set(63, true);
34/// assert_eq!(b.is_set(63), false);
35/// ```
36#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone)]
37pub struct BitString {
38 data: Vec<u8>,
39}
40
41impl BitString {
42 /// Returns inner bytes slice
43 pub fn as_bytes(&self) -> &[u8] {
44 &self.data
45 }
46
47 fn h_number_of_unused_bits(data_size: usize, num_bits: usize) -> u8 {
48 (data_size * 8 - num_bits) as u8
49 }
50
51 /// Construct a `BitString` of length `n` with all bits set to 0.
52 pub fn with_len(num_bits: usize) -> BitString {
53 let data_size = num_bits / 8 + if num_bits % 8 == 0 { 0 } else { 1 };
54 let mut data = vec![0x00u8; data_size + 1];
55 data[0] = Self::h_number_of_unused_bits(data_size, num_bits);
56 BitString { data }
57 }
58
59 /// Construct a `BitString` of length `n` with initial values contained in `data`.
60 ///
61 /// # Examples
62 ///
63 /// ```
64 /// use picky_asn1::bit_string::BitString;
65 ///
66 /// let v: Vec<u8> = vec![0x00, 0x02];
67 /// let b = BitString::with_bytes_and_len(v, 15);
68 /// assert_eq!(b.is_set(0), false);
69 /// assert_eq!(b.is_set(14), true);
70 ///
71 /// // because len is 15, everything greater than 14 will returns false
72 /// assert_eq!(b.is_set(15), false);
73 /// assert_eq!(b.is_set(938), false);
74 /// ```
75 pub fn with_bytes_and_len<V>(data: V, num_bits: usize) -> BitString
76 where
77 V: Into<Vec<u8>>,
78 {
79 let mut data = data.into();
80 let number_of_unused = Self::h_number_of_unused_bits(data.len(), num_bits);
81 data.insert(0, number_of_unused);
82 BitString { data }
83 }
84
85 /// Construct a `BitString` from initial values contained in `data`.
86 /// Length is inferred fromthe size of `data`.
87 ///
88 /// # Examples
89 ///
90 /// ```
91 /// use picky_asn1::bit_string::BitString;
92 ///
93 /// let v: Vec<u8> = vec![0x00, 0x02];
94 /// let b = BitString::with_bytes(v);
95 /// assert_eq!(b.is_set(0), false);
96 /// assert_eq!(b.is_set(14), true);
97 /// ```
98 pub fn with_bytes<V>(data: V) -> BitString
99 where
100 V: Into<Vec<u8>>,
101 {
102 let mut data = data.into();
103 data.insert(0, 0); // no unused bits
104 BitString { data }
105 }
106
107 /// Get the number of available bits in the `BitString`
108 pub fn get_num_bits(&self) -> usize {
109 (self.data.len() - 1) * 8 - self.data[0] as usize
110 }
111
112 /// Set the length of a `BitString` with each additional slot filled with 0.
113 ///
114 /// # Examples
115 ///
116 /// ```
117 /// use picky_asn1::bit_string::BitString;
118 ///
119 /// let v: Vec<u8> = vec![0x01, 0x01];
120 /// let mut b = BitString::with_bytes_and_len(v, 16);
121 /// assert_eq!(b.is_set(7), true);
122 /// assert_eq!(b.is_set(15), true);
123 ///
124 /// b.set_num_bits(8);
125 /// assert_eq!(b.is_set(7), true);
126 /// b.set(15, true); // attempts to set a value out of the bounds are ignored
127 /// assert_eq!(b.is_set(15), false);
128 ///
129 /// b.set_num_bits(16);
130 /// assert_eq!(b.is_set(7), true);
131 /// assert_eq!(b.is_set(15), false);
132 /// b.set(15, true);
133 /// assert_eq!(b.is_set(15), true);
134 /// ```
135 pub fn set_num_bits(&mut self, num_bits: usize) {
136 let new_size = num_bits / 8 + if num_bits % 8 == 0 { 0 } else { 1 };
137 self.data[0] = Self::h_number_of_unused_bits(new_size, num_bits);
138 self.data.resize(new_size + 1, 0);
139 }
140
141 /// Check if bit `i` is set.
142 ///
143 /// # Examples
144 ///
145 /// ```
146 /// use picky_asn1::bit_string::BitString;
147 ///
148 /// let mut b = BitString::with_len(10);
149 /// assert_eq!(b.is_set(7), false);
150 /// b.set(7, true);
151 /// assert_eq!(b.is_set(7), true);
152 /// ```
153 pub fn is_set(&self, i: usize) -> bool {
154 if i > self.get_num_bits() {
155 return false;
156 }
157
158 let bucket = i / 8;
159 let pos = i - bucket * 8;
160 let mask = (1 << (7 - pos)) as u8;
161 self.data[bucket + 1] & mask != 0
162 }
163
164 /// Set bit `i` to `val`.
165 pub fn set(&mut self, i: usize, val: bool) {
166 if i > self.get_num_bits() {
167 return;
168 }
169
170 let bucket = i / 8;
171 let pos = i - bucket * 8;
172 let mask = (1 << (7 - pos)) as u8;
173
174 if val {
175 self.data[bucket + 1] |= mask;
176 } else {
177 self.data[bucket + 1] &= !mask;
178 }
179 }
180
181 pub fn get_num_unused_bits(&self) -> u8 {
182 self.data[0]
183 }
184
185 pub fn get_num_buckets(&self) -> usize {
186 self.data.len() - 1
187 }
188
189 pub fn get_bucket(&self, i: usize) -> u8 {
190 self.data[i + 1]
191 }
192
193 pub fn get_bucket_mut(&mut self, i: usize) -> &mut u8 {
194 &mut self.data[i + 1]
195 }
196
197 pub fn set_bucket(&mut self, i: usize, value: u8) {
198 self.data[i + 1] = value
199 }
200
201 /// Returns an immutabe view on the payload.
202 ///
203 /// # Examples
204 ///
205 /// ```
206 /// use picky_asn1::bit_string::BitString;
207 ///
208 /// let v: Vec<u8> = vec![0x01, 0x00];
209 /// let mut b = BitString::with_bytes_and_len(v, 15);
210 /// b.set(14, true);
211 /// let payload = b.payload_view();
212 /// assert_eq!(payload, &[0x01, 0x02]);
213 /// ```
214 pub fn payload_view(&self) -> &[u8] {
215 &self.data[1..]
216 }
217
218 /// Returns a mutabe view on the payload.
219 ///
220 /// # Examples
221 ///
222 /// ```
223 /// use picky_asn1::bit_string::BitString;
224 ///
225 /// let v: Vec<u8> = vec![0x01, 0x00];
226 /// let mut b = BitString::with_bytes_and_len(v, 15);
227 /// b.set(14, true);
228 /// let payload = b.payload_view_mut();
229 /// payload[0] = 0x20;
230 /// assert_eq!(payload, &[0x20, 0x02]);
231 /// ```
232 pub fn payload_view_mut(&mut self) -> &mut [u8] {
233 &mut self.data[1..]
234 }
235}
236
237impl fmt::Debug for BitString {
238 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
239 write!(f, "0x")?;
240 self.data.iter().try_for_each(|byte| write!(f, "{byte:02X}"))?;
241 Ok(())
242 }
243}
244
245impl From<BitString> for Vec<u8> {
246 /// Strips 'unused bits count' byte and returns payload.
247 ///
248 /// # Examples
249 ///
250 /// ```
251 /// use picky_asn1::bit_string::BitString;
252 ///
253 /// let v: Vec<u8> = vec![0x01, 0x00];
254 /// let mut b = BitString::with_bytes_and_len(v, 15);
255 /// b.set(14, true);
256 /// let payload: Vec<u8> = b.into();
257 /// assert_eq!(payload, vec![0x01, 0x02]);
258 /// ```
259 fn from(mut bs: BitString) -> Self {
260 bs.data.drain(1..).collect()
261 }
262}
263
264impl<'de> de::Deserialize<'de> for BitString {
265 fn deserialize<D>(deserializer: D) -> Result<BitString, D::Error>
266 where
267 D: de::Deserializer<'de>,
268 {
269 struct Visitor;
270
271 impl<'de> de::Visitor<'de> for Visitor {
272 type Value = BitString;
273
274 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
275 formatter.write_str("a valid buffer representing a bit string")
276 }
277
278 fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
279 where
280 E: de::Error,
281 {
282 self.visit_byte_buf(v.to_vec())
283 }
284
285 fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
286 where
287 E: de::Error,
288 {
289 Ok(BitString { data: v })
290 }
291 }
292
293 deserializer.deserialize_byte_buf(Visitor)
294 }
295}
296
297impl ser::Serialize for BitString {
298 fn serialize<S>(&self, serializer: S) -> Result<<S as ser::Serializer>::Ok, <S as ser::Serializer>::Error>
299 where
300 S: ser::Serializer,
301 {
302 serializer.serialize_bytes(&self.data)
303 }
304}
305
306impl Default for BitString {
307 fn default() -> Self {
308 BitString::with_len(0)
309 }
310}