-
Notifications
You must be signed in to change notification settings - Fork 0
/
fs_rom.py
147 lines (105 loc) · 4.99 KB
/
fs_rom.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# Imports
import io
# Constants
__FILE_SYSTEM_CONTENT = [
["test.txt", "Hello world from a text file !"],
["test.py", "print(\"> Hello world from a fake .py file :)\")"],
["__init__.py", ""],
]
# Code
class ReadOnlyMemoryFileSystem:
label: str
readonly: bool
def __init__(self, label: str = "ROM", readonly: bool = False):
# Preliminary check
if len(label.encode('utf-8')) > 11:
raise OSError("The given label '{}' is longer than 11 bytes !".format(label))
self.label = label
self.readonly = readonly
def open(self, path: str, mode: str) -> Union[None, io.StringIO, io.BytesIO]:
# Preliminary checks
if not (mode in ["r", "rb", "rt"]):
raise OSError("The mode '{}' isn't supported".format(mode))
# Checking if the requested file exists
requested_content: Union[None, str] = None
for file_data in __FILE_SYSTEM_CONTENT:
# Checking the filename (The lstrip call is required !)
if file_data[0] == path.lstrip("/"):
requested_content = file_data[1]
break
if requested_content is None:
# The file wasn't found.
raise OSError("[Errno 2] No such file/directory: {}".format(path))
# Returning the file's content.
if mode.endswith("b"):
return io.BytesIO(requested_content)
else:
return io.StringIO(requested_content)
def stat(self, path: str) -> Tuple[int, int, int, int, int, int, int, int, int, int]:
# If the file system's root folder is request, we just say it exists.
if path == "/":
return (0x4000, 0, 0, 0, 0, 0, 0, 0, 0, 0)
# If we have any other path, we check if it is corresponds to one of the files provided by this file system.
requested_content: Union[None, str] = None
for file_data in __FILE_SYSTEM_CONTENT:
# Checking the filename (The lstrip call is required !)
if file_data[0] == path.lstrip("/"):
requested_content = file_data[1]
break
if not (requested_content is None):
# We found the file.
return (0x8000, 0, 0, 0, 0, 0, len(requested_content.encode("utf-8")), 0, 0, 0)
# Saying we don't have the requested file or folder.
raise OSError("[Errno 2] No such file/directory")
def ilistdir(self, path: str) -> Iterator[Union[Tuple[AnyStr, int, int, int], Tuple[AnyStr, int, int]]]:
# Returning the basic info of all the files in the root folder if requested.
if path == "/":
return iter([
(file_data[0], 0x8000, 0, len(file_data[1].encode("utf-8"))) for file_data in __FILE_SYSTEM_CONTENT
])
# An invalid path was given
raise OSError("[Errno 2] No such file/directory")
def statvfs(self, path: int) -> Tuple[int, int, int, int, int, int, int, int, int, int]:
# We return a tuple saying the following:
# * Saying the we have a FS with 512 bytes blocks(0) and fragments(1)
# * We have a total of 1024 blocks(3) => 1024 * 512 B => 512 KiB
# * We have 896 blocks available in total(4), and 896 for unprivileged users(5) => 448 KiB
# * We have 0 inodes in total(6), 0 inodes free(7), and 0 inodes for unprivileged users(8)
# * We don't have mount flags (9) => 0 (Not used in CircuitPython, see CPython's official documentation)
# * The maximum filename is 255(10)
return (512, 512, 1024, 896, 896, 0, 0, 0, 0, 255)
def mkfs(self) -> None:
return None
def mkdir(self, path: str) -> None:
return None
def rmdir(self, path: str) -> None:
return None
def mount(self, readonly: bool, mkfs: VfsFat) -> None:
return None
def umount(self) -> None:
return None
def remove(self) -> None:
# Warning:
# * The parameters to this method are unknown.
# * This method isn't documented at the time of writing.
return None
def chdir(self) -> None:
# Warning:
# * The parameters to this method are unknown.
# * This method isn't documented at the time of writing.
return None
def getcwd(self) -> None:
# Warning:
# * The parameters to this method are unknown.
# * This method isn't documented at the time of writing.
return None
def rename(self) -> None:
# Warning:
# * The parameters to this method are unknown.
# * This method isn't documented at the time of writing.
return None
def utime(self) -> None:
# Warning:
# * The parameters to this method are unknown.
# * This method isn't documented at the time of writing.
return None