| View previous topic :: View next topic |
| Author |
Message |
hantheman Guest
|
Posted: Sat Dec 20, 2003 10:07 am Post subject: 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) >> |
(((uint16)(A) & 0x00ff) << )
#define htonl(A) ((((uint32)(A) & 0xff000000) >> 24) |
(((uint32)(A) & 0x00ff0000) >> |
(((uint32)(A) & 0x0000ff00) << |
(((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
|
|
| Back to top |
|
 |
Jeff Schwab Guest
|
Posted: Sat Dec 20, 2003 2:41 pm Post subject: Re: Portable endianess |
|
|
hantheman wrote:
| Quote: | 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) >> |
(((uint16)(A) & 0x00ff) << )
#define htonl(A) ((((uint32)(A) & 0xff000000) >> 24) |
(((uint32)(A) & 0x00ff0000) >> |
(((uint32)(A) & 0x0000ff00) << |
(((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?
|
|
| Back to top |
|
 |
Heinz Ozwirk Guest
|
Posted: Sun Dec 21, 2003 10:51 am Post subject: Re: Portable endianess |
|
|
"Jeff Schwab" <jeffplus (AT) comcast (DOT) net> schrieb im Newsbeitrag news:yM6dnc13PoxgwnmiRVn-hQ (AT) comcast (DOT) 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) >> |
: > (((uint16)(A) & 0x00ff) << )
: > #define htonl(A) ((((uint32)(A) & 0xff000000) >> 24) |
: > (((uint32)(A) & 0x00ff0000) >> |
: > (((uint32)(A) & 0x0000ff00) << |
: > (((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
|
|
| Back to top |
|
 |
Jeff Schwab Guest
|
Posted: Sun Dec 21, 2003 4:09 pm Post subject: Re: Portable endianess |
|
|
Heinz Ozwirk wrote:
| Quote: | "Jeff Schwab" <jeffplus (AT) comcast (DOT) net> schrieb im Newsbeitrag news:yM6dnc13PoxgwnmiRVn-hQ (AT) comcast (DOT) 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) >> |
: > (((uint16)(A) & 0x00ff) << )
: > #define htonl(A) ((((uint32)(A) & 0xff000000) >> 24) |
: > (((uint32)(A) & 0x00ff0000) >> |
: > (((uint32)(A) & 0x0000ff00) << |
: > (((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?
|
|
| Back to top |
|
 |
Gene Wirchenko Guest
|
Posted: Mon Dec 22, 2003 5:52 pm Post subject: Re: Portable endianess |
|
|
On Sun, 21 Dec 2003 11:51:46 +0100, "Heinz Ozwirk" <wansor42 (AT) gmx (DOT) de>
wrote:
| Quote: | "Jeff Schwab" <jeffplus (AT) comcast (DOT) net> schrieb im Newsbeitrag news:yM6dnc13PoxgwnmiRVn-hQ (AT) comcast (DOT) 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
|
|
| Back to top |
|
 |
Stewart Gordon Guest
|
Posted: Sat Dec 27, 2003 10:30 pm Post subject: Re: Portable endianess |
|
|
Jeff Schwab wrote:
| Quote: | 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 >> ;
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.
|
|
| Back to top |
|
 |
Nick Hounsome Guest
|
Posted: Sun Dec 28, 2003 10:14 am Post subject: Re: Portable endianess |
|
|
"Stewart Gordon" <smjg_1998 (AT) yahoo (DOT) com> wrote
| Quote: | 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.
|
|
| Back to top |
|
 |
|