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
signature.asc
Description: OpenPGP digital signature
-- libvir-list mailing list [email protected] https://www.redhat.com/mailman/listinfo/libvir-list
