Portable endianess



 DEVELOP > c-Plus-Plus > Portable endianess

LINK TO THIS PAGE  


rating :  0   |  0


  Page 1 of 1

1

 
Topic: DEVELOP > c-Plus-Plus
User: "hantheman"
Date: 20 Dec 2003 04:07:41 AM
Object: Portable endianess
Is this a portable implementation?
#if defined(BIG_ENDIAN) && !defined(LITTLE_ENDIAN)
#define htons(A) (A)
#define htonl(A) (A)
#define ntohs(A) (A)
#define ntohl(A) (A)
#elif defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN)
#define htons(A) ((((uint16)(A) & 0xff00) >> 8) | \
(((uint16)(A) & 0x00ff) << 8))
#define htonl(A) ((((uint32)(A) & 0xff000000) >> 24) | \
(((uint32)(A) & 0x00ff0000) >> 8) | \
(((uint32)(A) & 0x0000ff00) << 8) | \
(((uint32)(A) & 0x000000ff) << 24))
#define ntohs htons
#define ntohl htohl
#else
#error "Either BIG_ENDIAN or LITTLE_ENDIAN must be #defined, but not both."
#endif
.

User: "Jeff Schwab"

Title: Re: Portable endianess 20 Dec 2003 08:41:44 AM
hantheman wrote:

Is this a portable implementation?

#if defined(BIG_ENDIAN) && !defined(LITTLE_ENDIAN)

#define htons(A) (A)
#define htonl(A) (A)
#define ntohs(A) (A)
#define ntohl(A) (A)

#elif defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN)

#define htons(A) ((((uint16)(A) & 0xff00) >> 8) | \
(((uint16)(A) & 0x00ff) << 8))
#define htonl(A) ((((uint32)(A) & 0xff000000) >> 24) | \
(((uint32)(A) & 0x00ff0000) >> 8) | \
(((uint32)(A) & 0x0000ff00) << 8) | \
(((uint32)(A) & 0x000000ff) << 24))
#define ntohs htons
#define ntohl htohl

#else

#error "Either BIG_ENDIAN or LITTLE_ENDIAN must be #defined, but not both."

#endif

Who said bytes had eight bits?
.
User: "Heinz Ozwirk"

Title: Re: Portable endianess 21 Dec 2003 04:51:46 AM
"Jeff Schwab" <jeffplus@comcast.net> schrieb im Newsbeitrag =
news:yM6dnc13PoxgwnmiRVn-hQ@comcast.com...
: hantheman wrote:
: > Is this a portable implementation?
: >=20
: > #if defined(BIG_ENDIAN) && !defined(LITTLE_ENDIAN)
: >=20
: > #define htons(A) (A)
: > #define htonl(A) (A)
: > #define ntohs(A) (A)
: > #define ntohl(A) (A)
: >=20
: > #elif defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN)
: >=20
: > #define htons(A) ((((uint16)(A) & 0xff00) >> 8) | \
: > (((uint16)(A) & 0x00ff) << 8))
: > #define htonl(A) ((((uint32)(A) & 0xff000000) >> 24) | \
: > (((uint32)(A) & 0x00ff0000) >> 8) | \
: > (((uint32)(A) & 0x0000ff00) << 8) | \
: > (((uint32)(A) & 0x000000ff) << 24))
: > #define ntohs htons
: > #define ntohl htohl
: >=20
: > #else
: >=20
: > #error "Either BIG_ENDIAN or LITTLE_ENDIAN must be #defined, but not =
both."
: >=20
: > #endif
:=20
: Who said bytes had eight bits?
Who's talking about bytes? The 8 bits you probaly assume to be the =
number of bits in a (C++-) "byte" are the number of bits in a network =
octet, which is defined to be 8 bits.
Heinz
.
User: "Jeff Schwab"

Title: Re: Portable endianess 21 Dec 2003 10:09:23 AM
Heinz Ozwirk wrote:

