ext4_lwext4/blockdev/
memory.rs1use crate::error::Result;
4use crate::blockdev::traits::BlockDevice;
5
6pub struct MemoryBlockDevice {
11 data: Vec<u8>,
12 block_size: u32,
13 block_count: u64,
14}
15
16impl MemoryBlockDevice {
17 pub fn new(size: u64, block_size: u32) -> Self {
26 let block_count = size / block_size as u64;
27 let actual_size = block_count * block_size as u64;
28
29 Self {
30 data: vec![0u8; actual_size as usize],
31 block_size,
32 block_count,
33 }
34 }
35
36 pub fn with_size(size: u64) -> Self {
38 Self::new(size, 512)
39 }
40
41 pub fn from_vec(data: Vec<u8>, block_size: u32) -> Self {
50 assert!(
51 data.len() % block_size as usize == 0,
52 "data length must be aligned to block size"
53 );
54
55 let block_count = data.len() as u64 / block_size as u64;
56
57 Self {
58 data,
59 block_size,
60 block_count,
61 }
62 }
63
64 pub fn as_slice(&self) -> &[u8] {
66 &self.data
67 }
68
69 pub fn as_mut_slice(&mut self) -> &mut [u8] {
71 &mut self.data
72 }
73
74 pub fn into_vec(self) -> Vec<u8> {
76 self.data
77 }
78}
79
80impl BlockDevice for MemoryBlockDevice {
81 fn read_blocks(&self, block_id: u64, buf: &mut [u8]) -> Result<u32> {
82 let offset = (block_id * self.block_size as u64) as usize;
83 let len = buf.len();
84
85 if offset + len > self.data.len() {
86 return Err(crate::error::Error::Io(std::io::Error::new(
87 std::io::ErrorKind::UnexpectedEof,
88 "read past end of device",
89 )));
90 }
91
92 buf.copy_from_slice(&self.data[offset..offset + len]);
93 Ok((len / self.block_size as usize) as u32)
94 }
95
96 fn write_blocks(&mut self, block_id: u64, buf: &[u8]) -> Result<u32> {
97 let offset = (block_id * self.block_size as u64) as usize;
98 let len = buf.len();
99
100 if offset + len > self.data.len() {
101 return Err(crate::error::Error::Io(std::io::Error::new(
102 std::io::ErrorKind::UnexpectedEof,
103 "write past end of device",
104 )));
105 }
106
107 self.data[offset..offset + len].copy_from_slice(buf);
108 Ok((len / self.block_size as usize) as u32)
109 }
110
111 fn flush(&mut self) -> Result<()> {
112 Ok(())
114 }
115
116 fn block_size(&self) -> u32 {
117 self.block_size
118 }
119
120 fn block_count(&self) -> u64 {
121 self.block_count
122 }
123}
124
125#[cfg(test)]
126mod tests {
127 use super::*;
128
129 #[test]
130 fn test_memory_device_read_write() {
131 let mut dev = MemoryBlockDevice::new(4096, 512);
132
133 let write_buf = vec![0xAA; 512];
134 dev.write_blocks(0, &write_buf).unwrap();
135
136 let mut read_buf = vec![0u8; 512];
137 dev.read_blocks(0, &mut read_buf).unwrap();
138
139 assert_eq!(write_buf, read_buf);
140 }
141
142 #[test]
143 fn test_memory_device_block_count() {
144 let dev = MemoryBlockDevice::new(8192, 512);
145 assert_eq!(dev.block_count(), 16);
146 assert_eq!(dev.block_size(), 512);
147 }
148}