1use ::gf::poly_math::*;
2use ::gf::poly::Polynom;
3use ::buffer::Buffer;
4use ::gf;
5
6#[derive(Debug)]
8pub struct Encoder {
9 generator: Polynom,
10}
11
12impl Encoder {
13 pub fn new(ecc_len: usize) -> Self {
22 Encoder { generator: generator_poly(ecc_len) }
23 }
24
25 pub fn encode(&self, data: &[u8]) -> Buffer {
41 let mut data_out = Polynom::from(data);
42 let data_len = data.len();
43
44 data_out.set_length(data_len + self.generator.len() - 1);
45
46 let gen = self.generator;
47 let mut lgen = Polynom::with_length(self.generator.len());
48 for (i, gen_i) in gen.iter().enumerate() {
49 uncheck_mut!(lgen[i]) = gf::LOG[*gen_i as usize];
50 }
51
52 for i in 0..data_len {
53 let coef = uncheck!(data_out[i]);
54 if coef != 0 {
55 let lcoef = gf::LOG[coef as usize] as usize;
56 for j in 1..gen.len() {
57 uncheck_mut!(data_out[i + j]) ^= gf::EXP[(lcoef + lgen[j] as usize)];
58 }
59 }
60 }
61
62 data_out[..data_len].copy_from_slice(data);
63 Buffer::from_polynom(data_out, data_len)
64 }
65}
66
67fn generator_poly(ecclen: usize) -> Polynom {
68 let mut gen = polynom![1];
69 let mut mm = [1, 0];
70 for i in 0..ecclen {
71 mm[1] = gf::pow(2, i as i32);
72 gen = gen.mul(&mm);
73 }
74 gen
75}
76
77
78#[cfg(test)]
79mod tests {
80 #[test]
81 fn generator_poly() {
82 let answers =
83 [polynom![1, 3, 2],
84 polynom![1, 15, 54, 120, 64],
85 polynom![1, 255, 11, 81, 54, 239, 173, 200, 24],
86 polynom![1, 59, 13, 104, 189, 68, 209, 30, 8, 163, 65, 41, 229, 98, 50, 36, 59],
87 polynom![1, 116, 64, 52, 174, 54, 126, 16, 194, 162, 33, 33, 157, 176, 197, 225, 12,
88 59, 55, 253, 228, 148, 47, 179, 185, 24, 138, 253, 20, 142, 55, 172, 88],
89 polynom![1, 193, 10, 255, 58, 128, 183, 115, 140, 153, 147, 91, 197, 219, 221, 220,
90 142, 28, 120, 21, 164, 147, 6, 204, 40, 230, 182, 14, 121, 48, 143, 77,
91 228, 81, 85, 43, 162, 16, 195, 163, 35, 149, 154, 35, 132, 100, 100, 51,
92 176, 11, 161, 134, 208, 132, 244, 176, 192, 221, 232, 171, 125, 155, 228,
93 242, 245]];
94
95 let mut ecclen = 2;
96 for i in 0..6 {
97 assert_eq!(*answers[i], *super::generator_poly(ecclen));
98 ecclen *= 2;
99 }
100 }
101
102 #[test]
103 fn encode() {
104 let data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
105 22, 23, 24, 25, 26, 27, 28, 29];
106 let ecc = [99, 26, 219, 193, 9, 94, 186, 143];
107
108 let encoder = super::Encoder::new(ecc.len());
109 let encoded = encoder.encode(&data[..]);
110
111 assert_eq!(data, encoded.data());
112 assert_eq!(ecc, encoded.ecc());
113 }
114
115}