1use std::fmt::Debug;
4use std::io::Read;
5
6use byteorder::{BigEndian, ReadBytesExt};
7
8use crate::{
9 Error,
10 tables::{TableBEntry, TableDEntry, Tables},
11};
12
13#[derive(Hash, Copy, Clone, Eq, PartialEq)]
15#[cfg_attr(feature = "serde", derive(serde::Serialize))]
16pub struct Descriptor {
17 pub f: u8,
18 pub x: u8,
19 pub y: u8,
20}
21
22impl Descriptor {
23 pub fn read<R: Read>(reader: &mut R) -> Result<Self, Error> {
24 let val = reader.read_u16::<BigEndian>()?;
25 Ok(Descriptor {
26 f: (val >> 14) as u8,
27 x: ((val >> 8) & 0x3f) as u8,
28 y: (val & 0xff) as u8,
29 })
30 }
31}
32
33impl Debug for Descriptor {
34 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
35 write!(f, "Descriptor {0:1}{1:02}{2:03}", self.f, self.x, self.y)
36 }
37}
38
39impl Descriptor {
40 pub fn xy(&self) -> XY {
41 XY {
42 x: self.x,
43 y: self.y,
44 }
45 }
46}
47
48#[derive(Hash, Debug, Clone, Copy, Eq, PartialEq)]
50pub struct XY {
51 pub x: u8,
52 pub y: u8,
53}
54
55#[derive(Debug)]
57pub enum ResolvedDescriptor<'a> {
58 Data(&'a TableBEntry),
59 Replication {
60 y: u8,
61 delayed_bits: u8,
62 descriptors: Vec<ResolvedDescriptor<'a>>,
63 },
64 Operator(XY),
65 Sequence(&'a TableDEntry, Vec<ResolvedDescriptor<'a>>),
66}
67
68impl<'a> ResolvedDescriptor<'a> {
69 pub fn from_descriptor(desc: &Descriptor, tables: &Tables) -> Result<Self, Error> {
70 Ok(match desc.f {
71 0 => {
72 let Some(b) = tables.table_b.get(&desc.xy()) else {
73 return Err(Error::Table(format!(
74 "Table B entry not found for xy: {:?}",
75 desc.xy()
76 )));
77 };
78 ResolvedDescriptor::Data(b)
79 }
80 1 => unreachable!(),
81 2 => ResolvedDescriptor::Operator(desc.xy()),
82 3 => {
83 let Some(d) = tables.table_d.get(&desc.xy()) else {
84 return Err(Error::Table(format!(
85 "Table D entry not found for xy: {:?}",
86 desc.xy()
87 )));
88 };
89 let resolved_elements = resolve_descriptors(tables, d.elements)?;
90 ResolvedDescriptor::Sequence(d, resolved_elements)
91 }
92 _ => {
93 return Err(Error::Table(format!(
94 "Table B entry not found for xy: {:?}",
95 desc.xy()
96 )));
97 }
98 })
99 }
100}
101
102pub(crate) fn resolve_descriptors<'a>(
103 tables: &Tables,
104 descriptors: &'a [Descriptor],
105) -> Result<Vec<ResolvedDescriptor<'a>>, Error> {
106 let mut resolved = vec![];
107 let mut pos = 0;
108 while pos < descriptors.len() {
109 match &descriptors[pos] {
110 &Descriptor { f: 1, x, y } => {
111 let delayed_bits = match y {
112 0 => {
114 pos += 1;
115 match descriptors[pos] {
116 Descriptor { f: 0, x: 31, y: 0 } => 1,
117 Descriptor { f: 0, x: 31, y: 1 } => 8,
118 Descriptor { f: 0, x: 31, y: 2 } => 16,
119 Descriptor { f: 0, x: 31, y: 3 } => 8, desc => {
121 return Err(Error::NotSupported(format!(
122 "Unsupported delayed descriptor replication factor: {desc:#?}",
123 )));
124 }
125 }
126 }
127 _ => 0,
128 };
129 pos += 1;
130 if pos + x as usize > descriptors.len() {
131 return Err(Error::Invalid(
132 "Replication range out of bounds".to_string(),
133 ));
134 }
135 resolved.push(ResolvedDescriptor::Replication {
136 y,
137 descriptors: resolve_descriptors(tables, &descriptors[pos..pos + x as usize])?,
138 delayed_bits,
139 });
140 pos += x as usize;
141 }
142 desc => {
143 resolved.push(ResolvedDescriptor::from_descriptor(desc, tables)?);
144 pos += 1;
145 }
146 }
147 }
148
149 Ok(resolved)
150}