def _encode_data(entry, value, length): if entry.format in (Field.BINARY, Field.HEX): assert isinstance(value, Data) result = value.copy() elif entry.format == Field.TEXT: assert isinstance(value, basestring) try: result = Data(value.encode(entry.encoding)) except UnicodeDecodeError: raise BadEncodingError(entry, value) elif entry.format == Field.INTEGER: assert isinstance(value, (int, long)) if length is None: raise FieldDataError(entry, "Unable to encode integer field " "without explicit length") assert entry.encoding in [Field.BIG_ENDIAN, Field.LITTLE_ENDIAN] if entry.encoding == Field.BIG_ENDIAN: result = Data.from_int_big_endian(value, length) else: result = Data.from_int_little_endian(value, length) elif entry.format == Field.FLOAT: assert entry.encoding in [Field.BIG_ENDIAN, Field.LITTLE_ENDIAN] assert isinstance(value, float) if entry.encoding == Field.BIG_ENDIAN: result = Data.from_float_big_endian(value, length) else: result = Data.from_float_little_endian(value, length) else: raise Exception("Unknown field format of '%s'!" % entry.format) return result
def check(self, entry, value, context): expected = self.limit.evaluate(context) if isinstance(expected, int): if int(value) != expected: raise ConstraintError(entry, int(value), '==', expected) elif isinstance(expected, Data): # We aren't checking the length here, only the value (for example, # the expected value for a variable length binary field will have # a different length than the actual). Only compare the bits that # are valid. length_diff = len(value) - len(expected) if length_diff > 0: # The expected value is shorter than the actual, so grow it. expected = Data('\x00' * (length_diff / 8 + 1), 0, length_diff) + expected elif length_diff < 0: # The expected value is longer than the actual, so shrink it. shorter = expected.copy() leading = shorter.pop(-length_diff) if not int(leading): # We can safely pop the leading bits. expected = shorter if value != expected: raise ConstraintError(entry, value, '==', expected) else: if value != expected: raise ConstraintError(entry, value, '==', expected)
def decode(self, input_file): # Encode aivdm data back into binary fragments = [] payload = self._aivdm[1][0] data = Data(input_file) while data: try: calculated_crc = self._get_crc(data) packet = decode(self._aivdm[0], data) if packet.checksum != calculated_crc: sys.stderr.write('Crc mismatch; expected %02X, but ' 'calculated %02X. Skipping packet.\n' % (packet.checksum, calculated_crc)) continue bits = encode(payload, list(ord(c.character) for c in packet.payload)) bits = bits.pop(len(bits) - packet.num_fill_bits) if len(fragments) == packet.fragment_number - 1: fragments.append(bits) if len(fragments) == packet.fragment_count: self._decode_ais(reduce(operator.add, fragments)) fragments = [] else: sys.stderr.write('Expected fragment number %i, got %i (of %i)\n' % ( len(fragments) + 1, packet.fragment_number, packet.fragment_count)) fragments = [] except DecodeError, ex: filename, line_number, column_number = self._aivdm[2][ex.entry] sys.stderr.write('%s[%i] - %s\n' % (filename, line_number, ex)) fragments = [] # Read to the next newline while data and data.pop(8).text('ascii') != '\n': pass
def convert_value(entry, value, length): """Convert a value to the correct type given the entry. For example, given an integer field, the string '43' would be converted to the number 43.""" temp_original = value if entry.format == Field.BINARY: try: if isinstance(value, Data): value = value.copy() elif isinstance(value, int) or isinstance(value, long): value = Data.from_int_big_endian(value, int(length)) else: value = Data.from_binary_text(_convert_type(entry, value, str)) except DataError, ex: raise FieldDataError(entry, ex)
def _encode_unknown_variable_length_integer(entry, value, params): # Integers require a specific length of encoding. If one is # not specified, we'll try several lengths until we find one # that fits. # # We only consider lengths that are in the range specified by # the entry length to avoid choosing an out of bounds length. assert params is not None, "Asked to encode a variable length field " \ "without parameters. This shouldn't happen." for length in get_valid_integer_lengths(entry, params): try: if entry.format != Field.INTEGER or entry.encoding == Field.BIG_ENDIAN: result = Data.from_int_big_endian(value, length) return result else: return Data.from_int_little_endian(value, length) except IntegerTooLongError: # The value didn't fit in this length... try the next # one. pass else: raise VariableIntegerTooLongError(entry, value)
from bdec.data import Data from bdec import DecodeError from bdec.spec.xmlspec import load from bdec.spec import load_specs from bdec.output.instance import decode from bdec.spec.references import References references = References() import sys with open(sys.argv[1], 'r') as pb: data = pb.read() spec = load_specs(["playback_faster.xml"])[0] try: values = decode(spec, Data(data)) except DecodeError, err: print 'Oh oh...', err raise for value in values: print(value) break print("done")
from bdec.data import Data from bdec import DecodeError from bdec.spec.xmlspec import load from bdec.spec import load_specs from bdec.output.instance import decode from bdec.spec.references import References references = References() def get_pb_line(fpath): with open(fpath) as f: for line in f: yield line count = 0 with open('playback.xml', 'r') as xml_f: spec = load_specs(["playback.xml"])[0] for line in get_pb_line(sys.argv[1]): try: values = decode(spec, Data(line)) except DecodeError, err: print 'Oh oh...', err raise count += 0 print(values) #import pdb #pdb.set_trace() #print(2) print("done", count)
For example, given an integer field, the string '43' would be converted to the number 43.""" temp_original = value if entry.format == Field.BINARY: try: if isinstance(value, Data): value = value.copy() elif isinstance(value, int) or isinstance(value, long): value = Data.from_int_big_endian(value, int(length)) else: value = Data.from_binary_text(_convert_type(entry, value, str)) except DataError, ex: raise FieldDataError(entry, ex) elif entry.format == Field.HEX: value = Data.from_hex(_convert_type(entry, value, str)) elif entry.format == Field.TEXT: value = _convert_type(entry, value, str) elif entry.format == Field.INTEGER: value = _convert_type(entry, value, int) elif entry.format == Field.FLOAT: value = _convert_type(entry, value, float) else: raise NotImplementedError(entry, value, context) return value class _ContextLength: def __init__(self, length, context): self.length = length self.context = context
temp_original = value if entry.format == Field.BINARY: try: if isinstance(value, Data): value = value.copy() elif isinstance(value, int) or isinstance(value, long): try: value = Data.from_int_big_endian(value, int(length)) except UndecodedReferenceError: value = _encode_unknown_variable_length_integer(entry, value, params) else: value = Data.from_binary_text(_convert_type(entry, value, str)) except DataError, ex: raise FieldDataError(entry, ex) elif entry.format == Field.HEX: value = Data.from_hex(_convert_type(entry, value, str)) elif entry.format == Field.TEXT: value = _convert_type(entry, value, str) elif entry.format == Field.INTEGER: value = _convert_type(entry, value, int) elif entry.format == Field.FLOAT: value = _convert_type(entry, value, float) else: raise NotImplementedError(entry, value, context) return value class _ContextLength: def __init__(self, length, context): self.length = length self.context = context