diff --git a/icu4c/source/i18n/rbt_set.cpp b/icu4c/source/i18n/rbt_set.cpp index 4d2e6333347..705384bc2fc 100644 --- a/icu4c/source/i18n/rbt_set.cpp +++ b/icu4c/source/i18n/rbt_set.cpp @@ -45,28 +45,36 @@ static void maskingError(const TransliterationRule& rule1, * Construct a new empty rule set. */ TransliterationRuleSet::TransliterationRuleSet(UErrorCode& status) { - maxContextLength = 0; - ruleVector = new UVector(status); - ruleVector->setDeleter(&_deleteRule); + ruleVector = new UVector(&_deleteRule, NULL, status); rules = NULL; + maxContextLength = 0; if (ruleVector == NULL) { status = U_MEMORY_ALLOCATION_ERROR; } } /** - * Copy constructor. We assume that the ruleset being copied - * has already been frozen. + * Copy constructor. */ TransliterationRuleSet::TransliterationRuleSet(const TransliterationRuleSet& other) : ruleVector(0), + rules(0), maxContextLength(other.maxContextLength) { + int32_t i, len; uprv_memcpy(index, other.index, sizeof(index)); - int32_t len = index[256]; // see freeze() - rules = new TransliterationRule*[len]; - for (int32_t i=0; isize(); + for (i=0; iaddElement(new TransliterationRule( + *(TransliterationRule*)other.ruleVector->elementAt(i)), status); + } + } + if (other.rules != 0) { + UParseError p; + freeze(p, status); } } @@ -74,7 +82,7 @@ TransliterationRuleSet::TransliterationRuleSet(const TransliterationRuleSet& oth * Destructor. */ TransliterationRuleSet::~TransliterationRuleSet() { - delete ruleVector; + delete ruleVector; // This deletes the contained rules delete[] rules; } @@ -101,6 +109,9 @@ int32_t TransliterationRuleSet::getMaximumContextLength(void) const { * significant. The last call to this method must be followed by * a call to freeze() before the rule set is used. * + *

If freeze() has already been called, calling addRule() + * unfreezes the rules, and freeze() must be called again. + * * @param adoptedRule the rule to add */ void TransliterationRuleSet::addRule(TransliterationRule* adoptedRule, @@ -116,7 +127,7 @@ void TransliterationRuleSet::addRule(TransliterationRule* adoptedRule, maxContextLength = len; } - delete[] rules; // Contains alias pointers + delete rules; rules = 0; } diff --git a/icu4c/source/i18n/rbt_set.h b/icu4c/source/i18n/rbt_set.h index bc4487e4cda..867eb96c1af 100644 --- a/icu4c/source/i18n/rbt_set.h +++ b/icu4c/source/i18n/rbt_set.h @@ -23,30 +23,34 @@ class UnicodeString; */ class TransliterationRuleSet { /** - * Vector of rules, in the order added. This is only used while the rule - * set is getting built. After that, freeze() reorders and indexes the - * rules into rules[]. However, the vector is kept until destruction. + * Vector of rules, in the order added. This is used while the + * rule set is getting built. After that, freeze() reorders and + * indexes the rules into rules[]. Any given rule is stored once + * in ruleVector, and one or more times in rules[]. ruleVector + * owns and deletes the rules. */ UVector* ruleVector; /** - * Length of the longest preceding context - */ - int32_t maxContextLength; - - /** - * Sorted and indexed table of rules. This is created by freeze() from - * the rules in ruleVector. + * Sorted and indexed table of rules. This is created by freeze() + * from the rules in ruleVector. It contains alias pointers to + * the rules in ruleVector. It is zero before freeze() is called + * and non-zero thereafter. */ TransliterationRule** rules; /** * Index table. For text having a first character c, compute x = c&0xFF. * Now use rules[index[x]..index[x+1]-1]. This index table is created by - * freeze(). + * freeze(). Before freeze() is called it contains garbage. */ int32_t index[257]; + /** + * Length of the longest preceding context + */ + int32_t maxContextLength; + public: /** @@ -80,6 +84,8 @@ public: * Add a rule to this set. Rules are added in order, and order is * significant. The last call to this method must be followed by * a call to freeze() before the rule set is used. + * This method must not be called after freeze() has been + * called. * * @param adoptedRule the rule to add */