Audacity  2.2.2
CommandBuilder.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3  Audacity - A Digital Audio Editor
4  Copyright 1999-2009 Audacity Team
5  File License: wxWidgets
6 
7  Dan Horgan
8 
9 ******************************************************************//*******************************************************************/
23 
24 #include "../Audacity.h"
25 #include "CommandBuilder.h"
26 #include "CommandDirectory.h"
27 #include "../Shuttle.h"
28 #include "BatchEvalCommand.h"
29 #include "Command.h"
30 #include "CommandTargets.h"
31 #include "ScriptCommandRelay.h"
32 
33 CommandBuilder::CommandBuilder(const wxString &cmdString)
34  : mValid(false)
35 {
36  BuildCommand(cmdString);
37 }
38 
39 CommandBuilder::CommandBuilder(const wxString &cmdName, const wxString &params)
40  : mValid(false)
41 {
42  BuildCommand(cmdName, params);
43 }
44 
46 {
47 }
48 
50 {
51  return mValid;
52 }
53 
55 {
56  return mError;
57 }
58 
60 {
61  wxASSERT(mValid);
62  wxASSERT(mCommand);
63  auto result = mCommand;
64  mCommand.reset();
65  return result;
66 }
67 
68 void CommandBuilder::Failure(const wxString &msg)
69 {
70  mError = msg;
71  mValid = false;
72 }
73 
75 {
76  mCommand = cmd;
77  mValid = true;
78 }
79 
80 void CommandBuilder::BuildCommand(const wxString &cmdName,
81  const wxString &cmdParamsArg)
82 {
83  // Stage 1: create a Command object of the right type
84 
85  auto scriptOutput = ScriptCommandRelay::GetResponseTarget();
86  auto output
87  = std::make_unique<CommandOutputTarget>(std::make_unique<NullProgressTarget>(),
88  scriptOutput,
89  scriptOutput);
90 
91  CommandType *factory = CommandDirectory::Get()->LookUp(cmdName);
92 
93  if (factory == NULL)
94  {
95  // Fall back to hoping the Batch Command system can handle it
96  CommandType *type = CommandDirectory::Get()->LookUp(wxT("BatchCommand"));
97  wxASSERT(type != NULL);
98  mCommand = type->Create(std::move(output));
99  mCommand->SetParameter(wxT("CommandName"), cmdName);
100  mCommand->SetParameter(wxT("ParamString"), cmdParamsArg);
101  Success(std::make_shared<ApplyAndSendResponse>(mCommand));
102  return;
103  }
104 
105  CommandSignature &signature = factory->GetSignature();
106  mCommand = factory->Create(std::move(output));
107 
108  // Stage 2: set the parameters
109 
110  ShuttleCli shuttle;
111  shuttle.mParams = cmdParamsArg;
112  shuttle.mbStoreInClient = true;
113 
114  ParamValueMap::const_iterator iter;
115  ParamValueMap params = signature.GetDefaults();
116 
117  // Iterate through the parameters defined by the command
118  for (iter = params.begin(); iter != params.end(); ++iter)
119  {
120  wxString paramString;
121  // IF there is a match in the args actually used
122  if (shuttle.TransferString(iter->first, paramString, wxT("")))
123  {
124  // Then set that parameter.
125  if (!mCommand->SetParameter(iter->first, paramString))
126  {
127  Failure();
128  return;
129  }
130  }
131  }
132 
133  // Check for unrecognised parameters
134 
135  wxString cmdParams(cmdParamsArg);
136 
137  while (cmdParams != wxEmptyString)
138  {
139  cmdParams.Trim(true);
140  cmdParams.Trim(false);
141  int splitAt = cmdParams.Find(wxT('='));
142  if (splitAt < 0 && cmdParams != wxEmptyString)
143  {
144  Failure(wxT("Parameter string is missing '='"));
145  return;
146  }
147  wxString paramName = cmdParams.Left(splitAt);
148  if (params.find(paramName) == params.end())
149  {
150  Failure(wxT("Unrecognized parameter: '") + paramName + wxT("'"));
151  return;
152  }
153  // Handling of quoted strings is quite limitted.
154  // You start and end with a " or a '.
155  // There is no escaping in the string.
156  cmdParams = cmdParams.Mid(splitAt+1);
157  if( cmdParams.IsEmpty() )
158  splitAt =-1;
159  else if( cmdParams[0] == '\"' ){
160  cmdParams = cmdParams.Mid(1);
161  splitAt = cmdParams.Find(wxT('\"'))+1;
162  }
163  else if( cmdParams[0] == '\'' ){
164  cmdParams = cmdParams.Mid(1);
165  splitAt = cmdParams.Find(wxT('\''))+1;
166  }
167  else
168  splitAt = cmdParams.Find(wxT(' '))+1;
169  if (splitAt < 1)
170  {
171  splitAt = cmdParams.Len();
172  }
173  cmdParams = cmdParams.Mid(splitAt);
174  }
175 
176  Success(std::make_shared<ApplyAndSendResponse>(mCommand));
177 }
178 
179 void CommandBuilder::BuildCommand(const wxString &cmdStringArg)
180 {
181  wxString cmdString(cmdStringArg);
182 
183  // Find the command name terminator... If there is more than one word and
184  // no terminator, the command is badly formed
185  cmdString.Trim(true); cmdString.Trim(false);
186  int splitAt = cmdString.Find(wxT(':'));
187  if (splitAt < 0 && cmdString.Find(wxT(' ')) >= 0) {
188  mError = wxT("Command is missing ':'");
190  mValid = false;
191  return;
192  }
193 
194  wxString cmdName = cmdString.Left(splitAt);
195  wxString cmdParams = cmdString.Mid(splitAt+1);
196  if( splitAt < 0 )
197  cmdParams = "";
198 
199  cmdName.Trim(true);
200  cmdParams.Trim(false);
201 
202  BuildCommand(cmdName, cmdParams);
203 }
static CommandDirectory * Get()
Get a pointer to the singleton instance.
std::map< wxString, wxVariant > ParamValueMap
Definition: CommandMisc.h:23
CommandBuilder(const wxString &cmdString)
const wxString & GetErrorMessage()
std::shared_ptr< Command > CommandHolder
void Success(const CommandHolder &cmd)
Contains declaration of Command base class.
wxString mParams
Definition: Shuttle.h:56
Derived from Shuttle, this class exchanges string parameters with a binary representation.
Definition: Shuttle.h:53
Contains declarations for ScriptCommandRelay.
void BuildCommand(const wxString &cmdName, const wxString &cmdParams)
CommandSignature & GetSignature()
Definition: CommandType.cpp:41
Contains declarations for CommandDirectory class.
ParamValueMap GetDefaults() const
CommandType * LookUp(const wxString &cmdName) const
static std::shared_ptr< ResponseQueueTarget > GetResponseTarget()
Base class for containing data common to all commands of a given type. Also acts as a factory...
Definition: CommandType.h:29
virtual bool TransferString(const wxString &Name, wxString &strValue, const wxString &strDefault)
Definition: Shuttle.cpp:240
void Failure(const wxString &msg=wxEmptyString)
CommandHolder GetCommand()
bool mbStoreInClient
Definition: Shuttle.h:34
CommandHolder mCommand
virtual CommandHolder Create(std::unique_ptr< CommandOutputTarget > &&target)=0
static void SendResponse(const wxString &response)
Adds a response to the queue to be sent back to the script.
Contains declaration of CommandBuilder class.
EffectDistortion::Params params
Definition: Distortion.cpp:95
Class that maps parameter names to default values and validators.