jefffhaynes / BinarySerializer

A declarative serialization framework for controlling formatting of data at the byte and bit level using field bindings, converters, and code.
MIT License
291 stars 62 forks source link

[Question] Read 3 bytes with a uint and advance only those 3 bytes on the stream #186

Open sn4k3 opened 2 years ago

sn4k3 commented 2 years ago

I have some situations where the format have uint's with 3 bytes, currently is it possible to define an uint and deserialize/serialize in 3 byte order? Making stream only to advance that 3 bytes so the next field will decode/encode at position 3 rather than 4?

PS: Should be cool to enable github discussions to use it as a forum board for questions instead the need to use issues for that purpose

sn4k3 commented 2 years ago

Still struggle with this one... [FieldBitLength(24)] uint FieldName {get; set;} does not return the correct value from 3 bytes as uint. Any suggestion?

jefffhaynes commented 2 years ago

Can you give me some more info? I just wrote a simple test that seems to work but I might be missing something.

sn4k3 commented 2 years ago

Sure, here my definition:

devenv_2022-07-23_23-58-18

What i get:

devenv_2022-07-24_00-03-48

What i expect:

010Editor_2022-07-24_00-04-18

File is in BIG order and use a ton of uint24

jefffhaynes commented 2 years ago

Ahh it's big endian. Unfortunately there is a bug involving big endian and bit fields. I've spent hours trying to fix it but unfortunately it's incredibly complex. I need to at least add a check that will throw in these cases. Sorry about that, I'll try to get back to it soon!

sn4k3 commented 2 years ago

Thanks for looking into it. I've not look at source code, but one thing i always do when working with bytes and convertion is to avoid C# converter functions (BitConverter), and do my own with bitwise. Those utility methods can return different outputs depending on machine endiness, unless you cover it with if (BitConverter.IsLittleEndian) Array.Reverse(bytes); which is easy forgetable.

jefffhaynes commented 2 years ago

As much as I would like to blame something else, it is unfortunately all my own code! The issue has to do with assumptions I made when doing bit-packing early on. Unfortunately, fixing it will mean rewriting quite a bit of the underlying bit field assemblage, which gets complicated fast. If you're interested, most of the rabbit hole is contained in BoundedStream.

bevanweiss commented 1 year ago

@sn4k3 could you perhaps but together a couple of Test Cases for this in Github (within the FieldBitOffset / Endianess stuff probably makes sense).

I've had a bit of a dig through the BoundedStream stuff recently, so might be able to have a look at this problem also.