slpm_file/
chunk_management.rs

1use std::convert::TryFrom;
2use std::fs::File;
3use std::io::Write;
4#[cfg(target_family = "unix")]
5use std::os::unix::fs::FileExt
6;
7#[cfg(target_family = "windows")]
8use std::os::windows::fs::FileExt;
9
10pub struct BufferReader {
11	/// Optional file handle for creating new instance
12	pub file: File,
13
14	/// File length for easier ownership handling and avoiding repetition
15	pub file_len: u64,
16
17	/// Offset of the seek-reader to carry over progress across runs
18	pub offset: u64,
19
20	/// Specifies in which size the file buffer was written in, mismatched sizes wont allow the reader to gather correct data
21	pub buffer_size: u64,
22}
23
24impl BufferReader {
25	/// # Panics
26	///
27	/// Panics when file lengths dont match
28	#[must_use]
29	pub fn read_next(&mut self) -> Vec<u8> {
30		let buffer_len: usize;
31		if self.offset + self.buffer_size < self.file_len {
32			buffer_len = usize::try_from(self.buffer_size).unwrap();
33		} else {
34			buffer_len = usize::try_from(self.file_len - self.offset).unwrap();
35		}
36		let mut buffer = vec![0; buffer_len];
37
38		#[cfg(target_family = "unix")]
39			self.file.read_exact_at(&mut buffer, self.offset).unwrap();
40
41		#[cfg(target_family = "windows")]
42			self.file.seek_read(&mut buffer, self.offset).unwrap();
43
44		self.offset += &self.buffer_size;
45		buffer
46	}
47
48	/// # Panics
49	///
50	/// Panics when file handle is invalid in any form
51	#[must_use]
52	pub fn write_next(mut self, buffer: &[u8]) -> Self {
53		#[cfg(target_family = "windows")]
54			self.file.seek_write(buffer, self.offset).unwrap();
55
56		#[cfg(target_family = "unix")]
57			self.file.write_all(buffer).unwrap();
58
59		self.offset += self.buffer_size;
60		self
61	}
62
63	#[must_use]
64	pub fn new(file: File, buffer_size: u64) -> Self {
65		#[allow(clippy::cast_possible_truncation)] // Cast has to be save, should not ever panic
66		Self {
67			file,
68			file_len: 0,
69			offset: 0,
70			buffer_size,
71		}
72	}
73}
74
75/// # Panics
76///
77/// WIP
78pub fn read_file_in_chunks_and_write() {
79	const BUFFER_SIZE: u64 = 100_000;
80	#[allow(clippy::cast_possible_truncation)] // Cast has to be save, should not ever panic
81	const BUFF_U: usize = BUFFER_SIZE as usize;
82	let file = File::open("./src/assets/100MB.bin").unwrap();
83	let mut new_file = File::create("./src/assets/new.bin").unwrap();
84
85	let file_len = file.metadata().unwrap().len();
86	let mut offset = 0;
87	let buff_count = file_len / BUFFER_SIZE;
88	let mut buffer = [0; BUFF_U];
89
90	for _ in 0..buff_count {
91		#[cfg(target_family = "unix")]
92			file.read_exact_at(&mut buffer, offset).unwrap();
93
94		#[cfg(target_family = "windows")]
95			file.seek_read(&mut buffer, offset).unwrap();
96
97		new_file.write_all(&buffer).unwrap();
98		offset += BUFFER_SIZE;
99	}
100
101	let remain = file_len - offset;
102	#[allow(clippy::cast_possible_truncation)] // Cast has to be save, should not ever panic
103		let mut buffer_last = vec![0; remain as usize];
104
105	#[cfg(target_family = "unix")]
106		file.read_exact_at(&mut buffer_last, offset).unwrap();
107
108	#[cfg(target_family = "windows")]
109		file.seek_read(&mut buffer_last, offset).unwrap();
110
111	new_file.write_all(&buffer_last).unwrap();
112}