Skip to content

Commit

Permalink
Use DirEntry#size (#9)
Browse files Browse the repository at this point in the history
* Fix off by one line error

* Change create_file and create_dir to return DirEntry

* Implement DirEntry#size

* Use filesize to copy file

* Add example of long text

* Replace sleep after write in FS by wait in ATA
  • Loading branch information
vinc authored Jan 23, 2020
1 parent ad2ea50 commit 2de4861
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 27 deletions.
92 changes: 92 additions & 0 deletions dsk/tmp/alice.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
ALICE'S ADVENTURES IN WONDERLAND

Lewis Carroll


CHAPTER I. Down the Rabbit-Hole

Alice was beginning to get very tired of sitting by her sister on the
bank, and of having nothing to do: once or twice she had peeped into the
book her sister was reading, but it had no pictures or conversations in
it, 'and what is the use of a book,' thought Alice 'without pictures or
conversations?'

So she was considering in her own mind (as well as she could, for the
hot day made her feel very sleepy and stupid), whether the pleasure
of making a daisy-chain would be worth the trouble of getting up and
picking the daisies, when suddenly a White Rabbit with pink eyes ran
close by her.

There was nothing so VERY remarkable in that; nor did Alice think it so
VERY much out of the way to hear the Rabbit say to itself, 'Oh dear!
Oh dear! I shall be late!' (when she thought it over afterwards, it
occurred to her that she ought to have wondered at this, but at the time
it all seemed quite natural); but when the Rabbit actually TOOK A WATCH
OUT OF ITS WAISTCOAT-POCKET, and looked at it, and then hurried on,
Alice started to her feet, for it flashed across her mind that she had
never before seen a rabbit with either a waistcoat-pocket, or a watch
to take out of it, and burning with curiosity, she ran across the field
after it, and fortunately was just in time to see it pop down a large
rabbit-hole under the hedge.

In another moment down went Alice after it, never once considering how
in the world she was to get out again.

The rabbit-hole went straight on like a tunnel for some way, and then
dipped suddenly down, so suddenly that Alice had not a moment to think
about stopping herself before she found herself falling down a very deep
well.

Either the well was very deep, or she fell very slowly, for she had
plenty of time as she went down to look about her and to wonder what was
going to happen next. First, she tried to look down and make out what
she was coming to, but it was too dark to see anything; then she
looked at the sides of the well, and noticed that they were filled with
cupboards and book-shelves; here and there she saw maps and pictures
hung upon pegs. She took down a jar from one of the shelves as
she passed; it was labelled 'ORANGE MARMALADE', but to her great
disappointment it was empty: she did not like to drop the jar for fear
of killing somebody, so managed to put it into one of the cupboards as
she fell past it.

'Well!' thought Alice to herself, 'after such a fall as this, I shall
think nothing of tumbling down stairs! How brave they'll all think me at
home! Why, I wouldn't say anything about it, even if I fell off the top
of the house!' (Which was very likely true.)

Down, down, down. Would the fall NEVER come to an end! 'I wonder how
many miles I've fallen by this time?' she said aloud. 'I must be getting
somewhere near the centre of the earth. Let me see: that would be four
thousand miles down, I think--' (for, you see, Alice had learnt several
things of this sort in her lessons in the schoolroom, and though this
was not a VERY good opportunity for showing off her knowledge, as there
was no one to listen to her, still it was good practice to say it over)
'--yes, that's about the right distance--but then I wonder what Latitude
or Longitude I've got to?' (Alice had no idea what Latitude was, or
Longitude either, but thought they were nice grand words to say.)

Presently she began again. 'I wonder if I shall fall right THROUGH the
earth! How funny it'll seem to come out among the people that walk with
their heads downward! The Antipathies, I think--' (she was rather glad
there WAS no one listening, this time, as it didn't sound at all the
right word) '--but I shall have to ask them what the name of the country
is, you know. Please, Ma'am, is this New Zealand or Australia?' (and
she tried to curtsey as she spoke--fancy CURTSEYING as you're falling
through the air! Do you think you could manage it?) 'And what an
ignorant little girl she'll think me for asking! No, it'll never do to
ask: perhaps I shall see it written up somewhere.'

Down, down, down. There was nothing else to do, so Alice soon began
talking again. 'Dinah'll miss me very much to-night, I should think!'
(Dinah was the cat.) 'I hope they'll remember her saucer of milk at
tea-time. Dinah my dear! I wish you were down here with me! There are no
mice in the air, I'm afraid, but you might catch a bat, and that's very
like a mouse, you know. But do cats eat bats, I wonder?' And here Alice
began to get rather sleepy, and went on saying to herself, in a dreamy
sort of way, 'Do cats eat bats? Do cats eat bats?' and sometimes, 'Do
bats eat cats?' for, you see, as she couldn't answer either question,
it didn't much matter which way she put it. She felt that she was dozing
off, and had just begun to dream that she was walking hand in hand with
Dinah, and saying to her very earnestly, 'Now, Dinah, tell me the truth:
did you ever eat a bat?' when suddenly, thump! thump! down she came upon
a heap of sticks and dry leaves, and the fall was over.
2 changes: 2 additions & 0 deletions src/kernel/ata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,8 @@ impl Bus {
data.set_bits(8..16, buf[i * 2 + 1] as u16);
self.write_data(data);
}

while self.is_busy() {}
}
}

Expand Down
63 changes: 47 additions & 16 deletions src/kernel/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,12 @@ pub fn filename(pathname: &str) -> &str {
&pathname[i..n]
}

#[derive(Debug, Clone, Copy)]
#[derive(Clone)]
pub struct File {
addr: u32
name: String,
addr: u32,
size: u32,
dir: Dir, // TODO: Replace with `parent: Some(Dir)` and also add it to `Dir`
}