"Jeff Schwab" <jeffplus@comcast.net> schrieb im Newsbeitrag news:yM6dnc13PoxgwnmiRVn-hQ@comcast.com...
: hantheman wrote:
: > Is this a portable implementation?
: >
: > #if defined(BIG_ENDIAN) && !defined(LITTLE_ENDIAN)
: >
: > #define htons(A) (A)
: > #define htonl(A) (A)
: > #define ntohs(A) (A)
: > #define ntohl(A) (A)
: >
: > #elif defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN)
: >
: > #define htons(A) ((((uint16)(A) & 0xff00) >> 8) | \
: > (((uint16)(A) & 0x00ff) << 8))
: > #define htonl(A) ((((uint32)(A) & 0xff000000) >> 24) | \
: > (((uint32)(A) & 0x00ff0000) >> 8) | \
: > (((uint32)(A) & 0x0000ff00) << 8) | \
: > (((uint32)(A) & 0x000000ff) << 24))
: > #define ntohs htons
: > #define ntohl htohl
: >
: > #else
: >
: > #error "Either BIG_ENDIAN or LITTLE_ENDIAN must be #defined, but not both."
: >
: > #endif
:
: Who said bytes had eight bits?

Who's talking about bytes? The 8 bits you probaly assume to be the number of bits in a (C++-) "byte" are the number of bits in a network octet, which is defined to be 8 bits.

Heinz

Thanks for clarifying. :) Poor assumption on my part.
Another question: Why are you doing all this in the preprocessor?
.

User: "Gene Wirchenko"

Title: Re: Portable endianess 22 Dec 2003 11:52:42 AM
On Sun, 21 Dec 2003 11:51:46 +0100, "Heinz Ozwirk" <wansor42@gmx.de>
wrote:

"Jeff Schwab" <jeffplus@comcast.net> schrieb im Newsbeitrag news:yM6dnc13PoxgwnmiRVn-hQ@comcast.com...
: hantheman wrote:
: > Is this a portable implementation?

#include <winsock.h>
and
#include <winsock2.h>
are. Unless you are implementing Winsock, you should use your
system's header.
[snip]
Sincerely,
Gene Wirchenko
.


User: "Stewart Gordon"

Title: Re: Portable endianess 27 Dec 2003 04:30:02 PM
Jeff Schwab wrote:

hantheman wrote:

Is this a portable implementation?

#if defined(BIG_ENDIAN) && !defined(LITTLE_ENDIAN)

<snip>
Only if you can rely on the programmer's knowing which endianness
his/her platform is.
Moreover, there might not even be a programmer, but merely someone who's
compiling a program delivered in source form.
I recently did something with this. Basically, I was modifying rayshade
to generate BMP output. I don't have the code over here, but it was
something like:
union EndianBytes {
unsigned char b[4];
short s;
long l;
}
short LEShort(short s) {
EndianBytes e;
e.b[0] = (unsigned char) s;
e.b[1] = (unsigned char) (s >> 8);
return e.s;
}
LEShort converts a short from platform byte-order to little-endian or
vice versa. It's straightforward to write BEShort, LELong and BELong on
the same principle.
Of course it still relies on some standard dimensions (byte = 8 bits,
short = 2 bytes, long = 4 bytes), but it'll work on either BE or LE
platforms without requiring any extra attention or knowledge on the side
of the person writing/compiling a program that uses it.
Stewart.
--
My e-mail is valid but not my primary mailbox. Please keep replies on
on the 'group where everyone may benefit.
.
User: "Nick Hounsome"

Title: Re: Portable endianess 28 Dec 2003 04:14:49 AM
"Stewart Gordon" <smjg_1998@yahoo.com> wrote in message
news:3fee0936@212.67.96.135...

Jeff Schwab wrote:

hantheman wrote:

Is this a portable implementation?

#if defined(BIG_ENDIAN) && !defined(LITTLE_ENDIAN)

<snip>

Only if you can rely on the programmer's knowing which endianness
his/her platform is.

I've recently been using QNX and they have a very clean and logical way of
pushing the endianness issue into 'the implementation':
They just provide macros such as ENDIAN_BE16(x), ENDIAN_LE16(x),
ENDIAN_BE32(x) etc..
If you are dealing with an external format that you know to be Bigendian 16
bits then whenever you read it in you convert it with
internal_format = ENDIAN_BE16(external_format) and when you want to send it
out you use
external_format = ENDIAN_BE16(internal_format)
The implementation conditionally compiles the macros to be either a byte
swap or no op depending on the endianness of the system.
Obviously this doesn't actually answer the question of how to determine the
endianness of a system (which cannot portably be done at compile time) but
is a very clean way of keeping all (host) endianness issues hidden away in
one header file and concentrates instead on interface endianness which is as
it should be.
.




  Page 1 of 1

1

 


Related Articles
 

NEWER

pg.1232     pg.940     pg.716     pg.544     pg.412     pg.311     pg.234     pg.175     pg.130     pg.96     pg.70     pg.50     pg.35     pg.24     pg.16     pg.10     pg.6     pg.3     pg.1

OLDER