1use std::str;
30use super::error::{Error, Result};
31
32#[derive(PartialEq, Debug, Copy, Clone)]
34pub enum TextFormat {
35 Text,
37 Binary = 2,
39 Octal = 8,
41 Decimal = 10,
43 Hex = 16
45}
46
47pub fn get_format_name(format: &TextFormat) -> &str {
49 match format {
50 TextFormat::Text => "Text",
51 TextFormat::Binary => "Binary",
52 TextFormat::Octal => "Octal",
53 TextFormat::Decimal => "Decimal",
54 TextFormat::Hex => "Hexadecimal"
55 }
56}
57
58pub fn get_next_format(format: &TextFormat) -> TextFormat {
62 match format {
63 TextFormat::Text => TextFormat::Binary,
64 TextFormat::Binary => TextFormat::Octal,
65 TextFormat::Octal => TextFormat::Decimal,
66 TextFormat::Decimal => TextFormat::Hex,
67 TextFormat::Hex => TextFormat::Text
68 }
69}
70
71#[derive(Debug, Copy, Clone, PartialEq)]
73pub enum NewlineFormat {
74 None,
75 CarriageReturn,
76 LineFeed,
77 Both
78}
79
80pub fn get_newline_format_name(format: &NewlineFormat) -> &str {
82 match format {
83 NewlineFormat::None => "None",
84 NewlineFormat::CarriageReturn => "Carriage return",
85 NewlineFormat::LineFeed => "Line feed",
86 NewlineFormat::Both => "Both"
87 }
88}
89
90pub fn get_next_newline_format(format: &NewlineFormat) -> NewlineFormat {
94 match format {
95 NewlineFormat::None => NewlineFormat::CarriageReturn,
96 NewlineFormat::CarriageReturn => NewlineFormat::LineFeed,
97 NewlineFormat::LineFeed => NewlineFormat::Both,
98 NewlineFormat::Both => NewlineFormat::None
99 }
100}
101
102pub fn bytes_from_hex_string(original_text: &str) -> Result<Vec<u8>> {
106 let mut text = original_text.replace("0x", "");
107 text = text.replace(" ", "");
108
109 bytes_from_radix_string(&text, 16)
110}
111
112pub fn bytes_from_binary_string(original_text: &str) -> Result<Vec<u8>> {
116 let mut text = original_text.replace("0b", "");
117 text = text.replace(" ", "");
118
119 bytes_from_radix_string(&text, 2)
120}
121
122pub fn bytes_from_octal_string(original_text: &str) -> Result<Vec<u8>> {
126 let mut text = original_text.replace(" ", "");
127 if text.starts_with('0') {
128 text.remove(0);
129 }
130
131 bytes_from_radix_string(&text, 8)
132}
133
134pub fn bytes_from_decimal_string(original_text: &str) -> Result<Vec<u8>> {
138 let text = original_text.replace(" ", "");
139
140 bytes_from_radix_string(&text, 10)
141}
142
143pub fn bytes_from_radix_string(text: &str, radix: u32) -> Result<Vec<u8>> {
147 let mut bytes: Vec<u8> = Vec::new();
148
149 let mut chars = text.chars().peekable();
150
151 while chars.peek().is_some() {
152 let chunk: String = chars.by_ref().take(2).collect();
154
155 match u8::from_str_radix(&chunk, radix) {
156 Ok(value) => bytes.push(value),
157 Err(e) => return Err(Error::from(e))
158 };
159 }
160
161 Ok(bytes)
162}
163
164pub fn radix_string(buffer: &[u8], text_format: &TextFormat) -> Result<String> {
166 if *text_format == TextFormat::Text {
167 return match str::from_utf8(buffer) {
168 Ok(text) => Ok(text.to_string()),
169 Err(e) => Err(Error::from(e))
170 };
171 }
172
173 let mut text = String::new();
174
175 for b in buffer {
176 match text_format {
177 TextFormat::Binary => text.push_str(format!("{:08b}", b).as_str()),
178 TextFormat::Octal => text.push_str(format!("{:04o}", b).as_str()),
179 TextFormat::Decimal => text.push_str(format!("{}", b).as_str()),
180 TextFormat::Hex => text.push_str(format!("{:02X}", b).as_str()),
181 _ => ()
182 };
183 }
184
185 Ok(text)
186}
187
188pub fn print_radix_string(buffer: &[u8], text_format: &TextFormat, row_entries: &mut u32) {
198 let max_row_entries = match text_format {
199 TextFormat::Binary => 10,
200 TextFormat::Octal => 16,
201 TextFormat::Decimal => 18,
202 TextFormat::Hex => 20,
203 _ => 0
204 };
205
206 for b in buffer {
207 match text_format {
208 TextFormat::Binary => print!("{:#b} ", b),
209 TextFormat::Octal => print!("{:#o} ", b),
210 TextFormat::Hex => print!("0x{:02X} ", b),
211 _ => print!("{}", b)
212 };
213
214 *row_entries += 1;
215 if max_row_entries > 0 && *row_entries > max_row_entries {
216 *row_entries = 0;
217
218 println!();
219 }
220 }
221}
222
223pub fn escape_text(text: String) -> String {
227 let mut text = text.replace("\\r", "\r");
228 text = text.replace("\\n", "\n");
229 text = text.replace("\\t", "\t");
230 text = text.replace("\\\"", "\"");
231
232 text
233}
234
235pub fn char_count(str: &String) -> usize {
237 str.char_indices().count()
238}
239
240pub fn byte_position_of_char(str: &String, index: usize) -> Option<usize> {
245 match str.char_indices().nth(index) {
246 Some((pos, _)) => Some(pos),
247 None => None
248 }
249}
250
251pub fn remove_char(str: &mut String, index: usize) {
253 if let Some(pos) = byte_position_of_char(str, index) {
254 str.remove(pos);
255 };
256}
257
258pub fn insert_char(str: &mut String, index: usize, c: char) {
260 if let Some(pos) = byte_position_of_char(str, index) {
261 str.insert(pos, c);
262 }
263}
264
265pub fn add_newline(text: &mut String, text_format: TextFormat, newline_format: NewlineFormat) {
269 if newline_format == NewlineFormat::None {
270 return;
271 }
272
273 let cr = match text_format {
274 TextFormat::Text => "\r",
275 TextFormat::Binary => "00001101",
276 TextFormat::Octal => "015",
277 TextFormat::Decimal => "13",
278 TextFormat::Hex => "0D"
279 };
280
281 let lf = match text_format {
282 TextFormat::Text => "\n",
283 TextFormat::Binary => "00001010",
284 TextFormat::Octal => "012",
285 TextFormat::Decimal => "10",
286 TextFormat::Hex => "0A"
287 };
288
289 if newline_format == NewlineFormat::CarriageReturn || newline_format == NewlineFormat::Both {
290 text.push_str(cr);
291 }
292
293 if newline_format == NewlineFormat::LineFeed || newline_format == NewlineFormat::Both {
294 text.push_str(lf);
295 }
296}