Skip to content

Instantly share code, notes, and snippets.

@dutchLuck
Last active September 30, 2024 12:51
Show Gist options
  • Save dutchLuck/c0429dec8606e852592a67b3c6249089 to your computer and use it in GitHub Desktop.
Save dutchLuck/c0429dec8606e852592a67b3c6249089 to your computer and use it in GitHub Desktop.
Another (very simple) file byte display/dump command line utility in the Rust language, largely produced by CopilotAI from newbie queries.
//
// F I L E _ B Y T E _ D I S P L A Y
//
// File Byte display
//
// Display the bytes in a small file, or the first 1000 bytes
// of a larger file.
//
// Warning: lacks adequate command line parameter checking
//
// Copilot AI generated code Sep 2024
//
// This is the combination of a couple of attempts
// to get a file dump kind of utility out of Copilot AI
//
// Please heed the warning shown at the bottom of the Copilot
// response to my code generation requests; -
// "AI-generated code. Review and use carefully. More info on FAQ."
//
// Else-where are warning statements such as; -
// "Copilot uses AI. Check for mistakes."
//
// Please consider yourself duly warned.
//
// This program does the following:
// 1. Gets the name of the file to display
// 2. Gets the file metadata to determine its size.
// 3. Warns if the file size is greater than 1000 bytes.
// 4. Reads the file contents into a buffer with storage
// capacity of 1000 bytes.
// 5 Prints the buffer contents in hexadecimal or decimal format.
//
// Recipe to build this code - assuming Rust is already installed
// 1. Change into a convenient folder. i.e. cd rust
// 2. Initialize sub-folder. i.e. cargo init fbd
// where fbd is the file byte display project
// 3. Change into fbd. i.e. cd fbd
// 4. Build and run the Hello, world! sample already available. i.e. cargo run
// 5. Copy this source file over the top of src/main.rs
// 6. Edit Cargo.toml to put clap = { version = "4.0", features = ["derive"]}
// on the line below [dependencies]
// 7. Build this file byte display utility. i.e. cargo build
// 8. Try it out by running the code on itself. e.g. cargo run -- -v target/debug/fbd
//
use clap::Parser;
use std::fs::File;
use std::io::{self, Read};
#[derive(Parser,Debug)]
#[command(
author = "Copilot AI & OFH",
version,
about = "Display the bytes in a file"
)]
struct Cli {
/// turns on optional verbose output
#[arg(short,long = "verbose")]
verbose: bool,
/// turns off output of index
#[arg(short,long = "no_index")]
no_index: bool,
/// turns on optional decimal output, instead of default hexadecimal output
#[arg(short,long = "decimal")]
decimal: bool,
/// the path to the file to display
path: std::path::PathBuf,
}
fn main() -> io::Result<()> {
// Get the command line arguments
let args = Cli::parse();
let mut bytes_per_line = 16; //if no decimal option then use 16
if args.decimal {
bytes_per_line = 10; //if decimal option is active then dump 10 bytes in a line
}
// Specify the file path from the command line argument
let metadata = match std::fs::metadata(&args.path) {
Ok(metadata) => metadata,
Err(err) => {
eprintln!("Error: Cannot get file size of '{}'", args.path.display());
eprintln!("Error: {} '{}'", err, args.path.display());
std::process::exit(1);
},
};
let file_size = metadata.len();
// Output warnings if file isn't between 1 - 1000 bytes in size
if file_size > 1000 {
println!(
"Warning: File named '{}' is larger than 1000 bytes.",
args.path.display()
);
println!("Info: Only displaying the first 1000 bytes.");
} else if file_size < 1 {
println!(
"Warning: File named '{}' has no data bytes to display (i.e. file size is {} bytes).",
args.path.display(), file_size
);
}
let mut file = File::open(&args.path)?;
let mut buffer = [0; 1000];
let bytes_read = file.read(&mut buffer)?;
for (i, byte) in buffer[..bytes_read].iter().enumerate() {
if i % bytes_per_line == 0 {
if i != 0 {
//start a new line unless this is the 1st line
println!();
}
// display the index unless the dont_display_index option is active
if !args.no_index {
if args.decimal {
print!("{:3}:", i); //print index number in decimal
} else {
print!("0x{:03x}:", i); //print index number in hexadecimal
}
}
}
if args.decimal {
print!(" {:3}", byte);
} else {
print!(" 0x{:02x}", byte);
}
}
println!();
if args.verbose {
println!(
"Info: Displayed {} bytes from file named '{}'.",
bytes_read, args.path.display()
);
}
Ok(())
}
# Valid UTF-8 Characters
English: This is a valid UTF-8 encoded sentence.
Greek: Αυτό είναι μια έγκυρη πρόταση κωδικοποιημένη σε UTF-8.
# Invalid UTF-8 Characters
Overlong Encoding: \xC0\xAF À¯
Invalid Byte: \xC3\x28 Ã(
Unexpected Continuation Byte: \xA0\xA1  ¡
Truncated Character Sequence: \xE2\x82 â‚
Invalid Code Point: \xF5\x90\x80\x80 õ€€
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment