use crate::byte_writer; use std::collections::HashMap; use std::fs::File; use std::io::prelude::*; use std::io::{Seek, SeekFrom}; use crate::node; use byte_writer::*; use node::*; const MAGIC_NUMBER: u8 = 128; pub fn read_n_bytes(file: &mut File, len: u32) -> Vec { let mut n = 0; let mut out: Vec = Vec::new(); let mut buffer = vec![0u8; 1]; while n < len { let read = file.read_exact(&mut buffer); match read { Ok(_c) => { out.push(buffer[0]); } Err(e) => { println!("Problem {}", e); } } n += 8; } out } pub fn save_action(txt: &str, file: &mut File) -> Result<(), std::io::Error> { file.seek(SeekFrom::Start(0))?; let map = get_map_string(txt)?; let nodes = nodes_at_vec(map); let mut tree = create_tree(nodes); let (str_bin, chars) = tree_to_string(&mut tree); let binary = string_to_binary(&str_bin); let len_tree: u32 = str_bin.len() as u32; let string: String = chars.iter().collect(); file.write_all(&MAGIC_NUMBER.to_be_bytes())?; file.write_all(&len_tree.to_be_bytes())?; file.write_all(&(string.len() as u32).to_be_bytes())?; file.write_all(&binary)?; file.write_all(string.as_bytes())?; let map = tree_to_map(&mut tree, true); let trad = body_to_bin(&txt, map); let trad_bin = string_to_binary(&trad); let len_body = trad.len() as u32; file.write_all(&len_body.to_be_bytes())?; file.write_all(&trad_bin)?; Ok(()) } pub fn get_map_string(txt: &str) -> Result, std::io::Error> { let mut hashmap: HashMap = HashMap::new(); for c in txt.chars() { let counter = hashmap.entry(c).or_insert(0); *counter += 1; } Ok(hashmap) } pub fn is_valid_file(file: &mut File) -> bool { let mut mag_buf = [0u8]; let _ = file.read_exact(&mut mag_buf); match u8::from_be_bytes(mag_buf) { 128 => true, _ => false, } } pub fn body_to_bin(txt: &str, map: HashMap) -> String { let mut translate = String::new(); for c in txt.chars() { if let Some(code) = map.get(&c.to_string()) { translate.push_str(code); } } translate } pub fn string_translate(file: &mut File) -> String { let mut buffer = [0u8; 4]; let _ = file.read_exact(&mut buffer); let len_tree = u32::from_be_bytes(buffer); let _ = file.read_exact(&mut buffer); let len_chars = u32::from_be_bytes(buffer) * 8; let tree_bin = read_n_bytes(file, len_tree); let tree_str = binary_to_string(tree_bin, len_tree); let chars_bin = read_n_bytes(file, len_chars); let chars_str = String::from_utf8(chars_bin).unwrap(); let root = read_tree(&tree_str, &chars_str.chars().collect()); let _ = file.read_exact(&mut buffer); let len_body = u32::from_be_bytes(buffer); translate_bin_char(file, root, len_body) } pub fn translate_bin_char(file: &mut File, root: Node, len: u32) -> String { let mut txt = Vec::new(); let mut translate = String::new(); let mut current = &root; let _ = file.read_to_end(&mut txt); let txt_str = binary_to_string(txt, len); for b in txt_str.chars() { match b { '1' => { if let Some(r) = ¤t.r { current = r; } } '0' => { if let Some(l) = ¤t.l { current = l; } } _ => { println!("Error !"); return String::new(); } } if let Some(v) = current.val { translate.push(v); current = &root; } } translate }