On 02/11/2013 05:56 PM, John Ferlan wrote: > On 02/11/2013 07:07 PM, Eric Blake wrote: >> We have several cases where we need to read endian-dependent >> data regardless of host endianness; rather than open-coding >> these call sites, it will be nicer to funnel things through >> a macro. >> >> The virendian.h file can be expanded to add writer functions, >> and/or 16-bit access patterns, if needed. Also, if we need >> to turn things into a function to avoid multiple evaluations >> of buf, that can be done later. But for now, a macro worked. >> >> +# define virReadBufInt32LE(buf) \ >> + ((uint32_t)(uint8_t)((buf)[0]) | \ >> + ((uint32_t)(uint8_t)((buf)[1]) << 8) | \ >> + ((uint32_t)(uint8_t)((buf)[2]) << 16) | \ >> + ((uint32_t)(uint8_t)((buf)[3]) << 24)) >> + >> +#endif /* __VIR_ENDIAN_H__ */ > > Looking at byteswap.h.in I'm reminded of what I've seen in a previous job where > we had lots of byteswapping to do. The macros will "isolate" each byte to move, eg: > > #define bswap_32(x) ((((x) & 0x000000FF) << 24) | \ > (((x) & 0x0000FF00) << 8) | \ > (((x) & 0x00FF0000) >> 8) | \ > (((x) & 0xFF000000) >> 24)) > > Not sure if it's necessary in this case, but figured I'd ask. In the byteswap case, you are going from an int to an int; so you do have to mask out bytes on each part of the expression. But this function is going from a char[] to an int, so we are already starting with bytes. You will also notice that my code does a double cast: first to uint8_t (to guarantee that the byte is not sign-extended) then to uint{32,64}_t (to widen to the correct size of the resulting expression); the first cast is the same as masking with 0xff. > > ACK Thanks for reviewing; and I have now pushed the series. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
Attachment:
signature.asc
Description: OpenPGP digital signature
-- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list