GM6000 Digital Heater Controller Build: 16 (Branch = develop)
SDX-1330
Processor.h
Go to the documentation of this file.
1#ifndef Cpl_TShell_Processor_h_
2#define Cpl_TShell_Processor_h_
3/*-----------------------------------------------------------------------------
4* This file is part of the Colony.Core Project. The Colony.Core Project is an
5* open source project with a BSD type of licensing agreement. See the license
6* agreement (license.txt) in the top/ directory or on the Internet at
7* http://integerfox.com/colony.core/license.txt
8*
9* Copyright (c) 2014-2025 John T. Taylor
10*
11* Redistributions of the source code must retain the above copyright notice.
12*----------------------------------------------------------------------------*/
13/** @file */
14
15#include "colony_config.h"
16#include "Cpl/TShell/Context_.h"
17#include "Cpl/System/Mutex.h"
18#include "Cpl/Text/FString.h"
21
22
23/** This symbol defines the size, in bytes, of the maximum allowed input
24 string/command.
25 */
26#ifndef OPTION_CPL_TSHELL_PROCESSOR_INPUT_SIZE
27#define OPTION_CPL_TSHELL_PROCESSOR_INPUT_SIZE 128
28#endif
29
30/** This symbol defines the size, in bytes, of the maximum allowed unframed
31 output string/command.
32 */
33#ifndef OPTION_CPL_TSHELL_PROCESSOR_OUTPUT_SIZE
34#define OPTION_CPL_TSHELL_PROCESSOR_OUTPUT_SIZE 256
35#endif
36
37/** This symbols defines the Shell's greeting message
38 */
39#ifndef OPTION_CPL_TSHELL_PROCESSOR_GREETING
40#define OPTION_CPL_TSHELL_PROCESSOR_GREETING "\n--- Your friendly neighborhood TShell. ---\n\n\n"
41#endif
42
43/** This symbols defines the Shell's farewell message
44 */
45#ifndef OPTION_CPL_TSHELL_PROCESSOR_FAREWELL
46#define OPTION_CPL_TSHELL_PROCESSOR_FAREWELL "\n--- ...I am melting, am melting... ---\n\n"
47#endif
48
49/** This symbols defines the Shell's prompt string
50 */
51#ifndef OPTION_CPL_TSHELL_PROCESSOR_PROMPT
52#define OPTION_CPL_TSHELL_PROCESSOR_PROMPT "$ "
53#endif
54
55///
56namespace Cpl {
57///
58namespace TShell {
59
60/** This concrete class provides the implementation of Command Processor for
61 a TShell engine.
62
63 The implementation assumes a single threaded model, i.e. the Command
64 Processor and all of its commands run in a single thread. It is
65 APPLICATION's responsibility to provide any desired multi-threaded
66 support. There are two caveats to the single-threaded model:
67
68 o The output of the commands are mutex protected. This allows the
69 Output stream to be 'shared' with other sub-systems and/or
70 threads (e.g. the shell shares the same Output stream as the
71 Cpl::System::Trace logging output).
72
73 o The stop() method can be called safely from other threads.
74
75
76 Commands have the following syntax:
77
78 o A command starts with a printable ASCII character and ends with
79 a newline.
80
81 o Non-printable ASCII characters are not allowed.
82
83 o Any line that starts with a '#' is treated as comment line and
84 is ignored.
85
86 o Format of a command is: verb [arg]* where the verb and arguments
87 are separated by spaces. Arguments can contain spaces character
88 by enclosing the argument with double quote characters. A double
89 quote character can be embedded inside a quoted string by preceding
90 it the double quote character with the escape character. The escape
91 character can be embedded by escaping the escape character.
92
93 The USE_CPL_TSHELL_PROCESSOR_SILENT_WHEN_PUBLIC switch is use
94 to alter the TShell's output behavior - to not 'say anything'
95 until a user has successfully been authenticated (using the 'User'
96 command
97
98 HOW TO Enable Security:
99
100 - Set OPTION_TSHELL_CMD_COMMAND_DEFAULT_PERMISSION_LEVEL to something
101 other than ePUBLIC. This will be the permission for all legacy (i.e.
102 not Security aware) TShell commands
103
104 - Recommend turning on the switch: USE_CPL_TSHELL_PROCESSOR_SILENT_WHEN_PUBLIC
105
106 - Include the Cpl::TShell::Cmd::User command and provide an
107 implementation of the Cpl::TShell::Security interface (that is passed
108 to the command's constructor).
109
110 - Optionally include new security aware commands
111 */
112class Processor : public Context_
113{
114public:
115 /** Constructor.
116
117 @param commands Set of supported commands
118 @param deframer Frame decoder used to identify individual command
119 strings within the raw Input stream
120 @param framer Frame encoder used to encapsulate the output of
121 command in the Output stream.
122 @param outputLock Mutex to be used for ensuring the atomic output
123 of the commands.
124 @param commentChar The comment character used to indicate that the
125 input string is a comment and should not be
126 executed.
127 @param argEscape Escape character to be used when escaping double
128 quote characters inside a quoted argument.
129 @param argDelimiter The delimiter character used to separate the
130 command verb and arguments.
131 @param argQuote The quote character used to 'double quote' a
132 argument string.
133 @param argTerminator The command terminator character.
134 @param initialPermissionLevel The initial minimum permission level that a user needs to issue command(s)
135 */
139 Cpl::System::Mutex& outputLock,
140 char commentChar = '#',
141 char argEscape = '`',
142 char argDelimiter = ' ',
143 char argQuote = '"',
144 char argTerminator = '\n',
145 Security::Permission_T initialPermissionLevel = Security::ePUBLIC );
146
147
148public:
149 /// See Cpl::TShell::ProcessorApi
150 bool start( Cpl::Io::Input& infd, Cpl::Io::Output& outfd, bool blocking = true ) noexcept;
151
152 /// See Cpl::TShell::ProcessorApi
153 int poll() noexcept;
154
155 /// See Cpl::TShell::ProcessorApi
156 void requestStop() noexcept;
157
158 /// See Cpl::TShell::ProcessorApi
159 char getEscapeChar() noexcept;
160
161 /// See Cpl::TShell::ProcessorApi
162 char getDelimiterChar() noexcept;
163
164 /// See Cpl::TShell::ProcessorApi
165 char getQuoteChar() noexcept;
166
167 /// See Cpl::TShell::ProcessorApi
168 char getTerminatorChar() noexcept;
169
170public:
171 /// See Cpl::TShell::Context_
172 Cpl::Container::SList<Command>& getCommands() noexcept;
173
174 /// See Cpl::TShell::Context_
175 Command* findCommand( const char* verb, size_t verbLength ) noexcept;
176
177 /// See Cpl::TShell::Context_
178 bool writeFrame( const char* text ) noexcept;
179
180 /// See Cpl::TShell::Context_
181 bool writeFrame( const char* text, size_t maxBytes ) noexcept;
182
183 /// See Cpl::TShell::Context_
184 Cpl::Text::String& getOutputBuffer() noexcept;
185
186 /// See Cpl::TShell::Context_
187 Cpl::Text::String& getTokenBuffer() noexcept;
188
189 /// See Cpl::TShell::Context_
190 Cpl::Text::String& getTokenBuffer2() noexcept;
191
192 /// See Cpl::TShell::Context_
193 bool oobRead( void* buffer, int numBytes, int& bytesRead ) noexcept;
194
195 /// See Cpl::TShell::Context_
196 Security::Permission_T getUserPermissionLevel() const noexcept;
197
198 /// See Cpl::TShell::Context_
199 Security::Permission_T setUserPermissionLevel( Security::Permission_T newPermissionLevel ) noexcept;
200
201protected:
202 /** Helper method that attempts to execute the content of the de-framed/decoded
203 'inputString'. The method returns the result code of the execute
204 command. If 'inputString' is not a valid command, then the appropriate
205 error/result code is returned.
206 */
207 virtual Command::Result_T executeCommand( char* deframedInput, Cpl::Io::Output& outfd ) noexcept;
208
209 /// Helper method
210 bool outputCommandError( Command::Result_T result, const char* deframedInput ) noexcept;
211
212 /** Helper method that performs a 'single' read cycle of the input stream.
213 Returns 0 if successful. Returns 1 if exiting. Returns -1 on error
214 */
215 int getAndProcessFrame( Cpl::Io::Output& outfd ) noexcept;
216
217 /** Helper method that executes the decoder, i.e. logic to parse the incoming
218 text. Returns 1 if a full/valid frame was found. Returns 0 if input frame
219 is incomplete. Return -1 if an error occurred.
220 */
221 virtual int readInput( size_t& frameSize ) noexcept;
222
223 /// Helper method
224 virtual void sortCommandList() noexcept;
225
226protected:
227 /// Command list
228 Cpl::Container::SList<Command>& m_commands;
229
230 /// Raw input de-framer
231 Cpl::Text::Frame::StreamDecoder& m_deframer;
232
233 /// Output framer handle
234 Cpl::Text::Frame::StreamEncoder& m_framer;
235
236 /// Output lock
237 Cpl::System::Mutex& m_outLock;
238
239 /// User's permission level
241
242 /// Comment character
244
245 /// Argument Escape character
246 char m_esc;
247
248 /// Argument delimiter
249 char m_del;
250
251 /// Argument quote character
253
254 /// Argument terminator character
255 char m_term;
256
257 /// Set to true when 'command prompt' should be outputted
259
260 /// Current frame size
262
263 /// My run state
265
266 /// Input Frame buffer
268
269 /// Buffer that is used to construct output messages
271
272 /// Shared token work buffer
274
275 /// Shared token work buffer
277};
278
279
280}; // end namespaces
281};
282#endif // end header latch
#define OPTION_CPL_TSHELL_PROCESSOR_INPUT_SIZE
This symbol defines the size, in bytes, of the maximum allowed input string/command.
Definition Processor.h:27
#define OPTION_CPL_TSHELL_PROCESSOR_OUTPUT_SIZE
This symbol defines the size, in bytes, of the maximum allowed unframed output string/command.
Definition Processor.h:34
This template class implements a THREAD SAFE Ring Buffer.
Definition RingBufferMT.h:33
This partially abstract class defines a interface for operating on an input stream (example of a stre...
Definition Input.h:37
This partially abstract class defines a interface for operating on an output stream (example of a str...
Definition Output.h:34
This mutex class defines the interface for a mutex that has "recursive" semantics.
Definition Mutex.h:33
This class defines the interface for a TShell command.
Definition Command.h:32
This Private Namespace class defines a "Context" for a TShell command.
Definition Context_.h:32
This concrete class provides the implementation of Command Processor for a TShell engine.
Definition Processor.h:113
Cpl::Text::String & getOutputBuffer() noexcept
See Cpl::TShell::Context_.
virtual void sortCommandList() noexcept
Helper method.
Cpl::Text::FString< OPTION_CPL_TSHELL_PROCESSOR_OUTPUT_SIZE > m_outputBuffer
Buffer that is used to construct output messages.
Definition Processor.h:270
virtual Command::Result_T executeCommand(char *deframedInput, Cpl::Io::Output &outfd) noexcept
Helper method that attempts to execute the content of the de-framed/decoded 'inputString'.
bool oobRead(void *buffer, int numBytes, int &bytesRead) noexcept
See Cpl::TShell::Context_.
Security::Permission_T getUserPermissionLevel() const noexcept
See Cpl::TShell::Context_.
char m_term
Argument terminator character.
Definition Processor.h:255
bool m_writeCommandPrompt
Set to true when 'command prompt' should be outputted.
Definition Processor.h:258
Cpl::Text::Frame::StreamEncoder & m_framer
Output framer handle.
Definition Processor.h:234
int poll() noexcept
See Cpl::TShell::ProcessorApi.
char getQuoteChar() noexcept
See Cpl::TShell::ProcessorApi.
Command * findCommand(const char *verb, size_t verbLength) noexcept
See Cpl::TShell::Context_.
virtual int readInput(size_t &frameSize) noexcept
Helper method that executes the decoder, i.e.
Cpl::Text::String & getTokenBuffer2() noexcept
See Cpl::TShell::Context_.
char m_inputBuffer[OPTION_CPL_TSHELL_PROCESSOR_INPUT_SIZE+1]
Input Frame buffer.
Definition Processor.h:267
char m_comment
Comment character.
Definition Processor.h:243
char getEscapeChar() noexcept
See Cpl::TShell::ProcessorApi.
Security::Permission_T m_userPermLevel
User's permission level.
Definition Processor.h:240
char m_quote
Argument quote character.
Definition Processor.h:252
size_t m_frameSize
Current frame size.
Definition Processor.h:261
Cpl::Container::SList< Command > & m_commands
Command list.
Definition Processor.h:228
Cpl::Text::FString< OPTION_CPL_TSHELL_PROCESSOR_INPUT_SIZE > m_tokenBuffer2
Shared token work buffer.
Definition Processor.h:276
Cpl::Text::Frame::StreamDecoder & m_deframer
Raw input de-framer.
Definition Processor.h:231
int getAndProcessFrame(Cpl::Io::Output &outfd) noexcept
Helper method that performs a 'single' read cycle of the input stream.
bool start(Cpl::Io::Input &infd, Cpl::Io::Output &outfd, bool blocking=true) noexcept
See Cpl::TShell::ProcessorApi.
Cpl::Text::String & getTokenBuffer() noexcept
See Cpl::TShell::Context_.
char getTerminatorChar() noexcept
See Cpl::TShell::ProcessorApi.
bool writeFrame(const char *text) noexcept
See Cpl::TShell::Context_.
Cpl::Text::FString< OPTION_CPL_TSHELL_PROCESSOR_INPUT_SIZE > m_tokenBuffer
Shared token work buffer.
Definition Processor.h:273
bool outputCommandError(Command::Result_T result, const char *deframedInput) noexcept
Helper method.
char m_esc
Argument Escape character.
Definition Processor.h:246
Security::Permission_T setUserPermissionLevel(Security::Permission_T newPermissionLevel) noexcept
See Cpl::TShell::Context_.
char m_del
Argument delimiter.
Definition Processor.h:249
Cpl::System::Mutex & m_outLock
Output lock.
Definition Processor.h:237
Cpl::Container::SList< Command > & getCommands() noexcept
See Cpl::TShell::Context_.
char getDelimiterChar() noexcept
See Cpl::TShell::ProcessorApi.
void requestStop() noexcept
See Cpl::TShell::ProcessorApi.
Processor(Cpl::Container::SList< Command > &commands, Cpl::Text::Frame::StreamDecoder &deframer, Cpl::Text::Frame::StreamEncoder &framer, Cpl::System::Mutex &outputLock, char commentChar='#', char argEscape='`', char argDelimiter=' ', char argQuote='"', char argTerminator = '\n', Security::Permission_T initialPermissionLevel = Security::ePUBLIC )
Constructor.
bool m_running
My run state.
Definition Processor.h:264
This abstract defines the interface for validating a 'user login' for TShell.
Definition Security.h:31
Permission_T
Permissions levels.
Definition Security.h:34
@ ePUBLIC
No permissions, i.e.
Definition Security.h:35
This partially concrete class defines an interface a Text "Decoder" that has a Cpl::Io::Input stream ...
Definition StreamDecoder.h:34
This concrete class implements the Encoder API where the Output destination is a Cpl::Io::Output stre...
Definition StreamEncoder.h:36
The 'Cpl' namespace is the root name space for the Colony.
Definition Api16.h:20