1use crate::{Config, Error, FrameSizes, FrameSpec, Metadata, Result};
2use crate::{compression::CompressionState, crypto::EncryptionState};
3
4pub struct Encoder {
10 config: Config,
11 compression: CompressionState,
12 encryption: EncryptionState,
13}
14
15impl TryFrom<&Metadata> for Encoder {
16 type Error = Error;
17
18 fn try_from(metadata: &Metadata) -> Result<Self> {
19 let config = metadata.config().clone();
20 Ok(Self {
21 compression: CompressionState::new(config.compression())?,
22 encryption: EncryptionState::new(config.encryption())?,
23 config,
24 })
25 }
26}
27
28impl TryFrom<Metadata> for Encoder {
29 type Error = Error;
30
31 fn try_from(metadata: Metadata) -> Result<Self> {
32 Self::try_from(&metadata)
33 }
34}
35
36impl Encoder {
37 pub fn encode_frame(&mut self, index: u64, buffer: &mut Vec<u8>) -> Result<FrameSizes> {
44 let result = self.encode_inner(index, buffer);
45 if result.is_err() {
46 buffer.clear();
47 }
48 result
49 }
50
51 pub fn encode_frame_alloc(
56 &mut self,
57 index: u64,
58 buffer: &[u8],
59 ) -> Result<(Vec<u8>, FrameSizes)> {
60 let capacity = buffer
61 .len()
62 .checked_add(self.encryption.overhead())
63 .ok_or(Error::Overflow)?;
64 let mut encoded = Vec::new();
65 encoded
66 .try_reserve(capacity)
67 .map_err(|_| Error::Allocation)?;
68 encoded.extend_from_slice(buffer);
69 let sizes = self.encode_frame(index, &mut encoded)?;
70 Ok((encoded, sizes))
71 }
72
73 fn encode_inner(&mut self, index: u64, buffer: &mut Vec<u8>) -> Result<FrameSizes> {
74 let raw = buffer.len() as u64;
75 self.config.validate_frame(index, raw, raw)?;
76 self.compression.encode(buffer)?;
77 let payload = buffer.len() as u64;
78 self.encryption.seal(index, buffer)?;
79 Ok(FrameSizes { raw, payload })
80 }
81}
82
83pub struct Decoder {
87 config: Config,
88 compression: CompressionState,
89 encryption: EncryptionState,
90}
91
92impl TryFrom<&Metadata> for Decoder {
93 type Error = Error;
94
95 fn try_from(metadata: &Metadata) -> Result<Self> {
96 let config = metadata.config().clone();
97 Ok(Self {
98 compression: CompressionState::new(config.compression())?,
99 encryption: EncryptionState::new(config.encryption())?,
100 config,
101 })
102 }
103}
104
105impl TryFrom<Metadata> for Decoder {
106 type Error = Error;
107
108 fn try_from(metadata: Metadata) -> Result<Self> {
109 Self::try_from(&metadata)
110 }
111}
112
113impl Decoder {
114 pub fn decode_frame(&mut self, spec: FrameSpec, buffer: &mut Vec<u8>) -> Result<()> {
118 let result = self.decode_inner(spec, buffer);
119 if result.is_err() {
120 buffer.clear();
121 }
122 result
123 }
124
125 fn decode_inner(&mut self, spec: FrameSpec, buffer: &mut Vec<u8>) -> Result<()> {
126 if spec.config != self.config {
127 return Err(Error::ProfileMismatch);
128 }
129 if buffer.len() != spec.stored_len() {
130 return Err(Error::InvalidStoredLength);
131 }
132 self.encryption.open(spec.index(), buffer)?;
133 if spec.payload_len() < spec.raw_len() {
134 self.compression.decode(buffer, spec.raw_len())?;
135 }
136 if buffer.len() != spec.raw_len() {
137 return Err(Error::DecompressionFailed);
138 }
139 Ok(())
140 }
141}