// © 2018 and later: Unicode, Inc. and others. // License & terms of use: http://www.unicode.org/copyright.html #ifndef __FILTERRB_H__ #define __FILTERRB_H__ #include #include #include #include #include #include "unicode/utypes.h" /** * Represents an absolute path into a resource bundle. * For example: "/units/length/meter" */ class ResKeyPath { public: /** Constructs an empty path (top of tree) */ ResKeyPath(); /** Constructs from a string path */ ResKeyPath(const std::string& path, UErrorCode& status); void push(const std::string& key); void pop(); const std::list& pieces() const; private: std::list fPath; }; std::ostream& operator<<(std::ostream& out, const ResKeyPath& value); /** * Interface used to determine whether to include or reject pieces of a * resource bundle based on their absolute path. */ class PathFilter { public: enum EInclusion { INCLUDE, PARTIAL, EXCLUDE }; static const char* kEInclusionNames[]; virtual ~PathFilter(); /** * Returns an EInclusion on whether or not the given path should be included. * * INCLUDE = include the whole subtree * PARTIAL = recurse into the subtree * EXCLUDE = reject the whole subtree */ virtual EInclusion match(const ResKeyPath& path) const = 0; }; /** * Implementation of PathFilter for a list of inclusion/exclusion rules. * * The wildcard pattern "*" means that the subsequent filters are applied to * every other tree sharing the same parent. * * For example, given this list of filter rules: */ // -/alabama // +/alabama/alaska/arizona // -/fornia/hawaii // -/mississippi // +/mississippi/michigan // +/mississippi/*/maine // -/mississippi/*/iowa // +/mississippi/louisiana/iowa /* * You get the following structure: * * SimpleRuleBasedPathFilter { * included: PARTIAL * alabama: { * included: EXCLUDE * alaska: { * included: PARTIAL * arizona: { * included: INCLUDE * } * } * } * fornia: { * included: PARTIAL * hawaii: { * included: EXCLUDE * } * } * mississippi: { * included: EXCLUDE * louisiana: { * included: PARTIAL * iowa: { * included: INCLUDE * } * maine: { * included: INCLUDE * } * } * michigan: { * included: INCLUDE * iowa: { * included: EXCLUDE * } * maine: { * included: INCLUDE * } * } * * { * included: PARTIAL * iowa: { * included: EXCLUDE * } * maine: { * included: INCLUDE * } * } * } * } */ class SimpleRuleBasedPathFilter : public PathFilter { public: void addRule(const std::string& ruleLine, UErrorCode& status); void addRule(const ResKeyPath& path, bool inclusionRule, UErrorCode& status); EInclusion match(const ResKeyPath& path) const override; void print(std::ostream& out) const; private: struct Tree { Tree() = default; /** Copy constructor */ Tree(const Tree& other); /** * Information on the USER-SPECIFIED inclusion/exclusion. * * INCLUDE = this path exactly matches a "+" rule * PARTIAL = this path does not match any rule, but subpaths exist * EXCLUDE = this path exactly matches a "-" rule */ EInclusion fIncluded = PARTIAL; std::map fChildren; std::unique_ptr fWildcard; void applyRule( const ResKeyPath& path, std::list::const_iterator it, bool inclusionRule, UErrorCode& status); bool isLeaf() const; void print(std::ostream& out, int32_t indent) const; }; Tree fRoot; }; std::ostream& operator<<(std::ostream& out, const SimpleRuleBasedPathFilter& value); #endif //__FILTERRB_H__