/// Reads all the metadata blocks.
Reads all the metadata blocks.
Reads all the metadata blocks .
fn read_all_metadata_blocks(flac: &mut FlacReader) -> Result<()> {
    let mut metadata_builder = MetadataBuilder::new();
    loop {
        let header = MetadataBlockHeader::read(&mut flac.reader)?;
        // Create a scoped bytestream to error if the metadata block read functions exceed the
        // stated length of the block.
        let mut block_stream = ScopedStream::new(&mut flac.reader, u64::from(header.block_len));
        match header.block_type {
            MetadataBlockType::Application => {
                // TODO: Store vendor data.
                read_application_block(&mut block_stream, header.block_len)?;
            },
            // SeekTable blocks are parsed into a SeekIndex.
            MetadataBlockType::SeekTable => {
                // Check if a SeekTable has already be parsed. If one has, then the file is
                // invalid, atleast for seeking. Either way, it's a violation of the
                // specification.
                if flac.index.is_none() {
                    let mut index = SeekIndex::new();
                    read_seek_table_block(&mut block_stream, header.block_len, &mut index)?;
                    flac.index = Some(index);
                }
                else {
                    return decode_error("found more than one seek table block");
                }
            },
            // VorbisComment blocks are parsed into Tags.
            MetadataBlockType::VorbisComment => {
                read_comment_block(&mut block_stream, &mut metadata_builder)?;
            },
            // Cuesheet blocks are parsed into Cues.
            MetadataBlockType::Cuesheet => {
                read_cuesheet_block(&mut block_stream, &mut flac.cues)?;
            },
            // Picture blocks are read as Visuals.
            MetadataBlockType::Picture => {
                read_picture_block(&mut block_stream, &mut metadata_builder)?;
            },
            // StreamInfo blocks are parsed into Streams.
            MetadataBlockType::StreamInfo => {
                read_stream_info_block(&mut block_stream, &mut flac.streams, &mut flac.parser)?;
            },
            // Padding blocks are skipped.
            MetadataBlockType::Padding => {
                block_stream.ignore_bytes(u64::from(header.block_len))?;
            },
            // Unknown block encountered. Skip these blocks as they may be part of a future
            // version of FLAC, but  print a message.
            MetadataBlockType::Unknown(id) => {
                block_stream.ignore_bytes(u64::from(header.block_len))?;
                info!("ignoring {} bytes of block width id={}.", header.block_len, id);
            }
        }
        // If the stated block length is longer than the number of bytes from the block read,
        // ignore the remaining unread data.
        let block_unread_len = block_stream.bytes_available();
        if block_unread_len > 0 {
            info!("under read block by {} bytes.", block_unread_len);
            block_stream.ignore_bytes(block_unread_len)?;
        }
        // Exit when the last header is read.
        if header.is_last {
            break;
        }
    }
    // Commit any read metadata to the metadata queue.
    flac.metadata.push(metadata_builder.metadata());
    Ok(())
}
fn read_all_metadata_blocks ( flac : & mut FlacReader ) -> Result < ( ) > { let mut metadata_builder = MetadataBuilder :: new ( ) ; loop { let header = MetadataBlockHeader :: read ( & mut flac . reader ) ? ; // Create a scoped bytestream to error if the metadata block read functions exceed the // stated length of the block. let mut block_stream = ScopedStream :: new ( & mut flac . reader , u64 :: from ( header . block_len ) ) ; match header . block_type { MetadataBlockType :: Application => { // TODO: Store vendor data. read_application_block ( & mut block_stream , header . block_len ) ? ; } , // SeekTable blocks are parsed into a SeekIndex. MetadataBlockType :: SeekTable => { // Check if a SeekTable has already be parsed. If one has, then the file is // invalid, atleast for seeking. Either way, it's a violation of the // specification. if flac . index . is_none ( ) { let mut index = SeekIndex :: new ( ) ; read_seek_table_block ( & mut block_stream , header . block_len , & mut index ) ? ; flac . index = Some ( index ) ; } else { return decode_error ( " " ) ; } } , // VorbisComment blocks are parsed into Tags. MetadataBlockType :: VorbisComment => { read_comment_block ( & mut block_stream , & mut metadata_builder ) ? ; } , // Cuesheet blocks are parsed into Cues. MetadataBlockType :: Cuesheet => { read_cuesheet_block ( & mut block_stream , & mut flac . cues ) ? ; } , // Picture blocks are read as Visuals. MetadataBlockType :: Picture => { read_picture_block ( & mut block_stream , & mut metadata_builder ) ? ; } , // StreamInfo blocks are parsed into Streams. MetadataBlockType :: StreamInfo => { read_stream_info_block ( & mut block_stream , & mut flac . streams , & mut flac . parser ) ? ; } , // Padding blocks are skipped. MetadataBlockType :: Padding => { block_stream . ignore_bytes ( u64 :: from ( header . block_len ) ) ? ; } , // Unknown block encountered. Skip these blocks as they may be part of a future // version of FLAC, but  print a message. MetadataBlockType :: Unknown ( id ) => { block_stream . ignore_bytes ( u64 :: from ( header . block_len ) ) ? ; info ! ( " " header block_len id ) ; } } // If the stated block length is longer than the number of bytes from the block read, // ignore the remaining unread data. let block_unread_len = block_stream . bytes_available ( ) ; if block_unread_len > 0 { info ! ( " " block_unread_len ) ; block_stream . ignore_bytes ( block_unread_len ) ? ; } // Exit when the last header is read. if header . is_last { break ; } } // Commit any read metadata to the metadata queue. flac . metadata . push ( metadata_builder . metadata ( ) ) ; Ok ( ( ) ) }
Reads all the metadata blocks.
Reads all the metadata blocks .
flac
&mut FlacReader