MCPcopy Create free account
hub / github.com/RustCrypto/formats / decode

Method decode

base64ct/src/decoder.rs:107–162  ·  view source on GitHub ↗

Fill the provided buffer with data decoded from Base64. Enough Base64 input data must remain to fill the entire buffer. # Returns - `Ok(bytes)` if the expected amount of data was read - `Err(Error::InvalidLength)` if the exact amount of data couldn't be read

(&mut self, out: &'o mut [u8])

Source from the content-addressed store, hash-verified

105 /// - `Ok(bytes)` if the expected amount of data was read
106 /// - `Err(Error::InvalidLength)` if the exact amount of data couldn't be read
107 pub fn decode<'o>(&mut self, out: &'o mut [u8]) -> Result<&'o [u8], Error> {
108 if self.is_finished() {
109 return Err(InvalidLength);
110 }
111
112 let mut out_pos = 0;
113
114 while out_pos < out.len() {
115 // If there's data in the block buffer, use it
116 if !self.block_buffer.is_empty() {
117 let out_rem = out.len().checked_sub(out_pos).ok_or(InvalidLength)?;
118 let bytes = self.block_buffer.take(out_rem)?;
119 out[out_pos..][..bytes.len()].copy_from_slice(bytes);
120 out_pos = out_pos.checked_add(bytes.len()).ok_or(InvalidLength)?;
121 }
122
123 // Advance the line reader if necessary
124 if self.line.is_empty() && !self.line_reader.is_empty() {
125 self.advance_line()?;
126 }
127
128 // Attempt to decode a stride of block-aligned data
129 let in_blocks = self.line.len() / 4;
130 let out_rem = out.len().checked_sub(out_pos).ok_or(InvalidLength)?;
131 let out_blocks = out_rem / 3;
132 let blocks = cmp::min(in_blocks, out_blocks);
133 let in_aligned = self.line.take(blocks.checked_mul(4).ok_or(InvalidLength)?);
134
135 if !in_aligned.is_empty() {
136 let out_buf = &mut out[out_pos..][..blocks.checked_mul(3).ok_or(InvalidLength)?];
137 let decoded_len = self.perform_decode(in_aligned, out_buf)?.len();
138 out_pos = out_pos.checked_add(decoded_len).ok_or(InvalidLength)?;
139 }
140
141 if out_pos < out.len() {
142 if self.is_finished() {
143 // If we're out of input then we've been requested to decode
144 // more data than is actually available.
145 return Err(InvalidLength);
146 } else {
147 // If we still have data available but haven't completely
148 // filled the output slice, we're in a situation where
149 // either the input or output isn't block-aligned, so fill
150 // the internal block buffer.
151 self.fill_block_buffer()?;
152 }
153 }
154 }
155
156 self.remaining_len = self
157 .remaining_len
158 .checked_sub(out.len())
159 .ok_or(InvalidLength)?;
160
161 Ok(out)
162 }
163
164 /// Decode all remaining Base64 data, placing the result into `buf`.

Callers 5

decode_valueMethod · 0.45
decode_to_endMethod · 0.45
readMethod · 0.45
read_exactMethod · 0.45
decode_testFunction · 0.45

Calls 7

advance_lineMethod · 0.80
perform_decodeMethod · 0.80
fill_block_bufferMethod · 0.80
is_finishedMethod · 0.45
lenMethod · 0.45
is_emptyMethod · 0.45
takeMethod · 0.45

Tested by 1

decode_valueMethod · 0.36