Won't this leave all multi-byte values in network endianness?
The bigger problem with this scheme is alignment, although we appear to have outgrown architectures that will blow up when you get this wrong.
This method is so much less error prone than pulling stuff out a byte at a time. Plus you can use unions for network addresses, etc.
It's a simplified example to show what you can do.
s->field1 = ld32(&cp, ep);
s->field2 = ld16(&cp, ep);
s->field3 = ld16(&cp, ep);
s->field4 = ld8(&cp, ep);
s->field5 = ld8(&cp, ep);
s->field6 = ld32(&cp, ep);
You can just about automate this with a macro (you need to macro out the structure fields and use them both for the structure declaration and the field expansion), but the extra function call there gives you an opportunity to be defensive about e.g. buffer sizes, never blows up alignment, and isn't appreciably slower.From my virtual machine work:
struct vmx_entry_ctrls {
union {
uint32_t value;
struct {
uint_t rsvd1 : 2;
uint_t ld_dbg_ctrls : 1;
uint_t rsvd2 : 6;
uint_t guest_ia32e : 1;
uint_t smm_entry : 1;
uint_t no_dual_monitor : 1;
uint_t rsvd3 : 1;
uint_t ld_perf_glbl_ctrl : 1;
uint_t ld_pat : 1;
uint_t ld_efer : 1;
uint_t rsvd4 : 16;
} __attribute__((packed));
} __attribute__((packed));
} __attribute__((packed));