Skip to content

Commit

Permalink
Merge pull request #41 from vesuvisian/master
Browse files Browse the repository at this point in the history
Map "error" and "out of range" values to None
  • Loading branch information
All4Gis authored Apr 27, 2021
2 parents b536550 + cb54fe0 commit cfd1682
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 22 deletions.
14 changes: 10 additions & 4 deletions klvdata/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,6 @@ def linear_map(src_value, src_domain, dst_range):
it should always fall within the src_domain. If not, that's a problem.
"""
src_min, src_max, dst_min, dst_max = src_domain + dst_range
# assert(src_min <= src_value <= src_max)

if not (src_min <= src_value <= src_max):
raise ValueError
Expand All @@ -125,9 +124,13 @@ def linear_map(src_value, src_domain, dst_range):
return dst_value


def bytes_to_float(value, _domain, _range):
def bytes_to_float(value, _domain, _range, _error=None):
"""Convert the fixed point value self.value to a floating point value."""
src_value = int().from_bytes(value, byteorder='big', signed=(min(_domain) < 0))

if src_value == _error:
return None

return linear_map(src_value, _domain, _range)


Expand All @@ -142,15 +145,18 @@ def ieee754_bytes_to_fp(value):
else:
raise ValueError

def float_to_bytes(value, _domain, _range):
def float_to_bytes(value, _domain, _range, _error=None):
"""Convert the fixed point value self.value to a floating point value."""
# Some classes like MappedElement are calling float_to_bytes with arguments _domain
# and _range in the incorrect order. The naming convention used is confusing and
# needs addressed. Until that time, swap the order here as a workaround...
src_domain, dst_range = _range, _domain
src_min, src_max, dst_min, dst_max = src_domain + dst_range
length = int((dst_max - dst_min - 1).bit_length() / 8)
dst_value = linear_map(value, src_domain=src_domain, dst_range=dst_range)
if value is None:
dst_value = _error
else:
dst_value = linear_map(value, src_domain=src_domain, dst_range=dst_range)
return round(dst_value).to_bytes(length, byteorder='big', signed=(dst_min < 0))


Expand Down
15 changes: 11 additions & 4 deletions klvdata/elementparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ def __str__(self):

class MappedElementParser(ElementParser, metaclass=ABCMeta):
def __init__(self, value):
super().__init__(MappedValue(value, self._domain, self._range))
super().__init__(MappedValue(value, self._domain, self._range, self._error))

@property
@classmethod
Expand All @@ -147,18 +147,25 @@ def _domain(cls):
def _range(cls):
pass

@property
@classmethod
@abstractmethod
def _error(cls):
pass

class MappedValue(BaseValue):
def __init__(self, value, _domain, _range):
def __init__(self, value, _domain, _range, _error):
self._domain = _domain
self._range = _range
self._error = _error

try:
self.value = bytes_to_float(value, self._domain, self._range)
self.value = bytes_to_float(value, self._domain, self._range, self._error)
except TypeError:
self.value = value

def __bytes__(self):
return float_to_bytes(self.value, self._domain, self._range)
return float_to_bytes(self.value, self._domain, self._range, self._error)

def __str__(self):
if self.value is not None:
Expand Down
Loading

0 comments on commit cfd1682

Please sign in to comment.