From cfb64dd41410d363fe2e24faf6cd33c9e846b401 Mon Sep 17 00:00:00 2001 From: Patrick Benavoli Date: Mon, 24 Oct 2011 18:50:03 +0200 Subject: parameter-framework: Reusable command handlers BZ: 13035 - Added a template class in remote-processor library allowing a resuable way for command handlers to be implemented as C++ function pointers Change-Id: I99fd9ba4e17648fd949c2effdcf1373307e1d1ce Signed-off-by: Patrick Benavoli Reviewed-on: http://android.intel.com:8080/22326 Reviewed-by: Centelles, Sylvain Tested-by: Barthes, FabienX Reviewed-by: buildbot Tested-by: buildbot Reviewed-on: http://android.intel.com:8080/26779 Reviewed-by: Barthes, FabienX --- remote-processor/RemoteCommandHandlerTemplate.h | 219 ++++++++++++++++++++++++ 1 file changed, 219 insertions(+) create mode 100644 remote-processor/RemoteCommandHandlerTemplate.h (limited to 'remote-processor') diff --git a/remote-processor/RemoteCommandHandlerTemplate.h b/remote-processor/RemoteCommandHandlerTemplate.h new file mode 100644 index 0000000..5d9817e --- /dev/null +++ b/remote-processor/RemoteCommandHandlerTemplate.h @@ -0,0 +1,219 @@ +#pragma once + +#include +#include "RemoteCommandHandler.h" + +template +class TRemoteCommandHandlerTemplate : public IRemoteCommandHandler +{ +public: + // Remote command execution status + enum CommandStatus { + EDone, + ESucceeded, + EFailed, + EShowUsage + }; + + // Remote command parsers + typedef CommandStatus (CCommandParser::*RemoteCommandParser)(const IRemoteCommand& remoteCommand, std::string& strResult); + +private: + // Parser descriptions + class CRemoteCommandParserItem + { + public: + CRemoteCommandParserItem(const std::string& strCommandName, + RemoteCommandParser pfnParser, + uint32_t uiMinArgumentCount, + const std::string& strHelp, + const std::string& strDescription) + : _strCommandName(strCommandName), + _pfnParser(pfnParser), + _uiMinArgumentCount(uiMinArgumentCount), + _strHelp(strHelp), + _strDescription(strDescription) {} + + const std::string& getCommandName() const + { + return _strCommandName; + } + + const std::string& getDescription() const + { + return _strDescription; + } + + // Usage + std::string usage() const + { + return _strCommandName + " " + _strHelp; + } + + bool parse(CCommandParser* pCommandParser, const IRemoteCommand& remoteCommand, std::string& strResult) const + { + // Check enough arguments supplied + if (remoteCommand.getArgumentCount() < _uiMinArgumentCount) { + + strResult = std::string("Not enough arguments supplied\nUsage:\n") + usage(); + + return false; + } + + switch ((pCommandParser->*_pfnParser)(remoteCommand, strResult)) { + case EDone: + strResult = "Done"; + // Fall through intentionally + case ESucceeded: + return true; + case EShowUsage: + strResult = usage(); + // Fall through intentionally + case EFailed: + return false; + } + + return false; + } + + private: + std::string _strCommandName; + RemoteCommandParser _pfnParser; + uint32_t _uiMinArgumentCount; + std::string _strHelp; + std::string _strDescription; + }; + +public: + TRemoteCommandHandlerTemplate(CCommandParser* pCommandParser) : _pCommandParser(pCommandParser), _uiMaxCommandUsageLength(0) + { + // Help Command + addCommandParser("help", NULL, 0, "", "Show commands description and usage"); + } + ~TRemoteCommandHandlerTemplate() + { + uint32_t uiIndex; + + for (uiIndex = 0; uiIndex < _remoteCommandParserVector.size(); uiIndex++) { + + delete _remoteCommandParserVector[uiIndex]; + } + } + + // Parsers + bool addCommandParser(const std::string& strCommandName, + RemoteCommandParser pfnParser, + uint32_t uiMinArgumentCount, + const std::string& strHelp, + const std::string& strDescription) + { + if (findCommandParserItem(strCommandName)) { + + // Already exists + return false; + } + + // Add command + _remoteCommandParserVector.push_back(new CRemoteCommandParserItem(strCommandName, pfnParser, uiMinArgumentCount, strHelp, strDescription)); + + return true; + } + +private: + // Command processing + bool remoteCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult) + { + // Dispatch + const CRemoteCommandParserItem* pRemoteCommandParserItem = findCommandParserItem(remoteCommand.getCommand()); + + if (!pRemoteCommandParserItem) { + + // Not found + strResult = "Command not found!"; + + return false; + } + + if (remoteCommand.getCommand() == "help") { + + helpCommandProcess(strResult); + + return true; + } + + return pRemoteCommandParserItem->parse(_pCommandParser, remoteCommand, strResult); + } + + // Max command usage length, use for formatting + void initMaxCommandUsageLength() + { + if (!_uiMaxCommandUsageLength) { + // Show usages + uint32_t uiIndex; + + for (uiIndex = 0; uiIndex < _remoteCommandParserVector.size(); uiIndex++) { + + const CRemoteCommandParserItem* pRemoteCommandParserItem = _remoteCommandParserVector[uiIndex]; + + uint32_t uiRemoteCommandUsageLength = pRemoteCommandParserItem->usage().length(); + + if (uiRemoteCommandUsageLength > _uiMaxCommandUsageLength) { + + _uiMaxCommandUsageLength = uiRemoteCommandUsageLength; + } + } + } + } + + /////////////////// Remote command parsers + /// Help + void helpCommandProcess(std::string& strResult) + { + initMaxCommandUsageLength(); + + strResult = "\n"; + + // Show usages + uint32_t uiIndex; + + for (uiIndex = 0; uiIndex < _remoteCommandParserVector.size(); uiIndex++) { + + const CRemoteCommandParserItem* pRemoteCommandParserItem = _remoteCommandParserVector[uiIndex]; + + std::string strUsage = pRemoteCommandParserItem->usage(); + + strResult += strUsage; + + // Align + uint32_t uiToSpacesAdd = _uiMaxCommandUsageLength + 5 - strUsage.length(); + + while (uiToSpacesAdd--) { + + strResult += " "; + } + + strResult += std::string("=> ") + std::string(pRemoteCommandParserItem->getDescription()) + "\n"; + } + } + + const CRemoteCommandParserItem* findCommandParserItem(const std::string& strCommandName) const + { + uint32_t uiIndex; + + for (uiIndex = 0; uiIndex < _remoteCommandParserVector.size(); uiIndex++) { + + const CRemoteCommandParserItem* pRemoteCommandParserItem = _remoteCommandParserVector[uiIndex]; + + if (pRemoteCommandParserItem->getCommandName() == strCommandName) { + + return pRemoteCommandParserItem; + } + } + return NULL; + } + +private: + CCommandParser* _pCommandParser; + std::vector _remoteCommandParserVector; + uint32_t _uiMaxCommandUsageLength; +}; -- cgit v1.1