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