129 lines
3.7 KiB
Rust
129 lines
3.7 KiB
Rust
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<u8> {
|
|
let mut n = 0;
|
|
let mut out: Vec<u8> = 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<HashMap<char, i32>, std::io::Error> {
|
|
let mut hashmap: HashMap<char, i32> = 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, String>) -> 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
|
|
}
|