Skip to content

Instantly share code, notes, and snippets.

@SethDusek
Created August 17, 2016 19:51
#![feature(test)]
#![feature(question_mark)]
extern crate rand;
extern crate test;
#[cfg(feature="parallel")]
extern crate rayon;
use std::ptr;
use std::path::Path;
#[cfg(feature="parallel")]
use rayon::prelude::*;
use std::io::Read;
use std::fs::File;
use std::os::unix::fs::PermissionsExt;
use std::fmt::Write;
const BUF_SIZE: usize = 1_024_000;
fn convert(x: [u8; 3]) -> [u8; 4] {
[
(x[0] >> 2) + 32,
(((x[0] & 0b00000011) << 4) | (x[1] >> 4)) + 32,
(((x[1] & 0b00001111) << 2) | (x[2] >> 6)) + 32,
(x[2] & 0b00111111) + 32,
]
}
#[cfg(feature="parallel")]
fn uuencode<T: AsRef<[u8]>>(val: T) -> Vec<String> {
let lines = val.as_ref().chunks(45).collect::<Vec<&[u8]>>();
let mut encoded = Vec::new();
lines.par_iter().map(|line| {
let len = (if line.len() > 0 { line.len() as u8 + 32 } else { 96 }) as char;
let mut encoded = String::new();
for chunk in line.chunks(3) {
let mut bits = [0u8; 3];
unsafe { std::ptr::copy(chunk.as_ptr(), bits.as_mut_ptr(), chunk.len()); }
let converted = convert(bits);
let converted = std::str::from_utf8(&converted).unwrap();
encoded.push_str(converted);
}
encoded.insert(0, len);
encoded
}).collect_into(&mut encoded);
encoded
}
#[cfg(not(feature="parallel"))]
fn uuencode<T: AsRef<[u8]>>(val: T) -> Vec<String> {
let lines = val.as_ref().chunks(45);
let encoded = lines.map(|line| {
let len = (if line.len() > 0 { line.len() as u8 + 32 } else { 96 }) as char;
let mut encoded = String::new();
for chunk in line.chunks(3) {
let mut bits = [0u8; 3];
unsafe { std::ptr::copy(chunk.as_ptr(), bits.as_mut_ptr(), chunk.len()); }
let converted = convert(bits);
let converted = std::str::from_utf8(&converted).unwrap();
encoded.push_str(converted);
}
encoded.insert(0, len);
encoded
}).collect();
encoded
}
fn uuencode_file(path: &Path) -> std::io::Result<String> {
let mut file = File::open(path)?;
let metadata = file.metadata()?;
let mut encoded = String::with_capacity(metadata.len() as usize);
encoded.push_str(&format!("begin {} {}\n", metadata.permissions().mode(), path.file_name().unwrap().to_str().unwrap()));
let mut buf = [0; BUF_SIZE];
while let Ok(bytes) = file.read(&mut buf) {
if bytes == 0 {
encoded.write_str("`\nend");
break;
}
for line in uuencode(&buf[..bytes-1]) {
writeln!(encoded, "{}", line);
}
}
Ok(encoded)
}
#[bench]
fn uuencode_bench(bencher: &mut test::Bencher) {
use rand::thread_rng;
use rand::Rng;
let mut rng = thread_rng();
let mut buf = vec![];
buf.resize(10000000, 0);
rng.fill_bytes(&mut buf);
bencher.iter(move || { uuencode(&buf); });
}
fn main() {
println!("{}", uuencode_file(Path::new("/tmp/img.png")).unwrap());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment