#include <CTCLChannelCommander.h>
|
static void | inputRelay (ClientData pData, int mask) |
|
|
std::string | prompt1String () |
|
std::string | prompt2String () |
|
std::string | getPromptString (const char *scriptVariable, const char *defaultValue) |
|
|
CTCLInterpreter * | m_pInterp |
|
Tcl_Channel | m_channel |
|
std::string | m_command |
|
bool | m_active |
|
A Channel commander is an object that can accept commands on some channel in an event driven way, and submit them for processing to the interpreter. Commanders could point to some interactive channel (e.g. see CTCLStdioCommander), or something less interactive like the socket of CTCLTcpServerInstance.
This base class is suitable for the generic case but has member functions that can be overriden for more specific cases.
◆ CTCLChannelCommander()
CTCLChannelCommander::CTCLChannelCommander |
( |
CTCLInterpreter * |
interp, |
|
|
Tcl_Channel |
channel |
|
) |
| |
The channel commanders use a 2 phase construction scheme so that we can hang on to a commander and put it in and out of the event loop as we please.
Construction does nothing but save data. To enable event procesing/command dispatch on the channel, you must call start. Event/command processing can be disabled by invoking stop.
- Parameters
-
interp | - Pointer to the CTCLInterpreter object to which complete commands will be dispatched. |
channel | - Tcl_Channel on which commands will be accepted for submission to *interp. |
◆ ~CTCLChannelCommander()
CTCLChannelCommander::~CTCLChannelCommander |
( |
| ) |
|
|
virtual |
Destruction will stop command processing.
- The interpreter will, of course remain alive.
- The channel will not be closed. That's up to the framing software.
◆ getChannel()
Tcl_Channel CTCLChannelCommander::getChannel |
( |
| ) |
const |
- Returns
- Tcl_Channel
- Return values
-
The | channel on which commands are processed. |
◆ inputRelay()
void CTCLChannelCommander::inputRelay |
( |
ClientData |
pData, |
|
|
int |
mask |
|
) |
| |
|
static |
This static function establishes object context and calls onInput if there was an input event or onInputException if there was an exception event.
- Parameters
-
pData | - Really a pointer to a CTCLChannelHandler. |
mask | - Mask of the events that actually fired. In theory, more than one event can be dispatched to us. Since exceptions may result in channel closures, reads are handled first. |
◆ onCommand()
void CTCLChannelCommander::onCommand |
( |
| ) |
|
|
virtual |
Called when a command has been received. Default behavior:
- submits the command to the interpreter for execution.
- calls returnResult so that it can decide what to do with the interpreter result. Interpreter errors are just absorbed in the sense that we just let the result speak for itself,and Tcl's own -abort the proc on error- behavior deal with it all.
◆ onEndFile()
void CTCLChannelCommander::onEndFile |
( |
| ) |
|
|
virtual |
Called when an end of file was seen on the input. This calls the stop function by default, leaving it up to the client software to decidew what to do about the channel (which is still open).
Reimplemented in CTCLTcpServerInstance.
◆ onInput()
void CTCLChannelCommander::onInput |
( |
| ) |
|
|
virtual |
Input handler. The default action is to read a line of input with Tcl_GetsObj. The resulting object is converted to its string representation and appended to m_command. The m_command is then sent through Tcl_CommandComplete and, if the command is complete, onCommand is invoked to handle it. Prompting is done as follows:
- If the object acquired does not complete a line, then prompt2 is called.
- If the object acquired completes the line, then on the return from onCommand, prompt1() is called.
- Note
- Tcl_GetsObj will return a -1 if no input is available This can happen for three reasons which are all dealt with:
- Channel is in nonblocking mode and there's no data (normal return).
- Channel has an eof condition (onEndFile called).
- Channel has some error (onInputException called).
◆ onInputException()
void CTCLChannelCommander::onInputException |
( |
| ) |
|
|
virtual |
This is called when there's a problem on the input. default action is to stop accepting input events. The channel remains open, it's up to the client software to determine when, and if, the channel should be closed.
◆ prompt1()
void CTCLChannelCommander::prompt1 |
( |
| ) |
|
|
virtual |
Performs the begin of command prompt. Default action is to fetcht he prompt1 string and pass it to sendPrompt which has to decide what to do with it:
◆ prompt2()
void CTCLChannelCommander::prompt2 |
( |
| ) |
|
|
virtual |
Pefrorms the prompt for the middle of a command e.g.
prompt1> proc a {b} {
prompt2> ...
◆ returnResult()
void CTCLChannelCommander::returnResult |
( |
| ) |
|
|
virtual |
Return the result of a command to well... somewhere. By default this does nothing. In other contexts, you could expect it to write the result string somewhere (e.g. for sockets back to the client, for stdin, to stdout or stderr.
Reimplemented in CTCLTcpServerInstance.
◆ sendPrompt()
void CTCLChannelCommander::sendPrompt |
( |
std::string |
prompt | ) |
|
|
virtual |
Peform a prompt, given a string. The default is to do nothing leaving it to the derived classes to determine how prompting is emitted. Note that if different behavior is required for prompt1 and prompt2, those members can be directly overridden.
◆ start()
void CTCLChannelCommander::start |
( |
| ) |
|
|
virtual |
Start accumulating commands to be processed. This involves setting a channel handler for input on the channel pointed to the inputRelay function that establishes object context and calls the virtual function onInput. Note that since channel handlers are like highlander (there can be only one), there's no harm in calling this function if the handler is already established, so there's no attempt to catch this as an error.
◆ stop()
void CTCLChannelCommander::stop |
( |
| ) |
|
|
virtual |
Stop accumulating commands by disabling the channel handler. Any data in m_command is discarded, so that if start is called later, there's no stale partial command. m_command is cleared here, rather than in start so that multiple calls to start are harmless.
◆ stopped()
bool CTCLChannelCommander::stopped |
( |
| ) |
const |
stopped Returns true if the channel has stopped (due to eof).
The documentation for this class was generated from the following files: