fix a lot of stuff and generally make things better
This commit is contained in:
		
							parent
							
								
									20bac182c3
								
							
						
					
					
						commit
						86c3c6d62a
					
				
					 2 changed files with 52 additions and 38 deletions
				
			
		
							
								
								
									
										72
									
								
								src/lib.rs
									
										
									
									
									
								
							
							
						
						
									
										72
									
								
								src/lib.rs
									
										
									
									
									
								
							|  | @ -1,3 +1,7 @@ | |||
| #[cfg(test)] | ||||
| mod tests; | ||||
| 
 | ||||
| use std::collections::HashMap; | ||||
| use std::io::{BufReader, Read}; | ||||
| 
 | ||||
| /// Struct containing information about a file, without reading the actual data of the file.
 | ||||
|  | @ -25,8 +29,8 @@ pub struct FarFileInfo { | |||
| /// let file_a = FarFile::new_from_file(filename, buffer);
 | ||||
| ///
 | ||||
| /// let filename_b = "file_in_archive.jpg";
 | ||||
| /// let size_b = 12345;
 | ||||
| /// let offset_b = 67890;
 | ||||
| /// let size_b = 0;
 | ||||
| /// let offset_b = 0;
 | ||||
| /// let archive_buf = Vec::new(); // buffer containing the contents of the archive
 | ||||
| /// let file_b = FarFile::new_from_archive(filename_b, size_b, offset_b, &archive_buf);
 | ||||
| /// ```
 | ||||
|  | @ -40,18 +44,20 @@ pub struct FarFile { | |||
| ///
 | ||||
| /// Should be created by one of two ways:
 | ||||
| /// 1. Calling `FarArchive::new_from_files` if creating an archive from a list of FarFile structs
 | ||||
| /// 2. Calling `farlib::test(buffer)` if loading an archive from a file/buffer
 | ||||
| /// 2. Calling `read_archive(buffer)` if loading an archive from a file/buffer
 | ||||
| pub struct FarArchive { | ||||
|     pub version: u32, | ||||
|     pub file_count: u32, | ||||
|     pub file_list: Vec<FarFileInfo>, | ||||
|     pub file_data: Vec<FarFile>, | ||||
|     pub file_index: HashMap<String, usize>, | ||||
| } | ||||
| 
 | ||||
| impl FarFile { | ||||
|     /// Creates a new FarFile struct from an offset, size, and archive buffer.
 | ||||
|     pub fn new_from_archive(name: impl ToString, size: u32, offset: u32, original_file: &[u8]) -> FarFile { | ||||
|         let mut reader = BufReader::new(&original_file[offset as usize..(offset + size) as usize]); | ||||
|         const HEADER_SIZE: usize = 16; | ||||
|         let mut reader = BufReader::new(&original_file[HEADER_SIZE + offset as usize..HEADER_SIZE + (offset + size) as usize]); | ||||
|         let mut data = Vec::new(); | ||||
|         reader.read_to_end(&mut data).expect("Failed to read file data"); | ||||
|         FarFile { | ||||
|  | @ -81,32 +87,22 @@ impl FarArchive { | |||
|     /// use std::fs;
 | ||||
|     /// use libfar::*;
 | ||||
|     /// let mut file_list = Vec::new();
 | ||||
|     /// let file_names = fs::read_dir("files").expect("Failed to read directory");
 | ||||
|     /// for file in file_names {
 | ||||
|     ///     let file_name = file.clone().unwrap().path().file_name().unwrap().to_str().unwrap();
 | ||||
|     ///     let file_size = fs::metadata(file.clone()).expect("Failed to get file size").len();
 | ||||
|     ///     let file_data = fs::read(file.clone()).expect("Failed to read file");
 | ||||
|     ///     let file_obj = FarFile {
 | ||||
|     ///         name: file_name.to_string(),
 | ||||
|     ///         size: file_size as u32,
 | ||||
|     ///         data: file_data
 | ||||
|     ///     };
 | ||||
|     ///     file_list.push(file_obj);
 | ||||
|     /// }
 | ||||
|     ///
 | ||||
|     /// let archive = FarArchive::new_from_files(file_list);
 | ||||
|     /// ```
 | ||||
|     pub fn new_from_files(files: Vec<FarFile>) -> FarArchive { | ||||
|         let mut file_list = Vec::new(); | ||||
|         let mut file_data = Vec::new(); | ||||
|         let mut file_index = HashMap::new(); | ||||
|         let mut offset = 0; | ||||
|         for file in files { | ||||
|             offset += &file.size; | ||||
|         for (i, file) in files.into_iter().enumerate() { | ||||
|             file_list.push(FarFileInfo { | ||||
|                 name: file.name.clone(), | ||||
|                 size: file.size, | ||||
|                 offset, | ||||
|             }); | ||||
|             offset += &file.size; | ||||
|             file_index.insert(file.name.clone(), i); | ||||
|             file_data.push(file); | ||||
|         } | ||||
|         FarArchive { | ||||
|  | @ -114,6 +110,7 @@ impl FarArchive { | |||
|             file_count: file_list.len() as u32, | ||||
|             file_list, | ||||
|             file_data, | ||||
|             file_index, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -124,19 +121,20 @@ impl FarArchive { | |||
|     /// // buffer is a Vec<u8> containing the contents of a .far file
 | ||||
|     /// use std::fs;
 | ||||
|     /// use libfar::*;
 | ||||
|     /// let buffer = fs::read("test.far").expect("Failed to read file");
 | ||||
|     /// let test = test(&buffer);
 | ||||
|     /// let buffer = vec![]; // buffer containing the contents of a .far file
 | ||||
|     /// let test = read_archive(&buffer);
 | ||||
|     /// match test {
 | ||||
|     ///    Ok(archive) => {
 | ||||
|     ///        let archive = archive.load_file_data(&buffer);
 | ||||
|     ///    Ok(mut archive) => {
 | ||||
|     ///        archive.load_file_data(&buffer);
 | ||||
|     ///   }
 | ||||
|     ///   Err(e) => {
 | ||||
|     ///     panic!("test.far is not a valid archive: {}", e);
 | ||||
|     ///     panic!("test.far is not a valid archive: {:?}", e);
 | ||||
|     ///   }
 | ||||
|     /// }
 | ||||
|     /// ```
 | ||||
|     pub fn load_file_data(self, original_file: &[u8]) -> FarArchive { | ||||
|     pub fn load_file_data(&mut self, original_file: &[u8]) { | ||||
|         let mut new_file_data = Vec::new(); | ||||
|         let mut new_file_index = HashMap::new(); | ||||
|         for i in 0..self.file_list.len() { | ||||
|             new_file_data.push(FarFile::new_from_archive( | ||||
|                 self.file_list[i].name.clone(), | ||||
|  | @ -144,13 +142,10 @@ impl FarArchive { | |||
|                 self.file_list[i].offset, | ||||
|                 original_file, | ||||
|             )); | ||||
|             new_file_index.insert(self.file_list[i].name.clone(), i); | ||||
|         } | ||||
|         FarArchive { | ||||
|             version: self.version, | ||||
|             file_count: self.file_count, | ||||
|             file_list: self.file_list, | ||||
|             file_data: new_file_data, | ||||
|         } | ||||
|         self.file_data = new_file_data; | ||||
|         self.file_index = new_file_index; | ||||
|     } | ||||
| 
 | ||||
|     /// Creates a buffer representing the contents of a FarArchive struct.
 | ||||
|  | @ -164,9 +159,7 @@ impl FarArchive { | |||
|     /// use std::io::Write;
 | ||||
|     /// use libfar::*;
 | ||||
|     /// let archive: FarArchive = unimplemented!("Create a FarArchive struct");
 | ||||
|     /// let buffer = archive.to_vec();
 | ||||
|     /// let mut file = fs::File::create("test.far").expect("Failed to create file");
 | ||||
|     /// file.write_all(&buffer).expect("Failed to write to file");
 | ||||
|     /// let buffer = archive.to_vec(); // buffer containing the contents of the archive
 | ||||
|     /// ```
 | ||||
|     pub fn to_vec(self) -> Vec<u8> { | ||||
|         // write header
 | ||||
|  | @ -223,18 +216,18 @@ impl FarArchive { | |||
| /// ```
 | ||||
| /// use std::fs;
 | ||||
| /// use libfar::*;
 | ||||
| /// let buffer = fs::read("test.far").expect("Failed to read file");
 | ||||
| /// let test = test(&buffer);
 | ||||
| /// match test {
 | ||||
| /// let buffer = vec![]; // buffer containing the contents of a .far file
 | ||||
| /// let archive = read_archive(&buffer);
 | ||||
| /// match archive {
 | ||||
| ///     Ok(archive) => {
 | ||||
| ///         println!("test.far is a valid archive");
 | ||||
| ///     },
 | ||||
| ///     Err(e) => {
 | ||||
| ///         println!("test.far is not a valid archive: {}", e);
 | ||||
| ///         println!("test.far is not a valid archive: {:?}", e);
 | ||||
| ///     }
 | ||||
| /// }
 | ||||
| /// ```
 | ||||
| pub fn test(file: &[u8]) -> Result<FarArchive, FarError> { | ||||
| pub fn read_archive(file: &[u8]) -> Result<FarArchive, FarError> { | ||||
|     let mut reader = BufReader::new(file); | ||||
|     let mut magic = [0u8; 8]; | ||||
|     reader.read_exact(&mut magic).unwrap(); | ||||
|  | @ -251,6 +244,7 @@ pub fn test(file: &[u8]) -> Result<FarArchive, FarError> { | |||
|         file_count: files.len() as u32, | ||||
|         file_list: files, | ||||
|         file_data: vec![], | ||||
|         file_index: Default::default(), | ||||
|     }) | ||||
| } | ||||
| 
 | ||||
|  | @ -293,6 +287,7 @@ fn list_files(file: &[u8]) -> Result<Vec<FarFileInfo>, FarReadError> { | |||
| } | ||||
| 
 | ||||
| /// Enum representing possible errors when reading a FarArchive.
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub enum FarError { | ||||
|     /// The file is not a valid Far archive.
 | ||||
|     InvalidFile, | ||||
|  | @ -301,6 +296,7 @@ pub enum FarError { | |||
| } | ||||
| 
 | ||||
| /// Struct representing the location at which a FarArchive could no longer be read, and the associated error.
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub struct FarReadError { | ||||
|     pub offset: u32, | ||||
|     pub error: String, | ||||
|  |  | |||
							
								
								
									
										18
									
								
								src/tests.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								src/tests.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,18 @@ | |||
| use super::*; | ||||
| 
 | ||||
| #[test] | ||||
| fn can_read_our_own_archives() { | ||||
|     let file_data: Vec<u8> = vec![1,2,3,4,5]; | ||||
|     let file_name = "test_file"; | ||||
|     let file = FarFile::new_from_file(file_name, file_data.clone()); | ||||
| 
 | ||||
|     let archive = FarArchive::new_from_files(vec![file]); | ||||
|     let archive_data = archive.to_vec(); | ||||
| 
 | ||||
|     let mut archive = read_archive(&archive_data).expect("could not read archive"); | ||||
|     archive.load_file_data(&archive_data); | ||||
| 
 | ||||
|     let new_file = archive.file_index.get(file_name).expect("could not get file"); | ||||
|     let new_file = &archive.file_data[*new_file]; | ||||
|     assert_eq!(new_file.data, file_data); | ||||
| } | ||||
		Loading…
	
	Add table
		
		Reference in a new issue