use super::tag;
use alloc::vec::Vec;
fn encode_length(len: usize, out: &mut Vec<u8>) {
if len < 0x80 {
out.push(len as u8);
return;
}
let mut bytes = [0u8; core::mem::size_of::<usize>()];
let mut n = 0;
let mut l = len;
while l > 0 {
bytes[n] = (l & 0xff) as u8;
l >>= 8;
n += 1;
}
out.push(0x80 | n as u8);
for i in (0..n).rev() {
out.push(bytes[i]);
}
}
pub fn encode_tlv(tag: u8, content: &[u8]) -> Vec<u8> {
let mut out = Vec::with_capacity(content.len() + 4);
out.push(tag);
encode_length(content.len(), &mut out);
out.extend_from_slice(content);
out
}
pub fn encode_sequence(content: &[u8]) -> Vec<u8> {
encode_tlv(tag::SEQUENCE, content)
}
pub fn encode_integer(unsigned_be: &[u8]) -> Vec<u8> {
if unsigned_be.is_empty() {
return encode_tlv(tag::INTEGER, &[0u8]);
}
let mut start = 0;
while start + 1 < unsigned_be.len() && unsigned_be[start] == 0 {
start += 1;
}
let trimmed = &unsigned_be[start..];
let mut content = Vec::with_capacity(trimmed.len() + 1);
if trimmed[0] & 0x80 != 0 {
content.push(0x00);
}
content.extend_from_slice(trimmed);
encode_tlv(tag::INTEGER, &content)
}
pub fn encode_octet_string(content: &[u8]) -> Vec<u8> {
encode_tlv(tag::OCTET_STRING, content)
}
pub fn encode_bit_string(bits: &[u8]) -> Vec<u8> {
let mut content = Vec::with_capacity(bits.len() + 1);
content.push(0x00); content.extend_from_slice(bits);
encode_tlv(tag::BIT_STRING, &content)
}
pub fn encode_oid(body: &[u8]) -> Vec<u8> {
encode_tlv(tag::OID, body)
}
pub fn encode_null() -> Vec<u8> {
encode_tlv(tag::NULL, &[])
}
pub fn encode_boolean(value: bool) -> Vec<u8> {
encode_tlv(tag::BOOLEAN, &[if value { 0xff } else { 0x00 }])
}
pub fn encode_string(tag: u8, s: &str) -> Vec<u8> {
encode_tlv(tag, s.as_bytes())
}
pub fn encode_context(n: u8, content: &[u8]) -> Vec<u8> {
encode_tlv(tag::context(n), content)
}