use std::fs; use std::io; use std::io::BufRead; /* TRUCS MANQUANT * Verifier qu'il y a un nombre pair de caractere hexa dans la ligne correspondante d'une section du fichier source * Sinon on ne peut pas automatiquement remplir chaque octect car 2 hexa = 1 octet * OUBLI CONVERSIONS ADDR ET LEN QUI SONT AUSSI EN CARACTÈRES HEXA DS LE FICHIER */ /* FORMAT FICHIER.TXT Représentant la mémoire apres éxecution d'un prog * PC * SP * Section_1 * Section_2 * ... * ... * Section_n */ /* Chaque section se divise en 3 parties, sur 2 lignes de texte * addr ESPACE len * content */ //content est une suite hexadécimale //Section dans le fichier, champ String car informations proviennent d'un fichier txt struct SectionFormat{ addr: String, len: String, content: String, } //Section dans le programme struct Section{ addr: usize, // adresse dans la mémoire len: usize, // nombre d'octets de la donnée à addr content: Vec, // la donnée en question } /* * Voir si instanciation d'une structure deplace les valeurs "locales" à la méthode from, je sais plus .... */ impl Section{ fn from(section: &SectionFormat) -> Section { let mut content: Vec = Vec::new(); let addr: usize = string_hex_to_usize(§ion.addr); let len: usize = string_hex_to_usize(§ion.len); let mut tmp_a: char = ' '; let mut tmp_b: char = ' '; for (i, c) in section.content.chars().enumerate(){ if i%2 == 0 { tmp_a = c; } else { tmp_b = c; content.push(two_hex_to_u8(tmp_a,tmp_b)); } } Section{addr:addr, len:len, content:content} } fn print_Section(s: &Section){ println!("ADDR :: {}", s.addr); println!("LEN :: {}", s.len); println!("CONTENT :: {:?}", s.content); } } /* * Representation de l'etat de la mémoire (apres execution.... a confirmer), sous forme de sections */ struct Mem_Checker{ pc: usize, sp: usize, sections: Vec
, } impl Mem_Checker{ fn from(path: &String) -> Mem_Checker { let file = fs::File::open("test_file_section.txt").expect("Wrong filename"); let reader = io::BufReader::new(file); let mut pc: usize = 0; let mut sp: usize = 0; let mut sections: Vec
= Vec::new(); let mut tmp_addr_str: String = String::new(); let mut tmp_len_str: String = String::new(); for (i,line) in reader.lines().enumerate() { let current_line = line.unwrap(); if i == 0 { //Lecture de PC pc = string_hex_to_usize(¤t_line); } else if i == 1 { //Lecture SP sp = string_hex_to_usize(¤t_line); } else { //Lecture des sections if current_line.contains(' ') { //lecture ligne ADDR LEN let next_word_index = current_line.find(' ').unwrap(); tmp_addr_str = String::from(¤t_line[0..next_word_index]); tmp_len_str = String::from(¤t_line[next_word_index+1..]); } else { //lecture ligne CONTENT let section_f = SectionFormat{ addr: tmp_addr_str.clone(), len: tmp_len_str.clone(), content: current_line, }; sections.push(Section::from(§ion_f)); } } } Mem_Checker{pc:pc, sp:sp, sections:sections} } fn print_Mem_Checker(m_c: &Mem_Checker){ println!("PC :: {}", m_c.pc); println!("SP :: {}", m_c.sp); for(i,s) in m_c.sections.iter().enumerate() { println!("\nSection {}\n", i); Section::print_Section(&s); } } } fn string_hex_to_usize(s: &String) -> usize{ let max_pow = (s.len()-1) as u32; let mut ret_value: usize = 0; let base: usize = 16; for (i,c )in s.chars().enumerate(){ //println!("Current char :: {} :: Current pow :: {} ::", c, max_pow - (i as u32)); let tmp: usize = (one_hex_to_dec(c) as usize); ret_value += base.pow(max_pow - (i as u32))*tmp; } return ret_value; } /* * c doit etre un caractère hexadécimale */ fn one_hex_to_dec(c: char) -> u8 { match c { 'A' | 'a' => 10, 'B' | 'b' => 11, 'C' | 'c' => 12, 'D' | 'd' => 13, 'E' | 'e' => 14, 'F' | 'f' => 15, _ => { let ret : u8 = c.to_digit(10).unwrap() as u8; return ret; }, } } fn two_hex_to_u8(c1: char, c2: char) -> u8 { let a = one_hex_to_dec(c1); let b = one_hex_to_dec(c2); 16*a + b } /* * Juste pour voir si via BufReader les \n sont présent, apres test il s'avère que non * De toute facon on limitera d'une section la lecture par len */ fn test_show_sections_file(){ let file = fs::File::open("test_file_section.txt").expect("Wrong filename"); let reader = io::BufReader::new(file); for line in reader.lines() { //println!("Tailles de la ligne : {}", let current = line.unwrap(); //println!("Taille de la ligne : {}", current.len()); // En effet pas de \n dans chaque line, parfait println!("{}", ¤t); } } #[cfg(test)] mod tests { use super::*; #[test] fn test_create_Mem_Chercker(){ let path: String = "osef".to_string(); let m_c = Mem_Checker::from(&path); Mem_Checker::print_Mem_Checker(&m_c); } #[test] fn test_string_hex_to_usize(){ let s = String::from("AE1F20"); //println!("taille de string : {}", s.len()); let expected: usize = 11411232; let result = string_hex_to_usize(&s); assert_eq!(expected,result); } #[test] fn tmp_fct_read_file(){ println!("Reading A file \n"); test_show_sections_file(); } #[test] fn test_create_section_content(){ let section_format = SectionFormat{ addr: "0".to_string(), len: "0".to_string(), content: "00FF0AA0A5".to_string(), }; let section = Section::from(§ion_format); let mut expected_vec: Vec = Vec::new(); expected_vec.push(0u8); expected_vec.push(255u8); expected_vec.push(10u8); expected_vec.push(160u8); expected_vec.push(165u8); //println!("Vec from created section {:?}", §ion.content); //println!("Expected vec {:?}", &expected_vec); assert_eq!(section.content, expected_vec); } #[test] fn test_mod(){ let cond = (0%2) == 0; assert_eq!(true, cond); } #[test] fn test_mod_2(){ let cond = (1%2) == 1; assert_eq!(true, cond); } #[test] fn test_hex_1(){ let b = two_hex_to_u8('0', '0'); assert_eq!(0u8, b); } #[test] fn test_hex_2(){ let b = two_hex_to_u8('F', 'F'); assert_eq!(255u8, b); } #[test] fn test_hex_3(){ let b = two_hex_to_u8('0', 'A'); assert_eq!(10u8, b); } #[test] fn test_hex_4(){ let b = two_hex_to_u8('A', '0'); assert_eq!(160u8, b); } #[test] fn test_hex_5(){ let b = two_hex_to_u8('A', '5'); assert_eq!(165u8, b); } }