Added some convenience functions: reverse index mapping, valid index check, and sorted comments list

This commit is contained in:
Rob McMullen 2016-04-13 16:12:23 -07:00
parent d246b7ca70
commit 7cb1c13703

View File

@ -61,6 +61,13 @@ class OrderWrapper(object):
class SegmentData(object): class SegmentData(object):
def __init__(self, data, style=None, comments=None, debug=False, order=None): def __init__(self, data, style=None, comments=None, debug=False, order=None):
"""Storage for raw data
order is a list into the base array's data; each item in the list is an
index of the base array. E.g. if the base array is the 20 element list
containing the data [100, 101, ... 119] and the order is [10, 0, 5, 2],
the segment data used is [110, 100, 105, 102]
"""
self.order = order self.order = order
self.is_indexed = order is not None self.is_indexed = order is not None
if self.is_indexed: if self.is_indexed:
@ -80,6 +87,7 @@ class SegmentData(object):
if comments is None: if comments is None:
comments = dict() comments = dict()
self.comments = comments self.comments = comments
self.reverse_index_mapping = None
def __len__(self): def __len__(self):
return len(self.data) return len(self.data)
@ -139,6 +147,19 @@ class SegmentData(object):
if self.is_indexed: if self.is_indexed:
return self[index] return self[index]
return SegmentData(self.data, self.style, self.comments, order=index) return SegmentData(self.data, self.style, self.comments, order=index)
def get_reverse_index(self, base_index):
"""Get index into this segment's data given the index into the base data
Raises IndexError if the base index doesn't map to anything in this
segment's data
"""
if not self.reverse_index_mapping:
self.reverse_index_mapping = dict([(k,i) for i,k in enumerate(self.order)])
try:
return self.reverse_index_mapping[base_index]
except KeyError:
raise IndexError("index %d not mapped in this segment" % base_index)
class DefaultSegment(object): class DefaultSegment(object):
@ -220,11 +241,24 @@ class DefaultSegment(object):
""" """
return self.rawdata.byte_bounds_offset() return self.rawdata.byte_bounds_offset()
def is_valid_index(self, i):
return i >= 0 and i < len(self)
def get_raw_index(self, i): def get_raw_index(self, i):
"""Get index into base array's raw data, given the index into this """Get index into base array's raw data, given the index into this
segment segment
""" """
return self.rawdata.get_raw_index(i) return self.rawdata.get_raw_index(i)
def get_index_from_base_index(self, base_index):
"""Get index into this array's data given the index into the base array
"""
r = self.rawdata
if r.is_indexed:
index = r.get_reverse_index(base_index)
else:
index = base_index - r.get_raw_index(0)
return index
def tostring(self): def tostring(self):
return self.data.tostring() return self.data.tostring()
@ -384,6 +418,9 @@ class DefaultSegment(object):
if rawindex in self.rawdata.comments: if rawindex in self.rawdata.comments:
del self.rawdata.comments[rawindex] del self.rawdata.comments[rawindex]
def get_sorted_comments(self):
return sorted([[k, v] for k, v in self.rawdata.comments.iteritems()])
def label(self, index, lower_case=True): def label(self, index, lower_case=True):
if lower_case: if lower_case:
return "%04x" % (index + self.start_addr) return "%04x" % (index + self.start_addr)