import os UID = os.getuid() GID = os.getgid() class ObjectFs: """A simple read-only file system based on Python objects. Interface of Directory objects: * join(name) returns a file or subdirectory objects * listdir() returns a list of names, or a list of (name, object) join() is optional if listdir() returns a list of (name, object). Alternatively, Directory objects can be plain dictionaries {name: object}. Interface of File objects: * size() returns the size * read() returns the data Alternatively, File objects can be plain strings. """ def __init__(self, root): self.paths = {'/': root} self.openfiles = {} def get(self, path): path = os.path.normpath(path) try: return self.paths[path] except KeyError: parentpath = os.path.dirname(path) parent = self.get(parentpath) if isinstance(parent, dict): p = parent[os.path.basename(path)] elif hasattr(parent, 'join'): p = parent.join(os.path.basename(path)) else: self.readdir(parentpath) p = self.paths[path] self.paths[path] = p return p def readdir(self, dir): d = self.get(dir) names = [] if isinstance(d, dict): entries = d.items() else: entries = d.listdir() for d1 in entries: if isinstance(d1, tuple): d1, o1 = d1 self.paths[os.path.join(dir, d1)] = o1 names.append(d1) if '..' not in names: names.insert(0, '..') if '.' not in names: names.insert(0, '.') return names def stat(self, filename): f = self.get(filename) if isinstance(f, str): sz = len(f) elif hasattr(f, 'size'): sz = f.size() else: sz = None if sz is None: return (0040500, 2, UID, GID, 512, 0, 0, 0) else: return (0100400, 1, UID, GID, sz, 0, 0, 0) def open(self, filename, mode): f = self.get(filename) self.openfiles[filename] = f, False def release(self, filename): del self.openfiles[filename] def read(self, filename, offset, count): fd, already_read = self.openfiles[filename] if not isinstance(fd, str) and not already_read: fd = fd.read() self.openfiles[filename] = fd, True return fd[offset:offset+count]