| use leb128; |
| |
| use std::io::{self, BufRead, Write}; |
| use std::str; |
| |
| fn display(bytes: &[u8]) -> String { |
| let mut s = vec![]; |
| |
| // Base 10. |
| write!(&mut s, "{:?}\n", bytes).unwrap(); |
| |
| // Hex. |
| write!(&mut s, "[").unwrap(); |
| for (i, b) in bytes.iter().enumerate() { |
| if i != 0 { |
| write!(&mut s, ", ").unwrap(); |
| } |
| write!(&mut s, "{:0x}", b).unwrap(); |
| } |
| writeln!(&mut s, "]").unwrap(); |
| |
| // Binary. |
| write!(&mut s, "[").unwrap(); |
| for (i, b) in bytes.iter().enumerate() { |
| if i != 0 { |
| write!(&mut s, ", ").unwrap(); |
| } |
| write!(&mut s, "{:08b}", b).unwrap(); |
| } |
| writeln!(&mut s, "]").unwrap(); |
| |
| String::from_utf8(s).unwrap() |
| } |
| |
| fn main() { |
| println!( |
| " |
| LEB128 Read-Eval-Print-Loop! |
| |
| Converts numbers to signed and unsigned LEB128 and displays the results in |
| base-10, hex, and binary. |
| " |
| ); |
| |
| let mut stdin = io::BufReader::new(io::stdin()); |
| let mut stdout = io::stdout(); |
| |
| let mut buf = vec![]; |
| |
| loop { |
| stdout.write_all(b"> ").expect("failed to write to stdout"); |
| stdout.flush().expect("failed to flush stdout"); |
| |
| buf.clear(); |
| let n = stdin |
| .read_until(b'\n', &mut buf) |
| .expect("failed to read line from stdin"); |
| if n == 0 { |
| break; |
| } |
| |
| let uleb = str::from_utf8(&buf) |
| .ok() |
| .and_then(|s| s.trim().parse().ok()) |
| .and_then(|n: u64| { |
| let mut s = vec![]; |
| leb128::write::unsigned(&mut s, n).ok()?; |
| Some(display(&s)) |
| }) |
| .unwrap_or_else(|| "error\n".into()); |
| stdout |
| .write_all(b"# unsigned LEB128\n") |
| .and_then(|_| stdout.write_all(uleb.as_bytes())) |
| .and_then(|_| stdout.write_all(b"\n")) |
| .expect("failed to write to stdout"); |
| |
| let leb = str::from_utf8(&buf) |
| .ok() |
| .and_then(|s| s.trim().parse().ok()) |
| .and_then(|n: i64| { |
| let mut s = vec![]; |
| leb128::write::signed(&mut s, n).ok()?; |
| Some(display(&s)) |
| }) |
| .unwrap_or_else(|| "error\n".into()); |
| stdout |
| .write_all(b"# signed LEB128\n") |
| .and_then(|_| stdout.write_all(leb.as_bytes())) |
| .and_then(|_| stdout.write_all(b"\n")) |
| .expect("failed to write to stdout"); |
| |
| stdout.flush().expect("failed to flush stdout"); |
| } |
| } |