Reputation:
I don't know what's going on with this:
#define _PACK32(str, x) \
{ \
*(x) = ((int) *((str) + 3) ) \
| ((int) *((str) + 2) << 8) \
| ((int) *((str) + 1) << 16) \
| ((int) *((str) + 0) << 24); \
}
the str it's a integer and the x it's a integer pointer
Upvotes: 1
Views: 537
Reputation: 106
Well, as mentioned, str
is not an integer. It's a pointer, as it is being dereference with *
operator.
*((str) + 3)
is equivalent to *(str + sizeof(str[0])*3)
, thus this depends on the type of str, as seen here. Same goes for other dereference operator.
So what's going on? Well, it takes the least significant 8bit of str[0], str1, str[2], and assemble them to one 32 bit size integer.
For instance, let W, X, Y, Z, A
be arbitrary bit. Then,
*(str + 3) = WWWWWWWWWWWWWWWWWWWWWWWWXXXXXXXX
*(str + 2) = WWWWWWWWWWWWWWWWWWWWWWWWYYYYYYYY
*(str + 1) = WWWWWWWWWWWWWWWWWWWWWWWWZZZZZZZZ
*(str + 0) = WWWWWWWWWWWWWWWWWWWWWWWWAAAAAAAA
The last 3 are shifted, 8, 16, and 24, respectively, thus,
*(str + 3) = WWWWWWWWWWWWWWWWWWWWWWWWXXXXXXXX
*(str + 2) = WWWWWWWWWWWWWWWWYYYYYYYY00000000
*(str + 1) = WWWWWWWWZZZZZZZZ0000000000000000
*(str + 0) = AAAAAAAA000000000000000000000000
Note that the least significant digits of the last 3 are replaced with 0 during the shift.
Last, they are OR'ED, which is then assigned to X,
X = AAAAAAAAZZZZZZZZYYYYYYYYXXXXXXXX
Edit: O'Ring is not as straightforward as it might seem seems W's could be anything.
Upvotes: 3
Reputation: 78903
Correctly written as an inline
function this should look something like:
void pack32(void const*p, unsigned* x) {
unsigned char const* str = p;
*x = str[0];
*X = *x<<8 | str[1];
*X = *x<<8 | str[2];
*X = *x<<8 | str[3];
}
you should use unsigned types when you do bit shifting, otherwise your result can overflow. And perhaps it also makes the idea clearer. The suposedly 8 bit of each byte are placed in the different bits of the target x
.
Upvotes: 1
Reputation: 11428
Looks like str
is a pointer to an array of 4 bytes, and x
is a pointer to a 32 bit value. str
would actually point to the first byte (LSB) of a little endian 32 bit number, and this macro would read it and store in the variable pointed by x
.
Upvotes: 1