Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
Catalog Class Reference

#include <catalog.h>

Classes

struct  Entry
 VisibleForTesting. More...
 
class  Match
 

Public Member Functions

absl::StatusOr< std::vector< Match > > FindMatch (std::string_view query) const
 Tries to identify a match for the query across the Catalog.
 

Static Public Member Functions

static absl::StatusOr< CatalogOpen (std::string_view data_dir)
 
static absl::StatusOr< CatalogMake (const std::vector< Entry > &entries)
 Make a Catalog for testing.
 
static absl::StatusOr< EntryParseEntry (std::istream &is)
 VisibleForTesting.
 

Detailed Description

A storage of licenses that can be matched against. The in memory representation of the data/headers and data/licenses directories. This represents a 2 tiered search, first the sector is used to determine what matcher should be used, then a match is performend on that. This approach was chosen to minimize the size of the RE2::Set.

Definition at line 21 of file catalog.h.

Member Function Documentation

◆ FindMatch()

absl::StatusOr< std::vector< Catalog::Match > > Catalog::FindMatch ( std::string_view  query) const

Tries to identify a match for the query across the Catalog.

Parameters
queryThe text that will be matched against.
Returns
absl::StatusCode::kNotFound when a match can't be found. absl::StatusCode::kInvalidArgument if more than one match comes up from the selector.

Definition at line 186 of file catalog.cc.

187 {
188 std::vector<int> selector_results;
189 if (!selector_.Match(query, &selector_results)) {
190 return absl::NotFoundError("Selector didn't match.");
191 }
192
193 std::vector<Catalog::Match> results;
194 std::vector<int> missed_results;
195 missed_results.reserve(selector_results.size());
196 std::vector<int> hit_results;
197 hit_results.reserve(selector_results.size());
198 for (int selector_result : selector_results) {
199 RE2* matcher = matchers_[selector_result].get();
200 std::optional<Match> match =
201 FindMatchForSelectedMatcher(query, matcher, names_[selector_result]);
202 if (match.has_value()) {
203 results.emplace_back(std::move(match.value()));
204 hit_results.push_back(selector_result);
205 } else {
206 missed_results.push_back(selector_result);
207 }
208 }
209 if (selector_results.size() != results.size()) {
210 std::stringstream missed;
211 for (size_t i = 0; i < missed_results.size(); ++i) {
212 if (i != 0) {
213 missed << ", ";
214 }
215 missed << names_[missed_results[i]];
216 }
217 std::stringstream hit;
218 hit << " Hit matcher(s): (";
219 for (size_t i = 0; i < hit_results.size(); ++i) {
220 if (i != 0) {
221 hit << ", ";
222 }
223 hit << names_[hit_results[i]];
224 }
225 hit << ")";
226 return absl::NotFoundError(
227 absl::StrCat("Selected matcher(s) (", missed.str(), ") didn't match.",
228 hit_results.empty() ? "" : hit.str()));
229 } else {
230 for (size_t i = 0; i < results.size(); ++i) {
231 for (size_t j = i + 1; j < results.size(); ++j) {
232 if (Overlaps(results[i].GetMatchedText(),
233 results[j].GetMatchedText())) {
234 return absl::InvalidArgumentError(absl::StrCat(
235 "Selected matchers overlap (", results[i].GetMatcher(), ", ",
236 results[j].GetMatcher(), ").\n", results[i].GetMatchedText(),
237 "\n############\n", results[j].GetMatchedText()));
238 }
239 }
240 }
241
242 return results;
243 }
244}

References i.

◆ Make()

absl::StatusOr< Catalog > Catalog::Make ( const std::vector< Entry > &  entries)
static

Make a Catalog for testing.

Definition at line 154 of file catalog.cc.

154 {
155 RE2::Set selector(RE2::Options(), RE2::Anchor::UNANCHORED);
156 std::vector<std::unique_ptr<RE2>> matchers;
157 std::vector<std::string> names;
158
159 for (const Entry& entry : entries) {
160 std::string err;
161 names.push_back(std::string(entry.name));
162 int idx = selector.Add(entry.unique, &err);
163 if (idx < 0) {
164 return absl::InvalidArgumentError(
165 absl::StrCat("Unable to add set entry: ", entry.unique, " ", err));
166 }
167 matchers.push_back(std::make_unique<RE2>(entry.matcher));
168 }
169
170 bool did_compile = selector.Compile();
171 if (!did_compile) {
172 return absl::OutOfRangeError("RE2::Set ran out of memory.");
173 }
174 return Catalog(std::move(selector), std::move(matchers), std::move(names));
175}

