assembly_pack/common/
writer.rs1use std::{
4 collections::BTreeMap,
5 io::{self, Write},
6 ops::Range,
7};
8
9fn write_crc_tree_recursive<V, W: Write, I: Iterator<Item = (u32, V)>>(
16 writer: &mut W,
17 iterator: &mut I,
18 range: Range<u32>,
19 write_value: fn(&mut W, V) -> io::Result<()>,
20) -> io::Result<()> {
21 let len = range.end - range.start;
22 match len {
23 0 => { }
24 _ => {
25 let mid = range.start + len / 2;
26
27 let left_range = range.start..mid;
28 let left_len = left_range.end - left_range.start;
29 let left_ptr = if left_len == 0 {
30 u32::MAX
31 } else {
32 left_range.start + left_len / 2
33 };
34
35 let right_range = (mid + 1)..range.end;
36 let right_len = right_range.end - right_range.start;
37 let right_ptr = if right_len == 0 {
38 u32::MAX
39 } else {
40 right_range.start + right_len / 2
41 };
42
43 write_crc_tree_recursive(writer, iterator, left_range, write_value)?;
44
45 let (crc, data) = iterator.next().unwrap();
46 writer.write_all(&crc.to_le_bytes())?;
47 writer.write_all(&left_ptr.to_le_bytes())?;
48 writer.write_all(&right_ptr.to_le_bytes())?;
49 write_value(writer, data)?;
50
51 write_crc_tree_recursive(writer, iterator, right_range, write_value)?;
52 }
53 }
54
55 Ok(())
56}
57
58pub fn write_crc_tree<V, W: Write>(
60 writer: &mut W,
61 tree: &BTreeMap<u32, V>,
62 write_value: fn(&mut W, &V) -> io::Result<()>,
63) -> io::Result<()> {
64 let len = tree.len() as u32;
65 writer.write_all(&len.to_le_bytes())?;
66 write_crc_tree_recursive(
67 writer,
68 &mut tree.iter().map(|(a, b)| (*a, b)),
69 0..len,
70 write_value,
71 )
72}