Exemple #1
0
const NFRule*
NFRuleSet::findDoubleRule(double number) const
{
    // if this is a fraction rule set, use findFractionRuleSetRule()
    if (isFractionRuleSet()) {
        return findFractionRuleSetRule(number);
    }

    if (uprv_isNaN(number)) {
        const NFRule *rule = nonNumericalRules[NAN_RULE_INDEX];
        if (!rule) {
            rule = owner->getDefaultNaNRule();
        }
        return rule;
    }

    // if the number is negative, return the negative number rule
    // (if there isn't a negative-number rule, we pretend it's a
    // positive number)
    if (number < 0) {
        if (nonNumericalRules[NEGATIVE_RULE_INDEX]) {
            return  nonNumericalRules[NEGATIVE_RULE_INDEX];
        } else {
            number = -number;
        }
    }

    if (uprv_isInfinite(number)) {
        const NFRule *rule = nonNumericalRules[INFINITY_RULE_INDEX];
        if (!rule) {
            rule = owner->getDefaultInfinityRule();
        }
        return rule;
    }

    // if the number isn't an integer, we use one of the fraction rules...
    if (number != uprv_floor(number)) {
        // if the number is between 0 and 1, return the proper
        // fraction rule
        if (number < 1 && nonNumericalRules[PROPER_FRACTION_RULE_INDEX]) {
            return nonNumericalRules[PROPER_FRACTION_RULE_INDEX];
        }
        // otherwise, return the improper fraction rule
        else if (nonNumericalRules[IMPROPER_FRACTION_RULE_INDEX]) {
            return nonNumericalRules[IMPROPER_FRACTION_RULE_INDEX];
        }
    }

    // if there's a master rule, use it to format the number
    if (nonNumericalRules[MASTER_RULE_INDEX]) {
        return nonNumericalRules[MASTER_RULE_INDEX];
    }

    // and if we haven't yet returned a rule, use findNormalRule()
    // to find the applicable rule
    int64_t r = util64_fromDouble(number + 0.5);
    return findNormalRule(r);
}
Exemple #2
0
NFRule *
NFRuleSet::findDoubleRule(double number) const
{
	// if this is a fraction rule set, use findFractionRuleSetRule()
	if (isFractionRuleSet())
	{
		return findFractionRuleSetRule(number);
	}

	// if the number is negative, return the negative number rule
	// (if there isn't a negative-number rule, we pretend it's a
	// positive number)
	if (number < 0)
	{
		if (negativeNumberRule)
		{
			return  negativeNumberRule;
		}
		else
		{
			number = -number;
		}
	}

	// if the number isn't an integer, we use one of the fraction rules...
	if (number != uprv_floor(number))
	{
		// if the number is between 0 and 1, return the proper
		// fraction rule
		if (number < 1 && fractionRules[1])
		{
			return fractionRules[1];
		}
		// otherwise, return the improper fraction rule
		else if (fractionRules[0])
		{
			return fractionRules[0];
		}
	}

	// if there's a master rule, use it to format the number
	if (fractionRules[2])
	{
		return fractionRules[2];
	}

	// and if we haven't yet returned a rule, use findNormalRule()
	// to find the applicable rule
	int64_t r = util64_fromDouble(number + 0.5);
	return findNormalRule(r);
}
Exemple #3
0
void
NFRuleSet::parseRules(UnicodeString& description, const RuleBasedNumberFormat* owner, UErrorCode& status)
{
    // start by creating a Vector whose elements are Strings containing
    // the descriptions of the rules (one rule per element).  The rules
    // are separated by semicolons (there's no escape facility: ALL
    // semicolons are rule delimiters)

    if (U_FAILURE(status)) {
        return;
    }

    // ensure we are starting with an empty rule list
    rules.deleteAll();

    // dlf - the original code kept a separate description array for no reason,
    // so I got rid of it.  The loop was too complex so I simplified it.

    UnicodeString currentDescription;
    int32_t oldP = 0;
    while (oldP < description.length()) {
        int32_t p = description.indexOf(gSemicolon, oldP);
        if (p == -1) {
            p = description.length();
        }
        currentDescription.setTo(description, oldP, p - oldP);
        NFRule::makeRules(currentDescription, this, rules.last(), owner, rules, status);
        oldP = p + 1;
    }

    // for rules that didn't specify a base value, their base values
    // were initialized to 0.  Make another pass through the list and
    // set all those rules' base values.  We also remove any special
    // rules from the list and put them into their own member variables
    int64_t defaultBaseValue = 0;

    // (this isn't a for loop because we might be deleting items from
    // the vector-- we want to make sure we only increment i when
    // we _didn't_ delete aything from the vector)
    uint32_t i = 0;
    while (i < rules.size()) {
        NFRule* rule = rules[i];

        switch (rule->getType()) {
            // if the rule's base value is 0, fill in a default
            // base value (this will be 1 plus the preceding
            // rule's base value for regular rule sets, and the
            // same as the preceding rule's base value in fraction
            // rule sets)
        case NFRule::kNoBase:
            rule->setBaseValue(defaultBaseValue, status);
            if (!isFractionRuleSet()) {
                ++defaultBaseValue;
            }
            ++i;
            break;

            // if it's the negative-number rule, copy it into its own
            // data member and delete it from the list
        case NFRule::kNegativeNumberRule:
            if (negativeNumberRule) {
                delete negativeNumberRule;
            }
            negativeNumberRule = rules.remove(i);
            break;

            // if it's the improper fraction rule, copy it into the
            // correct element of fractionRules
        case NFRule::kImproperFractionRule:
            if (fractionRules[0]) {
                delete fractionRules[0];
            }
            fractionRules[0] = rules.remove(i);
            break;

            // if it's the proper fraction rule, copy it into the
            // correct element of fractionRules
        case NFRule::kProperFractionRule:
            if (fractionRules[1]) {
                delete fractionRules[1];
            }
            fractionRules[1] = rules.remove(i);
            break;

            // if it's the master rule, copy it into the
            // correct element of fractionRules
        case NFRule::kMasterRule:
            if (fractionRules[2]) {
                delete fractionRules[2];
            }
            fractionRules[2] = rules.remove(i);
            break;

            // if it's a regular rule that already knows its base value,
            // check to make sure the rules are in order, and update
            // the default base value for the next rule
        default:
            if (rule->getBaseValue() < defaultBaseValue) {
                // throw new IllegalArgumentException("Rules are not in order");
                status = U_PARSE_ERROR;
                return;
            }
            defaultBaseValue = rule->getBaseValue();
            if (!isFractionRuleSet()) {
                ++defaultBaseValue;
            }
            ++i;
            break;
        }
    }
}