Beispiel #1
0
    def decode(cls, encoded, taxonomy=None):
        """Decode a field from a byte array.

        Returns:
            (field, num_read).

            field: the field read from the byte array
            num_read: number of bytes this field took up

        Raises:
            Error: if there is not enough bytes in the array for the field.

        """
        assert len(encoded) >= 2

        # prefix
        pos = 0
        fixedwidth, variablewidth, has_ordinal, has_name = \
                prefix.decode_prefix(ord(encoded[pos]))
        pos += 1
        type_id = ord(encoded[pos])
        # TODO(jamesc) - need to handle user supplied registries
        field_type = DEFAULT_REGISTRY[type_id]
        pos += 1

        # ordinal
        ordinal = None
        if has_ordinal:
            ordinal = codecs.dec_short(encoded[pos:])
            pos += 2

        # name
        name = None
        if has_name:
            name_len = ord(encoded[pos])
            pos += 1  # length encoded as 1 byte
            name = codecs.dec_unicode(encoded[pos:pos + name_len])
            pos += name_len
        elif has_ordinal and taxonomy:
            name = taxonomy.get_name(ordinal)

        # value
        if fixedwidth:
            value = field_type.decoder(encoded[pos:pos +
                                               field_type.fixed_size])
            pos += field_type.fixed_size
        else:
            value_length = decode_value_length(encoded[pos:], variablewidth)

            pos += variablewidth
            if type_id == types.FUDGEMSG_TYPE_ID:
                value = fudgemsg.message.Message.decode(
                    encoded[pos:pos + value_length], taxonomy)
            else:
                value = field_type.decoder(encoded[pos:pos + value_length])
            pos += value_length

        field = Field(field_type, ordinal, name, value)
        return field, pos
Beispiel #2
0
    def decode(cls, encoded, taxonomy=None):
        """Decode a field from a byte array.

        Returns:
            (field, num_read).

            field: the field read from the byte array
            num_read: number of bytes this field took up

        Raises:
            Error: if there is not enough bytes in the array for the field.

        """
        assert len(encoded) >= 2

        # prefix
        pos = 0
        fixedwidth, variablewidth, has_ordinal, has_name = \
                prefix.decode_prefix(ord(encoded[pos]))
        pos += 1
        type_id = ord(encoded[pos])
        # TODO(jamesc) - need to handle user supplied registries
        field_type = DEFAULT_REGISTRY[type_id]
        pos += 1

        # ordinal
        ordinal = None
        if has_ordinal:
            ordinal = codecs.dec_short(encoded[pos:])
            pos += 2

        # name
        name = None
        if has_name:
            name_len = ord(encoded[pos])
            pos += 1 # length encoded as 1 byte
            name = codecs.dec_unicode(encoded[pos:pos+name_len])
            pos += name_len
        elif has_ordinal and taxonomy:
            name = taxonomy.get_name(ordinal)

        # value
        if fixedwidth:
            value = field_type.decoder(encoded[pos:pos+field_type.fixed_size])
            pos += field_type.fixed_size
        else:
            value_length = decode_value_length(encoded[pos:], variablewidth)

            pos += variablewidth
            if type_id == types.FUDGEMSG_TYPE_ID:
                value = fudgemsg.message.Message.decode(encoded[pos:pos+value_length], taxonomy)
            else:
                value = field_type.decoder(encoded[pos:pos+value_length])
            pos += value_length

        field = Field(field_type, ordinal, name, value)
        return field, pos
Beispiel #3
0
def decode_value_length(encoded, width):
    """Decode the length of a value from a
    var_width length.

    Arguments:
        encoded: The byte stream to read from
        width:  The number of bytes to read (1, 2, 4)

    Return:
        The decoded value length

    """
    assert width in (0, 1, 2, 4)

    if width == 0:
        return 0
    elif width == 1:
        return codecs.dec_byte(encoded[0])
    elif width == 2:
        return codecs.dec_short(encoded[0:2])
    else:
        return codecs.dec_int(encoded[0:4])
Beispiel #4
0
def decode_value_length(encoded, width):
    """Decode the length of a value from a
    var_width length.

    Arguments:
        encoded: The byte stream to read from
        width:  The number of bytes to read (1, 2, 4)

    Return:
        The decoded value length

    """
    assert width in (0, 1, 2, 4)

    if width == 0:
        return 0
    elif width == 1:
        return codecs.dec_byte(encoded[0])
    elif width == 2:
        return codecs.dec_short(encoded[0:2])
    else:
        return codecs.dec_int(encoded[0:4])