blob: d2584ec126dd361e4eb64c1e7f1ccb803790ffd0 [file] [log] [blame]
Yifan Hong676447a2016-11-15 12:57:23 -08001/*
2 * Copyright (C) 2017 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// Convert objects from and to strings.
18
19#include "parse_string.h"
20#include <android-base/parseint.h>
21
22namespace android {
23using base::ParseUint;
24
25namespace vintf {
26
27static const std::string kRequired("required");
28static const std::string kOptional("optional");
29static const std::string kConfigPrefix("CONFIG_");
30
31std::vector<std::string> SplitString(const std::string &s, char c) {
32 std::vector<std::string> components;
33
34 size_t startPos = 0;
35 size_t matchPos;
36 while ((matchPos = s.find(c, startPos)) != std::string::npos) {
37 components.push_back(s.substr(startPos, matchPos - startPos));
38 startPos = matchPos + 1;
39 }
40
41 if (startPos <= s.length()) {
42 components.push_back(s.substr(startPos));
43 }
44 return components;
45}
46
47template <typename T>
48std::ostream &operator<<(std::ostream &os, const std::vector<T> objs) {
49 bool first = true;
50 for (const T &v : objs) {
51 if (!first) {
52 os << ",";
53 }
54 os << v;
55 first = false;
56 }
57 return os;
58}
59
60template <typename T>
61bool parse(const std::string &s, std::vector<T> *objs) {
62 std::vector<std::string> v = SplitString(s, ',');
63 objs->resize(v.size());
64 size_t idx = 0;
65 for (const auto &item : v) {
66 T ver;
67 if (!parse(item, &ver)) {
68 return false;
69 }
70 objs->at(idx++) = ver;
71 }
72 return true;
73}
74
75template<typename E, typename Array>
76bool parseEnum(const std::string &s, E *e, const Array &strings) {
77 for (size_t i = 0; i < strings.size(); ++i) {
78 if (s == strings.at(i)) {
79 *e = static_cast<E>(i);
80 return true;
81 }
82 }
83 return false;
84}
85
86bool parse(const std::string &s, HalFormat *hf) {
87 return parseEnum(s, hf, gHalFormatStrings);
88}
89
90std::ostream &operator<<(std::ostream &os, HalFormat hf) {
91 return os << gHalFormatStrings.at(static_cast<size_t>(hf));
92}
93
94bool parse(const std::string &s, ImplLevel *il) {
95 return parseEnum(s, il, gImplLevelStrings);
96}
97
98std::ostream &operator<<(std::ostream &os, ImplLevel il) {
99 return os << gImplLevelStrings.at(static_cast<size_t>(il));
100}
101
102bool parse(const std::string &s, Transport *tr) {
103 return parseEnum(s, tr, gTransportStrings);
104}
105
106std::ostream &operator<<(std::ostream &os, Transport il) {
107 return os << gTransportStrings.at(static_cast<size_t>(il));
108}
109
110bool parse(const std::string &s, Version *ver) {
111 std::vector<std::string> v = SplitString(s, '.');
112 if (v.size() != 2) {
113 return false;
114 }
115 size_t major, minor;
116 if (!ParseUint(v[0], &major)) {
117 return false;
118 }
119 if (!ParseUint(v[1], &minor)) {
120 return false;
121 }
122 *ver = Version(major, minor);
123 return true;
124}
125
126std::ostream &operator<<(std::ostream &os, const Version &ver) {
127 return os << ver.majorVer << "." << ver.minorVer;
128}
129
130bool parse(const std::string &s, VersionRange *vr) {
131 std::vector<std::string> v = SplitString(s, '-');
132 if (v.size() != 1 && v.size() != 2) {
133 return false;
134 }
135 Version minVer;
136 if (!parse(v[0], &minVer)) {
137 return false;
138 }
139 if (v.size() == 1) {
140 *vr = VersionRange(minVer.majorVer, minVer.minorVer);
141 } else {
142 size_t maxMinor;
143 if (!ParseUint(v[1], &maxMinor)) {
144 return false;
145 }
146 *vr = VersionRange(minVer.majorVer, minVer.minorVer, maxMinor);
147 }
148 return true;
149}
150
151std::ostream &operator<<(std::ostream &os, const VersionRange &vr) {
152 if (vr.isSingleVersion()) {
153 return os << vr.minVer();
154 }
155 return os << vr.minVer() << "-" << vr.maxMinor;
156}
157
158bool parse(const std::string &s, ManifestHal *hal) {
159 std::vector<std::string> v = SplitString(s, '/');
160 if (v.size() != 5) {
161 return false;
162 }
163 if (!parse(v[0], &hal->format)) {
164 return false;
165 }
166 hal->name = v[1];
167 if (!parse(v[2], &hal->transport)) {
168 return false;
169 }
170 if (!parse(v[3], &hal->impl.implLevel)) {
171 return false;
172 }
173 hal->impl.impl = v[4];
174 if (!parse(v[5], &hal->versions)) {
175 return false;
176 }
177 return true;
178}
179
180std::ostream &operator<<(std::ostream &os, const ManifestHal &hal) {
181 return os << hal.format << "/"
182 << hal.name << "/"
183 << hal.transport << "/"
184 << hal.impl.implLevel << "/"
185 << hal.impl.impl << "/"
186 << hal.versions;
187}
188
189bool parse(const std::string &s, MatrixHal *req) {
190 std::vector<std::string> v = SplitString(s, '/');
191 if (v.size() != 4) {
192 return false;
193 }
194 if (!parse(v[0], &req->format)) {
195 return false;
196 }
197 req->name = v[1];
198 if (!parse(v[2], &req->versionRanges)) {
199 return false;
200 }
201 if (v[3] != kRequired || v[3] != kOptional) {
202 return false;
203 }
204 req->optional = (v[3] == kOptional);
205 return true;
206}
207
208std::ostream &operator<<(std::ostream &os, const MatrixHal &req) {
209 return os << req.format << "/"
210 << req.name << "/"
211 << req.versionRanges << "/"
212 << (req.optional ? kOptional : kRequired);
213}
214
215bool parse(const std::string &s, KernelConfig *kc) {
216 if (s.find(kConfigPrefix) != 0) {
217 return false;
218 }
219 *kc = s;
220 return true;
221}
222
223std::string dump(const VendorManifest &vm) {
224 std::ostringstream oss;
225 bool first = true;
226 for (const auto &pair : vm.hals) {
227 const auto &hal = pair.second;
228 if (!first) {
229 oss << ":";
230 }
231 oss << hal;
232 first = false;
233 }
234 return oss.str();
235}
236
237} // namespace vintf
238} // namespace android