Change alphabet to use bytes rather than chars
This commit is contained in:
parent
4b165a6736
commit
2e2ac8154e
3 changed files with 19 additions and 26 deletions
|
@ -1,5 +1,5 @@
|
||||||
use std::io::{self, Read, Write};
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use std::io::{self, Read, Write};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum DecoderError {
|
pub enum DecoderError {
|
||||||
|
@ -21,7 +21,11 @@ pub struct Decoder<R: Read, W: Write> {
|
||||||
|
|
||||||
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>) -> Self {
|
pub fn new(reader: R, writer: W, alphabet: Option<B32Alphabet>) -> Self {
|
||||||
Self { reader, writer, alphabet: alphabet.unwrap_or_default() }
|
Self {
|
||||||
|
reader,
|
||||||
|
writer,
|
||||||
|
alphabet: alphabet.unwrap_or_default(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn decode(&mut self) -> Result<(), DecoderError> {
|
pub fn decode(&mut self) -> Result<(), DecoderError> {
|
||||||
|
@ -34,10 +38,9 @@ impl<R: Read, W: Write> Decoder<R, W> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for c in &buf {
|
for c in &buf {
|
||||||
let c = char::from(*c);
|
|
||||||
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(DecoderError::IllegalChar)?;
|
let idx = self.alphabet.idx(*c).ok_or(DecoderError::IllegalChar)?;
|
||||||
num |= idx as u64;
|
num |= idx as u64;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,7 +78,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn get_idx() {
|
fn get_idx() {
|
||||||
let idx = B32_RFC4648_ALPHABET.idx('S').unwrap();
|
let idx = B32_RFC4648_ALPHABET.idx(b'S').unwrap();
|
||||||
assert_eq!(idx, 18);
|
assert_eq!(idx, 18);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,4 +91,3 @@ mod tests {
|
||||||
assert_eq!(HELLO, String::from_utf8(decoder.bytes()).unwrap());
|
assert_eq!(HELLO, String::from_utf8(decoder.bytes()).unwrap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -123,20 +123,10 @@ mod test {
|
||||||
let mut encoder = Encoder::new(reader, writer, 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.output(), "JBSWY3DPFQQFO33SNRSA====");
|
||||||
encoder = Encoder::new(
|
encoder = Encoder::new("Hello, World!".as_bytes(), String::new(), None, None);
|
||||||
"Hello, World!".as_bytes(),
|
|
||||||
String::new(),
|
|
||||||
None,
|
|
||||||
None
|
|
||||||
);
|
|
||||||
encoder.encode().unwrap();
|
encoder.encode().unwrap();
|
||||||
assert_eq!(encoder.output(), "JBSWY3DPFQQFO33SNRSCC===");
|
assert_eq!(encoder.output(), "JBSWY3DPFQQFO33SNRSCC===");
|
||||||
encoder = Encoder::new(
|
encoder = Encoder::new("Hello, World!\n".as_bytes(), String::new(), None, None);
|
||||||
"Hello, World!\n".as_bytes(),
|
|
||||||
String::new(),
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
encoder.encode().unwrap();
|
encoder.encode().unwrap();
|
||||||
assert_eq!(encoder.output(), "JBSWY3DPFQQFO33SNRSCCCQ=");
|
assert_eq!(encoder.output(), "JBSWY3DPFQQFO33SNRSCCCQ=");
|
||||||
}
|
}
|
||||||
|
|
15
src/lib.rs
15
src/lib.rs
|
@ -5,16 +5,17 @@ pub mod error;
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct B32Alphabet {
|
pub struct B32Alphabet {
|
||||||
items: [char; 32],
|
items: [u8; 32],
|
||||||
pad: Option<char>,
|
pad: Option<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub static B32_RFC4648_ALPHABET: B32Alphabet = B32Alphabet {
|
pub static B32_RFC4648_ALPHABET: B32Alphabet = B32Alphabet {
|
||||||
items: [
|
items: [
|
||||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
|
b'A', b'B', b'C', b'D', b'E', b'F', b'G', b'H', b'I', b'J', b'K', b'L', b'M', b'N', b'O',
|
||||||
'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '2', '3', '4', '5', '6', '7',
|
b'P', b'Q', b'R', b'S', b'T', b'U', b'V', b'W', b'X', b'Y', b'Z', b'2', b'3', b'4', b'5',
|
||||||
|
b'6', b'7',
|
||||||
],
|
],
|
||||||
pad: Some('='),
|
pad: Some(b'='),
|
||||||
};
|
};
|
||||||
|
|
||||||
impl Default for B32Alphabet {
|
impl Default for B32Alphabet {
|
||||||
|
@ -24,7 +25,7 @@ impl Default for B32Alphabet {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl B32Alphabet {
|
impl B32Alphabet {
|
||||||
pub(crate) fn idx(&self, c: char) -> Option<usize> {
|
pub(crate) fn idx(&self, c: u8) -> 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);
|
||||||
|
@ -33,7 +34,7 @@ impl B32Alphabet {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn pad(&self) -> Option<char> {
|
pub(crate) fn pad(&self) -> Option<u8> {
|
||||||
self.pad
|
self.pad
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue