// ----------------------------------------------------------------------- // boilerplate // ----------------------------------------------------------------------- /// <summary> /// Compares two rule sets for equality. /// </summary> /// /// <param name="that">The other rule set</param> /// <returns>true if the two rule sets are functionally equivalent.</returns> public override bool Equals(Object that) { // if different classes, they're not equal if (!(that is NFRuleSet)) { return(false); } else { // otherwise, compare the members one by one... NFRuleSet that2 = (NFRuleSet)that; if (!name.Equals(that2.name) || !IBM.ICU.Impl.Utility.ObjectEquals(negativeNumberRule, that2.negativeNumberRule) || !IBM.ICU.Impl.Utility.ObjectEquals(fractionRules[0], that2.fractionRules[0]) || !IBM.ICU.Impl.Utility.ObjectEquals(fractionRules[1], that2.fractionRules[1]) || !IBM.ICU.Impl.Utility.ObjectEquals(fractionRules[2], that2.fractionRules[2]) || rules.Length != that2.rules.Length || isFractionRuleSet != that2.isFractionRuleSet) { return(false); } // ...then compare the rule lists... for (int i = 0; i < rules.Length; i++) { if (!rules[i].Equals(that2.rules[i])) { return(false); } } // ...and if we make it here, tney're equal return(true); } }
/// <summary> /// Work routine. Post process the output, which was generated by the ruleset /// with the given name. /// </summary> /// public void Process(StringBuilder buf, NFRuleSet ruleSet) { // markers depend on what rule set we are using if (ruleSet != lastRuleSet) { String name = ruleSet.GetName(); for (int i = 0; i < rulesetNames.Length; ++i) { if (rulesetNames[i].Equals(name)) { format = i; longForm = i == 1 || i == 3; break; } } } if (longForm) { for (int i_0 = IBM.ICU.Impl.Utility.IndexOf(buf, "*"); i_0 != -1; i_0 = IBM.ICU.Impl.Utility .IndexOf(buf, "*", i_0)) { buf.Remove(i_0, i_0 + 1 - (i_0)); } return; } String DIAN = "\u9ede"; // decimal point String[][] markers = { new String[] { "\u842c", "\u5104", "\u5146", "\u3007" }, new String[] { "\u4e07", "\u4ebf", "\u5146", "\u3007" }, new String[] { "\u842c", "\u5104", "\u5146", "\u96f6" } }; // remove unwanted lings // a '0' (ling) with * might be removed // mark off 10,000 'chunks', markers are Z, Y, W (zhao, yii, and wan) // already, we avoid two lings in the same chunk -- ling without * wins // now, just need to avoid optional lings in adjacent chunks // process right to left // decision matrix: // state, situation // state none opt. req. // ----- ---- ---- ---- // none to right none opt. req. // opt. to right none clear, none clear right, req. // req. to right none clear, none req. // mark chunks with '|' for convenience { String[] m = markers[format]; for (int i_1 = 0; i_1 < m.Length - 1; ++i_1) { int n = IBM.ICU.Impl.Utility.IndexOf(buf, m[i_1]); if (n != -1) { buf.Insert(n + m[i_1].Length, '|'); } } } int x = IBM.ICU.Impl.Utility.IndexOf(buf, DIAN); if (x == -1) { x = buf.Length; } int s = 0; // 0 = none to right, 1 = opt. to right, 2 = req. to right int n_2 = -1; // previous optional ling String ling = markers[format][3]; while (x >= 0) { int m_3 = IBM.ICU.Impl.Utility.LastIndexOf(buf, "|", x); int nn = IBM.ICU.Impl.Utility.LastIndexOf(buf, ling, x); int ns = 0; if (nn > m_3) { ns = (nn > 0 && buf[nn - 1] != '*') ? 2 : 1; } x = m_3 - 1; // actually much simpler, but leave this verbose for now so it's // easier to follow switch (s * 3 + ns) { case 0: /* none, none */ s = ns; // redundant n_2 = -1; break; case 1: /* none, opt. */ s = ns; n_2 = nn; // remember optional ling to right break; case 2: /* none, req. */ s = ns; n_2 = -1; break; case 3: /* opt., none */ s = ns; n_2 = -1; break; case 4: /* opt., opt. */ buf.Remove(nn - 1, nn + ling.Length - (nn - 1)); // delete current // optional ling s = 0; n_2 = -1; break; case 5: /* opt., req. */ buf.Remove(n_2 - 1, n_2 + ling.Length - (n_2 - 1)); // delete previous // optional ling s = ns; n_2 = -1; break; case 6: /* req., none */ s = ns; n_2 = -1; break; case 7: /* req., opt. */ buf.Remove(nn - 1, nn + ling.Length - (nn - 1)); // delete current // optional ling s = 0; n_2 = -1; break; case 8: /* req., req. */ s = ns; n_2 = -1; break; default: throw new InvalidOperationException(); } } for (int i_4 = buf.Length; --i_4 >= 0;) { char c = buf[i_4]; if (c == '*' || c == '|') { buf.Remove(i_4, i_4 + 1 - (i_4)); } } }