diff options
author | Patrick Benavoli <patrickx.benavoli@intel.com> | 2011-10-24 18:50:03 +0200 |
---|---|---|
committer | David Wagner <david.wagner@intel.com> | 2014-02-10 17:14:57 +0100 |
commit | cfb64dd41410d363fe2e24faf6cd33c9e846b401 (patch) | |
tree | 9b6c6e504465cf274c35f18b46195424381e9598 | |
parent | 1352ae53c457466fadb3aa35f01afab899548657 (diff) | |
download | external_parameter-framework-cfb64dd41410d363fe2e24faf6cd33c9e846b401.zip external_parameter-framework-cfb64dd41410d363fe2e24faf6cd33c9e846b401.tar.gz external_parameter-framework-cfb64dd41410d363fe2e24faf6cd33c9e846b401.tar.bz2 |
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 <patrickx.benavoli@intel.com>
Reviewed-on: http://android.intel.com:8080/22326
Reviewed-by: Centelles, Sylvain <sylvain.centelles@intel.com>
Tested-by: Barthes, FabienX <fabienx.barthes@intel.com>
Reviewed-by: buildbot <buildbot@intel.com>
Tested-by: buildbot <buildbot@intel.com>
Reviewed-on: http://android.intel.com:8080/26779
Reviewed-by: Barthes, FabienX <fabienx.barthes@intel.com>
-rw-r--r-- | remote-processor/RemoteCommandHandlerTemplate.h | 219 |
1 files changed, 219 insertions, 0 deletions
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 <vector> +#include "RemoteCommandHandler.h" + +template <class CCommandParser> +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<CRemoteCommandParserItem*> _remoteCommandParserVector; + uint32_t _uiMaxCommandUsageLength; +}; |