/// Load blob information table from a reader.
Load blob information table from a reader.
Load blob information table from a reader .
pub fn load(
        &mut self,
        r: &mut RafsIoReader,
        blob_table_size: u32,
        chunk_size: u32,
        flags: RafsSuperFlags,
    ) -> Result<()> {
        if blob_table_size == 0 {
            return Ok(());
        }
        debug!("blob table size {}", blob_table_size);
        let mut data = vec![0u8; blob_table_size as usize];
        r.read_exact(&mut data)?;
        // Each entry frame looks like:
        // u32 | u32 | string | trailing '\0' , except that the last entry has no trailing '\0'
        let mut buf = data.as_mut_slice();
        while buf.len() > 2 * size_of::<u32>() {
            let readahead_offset =
                unsafe { std::ptr::read_unaligned::<u32>(buf[0..4].as_ptr() as *const u32) };
            let readahead_size =
                unsafe { std::ptr::read_unaligned::<u32>(buf[4..8].as_ptr() as *const u32) };
            let mut pos = 8;
            while pos < buf.len() && buf[pos] != 0 {
                pos += 1;
            }
            let blob_id = std::str::from_utf8(&buf[8..pos])
                .map(|v| v.to_owned())
                .map_err(|e| einval!(e))?;
            if pos == buf.len() {
                buf = &mut buf[pos..];
            } else {
                buf = &mut buf[pos + 1..];
            }
            debug!("blob {:?} lies on", blob_id);
            let index = self.entries.len();
            let (chunk_count, uncompressed_size, compressed_size, blob_features) =
                // For compatibility, blob table might not be associated with extended blob table.
                if !self.extended.entries.is_empty() {
                    let ext_len = self.extended.entries.len();
                    if index >= ext_len {
                        error!( "Extended blob table({}) is shorter than blob table", ext_len);
                        return Err(einval!());
                    }
                    let entry = &self.extended.entries[index];
                    (entry.chunk_count, entry.uncompressed_size, entry.compressed_size, BlobFeatures::empty())
                } else {
                    (0, 0, 0, BlobFeatures::V5_NO_EXT_BLOB_TABLE)
                };
            let mut blob_info = BlobInfo::new(
                index as u32,
                blob_id,
                uncompressed_size,
                compressed_size,
                chunk_size,
                chunk_count,
                blob_features,
            );
            blob_info.set_compressor(flags.into());
            blob_info.set_digester(flags.into());
            blob_info.set_readahead(readahead_offset as u64, readahead_size as u64);
            self.entries.push(Arc::new(blob_info));
        }
        Ok(())
    }
pub fn load ( & mut self , r : & mut RafsIoReader , blob_table_size : u32 , chunk_size : u32 , flags : RafsSuperFlags , ) -> Result < ( ) > { if blob_table_size == 0 { return Ok ( ( ) ) ; } debug ! ( " " blob_table_size ) ; let mut data = vec ! [ 0u8 blob_table_size as usize ] ; r . read_exact ( & mut data ) ? ; // Each entry frame looks like: // u32 | u32 | string | trailing '\0' , except that the last entry has no trailing '\0' let mut buf = data . as_mut_slice ( ) ; while buf . len ( ) > 2 * size_of :: < u32 > ( ) { let readahead_offset = unsafe { std :: ptr :: read_unaligned :: < u32 > ( buf [ 0 .. 4 ] . as_ptr ( ) as * const u32 ) } ; let readahead_size = unsafe { std :: ptr :: read_unaligned :: < u32 > ( buf [ 4 .. 8 ] . as_ptr ( ) as * const u32 ) } ; let mut pos = 8 ; while pos < buf . len ( ) && buf [ pos ] != 0 { pos += 1 ; } let blob_id = std :: str :: from_utf8 ( & buf [ 8 .. pos ] ) . map ( | v | v . to_owned ( ) ) . map_err ( | e | einval ! ( e ) ) ? ; if pos == buf . len ( ) { buf = & mut buf [ pos .. ] ; } else { buf = & mut buf [ pos + 1 .. ] ; } debug ! ( " " blob_id ) ; let index = self . entries . len ( ) ; let ( chunk_count , uncompressed_size , compressed_size , blob_features ) = // For compatibility, blob table might not be associated with extended blob table. if ! self . extended . entries . is_empty ( ) { let ext_len = self . extended . entries . len ( ) ; if index >= ext_len { error ! ( " " ext_len ) ; return Err ( einval ! ( ) ) ; } let entry = & self . extended . entries [ index ] ; ( entry . chunk_count , entry . uncompressed_size , entry . compressed_size , BlobFeatures :: empty ( ) ) } else { ( 0 , 0 , 0 , BlobFeatures :: V5_NO_EXT_BLOB_TABLE ) } ; let mut blob_info = BlobInfo :: new ( index as u32 , blob_id , uncompressed_size , compressed_size , chunk_size , chunk_count , blob_features , ) ; blob_info . set_compressor ( flags . into ( ) ) ; blob_info . set_digester ( flags . into ( ) ) ; blob_info . set_readahead ( readahead_offset as u64 , readahead_size as u64 ) ; self . entries . push ( Arc :: new ( blob_info ) ) ; } Ok ( ( ) ) }
Load blob information table from a reader.
Load blob information table from a reader .
&mut self
r
&mut RafsIoReader
blob_table_size
u32
chunk_size
u32
flags
RafsSuperFlags