Revision control
Copy as Markdown
Other Tools
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// Copyright by contributors to this project.
// SPDX-License-Identifier: (Apache-2.0 OR MIT)
use crate::{MlsDecode, MlsEncode, MlsSize, VarInt};
use alloc::vec::Vec;
pub fn mls_encoded_len<T>(iter: impl Iterator<Item = T>) -> usize
where
T: MlsSize,
{
let len = iter.map(|x| x.mls_encoded_len()).sum::<usize>();
let header_length = VarInt::try_from(len).unwrap_or(VarInt(0)).mls_encoded_len();
header_length + len
}
#[cfg(feature = "preallocate")]
pub fn mls_encode<I>(iter: I, writer: &mut Vec<u8>) -> Result<(), crate::Error>
where
I: IntoIterator + Clone,
I::Item: MlsEncode,
{
let len = iter
.clone()
.into_iter()
.map(|x| x.mls_encoded_len())
.sum::<usize>();
let header_length = VarInt::try_from(len)?;
header_length.mls_encode(writer)?;
writer.reserve(len);
iter.into_iter().try_for_each(|x| x.mls_encode(writer))?;
Ok(())
}
#[cfg(not(feature = "preallocate"))]
pub fn mls_encode<I>(iter: I, writer: &mut Vec<u8>) -> Result<(), crate::Error>
where
I: IntoIterator + Clone,
I::Item: MlsEncode,
{
let mut buffer = Vec::new();
iter.into_iter()
.try_for_each(|x| x.mls_encode(&mut buffer))?;
let len = VarInt::try_from(buffer.len())?;
len.mls_encode(writer)?;
writer.extend(buffer);
Ok(())
}
pub fn mls_decode_collection<T, F>(reader: &mut &[u8], item_decode: F) -> Result<T, crate::Error>
where
F: Fn(&mut &[u8]) -> Result<T, crate::Error>,
{
let (mut data, rest) = mls_decode_split_on_collection(reader)?;
let items = item_decode(&mut data)?;
*reader = rest;
Ok(items)
}
pub fn mls_decode_split_on_collection<'b>(
reader: &mut &'b [u8],
) -> Result<(&'b [u8], &'b [u8]), crate::Error> {
let len = VarInt::mls_decode(reader)?.0 as usize;
if len > reader.len() {
return Err(crate::Error::UnexpectedEOF);
}
Ok(reader.split_at(len))
}