• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include "host/commands/cvd/parser/cf_configs_common.h"
17 
18 #include <android-base/logging.h>
19 namespace cuttlefish {
20 
21 /**
22  * Validate Json data Name and type
23  */
ValidateTypo(const Json::Value & root,const std::map<std::string,Json::ValueType> & map)24 Result<void> ValidateTypo(const Json::Value& root,
25                           const std::map<std::string, Json::ValueType>& map) {
26   for (const std::string& flag : root.getMemberNames()) {
27     CF_EXPECT(map.count(flag) != 0 , "Invalid flag name (typo) , Param --> " << flag<< " not recognized");
28     CF_EXPECT(root[flag].isConvertibleTo(map.at(flag)), "Invalid flag typ"<< flag);
29   }
30   return {};
31 }
32 
ValidateIntConfig(const Json::Value & instances,const std::string & group,const std::string & json_flag,std::function<Result<void> (int)> validate_config)33 Result<void> ValidateIntConfig(
34     const Json::Value& instances, const std::string& group,
35     const std::string& json_flag,
36     std::function<Result<void>(int)> validate_config) {
37   // Allocate and initialize with default values
38   int size = instances.size();
39   for (int i = 0; i < size; i++) {
40     if (instances[i].isMember(group) &&
41         (instances[i][group].isMember(json_flag))) {
42       int flag = instances[i][group][json_flag].asInt();
43       CF_EXPECT(validate_config(flag), "Invalid flag value \"" << flag << "\"");
44     }
45   }
46   return {};
47 }
48 
ValidateIntConfigSubGroup(const Json::Value & instances,const std::string & group,const std::string & subgroup,const std::string & json_flag,std::function<Result<void> (int)> validate_config)49 Result<void> ValidateIntConfigSubGroup(
50     const Json::Value& instances, const std::string& group,
51     const std::string& subgroup, const std::string& json_flag,
52     std::function<Result<void>(int)> validate_config) {
53   // Allocate and initialize with default values
54   int size = instances.size();
55   for (int i = 0; i < size; i++) {
56     if (instances[i].isMember(group) &&
57         (instances[i][group].isMember(subgroup)) &&
58         (instances[i][group][subgroup].isMember(json_flag))) {
59       int flag = instances[i][group][subgroup][json_flag].asInt();
60       CF_EXPECT(validate_config(flag), "Invalid flag value \"" << flag << "\"");
61     }
62   }
63   return {};
64 }
65 
ValidateStringConfig(const Json::Value & instances,const std::string & group,const std::string & json_flag,std::function<Result<void> (const std::string &)> validate_config)66 Result<void> ValidateStringConfig(
67     const Json::Value& instances, const std::string& group,
68     const std::string& json_flag,
69     std::function<Result<void>(const std::string&)> validate_config) {
70   // Allocate and initialize with default values
71   int size = instances.size();
72   for (int i = 0; i < size; i++) {
73     if (instances[i].isMember(group) &&
74         (instances[i][group].isMember(json_flag))) {
75       // Validate input parameter
76       std::string flag = instances[i][group][json_flag].asString();
77       CF_EXPECT(validate_config(flag), "Invalid flag value \"" << flag << "\"");
78     }
79   }
80   return {};
81 }
82 
ValidateStringConfigSubGroup(const Json::Value & instances,const std::string & group,const std::string & subgroup,const std::string & json_flag,std::function<Result<void> (const std::string &)> validate_config)83 Result<void> ValidateStringConfigSubGroup(
84     const Json::Value& instances, const std::string& group,
85     const std::string& subgroup, const std::string& json_flag,
86     std::function<Result<void>(const std::string&)> validate_config) {
87   // Allocate and initialize with default values
88   int size = instances.size();
89   for (int i = 0; i < size; i++) {
90     if (!instances[i].isMember(group) ||
91         (!instances[i][group].isMember(subgroup)) ||
92         (!instances[i][group][subgroup].isMember(json_flag))) {
93       std::string flag = instances[i][group][subgroup][json_flag].asString();
94       CF_EXPECT(validate_config(flag), "Invalid flag value \"" << flag << "\"");
95     }
96   }
97   return {};
98 }
99 
InitIntConfig(Json::Value & instances,const std::string & group,const std::string & json_flag,int default_value)100 void InitIntConfig(Json::Value& instances, const std::string& group,
101                    const std::string& json_flag, int default_value) {
102   // Allocate and initialize with default values
103   int size = instances.size();
104   for (int i = 0; i < size; i++) {
105     if (!instances[i].isMember(group) ||
106         (!instances[i][group].isMember(json_flag))) {
107       instances[i][group][json_flag] = default_value;
108     }
109   }
110 }
111 
InitIntConfigSubGroup(Json::Value & instances,const std::string & group,const std::string & subgroup,const std::string & json_flag,int default_value)112 void InitIntConfigSubGroup(Json::Value& instances, const std::string& group,
113                            const std::string& subgroup,
114                            const std::string& json_flag, int default_value) {
115   // Allocate and initialize with default values
116   int size = instances.size();
117   for (int i = 0; i < size; i++) {
118     if (!instances[i].isMember(group) ||
119         (!instances[i][group].isMember(subgroup)) ||
120         (!instances[i][group][subgroup].isMember(json_flag))) {
121       instances[i][group][subgroup][json_flag] = default_value;
122     }
123   }
124 }
125 
InitIntConfigSubGroupVector(Json::Value & instances,const std::string & group,const std::string & subgroup,const std::string & json_flag,int default_value)126 void InitIntConfigSubGroupVector(Json::Value& instances,
127                                  const std::string& group,
128                                  const std::string& subgroup,
129                                  const std::string& json_flag,
130                                  int default_value) {
131   // Allocate and initialize with default values
132   for (int i = 0; i < instances.size(); i++) {
133     if (!instances[i].isMember(group) ||
134         (!instances[i][group].isMember(subgroup)) ||
135         (instances[i][group][subgroup].size() == 0)) {
136       instances[i][group][subgroup][0][json_flag] = default_value;
137 
138     } else {
139       // Check the whole array
140       int vector_size = instances[i][group][subgroup].size();
141       for (int j = 0; j < vector_size; j++) {
142         if (!instances[i][group][subgroup][j].isMember(json_flag)) {
143           instances[i][group][subgroup][j][json_flag] = default_value;
144         }
145       }
146     }
147   }
148 }
149 
InitStringConfig(Json::Value & instances,const std::string & group,const std::string & json_flag,const std::string & default_value)150 void InitStringConfig(Json::Value& instances, const std::string& group,
151                       const std::string& json_flag, const std::string& default_value) {
152   // Allocate and initialize with default values
153   int size = instances.size();
154   for (int i = 0; i < size; i++) {
155     if (!instances[i].isMember(group) ||
156         (!instances[i][group].isMember(json_flag))) {
157       instances[i][group][json_flag] = default_value;
158     }
159   }
160 }
161 
InitStringConfigSubGroup(Json::Value & instances,const std::string & group,const std::string & subgroup,const std::string & json_flag,const std::string & default_value)162 void InitStringConfigSubGroup(Json::Value& instances, const std::string& group,
163                               const std::string& subgroup,
164                               const std::string& json_flag,
165                               const std::string& default_value) {
166   // Allocate and initialize with default values
167   int size = instances.size();
168   for (int i = 0; i < size; i++) {
169     if (!instances[i].isMember(group) ||
170         (!instances[i][group].isMember(subgroup)) ||
171         (!instances[i][group][subgroup].isMember(json_flag))) {
172       instances[i][group][subgroup][json_flag] = default_value;
173     }
174   }
175 }
176 
InitBoolConfig(Json::Value & instances,const std::string & group,const std::string & json_flag,const bool default_value)177 void InitBoolConfig(Json::Value& instances, const std::string& group,
178                     const std::string& json_flag, const bool default_value) {
179   // Allocate and initialize with default values
180   int size = instances.size();
181   for (int i = 0; i < size; i++) {
182     if (!instances[i].isMember(group) ||
183         (!instances[i][group].isMember(json_flag))) {
184       instances[i][group][json_flag] = default_value;
185     }
186   }
187 }
188 
InitBoolConfigSubGroup(Json::Value & instances,const std::string & group,const std::string & subgroup,const std::string & json_flag,const bool default_value)189 void InitBoolConfigSubGroup(Json::Value& instances, const std::string& group,
190                             const std::string& subgroup,
191                             const std::string& json_flag,
192                             const bool default_value) {
193   // Allocate and initialize with default values
194   int size = instances.size();
195   for (int i = 0; i < size; i++) {
196     if (!instances[i].isMember(group) ||
197         (!instances[i][group].isMember(subgroup)) ||
198         (!instances[i][group][subgroup].isMember(json_flag))) {
199       instances[i][group][subgroup][json_flag] = default_value;
200     }
201   }
202 }
203 
204 // TODO(b/255384531) for using variadic functions
205 
GenerateGflag(const Json::Value & instances,const std::string & gflag_name,const std::string & group,const std::string & json_flag)206 std::string GenerateGflag(const Json::Value& instances,
207                           const std::string& gflag_name,
208                           const std::string& group,
209                           const std::string& json_flag) {
210   int size = instances.size();
211   std::stringstream buff;
212   // Append Header
213   buff << "--" << gflag_name << "=";
214   // Append values
215   for (int i = 0; i < size; i++) {
216     buff << instances[i][group][json_flag].asString();
217     if (i != size - 1) {
218       buff << ",";
219     }
220   }
221   return buff.str();
222 }
223 
GenerateGflagSubGroup(const Json::Value & instances,const std::string & gflag_name,const std::string & group,const std::string & subgroup,const std::string & json_flag)224 std::string GenerateGflagSubGroup(const Json::Value& instances,
225                                   const std::string& gflag_name,
226                                   const std::string& group,
227                                   const std::string& subgroup,
228                                   const std::string& json_flag) {
229   int size = instances.size();
230   std::stringstream buff;
231   // Append Header
232   buff << "--" << gflag_name << "=";
233   // Append values
234   for (int i = 0; i < size; i++) {
235     buff << instances[i][group][subgroup][json_flag].asString();
236     if (i != size - 1){ buff << ",";}
237   }
238   return buff.str();
239 }
240 
MergeResults(std::vector<std::string> first_list,std::vector<std::string> scond_list)241 std::vector<std::string> MergeResults(std::vector<std::string> first_list,
242                                       std::vector<std::string> scond_list) {
243   std::vector<std::string> result;
244   result.reserve(first_list.size() + scond_list.size());
245   result.insert(result.begin(), first_list.begin(), first_list.end());
246   result.insert(result.end(), scond_list.begin(), scond_list.end());
247   return result;
248 }
249 
250 /**
251  * @brief This function merges two json objects and override json tree in dst
252  * with src json keys
253  *
254  * @param dst : destination json object tree(modified in place)
255  * @param src : input json object tree to be merged
256  */
MergeTwoJsonObjs(Json::Value & dst,const Json::Value & src)257 void MergeTwoJsonObjs(Json::Value& dst, const Json::Value& src) {
258   // Merge all members of src into dst
259   for (const auto& key : src.getMemberNames()) {
260     if (src[key].type() == Json::arrayValue) {
261       for (int i = 0; i < src[key].size(); i++) {
262         MergeTwoJsonObjs(dst[key][i], src[key][i]);
263       }
264     } else if (src[key].type() == Json::objectValue) {
265       MergeTwoJsonObjs(dst[key], src[key]);
266     } else {
267       dst[key] = src[key];
268     }
269   }
270 }
271 
272 }  // namespace cuttlefish
273