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(&mut self, index: u64, buffer: &[u8]) -> Result<Vec<u8>> {
55 let capacity = buffer
56 .len()
57 .checked_add(self.encryption.overhead())
58 .ok_or(Error::Overflow)?;
59 let mut encoded = Vec::new();
60 encoded
61 .try_reserve(capacity)
62 .map_err(|_| Error::Allocation)?;
63 encoded.extend_from_slice(buffer);
64 self.encode_frame(index, &mut encoded)?;
65 Ok(encoded)
66 }
67
68 fn encode_inner(&mut self, index: u64, buffer: &mut Vec<u8>) -> Result<FrameSizes> {
69 let raw = buffer.len() as u64;
70 self.config.validate_frame(index, raw, raw)?;
71 self.compression.encode(buffer)?;
72 let payload = buffer.len() as u64;
73 self.encryption.seal(index, buffer)?;
74 Ok(FrameSizes { raw, payload })
75 }
76}
77
78pub struct Decoder {
82 config: Config,
83 compression: CompressionState,
84 encryption: EncryptionState,
85}
86
87impl TryFrom<&Metadata> for Decoder {
88 type Error = Error;
89
90 fn try_from(metadata: &Metadata) -> Result<Self> {
91 let config = metadata.config().clone();
92 Ok(Self {
93 compression: CompressionState::new(config.compression())?,
94 encryption: EncryptionState::new(config.encryption())?,
95 config,
96 })
97 }
98}
99
100impl TryFrom<Metadata> for Decoder {
101 type Error = Error;
102
103 fn try_from(metadata: Metadata) -> Result<Self> {
104 Self::try_from(&metadata)
105 }
106}
107
108impl Decoder {
109 pub fn decode_frame(&mut self, spec: FrameSpec, buffer: &mut Vec<u8>) -> Result<()> {
113 let result = self.decode_inner(spec, buffer);
114 if result.is_err() {
115 buffer.clear();
116 }
117 result
118 }
119
120 fn decode_inner(&mut self, spec: FrameSpec, buffer: &mut Vec<u8>) -> Result<()> {
121 if spec.config != self.config {
122 return Err(Error::ProfileMismatch);
123 }
124 if buffer.len() != spec.stored_len() {
125 return Err(Error::InvalidStoredLength);
126 }
127 self.encryption.open(spec.index(), buffer)?;
128 if spec.payload_len() < spec.raw_len() {
129 self.compression.decode(buffer, spec.raw_len())?;
130 }
131 if buffer.len() != spec.raw_len() {
132 return Err(Error::DecompressionFailed);
133 }
134 Ok(())
135 }
136}