Add wrapping and styling. Todo: test styling, make sure there is no
double newline at the end of the output
This commit is contained in:
parent
68138ab850
commit
29172fb5f9
5 changed files with 149 additions and 18 deletions
|
@ -43,13 +43,13 @@ impl<R: Read, W: Write> Decoder<R, W> {
|
|||
_ => unreachable!(),
|
||||
}
|
||||
let mut c = char::from(in_buf[0]);
|
||||
if let Some(idx) = super::get_idx(c.to_ascii_uppercase()) {
|
||||
if let Some(idx) = super::get_idx(c.to_ascii_uppercase().try_into().unwrap()) {
|
||||
out_buf[0] |= (idx << 4) as u8;
|
||||
} else {
|
||||
return Err(Error::IllegalChar(c));
|
||||
}
|
||||
c = char::from(in_buf[1]);
|
||||
if let Some(idx) = super::get_idx(c.to_ascii_uppercase()) {
|
||||
if let Some(idx) = super::get_idx(c.to_ascii_uppercase().try_into().unwrap()) {
|
||||
out_buf[0] |= idx as u8;
|
||||
} else {
|
||||
return Err(Error::IllegalChar(c));
|
||||
|
|
|
@ -3,25 +3,45 @@ use {
|
|||
std::io::{ErrorKind, Read, Write},
|
||||
};
|
||||
|
||||
pub enum Style {
|
||||
Plain,
|
||||
Spaces,
|
||||
SpacesWithHex,
|
||||
}
|
||||
|
||||
impl Default for Style {
|
||||
fn default() -> Self {
|
||||
Self::Plain
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Encoder<R: Read, W: Write> {
|
||||
reader: R,
|
||||
writer: W,
|
||||
style: Style,
|
||||
wrap: Option<usize>,
|
||||
}
|
||||
|
||||
impl<R: Read, W: Write> Encoder<R, W> {
|
||||
/// Creates a new encoder with the given reader and writer. If alphabet is
|
||||
/// `None` the encoder will use the default rfc4648 alphabet.
|
||||
pub fn new(reader: R, writer: W) -> Self {
|
||||
Self { reader, writer }
|
||||
pub fn new(reader: R, writer: W, style: Option<Style>, wrap: Option<usize>) -> Self {
|
||||
Self {
|
||||
reader,
|
||||
writer,
|
||||
style: style.unwrap_or_default(),
|
||||
wrap,
|
||||
}
|
||||
}
|
||||
|
||||
/// Encodes the given data as hexadecimal
|
||||
/// # Errors
|
||||
/// May return an error on IO failure
|
||||
pub fn encode(&mut self) -> Result<(), Error> {
|
||||
let mut total = 0;
|
||||
loop {
|
||||
let mut ibuf = [0; 1];
|
||||
let mut obuf = [' '; 2];
|
||||
let mut obuf = [b' '; 2];
|
||||
let mut n_bytes = 0;
|
||||
loop {
|
||||
n_bytes += match self.reader.read(&mut ibuf) {
|
||||
|
@ -32,13 +52,46 @@ impl<R: Read, W: Write> Encoder<R, W> {
|
|||
break;
|
||||
}
|
||||
if n_bytes == 0 {
|
||||
writeln!(self.writer)?;
|
||||
break;
|
||||
}
|
||||
let mut idx = usize::from(ibuf[0] & 0b1111);
|
||||
obuf[1] = B16_ALPHABET[idx];
|
||||
idx = usize::from((ibuf[0] & 0b1111_0000) >> 4);
|
||||
obuf[0] = B16_ALPHABET[idx];
|
||||
write!(self.writer, "{}{}", obuf[0], obuf[1])?;
|
||||
match self.style {
|
||||
Style::Plain => {
|
||||
if let Some(w) = self.wrap {
|
||||
if total > 0 && total % w < 2 {
|
||||
writeln!(self.writer)?;
|
||||
}
|
||||
}
|
||||
self.writer.write_all(&obuf)?;
|
||||
total += 2;
|
||||
}
|
||||
Style::Spaces => {
|
||||
if let Some(w) = self.wrap {
|
||||
if total % w < 3 {
|
||||
writeln!(self.writer)?;
|
||||
} else if total > 0 {
|
||||
write!(self.writer, " ")?;
|
||||
}
|
||||
}
|
||||
self.writer.write_all(&obuf)?;
|
||||
total += 3;
|
||||
}
|
||||
Style::SpacesWithHex => {
|
||||
if let Some(w) = self.wrap {
|
||||
if total % w < 5 {
|
||||
writeln!(self.writer)?;
|
||||
} else if total > 0 {
|
||||
write!(self.writer, " ")?;
|
||||
}
|
||||
}
|
||||
write!(self.writer, "0x{}{}", obuf[0], obuf[1])?;
|
||||
total += 5;
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -51,20 +104,28 @@ impl<R: Read, W: Write> Encoder<R, W> {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use std::{
|
||||
fs::{self, File},
|
||||
io::BufReader,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn encode() {
|
||||
let mut encoder = Encoder::new("Hello, World".as_bytes(), vec![]);
|
||||
let mut encoder = Encoder::new("Hello, World".as_bytes(), vec![], None, None);
|
||||
encoder.encode().unwrap();
|
||||
assert_eq!(encoder.output(), b"48656C6C6F2C20576F726C64");
|
||||
encoder = Encoder {
|
||||
reader: "Hello, World!".as_bytes(),
|
||||
writer: vec![],
|
||||
};
|
||||
assert_eq!(encoder.output(), b"48656C6C6F2C20576F726C64\n");
|
||||
encoder = Encoder::new("Hello, World!".as_bytes(), vec![], None, None);
|
||||
encoder.encode().unwrap();
|
||||
assert_eq!(encoder.output(), b"48656C6C6F2C20576F726C6421");
|
||||
encoder = Encoder::new("Hello, World!\n".as_bytes(), vec![]);
|
||||
assert_eq!(encoder.output(), b"48656C6C6F2C20576F726C6421\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn encode_wrapping() {
|
||||
let infile = File::open("testdata/lorem.txt").unwrap();
|
||||
let reader = BufReader::new(infile);
|
||||
let outfile = fs::read_to_string("testdata/lorem_b16.txt").unwrap();
|
||||
let mut encoder = Encoder::new(reader, vec![], None, Some(76));
|
||||
encoder.encode().unwrap();
|
||||
assert_eq!(encoder.output(), b"48656C6C6F2C20576F726C64210A");
|
||||
assert_eq!(encoder.writer, outfile.as_bytes());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,11 +4,11 @@ mod encode;
|
|||
mod error;
|
||||
pub use {decode::Decoder, encode::Encoder, error::Error};
|
||||
|
||||
pub static B16_ALPHABET: [char; 16] = [
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
|
||||
pub static B16_ALPHABET: [u8; 16] = [
|
||||
b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', b'A', b'B', b'C', b'D', b'E', b'F',
|
||||
];
|
||||
|
||||
pub(crate) fn get_idx(c: char) -> Option<usize> {
|
||||
pub(crate) fn get_idx(c: u8) -> Option<usize> {
|
||||
for (idx, x) in B16_ALPHABET.iter().enumerate() {
|
||||
if *x == c {
|
||||
return Some(idx);
|
||||
|
|
9
testdata/lorem.txt
vendored
Normal file
9
testdata/lorem.txt
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
Lorem ipsum odor amet, consectetuer adipiscing elit. Hendrerit eu semper lectus amet est proin. Tempus himenaeos at fusce lacus habitasse sociosqu torquent varius arcu. Odio netus fermentum nisl natoque per cubilia himenaeos urna. Elit venenatis eros risus vulputate duis interdum. Mauris dis ad pharetra dui aptent. Imperdiet orci auctor condimentum adipiscing arcu. Nullam tempor magna odio volutpat nisi. Condimentum scelerisque risus faucibus; duis sollicitudin nullam.
|
||||
|
||||
Condimentum ex fringilla tempus ultricies consectetur odio egestas venenatis vulputate. Sem sapien pellentesque ornare; viverra scelerisque consequat. Platea posuere mi senectus felis dolor dictumst mattis ultricies est. Malesuada elit adipiscing suspendisse est a. Justo luctus turpis tempus leo finibus rutrum nostra magnis aliquam. Felis posuere molestie praesent porta justo nisi. Etiam aptent conubia consectetur dis; penatibus elementum ut.
|
||||
|
||||
Morbi nostra netus ad nunc egestas neque nascetur fusce. Consequat ultrices scelerisque ut rhoncus volutpat, hendrerit convallis massa. Tortor himenaeos nullam malesuada suspendisse consectetur potenti volutpat. In suscipit sit maximus; lacinia eu nulla porta. Tempus commodo libero auctor cras bibendum sit. Metus aptent mauris nascetur venenatis diam metus. Inceptos mi ultrices class morbi donec. Orci pulvinar risus accumsan faucibus litora duis commodo commodo.
|
||||
|
||||
Aliquam etiam habitasse fames massa, hendrerit purus interdum nullam. Curabitur placerat tortor placerat nec adipiscing habitasse. Massa litora interdum pretium fusce nascetur primis faucibus magna. Dui curabitur molestie justo ullamcorper leo molestie mauris. Inceptos malesuada taciti litora libero maecenas neque nam laoreet. Tristique vivamus eget maecenas; porta fames curae mollis cras. Ipsum vulputate ullamcorper et nascetur nascetur vel orci.
|
||||
|
||||
Curae et odio; urna eros pulvinar malesuada eget dignissim. Cursus fermentum lectus phasellus tempor posuere vulputate quam. Mauris commodo commodo mauris inceptos metus varius urna sagittis. Ligula duis erat ipsum pretium eu facilisis. Duis lobortis proin facilisi ad suscipit vestibulum hac tortor interdum. Ultrices tincidunt maximus aptent phasellus in ullamcorper nisl varius dis. Venenatis enim potenti potenti sodales massa id elementum.
|
61
testdata/lorem_b16.txt
vendored
Normal file
61
testdata/lorem_b16.txt
vendored
Normal file
|
@ -0,0 +1,61 @@
|
|||
4C6F72656D20697073756D206F646F7220616D65742C20636F6E736563746574756572206164
|
||||
6970697363696E6720656C69742E2048656E6472657269742065752073656D706572206C6563
|
||||
74757320616D6574206573742070726F696E2E2054656D7075732068696D656E61656F732061
|
||||
74206675736365206C616375732068616269746173736520736F63696F73717520746F727175
|
||||
656E742076617269757320617263752E204F64696F206E65747573206665726D656E74756D20
|
||||
6E69736C206E61746F7175652070657220637562696C69612068696D656E61656F732075726E
|
||||
612E20456C69742076656E656E617469732065726F732072697375732076756C707574617465
|
||||
206475697320696E74657264756D2E204D617572697320646973206164207068617265747261
|
||||
2064756920617074656E742E20496D70657264696574206F72636920617563746F7220636F6E
|
||||
64696D656E74756D2061646970697363696E6720617263752E204E756C6C616D2074656D706F
|
||||
72206D61676E61206F64696F20766F6C7574706174206E6973692E20436F6E64696D656E7475
|
||||
6D207363656C657269737175652072697375732066617563696275733B206475697320736F6C
|
||||
6C696369747564696E206E756C6C616D2E0A0A436F6E64696D656E74756D206578206672696E
|
||||
67696C6C612074656D70757320756C7472696369657320636F6E7365637465747572206F6469
|
||||
6F20656765737461732076656E656E617469732076756C7075746174652E2053656D20736170
|
||||
69656E2070656C6C656E746573717565206F726E6172653B2076697665727261207363656C65
|
||||
72697371756520636F6E7365717561742E20506C6174656120706F7375657265206D69207365
|
||||
6E65637475732066656C697320646F6C6F722064696374756D7374206D617474697320756C74
|
||||
726963696573206573742E204D616C65737561646120656C69742061646970697363696E6720
|
||||
73757370656E64697373652065737420612E204A7573746F206C756374757320747572706973
|
||||
2074656D707573206C656F2066696E696275732072757472756D206E6F73747261206D61676E
|
||||
697320616C697175616D2E2046656C697320706F7375657265206D6F6C657374696520707261
|
||||
6573656E7420706F727461206A7573746F206E6973692E20457469616D20617074656E742063
|
||||
6F6E7562696120636F6E7365637465747572206469733B2070656E61746962757320656C656D
|
||||
656E74756D2075742E0A0A4D6F726269206E6F73747261206E65747573206164206E756E6320
|
||||
65676573746173206E65717565206E617363657475722066757363652E20436F6E7365717561
|
||||
7420756C747269636573207363656C657269737175652075742072686F6E63757320766F6C75
|
||||
747061742C2068656E64726572697420636F6E76616C6C6973206D617373612E20546F72746F
|
||||
722068696D656E61656F73206E756C6C616D206D616C6573756164612073757370656E646973
|
||||
736520636F6E736563746574757220706F74656E746920766F6C75747061742E20496E207375
|
||||
73636970697420736974206D6178696D75733B206C6163696E6961206575206E756C6C612070
|
||||
6F7274612E2054656D70757320636F6D6D6F646F206C696265726F20617563746F7220637261
|
||||
7320626962656E64756D207369742E204D6574757320617074656E74206D6175726973206E61
|
||||
7363657475722076656E656E61746973206469616D206D657475732E20496E636570746F7320
|
||||
6D6920756C74726963657320636C617373206D6F72626920646F6E65632E204F726369207075
|
||||
6C76696E617220726973757320616363756D73616E206661756369627573206C69746F726120
|
||||
6475697320636F6D6D6F646F20636F6D6D6F646F2E0A0A416C697175616D20657469616D2068
|
||||
61626974617373652066616D6573206D617373612C2068656E64726572697420707572757320
|
||||
696E74657264756D206E756C6C616D2E2043757261626974757220706C61636572617420746F
|
||||
72746F7220706C616365726174206E65632061646970697363696E6720686162697461737365
|
||||
2E204D61737361206C69746F726120696E74657264756D207072657469756D20667573636520
|
||||
6E61736365747572207072696D6973206661756369627573206D61676E612E20447569206375
|
||||
72616269747572206D6F6C6573746965206A7573746F20756C6C616D636F72706572206C656F
|
||||
206D6F6C6573746965206D61757269732E20496E636570746F73206D616C6573756164612074
|
||||
6163697469206C69746F7261206C696265726F206D616563656E6173206E65717565206E616D
|
||||
206C616F726565742E2054726973746971756520766976616D75732065676574206D61656365
|
||||
6E61733B20706F7274612066616D6573206375726165206D6F6C6C697320637261732E204970
|
||||
73756D2076756C70757461746520756C6C616D636F72706572206574206E6173636574757220
|
||||
6E617363657475722076656C206F7263692E0A0A4375726165206574206F64696F3B2075726E
|
||||
612065726F732070756C76696E6172206D616C6573756164612065676574206469676E697373
|
||||
696D2E20437572737573206665726D656E74756D206C65637475732070686173656C6C757320
|
||||
74656D706F7220706F73756572652076756C707574617465207175616D2E204D617572697320
|
||||
636F6D6D6F646F20636F6D6D6F646F206D617572697320696E636570746F73206D6574757320
|
||||
7661726975732075726E612073616769747469732E204C6967756C6120647569732065726174
|
||||
20697073756D207072657469756D20657520666163696C697369732E2044756973206C6F626F
|
||||
727469732070726F696E20666163696C69736920616420737573636970697420766573746962
|
||||
756C756D2068616320746F72746F7220696E74657264756D2E20556C7472696365732074696E
|
||||
636964756E74206D6178696D757320617074656E742070686173656C6C757320696E20756C6C
|
||||
616D636F72706572206E69736C20766172697573206469732E2056656E656E6174697320656E
|
||||
696D20706F74656E746920706F74656E746920736F64616C6573206D6173736120696420656C
|
||||
656D656E74756D2E0A
|
Loading…
Add table
Reference in a new issue