Advanced Tools Module User’s Guide : PART II Advanced Tools Module Packages : Chapter 6 Using Object Serialization : Using the Stream Contents Macros
Using the Stream Contents Macros
The stream contents macros are added to a class so that its objects can be serialized. This section introduces the streaming macros you need to use in most situations. For details of these macros and additional macros required in some cases, see Advanced Tools Module | Serialization | Serialization Macros on the Modules tab of the SourcePro C++ API Reference Guide.
The serialization support macros include macros for the header file and macros for the source file. The header file macros declare the underlying streaming implementation methods that make your C++ class serializable. The source file macros define some required streaming functions and help you define the streamContents() function.
Header File Macros
The simplest and most efficient way to serialize your classes is to build serialization directly into your objects (intrusive serialization) using these macros:
RW_DECLARE_VIRTUAL_STREAM_FNS(className)
RW_DECLARE_STREAMABLE_POINTER(className)
RW_DECLARE_STREAMABLE_AS_SELF(className)
RW_DECLARE_STREAMABLE_AS_BASE(className)
The RW_DECLARE_VIRTUAL_STREAM_FNS macro should be placed inside the class declaration—just inside the opening curly brace is a good place to put it. This macro declares, among other things, a streamContents() method, used to add the contents of your object to a virtual stream.
The RW_DECLARE_STREAMABLE_POINTER macro should be placed in the header file outside the class declaration. This macro declares global serialization operators.
The RW_DECLARE_STREAMABLE_AS_SELF macro should be placed in the header of the class outside the class declaration. This macro declares the factory for your class and declares its registrar.
The RW_DECLARE_STREAMABLE_AS_BASE macro should be placed after the above macro in the header of your class. It declares a registrar for your class's factory for when the class is serialized through a base pointer.
You can also enable streaming with these macros, which provide special handling for certain data types:
RW_DECLARE_STREAMABLE_VAL_SEQUENCE for streaming Rogue Wave value-based template collections
RW_DECLARE_STREAMABLE_PTR_SEQUENCE for streaming Rogue Wave pointer-based template collections
RW_DECLARE_STREAMABLE_STD_SEQUENCE for streaming Standard C++ Library sequences
RW_DECLARE_STREAMABLE_COLLECTABLE_SEQUENCE for streaming Rogue Wave RWCollectable-based sequences
To enable streaming of maps (associations), use the corresponding macros:
RW_DECLARE_STREAMABLE_VAL_MAP
RW_DECLARE_STREAMABLE_PTR_MAP
RW_DECLARE_STREAMABLE_STD_MAP
RW_DECLARE_STREAMABLE_COLLECTABLE_MAP
Source File Macros
Preparing the source file to define a serializable class is nearly as straightforward as modifying the header file. As in the case of the class declaration, there are two primary macros you must place in the source file.
RW_DEFINE_STREAMABLE_POINTER(className)
Apply this macro to all classes involved in the serialization, including abstract base classes, non-abstract base classes, and derived classes. For abstract base classes, apply only this macro.
RW_DEFINE_STREAMABLE_AS_SELF(className)
Apply this macro to a class if its instantiations will be serialized as pointers directly to the instantiations. This macro can be applied to non-abstract base classes or derived classes. It cannot be applied to abstract base classes because the macro generates code for the instantiation of the class, which is impossible for abstract base classes.
RW_DEFINE_STREAMABLE_AS_BASE(derivedClass,baseClass)
Apply this macro to a class derived from a base class if its instantiations will be serialized as pointers to the base class. The base class may be either abstract or non-abstract. The important distinction is that the derived class is being serialized through virtual indirection.
Be sure to indicate all inheritance relationships with RW_DEFINE_STREAMABLE_AS_BASE. For instance, if you have the inheritance relationship C->B->A (C inherits from B, which inherits from A), you need to add the following three lines:
RW_DEFINE_STREAMABLE_AS_BASE(B, A)
RW_DEFINE_STREAMABLE_AS_BASE(C, B)
RW_DEFINE_STREAMABLE_AS_BASE(C, A)
Just having
RW_DEFINE_STREAMABLE_AS_BASE(B, A)
RW_DEFINE_STREAMABLE_AS_BASE(C, B)
is not enough to allow serializing a C* through an A*.
The streaming support macros also include a set of helper macros to help you define the streamContents() member function used for object serialization. The ones you’ll use most often are:
RW_BEGIN_STREAM_CONTENTS(className)
Begins the streamContents() function.
RW_END_STREAM_CONTENTS
Ends the streamContents() function.
RW_STREAM_ATTR_GET_SET(attrName, attrType, get, set)
Streams the member data accessed by get() and set() member functions.
RW_STREAM_ATTR_MEMBER(attrName, memberName)
Streams the member data indicated by memberName using the label attrName.
RW_STREAM_PARENT(parentClass)
If your serializable class is derived from a serializable base class, place RW_STREAM_PARENT(parentClass) just after the begin macro. This calls streamContents() on the base class, effectively chaining the function calls to stream the contents of the base class before streaming the derived class.
Macros for External Serialization
Some of the macros mentioned earlier can be used for either intrusive or external serialization. Others, such as RW_DECLARE_VIRTUAL_STREAM_FNS, for example, can be used only in the class files. In those cases, the Serialization package provides equivalent external macros:
RW_DECLARE_EXTERNAL_STREAM_FNS
RW_DECLARE_EXTERNAL_STREAMABLE_POINTER
RW_DEFINE_EXTERNAL_STREAMABLE_POINTER
RW_DECLARE_EXTERNAL_STREAMABLE_AS_SELF
RW_DEFINE_EXTERNAL_STREAMABLE_AS_SELF
RW_DECLARE_EXTERNAL_STREAMABLE_AS_BASE
RW_DEFINE_EXTERNAL_STREAMABLE_AS_BASE
RW_BEGIN_EXTERNAL_STREAM_CONTENTS
RW_STREAM_EXTERNAL_PARENT
Macro Summary
Table 3 lists the macros most commonly used for serialization. The following sections explain how to use these macros.
Table 3 – Header file macros for serialization 
Name
Use
Intrusive or external serialization
 
RW_DECLARE_FRIEND_CTOR_METHOD (derivedClass, baseClass)
When a derived class has a non-public default constructor, use this macro for each base class that might be streamed in as a polymorphic pointer. Intrusive or external. Put in header file inside the derived class declaration.
RW_DECLARE_STREAMABLE_PTR_MAP (container)
Declares global serialization operators for streaming maps (associations) of pointers. Intrusive or external. Put in header file outside the class declaration.
RW_DECLARE_STREAMABLE_PTR_SEQUENCE (container)
Declares global serialization operators for streaming Rogue Wave pointer-based template collections. Intrusive or external. Put in header file outside the class declaration.
RW_DECLARE_STREAMABLE_STD_MAP (container)
Declares global serialization operators for streaming maps (associations) of Standard C++ Library types. Intrusive or external. Put in header file outside the class declaration.
RW_DECLARE_STREAMABLE_STD_SEQUENCE (container)
Declares global serialization operators for streaming Standard C++ Library sequences. Intrusive or external. Put in header file outside the class declaration.
RW_DECLARE_STREAMABLE_VAL_MAP (container)
Declares global serialization operators for streaming maps (associations) of value-based templates. Intrusive or external. Put in header file outside the class declaration.
RW_DECLARE_STREAMABLE_VAL_SEQUENCE (container)
Declares global serialization operators for streaming Rogue Wave value-based template collections. Intrusive or external. Put in header file outside the class
RW_DECLARE_STREAMABLE_COLLECTABLE_MAP (container)
Declares global serialization operators for streaming maps (associations) of RWCollectable-based associative collections. Intrusive or external. Put in header file outside the class declaration.
RW_DECLARE_STREAMABLE_COLLECTABLE_SEQUENCE(container)
Declares global serialization operators for streaming Rogue Wave RWCollectable based collections. Intrusive or external. Put in header file outside the class declaration.
RW_DEFINE_STREAMABLE_TEMPLATE_POINTER (className)
Defines global serialization operators to provide serialization support for template classes. (For other classes, use RW_DEFINE_STREAMABLE_POINTER in the source file.)
Intrusive serialization only
 
RW_DECLARE_VIRTUAL_STREAM_FNS (className)
Declares streamContents(), used to add the contents of your object to a virtual stream, and other things. Put in header file inside the class declaration. (For external, use RW_DECLARE_EXTERNAL_STREAM_FNS).
RW_DECLARE_STREAMABLE_POINTER (className)
Declares global serialization operators, for streaming most class types. Intrusive. Put in header file outside the class declaration.
RW_DECLARE_STREAMABLE_AS_SELF (className)
Declares class's factory and its registrar. Intrusive. Place in header file outside class declaration.
RW_DECLARE_STREAMABLE_AS_BASE (className)
Declares class's factory registrar for serialization through base class pointers. Place in header file outside class declaration.
External serialization only
 
RW_DECLARE_EXTERNAL_STREAM_FNS (className)
Declares streamContents(), used to add the contents of your object to a virtual stream, and other things. (For intrusive, use RW_DECLARE_VIRTUAL_STREAM_FNS.)
RW_DECLARE_EXTERNAL_STREAMABLE_POINTER(className)
Declares the serialization streaming operators for streaming objects through pointers to class objects.
RW_DECLARE_EXTERNAL_STREAMABLE_AS_SELF(className)
Declares the factory for the class and declares the factory's registrar. Place in header file outside the class declaration.
RW_DECLARE_EXTERNAL_STREAMABLE_AS_BASE(className, baseClassName)
Declares the factory registrar for streaming objects through pointers to base classes. Place after the macro above.
Table 4 – Source file macros for serialization 
Name
Use
Intrusive or external serialization
 
RW_END_STREAM_CONTENTS
Ends the streamContents() function.
RW_INPUT_STREAM
Used in custom code to access the object input stream.
RW_OUTPUT_STREAM
Used in custom code to access the object output stream.
RW_STREAM_ATTR_GET_SET(attrName, attrType, get, set)
Identifies an attribute of the class to be streamed in terms of a get() and set() function pair. This is useful in external streaming when the internal data member is private but has public get() and set() functions.
RW_STREAM_ATTR_MEMBER(attrName, memberName)
Identifies a data member as an attribute of the class. If using external streaming, the data member must be public.
RW_WHEN_INPUT
Used to insert custom code into stream contents that only executes during input operations.
RW_WHEN_OUTPUT
Used to insert custom code into stream contents that only executes during output operations.
Intrusive serialization only
 
RW_BEGIN_STREAM_CONTENTS(className)
Starts the streamContents() function. Put in source file for class. (For external, use RW_BEGIN_EXTERNAL_STREAM_CONTENTS.)
RW_DEFINE_STREAMABLE_AS_BASE (derivedClass, baseClass)
Allows concrete derived types to be streamed out and streamed back in as pointers to their base class. Put in source file for class. (For external, use RW_DEFINE_EXTERNAL_STREAMABLE_AS_BASE.)
RW_DEFINE_STREAMABLE_AS_SELF (className)
Apply this macro to a class if its instantiations will be serialized as pointers directly to the instantiations. (For external, use RW_DEFINE_EXTERNAL_STREAMABLE_AS_SELF.) Do not use this macro with abstract base classes (See “Source File Macros”.).
RW_DEFINE_STREAMABLE_POINTER (className)
Defines the global serialization operators for pointers. Put in source file for class. (For external, use RW_DEFINE_EXTERNAL_STREAMABLE_POINTER. For template classes, use RW_DEFINE_STREAMABLE_TEMPLATE_POINTER in the header file.)
RW_STREAM_PARENT(parentClass)
For classes derived from a serializable base class. Calls streamContents() on the base class to stream the contents of the base class before streaming the derived class. Put in source file for class. (For external, use RW_STREAM_EXTERNAL_PARENT.)
External serialization only
 
RW_BEGIN_EXTERNAL_STREAM_CONTENTS (className)
Starts the streamContents() function. Put in separate source file. (For intrusive, use RW_BEGIN_STREAM_CONTENTS.)
RW_DEFINE_EXTERNAL_STREAMABLE_AS_BASE(derivedClass, baseClass)
Allows concrete derived types to be streamed out and streamed back in as pointers to their base class. Put in separate source file. (For intrusive, use RW_DEFINE_STREAMABLE_AS_BASE.)
RW_DEFINE_EXTERNAL_STREAMABLE_POINTER (className)
Defines the global serialization operators. Put in separate source file. (For intrusive, use RW_DEFINE_STREAMABLE_POINTER.)
RW_DEFINE_EXTERNAL_STREAMABLE_AS_SELF (className)
Apply this macro to a class if its instantiations will be serialized as pointers directly to the instantiations. Put in separate source file. (For intrusive, use RW_DEFINE_STREAMABLE_AS_SELF.)
RW_STREAM_EXTERNAL_PARENT(parentClass)
For classes derived from a serializable base class. Calls streamContents() on the base class to stream the contents of the base class before streaming the derived class. Put in separate source file. (For intrusive, use RW_STREAM_PARENT.)