1 // © 2018 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html 3 4 #ifndef __FILTERRB_H__ 5 #define __FILTERRB_H__ 6 7 #include <list> 8 #include <map> 9 #include <memory> 10 #include <ostream> 11 #include <string> 12 13 #include "unicode/utypes.h" 14 15 16 /** 17 * Represents an absolute path into a resource bundle. 18 * For example: "/units/length/meter" 19 */ 20 class ResKeyPath { 21 public: 22 /** Constructs an empty path (top of tree) */ 23 ResKeyPath(); 24 25 /** Constructs from a string path */ 26 ResKeyPath(const std::string& path, UErrorCode& status); 27 28 void push(const std::string& key); 29 void pop(); 30 31 const std::list<std::string>& pieces() const; 32 33 private: 34 std::list<std::string> fPath; 35 }; 36 37 std::ostream& operator<<(std::ostream& out, const ResKeyPath& value); 38 39 40 /** 41 * Interface used to determine whether to include or reject pieces of a 42 * resource bundle based on their absolute path. 43 */ 44 class PathFilter { 45 public: 46 enum EInclusion { 47 INCLUDE, 48 PARTIAL, 49 EXCLUDE 50 }; 51 52 static const char* kEInclusionNames[]; 53 54 virtual ~PathFilter(); 55 56 /** 57 * Returns an EInclusion on whether or not the given path should be included. 58 * 59 * INCLUDE = include the whole subtree 60 * PARTIAL = recurse into the subtree 61 * EXCLUDE = reject the whole subtree 62 */ 63 virtual EInclusion match(const ResKeyPath& path) const = 0; 64 }; 65 66 67 /** 68 * Implementation of PathFilter for a list of inclusion/exclusion rules. 69 * 70 * The wildcard pattern "*" means that the subsequent filters are applied to 71 * every other tree sharing the same parent. 72 * 73 * For example, given this list of filter rules: 74 */ 75 // -/alabama 76 // +/alabama/alaska/arizona 77 // -/fornia/hawaii 78 // -/mississippi 79 // +/mississippi/michigan 80 // +/mississippi/*/maine 81 // -/mississippi/*/iowa 82 // +/mississippi/louisiana/iowa 83 /* 84 * You get the following structure: 85 * 86 * SimpleRuleBasedPathFilter { 87 * included: PARTIAL 88 * alabama: { 89 * included: EXCLUDE 90 * alaska: { 91 * included: PARTIAL 92 * arizona: { 93 * included: INCLUDE 94 * } 95 * } 96 * } 97 * fornia: { 98 * included: PARTIAL 99 * hawaii: { 100 * included: EXCLUDE 101 * } 102 * } 103 * mississippi: { 104 * included: EXCLUDE 105 * louisiana: { 106 * included: PARTIAL 107 * iowa: { 108 * included: INCLUDE 109 * } 110 * maine: { 111 * included: INCLUDE 112 * } 113 * } 114 * michigan: { 115 * included: INCLUDE 116 * iowa: { 117 * included: EXCLUDE 118 * } 119 * maine: { 120 * included: INCLUDE 121 * } 122 * } 123 * * { 124 * included: PARTIAL 125 * iowa: { 126 * included: EXCLUDE 127 * } 128 * maine: { 129 * included: INCLUDE 130 * } 131 * } 132 * } 133 * } 134 */ 135 class SimpleRuleBasedPathFilter : public PathFilter { 136 public: 137 void addRule(const std::string& ruleLine, UErrorCode& status); 138 void addRule(const ResKeyPath& path, bool inclusionRule, UErrorCode& status); 139 140 EInclusion match(const ResKeyPath& path) const override; 141 142 void print(std::ostream& out) const; 143 144 private: 145 struct Tree { 146 147 Tree() = default; 148 149 /** Copy constructor */ 150 Tree(const Tree& other); 151 152 /** 153 * Information on the USER-SPECIFIED inclusion/exclusion. 154 * 155 * INCLUDE = this path exactly matches a "+" rule 156 * PARTIAL = this path does not match any rule, but subpaths exist 157 * EXCLUDE = this path exactly matches a "-" rule 158 */ 159 EInclusion fIncluded = PARTIAL; 160 std::map<std::string, Tree> fChildren; 161 std::unique_ptr<Tree> fWildcard; 162 163 void applyRule( 164 const ResKeyPath& path, 165 std::list<std::string>::const_iterator it, 166 bool inclusionRule, 167 UErrorCode& status); 168 169 bool isLeaf() const; 170 171 void print(std::ostream& out, int32_t indent) const; 172 }; 173 174 Tree fRoot; 175 }; 176 177 std::ostream& operator<<(std::ostream& out, const SimpleRuleBasedPathFilter& value); 178 179 180 #endif //__FILTERRB_H__ 181