-
Notifications
You must be signed in to change notification settings - Fork 38
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
Improve support for serializing data containing offsets (FilePtr, etc.) #4
Comments
I'd say we might want to go the route of file offset calculations, leading to a trait BinWrite {
type Args;
fn write_options<W: binrw::io::Write>(&self, writer: &mut W, options: &WriterOption, args: Self::Args, file_heap_pos: &mut u64) -> binrw::Result<()>;
fn get_write_size(&self, options: &WriterOption, args: Self::Args) -> binrw::Result<u64>;
fn write_file_heap_contents(&self, writer: &mut W, options: &WriterOption, args: Self::Args, file_heap_pos: &mut u64) -> binrw::Result<()>;
} The general concept being:
Thoughts? Some known drawbacks:
|
fwiw my current take on this is that we should probably not provide an implementation of BinWrite for FilePtr for now and experiment out-of-tree for a bit. File formats are going to have different requirements for how things are positioned, and I don't think we have enough information at the moment to properly cover every file format. what i think we should do instead is focus on having tools available such that people can implement a serialization scheme for their file pointers on top using a newtype, (or, heck, i guess serialize_with could be a thing) in a somewhat ergonomic fashion. To me, this means exposing some sort of user-expandable ReadOptions type thing that the user can stick some sort of mutable state (through rc?) in and perhaps implement the scheme that jam suggested in previous message, or some other scheme. Or maybe we do something else, idk. once we experiment enough out of tree we can revisit actually including something in binrw proper. does that make sense? |
I've successfully implemented a two pass writing approach for offsets that I've used for a number of different binary formats across multiple projects. In most cases, the writing can be fully derived. Some formats require manually defining the second "layout" pass to match the original layout. I'll link the solution here for anyone else that stumbles onto this issue. It's also fairly simple to implement. Original post on discord:
// Fill in 0's for any offsets.
let offsets = value.write(...)?;
// Go back and write the pointed to data.
// This often needs to be implemented manually
// for adjusting item order, string sections, etc.
offsets.offset3.update_and_write(...)?;
offsets.offset1.update_and_write(...)?; |
Here's what roblabla had to say (on discord):
I had a similar idea awhile back (though I wasn't looking to implement at the library level) but i don't think this'll quite work for some types of files -- specifically those which break it into different sections, and different things go into different sections. i.e.:
under the scheme of the current idea i don't think we have a good way to represent this: we'd write out
info section, info, info, info, data section, string, data, string, data, string, data
instead ofinfo section, info, info, info, string, string, string, data section, data, data, data
. I think this is fixable by adding some sort of marker typePool
with some way of specifying a identifier such that you can do the same thing as the original idea, but for each pool in turn as you come across them while writing the file.Are there any other methods we might want to consider?
The text was updated successfully, but these errors were encountered: