When writing network code we often find ourselves populating structs from byte slices to access the data in form of an object.
Let's take this struct
type PACKETHEAD struct {
Type uint16
Size uint16
Hash uint32
}
and a byte slice that has been somehow populated with data
data := make([]byte, 1024)
My solution would be to
var pkthead PACKETHEAD
pktsiz := unsafe.Sizeof(pkthead)
pktbuf := bytes.NewReader(buf[:pktsiz])
err = binary.Read(pktbuf, binary.BigEndian, &pkthead)
if err != nil {
// handle it
}
But
It uses
unsafe
Requires ~7 lines of code for every cast (what if we had hundreds of different packets)
Can't be trivially packed into a
Cast(*struct, data)
functionNo control over struct padding, what If go's compiler decides to add extra bytes in between members on one end of a network?
binary.Read performs a data copy if I'm not mistaken (this isn't necessarily a con)
In C one would just #pragma pack(1)
on both network ends, agree on one type of endianess
and finally PACKETHEAD* pkt = (PACKETHEAD*)dataptr;
How can we achieve the same thing with Go?
Have a nice day, Kris