This commit is contained in:
Rob McMullen 2017-04-04 22:21:03 -07:00
parent 32d3e0de76
commit 281fea2038
2 changed files with 53 additions and 8 deletions

View File

@ -25,6 +25,34 @@ class SegmentParser(object):
self.segment_data = segment_data
self.parse()
def __getstate__(self):
"""Custom jsonpickle state save routine
This routine culls down the list of attributes that should be
serialized, and in some cases changes their format slightly so they
have a better mapping to json objects. For instance, json can't handle
dicts with integer keys, so dicts are turned into lists of lists.
Tuples are also turned into lists because tuples don't have a direct
representation in json, while lists have a compact representation in
json.
"""
state = dict()
for key in ['segments', 'strict']:
state[key] = getattr(self, key)
return state
def __setstate__(self, state):
"""Custom jsonpickle state restore routine
The use of jsonpickle to recreate objects doesn't go through __init__,
so there will be missing attributes when restoring old versions of the
json. Once a version gets out in the wild and additional attributes are
added to a segment, a default value should be applied here.
"""
print "UPDATING!!!!", state
self.__dict__.update(state)
print self.segments
def parse(self):
r = self.segment_data
self.segments.append(self.container_segment(r, 0, name=self.menu_name))

View File

@ -341,6 +341,9 @@ class DefaultSegment(object):
savers = [SegmentSaver]
can_resize_default = False
base_serializable_attributes = ['start_addr', 'error', 'name', 'verbose_name', 'page_size', 'map_width', 'uuid', 'can_resize']
extra_serializable_attributes = []
def __init__(self, rawdata, start_addr=0, name="All", error=None, verbose_name=None, memory_map=None):
self.start_addr = int(start_addr) # force python int to decouple from possibly being a numpy datatype
self.set_raw(rawdata)
@ -412,7 +415,9 @@ class DefaultSegment(object):
json.
"""
state = dict()
for key in ['start_addr', 'error', 'name', 'verbose_name', 'page_size', 'map_width', 'uuid', 'can_resize']:
for key in self.base_serializable_attributes:
state[key] = getattr(self, key)
for key in self.extra_serializable_attributes:
state[key] = getattr(self, key)
r = self.rawdata
state['_rawdata_bounds'] = list(r.byte_bounds_offset())
@ -434,8 +439,16 @@ class DefaultSegment(object):
self.memory_map = dict(state.pop('memory_map', []))
self.uuid = state.pop('uuid', uuid.uuid4())
self.can_resize = state.pop('can_resize', self.__class__.can_resize_default)
self.restore_missing_serializable_defaults()
self.__dict__.update(state)
def restore_missing_serializable_defaults(self):
"""Hook for the future when extra serializable attributes are added to
subclasses so new versions of the code can restore old saved files by
providing defaults to any missing attributes.
"""
pass
def reconstruct_raw(self, rawdata):
"""Reconstruct the pointers to the parent data arrays
@ -998,10 +1011,12 @@ class EmptySegment(DefaultSegment):
class ObjSegment(DefaultSegment):
extra_serializable_attributes = ['metadata_start', 'data_start']
def __init__(self, rawdata, metadata_start, data_start, start_addr, end_addr=0, name="", **kwargs):
DefaultSegment.__init__(self, rawdata, start_addr, name, **kwargs)
self.metadata_start = metadata_start
self.data_start = data_start
self.metadata_start = int(metadata_start)
self.data_start = int(data_start)
def __str__(self):
count = len(self)
@ -1025,13 +1040,15 @@ class SegmentedFileSegment(ObjSegment):
class RawSectorsSegment(DefaultSegment):
extra_serializable_attributes = ['boot_sector_size', 'num_boot_sectors', 'page_size', 'first_sector', 'num_sectors']
def __init__(self, rawdata, first_sector, num_sectors, count, boot_sector_size, num_boot_sectors, sector_size, **kwargs):
DefaultSegment.__init__(self, rawdata, 0, **kwargs)
self.boot_sector_size = boot_sector_size
self.num_boot_sectors = num_boot_sectors
self.page_size = sector_size
self.first_sector = first_sector
self.num_sectors = num_sectors
self.boot_sector_size = int(boot_sector_size)
self.num_boot_sectors = int(num_boot_sectors)
self.page_size = int(sector_size)
self.first_sector = int(first_sector)
self.num_sectors = int(num_sectors)
def __str__(self):
if self.num_sectors > 1: