Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
O
Oblig3-myFS
Manage
Activity
Members
Labels
Plan
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
ii
INF113
24H
Oblig3-myFS
Commits
ce8f6d43
Commit
ce8f6d43
authored
5 months ago
by
David Grellscheid
Browse files
Options
Downloads
Patches
Plain Diff
Initial sketch of the task. Needs cleanup
parents
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
.gitignore
+2
-0
2 additions, 0 deletions
.gitignore
myfs.py
+173
-0
173 additions, 0 deletions
myfs.py
with
175 additions
and
0 deletions
.gitignore
0 → 100644
+
2
−
0
View file @
ce8f6d43
myfilesystem.fs
This diff is collapsed.
Click to expand it.
myfs.py
0 → 100644
+
173
−
0
View file @
ce8f6d43
import
sys
if
len
(
sys
.
argv
)
<
2
:
# Missing filesystem name. Assuming default myfilesystem.fs
backingfile
=
'
myfilesystem.fs
'
else
:
backingfile
=
sys
.
argv
[
1
]
# one could actually use a usb stick raw at "/dev/something"
# Data loss, and it'll need reformatting afterwards!
# create backingfile if needed
try
:
with
open
(
backingfile
,
'
x
'
):
pass
except
FileExistsError
:
pass
##########################################
##########################################
# file system parameters
TOTAL_SIZE
=
0x800
# 2kB
HEADER_START
=
0x0
COUNTER_BYTES
=
0x1
FILE_ENTRY_SIZE
=
0x10
FILE_BLOCK_SIZE
=
0x100
# file block 0 is the metainfo block
# line 0 of metainfo contains the number of files
# lines 1.. contain the filenames.
# line N has the filename of the file in Block N
# file blocks 1.. contain just the file contents
# use "xxd myfilesystem.fs" to look at the raw contents
# internal exception to signal no file
class
NoFile
(
Exception
):
pass
def
format
(
f
):
# 2kB filesystem
f
.
write
(
b
'
\0
'
*
TOTAL_SIZE
)
def
_get_num_files
(
f
):
f
.
seek
(
HEADER_START
)
bytes
=
f
.
read
(
COUNTER_BYTES
)
num
=
int
.
from_bytes
(
bytes
,
"
little
"
,
signed
=
False
)
return
num
def
_set_num_files
(
f
,
n
):
f
.
seek
(
HEADER_START
)
bytes
=
n
.
to_bytes
(
COUNTER_BYTES
,
"
little
"
,
signed
=
False
)
f
.
write
(
bytes
)
def
save
(
f
,
filename
,
content
):
num_existing
=
_get_num_files
(
f
)
new_fileno
=
num_existing
+
1
_set_num_files
(
f
,
new_fileno
)
# write filename in ftable next free entry, truncate if needed
f
.
seek
(
HEADER_START
+
FILE_ENTRY_SIZE
*
new_fileno
)
f
.
write
(
filename
.
encode
(
'
ascii
'
)[:
FILE_ENTRY_SIZE
])
# write content to file block, truncate if needed
f
.
seek
(
HEADER_START
+
FILE_BLOCK_SIZE
*
new_fileno
)
f
.
write
(
content
.
encode
(
'
ascii
'
)[:
FILE_BLOCK_SIZE
])
def
find_fileno
(
f
,
filename
):
N
=
_get_num_files
(
f
)
for
pos
in
range
(
0
,
N
):
f
.
seek
(
HEADER_START
+
FILE_ENTRY_SIZE
*
(
pos
+
1
))
name
=
f
.
read
(
FILE_ENTRY_SIZE
)
name
=
name
.
decode
(
"
ascii
"
).
strip
(
'
\0
'
)
if
name
==
filename
:
return
pos
else
:
print
(
f
"
File
{
filename
}
not found
"
,
file
=
sys
.
stderr
)
raise
NoFile
def
load
(
f
,
filename
):
fileno
=
find_fileno
(
f
,
filename
)
f
.
seek
(
HEADER_START
+
FILE_BLOCK_SIZE
*
(
fileno
+
1
))
content
=
f
.
read
(
FILE_BLOCK_SIZE
)
content
=
content
.
decode
(
"
ascii
"
).
strip
(
'
\0
'
)
# what if \0 is a valid part of the content?
return
content
def
copy
(
f
,
infile
,
outfile
):
try
:
content
=
load
(
f
,
infile
)
except
NoFile
:
return
save
(
f
,
outfile
,
content
)
def
remove
(
f
,
filename
):
fileno
=
find_fileno
(
f
,
filename
)
f
.
seek
(
HEADER_START
+
FILE_BLOCK_SIZE
*
(
fileno
+
1
))
f
.
write
(
b
'
\0
'
*
FILE_BLOCK_SIZE
)
f
.
seek
(
HEADER_START
+
FILE_ENTRY_SIZE
*
(
fileno
+
1
))
f
.
write
(
b
'
\0
'
*
FILE_ENTRY_SIZE
)
##########################
##########################
alice_sample
=
"""
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?
'
"""
if
__name__
==
"
__main__
"
:
print
()
print
(
"
*
"
*
60
)
print
(
f
"
* Use xxd
{
backingfile
}
to inspect contents
"
)
print
(
"
*
"
*
60
)
print
()
with
open
(
backingfile
,
'
r+b
'
)
as
f
:
format
(
f
)
save
(
f
,
"
hello.txt
"
,
"
Hello
"
)
save
(
f
,
"
alice.txt
"
,
alice_sample
)
alice_back
=
load
(
f
,
"
alice.txt
"
)
print
(
alice_back
)
copy
(
f
,
"
hello.txt
"
,
"
clone.txt
"
)
save
(
f
,
"
bye.txt
"
,
"
Bye Bye
"
)
copy
(
f
,
"
hello.txt
"
,
"
clone2.txt
"
)
remove
(
f
,
"
bye.txt
"
)
# ls(f)
# save(f, A)
# save(f, B)
# remove(f,A)
# save(f,C)
# C should re-use the free slot
# ls(f)
# error if FS full, filetable full, file too big, filename too big, etc.
# how to use the free file block after remove()?
# keep track of file sizes?
# binary file support?
#
# by file ending?
# make a simple REPL that understands the above commands
# NoFile should be handled in the REPL, REPL itself not crashing
# files bigger than 1 block
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment