Thread View: comp.sys.next.programmer
2 messages
2 total messages
Started by William Clocksin
Mon, 28 Sep 1992 16:34
archiving structs with bit fields
Author: William Clocksin
Date: Mon, 28 Sep 1992 16:34
Date: Mon, 28 Sep 1992 16:34
4 lines
748 bytes
748 bytes
Does anybody know where I can find good examples of using typed streams to archive structs that contain bit fields? I am particularly interesting in knowing how to deal with multiple ClassVersions in which the bit fields in the structs are differently defined.
Re: archiving structs with bit fields
Author: Josh Doenias
Date: Tue, 29 Sep 1992 22:00
Date: Tue, 29 Sep 1992 22:00
89 lines
3689 bytes
3689 bytes
In article <1992Sep28.163408.6449@infodev.cam.ac.uk> wfc@cl.cam.ac.uk
(William Clocksin) writes:
>Does anybody know where I can find good examples of using typed streams
to
>archive structs that contain bit fields? I am particularly interesting
in
>knowing how to deal with multiple ClassVersions in which the bit fields
in the
>structs are differently defined.
This is a point that warrants a little discussion. Bitfields are an
extremely useful and powerful feature of the language, but one must be
careful when using them. Especially in regards to reading them from and
writing them to disk.
With the upcoming release of NeXTStep on intel based machines, this issue
becomes especially important. The Intel chips have a different endianness
from the Motorola ones, so if you write out bit fields on one
architecture, they can come out reversed when read into a different
architecture.
What we recommend is the following solution.
Let's say that we have the following structure declaration:
struct BitFieldStruct {
unsigned int firstFlag:1;
unsigned int secondFlag:1;
unsigned int thirdFlag:1;
unsigned int someRange:4;
unsigned int someOtherRange:2;
}
You may be tempted to write it as an int:
NXWriteType(thestream, "i", (int *)(&myStruct));
THIS IS NOT A GOOD WAY TO GO!! If you do this, you will have to byte-swap
the value when reading the file on a little-endian machine. You really
don't want to be forced to do this.
What is better is to access each value separately and write them out:
unsigned int outputValue;
outputValue = myStruct.firstFlag;
NXWriteType(thestream,"i",&outputValue);
outputValue = myStruct.secondFlag;
NXWriteType(thestream,"i",&outputValue);
...
And read them in using the opposite scheme :
unsigned int inputValue;
NXReadType(thestream,"i",&inputValue);
myStruct.firstFlag = inputValue;
...
This will guarantee that you don't have any endian-ness dependancies in
your files.
Now back to the original question. If you want to have different class
versions that have different bit field structures in them, just use the
above method for reading and writing the bit fields, but use
NXTypedStreamClassVersion() to determine the structure:
int version = NXTypedStreamClassVersion(thestream,[self name]);
switch (version) {
case MYOBJECT_VERSION1: [self readVersionOneStruct:thestream]; break;
case MYOBJECT_VERSION2: [self readVersionTwoStruct:thestream]; break;
...
}
Remember that, when it comes to porting your software, the external files
that you generate can be one of the largest problems you'll have to deal
with. That's why NeXT supplies functionality like TypedStreams in the
first place.
Another point is that you may already have a version of your software out
which generates files that have some sort of endian-ness or other
architecture depandant features. If this is the case, and you want to
support old files, you will have to address this issue.
If, however, when you are designing your software, you carefully think
about these sorts of issues, you can circumvent these problems from
arising in the future. Remember what mom always said about an ounce of
prevention.
-- josh
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads