reed_solomon_16/rate/
encoder_work.rs

1use crate::{
2    engine::{Shards, ShardsRefMut},
3    Error,
4};
5
6// ======================================================================
7// EncoderWork - PUBLIC
8
9/// Working space for [`RateEncoder`].
10///
11/// [`RateEncoder`]: crate::rate::RateEncoder
12pub struct EncoderWork {
13    original_count: usize,
14    recovery_count: usize,
15    shard_bytes: usize,
16
17    original_received_count: usize,
18    shards: Shards,
19}
20
21impl EncoderWork {
22    /// Creates new [`EncoderWork`] which initially
23    /// has no working space allocated.
24    pub fn new() -> Self {
25        Self {
26            original_count: 0,
27            recovery_count: 0,
28            shard_bytes: 0,
29
30            original_received_count: 0,
31            shards: Shards::new(),
32        }
33    }
34}
35
36// ======================================================================
37// EncoderWork - IMPL Default
38
39impl Default for EncoderWork {
40    fn default() -> Self {
41        Self::new()
42    }
43}
44
45// ======================================================================
46// EncoderWork - CRATE
47
48impl EncoderWork {
49    pub(crate) fn add_original_shard<T: AsRef<[u8]>>(
50        &mut self,
51        original_shard: T,
52    ) -> Result<(), Error> {
53        let original_shard = original_shard.as_ref();
54
55        if self.original_received_count == self.original_count {
56            Err(Error::TooManyOriginalShards {
57                original_count: self.original_count,
58            })
59        } else if original_shard.len() != self.shard_bytes {
60            Err(Error::DifferentShardSize {
61                shard_bytes: self.shard_bytes,
62                got: original_shard.len(),
63            })
64        } else {
65            self.shards[self.original_received_count].copy_from_slice(original_shard);
66            self.original_received_count += 1;
67            Ok(())
68        }
69    }
70
71    pub(crate) fn encode_begin(&mut self) -> Result<(ShardsRefMut, usize, usize), Error> {
72        if self.original_received_count != self.original_count {
73            Err(Error::TooFewOriginalShards {
74                original_count: self.original_count,
75                original_received_count: self.original_received_count,
76            })
77        } else {
78            Ok((
79                self.shards.as_ref_mut(),
80                self.original_count,
81                self.recovery_count,
82            ))
83        }
84    }
85
86    // This must only be called by `EncoderResult`.
87    pub(crate) fn recovery(&self, index: usize) -> Option<&[u8]> {
88        if index < self.recovery_count {
89            Some(&self.shards[index])
90        } else {
91            None
92        }
93    }
94
95    pub(crate) fn reset(
96        &mut self,
97        original_count: usize,
98        recovery_count: usize,
99        shard_bytes: usize,
100        work_count: usize,
101    ) {
102        self.original_count = original_count;
103        self.recovery_count = recovery_count;
104        self.shard_bytes = shard_bytes;
105
106        self.original_received_count = 0;
107        self.shards.resize(work_count, shard_bytes);
108    }
109
110    pub(crate) fn reset_received(&mut self) {
111        self.original_received_count = 0;
112    }
113}