/*
******************************************************************************
-* Copyright (C) 1997-2001, International Business Machines
+* Copyright (C) 1997-2004, International Business Machines
* Corporation and others. All Rights Reserved.
******************************************************************************
* file name: nfrs.cpp
#include "cmemory.h"
#endif
-#include "uprops.h"
+#include "util.h"
U_NAMESPACE_BEGIN
, negativeNumberRule(NULL)
, fIsFractionRuleSet(FALSE)
, fIsPublic(FALSE)
+ , fRecursionCount(0)
{
for (int i = 0; i < 3; ++i) {
fractionRules[i] = NULL;
UnicodeString& description = descriptions[index]; // !!! make sure index is valid
+ if (description.length() == 0) {
+ // throw new IllegalArgumentException("Empty rule set description");
+ status = U_PARSE_ERROR;
+ return;
+ }
+
// if the description begins with a rule set name (the rule set
// name can be omitted in formatter descriptions that consist
// of only one rule set), copy it out into our "name" member
description.remove(0, pos);
}
} else {
- name.setTo("%default");
+ name.setTo(UNICODE_STRING_SIMPLE("%default"));
}
if (description.length() == 0) {
// same as the preceding rule's base value in fraction
// rule sets)
case NFRule::kNoBase:
- rule->setBaseValue(defaultBaseValue);
+ rule->setBaseValue(defaultBaseValue, status);
if (!isFractionRuleSet()) {
++defaultBaseValue;
}
delete fractionRules[2];
}
-UBool
+static UBool
util_equalRules(const NFRule* rule1, const NFRule* rule2)
{
if (rule1) {
return FALSE;
}
+#define RECURSION_LIMIT 50
+
void
NFRuleSet::format(int64_t number, UnicodeString& toAppendTo, int32_t pos) const
{
NFRule *rule = findNormalRule(number);
- rule->doFormat(number, toAppendTo, pos);
+ if (rule) { // else error, but can't report it
+ NFRuleSet* ncThis = (NFRuleSet*)this;
+ if (ncThis->fRecursionCount++ >= RECURSION_LIMIT) {
+ // stop recursion
+ ncThis->fRecursionCount = 0;
+ } else {
+ rule->doFormat(number, toAppendTo, pos);
+ ncThis->fRecursionCount--;
+ }
+ }
}
void
NFRuleSet::format(double number, UnicodeString& toAppendTo, int32_t pos) const
{
NFRule *rule = findDoubleRule(number);
- rule->doFormat(number, toAppendTo, pos);
+ if (rule) { // else error, but can't report it
+ NFRuleSet* ncThis = (NFRuleSet*)this;
+ if (ncThis->fRecursionCount++ >= RECURSION_LIMIT) {
+ // stop recursion
+ ncThis->fRecursionCount = 0;
+ } else {
+ rule->doFormat(number, toAppendTo, pos);
+ ncThis->fRecursionCount--;
+ }
+ }
}
NFRule*
lo = mid + 1;
}
}
+ if (hi == 0) { // bad rule set, minimum base > 0
+ return NULL; // want to throw exception here
+ }
+
NFRule *result = rules[hi - 1];
// use shouldRollBack() to see whether we need to invoke the
// one rule and return that one instead of the one we'd normally
// return
if (result->shouldRollBack((double)number)) {
+ if (hi == 1) { // bad rule set, no prior rule to rollback to from this base
+ return NULL;
+ }
result = rules[hi - 2];
}
return result;