Struct ImageReader
pub struct ImageReader<'a, R> {
image: R,
buffer: &'a mut [u8],
blocks: u64,
trailing: usize,
next: u64,
headers: ImageHeaders,
}Expand description
Reader over the erase blocks of a UBI image, such as the output of
ubinize.
It reads one block at a time into the buffer of the caller. A block that fails to read or has an invalid header returns an error, but the reader can go on with the next block. The example below stops at the first error instead.
Like ubiformat, it rejects a block with a damaged EC header. When the
kernel attaches a device, it still uses the VID header of such a block.
use std::fs::File;
use flashkit_ubi::{HeaderOffsets, ImageReader};
let offsets = HeaderOffsets::from_io_sizes(4096, 4096).ok_or("invalid I/O size")?;
let mut buffer = vec![0; 256 * 1024];
let mut image = ImageReader::new(File::open("system.ubi")?, &mut buffer, offsets)?;
while let Some(block) = image.next_block()? {
if let Some(vid) = block.vid_header() {
println!(
"block {} holds LEB {} of volume {}",
block.index(),
vid.lnum,
vid.volume_id
);
}
}Fields§
§image: R§buffer: &'a mut [u8]Buffer for one block. Its length is the block size.
blocks: u64Number of whole blocks in the image.
trailing: usizeBytes after the last whole block, or 0 once they are reported.
next: u64Index of the next block.
headers: ImageHeadersChecks of the EC headers against each other.
Implementations§
§impl<'a, R: ReadAt> ImageReader<'a, R>
impl<'a, R: ReadAt> ImageReader<'a, R>
pub fn new(
image: R,
buffer: &'a mut [u8],
offsets: HeaderOffsets,
) -> Result<Self, ImageError<R::Error>>
pub fn new( image: R, buffer: &'a mut [u8], offsets: HeaderOffsets, ) -> Result<Self, ImageError<R::Error>>
Creates a reader over image.
buffer must be exactly one erase block of the flash the image was
built for, for example flashkit_mtd::Geometry::block_size of the
target partition. The headers don’t store the block size, so a wrong
size can’t always be detected.
Every block with an EC header must have offsets. Like the block
size, they depend on the flash, see HeaderOffsets::from_io_sizes.
§Errors
Returns ImageError::Offsets if the kernel rejects offsets for
this block size, ImageError::Size if the size of the image can’t
be read and ImageError::TooManyBlocks if the image has more blocks
than fit into a u32.
pub fn next_block(
&mut self,
) -> Result<Option<ImageBlock<'_>>, ImageError<R::Error>>
pub fn next_block( &mut self, ) -> Result<Option<ImageBlock<'_>>, ImageError<R::Error>>
Reads the next block.
Returns None at the end of the image. After an error, the next call
reads the following block.
§Errors
Returns an error if reading the block fails or a header of the block
is invalid. If the image ends in the middle of a block, the call after
the last whole block returns ImageError::PartialBlock.
It doesn’t check the data. See ImageBlock::check_data_crc.
fn end(&mut self) -> Result<Option<ImageBlock<'_>>, ImageError<R::Error>>
fn end(&mut self) -> Result<Option<ImageBlock<'_>>, ImageError<R::Error>>
Reports the bytes after the last whole block once, then the end.