summaryrefslogtreecommitdiffstats
path: root/sploit/types/indextbl.py
diff options
context:
space:
mode:
Diffstat (limited to 'sploit/types/indextbl.py')
-rw-r--r--sploit/types/indextbl.py103
1 files changed, 103 insertions, 0 deletions
diff --git a/sploit/types/indextbl.py b/sploit/types/indextbl.py
new file mode 100644
index 0000000..4f57a59
--- /dev/null
+++ b/sploit/types/indextbl.py
@@ -0,0 +1,103 @@
+from abc import abstractmethod
+from collections.abc import Collection
+
+from sploit.types.index_entry import IndexEntry
+
+class IndexTbl(IndexEntry, Collection):
+ """
+ Abstract Index Table
+
+ IndexTbl is a common interface to an abstracted key-value store. The
+ storage mechanism as well as lookup semantics are defined by concrete
+ implementations. "Index" in this case is more akin to a directory index or
+ book index than a strictly numeric array index.
+
+ In general, concrete tables may store values of any or multiple different
+ types. In particular, tables should give special accommodation for values
+ of type IndexEntry. These objects usually represent "rich" versions of the
+ nominal data types the table expects to contain. Implementation repr()
+ methods usually also annotate which members are IndexEntries.
+
+ IndexTbl extends from IndexEntry, and so has a base value which represents
+ the "base index" of the table. The meaning of this depends on the
+ implementation. This inheritance also means that tables are generally
+ expected to be nestable.
+
+ IndexTbls allow indices to be accessed via attribute or subscript notation.
+ This is probably the key characteristic feature of the class. The class
+ namespace is kept as clean as possible to make for the fewest collisions
+ between index names and other (real) class attributes. Note that there are
+ abstract methods, required to be overridden, which implement the index
+ access. These methods are only called for normal indices, not the table
+ base.
+
+ Because this class overrides attribute access, normal automatic object
+ copying is broken. Because of this, implementations must also provide a
+ definition for the __copy__() method as well.
+ """
+
+ @abstractmethod
+ def __getindex__(self, index):
+ """Lookup and retrieve index value."""
+ raise NotImplementedError
+
+ @abstractmethod
+ def __setindex__(self, index, value):
+ """Lookup and set index value."""
+ raise NotImplementedError
+
+ @abstractmethod
+ def __delindex__(self, index):
+ """Lookup and delete index value."""
+ raise NotImplementedError
+
+ @abstractmethod
+ def __copy__(self):
+ """Create a copy of this IndexTbl object."""
+ raise NotImplementedError
+
+ def __contains__(self, index):
+ """Test the existence of the given index."""
+ try:
+ self.__getindex__(index)
+ except KeyError:
+ return False
+ else:
+ return True
+
+ # Attribute access methods
+
+ def __getattr__(self, index):
+ """Get value via attribute."""
+ return self[index]
+
+ def __setattr__(self, index, value):
+ """Set value via attribute."""
+ self[index] = value
+
+ def __delattr__(self, index):
+ """Delete value via attribute."""
+ del self[index]
+
+ # Subscript/item access methods
+
+ def __getitem__(self, index):
+ """Get value via subscript."""
+ if index == "base":
+ return self.base
+ return self.__getindex__(index)
+
+ def __setitem__(self, index, value):
+ """Set value via subscript."""
+ if index == "base":
+ object.__setattr__(self, "base", value)
+ elif index in dir(self):
+ raise KeyError(f"IndexTbl: Index is reserved: {index}")
+ else:
+ self.__setindex__(index, value)
+
+ def __delitem__(self, index):
+ """Delete value via subscript."""
+ if index == "base":
+ raise KeyError("IndexTbl: May not delete index: base")
+ self.__delindex__(index)