1 /*
2  * Copyright (C) 2018 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 
17 #include "MatrixInstance.h"
18 
19 #include <utility>
20 
21 #include "Regex.h"
22 #include "parse_string.h"
23 
24 namespace android {
25 namespace vintf {
26 
27 MatrixInstance::MatrixInstance() = default;
28 
29 MatrixInstance::MatrixInstance(const MatrixInstance&) = default;
30 
31 MatrixInstance::MatrixInstance(MatrixInstance&&) noexcept = default;
32 
33 MatrixInstance& MatrixInstance::operator=(const MatrixInstance&) = default;
34 
35 MatrixInstance& MatrixInstance::operator=(MatrixInstance&&) noexcept = default;
36 
37 MatrixInstance::MatrixInstance(HalFormat format, FqInstance&& fqInstance, VersionRange&& range,
38                                bool optional, bool isRegex)
39     : mFormat(format),
40       mFqInstance(std::move(fqInstance)),
41       mRange(std::move(range)),
42       mOptional(optional),
43       mIsRegex(isRegex) {}
44 
45 MatrixInstance::MatrixInstance(HalFormat format, const FqInstance fqInstance,
46                                const VersionRange& range, bool optional, bool isRegex)
47     : mFormat(format),
48       mFqInstance(fqInstance),
49       mRange(range),
50       mOptional(optional),
51       mIsRegex(isRegex) {}
52 
53 const std::string& MatrixInstance::package() const {
54     return mFqInstance.getPackage();
55 }
56 
57 const VersionRange& MatrixInstance::versionRange() const {
58     return mRange;
59 }
60 
61 const std::string& MatrixInstance::interface() const {
62     return mFqInstance.getInterface();
63 }
64 
65 HalFormat MatrixInstance::format() const {
66     return mFormat;
67 }
68 
69 bool MatrixInstance::optional() const {
70     return mOptional;
71 }
72 
73 bool MatrixInstance::isSatisfiedBy(const FqInstance& provided) const {
74     return package() == provided.getPackage() &&
75            versionRange().supportedBy(provided.getVersion()) &&
76            interface() == provided.getInterface() && matchInstance(provided.getInstance());
77 }
78 
79 bool MatrixInstance::matchInstance(const std::string& e) const {
80     if (!isRegex()) {
81         return exactInstance() == e;
82     }
83     details::Regex regex;
84     if (!regex.compile(regexPattern())) {
85         return false;
86     }
87     return regex.matches(e);
88 }
89 
90 const std::string& MatrixInstance::regexPattern() const {
91     static const std::string kEmptyString;
92     return isRegex() ? mFqInstance.getInstance() : kEmptyString;
93 }
94 
95 const std::string& MatrixInstance::exactInstance() const {
96     static const std::string kEmptyString;
97     return isRegex() ? kEmptyString : mFqInstance.getInstance();
98 }
99 
100 bool MatrixInstance::isRegex() const {
101     return mIsRegex;
102 }
103 
104 std::string MatrixInstance::interfaceDescription(Version replaceVersion) const {
105     switch (format()) {
106         case HalFormat::HIDL:
107             [[fallthrough]];
108         case HalFormat::NATIVE: {
109             return toFQNameString(package(), replaceVersion, interface());
110         } break;
111         case HalFormat::AIDL: {
112             return toAidlFqnameString(package(), interface()) + " (@" +
113                    aidlVersionToString(replaceVersion) + ")";
114         } break;
115     }
116 }
117 
118 std::string MatrixInstance::description(Version replaceVersion) const {
119     std::string instanceDescription = isRegex() ? regexPattern() : exactInstance();
120     switch (format()) {
121         case HalFormat::HIDL:
122             [[fallthrough]];
123         case HalFormat::NATIVE: {
124             return toFQNameString(package(), replaceVersion, interface(), instanceDescription);
125         } break;
126         case HalFormat::AIDL: {
127             return toAidlFqnameString(package(), interface(), instanceDescription) + " (@" +
128                    aidlVersionToString(replaceVersion) + ")";
129         } break;
130     }
131 }
132 
133 }  // namespace vintf
134 }  // namespace android
135