From 57db34632a8ae1241d228f902e43bf6809415120 Mon Sep 17 00:00:00 2001 From: chatty Date: Mon, 13 Feb 1995 16:56:17 +0000 Subject: NewMessage -> DecodeMessage ConvertAnswer -> DecodeAnswer Incorporated use of Activate --- comm/MsgStream.cc | 70 +++++++++++++++++++++++++++++++++---------------------- comm/MsgStream.h | 4 ++-- 2 files changed, 44 insertions(+), 30 deletions(-) (limited to 'comm') diff --git a/comm/MsgStream.cc b/comm/MsgStream.cc index e91860b..b3becea 100644 --- a/comm/MsgStream.cc +++ b/comm/MsgStream.cc @@ -219,18 +219,18 @@ The output buffer can be flushed by the application, or by the stream itself if Incoming messages are handled by the virtual function \fun{HandleRead} of class \typ{UchChannel}: it is redefined so that incoming bytes are packed into messages. When a full message is available, \fun{HandleRead} calls the virtual -function \fun{NewMessage}. In the class \typ{UchMsgStream}, this virtual function does -nothing but discarding the message. +function \fun{DecodeMessage} that instantiates a message, then calls the virtual function \fun{Activate} for that +message. Messages are not automatically destroyed. Messages that need an answer are handled in the following way: the sender calls the function\fun{Ask}, and is blocked until the answer is received; any incoming messages are stored for later processing. -When the answer arrives, \fun{Ask} calls the virtual function \fun{ConvertAnswer}. -The returned value of \fun{ConvertAnswer} is then returned by \fun{Ask}, +When the answer arrives, \fun{Ask} calls the virtual function \fun{DecodeAnswer}. +The returned value of \fun{DecodeAnswer} is then returned by \fun{Ask}, thus returning to the application the reply to its question. On the receiver's side, the following happens: -when a message sent with \fun{Ask} is received, \fun{NewMessage} is called as usual, +when a message sent with \fun{Ask} is received, \fun{DecodeMessage} is called as usual, but an argument indicates that it is a question that needs an answer. The receiver must then use \fun{Reply} to send its answer. Messages can be sent before replying, but it is not possible to send a question @@ -248,8 +248,8 @@ The output mode can be switched to a synchronous mode where each message is sent \medskip To use a message stream, a program needs to derive the class \typ{UchMsgStream} -in order to redefine the virtual functions \fun{NewMessage} and \fun{ConvertAnswer}. -\fun{NewMessage} treats the incoming message, and will probably call \fun{Send} and \fun{Ask}. +in order to redefine the virtual functions \fun{DecodeMessage} and \fun{DecodeAnswer}. +\fun{DecodeMessage} treats the incoming message, and will probably call \fun{Send} and \fun{Ask}. The top level of the program needs just call \fun{HandleRead} in a forever loop. Most of the time, a program will use several message streams @@ -262,7 +262,7 @@ The virtual function \fun{HandeWrite} of channels is redefined to flush the outp The virtual function \fun{HandleSelect} of channels is redefined to handle the incoming messages that were buffered while waiting for an answer. As for the single stream situation, you need just derive the class \fun{UchMsgStream} to -redefine the virtual functions \fun{NewMessage} and \fun{ConvertAnswer}. +redefine the virtual functions \fun{DecodeMessage} and \fun{DecodeAnswer}. ?*/ // ---- no byte swapping ... @@ -365,7 +365,7 @@ UchMsgStream :: Process (UchMsgBuffer& buf, bool waitAnswer) if (waitAnswer) { if (InType == ANS) { UchMsgBuffer fake (buf, InLength); - UchMessage* ans = ConvertAnswer (fake); + UchMessage* ans = DecodeAnswer (fake); buf.Flush (InLength); State = WAITING; return ans; @@ -379,12 +379,14 @@ UchMsgStream :: Process (UchMsgBuffer& buf, bool waitAnswer) if (InType == MSG || InType == ASK) { // pass a fake buffer to the handler UchMsgBuffer fake (buf, InLength); - if (! NewMessage (fake, WaitingReply)) + UchMessage* msg = DecodeMessage (fake); + if (! msg || !msg->Activate (*this, WaitingReply)) return 0; - // *** this return breaks the assumption that + // *** these returns break the assumption that // *** Process empties the buffer. // *** this is assumed in HandleRead/HandleSelect // *** because BufferedMessages is reset to false; + } } buf.Flush (InLength); @@ -424,23 +426,35 @@ UchMsgStream :: HandleSelect () This virtual function is called whenever a complete message is in the buffer. The buffer contains exactly one message, so that you can use \com{buf.ReadMsg (msg)} to extract the message from the buffer. -\var{ask} is true if the message was sent with \fun{Ask}. -In this case an answer must be sent back with \fun{Reply}. -Messages can be sent before replying; they will be buffered by the receiver for later processing. -But you cannot use \fun{Ask} before replying. -\fun{NewMessage} function must return true if it handled the message, else false. +\fun{DecodeMessage} must return the extracted message. The default version returns a dummy \typ{UchMessage}. If it returns false, it will be called again with the same arguments next time data arrives on this channel. -In the class \typ{UchMsgStream} this function does nothing and returns true; -if \var{ask} is true, it replies immediately with an empty message. +The function \typ{MyClient}::\fun{DecodeMessage} +may look like: +\begin{ccode} +UchMessage* +MyClient :: DecodeMessage (UchMsgBuffer& buffer) +{ + MyRequest* m = 0; + lword type; + buffer.Peek (type, lwsize); + switch (type) { + case MyFirstReqType: + m = new MyFirstRequest; + break; + case ... + ... + } + if (m) + buffer.Get (m); + + return m; +} +\end{ccode} ?*/ -bool -UchMsgStream :: NewMessage (UchMsgBuffer&, bool ask) +UchMessage* +UchMsgStream :: DecodeMessage (UchMsgBuffer&) { - if (ask) { - UchMessage dummy; - Reply (dummy); - } - return true; + return new UchMessage; } /*? @@ -488,7 +502,7 @@ UchMsgStream :: ReadMsg (UchMessage& msg) /*? Send a message and wait for an answer. Incoming messages that are received while waiting for the answer are kept for later processing. -The answer message is returned by calling the virtual function \fun{ConvertAnswer}. +The answer message is returned by calling the virtual function \fun{DecodeAnswer}. ?*/ UchMessage* UchMsgStream :: Ask (UchMessage& msg) @@ -533,7 +547,7 @@ This function is called by \fun{Ask} when the answer is in the buffer, in order to convert it into an object usable by the application. ?*/ UchMessage* -UchMsgStream :: ConvertAnswer (UchMsgBuffer&) +UchMsgStream :: DecodeAnswer (UchMsgBuffer&) { return 0; } @@ -544,7 +558,7 @@ If \var{flush} is true, the output buffer will be flushed. This also happens when the message stream is in synchronous mode, or if the output UchMsgBuffer.has exceeded its flush size (see \fun{FlushSize}). The buffer {\em must} contain a converted message. -This can be used for instance from inside \fun{NewMessage} to resend +This can be used for instance from inside \fun{DecodeMessage} to resend the incoming message to another client, without having to convert the buffer to a message. ?*/ diff --git a/comm/MsgStream.h b/comm/MsgStream.h index 333581a..ddfccaf 100644 --- a/comm/MsgStream.h +++ b/comm/MsgStream.h @@ -84,8 +84,8 @@ public: UchChannel* Copy () const; void HandleRead (); bool HandleSelect (); -virtual bool NewMessage (UchMsgBuffer&, bool); -virtual UchMessage* ConvertAnswer (UchMsgBuffer&); +virtual UchMessage* DecodeMessage (UchMsgBuffer&); +virtual UchMessage* DecodeAnswer (UchMsgBuffer&); void Send (UchMessage&, bool = false); UchMessage* Ask (UchMessage&); void Reply (UchMessage&); -- cgit v1.1