Guidelines for Writing rwSaveGuts
The global overloaded functions:
 
rwSaveGuts(RWFile& f, const YourClass& t)
rwSaveGuts(RWvostream& s, const YourClass& t)
are responsible for saving the internal state of a YourClass object to either a binary file (using class RWFile) or to a virtual output stream (an RWvostream). This allows the object to be restored at some later time.
The rwSaveGuts() functions that you write must save the state of each member in YourClass, including the members of the class from which you inherited.
How you write the functions depends upon the type of the member data:
*To save member data that are either C++ fundamental types (int, char, float, ...), or most Rogue Wave classes, including RWCollectable, use the overloaded insertion operator operator<<.
*Since size_t is normally a typedef for one of the basic types, it cannot be handled by operator<< (it would cause an ambiguity error), so you will need to save it specifically by calling putSizeT(aSizeTValue);.
*Saving members that are pointers to non RWCollectable objects can be a bit tricky. This is because it is possible that a pointer does not point to any object at all. One way of dealing with the possibility of nil pointers is to check whether a pointer points to a valid object. If the pointer is valid, save a boolean true, then save the dereferenced pointer. If the pointer is invalid, save a boolean false but don't save the pointer.
When you restore the pointer, rwRestoreGuts() first restores the boolean. If the boolean is true, then rwRestoreGuts() restores the valid pointer. If the boolean is false, then rwRestoreGuts() sets the pointer to nil.
*Saving pointers to objects derived from RWCollectable is easier. It is still possible that a pointer is nil. But if you use:
 
RWvostream& operator<<(RWvostream&, const RWCollectable*);
to save the pointer, the nil pointer will be detected automatically.
Using these guidelines, you can write rwSaveGuts() functions for the example class Gut as follows:
 
void rwSaveGuts(RWvostream& stream, const Gut& gut) {
// Use insertion operators to save fundamental objects,
// Rogue Wave objects, and pointers to
// RWCollectable-derived objects.
stream << gut.fundamentalType_
stream.putSizeT(gut.aSizeTValue_);
stream
<< gut.aRogueWaveObject_
<< gut.anotherRogueWaveObject_
<< gut.pointerToAnRWCollectable_;
// The tricky saving of a pointer
// to a non-RWCollectable object.
if (gut.pointerToAnObject_ == 0) { // Is it a nil pointer?
stream << false; // Yes, don't save.
}else {
stream << true; // No, it's valid
stream << gut.pointerToAnObject_; // so save it.
}
}
void rwSaveGuts(RWFile& stream, const Gut& gut) {
// The body of this function is identical to
// rwSaveGuts(RWvostream& stream, const Gut& gut).
}