<Off private members for sequencing objects. >= (U->) off_seq_t _seq; // Next sequence nb.
<Off protected methods for sequencing objects. >= (U->)
// Gets a new sequence number. (Container object must be locked.)
inline off_seq_t get_seq(void) {return _seq++;};
Note that the object must be locked during get_seq and
the sequence number must be initialized by the aggregate.
<Off initialization for sequencing objects. >= (U->) _seq=0;
To ensure that references to system resources are valid, every resource includes a magic number which can be tested at run time.
The magic number is actually a string of four characters.
<Off magic number. >= (U->)
class off_Magic {
private:
off_magic_t m_number; // The magic number.
public:
// Creates an unitilized magic number.
off_Magic(void){;}
// Creates a magic number.
off_Magic( const char *str ) : m_number(*(off_magic_t*)str) { assert(str); }
// Creates a magic number.
off_Magic( const off_magic_t n) : m_number(n) { }
// Test a magic number
boolean_t operator==(const off_Magic other) const {
return (m_number == other.m_number);
}
boolean_t operator==(const off_magic_t other) const {
return (m_number == other);
}
boolean_t operator!=(const off_Magic other) const {
return (m_number != other.m_number);
}
boolean_t operator!=(const off_magic_t other) const {
return (m_number != other);
}
<Other public members of off_Magic. >
};
Definesoff_Magic(links are to index).
This code depends on definitions found in types.h.
<Off magic number dependencies. >= (U->) #include <assert.h> // for assert #include <flux/types.h> // for boolean_t natural_t et al.
Resources can now include this member.
<Off private members for integrity checked resources. >= (U->) off_Magic _magic; // Magic number
Concrete instances of system resource should initialize the magic number with appropriate values for further checking. It must be initialized at resource instantiation time.
<Off initialization for integrity checked resources with magic. >= (U-> U->)
_magic(magic)
Thereafter, the magic number can be obtained with this method.
<Off protected methods for integrity checked resources. >= (U->)
// Returns the magic number.
off_Magic get_magic(void) const {return _magic;}
As the magic number identifies the class a resource belongs to, we also use magic numbers to obtain the name for a given magic number. This way every resource can know its own class.
<Other public members of off_Magic. >= (<-U)
// Returns a full name for this magic number.
const char *nameof(void);
Its implementation is a big switch on the magic number value.
<off_Magic::nameofimplementation. >= (U->) // Returns a full name for this magic number. const char *off_Magic::nameof(void) { switch(m_number) { <off_Magic::nameofcase form_numbers. > default: return "bad magic"; } }
As we introduce new magic numbers through this document, we will add
new case statements to this method. Those statements use constants
(which are also exported) for existing magic numbers.
<Off magic number data type. >= (U->)
// Magic number constants.
enum {
OFF_MAGIC_START_AT=0xdeadbeef,
<Off magic numbers. >
};
typedef int off_magic_t;
\subsubsection{Magic numbers \cpp{} source files}
Magic number code is kept in klib/Magic.h and klib/Magic.C.
<Magic.h*>= <Read the literate code instead warning. > #ifndef __OFF_MAGIC_H #define __OFF_MAGIC_H 1 <Off magic number dependencies. > <Off magic number data type. > <Off magic number. > #endif // __OFF_MAGIC_H
<Magic.C*>=
<Read the literate code instead warning. >
#include <klib/Magic.h> // Exported interface.
<off_Magic::nameof implementation. >