diff --git a/README.md b/README.md index 048bd35..d7df67b 100644 --- a/README.md +++ b/README.md @@ -1 +1,9 @@ # Œufman + +## Arrangement in the file +``` +Size header -> u32 +Size tree -> u32 +Tree -> {<1, Node>, <0, leaf>} +``` + diff --git a/src/byte_writer.rs b/src/byte_writer.rs index a2f3afa..3bf4803 100644 --- a/src/byte_writer.rs +++ b/src/byte_writer.rs @@ -28,10 +28,11 @@ pub fn string_to_binary(bits: &str) -> Vec { bytes } -pub fn binary_to_string(bytes: Vec, len: u8) -> String { +pub fn binary_to_string(bytes: Vec, len: u32) -> String { let mut binary = String::new(); //bytes.reverse(); let mut word = String::new(); + let mut n = 0; for b in &bytes { let current = *b; for i in 0..8 { @@ -43,9 +44,10 @@ pub fn binary_to_string(bytes: Vec, len: u8) -> String { } binary = binary + &word; word = String::new(); - } - for _ in 0..8 - len { - binary.pop(); + n += 1; + if n >= len { + break; + } } binary diff --git a/src/main.rs b/src/main.rs index 2edfd92..c99e989 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,32 +7,105 @@ mod byte_writer; mod node; use byte_writer::{binary_to_string, string_to_binary}; -use node::{Node, read_tree, tree_to_string}; +use node::{Node, create_tree, read_tree, tree_to_string}; fn main() -> std::io::Result<()> { let args: Vec = env::args().collect(); - // Afficher les arguments println!("Arguments passés au programme :"); for (index, arg) in args.iter().enumerate() { println!("Argument {}: {}", index, arg); } - let file = File::open("test.txt")?; + let request = args.get(1).map(|s| s.to_string()); + + match request { + Some(r) => { + if r == "compress" || r == "c" { + let file_name = args.get(2).map(|s| s.to_string()); + match file_name { + Some(f) => { + let to_compress = File::open(&f)?; + let mut after_compression = File::create(f + ".oeuf")?; + let map = get_map_file(&to_compress)?; + 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(); + after_compression.write_all( + &(len_tree + (string.as_bytes().len() as u32) * 8).to_be_bytes(), + )?; + after_compression.write_all(&len_tree.to_be_bytes())?; + after_compression.write_all(&binary)?; + after_compression.write_all(string.as_bytes())?; + } + None => { + println!("No file name!"); + display_options(); + } + } + } else if r == "print" || r == "p" { + let file_name = args.get(2).map(|s| s.to_string()); + match file_name { + Some(f) => { + let mut to_print = File::open(f)?; + let mut buffer = [0u8; 4]; + to_print.read_exact(&mut buffer)?; + eprintln!("buffer = {:?}", buffer); + let mut len_head = u32::from_be_bytes(buffer); + to_print.read_exact(&mut buffer)?; + eprintln!("buffer = {:?}", buffer); + let len_tree = u32::from_be_bytes(buffer); + eprintln!("len_head = {:?}", len_head); + eprintln!("len_tree = {:?}", len_tree); + + let len_chars = len_head - len_tree; + eprintln!("len_chars = {:?}", len_chars); + let tree_bin = read_n_bytes(&mut to_print, len_tree); + eprintln!("tree_bin = {:?}", tree_bin); + let tree_str = binary_to_string(tree_bin, len_tree); + eprintln!("tree_str = {:?}", tree_str); + + let chars_bin = read_n_bytes(&mut to_print, len_chars); + eprintln!("chars_bin = {:?}", &chars_bin); + let chars_str = String::from_utf8(chars_bin).unwrap(); + eprintln!("tree_str = {:?}", tree_str); + eprintln!("chars_str = {:?}", chars_str); + //let mut root = read_tree(&tree_str, &chars_str.chars().collect()); + //let txt = tree_to_string(&mut root); + //eprintln!("txt = {:?}", txt); + } + None => { + println!("No file name!"); + display_options(); + } + } + } + } + None => { + println!("No argument to deal with !"); + display_options(); + } + } + + //let file = File::open("test.txt")?; //let mut file2 = File::open("fo.txt")?; - let map = get_map_file(file).expect("Failed to load!"); - let vec = nodes_at_vec(map); - let mut root = node::create_tree(vec); + //let map = get_map_file(file).expect("Failed to load!"); + //let vec = nodes_at_vec(map); + //let mut root = node::create_tree(vec); //eprintln!("root.n = {:#?}", root.l.unwrap().n); - let txt = tree_to_string(&mut root); + //let txt = tree_to_string(&mut root); //eprintln!("txt = {:?}", txt); + /* let mut root2 = read_tree(&txt.0, &txt.1); eprintln!( "root2.l.unwrap().l.unwrap().val = {:?}", root2.l.unwrap().l.unwrap().val ); - + */ /* let binary = "101100001"; let mut v = string_to_binary(binary); @@ -70,7 +143,13 @@ fn main() -> std::io::Result<()> { Ok(()) } -fn get_map_file(mut file: File) -> Result, std::io::Error> { +fn display_options() { + println!("compress | c To compress a file."); + println!("uncompress | u To compress a file."); + println!("print | p To print a file compressed."); +} + +fn get_map_file(mut file: &File) -> Result, std::io::Error> { let mut hashmap: HashMap = HashMap::new(); let mut contents = String::new(); file.read_to_string(&mut contents)?; @@ -93,3 +172,18 @@ fn nodes_at_vec(map: HashMap) -> Vec { nodes.sort_by(|a, b| a.val.cmp(&b.val)); nodes } + +fn read_n_bytes(file: &mut File, len: u32) -> Vec { + let mut n = 0; + let mut out: Vec = Vec::new(); + let mut buffer = [0u8, 1]; + loop { + let _ = file.read_exact(&mut buffer); + out.push(buffer[0]); + n += 8; + if n >= len { + break; + } + } + out +} diff --git a/test.txt.oeuf b/test.txt.oeuf new file mode 100644 index 0000000..5c823a0 Binary files /dev/null and b/test.txt.oeuf differ