/// Reads all raw data for a given inode.
///
/// For a file, this will be the file data. For a symlink,
/// this will be the symlink target.
Reads all raw data for a given inode.
For a file, this will be the file data. For a symlink,
this will be the symlink target.
Reads all raw data for a given inode . For a file this will be the file data . For a symlink this will be the symlink target .
pub fn read_data(&self, inode_num: u32) -> Result<Vec<u8>, ParsingError> {
        let inode = self.inode(inode_num)?;
        let mut size_remaining = inode.size();
        let mut data = Vec::with_capacity(size_remaining.try_into().unwrap());
        // Check for symlink with inline data.
        if u16::from(inode.e2di_mode) & 0xa000 != 0 && u32::from(inode.e2di_nblock) == 0 {
            data.extend_from_slice(&inode.e2di_blocks[..inode.size().try_into().unwrap()]);
            return Ok(data);
        }
        let root_extent_tree_node = inode.extent_tree_node()?;
        let mut extents = Vec::new();
        self.iterate_extents_in_tree(&root_extent_tree_node, &mut |extent| {
            extents.push(extent.clone());
            Ok(())
        })?;
        let block_size = self.block_size()?;
        // Summarized from https://www.kernel.org/doc/ols/2007/ols2007v2-pages-21-34.pdf,
        // Section 2.2: Extent and ExtentHeader entries must be sorted by logical block number. This
        // enforces that when the extent tree is traversed depth first that a list of extents sorted
        // by logical block number is produced. This is a requirement to produce the proper ordering
        // of bytes within `data` here.
        for extent in extents {
            let buffer_offset = extent.e_blk.get() as u64 * block_size;
            // File may be sparse. Sparse files will have gaps
            // between logical blocks. Fill in any gaps with zeros.
            if buffer_offset > data.len() as u64 {
                size_remaining -= buffer_offset - data.len() as u64;
                data.resize(buffer_offset.try_into().unwrap(), 0);
            }
            self.read_extent_data(&extent, &mut data, &mut size_remaining)?;
        }
        Ok(data)
    }
pub fn read_data ( & self , inode_num : u32 ) -> Result < Vec < u8 > , ParsingError > { let inode = self . inode ( inode_num ) ? ; let mut size_remaining = inode . size ( ) ; let mut data = Vec :: with_capacity ( size_remaining . try_into ( ) . unwrap ( ) ) ; // Check for symlink with inline data. if u16 :: from ( inode . e2di_mode ) & 0xa000 != 0 && u32 :: from ( inode . e2di_nblock ) == 0 { data . extend_from_slice ( & inode . e2di_blocks [ .. inode . size ( ) . try_into ( ) . unwrap ( ) ] ) ; return Ok ( data ) ; } let root_extent_tree_node = inode . extent_tree_node ( ) ? ; let mut extents = Vec :: new ( ) ; self . iterate_extents_in_tree ( & root_extent_tree_node , & mut | extent | { extents . push ( extent . clone ( ) ) ; Ok ( ( ) ) } ) ? ; let block_size = self . block_size ( ) ? ; // Summarized from https://www.kernel.org/doc/ols/2007/ols2007v2-pages-21-34.pdf, // Section 2.2: Extent and ExtentHeader entries must be sorted by logical block number. This // enforces that when the extent tree is traversed depth first that a list of extents sorted // by logical block number is produced. This is a requirement to produce the proper ordering // of bytes within `data` here. for extent in extents { let buffer_offset = extent . e_blk . get ( ) as u64 * block_size ; // File may be sparse. Sparse files will have gaps // between logical blocks. Fill in any gaps with zeros. if buffer_offset > data . len ( ) as u64 { size_remaining -= buffer_offset - data . len ( ) as u64 ; data . resize ( buffer_offset . try_into ( ) . unwrap ( ) , 0 ) ; } self . read_extent_data ( & extent , & mut data , & mut size_remaining ) ? ; } Ok ( data ) }
Reads all raw data for a given inode.
Reads all raw data for a given inode .
&self
inode_num
u32