]>
Commit | Line | Data |
---|---|---|
3d1f044b A |
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__ |