#[cfg(all(not(feature = "std"), feature = "serde"))]
use alloc::string::String;
use smallvec::SmallVec;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Boolean(pub bool);
impl Boolean {
pub const fn new(value: bool) -> Self {
Self(value)
}
pub const fn value(&self) -> bool {
self.0
}
}
impl From<bool> for Boolean {
fn from(value: bool) -> Self {
Self(value)
}
}
impl From<Boolean> for bool {
fn from(value: Boolean) -> Self {
value.0
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Integer {
bytes: SmallVec<[u8; 16]>,
}
impl Integer {
pub fn from_i64(value: i64) -> Self {
let bytes = value.to_be_bytes();
let mut start = 0;
while start < bytes.len() - 1 {
let current = bytes[start];
let next = bytes[start + 1];
if (current == 0x00 && next & 0x80 == 0) || (current == 0xFF && next & 0x80 != 0) {
start += 1;
} else {
break;
}
}
Self {
bytes: SmallVec::from_slice(&bytes[start..]),
}
}
pub fn from_u64(value: u64) -> Self {
let bytes = value.to_be_bytes();
let mut start = 0;
while start < bytes.len() - 1 && bytes[start] == 0 {
start += 1;
}
let mut result_bytes = SmallVec::new();
if bytes[start] & 0x80 != 0 {
result_bytes.push(0x00);
}
result_bytes.extend_from_slice(&bytes[start..]);
Self {
bytes: result_bytes,
}
}
pub fn from_i128(value: i128) -> Self {
let bytes = value.to_be_bytes();
let mut start = 0;
while start < bytes.len() - 1 {
let current = bytes[start];
let next = bytes[start + 1];
if (current == 0x00 && next & 0x80 == 0) || (current == 0xFF && next & 0x80 != 0) {
start += 1;
} else {
break;
}
}
Self {
bytes: SmallVec::from_slice(&bytes[start..]),
}
}
pub fn from_bytes(bytes: &[u8]) -> Self {
Self {
bytes: SmallVec::from_slice(bytes),
}
}
pub fn as_bytes(&self) -> &[u8] {
&self.bytes
}
pub fn as_i64(&self) -> crate::Result<i64> {
if self.bytes.is_empty() {
return Ok(0);
}
if self.bytes.len() > 8 {
return Err(crate::Error::IntegerOverflow { position: 0 });
}
let mut bytes = [if self.bytes[0] & 0x80 != 0 {
0xFF
} else {
0x00
}; 8];
let offset = 8 - self.bytes.len();
bytes[offset..].copy_from_slice(&self.bytes);
Ok(i64::from_be_bytes(bytes))
}
pub fn as_u64(&self) -> crate::Result<u64> {
if self.bytes.is_empty() {
return Ok(0);
}
if self.bytes[0] & 0x80 != 0 {
return Err(crate::Error::IntegerOverflow { position: 0 });
}
if self.bytes.len() > 8 {
return Err(crate::Error::IntegerOverflow { position: 0 });
}
let mut bytes = [0u8; 8];
let offset = 8 - self.bytes.len();
bytes[offset..].copy_from_slice(&self.bytes);
Ok(u64::from_be_bytes(bytes))
}
pub fn as_i8(&self) -> crate::Result<i8> {
let v = self.as_i64()?;
i8::try_from(v).map_err(|_| crate::Error::IntegerOverflow { position: 0 })
}
pub fn as_i16(&self) -> crate::Result<i16> {
let v = self.as_i64()?;
i16::try_from(v).map_err(|_| crate::Error::IntegerOverflow { position: 0 })
}
pub fn as_i32(&self) -> crate::Result<i32> {
let v = self.as_i64()?;
i32::try_from(v).map_err(|_| crate::Error::IntegerOverflow { position: 0 })
}
pub fn as_u8(&self) -> crate::Result<u8> {
let v = self.as_u64()?;
u8::try_from(v).map_err(|_| crate::Error::IntegerOverflow { position: 0 })
}
pub fn as_u16(&self) -> crate::Result<u16> {
let v = self.as_u64()?;
u16::try_from(v).map_err(|_| crate::Error::IntegerOverflow { position: 0 })
}
pub fn as_u32(&self) -> crate::Result<u32> {
let v = self.as_u64()?;
u32::try_from(v).map_err(|_| crate::Error::IntegerOverflow { position: 0 })
}
pub fn as_i128(&self) -> crate::Result<i128> {
if self.bytes.is_empty() {
return Ok(0);
}
if self.bytes.len() > 16 {
return Err(crate::Error::IntegerOverflow { position: 0 });
}
let mut bytes = [if self.bytes[0] & 0x80 != 0 {
0xFF
} else {
0x00
}; 16];
let offset = 16 - self.bytes.len();
bytes[offset..].copy_from_slice(&self.bytes);
Ok(i128::from_be_bytes(bytes))
}
}
impl From<i8> for Integer {
fn from(value: i8) -> Self {
Self::from_i64(value as i64)
}
}
impl From<i16> for Integer {
fn from(value: i16) -> Self {
Self::from_i64(value as i64)
}
}
impl From<i32> for Integer {
fn from(value: i32) -> Self {
Self::from_i64(value as i64)
}
}
impl From<i64> for Integer {
fn from(value: i64) -> Self {
Self::from_i64(value)
}
}
impl From<u8> for Integer {
fn from(value: u8) -> Self {
Self::from_u64(value as u64)
}
}
impl From<u16> for Integer {
fn from(value: u16) -> Self {
Self::from_u64(value as u64)
}
}
impl From<u32> for Integer {
fn from(value: u32) -> Self {
Self::from_u64(value as u64)
}
}
impl From<u64> for Integer {
fn from(value: u64) -> Self {
Self::from_u64(value)
}
}
impl From<i128> for Integer {
fn from(value: i128) -> Self {
Self::from_i128(value)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Enumerated {
bytes: SmallVec<[u8; 4]>,
}
impl Enumerated {
pub fn from_i32(value: i32) -> Self {
let bytes = value.to_be_bytes();
let mut start = 0;
while start < bytes.len() - 1 {
let current = bytes[start];
let next = bytes[start + 1];
if (current == 0x00 && next & 0x80 == 0) || (current == 0xFF && next & 0x80 != 0) {
start += 1;
} else {
break;
}
}
Self {
bytes: SmallVec::from_slice(&bytes[start..]),
}
}
pub fn from_i64(value: i64) -> Self {
let bytes = value.to_be_bytes();
let mut start = 0;
while start < bytes.len() - 1 {
let current = bytes[start];
let next = bytes[start + 1];
if (current == 0x00 && next & 0x80 == 0) || (current == 0xFF && next & 0x80 != 0) {
start += 1;
} else {
break;
}
}
Self {
bytes: SmallVec::from_slice(&bytes[start..]),
}
}
pub fn from_bytes(bytes: &[u8]) -> Self {
Self {
bytes: SmallVec::from_slice(bytes),
}
}
pub fn as_bytes(&self) -> &[u8] {
&self.bytes
}
pub fn as_i64(&self) -> crate::Result<i64> {
if self.bytes.is_empty() {
return Ok(0);
}
if self.bytes.len() > 8 {
return Err(crate::Error::IntegerOverflow { position: 0 });
}
let fill = if self.bytes[0] & 0x80 != 0 {
0xFF
} else {
0x00
};
let mut buf = [fill; 8];
buf[8 - self.bytes.len()..].copy_from_slice(&self.bytes);
Ok(i64::from_be_bytes(buf))
}
pub fn as_i32(&self) -> crate::Result<i32> {
let v = self.as_i64()?;
i32::try_from(v).map_err(|_| crate::Error::IntegerOverflow { position: 0 })
}
pub fn as_u8(&self) -> crate::Result<u8> {
let v = self.as_i64()?;
if !(0..=255).contains(&v) {
return Err(crate::Error::IntegerOverflow { position: 0 });
}
Ok(v as u8)
}
}
impl From<i32> for Enumerated {
fn from(v: i32) -> Self {
Self::from_i32(v)
}
}
impl From<i64> for Enumerated {
fn from(v: i64) -> Self {
Self::from_i64(v)
}
}
impl crate::traits::Decode<'_> for Enumerated {
fn decode(decoder: &mut crate::der::decoder::Decoder) -> crate::Result<Self> {
use crate::tag::TAG_ENUMERATED;
let tag = decoder.read_tag()?;
let expected_tag = crate::Tag::universal(TAG_ENUMERATED);
if tag != expected_tag {
return Err(crate::Error::UnexpectedTag {
position: decoder.position(),
expected: expected_tag,
actual: tag,
});
}
let length = decoder.read_length()?;
let len = length.definite()?;
if len == 0 {
return Err(crate::Error::InvalidEncoding {
position: decoder.position(),
tag,
#[cfg(feature = "std")]
reason: "ENUMERATED length cannot be 0".to_string(),
#[cfg(not(feature = "std"))]
reason: "ENUMERATED length cannot be 0",
});
}
let bytes = decoder.read_bytes(len)?;
if (decoder.encoding() == crate::Encoding::Der
|| decoder.encoding() == crate::Encoding::Cer)
&& bytes.len() > 1
{
let first = bytes[0];
let second = bytes[1];
if (first == 0x00 && (second & 0x80) == 0) || (first == 0xFF && (second & 0x80) != 0) {
#[cfg(feature = "std")]
return Err(if decoder.encoding() == crate::Encoding::Der {
crate::Error::DerViolation {
position: decoder.position(),
reason: "DER requires minimal ENUMERATED encoding".to_string(),
}
} else {
crate::Error::CerViolation {
position: decoder.position(),
reason: "CER requires minimal ENUMERATED encoding".to_string(),
}
});
#[cfg(not(feature = "std"))]
return Err(if decoder.encoding() == crate::Encoding::Der {
crate::Error::DerViolation {
position: decoder.position(),
reason: "DER requires minimal ENUMERATED encoding",
}
} else {
crate::Error::CerViolation {
position: decoder.position(),
reason: "CER requires minimal ENUMERATED encoding",
}
});
}
}
Ok(Enumerated::from_bytes(bytes))
}
}
impl crate::traits::Encode for Enumerated {
fn encode(&self, encoder: &mut crate::der::encoder::Encoder) -> crate::Result<()> {
use crate::tag::TAG_ENUMERATED;
let tag = crate::Tag::universal(TAG_ENUMERATED);
encoder.write_tag(tag)?;
encoder.write_length(self.bytes.len())?;
encoder.write_bytes(&self.bytes);
Ok(())
}
fn encoded_len(&self) -> crate::Result<usize> {
let tag_len = 1;
let length = self.bytes.len();
let length_len = crate::Length::Definite(length).encoded_len()?;
Ok(tag_len + length_len + length)
}
}
impl crate::traits::Tagged for Enumerated {
fn tag() -> crate::Tag {
crate::Tag::universal(crate::tag::TAG_ENUMERATED)
}
}
#[cfg(feature = "serde")]
impl serde::Serialize for Enumerated {
fn serialize<S: serde::Serializer>(&self, s: S) -> core::result::Result<S::Ok, S::Error> {
match self.as_i64() {
Ok(v) => s.serialize_i64(v),
Err(_) => s.serialize_bytes(&self.bytes),
}
}
}
#[cfg(feature = "serde")]
impl<'de> serde::Deserialize<'de> for Enumerated {
fn deserialize<D: serde::Deserializer<'de>>(d: D) -> core::result::Result<Self, D::Error> {
let v = <i64 as serde::Deserialize<'de>>::deserialize(d)?;
Ok(Enumerated::from_i64(v))
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Null;
impl crate::traits::Decode<'_> for Boolean {
fn decode(decoder: &mut crate::der::decoder::Decoder) -> crate::Result<Self> {
use crate::tag::TAG_BOOLEAN;
let tag = decoder.read_tag()?;
let expected_tag = crate::Tag::universal(TAG_BOOLEAN);
if tag != expected_tag {
return Err(crate::Error::UnexpectedTag {
position: decoder.position(),
expected: expected_tag,
actual: tag,
});
}
let length = decoder.read_length()?;
if length.definite()? != 1 {
return Err(crate::Error::InvalidEncoding {
position: decoder.position(),
tag,
#[cfg(feature = "std")]
reason: "Boolean length must be 1".to_string(),
#[cfg(not(feature = "std"))]
reason: "Boolean length must be 1",
});
}
let bytes = decoder.remaining();
if bytes.is_empty() {
return Err(crate::Error::UnexpectedEof {
position: decoder.position(),
});
}
let bytes = decoder.read_bytes(1)?;
let value_byte = bytes[0];
if (decoder.encoding() == crate::Encoding::Der
|| decoder.encoding() == crate::Encoding::Cer)
&& value_byte != 0x00
&& value_byte != 0xFF
{
#[cfg(feature = "std")]
return Err(if decoder.encoding() == crate::Encoding::Der {
crate::Error::DerViolation {
position: decoder.position(),
reason: format!(
"DER requires BOOLEAN to be 0x00 or 0xFF, got 0x{:02X}",
value_byte
),
}
} else {
crate::Error::CerViolation {
position: decoder.position(),
reason: format!(
"CER requires BOOLEAN to be 0x00 or 0xFF, got 0x{:02X}",
value_byte
),
}
});
#[cfg(not(feature = "std"))]
return Err(if decoder.encoding() == crate::Encoding::Der {
crate::Error::DerViolation {
position: decoder.position(),
reason: "DER requires BOOLEAN to be 0x00 or 0xFF",
}
} else {
crate::Error::CerViolation {
position: decoder.position(),
reason: "CER requires BOOLEAN to be 0x00 or 0xFF",
}
});
}
Ok(Boolean(value_byte != 0))
}
}
impl crate::traits::Encode for Boolean {
fn encode(&self, encoder: &mut crate::der::encoder::Encoder) -> crate::Result<()> {
use crate::tag::TAG_BOOLEAN;
let tag = crate::Tag::universal(TAG_BOOLEAN);
encoder.write_tag(tag)?;
encoder.write_length(1)?;
encoder.write_bytes(&[if self.0 { 0xFF } else { 0x00 }]);
Ok(())
}
fn encoded_len(&self) -> crate::Result<usize> {
Ok(3)
}
}
impl crate::traits::Decode<'_> for Integer {
fn decode(decoder: &mut crate::der::decoder::Decoder) -> crate::Result<Self> {
use crate::tag::TAG_INTEGER;
let tag = decoder.read_tag()?;
let expected_tag = crate::Tag::universal(TAG_INTEGER);
if tag != expected_tag {
return Err(crate::Error::UnexpectedTag {
position: decoder.position(),
expected: expected_tag,
actual: tag,
});
}
let length = decoder.read_length()?;
let len = length.definite()?;
if len == 0 {
return Err(crate::Error::InvalidEncoding {
position: decoder.position(),
tag,
#[cfg(feature = "std")]
reason: "Integer length cannot be 0".to_string(),
#[cfg(not(feature = "std"))]
reason: "Integer length cannot be 0",
});
}
let bytes = decoder.read_bytes(len)?;
if (decoder.encoding() == crate::Encoding::Der
|| decoder.encoding() == crate::Encoding::Cer)
&& bytes.len() > 1
{
let first = bytes[0];
let second = bytes[1];
if first == 0x00 && (second & 0x80) == 0 {
#[cfg(feature = "std")]
return Err(if decoder.encoding() == crate::Encoding::Der {
crate::Error::DerViolation {
position: decoder.position(),
reason: "DER requires minimal INTEGER encoding (unnecessary leading 0x00)"
.to_string(),
}
} else {
crate::Error::CerViolation {
position: decoder.position(),
reason: "CER requires minimal INTEGER encoding (unnecessary leading 0x00)"
.to_string(),
}
});
#[cfg(not(feature = "std"))]
return Err(if decoder.encoding() == crate::Encoding::Der {
crate::Error::DerViolation {
position: decoder.position(),
reason: "DER requires minimal INTEGER encoding",
}
} else {
crate::Error::CerViolation {
position: decoder.position(),
reason: "CER requires minimal INTEGER encoding",
}
});
}
if first == 0xFF && (second & 0x80) != 0 {
#[cfg(feature = "std")]
return Err(if decoder.encoding() == crate::Encoding::Der {
crate::Error::DerViolation {
position: decoder.position(),
reason: "DER requires minimal INTEGER encoding (unnecessary leading 0xFF)"
.to_string(),
}
} else {
crate::Error::CerViolation {
position: decoder.position(),
reason: "CER requires minimal INTEGER encoding (unnecessary leading 0xFF)"
.to_string(),
}
});
#[cfg(not(feature = "std"))]
return Err(if decoder.encoding() == crate::Encoding::Der {
crate::Error::DerViolation {
position: decoder.position(),
reason: "DER requires minimal INTEGER encoding",
}
} else {
crate::Error::CerViolation {
position: decoder.position(),
reason: "CER requires minimal INTEGER encoding",
}
});
}
}
Ok(Integer::from_bytes(bytes))
}
}
impl crate::traits::Encode for Integer {
fn encode(&self, encoder: &mut crate::der::encoder::Encoder) -> crate::Result<()> {
use crate::tag::TAG_INTEGER;
let tag = crate::Tag::universal(TAG_INTEGER);
encoder.write_tag(tag)?;
encoder.write_length(self.bytes.len())?;
encoder.write_bytes(&self.bytes);
Ok(())
}
fn encoded_len(&self) -> crate::Result<usize> {
let tag_len = 1; let length = self.bytes.len();
let length_len = crate::Length::Definite(length).encoded_len()?;
Ok(tag_len + length_len + length)
}
}
impl crate::traits::Decode<'_> for Null {
fn decode(decoder: &mut crate::der::decoder::Decoder) -> crate::Result<Self> {
use crate::tag::TAG_NULL;
let tag = decoder.read_tag()?;
let expected_tag = crate::Tag::universal(TAG_NULL);
if tag != expected_tag {
return Err(crate::Error::UnexpectedTag {
position: decoder.position(),
expected: expected_tag,
actual: tag,
});
}
let length = decoder.read_length()?;
if length.definite()? != 0 {
return Err(crate::Error::InvalidEncoding {
position: decoder.position(),
tag,
#[cfg(feature = "std")]
reason: "NULL length must be 0".to_string(),
#[cfg(not(feature = "std"))]
reason: "NULL length must be 0",
});
}
Ok(Null)
}
}
impl crate::traits::Encode for Null {
fn encode(&self, encoder: &mut crate::der::encoder::Encoder) -> crate::Result<()> {
use crate::tag::TAG_NULL;
let tag = crate::Tag::universal(TAG_NULL);
encoder.write_tag(tag)?;
encoder.write_length(0)?;
Ok(())
}
fn encoded_len(&self) -> crate::Result<usize> {
Ok(2)
}
}
impl crate::traits::Tagged for Boolean {
fn tag() -> crate::Tag {
crate::Tag::universal(crate::tag::TAG_BOOLEAN)
}
}
impl crate::traits::Tagged for Integer {
fn tag() -> crate::Tag {
crate::Tag::universal(crate::tag::TAG_INTEGER)
}
}
impl crate::traits::Tagged for Null {
fn tag() -> crate::Tag {
crate::Tag::universal(crate::tag::TAG_NULL)
}
}
fn f64_to_real_parts(bits: u64) -> (bool, u64, i64) {
let sign = (bits >> 63) != 0;
let biased_exp = ((bits >> 52) & 0x7FF) as i32;
let frac_bits = bits & 0x000F_FFFF_FFFF_FFFF;
let (mut mantissa, mut exponent): (u64, i64) = if biased_exp == 0 {
(frac_bits, -1074)
} else {
(frac_bits | (1u64 << 52), i64::from(biased_exp) - 1023 - 52)
};
if mantissa != 0 {
let trailing = mantissa.trailing_zeros();
mantissa >>= trailing;
exponent += i64::from(trailing);
}
(sign, mantissa, exponent)
}
fn real_encode_exp(v: i64) -> (usize, [u8; 8]) {
let buf = v.to_be_bytes();
let mut start = 0usize;
while start < 7 {
let curr = buf[start];
let next = buf[start + 1];
if (curr == 0x00 && next & 0x80 == 0) || (curr == 0xFF && next & 0x80 != 0) {
start += 1;
} else {
break;
}
}
(8 - start, buf)
}
fn real_encode_mantissa(v: u64) -> (usize, [u8; 8]) {
if v == 0 {
return (1, [0u8; 8]);
}
let buf = v.to_be_bytes();
let start = buf.iter().position(|&b| b != 0).unwrap_or(7);
(8 - start, buf)
}
fn real_decode_exp(bytes: &[u8]) -> i64 {
let fill = if !bytes.is_empty() && bytes[0] & 0x80 != 0 {
0xFF
} else {
0x00
};
let mut buf = [fill; 8];
let offset = 8 - bytes.len().min(8);
buf[offset..].copy_from_slice(&bytes[..bytes.len().min(8)]);
i64::from_be_bytes(buf)
}
fn real_decode_mantissa(bytes: &[u8]) -> crate::Result<u64> {
if bytes.len() > 8 {
return Err(crate::Error::IntegerOverflow { position: 0 });
}
let mut buf = [0u8; 8];
buf[8 - bytes.len()..].copy_from_slice(bytes);
Ok(u64::from_be_bytes(buf))
}
fn f64_from_binary_real(sign: bool, mantissa: u64, exponent: i64) -> f64 {
if mantissa == 0 {
return if sign { -0.0 } else { 0.0 };
}
let msb = 63u32 - mantissa.leading_zeros();
let true_exp = exponent + msb as i64;
let sign_bit: u64 = if sign { 1 << 63 } else { 0 };
let bits = if true_exp > 1023 {
sign_bit | 0x7FF0_0000_0000_0000
} else if true_exp >= -1022 {
let biased = (true_exp + 1023) as u64;
let frac = if msb <= 52 {
(mantissa & ((1u64 << msb) - 1)) << (52 - msb)
} else {
(mantissa >> (msb - 52)) & 0x000F_FFFF_FFFF_FFFF
};
sign_bit | (biased << 52) | frac
} else if true_exp >= -1074 {
let shift = exponent + 1074;
let frac = if shift >= 0 {
let s = shift as u32;
if s < 64 {
mantissa.checked_shl(s).unwrap_or(u64::MAX)
} else {
0
}
} else {
let s = (-shift) as u32;
if s < 64 {
mantissa >> s
} else {
0
}
};
sign_bit | (frac & 0x000F_FFFF_FFFF_FFFF)
} else {
sign_bit
};
f64::from_bits(bits)
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Real(pub f64);
impl Real {
pub fn new(value: f64) -> Self {
Real(value)
}
pub fn value(&self) -> f64 {
self.0
}
}
impl From<f64> for Real {
fn from(value: f64) -> Self {
Real(value)
}
}
impl From<Real> for f64 {
fn from(real: Real) -> Self {
real.0
}
}
impl crate::traits::Encode for Real {
fn encode(&self, encoder: &mut crate::der::encoder::Encoder) -> crate::Result<()> {
use crate::tag::TAG_REAL;
let tag = crate::Tag::universal(TAG_REAL);
encoder.write_tag(tag)?;
if self.0 == 0.0 {
encoder.write_length(0)?;
return Ok(());
}
if self.0.is_infinite() {
encoder.write_length(1)?;
encoder.write_bytes(&[if self.0.is_sign_positive() {
0x40
} else {
0x41
}]);
return Ok(());
}
if self.0.is_nan() {
encoder.write_length(1)?;
encoder.write_bytes(&[0x42]);
return Ok(());
}
let (sign, mantissa, exponent) = f64_to_real_parts(self.0.to_bits());
let (exp_len, exp_buf) = real_encode_exp(exponent);
let (mant_len, mant_buf) = real_encode_mantissa(mantissa);
debug_assert!(exp_len <= 3);
let info = 0x80u8 | (u8::from(sign) << 6) | (exp_len as u8 - 1);
encoder.write_length(1 + exp_len + mant_len)?;
encoder.write_bytes(&[info]);
encoder.write_bytes(&exp_buf[8 - exp_len..]);
encoder.write_bytes(&mant_buf[8 - mant_len..]);
Ok(())
}
fn encoded_len(&self) -> crate::Result<usize> {
let tag_len = 1;
let content_len = if self.0 == 0.0 {
0
} else if self.0.is_infinite() || self.0.is_nan() {
1
} else {
let (_, mantissa, exponent) = f64_to_real_parts(self.0.to_bits());
let (exp_len, _) = real_encode_exp(exponent);
let (mant_len, _) = real_encode_mantissa(mantissa);
1 + exp_len + mant_len };
let length_len = crate::Length::Definite(content_len).encoded_len()?;
Ok(tag_len + length_len + content_len)
}
}
impl crate::traits::Decode<'_> for Real {
fn decode(decoder: &mut crate::der::decoder::Decoder) -> crate::Result<Self> {
use crate::tag::TAG_REAL;
let tag = decoder.read_tag()?;
let expected_tag = crate::Tag::universal(TAG_REAL);
if tag != expected_tag {
return Err(crate::Error::UnexpectedTag {
position: decoder.position(),
expected: expected_tag,
actual: tag,
});
}
let length = decoder.read_length()?;
let n = length.definite()?;
if n == 0 {
return Ok(Real(0.0));
}
let bytes = decoder.read_bytes(n)?;
let info = bytes[0];
if n == 1 {
return match info {
0x40 => Ok(Real(f64::INFINITY)),
0x41 => Ok(Real(f64::NEG_INFINITY)),
0x42 => Ok(Real(f64::NAN)),
_ => Err(crate::Error::InvalidEncoding {
position: decoder.position(),
tag: expected_tag,
reason: "Invalid REAL special value".into(),
}),
};
}
if info & 0x80 != 0 {
let sign = (info >> 6) & 1 != 0;
let base: u8 = match (info >> 4) & 0x03 {
0 => 2,
1 => 8,
2 => 16,
_ => {
return Err(crate::Error::InvalidEncoding {
position: decoder.position(),
tag: expected_tag,
reason: "Reserved base value in binary REAL".into(),
})
}
};
let scaling = (info >> 2) & 0x03;
let (exp_len, rest) = match info & 0x03 {
0 => (1usize, &bytes[1..]),
1 => (2, &bytes[1..]),
2 => (3, &bytes[1..]),
_ => {
if bytes.len() < 2 {
return Err(crate::Error::UnexpectedEof {
position: decoder.position(),
});
}
(bytes[1] as usize, &bytes[2..])
}
};
if rest.len() < exp_len || exp_len == 0 {
return Err(crate::Error::UnexpectedEof {
position: decoder.position(),
});
}
let (exp_bytes, mant_bytes) = rest.split_at(exp_len);
let exponent = real_decode_exp(exp_bytes);
let mantissa =
real_decode_mantissa(mant_bytes).map_err(|_| crate::Error::InvalidEncoding {
position: decoder.position(),
tag: expected_tag,
reason: "REAL mantissa too large for u64".into(),
})?;
let mantissa = mantissa << u32::from(scaling);
let base2_exp = match base {
2 => exponent,
8 => exponent.saturating_mul(3),
16 => exponent.saturating_mul(4),
_ => unreachable!(),
};
Ok(Real(f64_from_binary_real(sign, mantissa, base2_exp)))
} else if info & 0xC0 == 0 {
let nr_form = info & 0x3F;
if nr_form == 0 || nr_form > 3 {
return Err(crate::Error::InvalidEncoding {
position: decoder.position(),
tag: expected_tag,
reason: "Unknown decimal REAL NR form".into(),
});
}
let ascii = &bytes[1..];
let s = core::str::from_utf8(ascii).map_err(|_| crate::Error::InvalidEncoding {
position: decoder.position(),
tag: expected_tag,
reason: "Non-ASCII bytes in decimal REAL".into(),
})?;
let s = s.trim();
if s.is_empty() {
return Err(crate::Error::InvalidEncoding {
position: decoder.position(),
tag: expected_tag,
reason: "Empty decimal REAL string".into(),
});
}
s.parse::<f64>()
.map(Real)
.map_err(|_| crate::Error::InvalidEncoding {
position: decoder.position(),
tag: expected_tag,
reason: "Malformed decimal REAL string".into(),
})
} else {
Err(crate::Error::InvalidEncoding {
position: decoder.position(),
tag: expected_tag,
reason: "Invalid REAL encoding".into(),
})
}
}
}
impl crate::traits::Tagged for Real {
fn tag() -> crate::Tag {
crate::Tag::universal(crate::tag::TAG_REAL)
}
}
#[cfg(feature = "serde")]
impl serde::Serialize for Boolean {
fn serialize<S: serde::Serializer>(&self, s: S) -> core::result::Result<S::Ok, S::Error> {
s.serialize_bool(self.0)
}
}
#[cfg(feature = "serde")]
impl<'de> serde::Deserialize<'de> for Boolean {
fn deserialize<D: serde::Deserializer<'de>>(d: D) -> core::result::Result<Self, D::Error> {
let v = <bool as serde::Deserialize<'de>>::deserialize(d)?;
Ok(Boolean(v))
}
}
#[cfg(feature = "serde")]
impl serde::Serialize for Integer {
fn serialize<S: serde::Serializer>(&self, s: S) -> core::result::Result<S::Ok, S::Error> {
let hex = crate::serde_impl::bytes_to_hex(self.as_bytes());
s.serialize_str(&hex)
}
}
#[cfg(feature = "serde")]
impl<'de> serde::Deserialize<'de> for Integer {
fn deserialize<D: serde::Deserializer<'de>>(d: D) -> core::result::Result<Self, D::Error> {
let s = <String as serde::Deserialize<'de>>::deserialize(d)?;
let bytes = crate::serde_impl::hex_to_bytes::<D::Error>(&s)?;
Ok(Integer::from_bytes(&bytes))
}
}
#[cfg(feature = "serde")]
impl serde::Serialize for Null {
fn serialize<S: serde::Serializer>(&self, s: S) -> core::result::Result<S::Ok, S::Error> {
s.serialize_unit()
}
}
#[cfg(feature = "serde")]
impl<'de> serde::Deserialize<'de> for Null {
fn deserialize<D: serde::Deserializer<'de>>(d: D) -> core::result::Result<Self, D::Error> {
struct NullVisitor;
impl<'de> serde::de::Visitor<'de> for NullVisitor {
type Value = Null;
fn expecting(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
write!(f, "null")
}
fn visit_unit<E: serde::de::Error>(self) -> core::result::Result<Null, E> {
Ok(Null)
}
fn visit_none<E: serde::de::Error>(self) -> core::result::Result<Null, E> {
Ok(Null)
}
}
d.deserialize_unit(NullVisitor)
}
}
#[cfg(feature = "serde")]
impl serde::Serialize for Real {
fn serialize<S: serde::Serializer>(&self, s: S) -> core::result::Result<S::Ok, S::Error> {
s.serialize_f64(self.0)
}
}
#[cfg(feature = "serde")]
impl<'de> serde::Deserialize<'de> for Real {
fn deserialize<D: serde::Deserializer<'de>>(d: D) -> core::result::Result<Self, D::Error> {
let v = <f64 as serde::Deserialize<'de>>::deserialize(d)?;
Ok(Real(v))
}
}