xref: /aosp_15_r20/system/libvintf/FQName.cpp (revision 70a7ec852fcefd15a4fb57f8f183a8b1c3aacb08)
1*70a7ec85SAndroid Build Coastguard Worker /*
2*70a7ec85SAndroid Build Coastguard Worker  * Copyright (C) 2023 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 #include <vintf/FQName.h>
18*70a7ec85SAndroid Build Coastguard Worker 
19*70a7ec85SAndroid Build Coastguard Worker #include <android-base/logging.h>
20*70a7ec85SAndroid Build Coastguard Worker #include <android-base/parseint.h>
21*70a7ec85SAndroid Build Coastguard Worker #include <android-base/strings.h>
22*70a7ec85SAndroid Build Coastguard Worker #include <iostream>
23*70a7ec85SAndroid Build Coastguard Worker #include <sstream>
24*70a7ec85SAndroid Build Coastguard Worker 
25*70a7ec85SAndroid Build Coastguard Worker namespace android::vintf::details {
26*70a7ec85SAndroid Build Coastguard Worker 
FQName()27*70a7ec85SAndroid Build Coastguard Worker FQName::FQName() : mIsIdentifier(false) {}
28*70a7ec85SAndroid Build Coastguard Worker 
parse(const std::string & s,FQName * into)29*70a7ec85SAndroid Build Coastguard Worker bool FQName::parse(const std::string& s, FQName* into) {
30*70a7ec85SAndroid Build Coastguard Worker     return into->setTo(s);
31*70a7ec85SAndroid Build Coastguard Worker }
32*70a7ec85SAndroid Build Coastguard Worker 
FQName(const std::string & package,const std::string & version,const std::string & name)33*70a7ec85SAndroid Build Coastguard Worker FQName::FQName(const std::string& package, const std::string& version, const std::string& name) {
34*70a7ec85SAndroid Build Coastguard Worker     size_t majorVer, minorVer;
35*70a7ec85SAndroid Build Coastguard Worker     CHECK(parseVersion(version, &majorVer, &minorVer));
36*70a7ec85SAndroid Build Coastguard Worker     CHECK(setTo(package, majorVer, minorVer, name)) << string();
37*70a7ec85SAndroid Build Coastguard Worker }
38*70a7ec85SAndroid Build Coastguard Worker 
setTo(const std::string & package,size_t majorVer,size_t minorVer,const std::string & name)39*70a7ec85SAndroid Build Coastguard Worker bool FQName::setTo(const std::string& package, size_t majorVer, size_t minorVer,
40*70a7ec85SAndroid Build Coastguard Worker                    const std::string& name) {
41*70a7ec85SAndroid Build Coastguard Worker     mPackage = package;
42*70a7ec85SAndroid Build Coastguard Worker     mMajor = majorVer;
43*70a7ec85SAndroid Build Coastguard Worker     mMinor = minorVer;
44*70a7ec85SAndroid Build Coastguard Worker     mName = name;
45*70a7ec85SAndroid Build Coastguard Worker 
46*70a7ec85SAndroid Build Coastguard Worker     FQName other;
47*70a7ec85SAndroid Build Coastguard Worker     if (!parse(string(), &other)) return false;
48*70a7ec85SAndroid Build Coastguard Worker     if ((*this) != other) return false;
49*70a7ec85SAndroid Build Coastguard Worker     mIsIdentifier = other.isIdentifier();
50*70a7ec85SAndroid Build Coastguard Worker     return true;
51*70a7ec85SAndroid Build Coastguard Worker }
52*70a7ec85SAndroid Build Coastguard Worker 
isIdentifier() const53*70a7ec85SAndroid Build Coastguard Worker bool FQName::isIdentifier() const {
54*70a7ec85SAndroid Build Coastguard Worker     return mIsIdentifier;
55*70a7ec85SAndroid Build Coastguard Worker }
56*70a7ec85SAndroid Build Coastguard Worker 
isInterfaceName() const57*70a7ec85SAndroid Build Coastguard Worker bool FQName::isInterfaceName() const {
58*70a7ec85SAndroid Build Coastguard Worker     return !mName.empty() && mName[0] == 'I' && mName.find('.') == std::string::npos;
59*70a7ec85SAndroid Build Coastguard Worker }
60*70a7ec85SAndroid Build Coastguard Worker 
isIdentStart(char a)61*70a7ec85SAndroid Build Coastguard Worker static inline bool isIdentStart(char a) {
62*70a7ec85SAndroid Build Coastguard Worker     return ('a' <= a && a <= 'z') || ('A' <= a && a <= 'Z') || a == '_';
63*70a7ec85SAndroid Build Coastguard Worker }
isLeadingDigit(char a)64*70a7ec85SAndroid Build Coastguard Worker static inline bool isLeadingDigit(char a) {
65*70a7ec85SAndroid Build Coastguard Worker     return '1' <= a && a <= '9';
66*70a7ec85SAndroid Build Coastguard Worker }
isDigit(char a)67*70a7ec85SAndroid Build Coastguard Worker static inline bool isDigit(char a) {
68*70a7ec85SAndroid Build Coastguard Worker     return '0' <= a && a <= '9';
69*70a7ec85SAndroid Build Coastguard Worker }
isIdentBody(char a)70*70a7ec85SAndroid Build Coastguard Worker static inline bool isIdentBody(char a) {
71*70a7ec85SAndroid Build Coastguard Worker     return isIdentStart(a) || isDigit(a);
72*70a7ec85SAndroid Build Coastguard Worker }
73*70a7ec85SAndroid Build Coastguard Worker 
74*70a7ec85SAndroid Build Coastguard Worker // returns pointer to end of [a-zA-Z_][a-zA-Z0-9_]*
eatIdent(const char * l,const char * end)75*70a7ec85SAndroid Build Coastguard Worker static const char* eatIdent(const char* l, const char* end) {
76*70a7ec85SAndroid Build Coastguard Worker     if (!(l < end && isIdentStart(*l++))) return nullptr;
77*70a7ec85SAndroid Build Coastguard Worker     while (l < end && isIdentBody(*l)) l++;
78*70a7ec85SAndroid Build Coastguard Worker     return l;
79*70a7ec85SAndroid Build Coastguard Worker }
80*70a7ec85SAndroid Build Coastguard Worker 
81*70a7ec85SAndroid Build Coastguard Worker // returns pointer to end of <ident>(\.<ident>)*
eatPackage(const char * l,const char * end)82*70a7ec85SAndroid Build Coastguard Worker static const char* eatPackage(const char* l, const char* end) {
83*70a7ec85SAndroid Build Coastguard Worker     if ((l = eatIdent(l, end)) == nullptr) return nullptr;
84*70a7ec85SAndroid Build Coastguard Worker 
85*70a7ec85SAndroid Build Coastguard Worker     while (l < end && *l == '.') {
86*70a7ec85SAndroid Build Coastguard Worker         l++;
87*70a7ec85SAndroid Build Coastguard Worker         if ((l = eatIdent(l, end)) == nullptr) return nullptr;
88*70a7ec85SAndroid Build Coastguard Worker     }
89*70a7ec85SAndroid Build Coastguard Worker     return l;
90*70a7ec85SAndroid Build Coastguard Worker }
91*70a7ec85SAndroid Build Coastguard Worker 
92*70a7ec85SAndroid Build Coastguard Worker // returns pointer to end of [1-9][0-9]*|0
eatNumber(const char * l,const char * end)93*70a7ec85SAndroid Build Coastguard Worker static const char* eatNumber(const char* l, const char* end) {
94*70a7ec85SAndroid Build Coastguard Worker     if (!(l < end)) return nullptr;
95*70a7ec85SAndroid Build Coastguard Worker     if (*l == '0') return l + 1;
96*70a7ec85SAndroid Build Coastguard Worker     if (!isLeadingDigit(*l++)) return nullptr;
97*70a7ec85SAndroid Build Coastguard Worker     while (l < end && isDigit(*l)) l++;
98*70a7ec85SAndroid Build Coastguard Worker     return l;
99*70a7ec85SAndroid Build Coastguard Worker }
100*70a7ec85SAndroid Build Coastguard Worker 
setTo(const std::string & s)101*70a7ec85SAndroid Build Coastguard Worker bool FQName::setTo(const std::string& s) {
102*70a7ec85SAndroid Build Coastguard Worker     clear();
103*70a7ec85SAndroid Build Coastguard Worker 
104*70a7ec85SAndroid Build Coastguard Worker     if (s.empty()) return false;
105*70a7ec85SAndroid Build Coastguard Worker 
106*70a7ec85SAndroid Build Coastguard Worker     const char* l = s.c_str();
107*70a7ec85SAndroid Build Coastguard Worker     const char* end = l + s.size();
108*70a7ec85SAndroid Build Coastguard Worker     // [email protected]::IFoo.Type
109*70a7ec85SAndroid Build Coastguard Worker     // S                   ES ES E S        E
110*70a7ec85SAndroid Build Coastguard Worker     //
111*70a7ec85SAndroid Build Coastguard Worker     // S - start pointer
112*70a7ec85SAndroid Build Coastguard Worker     // E - end pointer
113*70a7ec85SAndroid Build Coastguard Worker 
114*70a7ec85SAndroid Build Coastguard Worker     struct StartEnd {
115*70a7ec85SAndroid Build Coastguard Worker         const char* start = nullptr;
116*70a7ec85SAndroid Build Coastguard Worker         const char* end = nullptr;
117*70a7ec85SAndroid Build Coastguard Worker 
118*70a7ec85SAndroid Build Coastguard Worker         std::string string() {
119*70a7ec85SAndroid Build Coastguard Worker             if (start == nullptr) return std::string();
120*70a7ec85SAndroid Build Coastguard Worker             return std::string(start, end - start);
121*70a7ec85SAndroid Build Coastguard Worker         }
122*70a7ec85SAndroid Build Coastguard Worker     };
123*70a7ec85SAndroid Build Coastguard Worker     StartEnd package, major, minor, name;
124*70a7ec85SAndroid Build Coastguard Worker 
125*70a7ec85SAndroid Build Coastguard Worker     if (l < end && isIdentStart(*l)) {
126*70a7ec85SAndroid Build Coastguard Worker         package.start = l;
127*70a7ec85SAndroid Build Coastguard Worker         if ((package.end = l = eatPackage(l, end)) == nullptr) return false;
128*70a7ec85SAndroid Build Coastguard Worker     }
129*70a7ec85SAndroid Build Coastguard Worker     if (l < end && *l == '@') {
130*70a7ec85SAndroid Build Coastguard Worker         l++;
131*70a7ec85SAndroid Build Coastguard Worker 
132*70a7ec85SAndroid Build Coastguard Worker         major.start = l;
133*70a7ec85SAndroid Build Coastguard Worker         if ((major.end = l = eatNumber(l, end)) == nullptr) return false;
134*70a7ec85SAndroid Build Coastguard Worker 
135*70a7ec85SAndroid Build Coastguard Worker         if (!(l < end && *l++ == '.')) return false;
136*70a7ec85SAndroid Build Coastguard Worker 
137*70a7ec85SAndroid Build Coastguard Worker         minor.start = l;
138*70a7ec85SAndroid Build Coastguard Worker         if ((minor.end = l = eatNumber(l, end)) == nullptr) return false;
139*70a7ec85SAndroid Build Coastguard Worker     }
140*70a7ec85SAndroid Build Coastguard Worker     if (l < end && *l == ':') {
141*70a7ec85SAndroid Build Coastguard Worker         l++;
142*70a7ec85SAndroid Build Coastguard Worker         if (l < end && *l == ':') {
143*70a7ec85SAndroid Build Coastguard Worker             l++;
144*70a7ec85SAndroid Build Coastguard Worker             name.start = l;
145*70a7ec85SAndroid Build Coastguard Worker             if ((name.end = l = eatPackage(l, end)) == nullptr) return false;
146*70a7ec85SAndroid Build Coastguard Worker         } else {
147*70a7ec85SAndroid Build Coastguard Worker             return false;
148*70a7ec85SAndroid Build Coastguard Worker         }
149*70a7ec85SAndroid Build Coastguard Worker     }
150*70a7ec85SAndroid Build Coastguard Worker 
151*70a7ec85SAndroid Build Coastguard Worker     if (l < end) return false;
152*70a7ec85SAndroid Build Coastguard Worker 
153*70a7ec85SAndroid Build Coastguard Worker     CHECK((major.start == nullptr) == (minor.start == nullptr));
154*70a7ec85SAndroid Build Coastguard Worker 
155*70a7ec85SAndroid Build Coastguard Worker     // if we only parse a package, consider this to be a name
156*70a7ec85SAndroid Build Coastguard Worker     if (name.start == nullptr && major.start == nullptr) {
157*70a7ec85SAndroid Build Coastguard Worker         name.start = package.start;
158*70a7ec85SAndroid Build Coastguard Worker         name.end = package.end;
159*70a7ec85SAndroid Build Coastguard Worker         package.start = package.end = nullptr;
160*70a7ec85SAndroid Build Coastguard Worker     }
161*70a7ec85SAndroid Build Coastguard Worker 
162*70a7ec85SAndroid Build Coastguard Worker     // failures after this goto fail to clear
163*70a7ec85SAndroid Build Coastguard Worker     mName = name.string();
164*70a7ec85SAndroid Build Coastguard Worker     mPackage = package.string();
165*70a7ec85SAndroid Build Coastguard Worker 
166*70a7ec85SAndroid Build Coastguard Worker     if (major.start != nullptr) {
167*70a7ec85SAndroid Build Coastguard Worker         if (!parseVersion(major.string(), minor.string(), &mMajor, &mMinor)) goto fail;
168*70a7ec85SAndroid Build Coastguard Worker     } else if (mPackage.empty() && name.end == eatIdent(name.start, name.end)) {
169*70a7ec85SAndroid Build Coastguard Worker         // major.start == nullptr
170*70a7ec85SAndroid Build Coastguard Worker         mIsIdentifier = true;
171*70a7ec85SAndroid Build Coastguard Worker     }
172*70a7ec85SAndroid Build Coastguard Worker 
173*70a7ec85SAndroid Build Coastguard Worker     if (!mPackage.empty() && version().empty()) goto fail;
174*70a7ec85SAndroid Build Coastguard Worker 
175*70a7ec85SAndroid Build Coastguard Worker     return true;
176*70a7ec85SAndroid Build Coastguard Worker fail:
177*70a7ec85SAndroid Build Coastguard Worker     clear();
178*70a7ec85SAndroid Build Coastguard Worker     return false;
179*70a7ec85SAndroid Build Coastguard Worker }
180*70a7ec85SAndroid Build Coastguard Worker 
package() const181*70a7ec85SAndroid Build Coastguard Worker const std::string& FQName::package() const {
182*70a7ec85SAndroid Build Coastguard Worker     return mPackage;
183*70a7ec85SAndroid Build Coastguard Worker }
184*70a7ec85SAndroid Build Coastguard Worker 
version() const185*70a7ec85SAndroid Build Coastguard Worker std::string FQName::version() const {
186*70a7ec85SAndroid Build Coastguard Worker     if (!hasVersion()) {
187*70a7ec85SAndroid Build Coastguard Worker         return "";
188*70a7ec85SAndroid Build Coastguard Worker     }
189*70a7ec85SAndroid Build Coastguard Worker     return std::to_string(mMajor) + "." + std::to_string(mMinor);
190*70a7ec85SAndroid Build Coastguard Worker }
191*70a7ec85SAndroid Build Coastguard Worker 
atVersion() const192*70a7ec85SAndroid Build Coastguard Worker std::string FQName::atVersion() const {
193*70a7ec85SAndroid Build Coastguard Worker     std::string v = version();
194*70a7ec85SAndroid Build Coastguard Worker     return v.empty() ? "" : ("@" + v);
195*70a7ec85SAndroid Build Coastguard Worker }
196*70a7ec85SAndroid Build Coastguard Worker 
clear()197*70a7ec85SAndroid Build Coastguard Worker void FQName::clear() {
198*70a7ec85SAndroid Build Coastguard Worker     mIsIdentifier = false;
199*70a7ec85SAndroid Build Coastguard Worker     mPackage.clear();
200*70a7ec85SAndroid Build Coastguard Worker     clearVersion();
201*70a7ec85SAndroid Build Coastguard Worker     mName.clear();
202*70a7ec85SAndroid Build Coastguard Worker }
203*70a7ec85SAndroid Build Coastguard Worker 
clearVersion(size_t * majorVer,size_t * minorVer)204*70a7ec85SAndroid Build Coastguard Worker void FQName::clearVersion(size_t* majorVer, size_t* minorVer) {
205*70a7ec85SAndroid Build Coastguard Worker     *majorVer = *minorVer = 0;
206*70a7ec85SAndroid Build Coastguard Worker }
207*70a7ec85SAndroid Build Coastguard Worker 
parseVersion(const std::string & majorStr,const std::string & minorStr,size_t * majorVer,size_t * minorVer)208*70a7ec85SAndroid Build Coastguard Worker bool FQName::parseVersion(const std::string& majorStr, const std::string& minorStr,
209*70a7ec85SAndroid Build Coastguard Worker                           size_t* majorVer, size_t* minorVer) {
210*70a7ec85SAndroid Build Coastguard Worker     bool versionParseSuccess = ::android::base::ParseUint(majorStr, majorVer) &&
211*70a7ec85SAndroid Build Coastguard Worker                                ::android::base::ParseUint(minorStr, minorVer);
212*70a7ec85SAndroid Build Coastguard Worker     if (!versionParseSuccess) {
213*70a7ec85SAndroid Build Coastguard Worker         LOG(ERROR) << "numbers in " << majorStr << "." << minorStr << " are out of range.";
214*70a7ec85SAndroid Build Coastguard Worker     }
215*70a7ec85SAndroid Build Coastguard Worker     return versionParseSuccess;
216*70a7ec85SAndroid Build Coastguard Worker }
217*70a7ec85SAndroid Build Coastguard Worker 
parseVersion(const std::string & v,size_t * majorVer,size_t * minorVer)218*70a7ec85SAndroid Build Coastguard Worker bool FQName::parseVersion(const std::string& v, size_t* majorVer, size_t* minorVer) {
219*70a7ec85SAndroid Build Coastguard Worker     if (v.empty()) {
220*70a7ec85SAndroid Build Coastguard Worker         clearVersion(majorVer, minorVer);
221*70a7ec85SAndroid Build Coastguard Worker         return true;
222*70a7ec85SAndroid Build Coastguard Worker     }
223*70a7ec85SAndroid Build Coastguard Worker 
224*70a7ec85SAndroid Build Coastguard Worker     std::vector<std::string> vs = base::Split(v, ".");
225*70a7ec85SAndroid Build Coastguard Worker     if (vs.size() != 2) return false;
226*70a7ec85SAndroid Build Coastguard Worker     return parseVersion(vs[0], vs[1], majorVer, minorVer);
227*70a7ec85SAndroid Build Coastguard Worker }
228*70a7ec85SAndroid Build Coastguard Worker 
setVersion(const std::string & v)229*70a7ec85SAndroid Build Coastguard Worker bool FQName::setVersion(const std::string& v) {
230*70a7ec85SAndroid Build Coastguard Worker     return parseVersion(v, &mMajor, &mMinor);
231*70a7ec85SAndroid Build Coastguard Worker }
232*70a7ec85SAndroid Build Coastguard Worker 
clearVersion()233*70a7ec85SAndroid Build Coastguard Worker void FQName::clearVersion() {
234*70a7ec85SAndroid Build Coastguard Worker     clearVersion(&mMajor, &mMinor);
235*70a7ec85SAndroid Build Coastguard Worker }
236*70a7ec85SAndroid Build Coastguard Worker 
parseVersion(const std::string & majorStr,const std::string & minorStr)237*70a7ec85SAndroid Build Coastguard Worker bool FQName::parseVersion(const std::string& majorStr, const std::string& minorStr) {
238*70a7ec85SAndroid Build Coastguard Worker     return parseVersion(majorStr, minorStr, &mMajor, &mMinor);
239*70a7ec85SAndroid Build Coastguard Worker }
240*70a7ec85SAndroid Build Coastguard Worker 
name() const241*70a7ec85SAndroid Build Coastguard Worker const std::string& FQName::name() const {
242*70a7ec85SAndroid Build Coastguard Worker     return mName;
243*70a7ec85SAndroid Build Coastguard Worker }
244*70a7ec85SAndroid Build Coastguard Worker 
string() const245*70a7ec85SAndroid Build Coastguard Worker std::string FQName::string() const {
246*70a7ec85SAndroid Build Coastguard Worker     std::string out;
247*70a7ec85SAndroid Build Coastguard Worker     out.append(mPackage);
248*70a7ec85SAndroid Build Coastguard Worker     out.append(atVersion());
249*70a7ec85SAndroid Build Coastguard Worker     if (!mName.empty()) {
250*70a7ec85SAndroid Build Coastguard Worker         if (!mPackage.empty() || !version().empty()) {
251*70a7ec85SAndroid Build Coastguard Worker             out.append("::");
252*70a7ec85SAndroid Build Coastguard Worker         }
253*70a7ec85SAndroid Build Coastguard Worker         out.append(mName);
254*70a7ec85SAndroid Build Coastguard Worker     }
255*70a7ec85SAndroid Build Coastguard Worker 
256*70a7ec85SAndroid Build Coastguard Worker     return out;
257*70a7ec85SAndroid Build Coastguard Worker }
258*70a7ec85SAndroid Build Coastguard Worker 
operator <(const FQName & other) const259*70a7ec85SAndroid Build Coastguard Worker bool FQName::operator<(const FQName& other) const {
260*70a7ec85SAndroid Build Coastguard Worker     return string() < other.string();
261*70a7ec85SAndroid Build Coastguard Worker }
262*70a7ec85SAndroid Build Coastguard Worker 
operator ==(const FQName & other) const263*70a7ec85SAndroid Build Coastguard Worker bool FQName::operator==(const FQName& other) const {
264*70a7ec85SAndroid Build Coastguard Worker     return string() == other.string();
265*70a7ec85SAndroid Build Coastguard Worker }
266*70a7ec85SAndroid Build Coastguard Worker 
operator !=(const FQName & other) const267*70a7ec85SAndroid Build Coastguard Worker bool FQName::operator!=(const FQName& other) const {
268*70a7ec85SAndroid Build Coastguard Worker     return !(*this == other);
269*70a7ec85SAndroid Build Coastguard Worker }
270*70a7ec85SAndroid Build Coastguard Worker 
getInterfaceName() const271*70a7ec85SAndroid Build Coastguard Worker const std::string& FQName::getInterfaceName() const {
272*70a7ec85SAndroid Build Coastguard Worker     CHECK(isInterfaceName()) << mName;
273*70a7ec85SAndroid Build Coastguard Worker 
274*70a7ec85SAndroid Build Coastguard Worker     return mName;
275*70a7ec85SAndroid Build Coastguard Worker }
276*70a7ec85SAndroid Build Coastguard Worker 
getPackageAndVersion() const277*70a7ec85SAndroid Build Coastguard Worker FQName FQName::getPackageAndVersion() const {
278*70a7ec85SAndroid Build Coastguard Worker     return FQName(package(), version(), "");
279*70a7ec85SAndroid Build Coastguard Worker }
280*70a7ec85SAndroid Build Coastguard Worker 
getPackageComponents() const281*70a7ec85SAndroid Build Coastguard Worker std::vector<std::string> FQName::getPackageComponents() const {
282*70a7ec85SAndroid Build Coastguard Worker     return base::Split(package(), ".");
283*70a7ec85SAndroid Build Coastguard Worker }
284*70a7ec85SAndroid Build Coastguard Worker 
hasVersion() const285*70a7ec85SAndroid Build Coastguard Worker bool FQName::hasVersion() const {
286*70a7ec85SAndroid Build Coastguard Worker     return mMajor > 0;
287*70a7ec85SAndroid Build Coastguard Worker }
288*70a7ec85SAndroid Build Coastguard Worker 
getVersion() const289*70a7ec85SAndroid Build Coastguard Worker std::pair<size_t, size_t> FQName::getVersion() const {
290*70a7ec85SAndroid Build Coastguard Worker     return {mMajor, mMinor};
291*70a7ec85SAndroid Build Coastguard Worker }
292*70a7ec85SAndroid Build Coastguard Worker 
getPackageMajorVersion() const293*70a7ec85SAndroid Build Coastguard Worker size_t FQName::getPackageMajorVersion() const {
294*70a7ec85SAndroid Build Coastguard Worker     CHECK(hasVersion()) << "FQName: No version exists at getPackageMajorVersion(). "
295*70a7ec85SAndroid Build Coastguard Worker                         << "Did you check hasVersion()?";
296*70a7ec85SAndroid Build Coastguard Worker     return mMajor;
297*70a7ec85SAndroid Build Coastguard Worker }
298*70a7ec85SAndroid Build Coastguard Worker 
getPackageMinorVersion() const299*70a7ec85SAndroid Build Coastguard Worker size_t FQName::getPackageMinorVersion() const {
300*70a7ec85SAndroid Build Coastguard Worker     CHECK(hasVersion()) << "FQName: No version exists at getPackageMinorVersion(). "
301*70a7ec85SAndroid Build Coastguard Worker                         << "Did you check hasVersion()?";
302*70a7ec85SAndroid Build Coastguard Worker     return mMinor;
303*70a7ec85SAndroid Build Coastguard Worker }
304*70a7ec85SAndroid Build Coastguard Worker 
inPackage(const std::string & package) const305*70a7ec85SAndroid Build Coastguard Worker bool FQName::inPackage(const std::string& package) const {
306*70a7ec85SAndroid Build Coastguard Worker     std::vector<std::string> components = getPackageComponents();
307*70a7ec85SAndroid Build Coastguard Worker     std::vector<std::string> inComponents = base::Split(package, ".");
308*70a7ec85SAndroid Build Coastguard Worker 
309*70a7ec85SAndroid Build Coastguard Worker     if (inComponents.size() > components.size()) {
310*70a7ec85SAndroid Build Coastguard Worker         return false;
311*70a7ec85SAndroid Build Coastguard Worker     }
312*70a7ec85SAndroid Build Coastguard Worker 
313*70a7ec85SAndroid Build Coastguard Worker     for (size_t i = 0; i < inComponents.size(); i++) {
314*70a7ec85SAndroid Build Coastguard Worker         if (inComponents[i] != components[i]) {
315*70a7ec85SAndroid Build Coastguard Worker             return false;
316*70a7ec85SAndroid Build Coastguard Worker         }
317*70a7ec85SAndroid Build Coastguard Worker     }
318*70a7ec85SAndroid Build Coastguard Worker 
319*70a7ec85SAndroid Build Coastguard Worker     return true;
320*70a7ec85SAndroid Build Coastguard Worker }
321*70a7ec85SAndroid Build Coastguard Worker 
322*70a7ec85SAndroid Build Coastguard Worker }  // namespace android::vintf::details
323