From 4c04aee9f8d854260261f8b971c3e71ea33810da Mon Sep 17 00:00:00 2001 From: Fredrik Tolf Date: Mon, 10 Apr 2023 18:02:12 +0200 Subject: [PATCH] Add a class-loading module. --- classfile/classpath.py | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 classfile/classpath.py diff --git a/classfile/classpath.py b/classfile/classpath.py new file mode 100644 index 0000000..2b82406 --- /dev/null +++ b/classfile/classpath.py @@ -0,0 +1,48 @@ +import os, zipfile +from . import file + +class dir(object): + def __init__(self, path): + self.path = path + + def get(self, name): + if '.' in name: + raise FileNotFoundError(name) + els = name.split('/') + fn = os.path.join(self.path, *els[:-1], els[-1] + ".class") + with open(fn, "rb") as fp: + return file.classfile.load(fp) + +class jar(object): + def __init__(self, filename): + self.filename = filename + + def get(self, name): + with zipfile.ZipFile(self.filename) as jar: + fn = name + ".class" + try: + fp = jar.open(fn, "r") + except KeyError: + raise FileNotFoundError(name) + with fp: + return file.classfile.load(fp) + +class path(object): + def __init__(self, *ents, caching=True): + self.ents = ents + self.cache = {} if caching else None + + def get(self, name): + if self.cache is not None and name in self.cache: + return self.cache[name] + for ent in self.ents: + try: + ret = ent.get(name) + break; + except FileNotFoundError: + pass + else: + raise FileNotFoundError(name) + if self.cache is not None: + self.cache[name] = ret + return ret -- 2.11.0