Skip to main content

ImageReader

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: u64

Number of whole blocks in the image.

§trailing: usize

Bytes after the last whole block, or 0 once they are reported.

§next: u64

Index of the next block.

§headers: ImageHeaders

Checks of the EC headers against each other.

Implementations§

§

impl<'a, R: ReadAt> ImageReader<'a, R>

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>>

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>>

Reports the bytes after the last whole block once, then the end.

Trait Implementations§

§

impl<R> Debug for ImageReader<'_, R>

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'a, R> !UnwindSafe for ImageReader<'a, R>

§

impl<'a, R> Freeze for ImageReader<'a, R>
where R: Freeze,

§

impl<'a, R> RefUnwindSafe for ImageReader<'a, R>
where R: RefUnwindSafe,

§

impl<'a, R> Send for ImageReader<'a, R>
where R: Send,

§

impl<'a, R> Sync for ImageReader<'a, R>
where R: Sync,

§

impl<'a, R> Unpin for ImageReader<'a, R>
where R: Unpin,

§

impl<'a, R> UnsafeUnpin for ImageReader<'a, R>
where R: UnsafeUnpin,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.