
Dear Joakim Tjernlund,
In message OFDFF8A95F.374EB267-ONC1257681.0042613C-C1257681.004485DD@transmode.se you wrote:
if (len == 1) {
xsum += (*p & 0xff00);
I doubt that this code is endianess-clean.
Nope, I would think some thing like this would work better: count = len >> 1; /* div by 2 */ for(p--; count; --count) xsum += *++p;
if (len & 1) /* Odd */ xsum += *(u_char *)(++p); /* one byte only */
It probably depends on the definition of "better" ;-)
Running this test code:
----------------------------------------- #include <stdio.h> #include <string.h>
#define LENGTH 6
int main (void) { char string[LENGTH] = { 1, 2, 3, 4, 5, 0, }; unsigned short array[LENGTH/2]; unsigned short *p; unsigned short xsum, xsum1, xsum2; int i, count;
memcpy (array, string, LENGTH);
count = LENGTH / 2;
xsum = 0; p = array;
while (count > 1) { printf ("Adding 0x%04x\n", *p); xsum += *p++; --count; }
xsum1 = xsum + (*p & 0xff00);
xsum2 = xsum + *(unsigned char *)(p);
printf ("*p = 0x%04x\n", *p); printf ("xsum = %04x, xsum1 = %04x, xsum2 = %04x\n", xsum, xsum1, xsum2); return (0); } -----------------------------------------
on a little endian system gives:
-> ./f-le Adding 0x0201 Adding 0x0403 *p = 0x0005 xsum = 0604, xsum1 = 0604, xsum2 = 0609
while running it on a big endian system gives
-> ./f-be Adding 0x0102 Adding 0x0304 *p = 0x0500 xsum = 0406, xsum1 = 0906, xsum2 = 040b
I don't know what you consider to be the exact result, but fact is that even if we ignore byte swapping, none of the implementations is endianess clean.
Of course, there is a chance that I mis-implemented your suggestion.
Best regards,
Wolfgang Denk