1#![no_implicit_prelude]
21
22extern crate core;
23
24use core::default::Default;
25use core::ops::{Deref, DerefMut};
26use core::option::Option::{self, None, Some};
27use core::result::Result::{self, Ok};
28use core::{cmp, unreachable};
29
30use crate::fs::{BlockDevice, DeviceError, Storage};
31
32pub struct BlockBuffer {
33 buf: [Block; 4],
34 status: u8,
35}
36pub struct BlockEntryIter {
37 buf: BlockBuffer,
38 prev: Option<u32>,
39 last: u32,
40 count: u8,
41}
42#[repr(transparent)]
43pub struct BlockCache(Option<u32>);
44#[repr(transparent)]
45pub struct Block([u8; Block::SIZE]);
46
47impl Block {
48 pub const SIZE: usize = 0x200;
49
50 #[inline(always)]
51 pub const fn new() -> Block {
52 Block([0u8; Block::SIZE])
53 }
54
55 #[inline(always)]
56 pub fn clear(&mut self) {
57 self.0.fill(0)
58 }
59}
60impl BlockCache {
61 #[inline(always)]
62 pub fn new() -> BlockCache {
63 BlockCache(None)
64 }
65
66 #[inline(always)]
67 pub fn clear(&mut self) {
68 self.0.take();
69 }
70 #[inline]
71 pub fn read_single(&mut self, dev: &Storage<impl BlockDevice>, b: &mut Block, pos: u32) -> Result<(), DeviceError> {
72 match self.0.replace(pos) {
73 Some(v) if v != pos => dev.read_single(b, pos),
74 None => dev.read_single(b, pos),
75 _ => Ok(()),
76 }
77 }
78}
79impl BlockBuffer {
80 pub const COUNT: u8 = 0x4u8;
81 pub const SLOT_A: u8 = 0x0u8;
82 pub const SLOT_B: u8 = 0x1u8;
83 pub const SLOT_C: u8 = 0x2u8;
84 pub const SLOT_D: u8 = 0x3u8;
85
86 #[inline]
87 pub fn new() -> BlockBuffer {
88 BlockBuffer {
89 buf: [Block::new(), Block::new(), Block::new(), Block::new()],
90 status: 0u8,
91 }
92 }
93
94 #[inline]
95 pub fn is_dirty(&self, slot: u8) -> bool {
96 match slot % BlockBuffer::COUNT {
97 BlockBuffer::SLOT_A if self.status & 0x80 != 0 => true,
98 BlockBuffer::SLOT_B if self.status & 0x40 != 0 => true,
99 BlockBuffer::SLOT_C if self.status & 0x20 != 0 => true,
100 BlockBuffer::SLOT_D if self.status & 0x10 != 0 => true,
101 _ => false,
102 }
103 }
104 #[inline]
105 pub fn is_loaded(&self, slot: u8) -> bool {
106 match slot % BlockBuffer::COUNT {
107 BlockBuffer::SLOT_A if self.status & 0x8 != 0 => true,
108 BlockBuffer::SLOT_B if self.status & 0x4 != 0 => true,
109 BlockBuffer::SLOT_C if self.status & 0x2 != 0 => true,
110 BlockBuffer::SLOT_D if self.status & 0x1 != 0 => true,
111 _ => false,
112 }
113 }
114 #[inline]
115 pub fn buffer(&mut self, slot: u8) -> &mut [u8] {
116 match slot % BlockBuffer::COUNT {
117 BlockBuffer::SLOT_A => {
118 self.status |= 0x80;
119 &mut self.buf[0]
120 },
121 BlockBuffer::SLOT_B => {
122 self.status |= 0x40;
123 &mut self.buf[1]
124 },
125 BlockBuffer::SLOT_C => {
126 self.status |= 0x20;
127 &mut self.buf[2]
128 },
129 BlockBuffer::SLOT_D => {
130 self.status |= 0x10;
131 &mut self.buf[3]
132 },
133 _ => unreachable!(),
134 }
135 }
136 pub fn flush(&mut self, dev: &Storage<impl BlockDevice>, start: u32) -> Result<(), DeviceError> {
137 let s = self.status;
138 self.status = s & 0xF;
139 match s {
140 v if (v >> 4) == 0xF => return dev.write(&self.buf, start),
143 v if (v >> 4) == 0xE => return dev.write(&self.buf[0..3], start),
145 v if (v >> 4) == 0xC => return dev.write(&self.buf[0..2], start),
147 v if (v >> 4) == 0x3 => return dev.write(&self.buf[2..], start + 2),
149 v if (v >> 4) == 0x7 => return dev.write(&self.buf[1..], start + 1),
151 v if (v >> 4) == 0x6 => return dev.write(&self.buf[1..3], start + 1),
153 v if (v >> 4) == 1 => return dev.write_single(&self.buf[3], start + 3),
156 v if (v >> 4) == 2 => return dev.write_single(&self.buf[2], start + 2),
158 v if (v >> 4) == 4 => return dev.write_single(&self.buf[1], start + 1),
160 v if (v >> 4) == 8 => return dev.write_single(&self.buf[0], start),
162 _ => (),
163 }
164 if s & 0x80 != 0 {
166 dev.write_single(&self.buf[0], start)?;
167 }
168 if s & 0x40 != 0 {
170 dev.write_single(&self.buf[1], start + 1)?;
171 }
172 if s & 0x20 != 0 {
174 dev.write_single(&self.buf[2], start + 2)?;
175 }
176 if s & 0x10 != 0 {
178 dev.write_single(&self.buf[3], start + 3)?;
179 }
180 Ok(())
181 }
182 #[inline]
183 pub fn read(&mut self, dev: &Storage<impl BlockDevice>, count: u8, start: u32) -> Result<(), DeviceError> {
184 let n = cmp::min(count, BlockBuffer::COUNT);
185 dev.read(&mut self.buf[0..n as usize], start)?;
186 self.status = match n {
187 4 => 0xF,
188 3 => 0xE,
189 2 => 0xC,
190 1 => 0x8,
191 _ => unreachable!(),
192 };
193 Ok(())
194 }
195}
196impl BlockEntryIter {
197 #[inline(always)]
198 pub fn new(count: u8) -> BlockEntryIter {
199 BlockEntryIter {
200 count,
201 buf: BlockBuffer::new(),
202 prev: None,
203 last: 0u32,
204 }
205 }
206
207 #[inline(always)]
208 pub fn pos(&self) -> u32 {
209 self.prev.unwrap_or(0)
210 }
211 #[inline(always)]
212 pub fn is_loaded(&self) -> bool {
213 self.prev.is_none()
214 }
215 #[inline(always)]
216 pub fn in_scope(&self, pos: u32) -> bool {
217 (pos - self.pos()) < BlockBuffer::COUNT as u32
218 }
219 #[inline(always)]
220 pub fn buffer(&mut self, pos: u32) -> &mut [u8] {
221 self.buf.buffer((pos - self.pos()) as u8)
222 }
223 #[inline]
224 pub fn flush(&mut self, dev: &Storage<impl BlockDevice>) -> Result<(), DeviceError> {
225 if let Some(v) = self.prev.take() {
226 self.buf.flush(dev, v)?;
227 }
228 Ok(())
229 }
230 pub fn load(&mut self, dev: &Storage<impl BlockDevice>, pos: u32) -> Result<(), DeviceError> {
231 if self.last != 0 && pos < self.last {
232 return Ok(());
233 }
234 let i = cmp::min(self.count, BlockBuffer::COUNT);
235 self.buf.read(dev, i, pos)?;
236 self.last = self.last.saturating_add(i as u32);
237 self.count = self.count.saturating_sub(i);
238 self.prev = Some(pos);
239 Ok(())
240 }
241 #[inline]
242 pub fn load_and_flush(&mut self, dev: &Storage<impl BlockDevice>, pos: u32) -> Result<(), DeviceError> {
243 self.flush(dev)?;
244 self.load(dev, pos)
245 }
246}
247
248impl Deref for Block {
249 type Target = [u8];
250
251 #[inline(always)]
252 fn deref(&self) -> &[u8] {
253 &self.0
254 }
255}
256impl Default for Block {
257 #[inline]
258 fn default() -> Block {
259 Block([0u8; 0x200])
260 }
261}
262impl DerefMut for Block {
263 #[inline(always)]
264 fn deref_mut(&mut self) -> &mut [u8] {
265 &mut self.0
266 }
267}
268
269impl Default for BlockCache {
270 #[inline(always)]
271 fn default() -> BlockCache {
272 BlockCache(None)
273 }
274}
275
276impl Default for BlockBuffer {
277 #[inline]
278 fn default() -> BlockBuffer {
279 BlockBuffer::new()
280 }
281}