🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

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
#1637
Author: William Clocksin
Date: Mon, 28 Sep 1992 16:34
4 lines
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
#1658
Author: Josh Doenias
Date: Tue, 29 Sep 1992 22:00
89 lines
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