use crate::data_model::rc::AccessDescription; pub(super) fn encode_access_description_der_for_vcir_ccr_projection( access_description: &AccessDescription, ) -> Result, String> { let oid = encode_oid_der_for_vcir_ccr_projection(&access_description.access_method_oid)?; let uri = encode_tlv_for_vcir_ccr_projection( 0x86, access_description.access_location.as_bytes().to_vec(), ); Ok(encode_sequence_for_vcir_ccr_projection(&[oid, uri])) } fn encode_oid_der_for_vcir_ccr_projection(oid: &str) -> Result, String> { let arcs = oid .split('.') .map(|part| { part.parse::() .map_err(|_| format!("unsupported accessMethod OID: {oid}")) }) .collect::, _>>()?; if arcs.len() < 2 { return Err(format!("unsupported accessMethod OID: {oid}")); } if arcs[0] > 2 || (arcs[0] < 2 && arcs[1] >= 40) { return Err(format!("unsupported accessMethod OID: {oid}")); } let mut body = Vec::new(); body.push((arcs[0] * 40 + arcs[1]) as u8); for arc in &arcs[2..] { encode_base128_for_vcir_ccr_projection(*arc, &mut body); } Ok(encode_tlv_for_vcir_ccr_projection(0x06, body)) } fn encode_base128_for_vcir_ccr_projection(mut value: u64, out: &mut Vec) { let mut tmp = vec![(value & 0x7F) as u8]; value >>= 7; while value > 0 { tmp.push(((value & 0x7F) as u8) | 0x80); value >>= 7; } tmp.reverse(); out.extend_from_slice(&tmp); } fn encode_sequence_for_vcir_ccr_projection(elements: &[Vec]) -> Vec { let total_len: usize = elements.iter().map(Vec::len).sum(); let mut buf = Vec::with_capacity(total_len); for element in elements { buf.extend_from_slice(element); } encode_tlv_for_vcir_ccr_projection(0x30, buf) } fn encode_tlv_for_vcir_ccr_projection(tag: u8, value: Vec) -> Vec { let mut out = Vec::with_capacity(1 + 9 + value.len()); out.push(tag); encode_length_for_vcir_ccr_projection(value.len(), &mut out); out.extend_from_slice(&value); out } fn encode_length_for_vcir_ccr_projection(len: usize, out: &mut Vec) { if len < 0x80 { out.push(len as u8); return; } let mut bytes = Vec::new(); let mut value = len; while value > 0 { bytes.push((value & 0xFF) as u8); value >>= 8; } bytes.reverse(); out.push(0x80 | (bytes.len() as u8)); out.extend_from_slice(&bytes); }