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

Method decoded_len

base64ct/src/decoder.rs:435–502  ·  view source on GitHub ↗

Get the total length of the data decoded from this line reader.

(&self)

Source from the content-addressed store, hash-verified

433
434 /// Get the total length of the data decoded from this line reader.
435 fn decoded_len<E: Encoding>(&self) -> Result<usize, Error> {
436 let mut buffer = [0u8; 4];
437 let mut lines = self.clone();
438 let mut line = match lines.next().transpose()? {
439 Some(l) => l,
440 None => return Ok(0),
441 };
442 let mut base64_len = 0usize;
443
444 loop {
445 base64_len = base64_len.checked_add(line.len()).ok_or(InvalidLength)?;
446
447 match lines.next().transpose()? {
448 Some(l) => {
449 // Store the end of the line in the buffer so we can
450 // reassemble the last block to determine the real length
451 buffer.copy_from_slice(line.slice_tail(4)?);
452
453 line = l
454 }
455
456 // To compute an exact decoded length we need to decode the
457 // last Base64 block and get the decoded length.
458 //
459 // This is what the somewhat complex code below is doing.
460 None => {
461 // Compute number of bytes in the last block (may be unpadded)
462 let base64_last_block_len = match base64_len % 4 {
463 0 => 4,
464 n => n,
465 };
466
467 // Compute decoded length without the last block
468 let decoded_len = encoding::decoded_len(
469 base64_len
470 .checked_sub(base64_last_block_len)
471 .ok_or(InvalidLength)?,
472 );
473
474 // Compute the decoded length of the last block
475 let mut out = [0u8; 3];
476 let last_block_len = if line.len() < base64_last_block_len {
477 let buffered_part_len = base64_last_block_len
478 .checked_sub(line.len())
479 .ok_or(InvalidLength)?;
480
481 let offset = 4usize.checked_sub(buffered_part_len).ok_or(InvalidLength)?;
482
483 for i in 0..buffered_part_len {
484 buffer[i] = buffer[offset.checked_add(i).ok_or(InvalidLength)?];
485 }
486
487 buffer[buffered_part_len..][..line.len()].copy_from_slice(line.remaining);
488 let buffer_len = buffered_part_len
489 .checked_add(line.len())
490 .ok_or(InvalidLength)?;
491
492 E::decode(&buffer[..buffer_len], &mut out)?.len()

Callers

nothing calls this directly

Calls 5

slice_tailMethod · 0.80
decoded_lenFunction · 0.70
decodeFunction · 0.50
nextMethod · 0.45
lenMethod · 0.45

Tested by

no test coverage detected