The ObjectStore dump/load facility allows you to
By default, objects are dumped in terms of the primitive values they directly or indirectly contain. You can use the default dump and load processes, or customize the dumping and loading of particular types of objects. You can, for example, dump and load objects in terms of sequences of high-level API operations needed to recreate them, rather than in terms of the primitive values they contain. This is appropriate for certain location-dependent structures, such as hash tables.
To enhance efficiency during a dump, database traversal is performed in address order whenever possible. To enhance efficiency during loads, loaders are generated by the dumper and tailored to the schema involved. This allows the elimination of most run-time schema lookups during the loading.
Read about the dump/load facility in ObjectStore Management Chapter 4, Utilities, osdump: Dumping Databases before you read the discussion in this chapter. This chapter focuses on When Is Customization Required? and addresses the following topics:
You might want to use customization to:
A dumped object and its equivalent loaded object do not necessarily have the same location, that is, the same offsets in their segment. Among the implications of this are the following:
The default dumper and loader also take into account the second implication for ObjectStore collections with hash-table representations. Since a dumped collection element hashes to a different value than the corresponding loaded element does, their hash-table slots are different. So the facility does not simply dump and load the array of slots based on fundamental values (which would result in using the same slot for the dumped and loaded objects).
Instead, it dumps the collection in terms of sequences of high-level API operations (that is, string representations of create() and insert() arguments) that the loader can use to recreate the collection with the appropriate membership.
The default dumper and loader do not take into account the second implication for non-ObjectStore classes. If you have collection classes that use hash-table representations, you must customize their dumping and loading. Any other location-dependent details of data structures (such as encoded offsets) should also be dealt with through customization.
Although the facility provides a great deal of flexibility, customization typically takes the form described for ObjectStore collections above.
For example, when the root of a collection is loaded, the collection elements might not yet exist, so the loader usually creates an empty collection, loads the elements (as well as other objects), and then inserts the elements. And the dumper usually dumps the create() arguments, dumps the elements (and all other objects except nonroot objects), and then dumps the insert() arguments.
It is important to distinguish between nonroots of a data structure and objects that are not part of the data structure at all. For example, if a collection's elements are pointers, the pointer objects are nonroots of the collection's data structure, but the objects pointed to by the elements are not part of the datastructure at all.
for each database, db, specified on the command line { for each segment, seg, in db { // plan mode for each top-level object, o, in seg Invoke the planner for o's type on o // dump mode for each top-level object, o, in seg Invoke the object dumper for o's type on o If necessary, create a fixup dumper for o, and associate it with either seg, db, or the whole dump // fixup mode for each fixup dumper associated with seg Invoke that fixup dumper } // fixup mode for each fixup dumper associated with db Invoke that fixup dumper } // fixup mode for each fixup associated with the whole dump invoke that fixup dumperBy default, object-dump actions sometimes invoke other object-dump actions on embedded objects. The following summarizes the behavior of the different object dump actions invoked by the default dumper for different types of objects:
For each object form the loader processes, it invokes a type-specific object loader, in a manner similar to that described for the dumper.
With the shallow approach, the invocation function creates an ignore record for the argument or does nothing, depending on whether the argument is a nonroot object of the data structure whose dump is being customized.
The shallow approach has better paging behavior, so use it if possible.
For each derived class supporting object dumping, planning, and fixup dumping, perform these steps:
Base Class | Members |
os_Planning_action | operator () |
os_Dumper_specialization | operator () |
should_use_default_constructor() | |
get_specialization_name() | |
os_Fixup_dumper | Constructor |
dump_info() | |
duplicate() |
Customizing Loads
During a load, the loader processes object and fixup forms in the order in which they were emitted by the dumper. To provide a customized loader for a given type, you implement functions that support the following tasks:
Base Class | Members |
os_Type_info | data |
Constructor | |
os_Type_loader | operator () |
load() | |
create() | |
fixup() | |
get() | |
os_Type_fixup_info | fixup_data |
Constructor | |
os_Type_fixup_loader | operator () |
load() | |
fixup() | |
get() |
Specializing os_Planning_action
Your specialization of os_Planning_action handles planning, including the identification of objects for which object forms should not be generated.
If you are using the shallow approach to planning, then, for each type, type, of nonroot object you must define a class that is
class my_table_entry_planner : public os_Planning_action {...}If you are using the deep approach to planning, then, for the type, type, of the root object, you must define a class that is
class my_table_entry_planner : public os_Planning_action {...}The derived class must implement operator ()().
You must also define and register an instance of the derived class.
If a class does not require fixups, then it does not require planning. Even if it does require fixups, it might not require planning. If the fixups do not create any objects that would be dumped normally without planning, planning might be unnecessary.
Implementing operator ()()
void type_planner::operator () ( const os_type& actual_type, void* object )
void type_planner::operator () ( const os_type& actual_type, void* object ) { ... /* Do type verification (optional) */ assert_is_ type(actual_type, object); ... type& obj = ( type&)*object; ... if (should_ignore(obj) { Dumper_reference ignored_object(&obj); Database_table::get().insert(ignored_object); } ... }In this example, assert_is_ type() and should_ignore() are user-defined.
If necessary, you can include application-specific processing in place of the "..."s.
{ ... /* Do type verification (optional) */ assert_is_ type(actual_type, object); ... type& obj = ( type&)*object; ... if (should_ignore(obj) { Dumper_reference ignored_object(&obj); Database_table::get().insert(ignored_object); } (* reachable_type_planner)(obj.reachable_pointer); ... }If you can define dump-related members of type, you can use the following approach:
void < type>_planner::operator () (const os_type& actual_type, void* object) { ... type& obj = ( type&)*object; obj.plan_dump(); ... } void type::plan_dump () { ... if (should_ignore(obj) { Dumper_reference ignored_object(&obj); Database_table::get().insert(ignored_object); } ... /* consider directly reachable objects */ reachable_pointer->plan_dump(); ... }
static type_planner the_ type_planner;and register it by including an entry in the global array entries[]:
static os_Planner_registration_entry planner_entries[] = { ... os_Planner_registration_entry(" type", &the_ type_planner), ... } static const unsigned number_planner_registration_entries = OS_NUMBER_REGISTRATIONS( planner_entries, os_Planner_registration_entry ); static os_Planner_registration_block block( planner_entries, number_planner_registration_entries, __FILE__, __LINE__ );This code should be at top level.
To customize the dump and load of instances of a type, type, define a class that is
class my_collection_dumper : public os_Dumper_specialization {...}The derived class must implement the following functions:
You must also define and register an instance of the derived class.
void type_dumper::operator () ( const os_class_type& actual_class, void* object )An object form has the following structure:
id ( Type) valueWhen you supply an object-form dumper, you are responsible for generation of the value portion only. The functions that generate the rest of the object form are inherited from os_Dumper_specialization.
The value portion is generated by operator ()(). Implement operator ()() to generate ASCII from which a loader can reconstruct function arguments. The arguments should be those required for recreation of the root portion of the object being dumped.
Define operator ()() to do the following:
If type is a nonarray type, the typical implementation has the following form:
void type_dumper::operator () ( const os_class_type& actual_class, void* object ) { ... // optional type verification // assert function defined by user assert_is_ type(actual_class, object); ... // cast the void* type& obj = (<Type&>)*object; ... // output the object form get_stream() << obj.get_representation() << ' ' << obj.get_size() << ' '; ... // create a Fixup_dumper on the stack type_fixup_dumper fixup( get_stream(), *this, actual_class, object ); // insert a fixup dumper for processing at the end of the dump Database_type::get().insert(fixup); }This example assumes that the output of type::get_representation() and type::get_size() provides sufficient information to create the root of object.
You can insert application-specific processing in place of the "..."s, but this is not required.
You do not usually have to customize array types, since you can customize the element type of an array type. The default array dumper will call the custom dumper on each array element.
If you do want to customize the array dumper, implement this overloading of the invocation operator:
void type_dumper::operator () ( const os_class_type& actual_class, void* object, unsigned number_elements ) { ... }
os_boolean should_use_default_constructor( const os_class_type& class_type ) const;When you customize the dump and load of a type, you supply code to construct instances of the type during a load - see Implementing create(). This code is used for all nonembedded instances of the type. For an instance of the type embedded in a noncustomized type, the loader calls the customized type's constructor automatically, using code generated by the dumper.
All other data members should have the same value type as the coreresponding member of type. All data members of type_data should have the same name as the coreresponding member or base class of type.
If you implement type_Loader::should_use_default_constructor() to return 0, the dumper-generated code calls the no-argument constructor. If you implement type_Loader::should_use_default_constructor() to return 1, the dumper-generated code calls the special loader constructor.
char* get_specialization_name( const os_class_type& class_type ) const;You must define this function only if there is a subtype of type such that both of the following hold:
Deleting the returned string is the responsibility of the caller of this function.
static type_dumper the_ type_dumper;and register it by including an entry in the global array entries[]:
static os_Dumper_registration_entry entries[] = { ... os_Dumper_registration_entry(" type", &the_ type_dumper), ... }; static const unsigned number_dumper_registration_entries = OS_NUMBER_REGISTRATIONS( entries, os_Dumper_registration_entry ); static os_Dumper_registration_block block( entries, number_dumper_registration_entries, __FILE__, __LINE__ );This code should be at top level.
To customize the dump and load of instances of a type, type, define a class that is
class my_collection_fixup_dumper : public os_Fixup_Dumper {...}The derived class must implement the following functions:
void type_fixup_dumper::dump_info()A fixup form has the following structure:
fixup id ( Type) infoWhen you supply a fixup-form dumper, you are responsible for generation of the info portion only. The functions that generate the rest of the fixup form are inherited from os_Fixup_dumper.
The info portion is generated by dump_info(). Implement dump_info() to generate ASCII from which a loader can reconstruct function arguments. The arguments should be those required for recreation of the nonroot portion of the object being fixed up.
Where type is the type of object being fixed up, the function should
For example, a fixup form for a collection might include ASCII from which a dumper can reconstruct pointers to all the collection's elements:
void type_fixup_dumper::dump_info() const { ... const void* object = get_object_to_fix(); assert_is_ type(get_type(), object); ... type& obj = ( type&)*object; ... os_Dumper_reference ref; for (unsigned count = 0; count < obj.get_size(); ++count) { element_type& element = obj[count]; ref = element; get_stream() << ref << ' '; } // info terminator -- assumes no null elements ref = 0; get_stream() << ref << ' '; ... }In this example,
Fixup& type_fixup_dumper::duplicate()Implement duplicate() to allocate a copy of this type_fixup_dumper in the specified segment. The following example assumes type_fixup_dumper defines a copy constructor and a get_os_typespec() function.
Fixup& type_fixup_dumper::duplicate ( os_segment& segment ) const { return *new(segment, type_fixup_dumper::get_os_typespec()) type_fixup_dumper(*this); }Be sure to include type_fixup_dumper in the application schema of the emitted loader.
type_fixup_dumper ( os_Dumper_stream&, os_Dumper&, const os_class_type&, const os_Dumper_reference object_to_fix, unsigned number_elements = 0 );Implement the constructor to pass the arguments to the base type constructor:
os_Fixup_dumper ( os_Dumper_stream&, os_Dumper&, const os_class_type&, const os_Dumper_reference object_to_fix, unsigned number_elements = 0 );
class type_info : public os_Type_infoA type_info holds information about the loading of the object form currently being processed. See os_Type_info. The derived type must define two members:
type_loader::operator ()() then passes the type_info to create(), which uses the information to create the postload object.
Your specialization can add any members you find convenient.
type_data &data;To implement this public data member, derive a type, type_data, from os_Type_data (this base class has no members). Define a data member of type_data for each portion of the object-form value emitted by type_dumper::operator ()(). These members will be set by load() based on information in the load stream, and used later by create() and fixup() to recreate the object being loaded.
type_data should have a data member for each data member and base class of type. For pointer and (C++) reference members of type, the type_data member should be of type os_Fixup_reference. For embedded class members, the type should be embedded_class_data. All data members corresponding to a base class should have the base class as value type.
All other data members should have the same value type as the coreresponding member of type. All data members of type_data should have the same name as the coreresponding member or base class of type.
type_info ( os_Type_loader cur_loader, os_Loader_stream lstr, os_Object_info& info, type_data &data_arg );Implement this function to set type_info::data to data_arg. Pass the first three arguments to the following os_Type_info constructor:
os_Type_info ( os_Type_loader& cur_loader, os_Loader_stream& lstr, os_Object_info& info );cur_loader is the loader for the object currently being loaded.
lstr is the dump stream from which the current object form is being processed.
info is the loader info for the object being loaded.
When you call type_info:: type_info() from within type_loader::operator ()(),
To customize the dumping and loading of instances of a type, type, define a class that is
class my_collection_loader : public os_Type_loader {...}The derived class must implement the following functions:
os_Loader_action* type_loader::operator () ( os_Loader_stream& stream, os_Loader_info& previous_info )Implement the invocation operator to do the following:
Loader_action* type_loader::operator () ( os_Loader_stream& stream, os_Loader_info& previous_info ) { os_Object_info& object_info = previous_info; type_data data; type_info info(*this, stream, object_info, data); load(stream, data); create(info); return 0; }
Loader_action* type_loader::load ( Loader_stream& stream, Type_data& given_data )This function is responsible for reading the value portion of the object form from the load stream, and setting the data members of given_data accordingly.
Once load() sets the data members of given_data, create() or fixup() uses given_data to guide recreation of the object being loaded.
Here is an example:
Loader_action* type_loader::load ( Loader_stream& stream, Type_data& given_data ) { type_data& data = ( type_data&) given_data; ... /* Input each part of the dumped value. */ stream >> data.representation; stream >> data.size; ... return 0; }If the current portion of the dumped value is an embedded object form for a class, embedded_class, retrieve that class's loader with embedded_class_loader::get(), and call embedded_class_loader::load(), passing stream and the embedded_class_data embedded in type_data:
/* Load embedded class. */ embedded_type_loader::get().load( stream, data. member );
void type_loader::create (Loader_info& given_info) ;This function is responsible for creating the persistent object corresponding to the object form being loaded. Arguments to persistent new can be retrieved from given_info. Arguments to the object constructor can be retrieved from the type_data associated with given_info.
The function should
The function must also create a mapping record that records the predump and postload locations of the object being loaded:
Here is an example:
void <Type>_loader::create (Loader_info& given_info) { type_info& info = ( type_info&) given_info; type* value; void* location = info.get_replacing_location(); if (location) value = ::new(location) type(info.data); else { value = new ( &info.get_replacing_segment(), type::get_os_typespec() ) type(info.data); // Insert a mapping of the constructed object's original // location to its replacing location into the Database_table. const os_type& value_type = info.get_type(); Dumper_reference replacing_location(value); info.set_replacing_location(value); Database_table::get().insert( info.get_original_location(), replacing_location, value_type ); } fixup(info.data, value); }
void type_loader::fixup (Type_data& given_data, void* object)The default loader automatically adjusts pointers and references in loaded objects. If you supply a type-specific loader, type_loader, you must explicitly direct the loader to make these adjustments for instances of type.
If create() does not use the no-argument constructor, and instances of type contain no pointers, no C++ references, and no ObjectStore references, you do not have to implement this function. You never have to implement a no-op fixup().
Here is a typical implementation:
void type_loader::fixup (Type_data& given_data, void* object) { type_data& data = ( type_data&) given_data; type& obj = type& *object; ... /* Fixup pointer. */ Dumper_reference pointer_location(&obj.pointer); Dumper_reference original_referent_location(data.pointer); Database_table::get().insert (Reference_fixup_kind::pointer, pointer_location, original_referent_location); ... }If a portion of the dumped value is an embedded object form for a class, embedded_class, retrieve that class's loader with embedded_class_loader::get(), and call embedded_class_loader::fixup(), passing the embedded_class_data embedded in type_data and the corresponding object embedded in obj:
/* Fixup embedded object. */ embedded_type_loader::get().fixup( data. member, &obj. member );
static type_loader the_ type_loader; Type_loader& type_loader::get () { return the_ type_loader; }
static type_loder the_ type_loader;and register it by including an entry in the global array entries[]:
static os_Loader_registration_entry entries[] = { ... os_Loader_registration_entry(" type", &the_ type_loader), ... } static const unsigned number_loader_registration_entries = OS_NUMBER_REGISTRATIONS( entries, os_Loader_registration_entry ); static os_Loader_registration_block block( entries, number_loader_registration_entries, __FILE__, __LINE__ );This code should be at top level.
class type_fixup_info : public os_Type_fixup_infoA type_fixup_info holds information about the loading of the fixup form currently being processed. os_Type_fixup_info is derived from os_Type_info.
type_fixup_info must define two members:
type_loader::operator ()() then passes the type_fixup_info to fixup(), which uses the information to create the postload object.
Your specialization can add any members you find convenient.
type_fixup_data &fixup_data;To implement this public data member, derive a type, type_fixup_data, from os_Type_data. Define a data member of type_fixup_data for each portion of the object-form value emitted by type_fixup_dumper::dump_info(). These members will be set by load() based on information in the load stream, and used later by fixup() to recreate the object being loaded.
type_fixup_info ( os_Type_fixup_loader cur_fixup_loader, os_Loader_stream lstr, os_Object_info& info, type_fixup_data &data_arg );Implement this function to set type_fixup_info::data to data_arg. Pass the first three arguments to the following os_Type_fixup_info constructor:
os_Type_fixup_info ( os_Type_loader& cur_loader, os_Loader_stream& lstr, os_Fixup_info& info );cur_loader is the loader for the object currently being fixed up.
lstr is the dump stream from which the current fixup form is being processed.
info is the fixup loader info for the object being fixed up.
When you call type_fixup_info:: type_fixup_info() from within type_loader::operator ()()
To customize the dump and load of instances a type, type, define a class that is:
class my_collection_fixup_loader : public os_Type_fixup_loader {...}The derived class must implement the following functions:
os_Loader_action* type_fixup_loader::operator () ( os_Loader_stream& stream, os_Loader_info& previous_info )Implement the invocation operator to do the following:
Here is an example:
os_Loader_action* type_fixup_loader::operator () ( os_Loader_stream& stream, os_Loader_info& previous_info ) { os_Fixup_info& fixup_info = previous_info; type_fixup_data data; type_fixup_info info(*this, stream, fixup_info, data); while( load(stream, data)) fixup(info); return 0; }This assumes load() is implemented to return 0 when the entire info portion has been consumed.
If the info portion is made up of dumped char*s, allocate the type_Fixup_info inside the load loop:
os_Loader_action* type_fixup_loader::operator () ( os_Loader_stream& stream, os_Loader_info& previous_info ) { os_Fixup_info& fixup_info = previous_info; type_fixup_data data; while( load(stream, data)) type_fixup_info info(*this, stream, fixup_info, data); fixup(info); return 0; }
Loader_action* load ( Loader_stream& stream, Type_data& given_data );This function is responsible for reading the info portion of the fixup form from the load stream, and setting the data members of given_data accordingly. If the invocation operator calls load() just once, load() must consume all of the info portion. If the invocation operator calls load() multiple times, each call to load() must consume just part of the info portion.
Once load() sets the data members of given_data, fixup() uses given_data to guide recreation of the nonroot portion of the object being fixed up.
If load() consumes just part of the info portion, you can return 0 when the entire info portion has been consumed, and return nonzero otherwise. You must cast the return value to os_Loader_action*.
Here is an example:
Loader_action* type_fixup_loader::load ( Loader_stream& stream, Type_data& given_data ) { type_fixup_data& data = ( type_fixup_data&) given_data; ... /* Input one part of the dumped value. */ os_Dumper_reference original_ref; stream >> original_ref; if (original_ref == 0) // info terminator return ( (os_Loader_action*) 0 ); else { data.dumper_ref = os_database_table::get().find_reference(original_ref); return ( (os_Loader_action*) 1 ); } }If a portion of the dumped info is an embedded fixup form for a class, embedded_class, load it as follows:
/* Load embedded class. */ embedded_type_fixup_loader::get().load( stream, data. member_3 );
void fixup (os_Type_fixup_info& info);This function performs fixup based on the information passed in. For example, if the object being fixed up is a collection, and each portion of the fixup form identifies a collection element, fixup() would insert an element in the collection.
The function should
void type_fixup_loader::fixup (Type_fixup_info& given_info) { type_fixup_info& info = ( type_fixup_info&) info; Dumper_reference original_location = info.get_original_location(); if ( ! original_location) { // Handle error, there should only be a fixup for an // existing object. } Dumper_reference replacing_location = os_Database_table::get().find_reference(original_location); if ( ! replacing_location) { // Handle error, there should only be a fixup for an // existing object. } type* object = replacing_location; ... /* Do whatever needs to be done to fix the designated object. */ element_type *the_element = ( element_type*) ( info.fixup_data.dumper_ref.resolve() ); object.insert(the_element) ... }Note that info.fixup_data_.dumper_ref is set by type_fixup_loader::load().
static os_Type_fixup_loader& get ();Define a global variable whose value is an instance of type_loader. Define the static function type_loader::get() to return this instance:
static type_fixup_loader the_ type_fixup_loader; os_Type_fixup_loader& type_fixup_loader::get () { return the_ type_fixup_loader; }
static type_fixup_loader the_ type_fixup_loader;Register the instance of the derived class by including an entry in the global array fixup_entries[]:
static os_Fixup_registration_entry fixup_entries[] = { ... os_Fixup_registration_entry(" type", &the_ type_fixup_loader), ... } static const unsigned number_fixup_registration_entries = OS_NUMBER_REGISTRATIONS( fixup_entries, os_Fixup_registration_entry ); static os_Fixup_registration_block block( fixup_entries, number_fixup_registration_entries, __FILE__, __LINE__ );
static os_Database_table& get ();Returns a reference to the (one and only) database table.
void insert ( const os_Dumper_reference source, const os_Dumper_reference target, const os_type& referent_type );Inserts a mapping record that associates a predump object with a postload object. Normally you call this from type_loader::create().
source is a dumper reference to the predump object.
target is a dumper reference to the postload object.
referent_type refers to an os_type representing the type of the object.
void insert ( os_Reference_fixup_kind::Kind kind, const os_Dumper_reference reference, const os_Dumper_reference referent_original_location );Inserts a fixup record that instructs the loader to adjust the pointer, C++ reference, or ObjectStore reference referred to by reference. The loader makes the adjustment after loading all object forms and before loading any fixup forms. Normally you call this from type_loader::fixup().
kind is one of the following:
referent_original_location refers to the predump referent of the pointer or reference to be fixed up.
void insert ( os_segment&, const os_Fixup& fixup );Associates the specified fixup dumper with the specified segment. Each fixup dumper associated with a segment is invoked after all object forms for that segment have been dumped. See Dumper Actions. Normally you call this function from type_dumper::operator ()().
void insert ( os_database&, const os_Fixup& fixup );Associates the specified fixup dumper with the specified database. Each fixup dumper associated with a database is invoked after all object forms for that database have been dumped. See Dumper Actions. Normally you call this function from type_dumper::operator ()().
void insert ( const os_Fixup& fixup );Associates the specified fixup dumper with the entire dump. Each fixup dumper associated with the entire dump is invoked after all object forms for the dump have been dumped. See Dumper Actions. Normally you call this function from type_dumper::operator ()().
void insert ( const os_Dumper_reference ignored_object );Inserts the specified object into the ignored set. If the object is already in the ignored set, the insertion is silently ignored. Before dumping an object, the dumper checks to see if the object is in the ignored set. If it is, the dumper does not dump the object.
ignored_object is a dumper reference to the object that should not be dumped.
os_Dumper_reference find_reference ( const os_Dumper_reference given_reference ) const;Finds the postload object corresponding to a given predump object. Both objects are specified with instances of os_Dumper_reference. given_reference refers to the predump object. The returned reference refers to the corresponding postload object.
If there is no object that corresponds to the referent of given_reference, a null reference is returned.
If given_reference is null, a null reference is returned.
See also os_Database_table::insert() (the first overloading, for mapping records).
os_boolean is_ignored (const os_Dumper_reference obj) const;Returns nonzero if obj is in the ignored set; returns nonzero otherwise. See os_Database_Table::insert(const os_Dumper_Reference().
As with a pointer, once the object referred to by a dumper reference is deleted, use of the reference accesses arbitrary data and might cause a segmentation violation.
You can construct or set a reference with os_Dumper_reference::os_Dumper_reference() or os_Dumper_reference::operator =(). You can resolve a reference with os_Dumper_reference::resolve() or os_Dumper_reference::resolve().
operator void*() const;Returns the pointer for which the specified reference is a substitute.
os_Dumper_reference& operator = (const os_Dumper_reference&);Establishes the referent of the right operand as the referent of the left operand.
os_Dumper_reference& operator = (void* object);Establishes the object pointed to by the right operand as the referent of the left operand.
os_Dumper_reference (const void*);Constructs a reference to substitute for the specified void*.
os_Dumper_reference ( os_unsigned_int32 database_number, os_unsigned_int32 segment_number, os_unsigned_int32 offset );Constructs a reference to the object with the specified database number, segment number, and offset.
os_Dumper_reference (const os_Dumper_reference&);Constructs a reference with the same referent as the specified reference.
os_Dumper_reference ();Constructs a null reference, that is, a reference without a current referent. See os_Dumper_reference::operator =().
void* resolve() const;Returns the valid void* for which the specified reference is a substitute.
os_boolean operator == (const os_Dumper_reference&) const;Returns 1 if the arguments have the same referent; returns 0 otherwise.
os_boolean operator < (const os_Dumper_reference&) const;If the first argument and second argument refer to elements of the same array or one beyond the end of the array, a return value of 1 indicates that the referent of the first argument precedes the referent of the second, and a return value of 0 indicates that it does not. Otherwise the results are undefined.
os_boolean operator > (const os_Dumper_reference&) const;If the first argument and second argument refer to elements of the same array or one beyond the end of the array, a return value of 1 indicates that the referent of the first argument follows the referent of the second, and a return value of 0 indicates that it does not. Otherwise the results are undefined.
os_boolean operator != (const os_Dumper_reference&) const;Returns 1 if the arguments have different referents; returns 0 otherwise.
os_boolean operator >= (const os_Dumper_reference&) const;If the first argument and second argument refer to elements of the same array or one beyond the end of the array, a return value of 1 indicates that the referent of the first argument follows or is the same as the referent of the second, and a return value of 0 indicates that it does not. Otherwise the results are undefined.
os_boolean operator <= (const os_Dumper_reference&) const;If the first argument and second argument refer to elements of the same array or one beyond the end of the array, a return value of 1 indicates that the referent of the first argument precedes or is the same as the referent of the second, and a return value of 0 indicates that it does not. Otherwise the results are undefined.
os_boolean operator ! () const;Returns nonzero if the reference is null, that is, has no current referent.
os_database* get_database () const;Returns the database containing the referent of this reference.
os_unsigned_int32 get_database_number () const;Returns the database table number of the database containing the referent of this reference.
os_segment* get_segment () const;Returns the segment containing the referent of this reference.
os_unsigned_int32 get_segment_number () const;Returns the segment number of the segment containing the referent of this reference.
os_unsigned_int32 get_offset () const;Returns the offset of the referent of this reference within its segment.
const char* get_string () const;Returns the reference's value as an encoded string.
os_boolean is_valid () const;Returns nonzero if this is completely valid; returns 0 otherwise.
os_Type_info ( os_Type_loader&, os_Loader_stream&, os_Object_info& );Constructs an object to hold information about the object currently being loaded by a specified loader. You must also pass as constructor argument the info for the previous object load. See Implementing operator ()() in the section on specializing os_Type_loader.
os_Type_info::get_original_location()
os_Dumper_reference get_original_location () const;Returns a reference that resolves to the predump location of the object being loaded. See Implementing create() in the section on specializing os_Type_loader.
os_Type_info::get_replacing_location()
os_Dumper_reference get_replacing_location () const;Returns a reference that resolves to the postload location of the object being loaded. See Implementing create() in the section on specializing os_Type_loader.
os_Type_info::set_replacing_location()
void set_replacing_location (os_Dumper_reference location);Records the location at which the postload object has been created. See Implementing create() in the section on specializing os_Type_loader.
const os_type& get_type () const;Returns a reference to an os_type that represents the type of the object being loaded. See Implementing create() in the section on specializing os_Type_loader.
os_Type_info::get_replacing_segment()
os_segment& get_replacing_segment () const;Returns a reference to the postload segment of the object being loaded.
os_database& get_replacing_database () const;Returns a reference to the postload database of the object being loaded.
os_Fixup_dumper::os_Fixup_dumper()
os_Fixup_dumper ( os_Dumper_stream&, os_Dumper&, const os_class_type&, const os_Dumper_reference object_to_fix, unsigned number_elements = 0 );Constructs a fixup dumper. The constructors for your customized fixup dumpers pass arguments to this constructor.
os_Fixup_dumper (const os_Fixup_dumper&);Copy constructor.
os_Dumper_reference get_object_to_fix () const;Returns a dumper reference to the object for which this dumps a fixup form. See Implementing dump_info() in the section on specializing os_Fixup_dumper.
os_type &get_type() const;Returns a reference to an os_type that represents the type of the object for which this is a fixup dumper. See Implementing dump_info() in the section on specializing os_Fixup_dumper.
virtual ~os_Fixup ();Virtual destructor
unsigned get_number_elements () const;If this is a fixup for an array, returns the number of elements to be fixed up. Returns 0 otherwise.
Updated: 03/31/98 15:30:45