aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick Benavoli <patrickx.benavoli@intel.com>2011-10-24 18:50:03 +0200
committerDavid Wagner <david.wagner@intel.com>2014-02-10 17:14:57 +0100
commitcfb64dd41410d363fe2e24faf6cd33c9e846b401 (patch)
tree9b6c6e504465cf274c35f18b46195424381e9598
parent1352ae53c457466fadb3aa35f01afab899548657 (diff)
downloadexternal_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.h219
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;
+};