Пример #1
0
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
Пример #2
0
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)
Пример #3
0
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)
Пример #4
0
                    value = Data('\x00' * (length / 8 + 1), 0, length - len(value)) + value
                break
        else:
            if self.is_hidden:
                range = EntryValueType(self.entry).range(self._params)
                value = Ranges([range]).get_default()
                try:
                    length = self.entry.length.evaluate(context)
                except UndecodedReferenceError, ex:
                    # We don't know, and can't calculate, the length
                    if value == 0:
                        length = 0
                    else:
                        length = 8
                if self.entry.format in [Field.HEX, Field.BINARY]:
                    value = Data.from_int_big_endian(value, length)
                elif self.entry.format in [Field.TEXT]:
                    value = '\x00' * (length / 8 - 1) + chr(value)
            else:
                # We don't have a default for this entry
                raise MissingFieldException(self.entry)
        return value

    def _get_data(self, value, context):
        try:
            length = self.entry.length.evaluate(context)
            return encode_value(self.entry, value, length)
        except UndecodedReferenceError, ex:
            # We don't know how long this entry should be.
            if self.entry.format == self.entry.INTEGER:
                return _encode_unknown_variable_length_integer(self.entry, value, self._params)