00001
00002 from collections import namedtuple
00003
00004
00005 class Fields(object):
00006 def __repr__(self):
00007 '''Get the namedtuple's repr, and replace the name with the current classname.
00008 This permits payloads to inherit from intermediary abstract payloads.'''
00009 parent_repr = super(Fields, self).__repr__()
00010 name, sep, fields = parent_repr.partition('_(')
00011 return "%s(%s" % (self.__class__.__name__, fields)
00012
00013 def hex(self):
00014 return ' '.join(map(lambda c: "%02X" % c, self.data()))
00015
00016 def check(self, fields):
00017 names = fields.split()
00018 return self.Check(self.__class__.__name__, names,
00019 map(lambda name: getattr(self, name), names))
00020
00021 class Check(object):
00022 def __init__(self, subjname, names, values):
00023 self.names = names
00024 self.values = values
00025 self.subjname = subjname
00026
00027 def _check(self, constraint, explanation):
00028 for name, value in zip(self.names, self.values):
00029 if constraint(value):
00030 e = "%s initialized with %s=%s: %s" % (self.subjname, name, repr(value), explanation)
00031 raise ValueError(e)
00032
00033 def range(self, lowerbound, upperbound):
00034 self._check(lambda x: x < lowerbound or x > upperbound,
00035 "Outside of allowed range [%0.1f,%0.1f]" %
00036 (lowerbound, upperbound))
00037
00038 def length(self, lowerbound, upperbound):
00039 self._check(lambda x: len(x) < lowerbound,
00040 "Length shorter than %d" % lowerbound)
00041 self._check(lambda x: len(x) > upperbound,
00042 "Length longer than %d" % upperbound)
00043
00044 def each(self):
00045 subnames = []
00046 subvalues = []
00047 for name, value in zip(self.names, self.values):
00048
00049
00050 self._check(lambda x: not isinstance(x, list), "Not a list")
00051 subnames += map(lambda index, subvalue: "%s[%s]" % (name, repr(index)), enumerate(value))
00052 subvalues += value
00053 return self.__class__(self.subjname, subnames, subvalues)
00054
00055 def ascii(self):
00056 self._check(lambda x: not all(ord(c) < 128 for c in x),
00057 "String contains non-ascii characters.")