dg_byte_order(3) SDK R4.11 dg_byte_order(3)
NAME
dg_byte_order: byte_swap_int16, byte_swap_uint16, byte_swap_int32,
byte_swap_uint32, byte_swap_int64, byte_swap_uint64,
byte_swap_ieeefp32, byte_swap_ieeefp64, little_endian_int16,
little_endian_uint16, little_endian_int32, little_endian_uint32,
little_endian_int64, little_endian_uint64, little_endian_ieeefp32,
little_endian_ieeefp64, big_endian_int16, big_endian_uint16,
big_endian_int32, big_endian_uint32, big_endian_int64,
big_endian_uint64, big_endian_ieeefp32, big_endian_ieeefp64 - byte
order-sensitive macros
SYNOPSIS
#include <dg_byte_order.h>
int16_t byte_swap_int16 (int16_t value)
uint16_t byte_swap_uint16 (uint16_t value)
int32_t byte_swap_int32 (int32_t value)
uint32_t byte_swap_uint32 (uint32_t value)
int64_t byte_swap_int64 (int64_t value)
uint64_t byte_swap_uint64 (uint64_t value)
ieeefp32_t byte_swap_ieeefp32 (ieee32fp_t value)
ieeefp64_t byte_swap_ieeefp64 (ieee64fp_t value)
int16_t little_endian_int16 (int16_t value)
uint16_t little_endian_uint16 (uint16_t value)
int32_t little_endian_int32 (int32_t value)
uint32_t little_endian_uint32 (uint32_t value)
int64_t little_endian_int64 (int64_t value)
uint64_t little_endian_uint64 (uint64_t value)
ieeefp32_t little_endian_ieeefp32 (ieee32fp_t value)
ieeefp64_t little_endian_ieeefp64 (ieee64fp_t value)
int16_t big_endian_int16 (int16_t value)
uint16_t big_endian_uint16 (uint16_t value)
int32_t big_endian_int32 (int32_t value)
uint32_t big_endian_uint32 (uint32_t value)
int64_t big_endian_int64 (int64_t value)
uint64_t big_endian_uint64 (uint64_t value)
ieeefp32_t big_endian_ieeefp32 (ieee32fp_t value)
ieeefp64_t big_endian_ieeefp64 (ieee64fp_t value)
DESCRIPTION
The macros and types defined in the dg_byte_order.h header are
intended for programmers who are writing data conversion programs or
have the rare need for byte order-sensitive programming.
Byte order is a property of computer architectures that describes the
order in which the several bytes of a multi-byte datum are assigned
addresses in memory. A machine is considered to be "little-endian"
if the least significant byte of the datum is at the lowest address.
Similarly, a machine is "big-endian" if the most significant byte is
at the lowest address. See the Data General manual titled "Porting
and Developing Applications for the DG/UX(TM) System" for more
information.
The names introduced above that begin with "byte_swap",
"little_endian", and "big_endian" are macros that provide byte-
swapping support. They are described with C function prototype
syntax to indicate the expected type of their argument and the type
of their result.
The types that are introduced can be interpreted as follows:
+---------------------------------------+
|Type Name Interpretation |
+---------------------------------------+
|int16_t signed 16-bit integer |
|uint16_t unsigned 16-bit integer |
|int32_t signed 32-bit integer |
|uint32_t unsigned 32-bit integer |
|int64_t signed 64-bit integer |
|uint64_t unsigned 64-bit integer |
|ieeefp32_t 32-bit floating-point value |
|ieeefp64_t 64-bit floating-point value |
+---------------------------------------+
These types are used, instead of C primitive types such as int or
float, to allow these functions to operate correctly across
architectures that use a different size for one or more primitive
types.
The macros are in two classes. The first class comprises the macros
whose names begin with "byte_swap". Each such macro performs a byte-
swap operation on its argument. Byte swapping is the operation that
converts a datum from one byte order to another.
The second class comprises the macros whose names began with
"little_endian" or "big_endian". Each such macro maintains an
appropriate byte ordering of its argument no matter what the byte
order of the architecture it is compiled for.
Each of the "little/big _endian" macros can be used in either of two
ways in a program:
A. To assert the representation of its operand and return a
natural representation, or
B. To assume a natural representation of the operand and return
the asserted representation.
Both interpretations are valid. Here are examples of each use.
A. If a pointer p addresses a memory location that always has a
big endian 32-bit integer and you wish to translate that value
to the natural representation of the machine you are running
on and then store it in a variable i, you would write:
i = big_endian_int32( *p );
On a little-endian machine, this statement would fetch the
32-bit quantity addressed by p, swap it, and store it in i.
On a big-endian machine, it would copy without swapping.
B. If you wish to store the integer value 17 into the same
location addressed by p, you would write:
*p = big_endian_int32( 17 );
On a little-endian machine, this statement would byte-swap the value
17, and store it in memory. On a big endian machine, it would just
store without swapping.
On rare occasions, a program source may encode an endian-specific
algorithm. If this program source is to be compiled for both big and
little endian architectures, it will need conditional compilation to
encode the big and little endian-specific program variants. The
dg_byte_order.h header aids this conditional compilation by
introducing the macros LITTLE_ENDIAN and BIG_ENDIAN, which are
defined according to the following table:
Macro Definitions
---------------------------------------
Target Machine BIG_ENDIAN LITTLE_ENDIAN
------------------ ------------------
little-endian arch.: undefined defined & nonzero
big-endian arch.: defined & nonzero undefined
This organization allows for any of the following coding styles:
#if LITTLE_ENDIAN
or
#ifdef LITTLE_ENDIAN
or
#if defined( LITTLE_ENDIAN )
It should be noted that the "endian" property has potentially more
then two values. The DEC VAX, for example, could possibly be called
a "middle-endian" machine. For complete portability, programs should
not assume that because one of the above is undefined that the other
is defined. For example, a program which had code for little and big
endian byte order would be written as follows:
#include <dg_byte_order.h>
..
#if LITTLE_ENDIAN
/* little endian version */
..
#elif BIG_ENDIAN
/* big endian version */
..
#else
#error Byte order could not be determined.
#endif
FILES
/usr/include/dg_byte_order.h
SEE ALSO
cc(1), gcc(1M).
NOTES
The implementation of the byte order-manipulating macros requires C
function prototypes. The macros are only defined in compilations
where prototypes are enabled. This is the default for the cc(1)
command and is also true when compiling with the -Xa or -Xc options.
It is not true when compiling with the -Xt option.
The implementation of the 64-bit integer types requires long long
support in the compiler. If this support is not enabled, the types
and macros that have "int64" in their names will not be defined by
dg_byte_order.h. Long long support is normally enabled by the cc and
gcc commands.
Licensed material--property of copyright holder(s)