1use crate::{
4 BytesRef, DecodeValue, DerOrd, EncodeValue, Error, ErrorKind, FixedTag, Header, Length, Reader,
5 Result, Tag, ValueOrd, Writer,
6};
7use core::{cmp::Ordering, iter::FusedIterator};
8
9#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
16pub struct BitStringRef<'a> {
17 unused_bits: u8,
19
20 bit_length: usize,
22
23 inner: BytesRef<'a>,
25}
26
27impl<'a> BitStringRef<'a> {
28 pub const MAX_UNUSED_BITS: u8 = 7;
30
31 pub fn new(unused_bits: u8, bytes: &'a [u8]) -> Result<Self> {
36 if (unused_bits > Self::MAX_UNUSED_BITS) || (unused_bits != 0 && bytes.is_empty()) {
37 return Err(Self::TAG.value_error());
38 }
39
40 let inner = BytesRef::new(bytes).map_err(|_| Self::TAG.length_error())?;
41
42 let bit_length = usize::try_from(inner.len())?
43 .checked_mul(8)
44 .and_then(|n| n.checked_sub(usize::from(unused_bits)))
45 .ok_or(ErrorKind::Overflow)?;
46
47 Ok(Self {
48 unused_bits,
49 bit_length,
50 inner,
51 })
52 }
53
54 pub fn from_bytes(bytes: &'a [u8]) -> Result<Self> {
58 Self::new(0, bytes)
59 }
60
61 pub fn unused_bits(&self) -> u8 {
63 self.unused_bits
64 }
65
66 pub fn has_unused_bits(&self) -> bool {
68 self.unused_bits != 0
69 }
70
71 pub fn bit_len(&self) -> usize {
73 self.bit_length
74 }
75
76 pub fn byte_len(&self) -> Length {
79 self.inner.len()
80 }
81
82 pub fn is_empty(&self) -> bool {
84 self.inner.is_empty()
85 }
86
87 pub fn as_bytes(&self) -> Option<&'a [u8]> {
95 if self.has_unused_bits() {
96 None
97 } else {
98 Some(self.raw_bytes())
99 }
100 }
101
102 pub fn raw_bytes(&self) -> &'a [u8] {
108 self.inner.as_slice()
109 }
110
111 pub fn bits(self) -> BitStringIter<'a> {
113 BitStringIter {
114 bit_string: self,
115 position: 0,
116 }
117 }
118}
119
120impl_any_conversions!(BitStringRef<'a>, 'a);
121
122impl<'a> DecodeValue<'a> for BitStringRef<'a> {
123 fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
124 let header = Header {
125 tag: header.tag,
126 length: (header.length - Length::ONE)?,
127 };
128
129 let unused_bits = reader.read_byte()?;
130 let inner = BytesRef::decode_value(reader, header)?;
131 Self::new(unused_bits, inner.as_slice())
132 }
133}
134
135impl EncodeValue for BitStringRef<'_> {
136 fn value_len(&self) -> Result<Length> {
137 self.byte_len() + Length::ONE
138 }
139
140 fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
141 writer.write_byte(self.unused_bits)?;
142 writer.write(self.raw_bytes())
143 }
144}
145
146impl ValueOrd for BitStringRef<'_> {
147 fn value_cmp(&self, other: &Self) -> Result<Ordering> {
148 match self.unused_bits.cmp(&other.unused_bits) {
149 Ordering::Equal => self.inner.der_cmp(&other.inner),
150 ordering => Ok(ordering),
151 }
152 }
153}
154
155impl<'a> From<&BitStringRef<'a>> for BitStringRef<'a> {
156 fn from(value: &BitStringRef<'a>) -> BitStringRef<'a> {
157 *value
158 }
159}
160
161impl<'a> TryFrom<&'a [u8]> for BitStringRef<'a> {
162 type Error = Error;
163
164 fn try_from(bytes: &'a [u8]) -> Result<BitStringRef<'a>> {
165 BitStringRef::from_bytes(bytes)
166 }
167}
168
169impl<'a> TryFrom<&&'a [u8]> for BitStringRef<'a> {
171 type Error = Error;
172
173 fn try_from(bytes: &&'a [u8]) -> Result<BitStringRef<'a>> {
174 BitStringRef::from_bytes(bytes)
175 }
176}
177
178impl<'a> TryFrom<BitStringRef<'a>> for &'a [u8] {
179 type Error = Error;
180
181 fn try_from(bit_string: BitStringRef<'a>) -> Result<&'a [u8]> {
182 bit_string
183 .as_bytes()
184 .ok_or_else(|| Tag::BitString.value_error())
185 }
186}
187
188impl<'a> FixedTag for BitStringRef<'a> {
189 const TAG: Tag = Tag::BitString;
190}
191
192#[cfg(feature = "arbitrary")]
195impl<'a> arbitrary::Arbitrary<'a> for BitStringRef<'a> {
196 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
197 Self::new(
198 u.int_in_range(0..=Self::MAX_UNUSED_BITS)?,
199 BytesRef::arbitrary(u)?.as_slice(),
200 )
201 .map_err(|_| arbitrary::Error::IncorrectFormat)
202 }
203
204 fn size_hint(depth: usize) -> (usize, Option<usize>) {
205 arbitrary::size_hint::and(u8::size_hint(depth), BytesRef::size_hint(depth))
206 }
207}
208
209#[cfg(feature = "alloc")]
210pub use self::allocating::BitString;
211
212#[cfg(feature = "alloc")]
213mod allocating {
214 use super::*;
215 use crate::referenced::*;
216 use alloc::vec::Vec;
217
218 #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
223 pub struct BitString {
224 unused_bits: u8,
226
227 bit_length: usize,
229
230 inner: Vec<u8>,
232 }
233
234 impl BitString {
235 pub const MAX_UNUSED_BITS: u8 = 7;
237
238 pub fn new(unused_bits: u8, bytes: impl Into<Vec<u8>>) -> Result<Self> {
243 let inner = bytes.into();
244
245 let bit_length = BitStringRef::new(unused_bits, &inner)?.bit_length;
247
248 Ok(BitString {
249 unused_bits,
250 bit_length,
251 inner,
252 })
253 }
254
255 pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
259 Self::new(0, bytes)
260 }
261
262 pub fn unused_bits(&self) -> u8 {
265 self.unused_bits
266 }
267
268 pub fn has_unused_bits(&self) -> bool {
270 self.unused_bits != 0
271 }
272
273 pub fn bit_len(&self) -> usize {
275 self.bit_length
276 }
277
278 pub fn is_empty(&self) -> bool {
280 self.inner.is_empty()
281 }
282
283 pub fn as_bytes(&self) -> Option<&[u8]> {
291 if self.has_unused_bits() {
292 None
293 } else {
294 Some(self.raw_bytes())
295 }
296 }
297
298 pub fn raw_bytes(&self) -> &[u8] {
300 self.inner.as_slice()
301 }
302
303 pub fn bits(&self) -> BitStringIter<'_> {
305 BitStringRef::from(self).bits()
306 }
307 }
308
309 impl_any_conversions!(BitString);
310
311 impl<'a> DecodeValue<'a> for BitString {
312 fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
313 let inner_len = (header.length - Length::ONE)?;
314 let unused_bits = reader.read_byte()?;
315 let inner = reader.read_vec(inner_len)?;
316 Self::new(unused_bits, inner)
317 }
318 }
319
320 impl EncodeValue for BitString {
321 fn value_len(&self) -> Result<Length> {
322 Length::ONE + Length::try_from(self.inner.len())?
323 }
324
325 fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
326 writer.write_byte(self.unused_bits)?;
327 writer.write(&self.inner)
328 }
329 }
330
331 impl FixedTag for BitString {
332 const TAG: Tag = Tag::BitString;
333 }
334
335 impl<'a> From<&'a BitString> for BitStringRef<'a> {
336 fn from(bit_string: &'a BitString) -> BitStringRef<'a> {
337 BitStringRef::new(bit_string.unused_bits, &bit_string.inner)
339 .expect("invalid BIT STRING")
340 }
341 }
342
343 impl ValueOrd for BitString {
344 fn value_cmp(&self, other: &Self) -> Result<Ordering> {
345 match self.unused_bits.cmp(&other.unused_bits) {
346 Ordering::Equal => self.inner.der_cmp(&other.inner),
347 ordering => Ok(ordering),
348 }
349 }
350 }
351
352 #[cfg(feature = "arbitrary")]
355 impl<'a> arbitrary::Arbitrary<'a> for BitString {
356 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
357 Self::new(
358 u.int_in_range(0..=Self::MAX_UNUSED_BITS)?,
359 BytesRef::arbitrary(u)?.as_slice(),
360 )
361 .map_err(|_| arbitrary::Error::IncorrectFormat)
362 }
363
364 fn size_hint(depth: usize) -> (usize, Option<usize>) {
365 arbitrary::size_hint::and(u8::size_hint(depth), BytesRef::size_hint(depth))
366 }
367 }
368
369 impl<'a> RefToOwned<'a> for BitStringRef<'a> {
370 type Owned = BitString;
371 fn ref_to_owned(&self) -> Self::Owned {
372 BitString {
373 unused_bits: self.unused_bits,
374 bit_length: self.bit_length,
375 inner: Vec::from(self.inner.as_slice()),
376 }
377 }
378 }
379
380 impl OwnedToRef for BitString {
381 type Borrowed<'a> = BitStringRef<'a>;
382 fn owned_to_ref(&self) -> Self::Borrowed<'_> {
383 self.into()
384 }
385 }
386}
387
388pub struct BitStringIter<'a> {
390 bit_string: BitStringRef<'a>,
392
393 position: usize,
395}
396
397impl<'a> Iterator for BitStringIter<'a> {
398 type Item = bool;
399
400 #[allow(clippy::integer_arithmetic)]
401 fn next(&mut self) -> Option<bool> {
402 if self.position >= self.bit_string.bit_len() {
403 return None;
404 }
405
406 let byte = self.bit_string.raw_bytes().get(self.position / 8)?;
407 let bit = 1u8 << (7 - (self.position % 8));
408 self.position = self.position.checked_add(1)?;
409 Some(byte & bit != 0)
410 }
411}
412
413impl<'a> ExactSizeIterator for BitStringIter<'a> {
414 fn len(&self) -> usize {
415 self.bit_string.bit_len()
416 }
417}
418
419impl<'a> FusedIterator for BitStringIter<'a> {}
420
421#[cfg(feature = "flagset")]
422impl<T: flagset::Flags> FixedTag for flagset::FlagSet<T> {
423 const TAG: Tag = BitStringRef::TAG;
424}
425
426#[cfg(feature = "flagset")]
427impl<T> ValueOrd for flagset::FlagSet<T>
428where
429 T: flagset::Flags,
430 T::Type: Ord,
431{
432 fn value_cmp(&self, other: &Self) -> Result<Ordering> {
433 Ok(self.bits().cmp(&other.bits()))
434 }
435}
436
437#[cfg(feature = "flagset")]
438#[allow(clippy::integer_arithmetic)]
439impl<'a, T> DecodeValue<'a> for flagset::FlagSet<T>
440where
441 T: flagset::Flags,
442 T::Type: From<bool>,
443 T::Type: core::ops::Shl<usize, Output = T::Type>,
444{
445 fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
446 let position = reader.position();
447 let bits = BitStringRef::decode_value(reader, header)?;
448
449 let mut flags = T::none().bits();
450
451 if bits.bit_len() > core::mem::size_of_val(&flags) * 8 {
452 return Err(Error::new(ErrorKind::Overlength, position));
453 }
454
455 for (i, bit) in bits.bits().enumerate() {
456 flags |= T::Type::from(bit) << i;
457 }
458
459 Ok(Self::new_truncated(flags))
460 }
461}
462
463#[cfg(feature = "flagset")]
464#[allow(clippy::integer_arithmetic)]
465#[inline(always)]
466fn encode_flagset<T>(set: &flagset::FlagSet<T>) -> (usize, [u8; 16])
467where
468 T: flagset::Flags,
469 u128: From<T::Type>,
470{
471 let bits: u128 = set.bits().into();
472 let mut swap = 0u128;
473
474 for i in 0..128 {
475 let on = bits & (1 << i);
476 swap |= on >> i << (128 - i - 1);
477 }
478
479 (bits.leading_zeros() as usize, swap.to_be_bytes())
480}
481
482#[cfg(feature = "flagset")]
483#[allow(clippy::cast_possible_truncation, clippy::integer_arithmetic)]
484impl<T: flagset::Flags> EncodeValue for flagset::FlagSet<T>
485where
486 T::Type: From<bool>,
487 T::Type: core::ops::Shl<usize, Output = T::Type>,
488 u128: From<T::Type>,
489{
490 fn value_len(&self) -> Result<Length> {
491 let (lead, buff) = encode_flagset(self);
492 let buff = &buff[..buff.len() - lead / 8];
493 BitStringRef::new((lead % 8) as u8, buff)?.value_len()
494 }
495
496 fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
497 let (lead, buff) = encode_flagset(self);
498 let buff = &buff[..buff.len() - lead / 8];
499 BitStringRef::new((lead % 8) as u8, buff)?.encode_value(writer)
500 }
501}
502
503#[cfg(test)]
504mod tests {
505 use super::{BitStringRef, Result, Tag};
506 use crate::asn1::AnyRef;
507 use hex_literal::hex;
508
509 fn parse_bitstring(bytes: &[u8]) -> Result<BitStringRef<'_>> {
511 AnyRef::new(Tag::BitString, bytes)?.try_into()
512 }
513
514 #[test]
515 fn decode_empty_bitstring() {
516 let bs = parse_bitstring(&hex!("00")).unwrap();
517 assert_eq!(bs.as_bytes().unwrap(), &[]);
518 }
519
520 #[test]
521 fn decode_non_empty_bitstring() {
522 let bs = parse_bitstring(&hex!("00010203")).unwrap();
523 assert_eq!(bs.as_bytes().unwrap(), &[0x01, 0x02, 0x03]);
524 }
525
526 #[test]
527 fn decode_bitstring_with_unused_bits() {
528 let bs = parse_bitstring(&hex!("066e5dc0")).unwrap();
529 assert_eq!(bs.unused_bits(), 6);
530 assert_eq!(bs.raw_bytes(), &hex!("6e5dc0"));
531
532 let mut bits = bs.bits();
534 assert_eq!(bits.len(), 18);
535
536 for bit in [0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1] {
537 assert_eq!(u8::from(bits.next().unwrap()), bit)
538 }
539
540 assert_eq!(bits.next(), None);
542 assert_eq!(bits.next(), None);
543 }
544
545 #[test]
546 fn reject_unused_bits_in_empty_string() {
547 assert_eq!(
548 parse_bitstring(&[0x03]).err().unwrap().kind(),
549 Tag::BitString.value_error().kind()
550 )
551 }
552}