By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,897 Members | 1,969 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,897 IT Pros & Developers. It's quick & easy.

Portable endianess

P: n/a
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
Jul 22 '05 #1
Share this Question
Share on Google+
6 Replies


P: n/a
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?

Jul 22 '05 #2

P: n/a
"Jeff Schwab" <je******@comcast.net> schrieb im Newsbeitrag news:yM********************@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
Jul 22 '05 #3

P: n/a
Heinz Ozwirk wrote:
"Jeff Schwab" <je******@comcast.net> schrieb im Newsbeitrag news:yM********************@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?

Jul 22 '05 #4

P: n/a
On Sun, 21 Dec 2003 11:51:46 +0100, "Heinz Ozwirk" <wa******@gmx.de>
wrote:
"Jeff Schwab" <je******@comcast.net> schrieb im Newsbeitrag news:yM********************@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

Jul 22 '05 #5

P: n/a
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.

Jul 22 '05 #6

P: n/a
"Stewart Gordon" <sm*******@yahoo.com> wrote in message
news:3f******@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.

Jul 22 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.