(self, data)
return True
Check if the FEC-encoded data is decodable

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

        Note: This is a faster processing tailored specifically to validate the
            given FEC-encoded data. Unlike method decode(), it does not make
            any expensive memory copying. The rationale is that the data will
            not be ready to be decoded most of the time. Hence, it is better to
            check if decodable separately than to try and decode it in one go.
Check if the FEC-encoded data is decodable
Check if the FEC - encoded data is decodable
def _is_decodable(self, data):
        """Check if the FEC-encoded data is decodable

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

        Note: This is a faster processing tailored specifically to validate the
            given FEC-encoded data. Unlike method decode(), it does not make
            any expensive memory copying. The rationale is that the data will
            not be ready to be decoded most of the time. Hence, it is better to
            check if decodable separately than to try and decode it in one go.

        """

        # The encoded data must contain an integer number of FEC packets,
        # although it may not contain the full FEC-encoded object(s), given
        # that some parts of it may have been lost.
        if (len(data) % PKT_SIZE != 0):
            logger.debug("Not a properly formatted FEC-encoded object")
            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 header (don't process the payload here):
            s_byte = i_fec_pkt * PKT_SIZE  # starting byte
            e_byte = s_byte + HEADER_LEN  # ending byte

            # Unpack the metadata from the FEC header
            metadata = struct.unpack(HEADER_FORMAT, data[s_byte:e_byte])
            obj_id = metadata[0]
            chunk_id = metadata[2]
            obj_len = metadata[3]

            # Check if the chunk id is valid
            if (chunk_id >= MAX_FEC_CHUNKS):
                logger.debug("Invalid chunk id - likely not FEC-encoded")
                return False

            # All packets of a FEC object should bring the same message length
            if (obj_id not in fec_map):
                fec_map[obj_id] = {'len': obj_len, 'n_chunks': 0}
                # NOTE: keep the count of chunks here (not the actual chunks).
            elif (obj_len != fec_map[obj_id]['len']):
                logger.debug("Inconsistent message length on FEC packets - "
                             "likely not FEC-encoded")
                return False

            # All FEC packets should bring the same metadata information
            # regarding the number of FEC objects
            if (n_fec_objects is None):
                n_fec_objects = metadata[1]
            elif (n_fec_objects != metadata[1]):
                logger.debug("Inconsistent number of FEC objects - "
                             "likely not FEC-encoded")
                return False

            # Increment the count of FEC chunks
            fec_map[obj_id]['n_chunks'] += 1

        # The decoder needs all the FEC objects
        if (n_fec_objects > len(fec_map)):
            logger.debug("Insufficient number of FEC objects")
            return False

        # All FEC objects should contain enough FEC chunks
        ready = n_fec_objects * [False]
        for i_obj in range(n_fec_objects):
            n_chunks = ceil(fec_map[i_obj]['len'] / CHUNK_SIZE)
            ready[i_obj] = fec_map[i_obj]['n_chunks'] >= n_chunks

        if (not all(ready)):
            logger.debug("Insufficient number of FEC chunks")
            return False

        logger.debug("Object decodable")

        return True
def _is_decodable ( self , data ) : # The encoded data must contain an integer number of FEC packets, # although it may not contain the full FEC-encoded object(s), given # that some parts of it may have been lost. if ( len ( data ) % PKT_SIZE != 0 ) : logger . debug ( "Not a properly formatted FEC-encoded object" ) 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 header (don't process the payload here): s_byte = i_fec_pkt * PKT_SIZE # starting byte e_byte = s_byte + HEADER_LEN # ending byte # Unpack the metadata from the FEC header metadata = struct . unpack ( HEADER_FORMAT , data [ s_byte : e_byte ] ) obj_id = metadata [ 0 ] chunk_id = metadata [ 2 ] obj_len = metadata [ 3 ] # Check if the chunk id is valid if ( chunk_id >= MAX_FEC_CHUNKS ) : logger . debug ( "Invalid chunk id - likely not FEC-encoded" ) return False # All packets of a FEC object should bring the same message length if ( obj_id not in fec_map ) : fec_map [ obj_id ] = { 'len' : obj_len , 'n_chunks' : 0 } # NOTE: keep the count of chunks here (not the actual chunks). elif ( obj_len != fec_map [ obj_id ] [ 'len' ] ) : logger . debug ( "Inconsistent message length on FEC packets - " "likely not FEC-encoded" ) return False # All FEC packets should bring the same metadata information # regarding the number of FEC objects if ( n_fec_objects is None ) : n_fec_objects = metadata [ 1 ] elif ( n_fec_objects != metadata [ 1 ] ) : logger . debug ( "Inconsistent number of FEC objects - " "likely not FEC-encoded" ) return False # Increment the count of FEC chunks fec_map [ obj_id ] [ 'n_chunks' ] += 1 # The decoder needs all the FEC objects if ( n_fec_objects > len ( fec_map ) ) : logger . debug ( "Insufficient number of FEC objects" ) return False # All FEC objects should contain enough FEC chunks ready = n_fec_objects * [ False ] for i_obj in range ( n_fec_objects ) : n_chunks = ceil ( fec_map [ i_obj ] [ 'len' ] / CHUNK_SIZE ) ready [ i_obj ] = fec_map [ i_obj ] [ 'n_chunks' ] >= n_chunks if ( not all ( ready ) ) : logger . debug ( "Insufficient number of FEC chunks" ) return False logger . debug ( "Object decodable" ) return True