Skip to content

Commit 2e18b52

Browse files
committed
use a smarter algorithm for integer lengths
1 parent ee47ced commit 2e18b52

File tree

1 file changed

+27
-7
lines changed

1 file changed

+27
-7
lines changed

src/types.rs

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -758,13 +758,33 @@ macro_rules! impl_asn1_element_for_int {
758758
}
759759

760760
fn data_length(&self) -> Option<usize> {
761-
let mut num_bytes = 1;
762-
let mut v: $t = *self;
763-
#[allow(unused_comparisons)]
764-
while v > 127 || ($signed && v < (-128i64) as $t) {
765-
num_bytes += 1;
766-
v = v.checked_shr(8).unwrap_or(0);
767-
}
761+
let num_bytes = if *self == 0 {
762+
1
763+
} else {
764+
#[allow(unused_comparisons)]
765+
let bits_needed = if $signed && *self < 0 {
766+
// For negative numbers, count significant bits
767+
// including sign bit
768+
<$t>::BITS - self.leading_ones() + 1
769+
} else {
770+
// For positive numbers, count all significant bits
771+
<$t>::BITS - self.leading_zeros()
772+
};
773+
774+
let bytes_needed = bits_needed.div_ceil(8) as usize;
775+
776+
// Check if we need an extra byte for ASN.1 encoding
777+
let shift = (bytes_needed - 1) * 8;
778+
let most_significant_byte = (*self >> shift) as u8;
779+
#[allow(unused_comparisons)]
780+
let needs_extra_byte = if $signed && *self < 0 {
781+
false
782+
} else {
783+
most_significant_byte >= 0x80
784+
};
785+
786+
bytes_needed + needs_extra_byte as usize
787+
};
768788
Some(num_bytes)
769789
}
770790
}

0 commit comments

Comments
 (0)