1use axdriver::prelude::*;
2
3const BLOCK_SIZE: usize = 512;
4
5pub struct Disk {
7 block_id: u64,
8 offset: usize,
9 dev: AxBlockDevice,
10}
11
12impl Disk {
13 pub fn new(dev: AxBlockDevice) -> Self {
15 assert_eq!(BLOCK_SIZE, dev.block_size());
16 Self {
17 block_id: 0,
18 offset: 0,
19 dev,
20 }
21 }
22
23 pub fn size(&self) -> u64 {
25 self.dev.num_blocks() * BLOCK_SIZE as u64
26 }
27
28 pub fn position(&self) -> u64 {
30 self.block_id * BLOCK_SIZE as u64 + self.offset as u64
31 }
32
33 pub fn set_position(&mut self, pos: u64) {
35 self.block_id = pos / BLOCK_SIZE as u64;
36 self.offset = pos as usize % BLOCK_SIZE;
37 }
38
39 pub fn read_one(&mut self, buf: &mut [u8]) -> DevResult<usize> {
41 let read_size = if self.offset == 0 && buf.len() >= BLOCK_SIZE {
42 self.dev
44 .read_block(self.block_id, &mut buf[0..BLOCK_SIZE])?;
45 self.block_id += 1;
46 BLOCK_SIZE
47 } else {
48 let mut data = [0u8; BLOCK_SIZE];
50 let start = self.offset;
51 let count = buf.len().min(BLOCK_SIZE - self.offset);
52
53 self.dev.read_block(self.block_id, &mut data)?;
54 buf[..count].copy_from_slice(&data[start..start + count]);
55
56 self.offset += count;
57 if self.offset >= BLOCK_SIZE {
58 self.block_id += 1;
59 self.offset -= BLOCK_SIZE;
60 }
61 count
62 };
63 Ok(read_size)
64 }
65
66 pub fn write_one(&mut self, buf: &[u8]) -> DevResult<usize> {
68 let write_size = if self.offset == 0 && buf.len() >= BLOCK_SIZE {
69 self.dev.write_block(self.block_id, &buf[0..BLOCK_SIZE])?;
71 self.block_id += 1;
72 BLOCK_SIZE
73 } else {
74 let mut data = [0u8; BLOCK_SIZE];
76 let start = self.offset;
77 let count = buf.len().min(BLOCK_SIZE - self.offset);
78
79 self.dev.read_block(self.block_id, &mut data)?;
80 data[start..start + count].copy_from_slice(&buf[..count]);
81 self.dev.write_block(self.block_id, &data)?;
82
83 self.offset += count;
84 if self.offset >= BLOCK_SIZE {
85 self.block_id += 1;
86 self.offset -= BLOCK_SIZE;
87 }
88 count
89 };
90 Ok(write_size)
91 }
92}