84 lines
2 KiB
Rust
84 lines
2 KiB
Rust
// 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))
|
|
}
|