xref: /aosp_15_r20/external/zucchini/imposed_ensemble_matcher.h (revision a03ca8b91e029cd15055c20c78c2e087c84792e4)
1*a03ca8b9SKrzysztof Kosiński // Copyright 2018 The Chromium Authors. All rights reserved.
2*a03ca8b9SKrzysztof Kosiński // Use of this source code is governed by a BSD-style license that can be
3*a03ca8b9SKrzysztof Kosiński // found in the LICENSE file.
4*a03ca8b9SKrzysztof Kosiński 
5*a03ca8b9SKrzysztof Kosiński #ifndef COMPONENTS_ZUCCHINI_IMPOSED_ENSEMBLE_MATCHER_H_
6*a03ca8b9SKrzysztof Kosiński #define COMPONENTS_ZUCCHINI_IMPOSED_ENSEMBLE_MATCHER_H_
7*a03ca8b9SKrzysztof Kosiński 
8*a03ca8b9SKrzysztof Kosiński #include <stddef.h>
9*a03ca8b9SKrzysztof Kosiński 
10*a03ca8b9SKrzysztof Kosiński #include <string>
11*a03ca8b9SKrzysztof Kosiński #include <vector>
12*a03ca8b9SKrzysztof Kosiński 
13*a03ca8b9SKrzysztof Kosiński #include "components/zucchini/buffer_view.h"
14*a03ca8b9SKrzysztof Kosiński #include "components/zucchini/element_detection.h"
15*a03ca8b9SKrzysztof Kosiński #include "components/zucchini/ensemble_matcher.h"
16*a03ca8b9SKrzysztof Kosiński 
17*a03ca8b9SKrzysztof Kosiński namespace zucchini {
18*a03ca8b9SKrzysztof Kosiński 
19*a03ca8b9SKrzysztof Kosiński // A class to parse imposed match format, which is either an empty string (no
20*a03ca8b9SKrzysztof Kosiński // imposed patch), or a string formatted as:
21*a03ca8b9SKrzysztof Kosiński //   "#+#=#+#,#+#=#+#,..."  (e.g., "1+2=3+4", "1+2=3+4,5+6=7+8"),
22*a03ca8b9SKrzysztof Kosiński // where "#+#=#+#" encodes a match as 4 unsigned integers:
23*a03ca8b9SKrzysztof Kosiński //   [offset in "old", size in "old", offset in "new", size in "new"].
24*a03ca8b9SKrzysztof Kosiński class ImposedMatchParser {
25*a03ca8b9SKrzysztof Kosiński  public:
26*a03ca8b9SKrzysztof Kosiński   enum Status {
27*a03ca8b9SKrzysztof Kosiński     kSuccess,
28*a03ca8b9SKrzysztof Kosiński     kInvalidDelimiter,
29*a03ca8b9SKrzysztof Kosiński     kParseError,
30*a03ca8b9SKrzysztof Kosiński     kOutOfBound,
31*a03ca8b9SKrzysztof Kosiński     kOverlapInNew,
32*a03ca8b9SKrzysztof Kosiński     kTypeMismatch,
33*a03ca8b9SKrzysztof Kosiński   };
34*a03ca8b9SKrzysztof Kosiński 
35*a03ca8b9SKrzysztof Kosiński   ImposedMatchParser();
36*a03ca8b9SKrzysztof Kosiński   ImposedMatchParser(const ImposedMatchParser&) = delete;
37*a03ca8b9SKrzysztof Kosiński   const ImposedMatchParser& operator=(const ImposedMatchParser&) = delete;
38*a03ca8b9SKrzysztof Kosiński   ~ImposedMatchParser();
39*a03ca8b9SKrzysztof Kosiński 
40*a03ca8b9SKrzysztof Kosiński   // Parses |imposed_matches| and writes the results to member variables.
41*a03ca8b9SKrzysztof Kosiński   // |old_image| and |new_image| are used for validation. Returns a Status value
42*a03ca8b9SKrzysztof Kosiński   // to signal success or various error modes. |detector| is used to validate
43*a03ca8b9SKrzysztof Kosiński   // Element types for matched pairs. This should only be called once for each
44*a03ca8b9SKrzysztof Kosiński   // instance.
45*a03ca8b9SKrzysztof Kosiński   Status Parse(std::string imposed_matches,
46*a03ca8b9SKrzysztof Kosiński                ConstBufferView old_image,
47*a03ca8b9SKrzysztof Kosiński                ConstBufferView new_image,
48*a03ca8b9SKrzysztof Kosiński                ElementDetector&& detector);
49*a03ca8b9SKrzysztof Kosiński 
num_identical()50*a03ca8b9SKrzysztof Kosiński   size_t num_identical() const { return num_identical_; }
mutable_matches()51*a03ca8b9SKrzysztof Kosiński   std::vector<ElementMatch>* mutable_matches() { return &matches_; }
mutable_bad_matches()52*a03ca8b9SKrzysztof Kosiński   std::vector<ElementMatch>* mutable_bad_matches() { return &bad_matches_; }
53*a03ca8b9SKrzysztof Kosiński 
54*a03ca8b9SKrzysztof Kosiński  private:
55*a03ca8b9SKrzysztof Kosiński   size_t num_identical_ = 0;
56*a03ca8b9SKrzysztof Kosiński   std::vector<ElementMatch> matches_;
57*a03ca8b9SKrzysztof Kosiński   // Stores "forgiven" bad matches, so the caller can impose matches for
58*a03ca8b9SKrzysztof Kosiński   // unsupported image types (which will simply be ignored). Note that imposing
59*a03ca8b9SKrzysztof Kosiński   // matches for known but incompatible image types would result in error.
60*a03ca8b9SKrzysztof Kosiński   std::vector<ElementMatch> bad_matches_;
61*a03ca8b9SKrzysztof Kosiński };
62*a03ca8b9SKrzysztof Kosiński 
63*a03ca8b9SKrzysztof Kosiński // An ensemble matcher that parses a format string that describes matches.
64*a03ca8b9SKrzysztof Kosiński class ImposedEnsembleMatcher : public EnsembleMatcher {
65*a03ca8b9SKrzysztof Kosiński  public:
66*a03ca8b9SKrzysztof Kosiński   // |imposed_matches| specifies imposed maches, using a format described below.
67*a03ca8b9SKrzysztof Kosiński   // Validation is performed in RunMatch().
68*a03ca8b9SKrzysztof Kosiński   explicit ImposedEnsembleMatcher(const std::string& imposed_matches);
69*a03ca8b9SKrzysztof Kosiński   ImposedEnsembleMatcher(const ImposedEnsembleMatcher&) = delete;
70*a03ca8b9SKrzysztof Kosiński   const ImposedEnsembleMatcher& operator=(const ImposedEnsembleMatcher&) =
71*a03ca8b9SKrzysztof Kosiński       delete;
72*a03ca8b9SKrzysztof Kosiński   ~ImposedEnsembleMatcher() override;
73*a03ca8b9SKrzysztof Kosiński 
74*a03ca8b9SKrzysztof Kosiński   // EnsembleMatcher:
75*a03ca8b9SKrzysztof Kosiński   bool RunMatch(ConstBufferView old_image, ConstBufferView new_image) override;
76*a03ca8b9SKrzysztof Kosiński 
77*a03ca8b9SKrzysztof Kosiński  private:
78*a03ca8b9SKrzysztof Kosiński   const std::string imposed_matches_;
79*a03ca8b9SKrzysztof Kosiński };
80*a03ca8b9SKrzysztof Kosiński 
81*a03ca8b9SKrzysztof Kosiński }  // namespace zucchini
82*a03ca8b9SKrzysztof Kosiński 
83*a03ca8b9SKrzysztof Kosiński #endif  // COMPONENTS_ZUCCHINI_IMPOSED_ENSEMBLE_MATCHER_H_
84