REQUIRE_SUCCESS(status);
assertEquals("alabama", alabama.getType(), URES_TABLE);
- ResourceBundle alaska = alabama.get("alaska", status);
- REQUIRE_SUCCESS(status);
- assertEquals("alaska", alaska.getType(), URES_TABLE);
-
- ResourceBundle arizona = alaska.get("arizona", status);
- REQUIRE_SUCCESS(status);
- assertEquals("arizona", arizona.getType(), URES_STRING);
-
- assertEquals("arizona", u"arkansas", arizona.getString(status));
- REQUIRE_SUCCESS(status);
+ {
+ ResourceBundle alaska = alabama.get("alaska", status);
+ REQUIRE_SUCCESS(status);
+ assertEquals("alaska", alaska.getType(), URES_TABLE);
- // Filter: california should not be included
- ResourceBundle california = alaska.get("california", status);
- REQUIRE_ERROR(U_MISSING_RESOURCE_ERROR, status);
+ {
+ ResourceBundle arizona = alaska.get("arizona", status);
+ REQUIRE_SUCCESS(status);
+ assertEquals("arizona", arizona.getType(), URES_STRING);
+ assertEquals("arizona", u"arkansas", arizona.getString(status));
+ REQUIRE_SUCCESS(status);
+
+ // Filter: california should not be included
+ ResourceBundle california = alaska.get("california", status);
+ REQUIRE_ERROR(U_MISSING_RESOURCE_ERROR, status);
+ }
- // Filter: connecticut should not be included
- ResourceBundle connecticut = alabama.get("connecticut", status);
- REQUIRE_ERROR(U_MISSING_RESOURCE_ERROR, status);
+ // Filter: connecticut should not be included
+ ResourceBundle connecticut = alabama.get("connecticut", status);
+ REQUIRE_ERROR(U_MISSING_RESOURCE_ERROR, status);
+ }
ResourceBundle fornia = rb.get("fornia", status);
REQUIRE_SUCCESS(status);
assertEquals("fornia", fornia.getType(), URES_TABLE);
- ResourceBundle hawaii = fornia.get("hawaii", status);
- REQUIRE_SUCCESS(status);
- assertEquals("hawaii", hawaii.getType(), URES_STRING);
+ {
+ ResourceBundle hawaii = fornia.get("hawaii", status);
+ REQUIRE_SUCCESS(status);
+ assertEquals("hawaii", hawaii.getType(), URES_STRING);
+ assertEquals("hawaii", u"idaho", hawaii.getString(status));
+ REQUIRE_SUCCESS(status);
+
+ // Filter: illinois should not be included
+ ResourceBundle illinois = fornia.get("illinois", status);
+ REQUIRE_ERROR(U_MISSING_RESOURCE_ERROR, status);
+ }
- assertEquals("hawaii", u"idaho", hawaii.getString(status));
+ ResourceBundle mississippi = rb.get("mississippi", status);
REQUIRE_SUCCESS(status);
+ assertEquals("mississippi", mississippi.getType(), URES_TABLE);
- // Filter: illinois should not be included
- ResourceBundle illinois = fornia.get("illinois", status);
- REQUIRE_ERROR(U_MISSING_RESOURCE_ERROR, status);
+ {
+ ResourceBundle louisiana = mississippi.get("louisiana", status);
+ REQUIRE_SUCCESS(status);
+ assertEquals("louisiana", louisiana.getType(), URES_TABLE);
+
+ {
+ ResourceBundle maine = louisiana.get("maine", status);
+ REQUIRE_SUCCESS(status);
+ assertEquals("maine", maine.getType(), URES_STRING);
+ assertEquals("maine", u"maryland", maine.getString(status));
+ REQUIRE_SUCCESS(status);
+
+ ResourceBundle iowa = louisiana.get("iowa", status);
+ REQUIRE_SUCCESS(status);
+ assertEquals("iowa", iowa.getType(), URES_STRING);
+ assertEquals("iowa", u"kansas", iowa.getString(status));
+ REQUIRE_SUCCESS(status);
+
+ // Filter: missouri should not be included
+ ResourceBundle missouri = louisiana.get("missouri", status);
+ REQUIRE_ERROR(U_MISSING_RESOURCE_ERROR, status);
+ }
+
+ ResourceBundle michigan = mississippi.get("michigan", status);
+ REQUIRE_SUCCESS(status);
+ assertEquals("michigan", michigan.getType(), URES_TABLE);
+
+ {
+ ResourceBundle maine = michigan.get("maine", status);
+ REQUIRE_SUCCESS(status);
+ assertEquals("maine", maine.getType(), URES_STRING);
+ assertEquals("maine", u"minnesota", maine.getString(status));
+ REQUIRE_SUCCESS(status);
+
+ // Filter: iowa should not be included
+ ResourceBundle iowa = michigan.get("iowa", status);
+ REQUIRE_ERROR(U_MISSING_RESOURCE_ERROR, status);
+
+ ResourceBundle missouri = michigan.get("missouri", status);
+ REQUIRE_SUCCESS(status);
+ assertEquals("missouri", missouri.getType(), URES_STRING);
+ assertEquals("missouri", u"nebraska", missouri.getString(status));
+ REQUIRE_SUCCESS(status);
+ }
+
+ ResourceBundle nevada = mississippi.get("nevada", status);
+ REQUIRE_SUCCESS(status);
+ assertEquals("nevada", nevada.getType(), URES_TABLE);
+
+ {
+ ResourceBundle maine = nevada.get("maine", status);
+ REQUIRE_SUCCESS(status);
+ assertEquals("maine", maine.getType(), URES_STRING);
+ assertEquals("maine", u"new-hampshire", maine.getString(status));
+ REQUIRE_SUCCESS(status);
+
+ // Filter: iowa should not be included
+ ResourceBundle iowa = nevada.get("iowa", status);
+ REQUIRE_ERROR(U_MISSING_RESOURCE_ERROR, status);
+
+ // Filter: missouri should not be included
+ ResourceBundle missouri = nevada.get("missouri", status);
+ REQUIRE_ERROR(U_MISSING_RESOURCE_ERROR, status);
+ }
+ }
}
//eof
if (U_FAILURE(status)) {
return;
}
- Tree* node = &fRoot;
- for (auto& key : path.pieces()) {
- // note: operator[] auto-constructs default values
- node = &node->fChildren[key];
- }
- if (isVerbose() && (node->fIncluded != PARTIAL || !node->fChildren.empty())) {
- std::cout << "genrb info: rule on path " << path
- << " overrides previous rules" << std::endl;
- }
- node->fIncluded = inclusionRule ? INCLUDE : EXCLUDE;
- node->fChildren.clear();
+ fRoot.applyRule(path, path.pieces().begin(), inclusionRule, status);
+
+ // DEBUG TIP: Enable the following line to view the inclusion tree:
+ //print(std::cout);
}
PathFilter::EInclusion SimpleRuleBasedPathFilter::match(const ResKeyPath& path) const {
auto child = node->fChildren.find(key);
// Leaf case 1: input path descends outside the filter tree
if (child == node->fChildren.end()) {
- isLeaf = true;
- break;
+ if (node->fWildcard) {
+ // A wildcard pattern is present; continue checking
+ node = node->fWildcard.get();
+ } else {
+ isLeaf = true;
+ break;
+ }
+ } else {
+ node = &child->second;
}
- node = &child->second;
if (node->fIncluded != PARTIAL) {
defaultResult = node->fIncluded;
}
return node->fIncluded;
}
+
+SimpleRuleBasedPathFilter::Tree::Tree(const Tree& other)
+ : fIncluded(other.fIncluded), fChildren(other.fChildren) {
+ // Note: can't use the default copy assignment because of the std::unique_ptr
+ if (other.fWildcard) {
+ fWildcard.reset(new Tree(*other.fWildcard));
+ }
+}
+
+void SimpleRuleBasedPathFilter::Tree::applyRule(
+ const ResKeyPath& path,
+ std::list<std::string>::const_iterator it,
+ bool inclusionRule,
+ UErrorCode& status) {
+
+ // Base Case
+ if (it == path.pieces().end()) {
+ if (isVerbose() && (fIncluded != PARTIAL || !fChildren.empty())) {
+ std::cout << "genrb info: rule on path " << path
+ << " overrides previous rules" << std::endl;
+ }
+ fIncluded = inclusionRule ? INCLUDE : EXCLUDE;
+ fChildren.clear();
+ fWildcard.reset();
+ return;
+ }
+
+ // Recursive Step
+ auto& key = *it;
+ if (key == "*") {
+ // Case 1: Wildcard
+ if (!fWildcard) {
+ fWildcard.reset(new Tree());
+ }
+ // Apply the rule to fWildcard and also to all existing children.
+ it++;
+ fWildcard->applyRule(path, it, inclusionRule, status);
+ for (auto& child : fChildren) {
+ child.second.applyRule(path, it, inclusionRule, status);
+ }
+ it--;
+
+ } else {
+ // Case 2: Normal Key
+ auto search = fChildren.find(key);
+ if (search == fChildren.end()) {
+ if (fWildcard) {
+ // Deep-copy the existing wildcard tree into the new key
+ search = fChildren.emplace(key, Tree(*fWildcard)).first;
+ } else {
+ search = fChildren.emplace(key, Tree()).first;
+ }
+ }
+ it++;
+ search->second.applyRule(path, it, inclusionRule, status);
+ it--;
+ }
+}
+
void SimpleRuleBasedPathFilter::Tree::print(std::ostream& out, int32_t indent) const {
for (int32_t i=0; i<indent; i++) out << "\t";
out << "included: " << kEInclusionNames[fIncluded] << std::endl;
for (int32_t i=0; i<indent; i++) out << "\t";
out << "}" << std::endl;
}
+ if (fWildcard) {
+ for (int32_t i=0; i<indent; i++) out << "\t";
+ out << "* {" << std::endl;
+ fWildcard->print(out, indent + 1);
+ for (int32_t i=0; i<indent; i++) out << "\t";
+ out << "}" << std::endl;
+ }
}
void SimpleRuleBasedPathFilter::print(std::ostream& out) const {