You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I work with binary file formats a lot and have many projects that all need to read or write binary files with varying endians. While the tools to do this already exist in the .NET API, they are verbose and I'm notoriously stingy; if I can write a reusable class to allow me to do a task with less code I will. I've been using a binary buffer class I wrote for a while now, but I'm currently looking at refactoring and polishing it to release it on NuGet, as it fits a niche where nothing else I could find exists. This discussion is to critique the API design, since I won't be able to change it anymore once it's on NuGet.
The refactored library contains two main types: a FixedBuffer ref struct that wraps a user-supplied Span<byte> and is intended for reading/writing fixed-size structures, and a DynamicBuffer class that dynamically allocates memory as needed as the buffer grows.
Both have very similar APIs, and resemble BinaryReader/BinaryWriter; they use stream semantics as that is the easiest way to read/write a list of different fields one after another. The key difference from the Reader/Writer classes is that most read/write functions have LE and BE variants. Additionally, all read/write functions take a parameter which specifies whether to advance the position, allowing read functions to serve as both read and peek.
As they are backed by memory rather than streams, they also have some functions of lists. Apart from the BinaryReader/BinaryWriter-like functions they have: Length, Position, AsSpan, Seek, and WriteFill. DynamicBuffer also has Capacity, EnsureCapacity, TrimExcess, and Clear.
In addition to individual values, sequence reads can be made into IList<T> or Span<T>. Writes can be made from IEnumerator<T>, IEnumerable<T>, IReadOnlyList<T>, and ReadOnlySpan<T>.
Additionally, sequences of a data type can be read via functions to get an IEnumerable<T> starting at the current position (separate position variable from the buffer object), allowing the use of LINQ functions for reading arrays. There is a different such function for each data type and endian.
In addition to general feedback of the API design, I have a couple questions:
Should it support explicit indexing for bytes? If so what would the semantics of this be? Would indices be absolute, or relative to the current position?
Do the write functions need the advance parameter (currently they have it), or is that only useful for read functions?
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
-
I work with binary file formats a lot and have many projects that all need to read or write binary files with varying endians. While the tools to do this already exist in the .NET API, they are verbose and I'm notoriously stingy; if I can write a reusable class to allow me to do a task with less code I will. I've been using a binary buffer class I wrote for a while now, but I'm currently looking at refactoring and polishing it to release it on NuGet, as it fits a niche where nothing else I could find exists. This discussion is to critique the API design, since I won't be able to change it anymore once it's on NuGet.
The refactored library contains two main types: a FixedBuffer ref struct that wraps a user-supplied
Span<byte>and is intended for reading/writing fixed-size structures, and a DynamicBuffer class that dynamically allocates memory as needed as the buffer grows.Both have very similar APIs, and resemble BinaryReader/BinaryWriter; they use stream semantics as that is the easiest way to read/write a list of different fields one after another. The key difference from the Reader/Writer classes is that most read/write functions have LE and BE variants. Additionally, all read/write functions take a parameter which specifies whether to advance the position, allowing read functions to serve as both read and peek.
As they are backed by memory rather than streams, they also have some functions of lists. Apart from the BinaryReader/BinaryWriter-like functions they have: Length, Position, AsSpan, Seek, and WriteFill. DynamicBuffer also has Capacity, EnsureCapacity, TrimExcess, and Clear.
In addition to individual values, sequence reads can be made into
IList<T>orSpan<T>. Writes can be made fromIEnumerator<T>,IEnumerable<T>,IReadOnlyList<T>, andReadOnlySpan<T>.Additionally, sequences of a data type can be read via functions to get an
IEnumerable<T>starting at the current position (separate position variable from the buffer object), allowing the use of LINQ functions for reading arrays. There is a different such function for each data type and endian.In addition to general feedback of the API design, I have a couple questions:
Beta Was this translation helpful? Give feedback.
All reactions