On May 18, 1:21 am, Martin Bonner yahoo.co.uk> wrote:
> On May 17, 9:29 am, nickf3 gmail.com> wrote:
>
>> On May 16, 8:27 pm, Alan McKenney
yahoo.com> wrote:
...
>
>>> A. // only works if host is big-endian
>
>>> unsigned char *buf = ....
>>> unsigned long uint32value;
>
>>> memcpy( &uint32value, buf+ipos, 4 );
>
>>> B. // works regardles of endianness of your host
>
>>> uint32value = ( buf[ipos] << 24 ) |
>>> ( buf[ipos+1] << 16 ) |
>>> ( buf[ipos+2] << 8 ) |
>>> buf[ipos+3] ;
>
>>> I generally use B, to avoid having to worry
>>> about endianness.
>
>> Please don't reinvent the wheel, use standard library:
>
>
>> uint32_t
>> htonl(uint32_t hostlong);
>
>> uint16_t
>> htons(uint16_t hostshort);
>
>> uint32_t
>> ntohl(uint32_t netlong);
>
>> uint16_t
>> ntohs(uint16_t netshort);
>
>> These are noops on big-endian machines, so there's no overhead.
>
> Except that they are /not/ part of the standard library unless you can
> assume Posix. Also they have a horrible interface. The code Alan
> wrote took a buffer of unsigned chars (presumably containing octets
> from the communications protocol) and converted it to a long in a way
> that will work on any compiler that implements the C++ standard (and a
> fair few that don't). ntohl et-al assumes all sorts of things about
> the representations (which may not be true, eg, on a DSP)
>
Let's look at the (open) source, shall we:
/* $OpenBSD: ntohl.c,v 1.6 2005/08/06 20:30:03 espie Exp $ */
/*
* Written by J.T. Conklin netbsd.org>.
* Public domain.
*/
#include
#include
#undef ntohl
u_int32_t
ntohl(u_int32_t x)
{
#if BYTE_ORDER == LITTLE_ENDIAN
u_char *s = (u_char *)&x;
return (u_int32_t)(s[0] << 24 | s[1] << 16 | s[2] << 8 |
s[3]);
#else
return x;
#endif
}
Taken directly from OpenBSD cvs. Looks familiar, doesn't it?
Where's that horror you speak of?
Then, there's arch-specific code for i386:
... BSD license
/* hostorder = ntohl(netorder) */
ENTRY(ntohl)
movl 4(%%esp),%%eax
rorw $8,%%ax
roll $16,%%eax
rorw $8,%%ax
ret
Then, sparc:
... BSD license
/* hostorder = ntohl(netorder) */
ENTRY(ntohl)
retl
nop
And many other archs.
It's perfectly fine (I'd say, required) to _understand_
how to write portable code, but would you want every
programmer on your team doing this stuff by hand, or
would you want them _reusing_ the existing libs?
Yes, it's not a part of the C++ std lib, but neither is that
socket API you use to get to the "communication channel", nor
whatever API you use to talk to a DSP (which doesn't have
C interface, only C++, right?)
Unless you elaborate on that last statement in
your post, I call it FUD.