| TIP: Click on subject to list as thread! | ANSI |
| echo: | |
|---|---|
| to: | |
| from: | |
| date: | |
| subject: | Re: QWK problem(s) |
-=> Bob Jones wrote to William McBrine <=-
BJ> what are you using in your code for dealing with
BJ> (a) big vs little endian for data that needs to be stored or transfered
BJ> that currently is being done in a binary format, and
BJ> (b) packing of data structures for binary reading / writing in a
BJ> portable way?
The key is defining everything in terms of arrays of unsigned chars. Mostly
that means that a "long" becomes an array of four chars, a
"short" an array
of two. This wasn't my idea, BTW -- credit goes to George Hatchew, who
included this scheme for the benefit of big-endian systems in later
revisions of bluewave.h (included in the MultiMail source or the Blue Wave
specs, if you want to see it). Not only does this make the structures
endian-neutral -- you just have to use a small function each time you
access a short or long -- but as a nice side effect, it eliminates padding
within structures. Structures themselves can still get padded at the end,
but I deal with that by specifying their size explictly when reading and
writing (where necessary -- i.e., where the size isn't divisible by four),
rather than using sizeof().
In my case, I use the BIG_ENDIAN (i.e., char-only) version of the structs
on both types of CPU. This adds a little overhead, but not much -- far less
than reading/writing numbers as ASCII, for example. Since it's only for
files on disk, the disk I/O time dwarfs it anyway. Of course, that means I
use a different set of structs (with native ints and longs) to represent
data in memory.
From bluewave.h:
#ifdef BIG_ENDIAN
typedef signed char tCHAR; /* 8 bit signed values */
typedef unsigned char tBYTE; /* 8 bit unsigned values */
typedef unsigned char tINT[2]; /* little-endian 16 bit signed */
typedef unsigned char tWORD[2]; /* little-endian 16 bit unsigned */
typedef unsigned char tLONG[4]; /* little-endian 32 bit signed */
typedef unsigned char tDWORD[4]; /* little-endian 32 bit unsigned */
#else
typedef signed char tCHAR; /* 8 bit signed values */
typedef unsigned char tBYTE; /* 8 bit unsigned values */
typedef signed short tINT; /* 16 bit signed values */
typedef unsigned short tWORD; /* 16 bit unsigned values */
typedef signed long tLONG; /* 32 bit signed values */
typedef unsigned long tDWORD; /* 32 bit unsigned values */
#endif
(Those are only for Blue Wave packets, but I use similar types for other
packet formats.) And the code I wrote to read and write each type (along
with some endian-neutral code to handle big-endian longs, as found in SOUP
packets):
/* get a little-endian short, return an int */
unsigned getshort(const unsigned char *x)
{
return ((unsigned) x[1] << 8) + (unsigned) x[0];
}
/* get a little-endian long */
unsigned long getlong(const unsigned char *x)
{
return ((unsigned long) x[3] << 24) + ((unsigned long) x[2]
<< 16) +
((unsigned long) x[1] << 8) + (unsigned long) x[0];
}
/* get a big-endian long */
unsigned long getblong(const unsigned char *x)
{
return ((unsigned long) x[0] << 24) + ((unsigned long) x[1]
<< 16) +
((unsigned long) x[2] << 8) + (unsigned long) x[3];
}
/* put an int into a little-endian short */
void putshort(unsigned char *dest, unsigned source)
{
dest[0] = source & 0xff;
dest[1] = (source & 0xff00) >> 8;
}
/* put a long into a little-endian long */
void putlong(unsigned char *dest, unsigned long source)
{
dest[0] = source & 0xff;
dest[1] = (source & 0xff00) >> 8;
dest[2] = (source & 0xff0000) >> 16;
dest[3] = (source & 0xff000000) >> 24;
}
/* put a long into a big-endian long */
void putblong(unsigned char *dest, unsigned long source)
{
dest[0] = (source & 0xff000000) >> 24;
dest[1] = (source & 0xff0000) >> 16;
dest[2] = (source & 0xff00) >> 8;
dest[3] = source & 0xff;
}
... Life is much easier if you look at the source code.
--- MultiMail/Linux v0.45
* Origin: COMM Port OS/2 juge.com 204.89.247.1 (281) 980-9671 (1:106/2000)SEEN-BY: 633/267 270 @PATH: 106/2000 633/267 |
|
| SOURCE: echomail via fidonet.ozzmosis.com | |
Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.