doug@hcr.UUCP (Doug Moen) (10/05/83)
I've read a number of complaints from people who have run into problems
porting binary files from one machine to another, or sending binary
records across a network. Sooo...
Here's how you can read and write binary files in a machine
independent fashion, without running into the byte order problem,
and without modifying the C language:
writeb(stream, format, arguments...)
FILE *stream;
char *format;
This is similar to fprintf, except that the arguments are chars,
shorts, ints, or longs, and a conversion specification has the form:
% <n> [+] <c>
where <n> specifies the number of bytes in the integer to be written,
and <c> is one of C, S, I, or L, meaning that the corresponding argument
is a char, short, int, or long. Writeb writes out each integer with
a standard byte order (ie, high order byte first, low order byte last).
If the optional '+' is present, it indicates
that the integer is signed, and causes sign extension if the integer
needs to be padded to fill the field width.
There is a corresponding routine, readb(), which works like fscanf.
There are also routines called sreadb() and swriteb() which operate
on buffers instead of file pointers, in the manner of sprintf and sscanf.
Additional features can be added, such as this one:
struct {
int x;
long y;
char z;
} foobar;
writeb(stdout, "%{2I,4L,1C}", &foobar);
which is easier to type than:
writeb(stdout, "%2I%4L%1C", foobar.x, foobar.y, foobar.z);
Or how about a repetition factor for arrays:
int x[32];
writeb(stdout, "%[32]4I", x);
Or even a way to read & write floats and doubles in a machine
independent manner.
It is possible to add the printf(3) conversion specifications to writeb,
as there are no conflicts between the two.
Does anybody think this is a good idea? (or am I off the mark, or
possibly re-inventing the wheel?)
Are there any further suggestions? If there is sufficient interest,
I will post a hopefully 'standard' implementation after corresponding
with other people interested in the problem.
stevesu@bronze.UUCP (Steve Summit) (10/06/83)
hcr!doug has a terriffic idea, if portable binary i/o is really needed. I don't like binary i/o, and I prefer to use ascii i/o whenever I can. It's far more portable that way, and there are always times when you want to look at the stuff yourself, which is a real pain if it's binary. The only reasons I can see for using binary i/o would be if you're VERY concerned about file space, or i/o speed, or if you're interfacing with a program that you can't change which does it that way. Steve Summit tektronix!tekmdp!stevesu
dmmartindale@watcgl.UUCP (Dave Martindale) (10/06/83)
Why do you pick the high-byte-first order as the example of a standard? Low-byte-first seems just as natural, and would be more efficient on the most common UNIX machines (DEC hardware). If you are going to produce something really portable, you should come up with some way of dealing with 6, 7, 9, and 10-bit bytes and word lengths which may be neither a multiple of 8 nor a multiple of the byte size.
ark@rabbit.UUCP (10/08/83)
Now that you've solved the byte order problem, how about getting going on the 1's complement problem and the floating point problem? Not to mention the 36-bit word problem and the 9-bit byte problem...