-
-
Notifications
You must be signed in to change notification settings - Fork 54
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
Pointer: jump to position, parse/write struct, and come back #100
Comments
I don't see why not! Possibly a |
There's a nice example of case of use in the construct gallery for the PE/COFF format. |
So, I went to implement something like this as part of my own project, and ran into the fact that currently, an implementation of DekuRead has no way to perform an absolute offset operation -- you'd have to pass in the original BitSlice as context. so, that indicates to me that some breaking changes to deku are likely necessary to make any sort of file pointer ergonomic, or else some very careful additions to the derive macro to thread the starting position through to whatever needs it. |
@kitlith Breaking changes are fine with me. This crate is still pre 1.0.0 :) |
For anybody looking for an interim solution, I hacked up this absolute nightmare: fn read_offset<'a, C, T, O>(
rest: &'a BitSlice<Msb0, u8>,
input: &'a BitSlice<Msb0, u8>,
ctx: C,
offset: O,
) -> Result<(&'a BitSlice<Msb0, u8>, T), DekuError>
where
C: Copy,
T: DekuRead<'a, C>,
O: Into<usize>,
{
let offset = offset.into();
let subslice = input.get(offset..).ok_or_else(|| {
let need = NeedSize::new(rest.len() - offset);
DekuError::Incomplete(need)
})?;
T::read(subslice, ctx)
}
fn read_offset_count<'a, C, T, U, O, N>(
rest: &'a BitSlice<Msb0, u8>,
input: &'a BitSlice<Msb0, u8>,
ctx: C,
offset: O,
count: N,
) -> Result<(&'a BitSlice<Msb0, u8>, T), DekuError>
where
C: Copy,
T: DekuRead<'a, (Limit<U, fn(&U) -> bool>, C)>,
U: Copy + DekuRead<'a, C>,
O: Into<usize>,
N: Into<usize>,
{
read_offset(rest, input, (Limit::new_count(count.into()), ctx), offset)
} Usage example: #[derive(PartialEq, Debug, DekuRead)]
#[deku(endian = "little", ctx = "endian: deku::ctx::Endian")]
pub struct MorrowindArchive {
...
/// File name hashes.
#[deku(reader = "read_offset_count(deku::rest, deku::input_bits, endian, ((*file_name_hashes_offset as usize) + 8) * 8, *file_count as usize)")]
file_name_hashes: Vec<u64>,
} |
In construct, there's a wrapper called Pointer, which is really useful for binary files that have jumptables. It uses a field as an offset, jumps to the position, parses/writes the content of the structure, and jumps back to position. Would something like this be feasible in Deku?
The text was updated successfully, but these errors were encountered: