Use io::Write instead of fmt::Write for Encoder
This commit is contained in:
parent
bb47d46586
commit
23babcc511
2 changed files with 29 additions and 50 deletions
|
@ -7,11 +7,16 @@ pub struct Decoder<R: Read, W: Write> {
|
||||||
reader: R,
|
reader: R,
|
||||||
writer: W,
|
writer: W,
|
||||||
alphabet: B32Alphabet,
|
alphabet: B32Alphabet,
|
||||||
ignore_whitespace: bool
|
ignore_whitespace: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: Read, W: Write> Decoder<R, W> {
|
impl<R: Read, W: Write> Decoder<R, W> {
|
||||||
pub fn new(reader: R, writer: W, alphabet: Option<B32Alphabet>, ignore_whitespace: bool) -> Self {
|
pub fn new(
|
||||||
|
reader: R,
|
||||||
|
writer: W,
|
||||||
|
alphabet: Option<B32Alphabet>,
|
||||||
|
ignore_whitespace: bool,
|
||||||
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
reader,
|
reader,
|
||||||
writer,
|
writer,
|
||||||
|
@ -20,7 +25,6 @@ impl<R: Read, W: Write> Decoder<R, W> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Decodes the bytes provided by `self.reader` and writes the resulting
|
/// Decodes the bytes provided by `self.reader` and writes the resulting
|
||||||
/// bytes into `self.writer`.
|
/// bytes into `self.writer`.
|
||||||
/// # Important
|
/// # Important
|
||||||
|
@ -63,7 +67,10 @@ impl<R: Read, W: Write> Decoder<R, W> {
|
||||||
for c in &in_buf {
|
for c in &in_buf {
|
||||||
num <<= 5;
|
num <<= 5;
|
||||||
if !matches!(self.alphabet.pad(), Some(ch) if ch == *c) {
|
if !matches!(self.alphabet.pad(), Some(ch) if ch == *c) {
|
||||||
let idx = self.alphabet.idx(*c).ok_or(Error::IllegalChar((*c).into()))?;
|
let idx = self
|
||||||
|
.alphabet
|
||||||
|
.idx(*c)
|
||||||
|
.ok_or(Error::IllegalChar((*c).into()))?;
|
||||||
num |= idx as u64;
|
num |= idx as u64;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,29 +1,8 @@
|
||||||
use {
|
use {
|
||||||
super::*,
|
crate::{error::Error, B32Alphabet},
|
||||||
std::{
|
std::io::{self, ErrorKind, Read, Write},
|
||||||
fmt::{self, Write},
|
|
||||||
io::{self, Read},
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum EncoderError {
|
|
||||||
IO(io::Error),
|
|
||||||
FMT(fmt::Error),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<io::Error> for EncoderError {
|
|
||||||
fn from(value: io::Error) -> Self {
|
|
||||||
Self::IO(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<fmt::Error> for EncoderError {
|
|
||||||
fn from(value: fmt::Error) -> Self {
|
|
||||||
Self::FMT(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Encoder<R: Read, W: Write> {
|
pub struct Encoder<R: Read, W: Write> {
|
||||||
reader: R,
|
reader: R,
|
||||||
writer: W,
|
writer: W,
|
||||||
|
@ -41,7 +20,7 @@ impl<R: Read, W: Write> Encoder<R, W> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn encode(&mut self) -> Result<(), EncoderError> {
|
pub fn encode(&mut self) -> Result<(), Error> {
|
||||||
let mut total: usize = 0;
|
let mut total: usize = 0;
|
||||||
loop {
|
loop {
|
||||||
let mut buf = [0; 5];
|
let mut buf = [0; 5];
|
||||||
|
@ -50,7 +29,7 @@ impl<R: Read, W: Write> Encoder<R, W> {
|
||||||
loop {
|
loop {
|
||||||
n_bytes = match self.reader.read(&mut buf) {
|
n_bytes = match self.reader.read(&mut buf) {
|
||||||
Ok(n) => n,
|
Ok(n) => n,
|
||||||
Err(e) if e.kind() == io::ErrorKind::Interrupted => continue,
|
Err(e) if e.kind() == ErrorKind::Interrupted => continue,
|
||||||
Err(e) => return Err(e.into()),
|
Err(e) => return Err(e.into()),
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
|
@ -64,10 +43,10 @@ impl<R: Read, W: Write> Encoder<R, W> {
|
||||||
num |= *c as u64;
|
num |= *c as u64;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let mut buf = ['\0'; 8];
|
let mut buf = [b'\0'; 8];
|
||||||
for i in (0..8).rev() {
|
for i in (0..8).rev() {
|
||||||
let b = (num & 0x1f) as u8;
|
let b = (num & 0x1f) as u8;
|
||||||
buf[i] = char::try_from(self.alphabet.items[b as usize]).unwrap();
|
buf[i] = self.alphabet.items[b as usize];
|
||||||
num >>= 5;
|
num >>= 5;
|
||||||
}
|
}
|
||||||
let mut outlen = n_bytes * 8 / 5;
|
let mut outlen = n_bytes * 8 / 5;
|
||||||
|
@ -76,19 +55,19 @@ impl<R: Read, W: Write> Encoder<R, W> {
|
||||||
outlen += 1;
|
outlen += 1;
|
||||||
}
|
}
|
||||||
buf[0..outlen].iter().try_for_each(|c| {
|
buf[0..outlen].iter().try_for_each(|c| {
|
||||||
self.writer.write_char(*c)?;
|
self.writer.write_all(&[*c])?;
|
||||||
total += 1;
|
total += 1;
|
||||||
if let Some(wrap) = self.wrap {
|
if let Some(wrap) = self.wrap {
|
||||||
if total % wrap == 0 {
|
if total % wrap == 0 {
|
||||||
self.writer.write_char('\n')?;
|
writeln!(self.writer)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok::<(), fmt::Error>(())
|
Ok::<(), io::Error>(())
|
||||||
})?;
|
})?;
|
||||||
if let Some(pad) = self.alphabet.pad {
|
if let Some(pad) = self.alphabet.pad {
|
||||||
if rem != 0 {
|
if rem != 0 {
|
||||||
for _c in 0..8 - outlen {
|
for _c in 0..8 - outlen {
|
||||||
self.writer.write_char(char::try_from(pad).unwrap())?;
|
self.writer.write_all(&[pad])?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,12 +79,6 @@ impl<R: Read, W: Write> Encoder<R, W> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: Read> Encoder<R, String> {
|
|
||||||
pub fn output(self) -> String {
|
|
||||||
self.writer
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use {
|
use {
|
||||||
|
@ -119,16 +92,15 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn hello() {
|
fn hello() {
|
||||||
let reader = "Hello, World".as_bytes();
|
let reader = "Hello, World".as_bytes();
|
||||||
let writer = String::new();
|
let mut encoder = Encoder::new(reader, vec![], None, None);
|
||||||
let mut encoder = Encoder::new(reader, writer, None, None);
|
|
||||||
encoder.encode().unwrap();
|
encoder.encode().unwrap();
|
||||||
assert_eq!(encoder.output(), "JBSWY3DPFQQFO33SNRSA====");
|
assert_eq!(encoder.writer, b"JBSWY3DPFQQFO33SNRSA====");
|
||||||
encoder = Encoder::new("Hello, World!".as_bytes(), String::new(), None, None);
|
encoder = Encoder::new("Hello, World!".as_bytes(), vec![], None, None);
|
||||||
encoder.encode().unwrap();
|
encoder.encode().unwrap();
|
||||||
assert_eq!(encoder.output(), "JBSWY3DPFQQFO33SNRSCC===");
|
assert_eq!(encoder.writer, b"JBSWY3DPFQQFO33SNRSCC===");
|
||||||
encoder = Encoder::new("Hello, World!\n".as_bytes(), String::new(), None, None);
|
encoder = Encoder::new("Hello, World!\n".as_bytes(), vec![], None, None);
|
||||||
encoder.encode().unwrap();
|
encoder.encode().unwrap();
|
||||||
assert_eq!(encoder.output(), "JBSWY3DPFQQFO33SNRSCCCQ=");
|
assert_eq!(encoder.writer, b"JBSWY3DPFQQFO33SNRSCCCQ=");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -136,8 +108,8 @@ mod test {
|
||||||
let infile = File::open("src/testdata/lorem.txt").unwrap();
|
let infile = File::open("src/testdata/lorem.txt").unwrap();
|
||||||
let reader = BufReader::new(infile);
|
let reader = BufReader::new(infile);
|
||||||
let outfile = fs::read_to_string("src/testdata/lorem_b32.txt").unwrap();
|
let outfile = fs::read_to_string("src/testdata/lorem_b32.txt").unwrap();
|
||||||
let mut encoder = Encoder::new(reader, String::new(), None, Some(76));
|
let mut encoder = Encoder::new(reader, vec![], None, Some(76));
|
||||||
encoder.encode().unwrap();
|
encoder.encode().unwrap();
|
||||||
assert_eq!(encoder.output(), outfile);
|
assert_eq!(encoder.writer, outfile.as_bytes());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue