Skip to content

Commit

Permalink
Merge rust-bitcoin#3227: feat: remove zeroed vector by pushing front
Browse files Browse the repository at this point in the history
441aac0 fix: vec! macro enabled only for test module (Chris Hyunhum Cho)
a050618 feat: remove zeroed vector by pushing front (Chris Hyunhum Cho)

Pull request description:

  Remove useless zeroed vector following rust-bitcoin#3131.
  1. Init vector with capacity not to realloc when pushing.
  2. If vector is empty(the first iteration), push data from the front.
  3. Iterate vector from the front, and copy it from the end.

ACKs for top commit:
  apoelstra:
    ACK 441aac0 successfully ran local tests
  jamillambert:
    ACK 441aac0
  Kixunil:
    ACK 441aac0

Tree-SHA512: dee934f675786e6977216de9516ecb7f03fa17304891f060b33d46ff3a02342b817628b68dc429c65730a52e1d99c3d0d5e9d47afee5b727b06d3c800767369e
  • Loading branch information
apoelstra committed Aug 26, 2024
2 parents de6a77d + 441aac0 commit d7ac6af
Showing 1 changed file with 14 additions and 7 deletions.
21 changes: 14 additions & 7 deletions base58/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
#![allow(clippy::needless_question_mark)] // https://github.com/rust-bitcoin/rust-bitcoin/pull/2134
#![allow(clippy::manual_range_contains)] // More readable than clippy's format.

#[macro_use]
extern crate alloc;

#[cfg(bench)]
Expand Down Expand Up @@ -69,7 +68,7 @@ static BASE58_DIGITS: [Option<u8>; 128] = [
/// Decodes a base58-encoded string into a byte vector.
pub fn decode(data: &str) -> Result<Vec<u8>, InvalidCharacterError> {
// 11/15 is just over log_256(58)
let mut scratch = vec![0u8; 1 + data.len() * 11 / 15];
let mut scratch = Vec::with_capacity(1 + data.len() * 11 / 15);
// Build in base 256
for d58 in data.bytes() {
// Compute "X = X * 58 + next_digit" in base 256
Expand All @@ -82,18 +81,25 @@ pub fn decode(data: &str) -> Result<Vec<u8>, InvalidCharacterError> {
return Err(InvalidCharacterError { invalid: d58 });
}
};
for d256 in scratch.iter_mut().rev() {
carry += u32::from(*d256) * 58;
*d256 = carry as u8; // cast loses data intentionally
carry /= 256;
if scratch.is_empty() {
for _ in 0..scratch.capacity() {
scratch.push(carry as u8);
carry /= 256;
}
} else {
for d256 in scratch.iter_mut() {
carry += u32::from(*d256) * 58;
*d256 = carry as u8; // cast loses data intentionally
carry /= 256;
}
}
assert_eq!(carry, 0);
}

// Copy leading zeroes directly
let mut ret: Vec<u8> = data.bytes().take_while(|&x| x == BASE58_CHARS[0]).map(|_| 0).collect();
// Copy rest of string
ret.extend(scratch.into_iter().skip_while(|&x| x == 0));
ret.extend(scratch.into_iter().rev().skip_while(|&x| x == 0));
Ok(ret)
}

Expand Down Expand Up @@ -241,6 +247,7 @@ where

#[cfg(test)]
mod tests {
use alloc::vec;
use hex::test_hex_unwrap as hex;

use super::*;
Expand Down

0 comments on commit d7ac6af

Please sign in to comment.