32 #include <rtt/Property.hpp> 33 #include "NiceHeaderMarshaller.hpp" 34 #include "TcpReporting.hpp" 35 #include "command.hpp" 37 #include "datasender.hpp" 38 #include "socketmarshaller.hpp" 49 class prefixbuf :
public std::streambuf
56 prefixbuf( std::streambuf* opt ) : _opt(opt)
75 if( _opt->sputn(
"300 ", 4) != 4 )
81 int ret = _opt->sputc(c);
82 newline = ( c ==
'\n' );
90 return _opt->pubsync();
97 class prefixstr :
public std::ostream
100 prefixstr(std::ostream& opt)
101 :
std::ostream( new prefixbuf( opt.rdbuf() ) )
113 char to_upper (
const char c)
124 void maincode(
int, std::string* )
126 std::vector<std::string> list = _parent->getConnection()->getMarshaller()->getReporter()->getReport()->list();
127 for(
unsigned int i=0;i<list.size();i++)
128 socket()<<
"305 "<<list[i]<<std::endl;
129 socket() <<
"306 End of list" << std::endl;
155 const std::vector<Command*> &cmds = _parent->giveCommands();
156 socket() <<
"Use HELP <command>" << std::endl;
157 for(
unsigned int i = 0; i < cmds.size(); i++ )
159 if( cmds[i] == cmds[i]->getRealCommand( cmds ) )
161 socket() << cmds[i]->getName() <<
'\n';
164 socket() <<
'.' << std::endl;
170 void printHelpFor(
const std::string& name,
const RealCommand* command )
172 socket() <<
"Name: " << name << std::endl;
173 socket() <<
"Usage: " << name;
178 socket() << std::endl;
184 void printHelpFor(
const std::string& cmd )
186 const std::vector<Command*> &cmds = _parent->giveCommands();
187 for(
unsigned int i = 0; i < cmds.size(); i++ )
189 if( cmds[i]->getName() == cmd )
191 printHelpFor( cmd, cmds[i]->getRealCommand( cmds ) );
198 void maincode(
int argc, std::string* params )
204 printHelpFor(params[0]);
209 :
RealCommand(
"HELP", parent, 0, 1,
"[nothing | <command name>]" )
217 void maincode(
int, std::string* )
219 socket() <<
"103 none" << std::endl;
232 void maincode(
int, std::string* )
252 void maincode(
int, std::string* args )
256 unsigned long long limit = strtoull( args[0].c_str(), &tailptr, 10 );
257 if( *tailptr !=
'\0' || ( errno != olderr && errno == ERANGE ) )
261 _parent->getConnection()->setLimit(limit);
268 :
RealCommand(
"SETLIMIT", parent, 1, 1,
"<frameid>" )
279 void maincode(
int, std::string* args )
282 if( args[0] ==
"ON" )
284 _parent->getConnection()->silence(
true);
285 }
else if( args[0] ==
"OFF") {
286 _parent->getConnection()->silence(
false);
291 socket() <<
"107 Silence " << args[0] << std::endl;
296 :
RealCommand(
"SILENCE", parent, 1, 1,
"[ON | OFF]" )
310 void maincode(
int, std::string* args )
312 if( _parent->getConnection()->addSubscription(args[0]) )
314 socket() <<
"302 " << args[0] << std::endl;
316 socket() <<
"301 " << args[0] << std::endl;
322 :
RealCommand(
"SUBSCRIBE", parent, 1, 1,
"<source name>" )
330 void maincode(
int, std::string* )
332 _parent->getConnection()->listSubscriptions();
345 void maincode(
int, std::string* args )
347 if( _parent->getConnection()->removeSubscription(args[0]) )
349 socket() <<
"303 " << args[0] << std::endl;
351 socket() <<
"304 " << args[0] << std::endl;
357 :
RealCommand(
"UNSUBSCRIBE", parent, 1, 1,
"<source name>" )
365 void maincode(
int, std::string* args )
367 if( args[0] ==
"1.0" )
369 _parent->setVersion10();
372 socket() <<
"106 Not supported" << std::endl;
394 Command::Command( std::string name )
403 Command* Command::find(
const std::vector<Command*>& cmds,
const std::string& cmp)
405 for(
unsigned int j = 0; j < cmds.size(); j++ )
407 if( *cmds[j] == cmp )
415 const std::string& Command::getName()
const 420 bool Command::is(std::string& cmd)
const 425 bool Command::operator==(
const std::string& cmp)
const 430 bool Command::operator!=(
const std::string& cmp)
const 435 bool Command::operator<(
const Command& cmp )
const 440 AliasCommand::AliasCommand( std::string name, std::string alias )
441 :
Command( name ), _alias( alias )
445 RealCommand* AliasCommand::getRealCommand(
const std::vector<Command*>& cmds)
const 447 Command* ret = Command::find( cmds, _alias );
456 unsigned int maxargs,
const char* syntax )
457 :
Command( name ), _parent( parent ), _minargs( minargs ), _maxargs( maxargs ), _syntax( syntax )
461 RealCommand::~RealCommand()
465 const char* RealCommand::getSyntax()
const 470 bool RealCommand::sendError102()
const 474 socket() <<
"102 Syntax: " << _name <<
' ' << _syntax << std::endl;
476 socket() <<
"102 Syntax: " << _name << std::endl;
481 bool RealCommand::sendOK()
const 483 socket() <<
"101 OK" << std::endl;
487 bool RealCommand::correctSyntax(
unsigned int argc, std::string* )
489 if( argc < _minargs || argc > _maxargs )
491 return sendError102();
496 RealCommand* RealCommand::getRealCommand(
const std::vector<Command*>& cmds)
const 501 void RealCommand::execute(
int argc, std::string* args )
503 if( correctSyntax( argc, args ) )
505 maincode( argc, args );
509 void RealCommand::toupper( std::string* args,
int i )
const 511 std::transform( args[i].begin(), args[i].end(), args[i].begin(), to_upper );
514 void RealCommand::toupper( std::string* args,
int start,
int stop )
const 516 for(
int i = start; i <= stop; i++ )
524 return _parent->getConnection()->getSocket();
527 TcpReportingInterpreter::TcpReportingInterpreter(
Datasender* parent)
536 TcpReportingInterpreter::~TcpReportingInterpreter()
538 for( std::vector<Command*>::iterator i = cmds.begin();
551 std::vector<Command*>::iterator i = cmds.begin();
552 while( i != cmds.end() && *command < **i ) {
557 if( i != cmds.end() && *command == (*i)->
getName() )
561 cmds.insert( i, command );
575 void TcpReportingInterpreter::process()
588 unsigned int argc = parseParameters( ipt, cmd, ¶ms );
590 std::transform( cmd.begin(), cmd.end(), cmd.begin(), to_upper );
593 bool correct =
false;
601 rcommand->
execute( argc, params );
605 Logger::log() << Logger::Error <<
"Invalid command: " << ipt << Logger::endl;
615 unsigned int TcpReportingInterpreter::parseParameters(
616 std::string& ipt, std::string& cmd, std::string** params )
618 unsigned int argc = 0;
619 std::string::size_type pos = ipt.find_first_of(
"\t ", 0);
620 while( pos != std::string::npos )
622 pos = ipt.find_first_of(
"\t ", pos + 1);
627 *params =
new std::string[argc];
628 pos = ipt.find_first_of(
"\t ", 0);
629 cmd = ipt.substr(0, pos);
631 for(
unsigned int i = 0; i < argc; i++ )
633 npos = ipt.find_first_of(
"\t ", pos + 1);
634 (*params)[i] = ipt.substr(pos+1,npos - pos - 1);
647 std::vector<Command*>::iterator i = cmds.begin();
648 while( i != cmds.end() && **i != ipt ) {
651 if( i == cmds.end() )
653 Logger::log() << Logger::Error <<
"TcpReportingInterpreter::removeCommand: removing unknown command" << ipt << Logger::endl;
Socket & getSocket() const
Get socket associated with this datasender.
static Command * find(const std::vector< Command * > &cmds, const std::string &cmp)
Find the command with the given name in the vector.
This class manages the connection with one single client.
Reads a line from the client and interprete it.
virtual RealCommand * getRealCommand(const std::vector< Command * > &cmds) const =0
Return a reference to the object which is really responsible for executing this command.
Datasender * getConnection() const
Get the marshaller associated with the current connection.
const std::vector< Command * > & giveCommands() const
Return a reference to the command list.
Another name for a command.
The Orocos Component Library.
std::string readLine()
Read a line from the socket.
void execute(int argc, std::string *args)
Execute this command.
void removeCommand(const char *name)
Remove support for the given command name.
Real command which can be executed.
const std::string & getName() const
Get the name of this command.
void silence(bool newstate)
Disable/enable output of data.
void setVersion10()
Accept all valid commands (except 'VERSION 1.0')
const char * getSyntax() const
Return syntax information.
void addCommand(Command *command)
Add support for the given command.