Skip to content

Commit d80c1f4

Browse files
committed
use a smarter algorithm for integer lengths
1 parent 1853d8e commit d80c1f4

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
@@ -717,13 +717,33 @@ macro_rules! impl_asn1_element_for_int {
717717
}
718718

719719
fn data_length(&self) -> Option<usize> {
720-
let mut num_bytes = 1;
721-
let mut v: $t = *self;
722-
#[allow(unused_comparisons)]
723-
while v > 127 || ($signed && v < (-128i64) as $t) {
724-
num_bytes += 1;
725-
v = v.checked_shr(8).unwrap_or(0);
726-
}
720+
let num_bytes = if *self == 0 {
721+
1
722+
} else {
723+
#[allow(unused_comparisons)]
724+
let bits_needed = if $signed && *self < 0 {
725+
// For negative numbers, count significant bits
726+
// including sign bit
727+
<$t>::BITS - self.leading_ones() + 1
728+
} else {
729+
// For positive numbers, count all significant bits
730+
<$t>::BITS - self.leading_zeros()
731+
};
732+
733+
let bytes_needed = bits_needed.div_ceil(8);
734+
735+
// Check if we need an extra byte for ASN.1 encoding
736+
let shift = (bytes_needed - 1) * 8;
737+
let most_significant_byte = (*self >> shift) as u8;
738+
#[allow(unused_comparisons)]
739+
let needs_extra_byte = if $signed && *self < 0 {
740+
false
741+
} else {
742+
most_significant_byte >= 0x80
743+
};
744+
745+
bytes_needed + needs_extra_byte as u32
746+
};
727747
Some(num_bytes)
728748
}
729749
}

0 commit comments

Comments
 (0)