xref: /aosp_15_r20/system/libvintf/parse_string.cpp (revision 70a7ec852fcefd15a4fb57f8f183a8b1c3aacb08)
1*70a7ec85SAndroid Build Coastguard Worker /*
2*70a7ec85SAndroid Build Coastguard Worker  * Copyright (C) 2017 The Android Open Source Project
3*70a7ec85SAndroid Build Coastguard Worker  *
4*70a7ec85SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*70a7ec85SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*70a7ec85SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*70a7ec85SAndroid Build Coastguard Worker  *
8*70a7ec85SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*70a7ec85SAndroid Build Coastguard Worker  *
10*70a7ec85SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*70a7ec85SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*70a7ec85SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*70a7ec85SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*70a7ec85SAndroid Build Coastguard Worker  * limitations under the License.
15*70a7ec85SAndroid Build Coastguard Worker  */
16*70a7ec85SAndroid Build Coastguard Worker 
17*70a7ec85SAndroid Build Coastguard Worker // Convert objects from and to strings.
18*70a7ec85SAndroid Build Coastguard Worker 
19*70a7ec85SAndroid Build Coastguard Worker #include "parse_string.h"
20*70a7ec85SAndroid Build Coastguard Worker 
21*70a7ec85SAndroid Build Coastguard Worker #include <android-base/parseint.h>
22*70a7ec85SAndroid Build Coastguard Worker #include <android-base/strings.h>
23*70a7ec85SAndroid Build Coastguard Worker 
24*70a7ec85SAndroid Build Coastguard Worker #include "constants-private.h"
25*70a7ec85SAndroid Build Coastguard Worker 
26*70a7ec85SAndroid Build Coastguard Worker namespace android {
27*70a7ec85SAndroid Build Coastguard Worker using base::ParseUint;
28*70a7ec85SAndroid Build Coastguard Worker 
29*70a7ec85SAndroid Build Coastguard Worker namespace vintf {
30*70a7ec85SAndroid Build Coastguard Worker 
SplitString(const std::string & s,char c)31*70a7ec85SAndroid Build Coastguard Worker std::vector<std::string> SplitString(const std::string &s, char c) {
32*70a7ec85SAndroid Build Coastguard Worker     std::vector<std::string> components;
33*70a7ec85SAndroid Build Coastguard Worker 
34*70a7ec85SAndroid Build Coastguard Worker     size_t startPos = 0;
35*70a7ec85SAndroid Build Coastguard Worker     size_t matchPos;
36*70a7ec85SAndroid Build Coastguard Worker     while ((matchPos = s.find(c, startPos)) != std::string::npos) {
37*70a7ec85SAndroid Build Coastguard Worker         components.push_back(s.substr(startPos, matchPos - startPos));
38*70a7ec85SAndroid Build Coastguard Worker         startPos = matchPos + 1;
39*70a7ec85SAndroid Build Coastguard Worker     }
40*70a7ec85SAndroid Build Coastguard Worker 
41*70a7ec85SAndroid Build Coastguard Worker     if (startPos <= s.length()) {
42*70a7ec85SAndroid Build Coastguard Worker         components.push_back(s.substr(startPos));
43*70a7ec85SAndroid Build Coastguard Worker     }
44*70a7ec85SAndroid Build Coastguard Worker     return components;
45*70a7ec85SAndroid Build Coastguard Worker }
46*70a7ec85SAndroid Build Coastguard Worker 
47*70a7ec85SAndroid Build Coastguard Worker template <typename T>
operator <<(std::ostream & os,const std::vector<T> objs)48*70a7ec85SAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &os, const std::vector<T> objs) {
49*70a7ec85SAndroid Build Coastguard Worker     bool first = true;
50*70a7ec85SAndroid Build Coastguard Worker     for (const T &v : objs) {
51*70a7ec85SAndroid Build Coastguard Worker         if (!first) {
52*70a7ec85SAndroid Build Coastguard Worker             os << ",";
53*70a7ec85SAndroid Build Coastguard Worker         }
54*70a7ec85SAndroid Build Coastguard Worker         os << v;
55*70a7ec85SAndroid Build Coastguard Worker         first = false;
56*70a7ec85SAndroid Build Coastguard Worker     }
57*70a7ec85SAndroid Build Coastguard Worker     return os;
58*70a7ec85SAndroid Build Coastguard Worker }
59*70a7ec85SAndroid Build Coastguard Worker 
60*70a7ec85SAndroid Build Coastguard Worker template <typename T>
parse(const std::string & s,std::vector<T> * objs)61*70a7ec85SAndroid Build Coastguard Worker bool parse(const std::string &s, std::vector<T> *objs) {
62*70a7ec85SAndroid Build Coastguard Worker     std::vector<std::string> v = SplitString(s, ',');
63*70a7ec85SAndroid Build Coastguard Worker     objs->resize(v.size());
64*70a7ec85SAndroid Build Coastguard Worker     size_t idx = 0;
65*70a7ec85SAndroid Build Coastguard Worker     for (const auto &item : v) {
66*70a7ec85SAndroid Build Coastguard Worker         T ver;
67*70a7ec85SAndroid Build Coastguard Worker         if (!parse(item, &ver)) {
68*70a7ec85SAndroid Build Coastguard Worker             return false;
69*70a7ec85SAndroid Build Coastguard Worker         }
70*70a7ec85SAndroid Build Coastguard Worker         objs->at(idx++) = ver;
71*70a7ec85SAndroid Build Coastguard Worker     }
72*70a7ec85SAndroid Build Coastguard Worker     return true;
73*70a7ec85SAndroid Build Coastguard Worker }
74*70a7ec85SAndroid Build Coastguard Worker 
75*70a7ec85SAndroid Build Coastguard Worker template<typename E, typename Array>
parseEnum(const std::string & s,E * e,const Array & strings)76*70a7ec85SAndroid Build Coastguard Worker bool parseEnum(const std::string &s, E *e, const Array &strings) {
77*70a7ec85SAndroid Build Coastguard Worker     for (size_t i = 0; i < strings.size(); ++i) {
78*70a7ec85SAndroid Build Coastguard Worker         if (s == strings.at(i)) {
79*70a7ec85SAndroid Build Coastguard Worker             *e = static_cast<E>(i);
80*70a7ec85SAndroid Build Coastguard Worker             return true;
81*70a7ec85SAndroid Build Coastguard Worker         }
82*70a7ec85SAndroid Build Coastguard Worker     }
83*70a7ec85SAndroid Build Coastguard Worker     return false;
84*70a7ec85SAndroid Build Coastguard Worker }
85*70a7ec85SAndroid Build Coastguard Worker 
86*70a7ec85SAndroid Build Coastguard Worker #define DEFINE_PARSE_STREAMIN_FOR_ENUM(ENUM) \
87*70a7ec85SAndroid Build Coastguard Worker     bool parse(const std::string &s, ENUM *hf) {                   \
88*70a7ec85SAndroid Build Coastguard Worker         return parseEnum(s, hf, g##ENUM##Strings);                 \
89*70a7ec85SAndroid Build Coastguard Worker     }                                                              \
90*70a7ec85SAndroid Build Coastguard Worker     std::ostream &operator<<(std::ostream &os, ENUM hf) {          \
91*70a7ec85SAndroid Build Coastguard Worker         return os << g##ENUM##Strings.at(static_cast<size_t>(hf)); \
92*70a7ec85SAndroid Build Coastguard Worker     }                                                              \
93*70a7ec85SAndroid Build Coastguard Worker 
94*70a7ec85SAndroid Build Coastguard Worker DEFINE_PARSE_STREAMIN_FOR_ENUM(HalFormat)
95*70a7ec85SAndroid Build Coastguard Worker DEFINE_PARSE_STREAMIN_FOR_ENUM(Transport)
96*70a7ec85SAndroid Build Coastguard Worker DEFINE_PARSE_STREAMIN_FOR_ENUM(Arch)
97*70a7ec85SAndroid Build Coastguard Worker DEFINE_PARSE_STREAMIN_FOR_ENUM(KernelConfigType)
98*70a7ec85SAndroid Build Coastguard Worker DEFINE_PARSE_STREAMIN_FOR_ENUM(Tristate)
99*70a7ec85SAndroid Build Coastguard Worker DEFINE_PARSE_STREAMIN_FOR_ENUM(SchemaType)
100*70a7ec85SAndroid Build Coastguard Worker DEFINE_PARSE_STREAMIN_FOR_ENUM(XmlSchemaFormat)
101*70a7ec85SAndroid Build Coastguard Worker DEFINE_PARSE_STREAMIN_FOR_ENUM(ExclusiveTo)
102*70a7ec85SAndroid Build Coastguard Worker 
103*70a7ec85SAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &os, const KernelConfigTypedValue &kctv) {
104*70a7ec85SAndroid Build Coastguard Worker     switch (kctv.mType) {
105*70a7ec85SAndroid Build Coastguard Worker         case KernelConfigType::STRING:
106*70a7ec85SAndroid Build Coastguard Worker             return os << kctv.mStringValue;
107*70a7ec85SAndroid Build Coastguard Worker         case KernelConfigType::INTEGER:
108*70a7ec85SAndroid Build Coastguard Worker             return os << to_string(kctv.mIntegerValue);
109*70a7ec85SAndroid Build Coastguard Worker         case KernelConfigType::RANGE:
110*70a7ec85SAndroid Build Coastguard Worker             return os << to_string(kctv.mRangeValue.first) << "-"
111*70a7ec85SAndroid Build Coastguard Worker                       << to_string(kctv.mRangeValue.second);
112*70a7ec85SAndroid Build Coastguard Worker         case KernelConfigType::TRISTATE:
113*70a7ec85SAndroid Build Coastguard Worker             return os << to_string(kctv.mTristateValue);
114*70a7ec85SAndroid Build Coastguard Worker     }
115*70a7ec85SAndroid Build Coastguard Worker }
116*70a7ec85SAndroid Build Coastguard Worker 
parse(const std::string & s,Level * l)117*70a7ec85SAndroid Build Coastguard Worker bool parse(const std::string& s, Level* l) {
118*70a7ec85SAndroid Build Coastguard Worker     if (s.empty()) {
119*70a7ec85SAndroid Build Coastguard Worker         *l = Level::UNSPECIFIED;
120*70a7ec85SAndroid Build Coastguard Worker         return true;
121*70a7ec85SAndroid Build Coastguard Worker     }
122*70a7ec85SAndroid Build Coastguard Worker     if (s == "legacy") {
123*70a7ec85SAndroid Build Coastguard Worker         *l = Level::LEGACY;
124*70a7ec85SAndroid Build Coastguard Worker         return true;
125*70a7ec85SAndroid Build Coastguard Worker     }
126*70a7ec85SAndroid Build Coastguard Worker     size_t value;
127*70a7ec85SAndroid Build Coastguard Worker     if (!ParseUint(s, &value)) {
128*70a7ec85SAndroid Build Coastguard Worker         return false;
129*70a7ec85SAndroid Build Coastguard Worker     }
130*70a7ec85SAndroid Build Coastguard Worker     *l = static_cast<Level>(value);
131*70a7ec85SAndroid Build Coastguard Worker     if (!IsValid(*l)) {
132*70a7ec85SAndroid Build Coastguard Worker         return false;
133*70a7ec85SAndroid Build Coastguard Worker     }
134*70a7ec85SAndroid Build Coastguard Worker     return true;
135*70a7ec85SAndroid Build Coastguard Worker }
136*70a7ec85SAndroid Build Coastguard Worker 
operator <<(std::ostream & os,Level l)137*70a7ec85SAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream& os, Level l) {
138*70a7ec85SAndroid Build Coastguard Worker     if (l == Level::UNSPECIFIED) {
139*70a7ec85SAndroid Build Coastguard Worker         return os;
140*70a7ec85SAndroid Build Coastguard Worker     }
141*70a7ec85SAndroid Build Coastguard Worker     if (l == Level::LEGACY) {
142*70a7ec85SAndroid Build Coastguard Worker         return os << "legacy";
143*70a7ec85SAndroid Build Coastguard Worker     }
144*70a7ec85SAndroid Build Coastguard Worker     return os << static_cast<size_t>(l);
145*70a7ec85SAndroid Build Coastguard Worker }
146*70a7ec85SAndroid Build Coastguard Worker 
147*70a7ec85SAndroid Build Coastguard Worker // Notice that strtoull is used even though KernelConfigIntValue is signed int64_t,
148*70a7ec85SAndroid Build Coastguard Worker // because strtoull can accept negative values as well.
149*70a7ec85SAndroid Build Coastguard Worker // Notice that according to man strtoul, strtoull can actually accept
150*70a7ec85SAndroid Build Coastguard Worker // -2^64 + 1 to 2^64 - 1, with the 65th bit truncated.
151*70a7ec85SAndroid Build Coastguard Worker // ParseInt / ParseUint are not used because they do not handle signed hex very well.
152*70a7ec85SAndroid Build Coastguard Worker template <typename T>
parseKernelConfigIntHelper(const std::string & s,T * i)153*70a7ec85SAndroid Build Coastguard Worker bool parseKernelConfigIntHelper(const std::string &s, T *i) {
154*70a7ec85SAndroid Build Coastguard Worker     char *end;
155*70a7ec85SAndroid Build Coastguard Worker     errno = 0;
156*70a7ec85SAndroid Build Coastguard Worker     unsigned long long int ulli = strtoull(s.c_str(), &end, 0 /* base */);
157*70a7ec85SAndroid Build Coastguard Worker     // It is implementation defined that what value will be returned by strtoull
158*70a7ec85SAndroid Build Coastguard Worker     // in the error case, so we are checking errno directly here.
159*70a7ec85SAndroid Build Coastguard Worker     if (errno == 0 && s.c_str() != end && *end == '\0') {
160*70a7ec85SAndroid Build Coastguard Worker         *i = static_cast<T>(ulli);
161*70a7ec85SAndroid Build Coastguard Worker         return true;
162*70a7ec85SAndroid Build Coastguard Worker     }
163*70a7ec85SAndroid Build Coastguard Worker     return false;
164*70a7ec85SAndroid Build Coastguard Worker }
165*70a7ec85SAndroid Build Coastguard Worker 
parseKernelConfigInt(const std::string & s,int64_t * i)166*70a7ec85SAndroid Build Coastguard Worker bool parseKernelConfigInt(const std::string &s, int64_t *i) {
167*70a7ec85SAndroid Build Coastguard Worker     return parseKernelConfigIntHelper(s, i);
168*70a7ec85SAndroid Build Coastguard Worker }
169*70a7ec85SAndroid Build Coastguard Worker 
parseKernelConfigInt(const std::string & s,uint64_t * i)170*70a7ec85SAndroid Build Coastguard Worker bool parseKernelConfigInt(const std::string &s, uint64_t *i) {
171*70a7ec85SAndroid Build Coastguard Worker     return parseKernelConfigIntHelper(s, i);
172*70a7ec85SAndroid Build Coastguard Worker }
173*70a7ec85SAndroid Build Coastguard Worker 
parseRange(const std::string & s,KernelConfigRangeValue * range)174*70a7ec85SAndroid Build Coastguard Worker bool parseRange(const std::string &s, KernelConfigRangeValue *range) {
175*70a7ec85SAndroid Build Coastguard Worker     auto pos = s.find('-');
176*70a7ec85SAndroid Build Coastguard Worker     if (pos == std::string::npos) {
177*70a7ec85SAndroid Build Coastguard Worker         return false;
178*70a7ec85SAndroid Build Coastguard Worker     }
179*70a7ec85SAndroid Build Coastguard Worker     return parseKernelConfigInt(s.substr(0, pos),  &range->first)
180*70a7ec85SAndroid Build Coastguard Worker         && parseKernelConfigInt(s.substr(pos + 1), &range->second);
181*70a7ec85SAndroid Build Coastguard Worker }
182*70a7ec85SAndroid Build Coastguard Worker 
parse(const std::string & s,KernelConfigKey * key)183*70a7ec85SAndroid Build Coastguard Worker bool parse(const std::string &s, KernelConfigKey *key) {
184*70a7ec85SAndroid Build Coastguard Worker     *key = s;
185*70a7ec85SAndroid Build Coastguard Worker     return true;
186*70a7ec85SAndroid Build Coastguard Worker }
187*70a7ec85SAndroid Build Coastguard Worker 
parseKernelConfigValue(const std::string & s,KernelConfigTypedValue * kctv)188*70a7ec85SAndroid Build Coastguard Worker bool parseKernelConfigValue(const std::string &s, KernelConfigTypedValue *kctv) {
189*70a7ec85SAndroid Build Coastguard Worker     switch (kctv->mType) {
190*70a7ec85SAndroid Build Coastguard Worker         case KernelConfigType::STRING:
191*70a7ec85SAndroid Build Coastguard Worker             kctv->mStringValue = s;
192*70a7ec85SAndroid Build Coastguard Worker             return true;
193*70a7ec85SAndroid Build Coastguard Worker         case KernelConfigType::INTEGER:
194*70a7ec85SAndroid Build Coastguard Worker             return parseKernelConfigInt(s, &kctv->mIntegerValue);
195*70a7ec85SAndroid Build Coastguard Worker         case KernelConfigType::RANGE:
196*70a7ec85SAndroid Build Coastguard Worker             return parseRange(s, &kctv->mRangeValue);
197*70a7ec85SAndroid Build Coastguard Worker         case KernelConfigType::TRISTATE:
198*70a7ec85SAndroid Build Coastguard Worker             return parse(s, &kctv->mTristateValue);
199*70a7ec85SAndroid Build Coastguard Worker     }
200*70a7ec85SAndroid Build Coastguard Worker }
201*70a7ec85SAndroid Build Coastguard Worker 
parseKernelConfigTypedValue(const std::string & s,KernelConfigTypedValue * kctv)202*70a7ec85SAndroid Build Coastguard Worker bool parseKernelConfigTypedValue(const std::string& s, KernelConfigTypedValue* kctv) {
203*70a7ec85SAndroid Build Coastguard Worker     if (s.size() > 1 && s[0] == '"' && s.back() == '"') {
204*70a7ec85SAndroid Build Coastguard Worker         kctv->mType = KernelConfigType::STRING;
205*70a7ec85SAndroid Build Coastguard Worker         kctv->mStringValue = s.substr(1, s.size()-2);
206*70a7ec85SAndroid Build Coastguard Worker         return true;
207*70a7ec85SAndroid Build Coastguard Worker     }
208*70a7ec85SAndroid Build Coastguard Worker     if (parseKernelConfigInt(s, &kctv->mIntegerValue)) {
209*70a7ec85SAndroid Build Coastguard Worker         kctv->mType = KernelConfigType::INTEGER;
210*70a7ec85SAndroid Build Coastguard Worker         return true;
211*70a7ec85SAndroid Build Coastguard Worker     }
212*70a7ec85SAndroid Build Coastguard Worker     if (parse(s, &kctv->mTristateValue)) {
213*70a7ec85SAndroid Build Coastguard Worker         kctv->mType = KernelConfigType::TRISTATE;
214*70a7ec85SAndroid Build Coastguard Worker         return true;
215*70a7ec85SAndroid Build Coastguard Worker     }
216*70a7ec85SAndroid Build Coastguard Worker     // Do not test for KernelConfigType::RANGE.
217*70a7ec85SAndroid Build Coastguard Worker     return false;
218*70a7ec85SAndroid Build Coastguard Worker }
219*70a7ec85SAndroid Build Coastguard Worker 
parse(const std::string & s,Version * ver)220*70a7ec85SAndroid Build Coastguard Worker bool parse(const std::string &s, Version *ver) {
221*70a7ec85SAndroid Build Coastguard Worker     std::vector<std::string> v = SplitString(s, '.');
222*70a7ec85SAndroid Build Coastguard Worker     if (v.size() != 2) {
223*70a7ec85SAndroid Build Coastguard Worker         return false;
224*70a7ec85SAndroid Build Coastguard Worker     }
225*70a7ec85SAndroid Build Coastguard Worker     size_t major, minor;
226*70a7ec85SAndroid Build Coastguard Worker     if (!ParseUint(v[0], &major)) {
227*70a7ec85SAndroid Build Coastguard Worker         return false;
228*70a7ec85SAndroid Build Coastguard Worker     }
229*70a7ec85SAndroid Build Coastguard Worker     if (!ParseUint(v[1], &minor)) {
230*70a7ec85SAndroid Build Coastguard Worker         return false;
231*70a7ec85SAndroid Build Coastguard Worker     }
232*70a7ec85SAndroid Build Coastguard Worker     *ver = Version(major, minor);
233*70a7ec85SAndroid Build Coastguard Worker     return true;
234*70a7ec85SAndroid Build Coastguard Worker }
235*70a7ec85SAndroid Build Coastguard Worker 
parse(const std::string & s,SepolicyVersion * sepolicyVer)236*70a7ec85SAndroid Build Coastguard Worker bool parse(const std::string& s, SepolicyVersion* sepolicyVer) {
237*70a7ec85SAndroid Build Coastguard Worker     size_t major;
238*70a7ec85SAndroid Build Coastguard Worker     // vFRC versioning
239*70a7ec85SAndroid Build Coastguard Worker     if (ParseUint(s, &major)) {
240*70a7ec85SAndroid Build Coastguard Worker         *sepolicyVer = SepolicyVersion(major, std::nullopt);
241*70a7ec85SAndroid Build Coastguard Worker         return true;
242*70a7ec85SAndroid Build Coastguard Worker     }
243*70a7ec85SAndroid Build Coastguard Worker     // fall back to normal Version
244*70a7ec85SAndroid Build Coastguard Worker     Version ver;
245*70a7ec85SAndroid Build Coastguard Worker     if (!parse(s, &ver)) return false;
246*70a7ec85SAndroid Build Coastguard Worker     *sepolicyVer = SepolicyVersion(ver.majorVer, ver.minorVer);
247*70a7ec85SAndroid Build Coastguard Worker     return true;
248*70a7ec85SAndroid Build Coastguard Worker }
249*70a7ec85SAndroid Build Coastguard Worker 
operator <<(std::ostream & os,const Version & ver)250*70a7ec85SAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &os, const Version &ver) {
251*70a7ec85SAndroid Build Coastguard Worker     return os << ver.majorVer << "." << ver.minorVer;
252*70a7ec85SAndroid Build Coastguard Worker }
253*70a7ec85SAndroid Build Coastguard Worker 
operator <<(std::ostream & os,const SepolicyVersion & ver)254*70a7ec85SAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream& os, const SepolicyVersion& ver) {
255*70a7ec85SAndroid Build Coastguard Worker     os << ver.majorVer;
256*70a7ec85SAndroid Build Coastguard Worker     if (ver.minorVer.has_value()) os << "." << ver.minorVer.value();
257*70a7ec85SAndroid Build Coastguard Worker     return os;
258*70a7ec85SAndroid Build Coastguard Worker }
259*70a7ec85SAndroid Build Coastguard Worker 
260*70a7ec85SAndroid Build Coastguard Worker // Helper for parsing a VersionRange object. versionParser defines how the first half
261*70a7ec85SAndroid Build Coastguard Worker // (before the '-' character) of the string is parsed.
parseVersionRange(const std::string & s,VersionRange * vr,const std::function<bool (const std::string &,Version *)> & versionParser)262*70a7ec85SAndroid Build Coastguard Worker static bool parseVersionRange(
263*70a7ec85SAndroid Build Coastguard Worker     const std::string& s, VersionRange* vr,
264*70a7ec85SAndroid Build Coastguard Worker     const std::function<bool(const std::string&, Version*)>& versionParser) {
265*70a7ec85SAndroid Build Coastguard Worker     std::vector<std::string> v = SplitString(s, '-');
266*70a7ec85SAndroid Build Coastguard Worker     if (v.size() != 1 && v.size() != 2) {
267*70a7ec85SAndroid Build Coastguard Worker         return false;
268*70a7ec85SAndroid Build Coastguard Worker     }
269*70a7ec85SAndroid Build Coastguard Worker     Version minVer;
270*70a7ec85SAndroid Build Coastguard Worker     if (!versionParser(v[0], &minVer)) {
271*70a7ec85SAndroid Build Coastguard Worker         return false;
272*70a7ec85SAndroid Build Coastguard Worker     }
273*70a7ec85SAndroid Build Coastguard Worker     if (v.size() == 1) {
274*70a7ec85SAndroid Build Coastguard Worker         *vr = VersionRange(minVer.majorVer, minVer.minorVer);
275*70a7ec85SAndroid Build Coastguard Worker     } else {
276*70a7ec85SAndroid Build Coastguard Worker         size_t maxMinor;
277*70a7ec85SAndroid Build Coastguard Worker         if (!ParseUint(v[1], &maxMinor)) {
278*70a7ec85SAndroid Build Coastguard Worker             return false;
279*70a7ec85SAndroid Build Coastguard Worker         }
280*70a7ec85SAndroid Build Coastguard Worker         *vr = VersionRange(minVer.majorVer, minVer.minorVer, maxMinor);
281*70a7ec85SAndroid Build Coastguard Worker     }
282*70a7ec85SAndroid Build Coastguard Worker     return true;
283*70a7ec85SAndroid Build Coastguard Worker }
284*70a7ec85SAndroid Build Coastguard Worker 
parse(const std::string & s,VersionRange * vr)285*70a7ec85SAndroid Build Coastguard Worker bool parse(const std::string& s, VersionRange* vr) {
286*70a7ec85SAndroid Build Coastguard Worker     bool (*versionParser)(const std::string&, Version*) = parse;
287*70a7ec85SAndroid Build Coastguard Worker     return parseVersionRange(s, vr, versionParser);
288*70a7ec85SAndroid Build Coastguard Worker }
289*70a7ec85SAndroid Build Coastguard Worker 
290*70a7ec85SAndroid Build Coastguard Worker // TODO(b/314010177): Add unit tests for this function.
parse(const std::string & s,SepolicyVersionRange * svr)291*70a7ec85SAndroid Build Coastguard Worker bool parse(const std::string& s, SepolicyVersionRange* svr) {
292*70a7ec85SAndroid Build Coastguard Worker     SepolicyVersion sepolicyVersion;
293*70a7ec85SAndroid Build Coastguard Worker     if (parse(s, &sepolicyVersion)) {
294*70a7ec85SAndroid Build Coastguard Worker         *svr = SepolicyVersionRange(sepolicyVersion.majorVer, sepolicyVersion.minorVer);
295*70a7ec85SAndroid Build Coastguard Worker         return true;
296*70a7ec85SAndroid Build Coastguard Worker     }
297*70a7ec85SAndroid Build Coastguard Worker     // fall back to normal VersionRange
298*70a7ec85SAndroid Build Coastguard Worker     VersionRange vr;
299*70a7ec85SAndroid Build Coastguard Worker     if (parse(s, &vr)) {
300*70a7ec85SAndroid Build Coastguard Worker         *svr = SepolicyVersionRange(vr.majorVer, vr.minMinor, vr.maxMinor);
301*70a7ec85SAndroid Build Coastguard Worker         return true;
302*70a7ec85SAndroid Build Coastguard Worker     }
303*70a7ec85SAndroid Build Coastguard Worker     return false;
304*70a7ec85SAndroid Build Coastguard Worker }
305*70a7ec85SAndroid Build Coastguard Worker 
operator <<(std::ostream & os,const VersionRange & vr)306*70a7ec85SAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &os, const VersionRange &vr) {
307*70a7ec85SAndroid Build Coastguard Worker     if (vr.isSingleVersion()) {
308*70a7ec85SAndroid Build Coastguard Worker         return os << vr.minVer();
309*70a7ec85SAndroid Build Coastguard Worker     }
310*70a7ec85SAndroid Build Coastguard Worker     return os << vr.minVer() << "-" << vr.maxMinor;
311*70a7ec85SAndroid Build Coastguard Worker }
312*70a7ec85SAndroid Build Coastguard Worker 
operator <<(std::ostream & os,const SepolicyVersionRange & svr)313*70a7ec85SAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream& os, const SepolicyVersionRange& svr) {
314*70a7ec85SAndroid Build Coastguard Worker     if (svr.maxMinor.has_value()) {
315*70a7ec85SAndroid Build Coastguard Worker         return os << VersionRange(svr.majorVer, svr.minMinor.value_or(0), svr.maxMinor.value());
316*70a7ec85SAndroid Build Coastguard Worker     }
317*70a7ec85SAndroid Build Coastguard Worker 
318*70a7ec85SAndroid Build Coastguard Worker     return os << SepolicyVersion(svr.majorVer, svr.minMinor);
319*70a7ec85SAndroid Build Coastguard Worker }
320*70a7ec85SAndroid Build Coastguard Worker 
321*70a7ec85SAndroid Build Coastguard Worker #pragma clang diagnostic push
322*70a7ec85SAndroid Build Coastguard Worker #pragma clang diagnostic ignored "-Wdeprecated-declarations"
parse(const std::string & s,VndkVersionRange * vr)323*70a7ec85SAndroid Build Coastguard Worker bool parse(const std::string &s, VndkVersionRange *vr) {
324*70a7ec85SAndroid Build Coastguard Worker     std::vector<std::string> v = SplitString(s, '-');
325*70a7ec85SAndroid Build Coastguard Worker     if (v.size() != 1 && v.size() != 2) {
326*70a7ec85SAndroid Build Coastguard Worker         return false;
327*70a7ec85SAndroid Build Coastguard Worker     }
328*70a7ec85SAndroid Build Coastguard Worker     std::vector<std::string> minVector = SplitString(v[0], '.');
329*70a7ec85SAndroid Build Coastguard Worker     if (minVector.size() != 3) {
330*70a7ec85SAndroid Build Coastguard Worker         return false;
331*70a7ec85SAndroid Build Coastguard Worker     }
332*70a7ec85SAndroid Build Coastguard Worker     if (!ParseUint(minVector[0], &vr->sdk) ||
333*70a7ec85SAndroid Build Coastguard Worker         !ParseUint(minVector[1], &vr->vndk) ||
334*70a7ec85SAndroid Build Coastguard Worker         !ParseUint(minVector[2], &vr->patchMin)) {
335*70a7ec85SAndroid Build Coastguard Worker         return false;
336*70a7ec85SAndroid Build Coastguard Worker     }
337*70a7ec85SAndroid Build Coastguard Worker     if (v.size() == 1) {
338*70a7ec85SAndroid Build Coastguard Worker         vr->patchMax = vr->patchMin;
339*70a7ec85SAndroid Build Coastguard Worker         return true;
340*70a7ec85SAndroid Build Coastguard Worker     } else {
341*70a7ec85SAndroid Build Coastguard Worker         return ParseUint(v[1], &vr->patchMax);
342*70a7ec85SAndroid Build Coastguard Worker     }
343*70a7ec85SAndroid Build Coastguard Worker }
344*70a7ec85SAndroid Build Coastguard Worker 
operator <<(std::ostream & os,const VndkVersionRange & vr)345*70a7ec85SAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &os, const VndkVersionRange &vr) {
346*70a7ec85SAndroid Build Coastguard Worker     os << vr.sdk << "." << vr.vndk << "." << vr.patchMin;
347*70a7ec85SAndroid Build Coastguard Worker     if (!vr.isSingleVersion()) {
348*70a7ec85SAndroid Build Coastguard Worker         os << "-" << vr.patchMax;
349*70a7ec85SAndroid Build Coastguard Worker     }
350*70a7ec85SAndroid Build Coastguard Worker     return os;
351*70a7ec85SAndroid Build Coastguard Worker }
352*70a7ec85SAndroid Build Coastguard Worker #pragma clang diagnostic pop
353*70a7ec85SAndroid Build Coastguard Worker 
parse(const std::string & s,KernelVersion * kernelVersion)354*70a7ec85SAndroid Build Coastguard Worker bool parse(const std::string &s, KernelVersion *kernelVersion) {
355*70a7ec85SAndroid Build Coastguard Worker     std::vector<std::string> v = SplitString(s, '.');
356*70a7ec85SAndroid Build Coastguard Worker     if (v.size() != 3) {
357*70a7ec85SAndroid Build Coastguard Worker         return false;
358*70a7ec85SAndroid Build Coastguard Worker     }
359*70a7ec85SAndroid Build Coastguard Worker     size_t version, major, minor;
360*70a7ec85SAndroid Build Coastguard Worker     if (!ParseUint(v[0], &version)) {
361*70a7ec85SAndroid Build Coastguard Worker         return false;
362*70a7ec85SAndroid Build Coastguard Worker     }
363*70a7ec85SAndroid Build Coastguard Worker     if (!ParseUint(v[1], &major)) {
364*70a7ec85SAndroid Build Coastguard Worker         return false;
365*70a7ec85SAndroid Build Coastguard Worker     }
366*70a7ec85SAndroid Build Coastguard Worker     if (!ParseUint(v[2], &minor)) {
367*70a7ec85SAndroid Build Coastguard Worker         return false;
368*70a7ec85SAndroid Build Coastguard Worker     }
369*70a7ec85SAndroid Build Coastguard Worker     *kernelVersion = KernelVersion(version, major, minor);
370*70a7ec85SAndroid Build Coastguard Worker     return true;
371*70a7ec85SAndroid Build Coastguard Worker }
372*70a7ec85SAndroid Build Coastguard Worker 
operator <<(std::ostream & os,const TransportArch & ta)373*70a7ec85SAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &os, const TransportArch &ta) {
374*70a7ec85SAndroid Build Coastguard Worker     return os << to_string(ta.transport) << to_string(ta.arch);
375*70a7ec85SAndroid Build Coastguard Worker }
376*70a7ec85SAndroid Build Coastguard Worker 
operator <<(std::ostream & os,const KernelVersion & ver)377*70a7ec85SAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &os, const KernelVersion &ver) {
378*70a7ec85SAndroid Build Coastguard Worker     return os << ver.version << "." << ver.majorRev << "." << ver.minorRev;
379*70a7ec85SAndroid Build Coastguard Worker }
380*70a7ec85SAndroid Build Coastguard Worker 
operator <<(std::ostream & os,const ManifestHal & hal)381*70a7ec85SAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &os, const ManifestHal &hal) {
382*70a7ec85SAndroid Build Coastguard Worker     return os << hal.format << "/"
383*70a7ec85SAndroid Build Coastguard Worker               << hal.name << "/"
384*70a7ec85SAndroid Build Coastguard Worker               << hal.transportArch << "/"
385*70a7ec85SAndroid Build Coastguard Worker               << hal.versions;
386*70a7ec85SAndroid Build Coastguard Worker }
387*70a7ec85SAndroid Build Coastguard Worker 
expandInstances(const MatrixHal & req,const VersionRange & vr,bool brace)388*70a7ec85SAndroid Build Coastguard Worker std::string expandInstances(const MatrixHal& req, const VersionRange& vr, bool brace) {
389*70a7ec85SAndroid Build Coastguard Worker     std::string s;
390*70a7ec85SAndroid Build Coastguard Worker     size_t count = 0;
391*70a7ec85SAndroid Build Coastguard Worker     req.forEachInstance(vr, [&](const auto& matrixInstance) {
392*70a7ec85SAndroid Build Coastguard Worker         if (count > 0) s += " AND ";
393*70a7ec85SAndroid Build Coastguard Worker         auto instance = matrixInstance.isRegex() ? matrixInstance.regexPattern()
394*70a7ec85SAndroid Build Coastguard Worker                                                  : matrixInstance.exactInstance();
395*70a7ec85SAndroid Build Coastguard Worker         switch (req.format) {
396*70a7ec85SAndroid Build Coastguard Worker             case HalFormat::AIDL: {
397*70a7ec85SAndroid Build Coastguard Worker                 s += toFQNameString(matrixInstance.interface(), instance) + " (@" +
398*70a7ec85SAndroid Build Coastguard Worker                      aidlVersionRangeToString(vr) + ")";
399*70a7ec85SAndroid Build Coastguard Worker             } break;
400*70a7ec85SAndroid Build Coastguard Worker             case HalFormat::HIDL:
401*70a7ec85SAndroid Build Coastguard Worker                 [[fallthrough]];
402*70a7ec85SAndroid Build Coastguard Worker             case HalFormat::NATIVE: {
403*70a7ec85SAndroid Build Coastguard Worker                 s += toFQNameString(vr, matrixInstance.interface(), instance);
404*70a7ec85SAndroid Build Coastguard Worker             } break;
405*70a7ec85SAndroid Build Coastguard Worker         }
406*70a7ec85SAndroid Build Coastguard Worker         count++;
407*70a7ec85SAndroid Build Coastguard Worker         return true;
408*70a7ec85SAndroid Build Coastguard Worker     });
409*70a7ec85SAndroid Build Coastguard Worker     if (count == 0) {
410*70a7ec85SAndroid Build Coastguard Worker         s += "@" + to_string(vr);
411*70a7ec85SAndroid Build Coastguard Worker     }
412*70a7ec85SAndroid Build Coastguard Worker     if (count >= 2 && brace) {
413*70a7ec85SAndroid Build Coastguard Worker         s = "(" + s + ")";
414*70a7ec85SAndroid Build Coastguard Worker     }
415*70a7ec85SAndroid Build Coastguard Worker     return s;
416*70a7ec85SAndroid Build Coastguard Worker }
417*70a7ec85SAndroid Build Coastguard Worker 
expandInstances(const MatrixHal & req)418*70a7ec85SAndroid Build Coastguard Worker std::vector<std::string> expandInstances(const MatrixHal& req) {
419*70a7ec85SAndroid Build Coastguard Worker     size_t count = req.instancesCount();
420*70a7ec85SAndroid Build Coastguard Worker     if (count == 0) {
421*70a7ec85SAndroid Build Coastguard Worker         return {};
422*70a7ec85SAndroid Build Coastguard Worker     }
423*70a7ec85SAndroid Build Coastguard Worker     if (count == 1) {
424*70a7ec85SAndroid Build Coastguard Worker         return {expandInstances(req, req.versionRanges.front(), false /* brace */)};
425*70a7ec85SAndroid Build Coastguard Worker     }
426*70a7ec85SAndroid Build Coastguard Worker     std::vector<std::string> ss;
427*70a7ec85SAndroid Build Coastguard Worker     for (const auto& vr : req.versionRanges) {
428*70a7ec85SAndroid Build Coastguard Worker         if (!ss.empty()) {
429*70a7ec85SAndroid Build Coastguard Worker             ss.back() += " OR";
430*70a7ec85SAndroid Build Coastguard Worker         }
431*70a7ec85SAndroid Build Coastguard Worker         ss.push_back(expandInstances(req, vr, true /* brace */));
432*70a7ec85SAndroid Build Coastguard Worker     }
433*70a7ec85SAndroid Build Coastguard Worker     return ss;
434*70a7ec85SAndroid Build Coastguard Worker }
435*70a7ec85SAndroid Build Coastguard Worker 
operator <<(std::ostream & os,KernelSepolicyVersion ksv)436*70a7ec85SAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &os, KernelSepolicyVersion ksv){
437*70a7ec85SAndroid Build Coastguard Worker     return os << ksv.value;
438*70a7ec85SAndroid Build Coastguard Worker }
439*70a7ec85SAndroid Build Coastguard Worker 
parse(const std::string & s,KernelSepolicyVersion * ksv)440*70a7ec85SAndroid Build Coastguard Worker bool parse(const std::string &s, KernelSepolicyVersion *ksv){
441*70a7ec85SAndroid Build Coastguard Worker     return ParseUint(s, &ksv->value);
442*70a7ec85SAndroid Build Coastguard Worker }
443*70a7ec85SAndroid Build Coastguard Worker 
dump(const HalManifest & vm)444*70a7ec85SAndroid Build Coastguard Worker std::string dump(const HalManifest &vm) {
445*70a7ec85SAndroid Build Coastguard Worker     std::ostringstream oss;
446*70a7ec85SAndroid Build Coastguard Worker     bool first = true;
447*70a7ec85SAndroid Build Coastguard Worker     for (const auto &hal : vm.getHals()) {
448*70a7ec85SAndroid Build Coastguard Worker         if (!first) {
449*70a7ec85SAndroid Build Coastguard Worker             oss << ":";
450*70a7ec85SAndroid Build Coastguard Worker         }
451*70a7ec85SAndroid Build Coastguard Worker         oss << hal;
452*70a7ec85SAndroid Build Coastguard Worker         first = false;
453*70a7ec85SAndroid Build Coastguard Worker     }
454*70a7ec85SAndroid Build Coastguard Worker     return oss.str();
455*70a7ec85SAndroid Build Coastguard Worker }
456*70a7ec85SAndroid Build Coastguard Worker 
dump(const RuntimeInfo & ki,bool verbose)457*70a7ec85SAndroid Build Coastguard Worker std::string dump(const RuntimeInfo& ki, bool verbose) {
458*70a7ec85SAndroid Build Coastguard Worker     std::ostringstream oss;
459*70a7ec85SAndroid Build Coastguard Worker 
460*70a7ec85SAndroid Build Coastguard Worker     oss << "kernel = " << ki.osName() << "/" << ki.nodeName() << "/" << ki.osRelease() << "/"
461*70a7ec85SAndroid Build Coastguard Worker         << ki.osVersion() << "/" << ki.hardwareId() << ";" << ki.mBootAvbVersion << "/"
462*70a7ec85SAndroid Build Coastguard Worker         << ki.mBootVbmetaAvbVersion << ";"
463*70a7ec85SAndroid Build Coastguard Worker         << "kernelSepolicyVersion = " << ki.kernelSepolicyVersion() << ";";
464*70a7ec85SAndroid Build Coastguard Worker 
465*70a7ec85SAndroid Build Coastguard Worker     if (verbose) {
466*70a7ec85SAndroid Build Coastguard Worker         oss << "\n\ncpu info:\n" << ki.cpuInfo();
467*70a7ec85SAndroid Build Coastguard Worker     }
468*70a7ec85SAndroid Build Coastguard Worker 
469*70a7ec85SAndroid Build Coastguard Worker     oss << "\n#CONFIG's loaded = " << ki.kernelConfigs().size() << ";\n";
470*70a7ec85SAndroid Build Coastguard Worker 
471*70a7ec85SAndroid Build Coastguard Worker     if (verbose) {
472*70a7ec85SAndroid Build Coastguard Worker         for (const auto& pair : ki.kernelConfigs()) {
473*70a7ec85SAndroid Build Coastguard Worker             oss << pair.first << "=" << pair.second << "\n";
474*70a7ec85SAndroid Build Coastguard Worker         }
475*70a7ec85SAndroid Build Coastguard Worker     }
476*70a7ec85SAndroid Build Coastguard Worker 
477*70a7ec85SAndroid Build Coastguard Worker     return oss.str();
478*70a7ec85SAndroid Build Coastguard Worker }
479*70a7ec85SAndroid Build Coastguard Worker 
toFQNameString(const std::string & package,const std::string & version,const std::string & interface,const std::string & instance)480*70a7ec85SAndroid Build Coastguard Worker std::string toFQNameString(const std::string& package, const std::string& version,
481*70a7ec85SAndroid Build Coastguard Worker                            const std::string& interface, const std::string& instance) {
482*70a7ec85SAndroid Build Coastguard Worker     std::stringstream ss;
483*70a7ec85SAndroid Build Coastguard Worker     ss << package << "@" << version;
484*70a7ec85SAndroid Build Coastguard Worker     if (!interface.empty()) {
485*70a7ec85SAndroid Build Coastguard Worker         ss << "::" << interface;
486*70a7ec85SAndroid Build Coastguard Worker     }
487*70a7ec85SAndroid Build Coastguard Worker     if (!instance.empty()) {
488*70a7ec85SAndroid Build Coastguard Worker         ss << "/" << instance;
489*70a7ec85SAndroid Build Coastguard Worker     }
490*70a7ec85SAndroid Build Coastguard Worker     return ss.str();
491*70a7ec85SAndroid Build Coastguard Worker }
492*70a7ec85SAndroid Build Coastguard Worker 
toFQNameString(const std::string & package,const Version & version,const std::string & interface,const std::string & instance)493*70a7ec85SAndroid Build Coastguard Worker std::string toFQNameString(const std::string& package, const Version& version,
494*70a7ec85SAndroid Build Coastguard Worker                            const std::string& interface, const std::string& instance) {
495*70a7ec85SAndroid Build Coastguard Worker     return toFQNameString(package, to_string(version), interface, instance);
496*70a7ec85SAndroid Build Coastguard Worker }
497*70a7ec85SAndroid Build Coastguard Worker 
toFQNameString(const Version & version,const std::string & interface,const std::string & instance)498*70a7ec85SAndroid Build Coastguard Worker std::string toFQNameString(const Version& version, const std::string& interface,
499*70a7ec85SAndroid Build Coastguard Worker                            const std::string& instance) {
500*70a7ec85SAndroid Build Coastguard Worker     return toFQNameString("", version, interface, instance);
501*70a7ec85SAndroid Build Coastguard Worker }
502*70a7ec85SAndroid Build Coastguard Worker 
503*70a7ec85SAndroid Build Coastguard Worker // [email protected]::IFoo/default.
504*70a7ec85SAndroid Build Coastguard Worker // Note that the format is extended to support a range of versions.
toFQNameString(const std::string & package,const VersionRange & range,const std::string & interface,const std::string & instance)505*70a7ec85SAndroid Build Coastguard Worker std::string toFQNameString(const std::string& package, const VersionRange& range,
506*70a7ec85SAndroid Build Coastguard Worker                            const std::string& interface, const std::string& instance) {
507*70a7ec85SAndroid Build Coastguard Worker     return toFQNameString(package, to_string(range), interface, instance);
508*70a7ec85SAndroid Build Coastguard Worker }
509*70a7ec85SAndroid Build Coastguard Worker 
toFQNameString(const VersionRange & range,const std::string & interface,const std::string & instance)510*70a7ec85SAndroid Build Coastguard Worker std::string toFQNameString(const VersionRange& range, const std::string& interface,
511*70a7ec85SAndroid Build Coastguard Worker                            const std::string& instance) {
512*70a7ec85SAndroid Build Coastguard Worker     return toFQNameString("", range, interface, instance);
513*70a7ec85SAndroid Build Coastguard Worker }
514*70a7ec85SAndroid Build Coastguard Worker 
toFQNameString(const std::string & interface,const std::string & instance)515*70a7ec85SAndroid Build Coastguard Worker std::string toFQNameString(const std::string& interface, const std::string& instance) {
516*70a7ec85SAndroid Build Coastguard Worker     return interface + "/" + instance;
517*70a7ec85SAndroid Build Coastguard Worker }
518*70a7ec85SAndroid Build Coastguard Worker 
operator <<(std::ostream & os,const FqInstance & fqInstance)519*70a7ec85SAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream& os, const FqInstance& fqInstance) {
520*70a7ec85SAndroid Build Coastguard Worker     return os << fqInstance.string();
521*70a7ec85SAndroid Build Coastguard Worker }
522*70a7ec85SAndroid Build Coastguard Worker 
parse(const std::string & s,FqInstance * fqInstance)523*70a7ec85SAndroid Build Coastguard Worker bool parse(const std::string& s, FqInstance* fqInstance) {
524*70a7ec85SAndroid Build Coastguard Worker     return fqInstance->setTo(s);
525*70a7ec85SAndroid Build Coastguard Worker }
526*70a7ec85SAndroid Build Coastguard Worker 
toAidlFqnameString(const std::string & package,const std::string & interface,const std::string & instance)527*70a7ec85SAndroid Build Coastguard Worker std::string toAidlFqnameString(const std::string& package, const std::string& interface,
528*70a7ec85SAndroid Build Coastguard Worker                                const std::string& instance) {
529*70a7ec85SAndroid Build Coastguard Worker     std::stringstream ss;
530*70a7ec85SAndroid Build Coastguard Worker     ss << package << "." << interface;
531*70a7ec85SAndroid Build Coastguard Worker     if (!instance.empty()) {
532*70a7ec85SAndroid Build Coastguard Worker         ss << "/" << instance;
533*70a7ec85SAndroid Build Coastguard Worker     }
534*70a7ec85SAndroid Build Coastguard Worker     return ss.str();
535*70a7ec85SAndroid Build Coastguard Worker }
536*70a7ec85SAndroid Build Coastguard Worker 
aidlVersionToString(const Version & v)537*70a7ec85SAndroid Build Coastguard Worker std::string aidlVersionToString(const Version& v) {
538*70a7ec85SAndroid Build Coastguard Worker     return to_string(v.minorVer);
539*70a7ec85SAndroid Build Coastguard Worker }
parseAidlVersion(const std::string & s,Version * version)540*70a7ec85SAndroid Build Coastguard Worker bool parseAidlVersion(const std::string& s, Version* version) {
541*70a7ec85SAndroid Build Coastguard Worker     version->majorVer = details::kFakeAidlMajorVersion;
542*70a7ec85SAndroid Build Coastguard Worker     return android::base::ParseUint(s, &version->minorVer);
543*70a7ec85SAndroid Build Coastguard Worker }
544*70a7ec85SAndroid Build Coastguard Worker 
aidlVersionRangeToString(const VersionRange & vr)545*70a7ec85SAndroid Build Coastguard Worker std::string aidlVersionRangeToString(const VersionRange& vr) {
546*70a7ec85SAndroid Build Coastguard Worker     if (vr.isSingleVersion()) {
547*70a7ec85SAndroid Build Coastguard Worker         return to_string(vr.minMinor);
548*70a7ec85SAndroid Build Coastguard Worker     }
549*70a7ec85SAndroid Build Coastguard Worker     return to_string(vr.minMinor) + "-" + to_string(vr.maxMinor);
550*70a7ec85SAndroid Build Coastguard Worker }
551*70a7ec85SAndroid Build Coastguard Worker 
parseAidlVersionRange(const std::string & s,VersionRange * vr)552*70a7ec85SAndroid Build Coastguard Worker bool parseAidlVersionRange(const std::string& s, VersionRange* vr) {
553*70a7ec85SAndroid Build Coastguard Worker     return parseVersionRange(s, vr, parseAidlVersion);
554*70a7ec85SAndroid Build Coastguard Worker }
555*70a7ec85SAndroid Build Coastguard Worker 
parseApexName(std::string_view path)556*70a7ec85SAndroid Build Coastguard Worker std::string_view parseApexName(std::string_view path) {
557*70a7ec85SAndroid Build Coastguard Worker     if (base::ConsumePrefix(&path, "/apex/")) {
558*70a7ec85SAndroid Build Coastguard Worker         return path.substr(0, path.find('/'));
559*70a7ec85SAndroid Build Coastguard Worker     }
560*70a7ec85SAndroid Build Coastguard Worker     return {};
561*70a7ec85SAndroid Build Coastguard Worker }
562*70a7ec85SAndroid Build Coastguard Worker 
563*70a7ec85SAndroid Build Coastguard Worker } // namespace vintf
564*70a7ec85SAndroid Build Coastguard Worker } // namespace android
565