Skip to content

Commit e7204ca

Browse files
committed
feat: support for reading from stdin
1 parent b0f198d commit e7204ca

File tree

4 files changed

+80
-44
lines changed

4 files changed

+80
-44
lines changed

Cargo.lock

+21-21
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
[package]
22
name = "binyl"
3-
description = "A bitwise UTF-8 inspection tool"
3+
description = "A bitwise UTF-8 string inspection tool"
44
version = "0.1.0"
55
authors = ["Yasuaki Uechi <[email protected]>"]
6-
edition = "2018"
7-
license = "Apache-2.0"
6+
edition = "2021"
87
license-file = "LICENSE"
98
repository = "https://github.com/uetchy/binyl"
109

1110
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
1211

1312
[dependencies]
14-
colored = "1.9.3"
13+
colored = "2.0.0"

README.md

+9-4
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
11
# binyl
22

3-
A bitwise UTF-8 inspection tool written in Rust.
3+
A bitwise UTF-8 string inspection tool written in Rust.
44

55
![Screenshot](https://github.com/uetchy/binyl/blob/master/.github/ss.png?raw=true)
66

77
## Installation
88

9-
```
9+
```bash
1010
cargo install binyl
1111
```
1212

1313
## Usage
1414

15-
```
16-
binyl <file to inspect>
15+
```bash
16+
binyl <file/to/inspect>
17+
18+
# or
19+
20+
echo わたしはネコ🐈 | binyl
21+
cat some.file | binyl
1722
```

src/main.rs

+47-15
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,23 @@ use std::process;
44

55
fn main() {
66
let args: Vec<String> = env::args().collect();
7-
let filename = match args.get(1) {
8-
Some(f) => f,
7+
8+
parse_string(match args.get(1) {
9+
// read from file
10+
Some(filename) => std::fs::read_to_string(filename).unwrap(),
11+
12+
// read from stdin
913
None => {
10-
println!("No arg provided");
11-
process::exit(1);
14+
let mut line = String::new();
15+
std::io::stdin().read_line(&mut line).unwrap();
16+
line
1217
}
13-
};
14-
let content = std::fs::read_to_string(filename).unwrap();
18+
})
19+
}
20+
21+
fn parse_string(content: String) {
1522
let mut bytes = content.bytes();
23+
1624
while let Some(b) = bytes.next() {
1725
if b & 0x80 == 0 {
1826
// if MSB is 0, is is ASCII.
@@ -23,42 +31,66 @@ fn main() {
2331
std::str::from_utf8(&[b])
2432
.unwrap()
2533
.replace("\x0a", "↵")
26-
.replace("\x20", "<space>"),
34+
.replace("\x20", "<space>")
35+
.bold(),
2736
b
2837
);
2938
} else {
3039
let nb = (!b).leading_zeros();
31-
let bin_str = format!("{:08b}", b);
32-
let (first_bin, second_bin) = bin_str.split_at(nb as usize + 1);
40+
let (first, last) = split_octet(b, nb);
41+
3342
print!("{} ", "├".bright_black());
34-
print!("{}{}", first_bin.magenta(), second_bin.green(),);
35-
let mut v: Vec<u8> = Vec::new();
43+
print!(
44+
"{}{}",
45+
format!("{:04b}", first).magenta(),
46+
format!("{:04b}", last).green(),
47+
);
48+
49+
let mut v: Vec<u8> = vec![];
3650
let mut f: u32 = 0;
3751
let base = 6 * (nb - 1);
3852

3953
v.push(b);
4054

4155
f |= (b as u32 & (u32::pow(2, 7 - nb) - 1)) << base;
56+
4257
for i in 0..(nb - 1) {
4358
let next_byte = bytes.next().unwrap();
59+
4460
// if first 2 MSB are not '10', it's illegal sequence.
4561
if next_byte & 0xC0 != 0x80 {
4662
println!("Illegal byte");
4763
process::exit(1);
4864
}
49-
let bin_str = format!("{:08b}", next_byte);
50-
let (first_bin, second_bin) = bin_str.split_at(2);
51-
print!("{}{}", first_bin.bright_black(), second_bin.green());
65+
66+
let (first, last) = split_octet(next_byte, 2);
67+
68+
print!(
69+
"{}{}",
70+
format!("{:02b}", first).bright_black(),
71+
format!("{:06b}", last).green()
72+
);
73+
5274
f |= (next_byte as u32 & 0x3f) << base - (i + 1) * 6;
5375
v.push(next_byte);
5476
}
77+
5578
println!(
5679
" ({} bytes) = {} {} (U+{:04X})",
5780
nb,
5881
format!("{:0b}", f).cyan(),
59-
std::str::from_utf8(&v[..]).unwrap().bold(),
82+
std::str::from_utf8(&v[..])
83+
.unwrap_or("[INVALID CODE]")
84+
.bold(),
6085
f
6186
);
6287
}
6388
}
6489
}
90+
91+
fn split_octet(octet: u8, separate_at: u32) -> (u8, u8) {
92+
let mask = u8::pow(2, separate_at) - 1;
93+
let first = (octet & !mask) >> (8 - separate_at);
94+
let last = octet & mask;
95+
(first, last)
96+
}

0 commit comments

Comments
 (0)