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