Envelope(Message& data);This constructor creates an Envelope that contains the Message
data,
which MUST have been allocated with new.
Message objects have reference counts; at any time, the reference count equals the number of Envelope objects that contain (refer to) the Message object. When the reference count drops to zero (because of execution of a destructor or assignment operator on an Envelope object), the Message will be deleted. Class Envelope defines an assignment operator, copy constructor, and destructor. The main work of these functions is to manipulate reference counts. When one Envelope is copied to another, both Envelopes refer to the same message.
int empty() const;Return TRUE if the Envelope is "empty" (points to the dummy message), FALSE otherwise.
const Message* myData() const;Return a pointer to the contained Message. This pointer must not be used to modify the Message object, since other Envelopes may refer to the same message.
Message* writableCopy();This method produces a writable copy of the contained Message, and also zeros the Envelope (sets it to the empty message). If this Envelope is the only Envelope that refers to the message, the return value is simply the contained message. If there are multiple references to the message, the
clone
method is called on the Message, making a duplicate, and the duplicate is returned. The user is now responsible for memory management of the resulting Message. If it is put into another Envelope, that Envelope will take over the responsibility, deleting the message when there is no more need for it. If it is not put into another Envelope, the user must make sure it is deleted somehow, or else there will be a memory leak.
int typeCheck(const char* type) const;This member function asks the question "is the contained Message of class
type,
or derived from type"
? It is implemented by calling isA
on the Message. Either TRUE or FALSE is returned.
const char* typeError(const char* expected) const;This member function may be used to format error messages for when one type of Message was expected and another was received. The return value points to a static buffer that is wiped out by subsequent calls.
const char* dataType() const;All these methods are "passthrough methods"; the return value is the result of calling the identically named function on the contained Message object.
int asInt() const;
double asFloat() const;
Complex asComplex() const;
StringList print() const;
virtual const char* dataType() const;This function returns the type of the Message. The default implementation returns "DUMMY".
virtual Message* clone() const;This function produces a duplicate of the object it is called on. The duplicate must be "good enough" so that applications work the same way whether the original Message or one produced by
clone()
is received. A typical strategy is to define the copy constructor for each derived Message class and write something like
Message* MyMessage::clone() const { return new MyMessage(*this);}The
virtual int isA(const char*) const;
isA
function returns true if given the name of the class or the name of any base class. Exception: the base class function returns FALSE to everything (as it has no data at all). A macro ISA_FUNC
is defined to automate the generation of implementations of derived class isA
functions; it is the same one as that used for the NamedObj class. The following methods may optionally be redefined.
virtual StringList print() const;This method returns a printable representation of the Message. The default implementation returns a message like
Message class <type>: no print methodwhere
type
is the message type as returned by the dataType
function.
virtual int asInt() const;These functions represent conversions of the Message data to an integer, a floating point value, and a complex number, respectively. Usually such conversions do not make sense; accordingly, the default implementations generate an error message (using the protected member function
virtual double asFloat() const;
virtual Complex asComplex() const;
errorConvert)
and return a zero of the appropriate type. If a conversion does make sense, they may be overridden by a method that does the appropriate conversion. These methods will be used by the MessageParticle class when an attempt is made to read a MessageParticle in a numeric context. One protected member function is provided:
int errorConvert(const char* cvttype) const;This function invokes
Error::abortRun
with a message of the form
Message class <msgtype>: invalid conversion to cvttypewhere
msgtype
is the type of the Message, and cvttype
is the argument.
void operator << (const Envelope& env);This method loads the Message contained in
env
into the Envelope contained in the MessageParticle. Since the Envelope assignment operator is used, after execution of this method both env
and the MessageParticle refer to the message, so its reference count is at least 2.
void getMessage(const Envelope& env);This method loads the message contained in the MessageParticle into the Envelope
env,
and removes the message from the MessageParticle (so that it now contains the dummy message). If env
previously contained the only reference to some other Message, that previously contained Message will be deleted.
void accessMessage(const Envelope& env);
accessMessage
is the same as getMessage
except that the message is not removed from the MessageParticle. It can be used in situations where the same Particle will be read again. We recommend that getMessage
be used where possible, especially for very large message objects, so that they are deleted as soon as possible.