Add b64 enocoding and test
This commit is contained in:
parent
683aa50d2a
commit
e12cc66fba
@ -1,8 +1,6 @@
|
||||
pub use {
|
||||
super::B64Alphabet,
|
||||
std::{
|
||||
io::{self, Read, Write, ErrorKind},
|
||||
},
|
||||
std::io::{self, ErrorKind, Read, Write},
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -33,4 +31,3 @@ pub struct Decoder<R: Read, W: Write> {
|
||||
mod tests {
|
||||
use super::*;
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@ pub use {
|
||||
super::B64Alphabet,
|
||||
std::{
|
||||
fmt::{self, Write},
|
||||
io::{self, Read, ErrorKind},
|
||||
io::{self, ErrorKind, Read},
|
||||
},
|
||||
};
|
||||
|
||||
@ -50,11 +50,57 @@ pub struct Encoder<R: Read, W: Write> {
|
||||
|
||||
impl<R: Read, W: Write> Encoder<R, W> {
|
||||
pub fn new(reader: R, writer: W, alphabet: B64Alphabet) -> Self {
|
||||
Self { reader, writer, alphabet }
|
||||
Self {
|
||||
reader,
|
||||
writer,
|
||||
alphabet,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn encode(&mut self) -> Result<(), Error> {
|
||||
todo!()
|
||||
loop {
|
||||
let mut ibuf = [0; 3];
|
||||
let mut obuf = [self.alphabet.pad(); 4];
|
||||
let mut n_bytes = 0;
|
||||
let mut num: u64 = 0;
|
||||
loop {
|
||||
n_bytes += match self.reader.read(&mut ibuf) {
|
||||
Ok(n) => n,
|
||||
Err(e) if e.kind() == ErrorKind::Interrupted => continue,
|
||||
Err(e) => return Err(e.into()),
|
||||
};
|
||||
break;
|
||||
}
|
||||
if n_bytes == 0 {
|
||||
break;
|
||||
}
|
||||
for (idx, n) in ibuf.iter().enumerate() {
|
||||
num <<= 8;
|
||||
if idx < n_bytes {
|
||||
num |= *n as u64;
|
||||
}
|
||||
}
|
||||
let pad = n_bytes * 8 % 6;
|
||||
for idx in (0..4).rev() {
|
||||
if pad == 0 || idx < 4 - pad {
|
||||
let b = num & 0b111111;
|
||||
obuf[idx] = self.alphabet.items[b as usize];
|
||||
}
|
||||
num >>= 6;
|
||||
}
|
||||
write!(
|
||||
self.writer,
|
||||
"{}{}{}{}",
|
||||
char::try_from(obuf[0]).unwrap(),
|
||||
char::try_from(obuf[1]).unwrap(),
|
||||
char::try_from(obuf[2]).unwrap(),
|
||||
char::try_from(obuf[3]).unwrap()
|
||||
)?;
|
||||
if pad > 0 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
19
src/lib.rs
19
src/lib.rs
@ -1,9 +1,9 @@
|
||||
mod encode;
|
||||
mod decode;
|
||||
mod encode;
|
||||
|
||||
pub use {
|
||||
encode::{Error as B64EncoderError, Encoder as B64Encoder},
|
||||
decode::{Error as B64DecoderError, Decoder as B64Decoder},
|
||||
decode::{Decoder as B64Decoder, Error as B64DecoderError},
|
||||
encode::{Encoder as B64Encoder, Error as B64EncoderError},
|
||||
};
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
@ -14,11 +14,10 @@ pub struct B64Alphabet {
|
||||
|
||||
pub static B64_RFC4648_ALPHABET: B64Alphabet = B64Alphabet {
|
||||
items: [
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
|
||||
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
|
||||
'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
|
||||
't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', '+', '/',
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
|
||||
'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
|
||||
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1',
|
||||
'2', '3', '4', '5', '6', '7', '8', '9', '+', '/',
|
||||
],
|
||||
pad: '=',
|
||||
};
|
||||
@ -33,9 +32,9 @@ impl B64Alphabet {
|
||||
pub fn idx(&self, c: char) -> Option<usize> {
|
||||
for (idx, x) in self.items.iter().enumerate() {
|
||||
if *x == c {
|
||||
return Some(idx)
|
||||
return Some(idx);
|
||||
}
|
||||
};
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user