summaryrefslogtreecommitdiff
path: root/python/binaryview.py
diff options
context:
space:
mode:
authorBrian Potchik <brian@vector35.com>2023-08-17 17:47:55 -0400
committerBrian Potchik <brian@vector35.com>2023-08-17 17:47:55 -0400
commit1174e544b0283bd30962d0a6a528af0aca43367c (patch)
tree786db6e7c4bc309bf54a5e4e957c95510516a90e /python/binaryview.py
parentdf645681ec6c8c5e6121450cccd3ba8ab773f97b (diff)
Ensure consistent lifetimes for UI-accessible BinaryView instances in Python.
Diffstat (limited to 'python/binaryview.py')
-rw-r--r--python/binaryview.py26
1 files changed, 26 insertions, 0 deletions
diff --git a/python/binaryview.py b/python/binaryview.py
index 6ba8d33f..4b1ca035 100644
--- a/python/binaryview.py
+++ b/python/binaryview.py
@@ -1911,6 +1911,30 @@ class BinaryView:
registered_view_type = None
_associated_data = {}
_registered_instances = []
+ _cached_instances = {}
+
+ @classmethod
+ def _cache_insert(cls, instance):
+ key = ctypes.addressof(instance.handle.contents)
+ if key not in cls._cached_instances:
+ cls._cached_instances[ctypes.addressof(instance.handle.contents)] = instance
+
+ @classmethod
+ def _cache_remove(cls, handle):
+ key = ctypes.addressof(handle.contents)
+ if key in cls._cached_instances:
+ cls._cached_instances.pop(key)
+
+ @classmethod
+ def _cache_contains(cls, handle):
+ return ctypes.addressof(handle.contents) in cls._cached_instances
+
+ def __new__(cls, file_metadata=None, parent_view=None, handle=None):
+ if handle:
+ key = ctypes.addressof(handle.contents)
+ if key in cls._cached_instances:
+ return cls._cached_instances[key]
+ return super().__new__(cls)
def __init__(
self, file_metadata: Optional['filemetadata.FileMetadata'] = None, parent_view: Optional['BinaryView'] = None,
@@ -1918,6 +1942,8 @@ class BinaryView:
):
if handle is not None:
_handle = handle
+ if self.__class__._cache_contains(handle):
+ return
if file_metadata is None:
self._file = filemetadata.FileMetadata(handle=core.BNGetFileForView(handle))
else: