blob: 79d16a12d76cbb260ed88a36141a50af33b08a53 [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>
Iliyan Malchev800273d2016-09-02 15:25:07 -070022#include <iostream>
Andreas Huber84f89de2016-07-28 15:39:51 -070023#include <regex>
Iliyan Malchev800273d2016-09-02 15:25:07 -070024#include <sstream>
Andreas Huber84f89de2016-07-28 15:39:51 -070025
26#define RE_COMPONENT "[a-zA-Z_][a-zA-Z_0-9]*"
Yifan Hong95a47bb2016-09-29 10:08:10 -070027#define RE_PATH RE_COMPONENT "(?:[.]" RE_COMPONENT ")*"
Yifan Hong90ea87f2016-11-01 14:25:47 -070028#define RE_MAJOR "[0-9]+"
29#define RE_MINOR "[0-9]+"
Andreas Huber84f89de2016-07-28 15:39:51 -070030
Yifan Hong333a6d22017-01-12 12:28:02 -080031// android.hardware.foo@1.0::IFoo.Type
32static const std::regex kRE1("(" RE_PATH ")@(" RE_MAJOR ")[.](" RE_MINOR ")::(" RE_PATH ")");
33// @1.0::IFoo.Type
Yifan Hong90ea87f2016-11-01 14:25:47 -070034static const std::regex kRE2("@(" RE_MAJOR ")[.](" RE_MINOR ")::(" RE_PATH ")");
Yifan Hong333a6d22017-01-12 12:28:02 -080035// android.hardware.foo@1.0 (for package declaration and whole package import)
Yifan Hong90ea87f2016-11-01 14:25:47 -070036static const std::regex kRE3("(" RE_PATH ")@(" RE_MAJOR ")[.](" RE_MINOR ")");
Yifan Hong333a6d22017-01-12 12:28:02 -080037// IFoo.Type
Yifan Hongb44a6c82016-09-22 15:50:18 -070038static const std::regex kRE4("(" RE_COMPONENT ")([.]" RE_COMPONENT ")+");
Yifan Hong333a6d22017-01-12 12:28:02 -080039// Type (a plain identifier)
Yifan Hongb44a6c82016-09-22 15:50:18 -070040static const std::regex kRE5("(" RE_COMPONENT ")");
41
Yifan Hong333a6d22017-01-12 12:28:02 -080042// android.hardware.foo@1.0::IFoo.Type:MY_ENUM_VALUE
43static const std::regex kRE6("(" RE_PATH ")@(" RE_MAJOR ")[.](" RE_MINOR ")::(" RE_PATH "):(" RE_COMPONENT ")");
44// @1.0::IFoo.Type:MY_ENUM_VALUE
Yifan Hong90ea87f2016-11-01 14:25:47 -070045static const std::regex kRE7("@(" RE_MAJOR ")[.](" RE_MINOR ")::(" RE_PATH "):(" RE_COMPONENT ")");
Yifan Hong333a6d22017-01-12 12:28:02 -080046// IFoo.Type:MY_ENUM_VALUE
Yifan Hongb44a6c82016-09-22 15:50:18 -070047static const std::regex kRE8("(" RE_PATH "):(" RE_COMPONENT ")");
Andreas Huber84f89de2016-07-28 15:39:51 -070048
Yifan Hong333a6d22017-01-12 12:28:02 -080049// 1.0
Yifan Hong90ea87f2016-11-01 14:25:47 -070050static const std::regex kREVer("(" RE_MAJOR ")[.](" RE_MINOR ")");
51
Andreas Huber84f89de2016-07-28 15:39:51 -070052namespace android {
53
Andreas Huberda51b8e2016-07-28 16:00:57 -070054FQName::FQName()
Yifan Hong327cfe12016-10-03 10:29:42 -070055 : mValid(false),
56 mIsIdentifier(false) {
Andreas Huberda51b8e2016-07-28 16:00:57 -070057}
58
Andreas Huber84f89de2016-07-28 15:39:51 -070059FQName::FQName(const std::string &s)
Yifan Hong327cfe12016-10-03 10:29:42 -070060 : mValid(false),
61 mIsIdentifier(false) {
Andreas Huber84f89de2016-07-28 15:39:51 -070062 setTo(s);
63}
64
Andreas Huber68f24592016-07-29 14:53:48 -070065FQName::FQName(
66 const std::string &package,
67 const std::string &version,
Yifan Hongb44a6c82016-09-22 15:50:18 -070068 const std::string &name,
69 const std::string &valueName)
Andreas Huber68f24592016-07-29 14:53:48 -070070 : mValid(true),
Yifan Hongb44a6c82016-09-22 15:50:18 -070071 mIsIdentifier(false),
Andreas Huber68f24592016-07-29 14:53:48 -070072 mPackage(package),
Yifan Hongb44a6c82016-09-22 15:50:18 -070073 mName(name),
74 mValueName(valueName) {
Yifan Hong90ea87f2016-11-01 14:25:47 -070075 setVersion(version);
Yifan Hongfece6ec2017-01-12 17:04:04 -080076
77 // Check if this is actually a valid fqName
78 FQName other;
79 other.setTo(this->string());
80 CHECK(other.mValid && (*this) == other);
Andreas Huber68f24592016-07-29 14:53:48 -070081}
82
Yifan Hongf24fa852016-09-23 11:03:15 -070083FQName::FQName(const FQName& other)
84 : mValid(other.mValid),
85 mIsIdentifier(other.mIsIdentifier),
86 mPackage(other.mPackage),
Yifan Hong90ea87f2016-11-01 14:25:47 -070087 mMajor(other.mMajor),
88 mMinor(other.mMinor),
Yifan Hongf24fa852016-09-23 11:03:15 -070089 mName(other.mName),
90 mValueName(other.mValueName) {
91}
92
Yifan Hong327cfe12016-10-03 10:29:42 -070093FQName::FQName(const std::vector<std::string> &names)
94 : mValid(false),
95 mIsIdentifier(false) {
96 setTo(StringHelper::JoinStrings(names, "."));
97}
98
Andreas Huber84f89de2016-07-28 15:39:51 -070099bool FQName::isValid() const {
100 return mValid;
101}
102
Yifan Hongb44a6c82016-09-22 15:50:18 -0700103bool FQName::isIdentifier() const {
104 return mIsIdentifier;
105}
106
Andreas Huber68f24592016-07-29 14:53:48 -0700107bool FQName::isFullyQualified() const {
Yifan Hong90ea87f2016-11-01 14:25:47 -0700108 return !mPackage.empty() && !version().empty() && !mName.empty();
Andreas Huber68f24592016-07-29 14:53:48 -0700109}
110
Yifan Hongb44a6c82016-09-22 15:50:18 -0700111bool FQName::isValidValueName() const {
112 return mIsIdentifier
113 || (!mName.empty() && !mValueName.empty());
114}
115
Andreas Huber84f89de2016-07-28 15:39:51 -0700116bool FQName::setTo(const std::string &s) {
117 mPackage.clear();
Steven Moreland88922c92017-02-11 18:16:09 +0000118 mMajor.clear();
119 mMinor.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);
Steven Moreland88922c92017-02-11 18:16:09 +0000129 mMajor = match.str(2);
130 mMinor = match.str(3);
Yifan Hong90ea87f2016-11-01 14:25:47 -0700131 mName = match.str(4);
132 } else if (std::regex_match(s, match, kRE2)) {
133 CHECK_EQ(match.size(), 4u);
134
Steven Moreland88922c92017-02-11 18:16:09 +0000135 mMajor = match.str(1);
136 mMinor = match.str(2);
Yifan Hong90ea87f2016-11-01 14:25:47 -0700137 mName = match.str(3);
138 } else if (std::regex_match(s, match, kRE3)) {
Yifan Hong95a47bb2016-09-29 10:08:10 -0700139 CHECK_EQ(match.size(), 4u);
Andreas Huber84f89de2016-07-28 15:39:51 -0700140
141 mPackage = match.str(1);
Steven Moreland88922c92017-02-11 18:16:09 +0000142 mMajor = match.str(2);
143 mMinor = match.str(3);
Andreas Huberda51b8e2016-07-28 16:00:57 -0700144 } else if (std::regex_match(s, match, kRE4)) {
Andreas Huber84f89de2016-07-28 15:39:51 -0700145 mName = match.str(0);
Yifan Hongb44a6c82016-09-22 15:50:18 -0700146 } else if (std::regex_match(s, match, kRE5)) {
147 mIsIdentifier = true;
148 mName = match.str(0);
149 } else if (std::regex_match(s, match, kRE6)) {
Yifan Hong90ea87f2016-11-01 14:25:47 -0700150 CHECK_EQ(match.size(), 6u);
Yifan Hongb44a6c82016-09-22 15:50:18 -0700151
152 mPackage = match.str(1);
Steven Moreland88922c92017-02-11 18:16:09 +0000153 mMajor = match.str(2);
154 mMinor = match.str(3);
Yifan Hong90ea87f2016-11-01 14:25:47 -0700155 mName = match.str(4);
156 mValueName = match.str(5);
157 } else if (std::regex_match(s, match, kRE7)) {
158 CHECK_EQ(match.size(), 5u);
159
Steven Moreland88922c92017-02-11 18:16:09 +0000160 mMajor = match.str(1);
161 mMinor = match.str(2);
Yifan Hong95a47bb2016-09-29 10:08:10 -0700162 mName = match.str(3);
163 mValueName = match.str(4);
Yifan Hongb44a6c82016-09-22 15:50:18 -0700164 } else if (std::regex_match(s, match, kRE8)) {
Yifan Hong95a47bb2016-09-29 10:08:10 -0700165 CHECK_EQ(match.size(), 3u);
Yifan Hongb44a6c82016-09-22 15:50:18 -0700166
167 mName = match.str(1);
Yifan Hong95a47bb2016-09-29 10:08:10 -0700168 mValueName = match.str(2);
Andreas Huber84f89de2016-07-28 15:39:51 -0700169 } else {
170 mValid = false;
171 }
172
Yifan Hongb44a6c82016-09-22 15:50:18 -0700173 // mValueName must go with mName.
Yifan Hong333a6d22017-01-12 12:28:02 -0800174 CHECK(mValueName.empty() || !mName.empty());
175
176 // package without version is not allowed.
177 CHECK(mPackage.empty() || !version().empty());
Yifan Hongb44a6c82016-09-22 15:50:18 -0700178
Andreas Huber84f89de2016-07-28 15:39:51 -0700179 return isValid();
180}
181
182std::string FQName::package() const {
183 return mPackage;
184}
185
186std::string FQName::version() const {
Steven Moreland88922c92017-02-11 18:16:09 +0000187 CHECK(mMajor.empty() == mMinor.empty());
188 if (mMajor.empty() && mMinor.empty()) {
Yifan Hong90ea87f2016-11-01 14:25:47 -0700189 return "";
190 }
Steven Moreland88922c92017-02-11 18:16:09 +0000191 return mMajor + "." + mMinor;
Yifan Hong90ea87f2016-11-01 14:25:47 -0700192}
193
Yifan Hong97288ac2016-12-12 16:03:51 -0800194std::string FQName::sanitizedVersion() const {
Steven Moreland88922c92017-02-11 18:16:09 +0000195 CHECK(mMajor.empty() == mMinor.empty());
196 if (mMajor.empty() && mMinor.empty()) {
Yifan Hong97288ac2016-12-12 16:03:51 -0800197 return "";
198 }
Steven Moreland88922c92017-02-11 18:16:09 +0000199 return "V" + mMajor + "_" + mMinor;
Yifan Hong97288ac2016-12-12 16:03:51 -0800200}
201
Yifan Hong90ea87f2016-11-01 14:25:47 -0700202std::string FQName::atVersion() const {
203 std::string v = version();
204 return v.empty() ? "" : ("@" + v);
205}
206
207void FQName::setVersion(const std::string &v) {
208 if (v.empty()) {
Steven Moreland88922c92017-02-11 18:16:09 +0000209 mMajor.clear();
210 mMinor.clear();
Yifan Hong90ea87f2016-11-01 14:25:47 -0700211 return;
212 }
213 std::smatch match;
214 if (std::regex_match(v, match, kREVer)) {
215 CHECK_EQ(match.size(), 3u);
216
Steven Moreland88922c92017-02-11 18:16:09 +0000217 mMajor = match.str(1);
218 mMinor = match.str(2);
Yifan Hong90ea87f2016-11-01 14:25:47 -0700219 } else {
220 mValid = false;
221 }
Andreas Huber84f89de2016-07-28 15:39:51 -0700222}
223
224std::string FQName::name() const {
225 return mName;
226}
227
Iliyan Malchev800273d2016-09-02 15:25:07 -0700228std::vector<std::string> FQName::names() const {
229 std::vector<std::string> res {};
230 std::istringstream ss(name());
231 std::string s;
232 while (std::getline(ss, s, '.')) {
233 res.push_back(s);
234 }
235 return res;
236}
237
Yifan Hongb44a6c82016-09-22 15:50:18 -0700238std::string FQName::valueName() const {
239 return mValueName;
240}
241
242FQName FQName::typeName() const {
Yifan Hong90ea87f2016-11-01 14:25:47 -0700243 return FQName(mPackage, version(), mName);
Yifan Hongb44a6c82016-09-22 15:50:18 -0700244}
245
Andreas Huber84f89de2016-07-28 15:39:51 -0700246void FQName::applyDefaults(
247 const std::string &defaultPackage,
248 const std::string &defaultVersion) {
Yifan Hong333a6d22017-01-12 12:28:02 -0800249
250 // package without version is not allowed.
251 CHECK(mPackage.empty() || !version().empty());
252
Andreas Huber84f89de2016-07-28 15:39:51 -0700253 if (mPackage.empty()) {
254 mPackage = defaultPackage;
255 }
256
Yifan Hong90ea87f2016-11-01 14:25:47 -0700257 if (version().empty()) {
258 setVersion(defaultVersion);
Andreas Huber84f89de2016-07-28 15:39:51 -0700259 }
260}
261
Andreas Huber68f24592016-07-29 14:53:48 -0700262std::string FQName::string() const {
Andreas Huber84f89de2016-07-28 15:39:51 -0700263 CHECK(mValid);
264
Andreas Huber5345ec22016-07-29 13:33:27 -0700265 std::string out;
Andreas Huber84f89de2016-07-28 15:39:51 -0700266 out.append(mPackage);
Yifan Hong90ea87f2016-11-01 14:25:47 -0700267 out.append(atVersion());
Andreas Huberda51b8e2016-07-28 16:00:57 -0700268 if (!mName.empty()) {
Yifan Hong90ea87f2016-11-01 14:25:47 -0700269 if (!mPackage.empty() || !version().empty()) {
Andreas Huberda51b8e2016-07-28 16:00:57 -0700270 out.append("::");
271 }
272 out.append(mName);
Yifan Hongb44a6c82016-09-22 15:50:18 -0700273
274 if (!mValueName.empty()) {
275 out.append(":");
276 out.append(mValueName);
277 }
Andreas Huber84f89de2016-07-28 15:39:51 -0700278 }
Andreas Huber84f89de2016-07-28 15:39:51 -0700279
280 return out;
281}
282
Andreas Huberda51b8e2016-07-28 16:00:57 -0700283void FQName::print() const {
284 if (!mValid) {
285 LOG(INFO) << "INVALID";
286 return;
287 }
288
Andreas Huber68f24592016-07-29 14:53:48 -0700289 LOG(INFO) << string();
290}
291
292bool FQName::operator<(const FQName &other) const {
293 return string() < other.string();
Andreas Huberda51b8e2016-07-28 16:00:57 -0700294}
295
Andreas Huberd2943e12016-08-05 11:59:31 -0700296bool FQName::operator==(const FQName &other) const {
297 return string() == other.string();
298}
299
Yifan Hongc8934042016-11-17 17:10:52 -0800300bool FQName::operator!=(const FQName &other) const {
301 return !(*this == other);
302}
303
Yifan Hongeefe4f22017-01-04 15:32:42 -0800304std::string FQName::getInterfaceName() const {
Steven Moreland197d56c2016-09-09 10:03:58 -0700305 CHECK(names().size() == 1) << "Must be a top level type";
306 CHECK(!mName.empty() && mName[0] == 'I') << mName;
307
Yifan Hongeefe4f22017-01-04 15:32:42 -0800308 return mName;
309}
310
311std::string FQName::getInterfaceBaseName() const {
Steven Moreland197d56c2016-09-09 10:03:58 -0700312 // cut off the leading 'I'.
Yifan Hongeefe4f22017-01-04 15:32:42 -0800313 return getInterfaceName().substr(1);
314}
315
316std::string FQName::getInterfaceHwName() const {
317 return "IHw" + getInterfaceBaseName();
318}
319
320std::string FQName::getInterfaceProxyName() const {
Yifan Hong01e7cde2017-01-09 17:45:45 -0800321 return "BpHw" + getInterfaceBaseName();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800322}
323
324std::string FQName::getInterfaceStubName() const {
Yifan Hong01e7cde2017-01-09 17:45:45 -0800325 return "BnHw" + getInterfaceBaseName();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800326}
327
328std::string FQName::getInterfacePassthroughName() const {
329 return "Bs" + getInterfaceBaseName();
330}
331
332FQName FQName::getInterfaceProxyFqName() const {
333 return FQName(package(), version(), getInterfaceProxyName());
334}
335
336FQName FQName::getInterfaceStubFqName() const {
337 return FQName(package(), version(), getInterfaceStubName());
338}
339
340FQName FQName::getInterfacePassthroughFqName() const {
341 return FQName(package(), version(), getInterfacePassthroughName());
Steven Moreland197d56c2016-09-09 10:03:58 -0700342}
343
Yifan Hong1977ea32016-10-05 12:49:08 -0700344FQName FQName::getTypesForPackage() const {
345 return FQName(package(), version(), "types");
346}
347
Yifan Hongfece6ec2017-01-12 17:04:04 -0800348FQName FQName::getPackageAndVersion() const {
349 return FQName(package(), version(), "");
350}
351
352FQName FQName::getTopLevelType() const {
Steven Moreland9c387612016-09-07 09:54:26 -0700353 auto idx = mName.find('.');
354
355 if (idx == std::string::npos) {
356 return *this;
357 }
358
Yifan Hong90ea87f2016-11-01 14:25:47 -0700359 return FQName(mPackage, version(), mName.substr(0, idx));
Steven Moreland9c387612016-09-07 09:54:26 -0700360}
361
362std::string FQName::tokenName() const {
363 std::vector<std::string> components;
364 getPackageAndVersionComponents(&components, true /* cpp_compatible */);
365
Steven Moreland6f596c82016-11-29 18:45:24 -0800366 if (!mName.empty()) {
367 std::vector<std::string> nameComponents;
368 StringHelper::SplitString(mName, '.', &nameComponents);
Steven Moreland9c387612016-09-07 09:54:26 -0700369
Steven Moreland6f596c82016-11-29 18:45:24 -0800370 components.insert(components.end(), nameComponents.begin(), nameComponents.end());
371 }
Steven Moreland9c387612016-09-07 09:54:26 -0700372
Steven Morelandaf440142016-09-07 10:09:11 -0700373 return StringHelper::JoinStrings(components, "_");
Steven Moreland9c387612016-09-07 09:54:26 -0700374}
375
Andreas Huber0e00de42016-08-03 09:56:02 -0700376std::string FQName::cppNamespace() const {
377 std::vector<std::string> components;
378 getPackageAndVersionComponents(&components, true /* cpp_compatible */);
379
380 std::string out = "::";
Steven Morelandaf440142016-09-07 10:09:11 -0700381 out += StringHelper::JoinStrings(components, "::");
Andreas Huber0e00de42016-08-03 09:56:02 -0700382
383 return out;
384}
385
Steven Moreland979e0992016-09-07 09:18:08 -0700386std::string FQName::cppLocalName() const {
387 std::vector<std::string> components;
Steven Morelandaf440142016-09-07 10:09:11 -0700388 StringHelper::SplitString(mName, '.', &components);
Steven Moreland979e0992016-09-07 09:18:08 -0700389
Yifan Hongb44a6c82016-09-22 15:50:18 -0700390 return StringHelper::JoinStrings(components, "::")
391 + (mValueName.empty() ? "" : ("::" + mValueName));
Steven Moreland979e0992016-09-07 09:18:08 -0700392}
393
Andreas Huber0e00de42016-08-03 09:56:02 -0700394std::string FQName::cppName() const {
395 std::string out = cppNamespace();
396
397 std::vector<std::string> components;
Steven Morelandaf440142016-09-07 10:09:11 -0700398 StringHelper::SplitString(name(), '.', &components);
Andreas Huber0e00de42016-08-03 09:56:02 -0700399 out += "::";
Steven Morelandaf440142016-09-07 10:09:11 -0700400 out += StringHelper::JoinStrings(components, "::");
Yifan Hongb44a6c82016-09-22 15:50:18 -0700401 if (!mValueName.empty()) {
402 out += "::" + mValueName;
403 }
Andreas Huber0e00de42016-08-03 09:56:02 -0700404
405 return out;
406}
407
Andreas Huber2831d512016-08-15 09:33:47 -0700408std::string FQName::javaPackage() const {
409 std::vector<std::string> components;
410 getPackageAndVersionComponents(&components, true /* cpp_compatible */);
411
Steven Morelandaf440142016-09-07 10:09:11 -0700412 return StringHelper::JoinStrings(components, ".");
Andreas Huber2831d512016-08-15 09:33:47 -0700413}
414
415std::string FQName::javaName() const {
Yifan Hongb44a6c82016-09-22 15:50:18 -0700416 return javaPackage() + "." + name()
417 + (mValueName.empty() ? "" : ("." + mValueName));
Andreas Huber2831d512016-08-15 09:33:47 -0700418}
419
Andreas Huber0e00de42016-08-03 09:56:02 -0700420void FQName::getPackageComponents(std::vector<std::string> *components) const {
Steven Morelandaf440142016-09-07 10:09:11 -0700421 StringHelper::SplitString(package(), '.', components);
Andreas Huber0e00de42016-08-03 09:56:02 -0700422}
423
424void FQName::getPackageAndVersionComponents(
425 std::vector<std::string> *components,
426 bool cpp_compatible) const {
427 getPackageComponents(components);
428
Andreas Huber0e00de42016-08-03 09:56:02 -0700429 if (!cpp_compatible) {
Steven Moreland88922c92017-02-11 18:16:09 +0000430 components->push_back(getPackageMajorVersion() +
431 "." + getPackageMinorVersion());
Andreas Huber0e00de42016-08-03 09:56:02 -0700432 return;
433 }
434
Yifan Hong97288ac2016-12-12 16:03:51 -0800435 components->push_back(sanitizedVersion());
Andreas Huber0e00de42016-08-03 09:56:02 -0700436}
437
Steven Moreland88922c92017-02-11 18:16:09 +0000438std::string FQName::getPackageMajorVersion() const {
Yifan Hong90ea87f2016-11-01 14:25:47 -0700439 return mMajor;
Martijn Coenena21f1492016-09-08 15:55:14 +0200440}
441
Steven Moreland88922c92017-02-11 18:16:09 +0000442std::string FQName::getPackageMinorVersion() const {
Yifan Hong90ea87f2016-11-01 14:25:47 -0700443 return mMinor;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -0700444}
445
Andreas Huber39fa7182016-08-19 14:27:33 -0700446bool FQName::endsWith(const FQName &other) const {
447 std::string s1 = string();
448 std::string s2 = other.string();
449
450 size_t pos = s1.rfind(s2);
451 if (pos == std::string::npos || pos + s2.size() != s1.size()) {
452 return false;
453 }
454
Yifan Hongd9f22f72016-10-05 15:17:33 -0700455 // A match is only a match if it is preceded by a "boundary", i.e.
456 // we perform a component-wise match from the end.
457 // "az" is not a match for "android.hardware.foo@1.0::IFoo.bar.baz",
458 // "baz", "bar.baz", "IFoo.bar.baz", "@1.0::IFoo.bar.baz" are.
459 if (pos == 0) {
460 // matches "android.hardware.foo@1.0::IFoo.bar.baz"
461 return true;
Andreas Huber39fa7182016-08-19 14:27:33 -0700462 }
463
Yifan Hongd9f22f72016-10-05 15:17:33 -0700464 if (s1[pos - 1] == '.') {
465 // matches "baz" and "bar.baz"
466 return true;
467 }
468
469 if (s1[pos - 1] == ':') {
470 // matches "IFoo.bar.baz"
471 return true;
472 }
473
474 if (s1[pos] == '@') {
475 // matches "@1.0::IFoo.bar.baz"
476 return true;
477 }
478
479 return false;
Andreas Huber39fa7182016-08-19 14:27:33 -0700480}
481
Steven Moreland62709d72017-01-18 10:14:51 -0800482bool FQName::inPackage(const std::string &package) const {
483 std::vector<std::string> components;
484 getPackageComponents(&components);
485
486 std::vector<std::string> inComponents;
487 StringHelper::SplitString(package, '.', &inComponents);
488
489 if (inComponents.size() > components.size()) {
490 return false;
491 }
492
493 for (size_t i = 0; i < inComponents.size(); i++) {
494 if (inComponents[i] != components[i]) {
495 return false;
496 }
497 }
498
499 return true;
500}
501
Andreas Huber84f89de2016-07-28 15:39:51 -0700502} // namespace android
503