Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DRAFT: Add DekuWriterMut #442

Open
wants to merge 1 commit into
base: impl-reader-seek
Choose a base branch
from
Open

Conversation

wcampbell0x2a
Copy link
Collaborator

Example that this allows. Basically, when you write, you can read from a Reader!

pub enum Data {
    /// On read: Save current stream_position() as `Offset`, seek `header.filesize`
    /// This will be used to seek this this position if we want to extract *just* this file
    Offset(u64),
    /// On write: Write `Reader` to write buffer
    Reader(Box<dyn ReadSeek>),
}

impl DekuReader<'_, u32> for Data {
    fn from_reader_with_ctx<R: Read + Seek>(
        reader: &mut Reader<R>,
        filesize: u32,
    ) -> Result<Data, DekuError> {
        let reader = reader.as_mut();

        // Save the current offset, this is where the file exists for reading later
        let current_pos = reader.stream_position().unwrap();

        // Seek past that file
        let position = filesize as i64 + pad_to_4(filesize as usize) as i64;
        let _ = reader.seek(SeekFrom::Current(position));

        Ok(Self::Offset(current_pos))
    }
}

impl DekuWriterMut for Data {
    fn to_writer_mut<W: Write + Seek>(
        &mut self,
        writer: &mut Writer<W>,
        _: (),
    ) -> Result<(), DekuError> {
        if let Self::Reader(reader) = self {
            // read from reader
            let mut data = vec![];
            reader.read_to_end(&mut data).unwrap();

            // write to deku
            data.to_writer(writer, ())?;

            // add padding
            for _ in 0..pad_to_4(data.len()) {
                0_u8.to_writer(writer, ())?;
            }
        } else {
            panic!("ah");
        }

        Ok(())
    }
}

#[derive(DekuWriteMut)]
pub struct Object {
    // other fields
    data: Data,
}
  • Add DekuWriterMut, to include parsers that mutate from &mut self during parsing.
  • Impls:
    • bool
    • Box
    • IpAddr,
    • NonZero
    • Primitive
    • Slice
    • Vec
    • ()
  • Add small example for a Writer that needs Mut

TODO

  • Make sure the code coverage is good
  • Support Cow?
  • Support HashMap?
  • Support HashSet?

* Add DekuWriterMut, to include parsers that mutate from &mut self during parsing.
* Impls:
  * bool
  * Box
  * IpAddr,
  * NonZero
  * Primitive
  * Slice
  * Vec
  * ()
* Add small example for a Writer that needs Mut
Copy link

Benchmark for e52c5f4

Click to view benchmark
Test Base PR %
deku_read_bits 1261.4±13.10ns 1295.9±19.04ns +2.74%
deku_read_byte 3.4±0.09ns 3.4±0.08ns 0.00%
deku_read_enum 2.6±0.18ns 2.6±0.17ns 0.00%
deku_read_vec 33.2±0.44ns 33.1±0.54ns -0.30%
deku_write_bits 153.9±2.69ns 164.7±4.54ns +7.02%
deku_write_byte 24.5±0.41ns 24.6±0.51ns +0.41%
deku_write_enum 22.7±0.38ns 22.7±0.42ns 0.00%
deku_write_vec 444.0±16.35ns 443.0±7.05ns -0.23%

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant