One of the main pieces still missing from this crate is support for little endian values. I made a first sketch of what this could look like, but I'm open to any critique (and obviously it would require testing which is completely lacking as of now and probably some performance improvements):
https://github.com/leoschwarz/opensim-networking/blob/20858c6e0c8c0f5de3b0f05778b3e1513d377538/src/layer_data/reader.rs
The main problem I had with the API wasn't the addition of a (generic) parameter specifying endianness to the methods, but also the fact that values can be padded from both the left and right with zeros, before applying the byte reordering. (i.e. say you read 9 bits 1 0010 and want that as a u16 it could either be 0001 0010 or 1001 0000, and when you swap the bytes this makes a difference) That's why I ended up taking two generic arguments for the read_part_u32 method. Obviously the read_full_* and read_part_* methods could be combined but then every call would involve supplying two generic arguments which is really verbose. One alternative is taking only one generic argument, which implements both traits, and then to define types implementing both traits.
One alternative to the calling read_u8 all the time would be to read into the target type directly, skip the byteorder crate, and have our own logic to call swap_bytes on the values if needed. (This would have to check the requested ordering and probably the host ordering too.)
One of the main pieces still missing from this crate is support for little endian values. I made a first sketch of what this could look like, but I'm open to any critique (and obviously it would require testing which is completely lacking as of now and probably some performance improvements):
https://github.com/leoschwarz/opensim-networking/blob/20858c6e0c8c0f5de3b0f05778b3e1513d377538/src/layer_data/reader.rs
The main problem I had with the API wasn't the addition of a (generic) parameter specifying endianness to the methods, but also the fact that values can be padded from both the left and right with zeros, before applying the byte reordering. (i.e. say you read 9 bits
1 0010and want that as a u16 it could either be0001 0010or1001 0000, and when you swap the bytes this makes a difference) That's why I ended up taking two generic arguments for theread_part_u32method. Obviously theread_full_*andread_part_*methods could be combined but then every call would involve supplying two generic arguments which is really verbose. One alternative is taking only one generic argument, which implements both traits, and then to define types implementing both traits.One alternative to the calling read_u8 all the time would be to read into the target type directly, skip the byteorder crate, and have our own logic to call swap_bytes on the values if needed. (This would have to check the requested ordering and probably the host ordering too.)