use std::str;
use super::error::{Error, Result};
#[derive(PartialEq, Debug, Copy, Clone)]
pub enum TextFormat {
Text,
Binary = 2,
Octal = 8,
Decimal = 10,
Hex = 16
}
pub fn get_format_name(format: &TextFormat) -> &str {
match format {
TextFormat::Text => "Text",
TextFormat::Binary => "Binary",
TextFormat::Octal => "Octal",
TextFormat::Decimal => "Decimal",
TextFormat::Hex => "Hexadecimal"
}
}
pub fn get_next_format(format: &TextFormat) -> TextFormat {
match format {
TextFormat::Text => TextFormat::Binary,
TextFormat::Binary => TextFormat::Octal,
TextFormat::Octal => TextFormat::Decimal,
TextFormat::Decimal => TextFormat::Hex,
TextFormat::Hex => TextFormat::Text
}
}
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum NewlineFormat {
None,
CarriageReturn,
LineFeed,
Both
}
pub fn get_newline_format_name(format: &NewlineFormat) -> &str {
match format {
NewlineFormat::None => "None",
NewlineFormat::CarriageReturn => "Carriage return",
NewlineFormat::LineFeed => "Line feed",
NewlineFormat::Both => "Both"
}
}
pub fn get_next_newline_format(format: &NewlineFormat) -> NewlineFormat {
match format {
NewlineFormat::None => NewlineFormat::CarriageReturn,
NewlineFormat::CarriageReturn => NewlineFormat::LineFeed,
NewlineFormat::LineFeed => NewlineFormat::Both,
NewlineFormat::Both => NewlineFormat::None
}
}
pub fn bytes_from_hex_string(original_text: &str) -> Result<Vec<u8>> {
let mut text = original_text.replace("0x", "");
text = text.replace(" ", "");
bytes_from_radix_string(&text, 16)
}
pub fn bytes_from_binary_string(original_text: &str) -> Result<Vec<u8>> {
let mut text = original_text.replace("0b", "");
text = text.replace(" ", "");
bytes_from_radix_string(&text, 2)
}
pub fn bytes_from_octal_string(original_text: &str) -> Result<Vec<u8>> {
let mut text = original_text.replace(" ", "");
if text.starts_with('0') {
text.remove(0);
}
bytes_from_radix_string(&text, 8)
}
pub fn bytes_from_decimal_string(original_text: &str) -> Result<Vec<u8>> {
let text = original_text.replace(" ", "");
bytes_from_radix_string(&text, 10)
}
pub fn bytes_from_radix_string(text: &str, radix: u32) -> Result<Vec<u8>> {
let mut bytes: Vec<u8> = Vec::new();
let mut chars = text.chars().peekable();
while chars.peek().is_some() {
let chunk: String = chars.by_ref().take(2).collect();
match u8::from_str_radix(&chunk, radix) {
Ok(value) => bytes.push(value),
Err(e) => return Err(Error::from(e))
};
}
Ok(bytes)
}
pub fn radix_string(buffer: &[u8], text_format: &TextFormat) -> Result<String> {
if *text_format == TextFormat::Text {
return match str::from_utf8(buffer) {
Ok(text) => Ok(text.to_string()),
Err(e) => Err(Error::from(e))
};
}
let mut text = String::new();
for b in buffer {
match text_format {
TextFormat::Binary => text.push_str(format!("{:08b}", b).as_str()),
TextFormat::Octal => text.push_str(format!("{:04o}", b).as_str()),
TextFormat::Decimal => text.push_str(format!("{}", b).as_str()),
TextFormat::Hex => text.push_str(format!("{:02X}", b).as_str()),
_ => ()
};
}
Ok(text)
}
pub fn print_radix_string(buffer: &[u8], text_format: &TextFormat, row_entries: &mut u32) {
let max_row_entries = match text_format {
TextFormat::Binary => 10,
TextFormat::Octal => 16,
TextFormat::Decimal => 18,
TextFormat::Hex => 20,
_ => 0
};
for b in buffer {
match text_format {
TextFormat::Binary => print!("{:#b} ", b),
TextFormat::Octal => print!("{:#o} ", b),
TextFormat::Hex => print!("0x{:02X} ", b),
_ => print!("{}", b)
};
*row_entries += 1;
if max_row_entries > 0 && *row_entries > max_row_entries {
*row_entries = 0;
println!();
}
}
}
pub fn escape_text(text: String) -> String {
let mut text = text.replace("\\r", "\r");
text = text.replace("\\n", "\n");
text = text.replace("\\t", "\t");
text = text.replace("\\\"", "\"");
text
}
pub fn char_count(str: &String) -> usize {
str.char_indices().count()
}
pub fn byte_position_of_char(str: &String, index: usize) -> Option<usize> {
match str.char_indices().nth(index) {
Some((pos, _)) => Some(pos),
None => None
}
}
pub fn remove_char(str: &mut String, index: usize) {
if let Some(pos) = byte_position_of_char(str, index) {
str.remove(pos);
};
}
pub fn insert_char(str: &mut String, index: usize, c: char) {
if let Some(pos) = byte_position_of_char(str, index) {
str.insert(pos, c);
}
}
pub fn add_newline(text: &mut String, text_format: TextFormat, newline_format: NewlineFormat) {
if newline_format == NewlineFormat::None {
return;
}
let cr = match text_format {
TextFormat::Text => "\r",
TextFormat::Binary => "00001101",
TextFormat::Octal => "015",
TextFormat::Decimal => "13",
TextFormat::Hex => "0D"
};
let lf = match text_format {
TextFormat::Text => "\n",
TextFormat::Binary => "00001010",
TextFormat::Octal => "012",
TextFormat::Decimal => "10",
TextFormat::Hex => "0A"
};
if newline_format == NewlineFormat::CarriageReturn || newline_format == NewlineFormat::Both {
text.push_str(cr);
}
if newline_format == NewlineFormat::LineFeed || newline_format == NewlineFormat::Both {
text.push_str(lf);
}
}