This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Re: Network/Host byte ordering and bitfields
Hi Marcio,
Here's the short example in GCC's C...
- - - a.h - - - - - - - - - - - - - - - - - -
struct A
{
unsigned int a : 1;
unsigned int b : 26;
unsigned int c : 3;
}; __attribute__((packed));
// WARNING: If this structure changes,
// change the readStructA and writeStructA routines!
extern void readStructA(int fd, struct A*);
extern void writeStructA(int fd, struct A*);
- - - a.c - - - - - - - - - - - - - - - - - -
#include <stdio.h>
#include <unistd.h>
#include <inttypes.h>
/* I'm going to use file descriptors instead of FILE*. That way, you don't
have to know what kind out output you are writing to (e.g., a file, a
socket, a pipe, et cetera). Feel free to substitute FILE* and the
analogous file functions instead.
*/
/* Canonical Struct A record format
* byte a[1];
* byte b[4]; // in agnostic network order
* byte c[1];
**/
void writeStructA(int fd, struct A* x)
{
uint8_t item1 = x->a;
uint32_t item2 = x->b;
uint8_t item3 = x->c;
ssize_t err;
err = write(fd, &item1, sizeof item1);
if(err != sizeof item1) Kboom();
item2 = htonl(item2);
err = write(fd, &item2, sizeof item2);
if(err != sizeof item2) Kboom();
err = write(fd, &item3, sizeof item3);
if(err != sizeof item3) Kboom();
/* If converting to FILE* and related functions, you MAY want a fflush
here, and a check to make sure the flush worked. The low level read/write
against a file descriptor is normally unbuffered. Except for IP sockets
and Nagle's algorithm for buffering packets, but that's a whole 'nother can
of worms.
*/
}
// C style slicing takes care of our bit twiddling needs.
// But I'm including masking anyway, just for illustration.
void readStructA(int fd, struct A* x)
{
uint8_t item1;
uint32_t item2;
uint8_t item3;
ssize_t err;
err = read(fd, &item1, sizeof item1);
if(err != sizeof item1) Kboom();
x->a = item1 & 0x01;
err = read(fd, &item2, sizeof item2);
if(err != sizeof item2) Kboom();
item2 = ntohl(item2);
x->b = item2 & 0x03FFFFFF;
err = read(fd, &item3, sizeof item3);
if(err != sizeof item3) Kboom();
x->c = item3 & 0x07;
}
// Kboom does something appropriate for handling error situations.
- - - - - - - - - - - - - - - - - - - - -
HTH,
--Eljay