| OLD | NEW |
| (Empty) |
| 1 // Copyright 2008-2009 Google Inc. | |
| 2 // | |
| 3 // Licensed under the Apache License, Version 2.0 (the "License"); | |
| 4 // you may not use this file except in compliance with the License. | |
| 5 // You may obtain a copy of the License at | |
| 6 // | |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 | |
| 8 // | |
| 9 // Unless required by applicable law or agreed to in writing, software | |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, | |
| 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 12 // See the License for the specific language governing permissions and | |
| 13 // limitations under the License. | |
| 14 // ======================================================================== | |
| 15 | |
| 16 #include "omaha/base/command_line_validator.h" | |
| 17 | |
| 18 #include <atlbase.h> | |
| 19 | |
| 20 #include "omaha/base/command_line_parser.h" | |
| 21 #include "omaha/base/debug.h" | |
| 22 #include "omaha/base/error.h" | |
| 23 #include "omaha/base/logging.h" | |
| 24 #include "omaha/base/utils.h" | |
| 25 | |
| 26 namespace omaha { | |
| 27 | |
| 28 CommandLineValidator::CommandLineValidator() : scenario_sequence_number_(0) { | |
| 29 } | |
| 30 | |
| 31 CommandLineValidator::~CommandLineValidator() { | |
| 32 Clear(); | |
| 33 } | |
| 34 | |
| 35 HRESULT CommandLineValidator::CreateScenario(const CString& scenario_name) { | |
| 36 if (scenarios_.find(scenario_name) != scenarios_.end()) { | |
| 37 return E_INVALIDARG; | |
| 38 } | |
| 39 | |
| 40 ScenarioParameters scenario_parameters; | |
| 41 scenarios_[scenario_name] = scenario_parameters; | |
| 42 return S_OK; | |
| 43 } | |
| 44 | |
| 45 // TODO(Omaha): Instead of creating the scenario in the map then populating it, | |
| 46 // which requires these methods to know about the map, verify the scenario | |
| 47 // exists, etc. - why not build the scenario then add it to the map? That seems | |
| 48 // more straightforward. | |
| 49 HRESULT CommandLineValidator::AddScenarioParameter( | |
| 50 const CString& scenario_name, | |
| 51 const CString& switch_name, | |
| 52 int num_required_parameters) { | |
| 53 MapScenariosIter iter = scenarios_.find(scenario_name); | |
| 54 if (iter == scenarios_.end()) { | |
| 55 return E_INVALIDARG; | |
| 56 } | |
| 57 | |
| 58 ScenarioParameter* scenario_parameter = | |
| 59 new ScenarioParameter(switch_name, num_required_parameters); | |
| 60 (*iter).second.required.push_back(scenario_parameter); | |
| 61 return S_OK; | |
| 62 } | |
| 63 | |
| 64 HRESULT CommandLineValidator::AddOptionalScenarioParameter( | |
| 65 const CString& scenario_name, | |
| 66 const CString& switch_name, | |
| 67 int num_required_parameters) { | |
| 68 MapScenariosIter iter = scenarios_.find(scenario_name); | |
| 69 if (iter == scenarios_.end()) { | |
| 70 return E_INVALIDARG; | |
| 71 } | |
| 72 | |
| 73 ScenarioParameter* scenario_parameter = | |
| 74 new ScenarioParameter(switch_name, num_required_parameters); | |
| 75 (*iter).second.optional.push_back(scenario_parameter); | |
| 76 return S_OK; | |
| 77 } | |
| 78 | |
| 79 HRESULT CommandLineValidator::CreateScenarioFromCmdLine( | |
| 80 const CString& command_line, | |
| 81 CString* scenario_name) { | |
| 82 ASSERT1(scenario_name); | |
| 83 | |
| 84 CommandLineParser parser; | |
| 85 HRESULT hr = parser.ParseFromString(command_line); | |
| 86 if (FAILED(hr)) { | |
| 87 return hr; | |
| 88 } | |
| 89 | |
| 90 // Generate a unique scenario name. | |
| 91 CString scenario_name_str; | |
| 92 do { | |
| 93 ++scenario_sequence_number_; | |
| 94 scenario_name_str.Format(_T("scenario_%d"), scenario_sequence_number_); | |
| 95 } while (scenarios_.find(scenario_name_str) != scenarios_.end()); | |
| 96 | |
| 97 CreateScenario(scenario_name_str); | |
| 98 | |
| 99 int switch_count = parser.GetSwitchCount(); | |
| 100 for (int idx_switch = 0; idx_switch < switch_count; ++idx_switch) { | |
| 101 CString switch_name; | |
| 102 hr = parser.GetSwitchNameAtIndex(idx_switch, &switch_name); | |
| 103 if (FAILED(hr)) { | |
| 104 return hr; | |
| 105 } | |
| 106 | |
| 107 int arg_count = 0; | |
| 108 hr = parser.GetSwitchArgumentCount(switch_name, &arg_count); | |
| 109 if (FAILED(hr)) { | |
| 110 return hr; | |
| 111 } | |
| 112 | |
| 113 hr = AddScenarioParameter(scenario_name_str, switch_name, arg_count); | |
| 114 if (FAILED(hr)) { | |
| 115 return hr; | |
| 116 } | |
| 117 } | |
| 118 | |
| 119 switch_count = parser.GetOptionalSwitchCount(); | |
| 120 for (int idx_switch = 0; idx_switch < switch_count; ++idx_switch) { | |
| 121 CString switch_name; | |
| 122 hr = parser.GetOptionalSwitchNameAtIndex(idx_switch, &switch_name); | |
| 123 if (FAILED(hr)) { | |
| 124 return hr; | |
| 125 } | |
| 126 | |
| 127 int arg_count = 0; | |
| 128 hr = parser.GetOptionalSwitchArgumentCount(switch_name, &arg_count); | |
| 129 if (FAILED(hr)) { | |
| 130 return hr; | |
| 131 } | |
| 132 | |
| 133 hr = AddOptionalScenarioParameter(scenario_name_str, | |
| 134 switch_name, | |
| 135 arg_count); | |
| 136 if (FAILED(hr)) { | |
| 137 return hr; | |
| 138 } | |
| 139 } | |
| 140 | |
| 141 *scenario_name = scenario_name_str; | |
| 142 | |
| 143 return S_OK; | |
| 144 } | |
| 145 | |
| 146 HRESULT CommandLineValidator::Validate( | |
| 147 const CommandLineParser& command_line_parser, | |
| 148 CString* scenario_name) const { | |
| 149 // Attempt to verify the data within the command_line_parser against each of | |
| 150 // the scenarios. | |
| 151 MapScenariosConstIter scenarios_iter; | |
| 152 for (scenarios_iter = scenarios_.begin(); | |
| 153 scenarios_iter != scenarios_.end(); | |
| 154 ++scenarios_iter) { | |
| 155 // Make sure we have a match for the number of switches in this scenario. | |
| 156 int parser_switch_count = command_line_parser.GetSwitchCount(); | |
| 157 int scenario_required_switch_count = | |
| 158 (*scenarios_iter).second.required.size(); | |
| 159 int scenario_optional_switch_count = | |
| 160 (*scenarios_iter).second.optional.size(); | |
| 161 | |
| 162 if (parser_switch_count < scenario_required_switch_count || | |
| 163 parser_switch_count > scenario_required_switch_count + | |
| 164 scenario_optional_switch_count) { | |
| 165 continue; | |
| 166 } | |
| 167 | |
| 168 if (DoesScenarioMatch(command_line_parser, (*scenarios_iter).second)) { | |
| 169 *scenario_name = (*scenarios_iter).first; | |
| 170 return S_OK; | |
| 171 } | |
| 172 } | |
| 173 | |
| 174 return GOOGLEUPDATE_COMMANDLINE_E_NO_SCENARIO_HANDLER_MATCHED; | |
| 175 } | |
| 176 | |
| 177 bool CommandLineValidator::DoesScenarioMatch( | |
| 178 const CommandLineParser& command_line_parser, | |
| 179 const ScenarioParameters& scenario_parameters) const { | |
| 180 // Make sure that each switch matches with the right number of arguments. | |
| 181 ScenarioParameterVectorConstIter parameter_iter; | |
| 182 for (parameter_iter = scenario_parameters.required.begin(); | |
| 183 parameter_iter != scenario_parameters.required.end(); | |
| 184 ++parameter_iter) { | |
| 185 CString current_switch_name = (*parameter_iter)->switch_name_; | |
| 186 // This would probably allow duplicate switches (i.e. /c /c) in a command | |
| 187 // line. | |
| 188 if (!command_line_parser.HasSwitch(current_switch_name)) { | |
| 189 return false; | |
| 190 } | |
| 191 | |
| 192 int arg_count = 0; | |
| 193 HRESULT hr = command_line_parser.GetSwitchArgumentCount(current_switch_name, | |
| 194 &arg_count); | |
| 195 if (FAILED(hr)) { | |
| 196 return false; | |
| 197 } | |
| 198 | |
| 199 int switch_arg_count = (*parameter_iter)->num_required_parameters_; | |
| 200 if (arg_count != switch_arg_count) { | |
| 201 return false; | |
| 202 } | |
| 203 } | |
| 204 | |
| 205 int parser_optional_switch_count = command_line_parser.GetSwitchCount() - | |
| 206 scenario_parameters.required.size(); | |
| 207 for (parameter_iter = scenario_parameters.optional.begin(); | |
| 208 parser_optional_switch_count != 0 && | |
| 209 parameter_iter != scenario_parameters.optional.end(); | |
| 210 ++parameter_iter) { | |
| 211 CString current_switch_name = (*parameter_iter)->switch_name_; | |
| 212 // This would probably allow duplicate optional switches (i.e. /oem /oem) in | |
| 213 // a command line. | |
| 214 if (!command_line_parser.HasSwitch(current_switch_name)) { | |
| 215 continue; | |
| 216 } | |
| 217 | |
| 218 int arg_count = 0; | |
| 219 HRESULT hr = command_line_parser.GetSwitchArgumentCount(current_switch_name, | |
| 220 &arg_count); | |
| 221 if (FAILED(hr)) { | |
| 222 return false; | |
| 223 } | |
| 224 | |
| 225 int switch_arg_count = (*parameter_iter)->num_required_parameters_; | |
| 226 if (arg_count != switch_arg_count) { | |
| 227 return false; | |
| 228 } | |
| 229 --parser_optional_switch_count; | |
| 230 } | |
| 231 | |
| 232 return parser_optional_switch_count == 0; | |
| 233 } | |
| 234 | |
| 235 void CommandLineValidator::Clear() { | |
| 236 MapScenariosIter scenarios_iter; | |
| 237 for (scenarios_iter = scenarios_.begin(); | |
| 238 scenarios_iter != scenarios_.end(); | |
| 239 ++scenarios_iter) { | |
| 240 ScenarioParameterVectorIter param_iter; | |
| 241 for (param_iter = (*scenarios_iter).second.required.begin(); | |
| 242 param_iter != (*scenarios_iter).second.required.end(); | |
| 243 ++param_iter) { | |
| 244 delete *param_iter; | |
| 245 } | |
| 246 for (param_iter = (*scenarios_iter).second.optional.begin(); | |
| 247 param_iter != (*scenarios_iter).second.optional.end(); | |
| 248 ++param_iter) { | |
| 249 delete *param_iter; | |
| 250 } | |
| 251 } | |
| 252 scenarios_.clear(); | |
| 253 } | |
| 254 | |
| 255 } // namespace omaha | |
| 256 | |
| OLD | NEW |