pub(crate) const MAJOR_UNSIGNED: u8 = 0;
pub(crate) const MAJOR_NEGATIVE: u8 = 1;
pub(crate) const MAJOR_BYTES: u8 = 2;
pub(crate) const MAJOR_TEXT: u8 = 3;
pub(crate) const MAJOR_ARRAY: u8 = 4;
pub(crate) const MAJOR_MAP: u8 = 5;
pub(crate) const MAJOR_TAG: u8 = 6;
#[cfg(feature = "unstable-anchor")]
pub(crate) const NULL: u8 = 0xf6;
pub(crate) fn write_head(out: &mut Vec<u8>, major: u8, value: u64) {
let major_bits = major << 5;
if let Ok(small) = u8::try_from(value) {
if small < 24 {
out.push(major_bits | small);
} else {
out.push(major_bits | 0x18);
out.push(small);
}
} else if let Ok(v) = u16::try_from(value) {
out.push(major_bits | 0x19);
out.extend_from_slice(&v.to_be_bytes());
} else if let Ok(v) = u32::try_from(value) {
out.push(major_bits | 0x1a);
out.extend_from_slice(&v.to_be_bytes());
} else {
out.push(major_bits | 0x1b);
out.extend_from_slice(&value.to_be_bytes());
}
}
pub(crate) fn write_i64(out: &mut Vec<u8>, value: i64) {
let (major, magnitude) = if value >= 0 {
(MAJOR_UNSIGNED, value.unsigned_abs())
} else {
(MAJOR_NEGATIVE, value.unsigned_abs() - 1)
};
write_head(out, major, magnitude);
}
pub(crate) fn write_text(out: &mut Vec<u8>, text: &str) {
write_head(out, MAJOR_TEXT, text.len() as u64);
out.extend_from_slice(text.as_bytes());
}
pub(crate) fn write_bytes(out: &mut Vec<u8>, bytes: &[u8]) {
write_head(out, MAJOR_BYTES, bytes.len() as u64);
out.extend_from_slice(bytes);
}
pub(crate) fn sig_structure_bytes(protected: &[u8], payload: &[u8]) -> Vec<u8> {
const CONTEXT: &str = "Signature1";
let mut out = Vec::with_capacity(CONTEXT.len() + protected.len() + payload.len() + 8);
write_head(&mut out, MAJOR_ARRAY, 4);
write_text(&mut out, CONTEXT);
write_bytes(&mut out, protected);
write_bytes(&mut out, &[]);
write_bytes(&mut out, payload);
out
}
#[cfg(test)]
#[path = "cbor_tests.rs"]
mod tests;