blob: dd29f48672b88609593d7b6845d6cc598d4ee2c6 [file] [log] [blame]
Andreas Huber1aec3972016-08-26 09:26:32 -07001/*
2 * Copyright (C) 2016 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
Andreas Huber84f89de2016-07-28 15:39:51 -070017#include "FQName.h"
18
Steven Moreland7ae3d542017-01-18 16:46:01 -080019#include "StringHelper.h"
20
Andreas Huber84f89de2016-07-28 15:39:51 -070021#include <android-base/logging.h>
Yifan Hong1faabf12017-02-02 14:15:21 -080022#include <android-base/parseint.h>
Iliyan Malchev800273d2016-09-02 15:25:07 -070023#include <iostream>
Andreas Huber84f89de2016-07-28 15:39:51 -070024#include <regex>
Iliyan Malchev800273d2016-09-02 15:25:07 -070025#include <sstream>
Andreas Huber84f89de2016-07-28 15:39:51 -070026
27#define RE_COMPONENT "[a-zA-Z_][a-zA-Z_0-9]*"
Yifan Hong95a47bb2016-09-29 10:08:10 -070028#define RE_PATH RE_COMPONENT "(?:[.]" RE_COMPONENT ")*"
Yifan Hong90ea87f2016-11-01 14:25:47 -070029#define RE_MAJOR "[0-9]+"
30#define RE_MINOR "[0-9]+"
Andreas Huber84f89de2016-07-28 15:39:51 -070031
Yifan Hong333a6d22017-01-12 12:28:02 -080032// android.hardware.foo@1.0::IFoo.Type
33static const std::regex kRE1("(" RE_PATH ")@(" RE_MAJOR ")[.](" RE_MINOR ")::(" RE_PATH ")");
34// @1.0::IFoo.Type
Yifan Hong90ea87f2016-11-01 14:25:47 -070035static const std::regex kRE2("@(" RE_MAJOR ")[.](" RE_MINOR ")::(" RE_PATH ")");
Yifan Hong333a6d22017-01-12 12:28:02 -080036// android.hardware.foo@1.0 (for package declaration and whole package import)
Yifan Hong90ea87f2016-11-01 14:25:47 -070037static const std::regex kRE3("(" RE_PATH ")@(" RE_MAJOR ")[.](" RE_MINOR ")");
Yifan Hong333a6d22017-01-12 12:28:02 -080038// IFoo.Type
Yifan Hongb44a6c82016-09-22 15:50:18 -070039static const std::regex kRE4("(" RE_COMPONENT ")([.]" RE_COMPONENT ")+");
Yifan Hong333a6d22017-01-12 12:28:02 -080040// Type (a plain identifier)
Yifan Hongb44a6c82016-09-22 15:50:18 -070041static const std::regex kRE5("(" RE_COMPONENT ")");
42
Yifan Hong333a6d22017-01-12 12:28:02 -080043// android.hardware.foo@1.0::IFoo.Type:MY_ENUM_VALUE
44static const std::regex kRE6("(" RE_PATH ")@(" RE_MAJOR ")[.](" RE_MINOR ")::(" RE_PATH "):(" RE_COMPONENT ")");
45// @1.0::IFoo.Type:MY_ENUM_VALUE
Yifan Hong90ea87f2016-11-01 14:25:47 -070046static const std::regex kRE7("@(" RE_MAJOR ")[.](" RE_MINOR ")::(" RE_PATH "):(" RE_COMPONENT ")");
Yifan Hong333a6d22017-01-12 12:28:02 -080047// IFoo.Type:MY_ENUM_VALUE
Yifan Hongb44a6c82016-09-22 15:50:18 -070048static const std::regex kRE8("(" RE_PATH "):(" RE_COMPONENT ")");
Andreas Huber84f89de2016-07-28 15:39:51 -070049
Yifan Hong333a6d22017-01-12 12:28:02 -080050// 1.0
Yifan Hong90ea87f2016-11-01 14:25:47 -070051static const std::regex kREVer("(" RE_MAJOR ")[.](" RE_MINOR ")");
52
Andreas Huber84f89de2016-07-28 15:39:51 -070053namespace android {
54
Andreas Huberda51b8e2016-07-28 16:00:57 -070055FQName::FQName()
Yifan Hong327cfe12016-10-03 10:29:42 -070056 : mValid(false),
57 mIsIdentifier(false) {
Andreas Huberda51b8e2016-07-28 16:00:57 -070058}
59
Andreas Huber84f89de2016-07-28 15:39:51 -070060FQName::FQName(const std::string &s)
Yifan Hong327cfe12016-10-03 10:29:42 -070061 : mValid(false),
62 mIsIdentifier(false) {
Andreas Huber84f89de2016-07-28 15:39:51 -070063 setTo(s);
64}
65
Andreas Huber68f24592016-07-29 14:53:48 -070066FQName::FQName(
67 const std::string &package,
68 const std::string &version,
Yifan Hongb44a6c82016-09-22 15:50:18 -070069 const std::string &name,
70 const std::string &valueName)
Andreas Huber68f24592016-07-29 14:53:48 -070071 : mValid(true),
Yifan Hongb44a6c82016-09-22 15:50:18 -070072 mIsIdentifier(false),
Andreas Huber68f24592016-07-29 14:53:48 -070073 mPackage(package),
Yifan Hongb44a6c82016-09-22 15:50:18 -070074 mName(name),
75 mValueName(valueName) {
Yifan Hong90ea87f2016-11-01 14:25:47 -070076 setVersion(version);
Yifan Hongfece6ec2017-01-12 17:04:04 -080077
78 // Check if this is actually a valid fqName
79 FQName other;
80 other.setTo(this->string());
81 CHECK(other.mValid && (*this) == other);
Andreas Huber68f24592016-07-29 14:53:48 -070082}
83
Yifan Hongf24fa852016-09-23 11:03:15 -070084FQName::FQName(const FQName& other)
85 : mValid(other.mValid),
86 mIsIdentifier(other.mIsIdentifier),
87 mPackage(other.mPackage),
Yifan Hong90ea87f2016-11-01 14:25:47 -070088 mMajor(other.mMajor),
89 mMinor(other.mMinor),
Yifan Hongf24fa852016-09-23 11:03:15 -070090 mName(other.mName),
91 mValueName(other.mValueName) {
92}
93
Yifan Hong327cfe12016-10-03 10:29:42 -070094FQName::FQName(const std::vector<std::string> &names)
95 : mValid(false),
96 mIsIdentifier(false) {
97 setTo(StringHelper::JoinStrings(names, "."));
98}
99
Andreas Huber84f89de2016-07-28 15:39:51 -0700100bool FQName::isValid() const {
101 return mValid;
102}
103
Yifan Hongb44a6c82016-09-22 15:50:18 -0700104bool FQName::isIdentifier() const {
105 return mIsIdentifier;
106}
107
Andreas Huber68f24592016-07-29 14:53:48 -0700108bool FQName::isFullyQualified() const {
Yifan Hong90ea87f2016-11-01 14:25:47 -0700109 return !mPackage.empty() && !version().empty() && !mName.empty();
Andreas Huber68f24592016-07-29 14:53:48 -0700110}
111
Yifan Hongb44a6c82016-09-22 15:50:18 -0700112bool FQName::isValidValueName() const {
113 return mIsIdentifier
114 || (!mName.empty() && !mValueName.empty());
115}
116
Andreas Huber84f89de2016-07-28 15:39:51 -0700117bool FQName::setTo(const std::string &s) {
Yifan Hong1faabf12017-02-02 14:15:21 -0800118 clearVersion();
Andreas Huber84f89de2016-07-28 15:39:51 -0700119 mPackage.clear();
Andreas Huber84f89de2016-07-28 15:39:51 -0700120 mName.clear();
121
122 mValid = true;
123
124 std::smatch match;
125 if (std::regex_match(s, match, kRE1)) {
Yifan Hong90ea87f2016-11-01 14:25:47 -0700126 CHECK_EQ(match.size(), 5u);
127
128 mPackage = match.str(1);
Yifan Hong1faabf12017-02-02 14:15:21 -0800129 parseVersion(match.str(2), match.str(3));
Yifan Hong90ea87f2016-11-01 14:25:47 -0700130 mName = match.str(4);
131 } else if (std::regex_match(s, match, kRE2)) {
132 CHECK_EQ(match.size(), 4u);
133
Yifan Hong1faabf12017-02-02 14:15:21 -0800134 parseVersion(match.str(1), match.str(2));
Yifan Hong90ea87f2016-11-01 14:25:47 -0700135 mName = match.str(3);
136 } else if (std::regex_match(s, match, kRE3)) {
Yifan Hong95a47bb2016-09-29 10:08:10 -0700137 CHECK_EQ(match.size(), 4u);
Andreas Huber84f89de2016-07-28 15:39:51 -0700138
139 mPackage = match.str(1);
Yifan Hong1faabf12017-02-02 14:15:21 -0800140 parseVersion(match.str(2), match.str(3));
Andreas Huberda51b8e2016-07-28 16:00:57 -0700141 } else if (std::regex_match(s, match, kRE4)) {
Andreas Huber84f89de2016-07-28 15:39:51 -0700142 mName = match.str(0);
Yifan Hongb44a6c82016-09-22 15:50:18 -0700143 } else if (std::regex_match(s, match, kRE5)) {
144 mIsIdentifier = true;
145 mName = match.str(0);
146 } else if (std::regex_match(s, match, kRE6)) {
Yifan Hong90ea87f2016-11-01 14:25:47 -0700147 CHECK_EQ(match.size(), 6u);
Yifan Hongb44a6c82016-09-22 15:50:18 -0700148
149 mPackage = match.str(1);
Yifan Hong1faabf12017-02-02 14:15:21 -0800150 parseVersion(match.str(2), match.str(3));
Yifan Hong90ea87f2016-11-01 14:25:47 -0700151 mName = match.str(4);
152 mValueName = match.str(5);
153 } else if (std::regex_match(s, match, kRE7)) {
154 CHECK_EQ(match.size(), 5u);
155
Yifan Hong1faabf12017-02-02 14:15:21 -0800156 parseVersion(match.str(1), match.str(2));
Yifan Hong95a47bb2016-09-29 10:08:10 -0700157 mName = match.str(3);
158 mValueName = match.str(4);
Yifan Hongb44a6c82016-09-22 15:50:18 -0700159 } else if (std::regex_match(s, match, kRE8)) {
Yifan Hong95a47bb2016-09-29 10:08:10 -0700160 CHECK_EQ(match.size(), 3u);
Yifan Hongb44a6c82016-09-22 15:50:18 -0700161
162 mName = match.str(1);
Yifan Hong95a47bb2016-09-29 10:08:10 -0700163 mValueName = match.str(2);
Andreas Huber84f89de2016-07-28 15:39:51 -0700164 } else {
165 mValid = false;
166 }
167
Yifan Hongb44a6c82016-09-22 15:50:18 -0700168 // mValueName must go with mName.
Yifan Hong333a6d22017-01-12 12:28:02 -0800169 CHECK(mValueName.empty() || !mName.empty());
170
171 // package without version is not allowed.
172 CHECK(mPackage.empty() || !version().empty());
Yifan Hongb44a6c82016-09-22 15:50:18 -0700173
Andreas Huber84f89de2016-07-28 15:39:51 -0700174 return isValid();
175}
176
177std::string FQName::package() const {
178 return mPackage;
179}
180
181std::string FQName::version() const {
Yifan Hong1faabf12017-02-02 14:15:21 -0800182 if (!hasVersion()) {
Yifan Hong90ea87f2016-11-01 14:25:47 -0700183 return "";
184 }
Yifan Hong1faabf12017-02-02 14:15:21 -0800185 return std::to_string(mMajor) + "." + std::to_string(mMinor);
Yifan Hong90ea87f2016-11-01 14:25:47 -0700186}
187
Yifan Hong97288ac2016-12-12 16:03:51 -0800188std::string FQName::sanitizedVersion() const {
Yifan Hong1faabf12017-02-02 14:15:21 -0800189 if (!hasVersion()) {
Yifan Hong97288ac2016-12-12 16:03:51 -0800190 return "";
191 }
Yifan Hong1faabf12017-02-02 14:15:21 -0800192 return "V" + std::to_string(mMajor) + "_" + std::to_string(mMinor);
Yifan Hong97288ac2016-12-12 16:03:51 -0800193}
194
Yifan Hong90ea87f2016-11-01 14:25:47 -0700195std::string FQName::atVersion() const {
196 std::string v = version();
197 return v.empty() ? "" : ("@" + v);
198}
199
200void FQName::setVersion(const std::string &v) {
201 if (v.empty()) {
Yifan Hong1faabf12017-02-02 14:15:21 -0800202 clearVersion();
Yifan Hong90ea87f2016-11-01 14:25:47 -0700203 return;
204 }
205 std::smatch match;
206 if (std::regex_match(v, match, kREVer)) {
207 CHECK_EQ(match.size(), 3u);
208
Yifan Hong1faabf12017-02-02 14:15:21 -0800209 parseVersion(match.str(1), match.str(2));
Yifan Hong90ea87f2016-11-01 14:25:47 -0700210 } else {
211 mValid = false;
212 }
Andreas Huber84f89de2016-07-28 15:39:51 -0700213}
214
Yifan Hong1faabf12017-02-02 14:15:21 -0800215void FQName::clearVersion() {
216 mMajor = mMinor = 0;
217}
218
219void FQName::parseVersion(const std::string &majorStr, const std::string &minorStr) {
220 bool versionParseSuccess =
221 ::android::base::ParseUint(majorStr, &mMajor) &&
222 ::android::base::ParseUint(minorStr, &mMinor);
223 if (!versionParseSuccess) {
224 LOG(ERROR) << "numbers in " << majorStr << "." << minorStr << " are out of range.";
225 mValid = false;
226 }
227}
228
Andreas Huber84f89de2016-07-28 15:39:51 -0700229std::string FQName::name() const {
230 return mName;
231}
232
Iliyan Malchev800273d2016-09-02 15:25:07 -0700233std::vector<std::string> FQName::names() const {
234 std::vector<std::string> res {};
235 std::istringstream ss(name());
236 std::string s;
237 while (std::getline(ss, s, '.')) {
238 res.push_back(s);
239 }
240 return res;
241}
242
Yifan Hongb44a6c82016-09-22 15:50:18 -0700243std::string FQName::valueName() const {
244 return mValueName;
245}
246
247FQName FQName::typeName() const {
Yifan Hong90ea87f2016-11-01 14:25:47 -0700248 return FQName(mPackage, version(), mName);
Yifan Hongb44a6c82016-09-22 15:50:18 -0700249}
250
Andreas Huber84f89de2016-07-28 15:39:51 -0700251void FQName::applyDefaults(
252 const std::string &defaultPackage,
253 const std::string &defaultVersion) {
Yifan Hong333a6d22017-01-12 12:28:02 -0800254
255 // package without version is not allowed.
256 CHECK(mPackage.empty() || !version().empty());
257
Andreas Huber84f89de2016-07-28 15:39:51 -0700258 if (mPackage.empty()) {
259 mPackage = defaultPackage;
260 }
261
Yifan Hong90ea87f2016-11-01 14:25:47 -0700262 if (version().empty()) {
263 setVersion(defaultVersion);
Andreas Huber84f89de2016-07-28 15:39:51 -0700264 }
265}
266
Andreas Huber68f24592016-07-29 14:53:48 -0700267std::string FQName::string() const {
Andreas Huber84f89de2016-07-28 15:39:51 -0700268 CHECK(mValid);
269
Andreas Huber5345ec22016-07-29 13:33:27 -0700270 std::string out;
Andreas Huber84f89de2016-07-28 15:39:51 -0700271 out.append(mPackage);
Yifan Hong90ea87f2016-11-01 14:25:47 -0700272 out.append(atVersion());
Andreas Huberda51b8e2016-07-28 16:00:57 -0700273 if (!mName.empty()) {
Yifan Hong90ea87f2016-11-01 14:25:47 -0700274 if (!mPackage.empty() || !version().empty()) {
Andreas Huberda51b8e2016-07-28 16:00:57 -0700275 out.append("::");
276 }
277 out.append(mName);
Yifan Hongb44a6c82016-09-22 15:50:18 -0700278
279 if (!mValueName.empty()) {
280 out.append(":");
281 out.append(mValueName);
282 }
Andreas Huber84f89de2016-07-28 15:39:51 -0700283 }
Andreas Huber84f89de2016-07-28 15:39:51 -0700284
285 return out;
286}
287
Andreas Huberda51b8e2016-07-28 16:00:57 -0700288void FQName::print() const {
289 if (!mValid) {
290 LOG(INFO) << "INVALID";
291 return;
292 }
293
Andreas Huber68f24592016-07-29 14:53:48 -0700294 LOG(INFO) << string();
295}
296
297bool FQName::operator<(const FQName &other) const {
298 return string() < other.string();
Andreas Huberda51b8e2016-07-28 16:00:57 -0700299}
300
Andreas Huberd2943e12016-08-05 11:59:31 -0700301bool FQName::operator==(const FQName &other) const {
302 return string() == other.string();
303}
304
Yifan Hongc8934042016-11-17 17:10:52 -0800305bool FQName::operator!=(const FQName &other) const {
306 return !(*this == other);
307}
308
Yifan Hongeefe4f22017-01-04 15:32:42 -0800309std::string FQName::getInterfaceName() const {
Steven Moreland197d56c2016-09-09 10:03:58 -0700310 CHECK(names().size() == 1) << "Must be a top level type";
311 CHECK(!mName.empty() && mName[0] == 'I') << mName;
312
Yifan Hongeefe4f22017-01-04 15:32:42 -0800313 return mName;
314}
315
316std::string FQName::getInterfaceBaseName() const {
Steven Moreland197d56c2016-09-09 10:03:58 -0700317 // cut off the leading 'I'.
Yifan Hongeefe4f22017-01-04 15:32:42 -0800318 return getInterfaceName().substr(1);
319}
320
321std::string FQName::getInterfaceHwName() const {
322 return "IHw" + getInterfaceBaseName();
323}
324
325std::string FQName::getInterfaceProxyName() const {
Yifan Hong01e7cde2017-01-09 17:45:45 -0800326 return "BpHw" + getInterfaceBaseName();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800327}
328
329std::string FQName::getInterfaceStubName() const {
Yifan Hong01e7cde2017-01-09 17:45:45 -0800330 return "BnHw" + getInterfaceBaseName();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800331}
332
333std::string FQName::getInterfacePassthroughName() const {
334 return "Bs" + getInterfaceBaseName();
335}
336
337FQName FQName::getInterfaceProxyFqName() const {
338 return FQName(package(), version(), getInterfaceProxyName());
339}
340
341FQName FQName::getInterfaceStubFqName() const {
342 return FQName(package(), version(), getInterfaceStubName());
343}
344
345FQName FQName::getInterfacePassthroughFqName() const {
346 return FQName(package(), version(), getInterfacePassthroughName());
Steven Moreland197d56c2016-09-09 10:03:58 -0700347}
348
Yifan Hong1977ea32016-10-05 12:49:08 -0700349FQName FQName::getTypesForPackage() const {
350 return FQName(package(), version(), "types");
351}
352
Yifan Hongfece6ec2017-01-12 17:04:04 -0800353FQName FQName::getPackageAndVersion() const {
354 return FQName(package(), version(), "");
355}
356
357FQName FQName::getTopLevelType() const {
Steven Moreland9c387612016-09-07 09:54:26 -0700358 auto idx = mName.find('.');
359
360 if (idx == std::string::npos) {
361 return *this;
362 }
363
Yifan Hong90ea87f2016-11-01 14:25:47 -0700364 return FQName(mPackage, version(), mName.substr(0, idx));
Steven Moreland9c387612016-09-07 09:54:26 -0700365}
366
367std::string FQName::tokenName() const {
368 std::vector<std::string> components;
369 getPackageAndVersionComponents(&components, true /* cpp_compatible */);
370
Steven Moreland6f596c82016-11-29 18:45:24 -0800371 if (!mName.empty()) {
372 std::vector<std::string> nameComponents;
373 StringHelper::SplitString(mName, '.', &nameComponents);
Steven Moreland9c387612016-09-07 09:54:26 -0700374
Steven Moreland6f596c82016-11-29 18:45:24 -0800375 components.insert(components.end(), nameComponents.begin(), nameComponents.end());
376 }
Steven Moreland9c387612016-09-07 09:54:26 -0700377
Steven Morelandaf440142016-09-07 10:09:11 -0700378 return StringHelper::JoinStrings(components, "_");
Steven Moreland9c387612016-09-07 09:54:26 -0700379}
380
Andreas Huber0e00de42016-08-03 09:56:02 -0700381std::string FQName::cppNamespace() const {
382 std::vector<std::string> components;
383 getPackageAndVersionComponents(&components, true /* cpp_compatible */);
384
385 std::string out = "::";
Steven Morelandaf440142016-09-07 10:09:11 -0700386 out += StringHelper::JoinStrings(components, "::");
Andreas Huber0e00de42016-08-03 09:56:02 -0700387
388 return out;
389}
390
Steven Moreland979e0992016-09-07 09:18:08 -0700391std::string FQName::cppLocalName() const {
392 std::vector<std::string> components;
Steven Morelandaf440142016-09-07 10:09:11 -0700393 StringHelper::SplitString(mName, '.', &components);
Steven Moreland979e0992016-09-07 09:18:08 -0700394
Yifan Hongb44a6c82016-09-22 15:50:18 -0700395 return StringHelper::JoinStrings(components, "::")
396 + (mValueName.empty() ? "" : ("::" + mValueName));
Steven Moreland979e0992016-09-07 09:18:08 -0700397}
398
Andreas Huber0e00de42016-08-03 09:56:02 -0700399std::string FQName::cppName() const {
400 std::string out = cppNamespace();
401
402 std::vector<std::string> components;
Steven Morelandaf440142016-09-07 10:09:11 -0700403 StringHelper::SplitString(name(), '.', &components);
Andreas Huber0e00de42016-08-03 09:56:02 -0700404 out += "::";
Steven Morelandaf440142016-09-07 10:09:11 -0700405 out += StringHelper::JoinStrings(components, "::");
Yifan Hongb44a6c82016-09-22 15:50:18 -0700406 if (!mValueName.empty()) {
407 out += "::" + mValueName;
408 }
Andreas Huber0e00de42016-08-03 09:56:02 -0700409
410 return out;
411}
412
Andreas Huber2831d512016-08-15 09:33:47 -0700413std::string FQName::javaPackage() const {
414 std::vector<std::string> components;
415 getPackageAndVersionComponents(&components, true /* cpp_compatible */);
416
Steven Morelandaf440142016-09-07 10:09:11 -0700417 return StringHelper::JoinStrings(components, ".");
Andreas Huber2831d512016-08-15 09:33:47 -0700418}
419
420std::string FQName::javaName() const {
Yifan Hongb44a6c82016-09-22 15:50:18 -0700421 return javaPackage() + "." + name()
422 + (mValueName.empty() ? "" : ("." + mValueName));
Andreas Huber2831d512016-08-15 09:33:47 -0700423}
424
Andreas Huber0e00de42016-08-03 09:56:02 -0700425void FQName::getPackageComponents(std::vector<std::string> *components) const {
Steven Morelandaf440142016-09-07 10:09:11 -0700426 StringHelper::SplitString(package(), '.', components);
Andreas Huber0e00de42016-08-03 09:56:02 -0700427}
428
429void FQName::getPackageAndVersionComponents(
430 std::vector<std::string> *components,
431 bool cpp_compatible) const {
432 getPackageComponents(components);
433
Yifan Hong1faabf12017-02-02 14:15:21 -0800434 if (!hasVersion()) {
435 LOG(WARNING) << "FQName: getPackageAndVersionComponents expects version.";
436 return;
437 }
438
Andreas Huber0e00de42016-08-03 09:56:02 -0700439 if (!cpp_compatible) {
Yifan Hong1faabf12017-02-02 14:15:21 -0800440 components->push_back(std::to_string(getPackageMajorVersion()) +
441 "." + std::to_string(getPackageMinorVersion()));
Andreas Huber0e00de42016-08-03 09:56:02 -0700442 return;
443 }
444
Yifan Hong97288ac2016-12-12 16:03:51 -0800445 components->push_back(sanitizedVersion());
Andreas Huber0e00de42016-08-03 09:56:02 -0700446}
447
Yifan Hong1faabf12017-02-02 14:15:21 -0800448bool FQName::hasVersion() const {
449 return mMajor > 0;
450}
451
452size_t FQName::getPackageMajorVersion() const {
453 CHECK(hasVersion()) << "FQName: No version exists at getPackageMajorVersion(). "
454 << "Did you check hasVersion()?";
Yifan Hong90ea87f2016-11-01 14:25:47 -0700455 return mMajor;
Martijn Coenena21f1492016-09-08 15:55:14 +0200456}
457
Yifan Hong1faabf12017-02-02 14:15:21 -0800458size_t FQName::getPackageMinorVersion() const {
459 CHECK(hasVersion()) << "FQName: No version exists at getPackageMinorVersion(). "
460 << "Did you check hasVersion()?";
Yifan Hong90ea87f2016-11-01 14:25:47 -0700461 return mMinor;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -0700462}
463
Andreas Huber39fa7182016-08-19 14:27:33 -0700464bool FQName::endsWith(const FQName &other) const {
465 std::string s1 = string();
466 std::string s2 = other.string();
467
468 size_t pos = s1.rfind(s2);
469 if (pos == std::string::npos || pos + s2.size() != s1.size()) {
470 return false;
471 }
472
Yifan Hongd9f22f72016-10-05 15:17:33 -0700473 // A match is only a match if it is preceded by a "boundary", i.e.
474 // we perform a component-wise match from the end.
475 // "az" is not a match for "android.hardware.foo@1.0::IFoo.bar.baz",
476 // "baz", "bar.baz", "IFoo.bar.baz", "@1.0::IFoo.bar.baz" are.
477 if (pos == 0) {
478 // matches "android.hardware.foo@1.0::IFoo.bar.baz"
479 return true;
Andreas Huber39fa7182016-08-19 14:27:33 -0700480 }
481
Yifan Hongd9f22f72016-10-05 15:17:33 -0700482 if (s1[pos - 1] == '.') {
483 // matches "baz" and "bar.baz"
484 return true;
485 }
486
487 if (s1[pos - 1] == ':') {
488 // matches "IFoo.bar.baz"
489 return true;
490 }
491
492 if (s1[pos] == '@') {
493 // matches "@1.0::IFoo.bar.baz"
494 return true;
495 }
496
497 return false;
Andreas Huber39fa7182016-08-19 14:27:33 -0700498}
499
Steven Moreland62709d72017-01-18 10:14:51 -0800500bool FQName::inPackage(const std::string &package) const {
501 std::vector<std::string> components;
502 getPackageComponents(&components);
503
504 std::vector<std::string> inComponents;
505 StringHelper::SplitString(package, '.', &inComponents);
506
507 if (inComponents.size() > components.size()) {
508 return false;
509 }
510
511 for (size_t i = 0; i < inComponents.size(); i++) {
512 if (inComponents[i] != components[i]) {
513 return false;
514 }
515 }
516
517 return true;
518}
519
Andreas Huber84f89de2016-07-28 15:39:51 -0700520} // namespace android
521