lilliput_core/encoder/
bytes.rs1use crate::{
2 config::PackingMode, error::Result, header::BytesHeader, io::Write,
3 num::WithPackedBeBytes as _, value::BytesValue,
4};
5
6use super::Encoder;
7
8impl<W> Encoder<W>
9where
10 W: Write,
11{
12 pub fn encode_bytes(&mut self, value: &[u8]) -> Result<()> {
16 self.encode_bytes_header(&BytesHeader::for_len(value.len()))?;
17
18 self.push_bytes(value)?;
20
21 Ok(())
22 }
23
24 pub fn encode_bytes_value(&mut self, value: &BytesValue) -> Result<()> {
26 self.encode_bytes(&value.0)
27 }
28
29 pub fn encode_bytes_header(&mut self, header: &BytesHeader) -> Result<()> {
33 let len = header.len();
34
35 let packing_mode = self.config.lengths.packing.min(PackingMode::Native);
37
38 len.with_packed_be_bytes(packing_mode, |bytes| {
39 let width = bytes.len();
40
41 debug_assert!(width.count_ones() == 1, "must be a power of two");
42
43 let mut byte = BytesHeader::TYPE_BITS;
44
45 const EXPONENT: [u8; 8] = [0, 1, 2, 2, 3, 3, 3, 3];
46 let exponent = EXPONENT[width - 1];
47
48 byte |= exponent & BytesHeader::LEN_WIDTH_EXPONENT_BITS;
49
50 #[cfg(feature = "tracing")]
51 tracing::debug!(
52 byte = crate::binary::fmt_byte(byte),
53 bytes = format!("{:b}", crate::binary::BytesSlice(bytes)),
54 len = len
55 );
56
57 self.push_byte(byte)?;
59
60 self.push_bytes(bytes)
62 })
63 }
64
65 pub fn header_for_bytes_len(&self, len: usize) -> BytesHeader {
67 BytesHeader::for_len(len)
68 }
69}