mlt_core/frames/v01/stream/
physical.rs1use integer_encoding::VarInt as _;
2
3use crate::MltError::ParsingStreamType;
4use crate::codecs::bytes::{encode_u32s_to_bytes, encode_u64s_to_bytes};
5use crate::codecs::fastpfor::encode_fastpfor;
6use crate::utils::parse_u8;
7use crate::v01::{
8 DictionaryType, EncodedStreamData, LengthType, OffsetType, PhysicalEncoding, StreamType,
9};
10use crate::{MltError, MltRefResult, MltResult};
11
12impl StreamType {
13 pub fn from_bytes(input: &'_ [u8]) -> MltRefResult<'_, Self> {
14 let (input, value) = parse_u8(input)?;
15 let pt = Self::from_u8(value).ok_or(ParsingStreamType(value))?;
16 Ok((input, pt))
17 }
18
19 fn from_u8(value: u8) -> Option<Self> {
20 let high4 = value >> 4;
21 let low4 = value & 0x0F;
22 Some(match high4 {
23 #[cfg(fuzzing)]
24 0 if low4 == 0 => StreamType::Present,
26 #[cfg(not(fuzzing))]
27 0 => StreamType::Present,
28 1 => StreamType::Data(DictionaryType::try_from(low4).ok()?),
29 2 => StreamType::Offset(OffsetType::try_from(low4).ok()?),
30 3 => StreamType::Length(LengthType::try_from(low4).ok()?),
31 _ => return None,
32 })
33 }
34 #[must_use]
35 pub fn as_u8(self) -> u8 {
36 let proto_high4 = match self {
37 StreamType::Present => 0,
38 StreamType::Data(_) => 1,
39 StreamType::Offset(_) => 2,
40 StreamType::Length(_) => 3,
41 };
42 let high4 = proto_high4 << 4;
43 let low4 = match self {
44 StreamType::Present => 0,
45 StreamType::Data(i) => i as u8,
46 StreamType::Offset(i) => i as u8,
47 StreamType::Length(i) => i as u8,
48 };
49 debug_assert!(low4 <= 0x0F, "secondary types should not exceed 4 bit");
50 high4 | low4
51 }
52}
53
54impl PhysicalEncoding {
55 pub fn parse(value: u8) -> MltResult<Self> {
56 Self::try_from(value).or(Err(MltError::ParsingPhysicalEncoding(value)))
57 }
58}
59
60#[derive(Debug, Clone, Copy, PartialEq, Eq, strum::EnumIter)]
61#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
62#[cfg_attr(all(not(test), feature = "arbitrary"), derive(arbitrary::Arbitrary))]
63pub enum PhysicalEncoder {
64 None,
65 VarInt,
68 FastPFOR,
72}
73
74impl PhysicalEncoder {
75 pub fn encode_u32s(
77 self,
78 values: Vec<u32>,
79 ) -> Result<(EncodedStreamData, PhysicalEncoding), MltError> {
80 match self {
81 Self::None => {
82 let data = encode_u32s_to_bytes(&values);
83 let stream = EncodedStreamData::Encoded(data);
84 Ok((stream, PhysicalEncoding::None))
85 }
86 Self::VarInt => {
87 let mut data = Vec::new();
88 for v in values {
89 data.extend_from_slice(&u64::from(v).encode_var_vec());
90 }
91 let stream = EncodedStreamData::VarInt(data);
92 Ok((stream, PhysicalEncoding::VarInt))
93 }
94 Self::FastPFOR => {
95 let data = encode_fastpfor(&values)?;
96 let stream = EncodedStreamData::Encoded(data);
97 Ok((stream, PhysicalEncoding::FastPFOR))
98 }
99 }
100 }
101
102 pub fn encode_u64s(
104 self,
105 values: Vec<u64>,
106 ) -> Result<(EncodedStreamData, PhysicalEncoding), MltError> {
107 match self {
108 Self::None => {
109 let data = encode_u64s_to_bytes(&values);
110 let stream = EncodedStreamData::Encoded(data);
111 Ok((stream, PhysicalEncoding::None))
112 }
113 Self::VarInt => {
114 let mut data = Vec::new();
115 for v in values {
116 data.extend_from_slice(&v.encode_var_vec());
117 }
118 let stream = EncodedStreamData::VarInt(data);
119 Ok((stream, PhysicalEncoding::VarInt))
120 }
121 Self::FastPFOR => Err(MltError::UnsupportedPhysicalEncoding("FastPFOR on u64")),
122 }
123 }
124}