BinarySerializer icon indicating copy to clipboard operation
BinarySerializer copied to clipboard

[FEATURE REQUEST] FieldAlignment to not just be stream based (but Parent / Field based)

Open bevanweiss opened this issue 1 year ago • 7 comments

I have a situation in this CIP driver that I'm putting together where it wants to have a field padded to an even number of bytes. But this field might start at an odd offset in the stream, however the padding should still be only within the Field itself.

i.e.

public class Parent
{
    [FieldOrder(0)]
    public byte Length;

    [FieldOrder(1)]
    [FieldLength(nameof(Length))]
    [FieldAlignment(2, FieldAlignmentMode.Right)]
    public byte[] Data;
}

If Data has 25 bytes, then it should be padded to be 26 bytes in total space (but the Length field should remain at 25). In the current implementation, since the byte for Length provides an offset of 1 byte in the stream, the Data alignment is 'off'. It's padding when it shouldn't.

I would propose to extend the FieldAlignmentAttribute with a FieldAlignmentScope which would have options of 'Stream' (default and current behaviour), 'Parent' which would align with regards to the offset inside the parent, 'Field' which would only align/pad internally to this Field (how I'd like it to operate).

Is there perhaps something that I'm missing that could already handle what I'm after? (without falling back to entirely custom serialization/deserialization).

It looks like the current Align(...) method only gets the BoundedStream, which has the stream.RelativePosition member. The simplest approach I can think of would be to follow along with a .FieldRelativePosition, and then a .ParentRelativePosition along with a stack to hold previous .ParentRelativePositions (pushed each time descending into a class, and popped when coming back out). This approach seems like it would be relatively expensive in performance though (3x increase in position tracking calculations).

bevanweiss avatar May 16 '23 05:05 bevanweiss