impl File {
Expand All @@ -39,7 +42,7 @@ impl File {
let filename = filename(pathname);
if let Some(dir) = Dir::open(dirname) {
if let Some(dir_entry) = dir.create_file(filename) {
return Some(Self { addr: dir_entry.addr });
return Some(dir_entry.to_file());
}
}
None
Expand All @@ -51,13 +54,17 @@ impl File {
if let Some(dir) = Dir::open(dirname) {
if let Some(dir_entry) = dir.find(filename) {
if dir_entry.is_file() {
return Some(Self { addr: dir_entry.addr });
return Some(dir_entry.to_file());
}
}
}
None
}

pub fn size(&self) -> usize {
self.size as usize
}

pub fn read(&self, buf: &mut [u8]) -> usize {
let buf_len = buf.len();
let mut addr = self.addr;
Expand All @@ -67,10 +74,7 @@ impl File {
let data = block.data();
let data_len = data.len();
for j in 0..data_len {
if i == buf_len {
return i;
}
if data[j] == 0 { // TODO: Use filesize
if i == buf_len || i == self.size() {
return i;
}
buf[i] = data[j];
Expand All @@ -84,8 +88,8 @@ impl File {
}

pub fn read_to_string(&self) -> String {
let mut buf: Vec<u8> = Vec::new();
buf.resize(2048, 0); // TODO: Use filesize
let mut buf: Vec<u8> = Vec::with_capacity(self.size());
buf.resize(self.size(), 0);
let bytes = self.read(&mut buf);
buf.resize(bytes, 0);
String::from_utf8(buf).unwrap()
Expand Down Expand Up @@ -131,6 +135,8 @@ impl File {
block.set_next(addr);
block.write();
}
self.size = i as u32;
self.dir.update_entry_size(&self.name, self.size);
Ok(())
}

Expand Down Expand Up @@ -176,7 +182,6 @@ impl Block {
let bus = 1; // TODO
let dsk = 0; // TODO
kernel::ata::write(bus, dsk, self.addr, &self.buf);
kernel::sleep::sleep(0.01);
}

pub fn alloc() -> Option<Self> {
Expand Down Expand Up @@ -285,18 +290,19 @@ impl BlockBitmap {
}
}

#[derive(Debug)]
#[derive(Clone)]
pub struct DirEntry {
dir: Dir,
kind: FileType,
addr: u32,
size: u32,
name: String,
}

impl DirEntry {
pub fn new(kind: FileType, addr: u32, size: u32, name: &str) -> Self {
pub fn new(dir: Dir, kind: FileType, addr: u32, size: u32, name: &str) -> Self {
let name = String::from(name);
Self { kind, addr, size, name }
Self { dir, kind, addr, size, name }
}

pub fn is_dir(&self) -> bool {
Expand All @@ -316,14 +322,21 @@ impl DirEntry {
}

pub fn to_dir(&self) -> Dir {
assert!(self.kind == FileType::Dir);
Dir { addr: self.addr }
}

pub fn to_file(&self) -> File {
assert!(self.kind == FileType::File);
File { name: self.name.clone(), addr: self.addr, size: self.size, dir: self.dir }
}

pub fn len(&self) -> usize {
1 + 4 + 4 + 1 + self.name.len()
}
}

#[derive(Clone, Copy)]
pub struct Dir {
addr: u32,
}
Expand Down Expand Up @@ -428,7 +441,7 @@ impl Dir {
}
read_dir.block.write();

Some(DirEntry::new(kind, entry_addr, entry_size, name))
Some(DirEntry::new(self.clone(), kind, entry_addr, entry_size, name))
}

// Deleting an entry is done by setting the entry address to 0
Expand Down Expand Up @@ -462,8 +475,25 @@ impl Dir {
Err(())
}

fn update_entry_size(&mut self, name: &str, size: u32) {
let mut read_dir = self.read();
for entry in &mut read_dir {
if entry.name == name {
let data = read_dir.block.data_mut();
let i = read_dir.data_offset - entry.len();
data[i + 5] = size.get_bits(24..32) as u8;
data[i + 6] = size.get_bits(16..24) as u8;
data[i + 7] = size.get_bits(8..16) as u8;
data[i + 8] = size.get_bits(0..8) as u8;
read_dir.block.write();
break;
}
}
}

pub fn read(&self) -> ReadDir {
ReadDir {
dir: self.clone(),
block: Block::read(self.addr),
data_offset: 0,
}
Expand All @@ -481,6 +511,7 @@ impl Dir {
}

pub struct ReadDir {
dir: Dir,
block: Block,
data_offset: usize,
}
Expand Down Expand Up @@ -537,7 +568,7 @@ impl Iterator for ReadDir {
continue;
}

return Some(DirEntry::new(entry_kind, entry_addr, entry_size, &entry_name));
return Some(DirEntry::new(self.dir, entry_kind, entry_addr, entry_size, &entry_name));
}

match self.block.next() {
Expand Down
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ fn main(boot_info: &'static BootInfo) -> ! {
include_file("/ini/boot.sh", include_str!("../dsk/ini/boot.sh"));
include_file("/ini/banner.txt", include_str!("../dsk/ini/banner.txt"));
include_file("/ini/passwords.csv", include_str!("../dsk/ini/passwords.csv"));
include_file("/tmp/alice.txt", include_str!("../dsk/tmp/alice.txt"));
loop {
user::shell::main(&["shell", "/ini/boot.sh"]);
}
Expand Down
5 changes: 4 additions & 1 deletion src/user/copy.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use alloc::vec::Vec;
use crate::{print, kernel, user};

pub fn main(args: &[&str]) -> user::shell::ExitCode {
Expand All @@ -15,7 +16,9 @@ pub fn main(args: &[&str]) -> user::shell::ExitCode {

if let Some(file_from) = kernel::fs::File::open(from) {
if let Some(mut file_to) = kernel::fs::File::create(to) {
let mut buf = [0u8; 2048];
let filesize = file_from.size();
let mut buf = Vec::with_capacity(filesize);
buf.resize(filesize, 0);
file_from.read(&mut buf);
match file_to.write(&buf) {
Ok(()) => {
Expand Down
21 changes: 11 additions & 10 deletions src/user/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,18 @@ impl Editor {
Self { file, pathname, lines, offset }
}

pub fn save(&self) -> user::shell::ExitCode {
if self.file.is_some() {
let mut contents = String::new();
let n = self.lines.len();
for i in 0..n {
contents.push_str(&self.lines[i]);
if i < n - 1 {
contents.push('\n');
}
pub fn save(&mut self) -> user::shell::ExitCode {
let mut contents = String::new();
let n = self.lines.len();
for i in 0..n {
contents.push_str(&self.lines[i]);
if i < n - 1 {
contents.push('\n');
}
self.file.unwrap().write(&contents.as_bytes()).unwrap();
}

if let Some(file) = &mut self.file {
file.write(&contents.as_bytes()).unwrap();
user::shell::ExitCode::CommandSuccessful
} else {
print!("Could not write to '{}'\n", self.pathname);
Expand Down

0 comments on commit 2de4861

Please sign in to comment.