(self, data)
return bytes(decoded_data)
Decode a sequence of FEC packets spanning multiple FEC objects

        Args:
            data : FEC-encoded data, a bytes array with multiple FEC packets
                   serially.

        Returns:
            False if decoding fails. Otherwise, a bytes array with the decoded
            data (i.e., the original message).
Decode a sequence of FEC packets spanning multiple FEC objects
Decode a sequence of FEC packets spanning multiple FEC objects
def decode(self, data):
        """Decode a sequence of FEC packets spanning multiple FEC objects

        Args:
            data : FEC-encoded data, a bytes array with multiple FEC packets
                   serially.

        Returns:
            False if decoding fails. Otherwise, a bytes array with the decoded
            data (i.e., the original message).

        """

        # Check if the given FEC-encoded can decoded before anything to avoid
        # the more expensive message decoding that follows.
        if (not self._is_decodable(data)):
            return False

        # Process each packet and create a map of FEC objects and chunks
        n_fec_pkts = len(data) // PKT_SIZE
        fec_map = {}
        n_fec_objects = None
        for i_fec_pkt in range(n_fec_pkts):
            # Byte range of the next FEC packet:
            s_byte = i_fec_pkt * PKT_SIZE  # starting byte
            e_byte = (i_fec_pkt + 1) * PKT_SIZE  # ending byte
            fec_pkt = data[s_byte:e_byte]

            # Unpack the metadata from the FEC header
            obj_id, n_fec_objects, chunk_id, obj_len = struct.unpack(
                HEADER_FORMAT, fec_pkt[:HEADER_LEN])

            # Save the FEC object length and the FEC chunk
            if (obj_id not in fec_map):
                fec_map[obj_id] = {'len': obj_len, 'chunks': {}}

            fec_map[obj_id]['chunks'][chunk_id] = fec_pkt[HEADER_LEN:]

        logger.debug("Processed chunks: {} / Processed objects: {}".format(
            n_fec_pkts, len(fec_map)))

        # Decode multiple objects and concatenate the decoded data
        decoded_data = bytearray()
        for i_obj in range(n_fec_objects):
            decoded_data += self._decode_obj(
                fec_map[i_obj]['len'], list(fec_map[i_obj]['chunks'].values()),
                list(fec_map[i_obj]['chunks'].keys()))

        return bytes(decoded_data)
def decode ( self , data ) : # Check if the given FEC-encoded can decoded before anything to avoid # the more expensive message decoding that follows. if ( not self . _is_decodable ( data ) ) : return False # Process each packet and create a map of FEC objects and chunks n_fec_pkts = len ( data ) // PKT_SIZE fec_map = { } n_fec_objects = None for i_fec_pkt in range ( n_fec_pkts ) : # Byte range of the next FEC packet: s_byte = i_fec_pkt * PKT_SIZE # starting byte e_byte = ( i_fec_pkt + 1 ) * PKT_SIZE # ending byte fec_pkt = data [ s_byte : e_byte ] # Unpack the metadata from the FEC header obj_id , n_fec_objects , chunk_id , obj_len = struct . unpack ( HEADER_FORMAT , fec_pkt [ : HEADER_LEN ] ) # Save the FEC object length and the FEC chunk if ( obj_id not in fec_map ) : fec_map [ obj_id ] = { 'len' : obj_len , 'chunks' : { } } fec_map [ obj_id ] [ 'chunks' ] [ chunk_id ] = fec_pkt [ HEADER_LEN : ] logger . debug ( "Processed chunks: {} / Processed objects: {}" . format ( n_fec_pkts , len ( fec_map ) ) ) # Decode multiple objects and concatenate the decoded data decoded_data = bytearray ( ) for i_obj in range ( n_fec_objects ) : decoded_data += self . _decode_obj ( fec_map [ i_obj ] [ 'len' ] , list ( fec_map [ i_obj ] [ 'chunks' ] . values ( ) ) , list ( fec_map [ i_obj ] [ 'chunks' ] . keys ( ) ) ) return bytes ( decoded_data )