reed_solomon_simd/rate/
encoder_work.rs1use crate::{
2 engine::{Shards, ShardsRefMut},
3 Error,
4};
5
6pub struct EncoderWork {
13 original_count: usize,
14 recovery_count: usize,
15
16 pub(crate) shard_bytes: usize,
17
18 original_received_count: usize,
19 shards: Shards,
20}
21
22impl EncoderWork {
23 pub fn new() -> Self {
26 Self {
27 original_count: 0,
28 recovery_count: 0,
29 shard_bytes: 0,
30
31 original_received_count: 0,
32 shards: Shards::new(),
33 }
34 }
35}
36
37impl Default for EncoderWork {
41 fn default() -> Self {
42 Self::new()
43 }
44}
45
46impl EncoderWork {
50 pub(crate) fn add_original_shard<T: AsRef<[u8]>>(
51 &mut self,
52 original_shard: T,
53 ) -> Result<(), Error> {
54 let original_shard = original_shard.as_ref();
55
56 if self.original_received_count == self.original_count {
57 Err(Error::TooManyOriginalShards {
58 original_count: self.original_count,
59 })
60 } else if original_shard.len() != self.shard_bytes {
61 Err(Error::DifferentShardSize {
62 shard_bytes: self.shard_bytes,
63 got: original_shard.len(),
64 })
65 } else {
66 self.shards
67 .insert(self.original_received_count, original_shard);
68
69 self.original_received_count += 1;
70 Ok(())
71 }
72 }
73
74 pub(crate) fn encode_begin(&mut self) -> Result<(ShardsRefMut, usize, usize), Error> {
75 if self.original_received_count == self.original_count {
76 Ok((
77 self.shards.as_ref_mut(),
78 self.original_count,
79 self.recovery_count,
80 ))
81 } else {
82 Err(Error::TooFewOriginalShards {
83 original_count: self.original_count,
84 original_received_count: self.original_received_count,
85 })
86 }
87 }
88
89 pub(crate) fn recovery(&self, index: usize) -> Option<&[u8]> {
91 if index < self.recovery_count {
92 Some(&self.shards[index].as_flattened()[..self.shard_bytes])
93 } else {
94 None
95 }
96 }
97
98 pub(crate) fn reset(
99 &mut self,
100 original_count: usize,
101 recovery_count: usize,
102 shard_bytes: usize,
103 work_count: usize,
104 ) {
105 assert!(shard_bytes % 2 == 0);
106
107 self.original_count = original_count;
108 self.recovery_count = recovery_count;
109 self.shard_bytes = shard_bytes;
110
111 self.original_received_count = 0;
112 self.shards.resize(work_count, shard_bytes.div_ceil(64));
113 }
114
115 pub(crate) fn reset_received(&mut self) {
116 self.original_received_count = 0;
117 }
118
119 pub(crate) fn undo_last_chunk_encoding(&mut self) {
120 self.shards
121 .undo_last_chunk_encoding(self.shard_bytes, 0..self.recovery_count);
122 }
123}