Referenced by TEST(), TEST(), TEST(), TEST(), TEST(), TEST(), and TEST().

◆ Open()

absl::StatusOr< Catalog > Catalog::Open ( std::string_view  data_dir)
static

Definition at line 101 of file catalog.cc.

101 {
102 fs::path data_dir_path(data_dir);
103 if (!fs::exists(data_dir_path)) {
104 return absl::InvalidArgumentError(
105 absl::StrCat("Data directory doesn't exist ", data_dir));
106 }
107 fs::path licenses_path = data_dir_path / "licenses";
108 if (!fs::exists(licenses_path)) {
109 return absl::InvalidArgumentError(absl::StrCat(
110 "Licenses directory doesn't exist ", licenses_path.string()));
111 }
112
113 RE2::Set selector(RE2::Options(), RE2::Anchor::UNANCHORED);
114 std::vector<std::unique_ptr<RE2>> matchers;
115 std::vector<std::string> names;
116
117 for (const fs::path& file : fs::directory_iterator(licenses_path)) {
118 std::ifstream infile(file.string());
119 if (!infile.good()) {
120 return absl::InvalidArgumentError("Unable to open file " + file.string());
121 }
122
123 absl::StatusOr<Entry> entry = ParseEntry(infile);
124 if (!entry.ok()) {
125 return absl::InvalidArgumentError(
126 absl::StrCat("Unable to parse data entry at ", file.string(), " : ",
127 entry.status()));
128 }
129
130 std::string err;
131 selector.Add(entry->unique, &err);
132 if (!err.empty()) {
133 return absl::InvalidArgumentError(absl::StrCat(
134 "Unable to add unique key from ", file.string(), " : ", err));
135 }
136 names.emplace_back(std::move(entry->name));
137
138 auto matcher_re2 = std::make_unique<RE2>(entry->matcher);
139 if (!matcher_re2) {
140 return absl::InvalidArgumentError("Unable to make matcher.");
141 }
142
143 matchers.emplace_back(std::move(matcher_re2));
144 }
145
146 bool did_compile = selector.Compile();
147 if (!did_compile) {
148 return absl::UnknownError("Unable to compile selector.");
149 }
150
151 return Catalog(std::move(selector), std::move(matchers), std::move(names));
152}
static absl::StatusOr< Entry > ParseEntry(std::istream &is)
VisibleForTesting.
Definition catalog.cc:246

References ParseEntry().

Referenced by Data::Open().

◆ ParseEntry()

absl::StatusOr< Catalog::Entry > Catalog::ParseEntry ( std::istream &  is)
static

VisibleForTesting.

Definition at line 246 of file catalog.cc.

246 {
247 if (!is.good()) {
248 return absl::InvalidArgumentError("Bad stream.");
249 }
250 std::string name;
251 std::getline(is, name);
252 if (is.eof()) {
253 return absl::InvalidArgumentError("Bad stream.");
254 }
255 std::string unique;
256 std::getline(is, unique);
257 if (is.eof()) {
258 return absl::InvalidArgumentError("Bad stream.");
259 }
260
261 std::string matcher_text((std::istreambuf_iterator<char>(is)),
262 std::istreambuf_iterator<char>());
263
264 std::string ignore_whitespace_matcher = IgnoreWhitespace(matcher_text);
265
266 VLOG(4) << "matcher:" << name << ":\n" << ignore_whitespace_matcher;
267
268 return Catalog::Entry{.name = std::move(name),
269 .unique = std::move(unique),
270 .matcher = std::move(ignore_whitespace_matcher)};
271}
const char * name
Definition fuchsia.cc:50
VisibleForTesting.
Definition catalog.h:24
std::string name
Definition catalog.h:25

References name, and Catalog::Entry::name.

Referenced by Open(), and TEST().


The documentation for this class was generated from the following files: