1# test VFS functionality with a user-defined filesystem
2# also tests parts of uio.IOBase implementation
3
4import usys
5
6try:
7    import uio
8
9    uio.IOBase
10    import uos
11
12    uos.mount
13except (ImportError, AttributeError):
14    print("SKIP")
15    raise SystemExit
16
17
18class UserFile(uio.IOBase):
19    def __init__(self, mode, data):
20        assert isinstance(data, bytes)
21        self.is_text = mode.find("b") == -1
22        self.data = data
23        self.pos = 0
24
25    def read(self):
26        if self.is_text:
27            return str(self.data, "utf8")
28        else:
29            return self.data
30
31    def readinto(self, buf):
32        assert not self.is_text
33        n = 0
34        while n < len(buf) and self.pos < len(self.data):
35            buf[n] = self.data[self.pos]
36            n += 1
37            self.pos += 1
38        return n
39
40    def ioctl(self, req, arg):
41        print("ioctl", req, arg)
42        return 0
43
44
45class UserFS:
46    def __init__(self, files):
47        self.files = files
48
49    def mount(self, readonly, mksfs):
50        pass
51
52    def umount(self):
53        pass
54
55    def stat(self, path):
56        print("stat", path)
57        if path in self.files:
58            return (32768, 0, 0, 0, 0, 0, 0, 0, 0, 0)
59        raise OSError
60
61    def open(self, path, mode):
62        print("open", path, mode)
63        return UserFile(mode, self.files[path])
64
65
66# create and mount a user filesystem
67user_files = {
68    "/data.txt": b"some data in a text file",
69    "/usermod1.py": b"print('in usermod1')\nimport usermod2",
70    "/usermod2.py": b"print('in usermod2')",
71}
72uos.mount(UserFS(user_files), "/userfs")
73
74# open and read a file
75f = open("/userfs/data.txt")
76print(f.read())
77
78# import files from the user filesystem
79usys.path.append("/userfs")
80import usermod1
81
82# unmount and undo path addition
83uos.umount("/userfs")
84usys.path.pop()
85