Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(281)

Side by Side Diff: source/i18n/nfsubs.cpp

Issue 1621843002: ICU 56 update step 1 (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/icu.git@561
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « source/i18n/nfsubs.h ('k') | source/i18n/numfmt.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 ****************************************************************************** 2 ******************************************************************************
3 * Copyright (C) 1997-2014, International Business Machines 3 * Copyright (C) 1997-2015, International Business Machines
4 * Corporation and others. All Rights Reserved. 4 * Corporation and others. All Rights Reserved.
5 ****************************************************************************** 5 ******************************************************************************
6 * file name: nfsubs.cpp 6 * file name: nfsubs.cpp
7 * encoding: US-ASCII 7 * encoding: US-ASCII
8 * tab size: 8 (not used) 8 * tab size: 8 (not used)
9 * indentation:4 9 * indentation:4
10 * 10 *
11 * Modification history 11 * Modification history
12 * Date Name Comments 12 * Date Name Comments
13 * 10/11/2001 Doug Ported from ICU4J 13 * 10/11/2001 Doug Ported from ICU4J
(...skipping 27 matching lines...) Expand all
41 { 41 {
42 0x3E, 0x3E, 0 42 0x3E, 0x3E, 0
43 }; /* ">>" */ 43 }; /* ">>" */
44 44
45 U_NAMESPACE_BEGIN 45 U_NAMESPACE_BEGIN
46 46
47 class SameValueSubstitution : public NFSubstitution { 47 class SameValueSubstitution : public NFSubstitution {
48 public: 48 public:
49 SameValueSubstitution(int32_t pos, 49 SameValueSubstitution(int32_t pos,
50 const NFRuleSet* ruleset, 50 const NFRuleSet* ruleset,
51 const RuleBasedNumberFormat* formatter,
52 const UnicodeString& description, 51 const UnicodeString& description,
53 UErrorCode& status); 52 UErrorCode& status);
54 virtual ~SameValueSubstitution(); 53 virtual ~SameValueSubstitution();
55 54
56 virtual int64_t transformNumber(int64_t number) const { return number; } 55 virtual int64_t transformNumber(int64_t number) const { return number; }
57 virtual double transformNumber(double number) const { return number; } 56 virtual double transformNumber(double number) const { return number; }
58 virtual double composeRuleValue(double newRuleValue, double /*oldRuleValue*/ ) const { return newRuleValue; } 57 virtual double composeRuleValue(double newRuleValue, double /*oldRuleValue*/ ) const { return newRuleValue; }
59 virtual double calcUpperBound(double oldUpperBound) const { return oldUpperB ound; } 58 virtual double calcUpperBound(double oldUpperBound) const { return oldUpperB ound; }
60 virtual UChar tokenChar() const { return (UChar)0x003d; } // '=' 59 virtual UChar tokenChar() const { return (UChar)0x003d; } // '='
61 60
62 public: 61 public:
63 static UClassID getStaticClassID(void); 62 static UClassID getStaticClassID(void);
64 virtual UClassID getDynamicClassID(void) const; 63 virtual UClassID getDynamicClassID(void) const;
65 }; 64 };
66 65
67 SameValueSubstitution::~SameValueSubstitution() {} 66 SameValueSubstitution::~SameValueSubstitution() {}
68 67
69 class MultiplierSubstitution : public NFSubstitution { 68 class MultiplierSubstitution : public NFSubstitution {
70 double divisor; 69 double divisor;
71 int64_t ldivisor; 70 int64_t ldivisor;
72 71
73 public: 72 public:
74 MultiplierSubstitution(int32_t _pos, 73 MultiplierSubstitution(int32_t _pos,
75 double _divisor, 74 double _divisor,
76 const NFRuleSet* _ruleSet, 75 const NFRuleSet* _ruleSet,
77 const RuleBasedNumberFormat* formatter,
78 const UnicodeString& description, 76 const UnicodeString& description,
79 UErrorCode& status) 77 UErrorCode& status)
80 : NFSubstitution(_pos, _ruleSet, formatter, description, status), diviso r(_divisor) 78 : NFSubstitution(_pos, _ruleSet, description, status), divisor(_divisor)
81 { 79 {
82 ldivisor = util64_fromDouble(divisor); 80 ldivisor = util64_fromDouble(divisor);
83 if (divisor == 0) { 81 if (divisor == 0) {
84 status = U_PARSE_ERROR; 82 status = U_PARSE_ERROR;
85 } 83 }
86 } 84 }
87 virtual ~MultiplierSubstitution(); 85 virtual ~MultiplierSubstitution();
88 86
89 virtual void setDivisor(int32_t radix, int32_t exponent, UErrorCode& status) { 87 virtual void setDivisor(int32_t radix, int32_t exponent, UErrorCode& status) {
90 divisor = uprv_pow(radix, exponent); 88 divisor = uprv_pow(radix, exponent);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 124
127 class ModulusSubstitution : public NFSubstitution { 125 class ModulusSubstitution : public NFSubstitution {
128 double divisor; 126 double divisor;
129 int64_t ldivisor; 127 int64_t ldivisor;
130 const NFRule* ruleToUse; 128 const NFRule* ruleToUse;
131 public: 129 public:
132 ModulusSubstitution(int32_t pos, 130 ModulusSubstitution(int32_t pos,
133 double _divisor, 131 double _divisor,
134 const NFRule* rulePredecessor, 132 const NFRule* rulePredecessor,
135 const NFRuleSet* ruleSet, 133 const NFRuleSet* ruleSet,
136 const RuleBasedNumberFormat* formatter,
137 const UnicodeString& description, 134 const UnicodeString& description,
138 UErrorCode& status); 135 UErrorCode& status);
139 virtual ~ModulusSubstitution(); 136 virtual ~ModulusSubstitution();
140 137
141 virtual void setDivisor(int32_t radix, int32_t exponent, UErrorCode& status) { 138 virtual void setDivisor(int32_t radix, int32_t exponent, UErrorCode& status) {
142 divisor = uprv_pow(radix, exponent); 139 divisor = uprv_pow(radix, exponent);
143 ldivisor = util64_fromDouble(divisor); 140 ldivisor = util64_fromDouble(divisor);
144 141
145 if (divisor == 0) { 142 if (divisor == 0) {
146 status = U_PARSE_ERROR; 143 status = U_PARSE_ERROR;
147 } 144 }
148 } 145 }
149 146
150 virtual UBool operator==(const NFSubstitution& rhs) const; 147 virtual UBool operator==(const NFSubstitution& rhs) const;
151 148
152 virtual void doSubstitution(int64_t number, UnicodeString& toInsertInto, int 32_t pos, UErrorCode& status) const; 149 virtual void doSubstitution(int64_t number, UnicodeString& toInsertInto, int 32_t pos, int32_t recursionCount, UErrorCode& status) const;
153 virtual void doSubstitution(double number, UnicodeString& toInsertInto, int3 2_t pos, UErrorCode& status) const; 150 virtual void doSubstitution(double number, UnicodeString& toInsertInto, int3 2_t pos, int32_t recursionCount, UErrorCode& status) const;
154 151
155 virtual int64_t transformNumber(int64_t number) const { return number % ldiv isor; } 152 virtual int64_t transformNumber(int64_t number) const { return number % ldiv isor; }
156 virtual double transformNumber(double number) const { return uprv_fmod(numbe r, divisor); } 153 virtual double transformNumber(double number) const { return uprv_fmod(numbe r, divisor); }
157 154
158 virtual UBool doParse(const UnicodeString& text, 155 virtual UBool doParse(const UnicodeString& text,
159 ParsePosition& parsePosition, 156 ParsePosition& parsePosition,
160 double baseValue, 157 double baseValue,
161 double upperBound, 158 double upperBound,
162 UBool lenientParse, 159 UBool lenientParse,
163 Formattable& result) const; 160 Formattable& result) const;
(...skipping 14 matching lines...) Expand all
178 static UClassID getStaticClassID(void); 175 static UClassID getStaticClassID(void);
179 virtual UClassID getDynamicClassID(void) const; 176 virtual UClassID getDynamicClassID(void) const;
180 }; 177 };
181 178
182 ModulusSubstitution::~ModulusSubstitution() {} 179 ModulusSubstitution::~ModulusSubstitution() {}
183 180
184 class IntegralPartSubstitution : public NFSubstitution { 181 class IntegralPartSubstitution : public NFSubstitution {
185 public: 182 public:
186 IntegralPartSubstitution(int32_t _pos, 183 IntegralPartSubstitution(int32_t _pos,
187 const NFRuleSet* _ruleSet, 184 const NFRuleSet* _ruleSet,
188 const RuleBasedNumberFormat* formatter,
189 const UnicodeString& description, 185 const UnicodeString& description,
190 UErrorCode& status) 186 UErrorCode& status)
191 : NFSubstitution(_pos, _ruleSet, formatter, description, status) {} 187 : NFSubstitution(_pos, _ruleSet, description, status) {}
192 virtual ~IntegralPartSubstitution(); 188 virtual ~IntegralPartSubstitution();
193 189
194 virtual int64_t transformNumber(int64_t number) const { return number; } 190 virtual int64_t transformNumber(int64_t number) const { return number; }
195 virtual double transformNumber(double number) const { return uprv_floor(numb er); } 191 virtual double transformNumber(double number) const { return uprv_floor(numb er); }
196 virtual double composeRuleValue(double newRuleValue, double oldRuleValue) co nst { return newRuleValue + oldRuleValue; } 192 virtual double composeRuleValue(double newRuleValue, double oldRuleValue) co nst { return newRuleValue + oldRuleValue; }
197 virtual double calcUpperBound(double /*oldUpperBound*/) const { return DBL_M AX; } 193 virtual double calcUpperBound(double /*oldUpperBound*/) const { return DBL_M AX; }
198 virtual UChar tokenChar() const { return (UChar)0x003c; } // '<' 194 virtual UChar tokenChar() const { return (UChar)0x003c; } // '<'
199 195
200 public: 196 public:
201 static UClassID getStaticClassID(void); 197 static UClassID getStaticClassID(void);
202 virtual UClassID getDynamicClassID(void) const; 198 virtual UClassID getDynamicClassID(void) const;
203 }; 199 };
204 200
205 IntegralPartSubstitution::~IntegralPartSubstitution() {} 201 IntegralPartSubstitution::~IntegralPartSubstitution() {}
206 202
207 class FractionalPartSubstitution : public NFSubstitution { 203 class FractionalPartSubstitution : public NFSubstitution {
208 UBool byDigits; 204 UBool byDigits;
209 UBool useSpaces; 205 UBool useSpaces;
210 enum { kMaxDecimalDigits = 8 }; 206 enum { kMaxDecimalDigits = 8 };
211 public: 207 public:
212 FractionalPartSubstitution(int32_t pos, 208 FractionalPartSubstitution(int32_t pos,
213 const NFRuleSet* ruleSet, 209 const NFRuleSet* ruleSet,
214 const RuleBasedNumberFormat* formatter,
215 const UnicodeString& description, 210 const UnicodeString& description,
216 UErrorCode& status); 211 UErrorCode& status);
217 virtual ~FractionalPartSubstitution(); 212 virtual ~FractionalPartSubstitution();
218 213
219 virtual UBool operator==(const NFSubstitution& rhs) const; 214 virtual UBool operator==(const NFSubstitution& rhs) const;
220 215
221 virtual void doSubstitution(double number, UnicodeString& toInsertInto, int3 2_t pos, UErrorCode& status) const; 216 virtual void doSubstitution(double number, UnicodeString& toInsertInto, int3 2_t pos, int32_t recursionCount, UErrorCode& status) const;
222 virtual void doSubstitution(int64_t /*number*/, UnicodeString& /*toInsertInt o*/, int32_t /*_pos*/, UErrorCode& /*status*/) const {} 217 virtual void doSubstitution(int64_t /*number*/, UnicodeString& /*toInsertInt o*/, int32_t /*_pos*/, int32_t /*recursionCount*/, UErrorCode& /*status*/) const {}
223 virtual int64_t transformNumber(int64_t /*number*/) const { return 0; } 218 virtual int64_t transformNumber(int64_t /*number*/) const { return 0; }
224 virtual double transformNumber(double number) const { return number - uprv_f loor(number); } 219 virtual double transformNumber(double number) const { return number - uprv_f loor(number); }
225 220
226 virtual UBool doParse(const UnicodeString& text, 221 virtual UBool doParse(const UnicodeString& text,
227 ParsePosition& parsePosition, 222 ParsePosition& parsePosition,
228 double baseValue, 223 double baseValue,
229 double upperBound, 224 double upperBound,
230 UBool lenientParse, 225 UBool lenientParse,
231 Formattable& result) const; 226 Formattable& result) const;
232 227
233 virtual double composeRuleValue(double newRuleValue, double oldRuleValue) co nst { return newRuleValue + oldRuleValue; } 228 virtual double composeRuleValue(double newRuleValue, double oldRuleValue) co nst { return newRuleValue + oldRuleValue; }
234 virtual double calcUpperBound(double /*oldUpperBound*/) const { return 0.0; } 229 virtual double calcUpperBound(double /*oldUpperBound*/) const { return 0.0; }
235 virtual UChar tokenChar() const { return (UChar)0x003e; } // '>' 230 virtual UChar tokenChar() const { return (UChar)0x003e; } // '>'
236 231
237 public: 232 public:
238 static UClassID getStaticClassID(void); 233 static UClassID getStaticClassID(void);
239 virtual UClassID getDynamicClassID(void) const; 234 virtual UClassID getDynamicClassID(void) const;
240 }; 235 };
241 236
242 FractionalPartSubstitution::~FractionalPartSubstitution() {} 237 FractionalPartSubstitution::~FractionalPartSubstitution() {}
243 238
244 class AbsoluteValueSubstitution : public NFSubstitution { 239 class AbsoluteValueSubstitution : public NFSubstitution {
245 public: 240 public:
246 AbsoluteValueSubstitution(int32_t _pos, 241 AbsoluteValueSubstitution(int32_t _pos,
247 const NFRuleSet* _ruleSet, 242 const NFRuleSet* _ruleSet,
248 const RuleBasedNumberFormat* formatter,
249 const UnicodeString& description, 243 const UnicodeString& description,
250 UErrorCode& status) 244 UErrorCode& status)
251 : NFSubstitution(_pos, _ruleSet, formatter, description, status) {} 245 : NFSubstitution(_pos, _ruleSet, description, status) {}
252 virtual ~AbsoluteValueSubstitution(); 246 virtual ~AbsoluteValueSubstitution();
253 247
254 virtual int64_t transformNumber(int64_t number) const { return number >= 0 ? number : -number; } 248 virtual int64_t transformNumber(int64_t number) const { return number >= 0 ? number : -number; }
255 virtual double transformNumber(double number) const { return uprv_fabs(numbe r); } 249 virtual double transformNumber(double number) const { return uprv_fabs(numbe r); }
256 virtual double composeRuleValue(double newRuleValue, double /*oldRuleValue*/ ) const { return -newRuleValue; } 250 virtual double composeRuleValue(double newRuleValue, double /*oldRuleValue*/ ) const { return -newRuleValue; }
257 virtual double calcUpperBound(double /*oldUpperBound*/) const { return DBL_M AX; } 251 virtual double calcUpperBound(double /*oldUpperBound*/) const { return DBL_M AX; }
258 virtual UChar tokenChar() const { return (UChar)0x003e; } // '>' 252 virtual UChar tokenChar() const { return (UChar)0x003e; } // '>'
259 253
260 public: 254 public:
261 static UClassID getStaticClassID(void); 255 static UClassID getStaticClassID(void);
262 virtual UClassID getDynamicClassID(void) const; 256 virtual UClassID getDynamicClassID(void) const;
263 }; 257 };
264 258
265 AbsoluteValueSubstitution::~AbsoluteValueSubstitution() {} 259 AbsoluteValueSubstitution::~AbsoluteValueSubstitution() {}
266 260
267 class NumeratorSubstitution : public NFSubstitution { 261 class NumeratorSubstitution : public NFSubstitution {
268 double denominator; 262 double denominator;
269 int64_t ldenominator; 263 int64_t ldenominator;
270 UBool withZeros; 264 UBool withZeros;
271 public: 265 public:
272 static inline UnicodeString fixdesc(const UnicodeString& desc) { 266 static inline UnicodeString fixdesc(const UnicodeString& desc) {
273 if (desc.endsWith(LTLT, 2)) { 267 if (desc.endsWith(LTLT, 2)) {
274 UnicodeString result(desc, 0, desc.length()-1); 268 UnicodeString result(desc, 0, desc.length()-1);
275 return result; 269 return result;
276 } 270 }
277 return desc; 271 return desc;
278 } 272 }
279 NumeratorSubstitution(int32_t _pos, 273 NumeratorSubstitution(int32_t _pos,
280 double _denominator, 274 double _denominator,
281 const NFRuleSet* _ruleSet, 275 NFRuleSet* _ruleSet,
282 const RuleBasedNumberFormat* formatter,
283 const UnicodeString& description, 276 const UnicodeString& description,
284 UErrorCode& status) 277 UErrorCode& status)
285 : NFSubstitution(_pos, _ruleSet, formatter, fixdesc(description), status ), denominator(_denominator) 278 : NFSubstitution(_pos, _ruleSet, fixdesc(description), status), denomina tor(_denominator)
286 { 279 {
287 ldenominator = util64_fromDouble(denominator); 280 ldenominator = util64_fromDouble(denominator);
288 withZeros = description.endsWith(LTLT, 2); 281 withZeros = description.endsWith(LTLT, 2);
289 } 282 }
290 virtual ~NumeratorSubstitution(); 283 virtual ~NumeratorSubstitution();
291 284
292 virtual UBool operator==(const NFSubstitution& rhs) const; 285 virtual UBool operator==(const NFSubstitution& rhs) const;
293 286
294 virtual int64_t transformNumber(int64_t number) const { return number * lden ominator; } 287 virtual int64_t transformNumber(int64_t number) const { return number * lden ominator; }
295 virtual double transformNumber(double number) const { return uprv_round(numb er * denominator); } 288 virtual double transformNumber(double number) const { return uprv_round(numb er * denominator); }
296 289
297 virtual void doSubstitution(int64_t /*number*/, UnicodeString& /*toInsertInt o*/, int32_t /*_pos*/, UErrorCode& /*status*/) const {} 290 virtual void doSubstitution(int64_t /*number*/, UnicodeString& /*toInsertInt o*/, int32_t /*_pos*/, int32_t /*recursionCount*/, UErrorCode& /*status*/) const {}
298 virtual void doSubstitution(double number, UnicodeString& toInsertInto, int3 2_t pos, UErrorCode& status) const; 291 virtual void doSubstitution(double number, UnicodeString& toInsertInto, int3 2_t pos, int32_t recursionCount, UErrorCode& status) const;
299 virtual UBool doParse(const UnicodeString& text, 292 virtual UBool doParse(const UnicodeString& text,
300 ParsePosition& parsePosition, 293 ParsePosition& parsePosition,
301 double baseValue, 294 double baseValue,
302 double upperBound, 295 double upperBound,
303 UBool /*lenientParse*/, 296 UBool /*lenientParse*/,
304 Formattable& result) const; 297 Formattable& result) const;
305 298
306 virtual double composeRuleValue(double newRuleValue, double oldRuleValue) co nst { return newRuleValue / oldRuleValue; } 299 virtual double composeRuleValue(double newRuleValue, double oldRuleValue) co nst { return newRuleValue / oldRuleValue; }
307 virtual double calcUpperBound(double /*oldUpperBound*/) const { return denom inator; } 300 virtual double calcUpperBound(double /*oldUpperBound*/) const { return denom inator; }
308 virtual UChar tokenChar() const { return (UChar)0x003c; } // '<' 301 virtual UChar tokenChar() const { return (UChar)0x003c; } // '<'
309 private: 302 private:
310 static const UChar LTLT[2]; 303 static const UChar LTLT[2];
311 304
312 public: 305 public:
313 static UClassID getStaticClassID(void); 306 static UClassID getStaticClassID(void);
314 virtual UClassID getDynamicClassID(void) const; 307 virtual UClassID getDynamicClassID(void) const;
315 }; 308 };
316 309
317 NumeratorSubstitution::~NumeratorSubstitution() {} 310 NumeratorSubstitution::~NumeratorSubstitution() {}
318 311
319 class NullSubstitution : public NFSubstitution {
320 public:
321 NullSubstitution(int32_t _pos,
322 const NFRuleSet* _ruleSet,
323 const RuleBasedNumberFormat* formatter,
324 const UnicodeString& description,
325 UErrorCode& status)
326 : NFSubstitution(_pos, _ruleSet, formatter, description, status) {}
327 virtual ~NullSubstitution();
328
329 virtual void toString(UnicodeString& /*result*/) const {}
330 virtual void doSubstitution(double /*number*/, UnicodeString& /*toInsertInto */, int32_t /*_pos*/, UErrorCode& /*status*/) const {}
331 virtual void doSubstitution(int64_t /*number*/, UnicodeString& /*toInsertInt o*/, int32_t /*_pos*/, UErrorCode& /*status*/) const {}
332 virtual int64_t transformNumber(int64_t /*number*/) const { return 0; }
333 virtual double transformNumber(double /*number*/) const { return 0; }
334 virtual UBool doParse(const UnicodeString& /*text*/,
335 ParsePosition& /*parsePosition*/,
336 double baseValue,
337 double /*upperBound*/,
338 UBool /*lenientParse*/,
339 Formattable& result) const
340 { result.setDouble(baseValue); return TRUE; }
341 virtual double composeRuleValue(double /*newRuleValue*/, double /*oldRuleVal ue*/) const { return 0.0; } // never called
342 virtual double calcUpperBound(double /*oldUpperBound*/) const { return 0; } // never called
343 virtual UBool isNullSubstitution() const { return TRUE; }
344 virtual UChar tokenChar() const { return (UChar)0x0020; } // ' ' never calle d
345
346 public:
347 static UClassID getStaticClassID(void);
348 virtual UClassID getDynamicClassID(void) const;
349 };
350
351 NullSubstitution::~NullSubstitution() {}
352
353 NFSubstitution* 312 NFSubstitution*
354 NFSubstitution::makeSubstitution(int32_t pos, 313 NFSubstitution::makeSubstitution(int32_t pos,
355 const NFRule* rule, 314 const NFRule* rule,
356 const NFRule* predecessor, 315 const NFRule* predecessor,
357 const NFRuleSet* ruleSet, 316 const NFRuleSet* ruleSet,
358 const RuleBasedNumberFormat* formatter, 317 const RuleBasedNumberFormat* formatter,
359 const UnicodeString& description, 318 const UnicodeString& description,
360 UErrorCode& status) 319 UErrorCode& status)
361 { 320 {
362 // if the description is empty, return a NullSubstitution 321 // if the description is empty, return a NullSubstitution
363 if (description.length() == 0) { 322 if (description.length() == 0) {
364 return new NullSubstitution(pos, ruleSet, formatter, description, status ); 323 return NULL;
365 } 324 }
366 325
367 switch (description.charAt(0)) { 326 switch (description.charAt(0)) {
368 // if the description begins with '<'... 327 // if the description begins with '<'...
369 case gLessThan: 328 case gLessThan:
370 // throw an exception if the rule is a negative number 329 // throw an exception if the rule is a negative number
371 // rule 330 // rule
372 if (rule->getBaseValue() == NFRule::kNegativeNumberRule) { 331 if (rule->getBaseValue() == NFRule::kNegativeNumberRule) {
373 // throw new IllegalArgumentException("<< not allowed in negative-nu mber rule"); 332 // throw new IllegalArgumentException("<< not allowed in negative-nu mber rule");
374 status = U_PARSE_ERROR; 333 status = U_PARSE_ERROR;
375 return NULL; 334 return NULL;
376 } 335 }
377 336
378 // if the rule is a fraction rule, return an 337 // if the rule is a fraction rule, return an
379 // IntegralPartSubstitution 338 // IntegralPartSubstitution
380 else if (rule->getBaseValue() == NFRule::kImproperFractionRule 339 else if (rule->getBaseValue() == NFRule::kImproperFractionRule
381 || rule->getBaseValue() == NFRule::kProperFractionRule 340 || rule->getBaseValue() == NFRule::kProperFractionRule
382 || rule->getBaseValue() == NFRule::kMasterRule) { 341 || rule->getBaseValue() == NFRule::kMasterRule) {
383 return new IntegralPartSubstitution(pos, ruleSet, formatter, descrip tion, status); 342 return new IntegralPartSubstitution(pos, ruleSet, description, statu s);
384 } 343 }
385 344
386 // if the rule set containing the rule is a fraction 345 // if the rule set containing the rule is a fraction
387 // rule set, return a NumeratorSubstitution 346 // rule set, return a NumeratorSubstitution
388 else if (ruleSet->isFractionRuleSet()) { 347 else if (ruleSet->isFractionRuleSet()) {
389 return new NumeratorSubstitution(pos, (double)rule->getBaseValue(), 348 return new NumeratorSubstitution(pos, (double)rule->getBaseValue(),
390 formatter->getDefaultRuleSet(), formatter, description, status); 349 formatter->getDefaultRuleSet(), description, status);
391 } 350 }
392 351
393 // otherwise, return a MultiplierSubstitution 352 // otherwise, return a MultiplierSubstitution
394 else { 353 else {
395 return new MultiplierSubstitution(pos, rule->getDivisor(), ruleSet, 354 return new MultiplierSubstitution(pos, rule->getDivisor(), ruleSet,
396 formatter, description, status); 355 description, status);
397 } 356 }
398 357
399 // if the description begins with '>'... 358 // if the description begins with '>'...
400 case gGreaterThan: 359 case gGreaterThan:
401 // if the rule is a negative-number rule, return 360 // if the rule is a negative-number rule, return
402 // an AbsoluteValueSubstitution 361 // an AbsoluteValueSubstitution
403 if (rule->getBaseValue() == NFRule::kNegativeNumberRule) { 362 if (rule->getBaseValue() == NFRule::kNegativeNumberRule) {
404 return new AbsoluteValueSubstitution(pos, ruleSet, formatter, descri ption, status); 363 return new AbsoluteValueSubstitution(pos, ruleSet, description, stat us);
405 } 364 }
406 365
407 // if the rule is a fraction rule, return a 366 // if the rule is a fraction rule, return a
408 // FractionalPartSubstitution 367 // FractionalPartSubstitution
409 else if (rule->getBaseValue() == NFRule::kImproperFractionRule 368 else if (rule->getBaseValue() == NFRule::kImproperFractionRule
410 || rule->getBaseValue() == NFRule::kProperFractionRule 369 || rule->getBaseValue() == NFRule::kProperFractionRule
411 || rule->getBaseValue() == NFRule::kMasterRule) { 370 || rule->getBaseValue() == NFRule::kMasterRule) {
412 return new FractionalPartSubstitution(pos, ruleSet, formatter, descr iption, status); 371 return new FractionalPartSubstitution(pos, ruleSet, description, sta tus);
413 } 372 }
414 373
415 // if the rule set owning the rule is a fraction rule set, 374 // if the rule set owning the rule is a fraction rule set,
416 // throw an exception 375 // throw an exception
417 else if (ruleSet->isFractionRuleSet()) { 376 else if (ruleSet->isFractionRuleSet()) {
418 // throw new IllegalArgumentException(">> not allowed in fraction ru le set"); 377 // throw new IllegalArgumentException(">> not allowed in fraction ru le set");
419 status = U_PARSE_ERROR; 378 status = U_PARSE_ERROR;
420 return NULL; 379 return NULL;
421 } 380 }
422 381
423 // otherwise, return a ModulusSubstitution 382 // otherwise, return a ModulusSubstitution
424 else { 383 else {
425 return new ModulusSubstitution(pos, rule->getDivisor(), predecessor, 384 return new ModulusSubstitution(pos, rule->getDivisor(), predecessor,
426 ruleSet, formatter, description, status); 385 ruleSet, description, status);
427 } 386 }
428 387
429 // if the description begins with '=', always return a 388 // if the description begins with '=', always return a
430 // SameValueSubstitution 389 // SameValueSubstitution
431 case gEquals: 390 case gEquals:
432 return new SameValueSubstitution(pos, ruleSet, formatter, description, s tatus); 391 return new SameValueSubstitution(pos, ruleSet, description, status);
433 392
434 // and if it's anything else, throw an exception 393 // and if it's anything else, throw an exception
435 default: 394 default:
436 // throw new IllegalArgumentException("Illegal substitution character"); 395 // throw new IllegalArgumentException("Illegal substitution character");
437 status = U_PARSE_ERROR; 396 status = U_PARSE_ERROR;
438 } 397 }
439 return NULL; 398 return NULL;
440 } 399 }
441 400
442 NFSubstitution::NFSubstitution(int32_t _pos, 401 NFSubstitution::NFSubstitution(int32_t _pos,
443 const NFRuleSet* _ruleSet, 402 const NFRuleSet* _ruleSet,
444 const RuleBasedNumberFormat* formatter,
445 const UnicodeString& description, 403 const UnicodeString& description,
446 UErrorCode& status) 404 UErrorCode& status)
447 : pos(_pos), ruleSet(NULL), numberFormat(NULL) 405 : pos(_pos), ruleSet(NULL), numberFormat(NULL)
448 { 406 {
449 // the description should begin and end with the same character. 407 // the description should begin and end with the same character.
450 // If it doesn't that's a syntax error. Otherwise, 408 // If it doesn't that's a syntax error. Otherwise,
451 // makeSubstitution() was the only thing that needed to know 409 // makeSubstitution() was the only thing that needed to know
452 // about these characters, so strip them off 410 // about these characters, so strip them off
453 UnicodeString workingDescription(description); 411 UnicodeString workingDescription(description);
454 if (description.length() >= 2 412 if (description.length() >= 2
455 && description.charAt(0) == description.charAt(description.length() - 1) ) 413 && description.charAt(0) == description.charAt(description.length() - 1) )
456 { 414 {
457 workingDescription.remove(description.length() - 1, 1); 415 workingDescription.remove(description.length() - 1, 1);
458 workingDescription.remove(0, 1); 416 workingDescription.remove(0, 1);
459 } 417 }
460 else if (description.length() != 0) { 418 else if (description.length() != 0) {
461 // throw new IllegalArgumentException("Illegal substitution syntax"); 419 // throw new IllegalArgumentException("Illegal substitution syntax");
462 status = U_PARSE_ERROR; 420 status = U_PARSE_ERROR;
463 return; 421 return;
464 } 422 }
465 423
466 // if the description was just two paired token characters
467 // (i.e., "<<" or ">>"), it uses the rule set it belongs to to
468 // format its result
469 if (workingDescription.length() == 0) { 424 if (workingDescription.length() == 0) {
425 // if the description was just two paired token characters
426 // (i.e., "<<" or ">>"), it uses the rule set it belongs to to
427 // format its result
470 this->ruleSet = _ruleSet; 428 this->ruleSet = _ruleSet;
471 } 429 }
472 // if the description contains a rule set name, that's the rule
473 // set we use to format the result: get a reference to the
474 // names rule set
475 else if (workingDescription.charAt(0) == gPercent) { 430 else if (workingDescription.charAt(0) == gPercent) {
476 this->ruleSet = formatter->findRuleSet(workingDescription, status); 431 // if the description contains a rule set name, that's the rule
432 // set we use to format the result: get a reference to the
433 // names rule set
434 this->ruleSet = _ruleSet->getOwner()->findRuleSet(workingDescription, st atus);
477 } 435 }
478 // if the description begins with 0 or #, treat it as a
479 // DecimalFormat pattern, and initialize a DecimalFormat with
480 // that pattern (then set it to use the DecimalFormatSymbols
481 // belonging to our formatter)
482 else if (workingDescription.charAt(0) == gPound || workingDescription.charAt (0) ==gZero) { 436 else if (workingDescription.charAt(0) == gPound || workingDescription.charAt (0) ==gZero) {
483 DecimalFormatSymbols* sym = formatter->getDecimalFormatSymbols(); 437 // if the description begins with 0 or #, treat it as a
438 // DecimalFormat pattern, and initialize a DecimalFormat with
439 // that pattern (then set it to use the DecimalFormatSymbols
440 // belonging to our formatter)
441 const DecimalFormatSymbols* sym = _ruleSet->getOwner()->getDecimalFormat Symbols();
484 if (!sym) { 442 if (!sym) {
485 status = U_MISSING_RESOURCE_ERROR; 443 status = U_MISSING_RESOURCE_ERROR;
486 return; 444 return;
487 } 445 }
488 this->numberFormat = new DecimalFormat(workingDescription, *sym, status) ; 446 DecimalFormat *tempNumberFormat = new DecimalFormat(workingDescription, *sym, status);
489 /* test for NULL */ 447 /* test for NULL */
490 if (this->numberFormat == 0) { 448 if (!tempNumberFormat) {
491 status = U_MEMORY_ALLOCATION_ERROR; 449 status = U_MEMORY_ALLOCATION_ERROR;
492 return; 450 return;
493 } 451 }
494 if (U_FAILURE(status)) { 452 if (U_FAILURE(status)) {
495 delete (DecimalFormat*)this->numberFormat; 453 delete tempNumberFormat;
496 this->numberFormat = NULL;
497 return; 454 return;
498 } 455 }
499 // this->numberFormat->setDecimalFormatSymbols(formatter->getDecimalForm atSymbols()); 456 this->numberFormat = tempNumberFormat;
500 } 457 }
501 // if the description is ">>>", this substitution bypasses the
502 // usual rule-search process and always uses the rule that precedes
503 // it in its own rule set's rule list (this is used for place-value
504 // notations: formats where you want to see a particular part of
505 // a number even when it's 0)
506 else if (workingDescription.charAt(0) == gGreaterThan) { 458 else if (workingDescription.charAt(0) == gGreaterThan) {
459 // if the description is ">>>", this substitution bypasses the
460 // usual rule-search process and always uses the rule that precedes
461 // it in its own rule set's rule list (this is used for place-value
462 // notations: formats where you want to see a particular part of
463 // a number even when it's 0)
464
507 // this causes problems when >>> is used in a frationalPartSubstitution 465 // this causes problems when >>> is used in a frationalPartSubstitution
508 // this->ruleSet = NULL; 466 // this->ruleSet = NULL;
509 this->ruleSet = _ruleSet; 467 this->ruleSet = _ruleSet;
510 this->numberFormat = NULL; 468 this->numberFormat = NULL;
511 } 469 }
512 // and of the description is none of these things, it's a syntax error
513 else { 470 else {
471 // and of the description is none of these things, it's a syntax error
472
514 // throw new IllegalArgumentException("Illegal substitution syntax"); 473 // throw new IllegalArgumentException("Illegal substitution syntax");
515 status = U_PARSE_ERROR; 474 status = U_PARSE_ERROR;
516 } 475 }
517 } 476 }
518 477
519 NFSubstitution::~NFSubstitution() 478 NFSubstitution::~NFSubstitution()
520 { 479 {
521 // cast away const 480 delete numberFormat;
522 delete (NumberFormat*)numberFormat; numberFormat = NULL; 481 numberFormat = NULL;
523 } 482 }
524 483
525 /** 484 /**
526 * Set's the substitution's divisor. Used by NFRule.setBaseValue(). 485 * Set's the substitution's divisor. Used by NFRule.setBaseValue().
527 * A no-op for all substitutions except multiplier and modulus 486 * A no-op for all substitutions except multiplier and modulus
528 * substitutions. 487 * substitutions.
529 * @param radix The radix of the divisor 488 * @param radix The radix of the divisor
530 * @param exponent The exponent of the divisor 489 * @param exponent The exponent of the divisor
531 */ 490 */
532 void 491 void
533 NFSubstitution::setDivisor(int32_t /*radix*/, int32_t /*exponent*/, UErrorCode& /*status*/) { 492 NFSubstitution::setDivisor(int32_t /*radix*/, int32_t /*exponent*/, UErrorCode& /*status*/) {
534 // a no-op for all substitutions except multiplier and modulus substitutions 493 // a no-op for all substitutions except multiplier and modulus substitutions
535 } 494 }
536 495
496 void
497 NFSubstitution::setDecimalFormatSymbols(const DecimalFormatSymbols &newSymbols, UErrorCode& /*status*/) {
498 if (numberFormat != NULL) {
499 numberFormat->setDecimalFormatSymbols(newSymbols);
500 }
501 }
537 502
538 //----------------------------------------------------------------------- 503 //-----------------------------------------------------------------------
539 // boilerplate 504 // boilerplate
540 //----------------------------------------------------------------------- 505 //-----------------------------------------------------------------------
541 506
542 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(NFSubstitution) 507 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(NFSubstitution)
543 508
544 /** 509 /**
545 * Compares two substitutions for equality 510 * Compares two substitutions for equality
546 * @param The substitution to compare this one to 511 * @param The substitution to compare this one to
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
595 * Performs a mathematical operation on the number, formats it using 560 * Performs a mathematical operation on the number, formats it using
596 * either ruleSet or decimalFormat, and inserts the result into 561 * either ruleSet or decimalFormat, and inserts the result into
597 * toInsertInto. 562 * toInsertInto.
598 * @param number The number being formatted. 563 * @param number The number being formatted.
599 * @param toInsertInto The string we insert the result into 564 * @param toInsertInto The string we insert the result into
600 * @param pos The position in toInsertInto where the owning rule's 565 * @param pos The position in toInsertInto where the owning rule's
601 * rule text begins (this value is added to this substitution's 566 * rule text begins (this value is added to this substitution's
602 * position to determine exactly where to insert the new text) 567 * position to determine exactly where to insert the new text)
603 */ 568 */
604 void 569 void
605 NFSubstitution::doSubstitution(int64_t number, UnicodeString& toInsertInto, int3 2_t _pos, UErrorCode& status) const 570 NFSubstitution::doSubstitution(int64_t number, UnicodeString& toInsertInto, int3 2_t _pos, int32_t recursionCount, UErrorCode& status) const
606 { 571 {
607 if (ruleSet != NULL) { 572 if (ruleSet != NULL) {
608 // perform a transformation on the number that is dependent 573 // perform a transformation on the number that is dependent
609 // on the type of substitution this is, then just call its 574 // on the type of substitution this is, then just call its
610 // rule set's format() method to format the result 575 // rule set's format() method to format the result
611 ruleSet->format(transformNumber(number), toInsertInto, _pos + this->pos, status); 576 ruleSet->format(transformNumber(number), toInsertInto, _pos + this->pos, recursionCount, status);
612 } else if (numberFormat != NULL) { 577 } else if (numberFormat != NULL) {
613 // or perform the transformation on the number (preserving 578 // or perform the transformation on the number (preserving
614 // the result's fractional part if the formatter it set 579 // the result's fractional part if the formatter it set
615 // to show it), then use that formatter's format() method 580 // to show it), then use that formatter's format() method
616 // to format the result 581 // to format the result
617 double numberToFormat = transformNumber((double)number); 582 double numberToFormat = transformNumber((double)number);
618 if (numberFormat->getMaximumFractionDigits() == 0) { 583 if (numberFormat->getMaximumFractionDigits() == 0) {
619 numberToFormat = uprv_floor(numberToFormat); 584 numberToFormat = uprv_floor(numberToFormat);
620 } 585 }
621 586
622 UnicodeString temp; 587 UnicodeString temp;
623 numberFormat->format(numberToFormat, temp, status); 588 numberFormat->format(numberToFormat, temp, status);
624 toInsertInto.insert(_pos + this->pos, temp); 589 toInsertInto.insert(_pos + this->pos, temp);
625 } 590 }
626 } 591 }
627 592
628 /** 593 /**
629 * Performs a mathematical operation on the number, formats it using 594 * Performs a mathematical operation on the number, formats it using
630 * either ruleSet or decimalFormat, and inserts the result into 595 * either ruleSet or decimalFormat, and inserts the result into
631 * toInsertInto. 596 * toInsertInto.
632 * @param number The number being formatted. 597 * @param number The number being formatted.
633 * @param toInsertInto The string we insert the result into 598 * @param toInsertInto The string we insert the result into
634 * @param pos The position in toInsertInto where the owning rule's 599 * @param pos The position in toInsertInto where the owning rule's
635 * rule text begins (this value is added to this substitution's 600 * rule text begins (this value is added to this substitution's
636 * position to determine exactly where to insert the new text) 601 * position to determine exactly where to insert the new text)
637 */ 602 */
638 void 603 void
639 NFSubstitution::doSubstitution(double number, UnicodeString& toInsertInto, int32 _t _pos, UErrorCode& status) const { 604 NFSubstitution::doSubstitution(double number, UnicodeString& toInsertInto, int32 _t _pos, int32_t recursionCount, UErrorCode& status) const {
640 // perform a transformation on the number being formatted that 605 // perform a transformation on the number being formatted that
641 // is dependent on the type of substitution this is 606 // is dependent on the type of substitution this is
642 double numberToFormat = transformNumber(number); 607 double numberToFormat = transformNumber(number);
643 608
609 if (uprv_isInfinite(numberToFormat)) {
610 // This is probably a minus rule. Combine it with an infinite rule.
611 const NFRule *infiniteRule = ruleSet->findDoubleRule(uprv_getInfinity()) ;
612 infiniteRule->doFormat(numberToFormat, toInsertInto, _pos + this->pos, r ecursionCount, status);
613 return;
614 }
615
644 // if the result is an integer, from here on out we work in integer 616 // if the result is an integer, from here on out we work in integer
645 // space (saving time and memory and preserving accuracy) 617 // space (saving time and memory and preserving accuracy)
646 if (numberToFormat == uprv_floor(numberToFormat) && ruleSet != NULL) { 618 if (numberToFormat == uprv_floor(numberToFormat) && ruleSet != NULL) {
647 ruleSet->format(util64_fromDouble(numberToFormat), toInsertInto, _pos + this->pos, status); 619 ruleSet->format(util64_fromDouble(numberToFormat), toInsertInto, _pos + this->pos, recursionCount, status);
648 620
649 // if the result isn't an integer, then call either our rule set's 621 // if the result isn't an integer, then call either our rule set's
650 // format() method or our DecimalFormat's format() method to 622 // format() method or our DecimalFormat's format() method to
651 // format the result 623 // format the result
652 } else { 624 } else {
653 if (ruleSet != NULL) { 625 if (ruleSet != NULL) {
654 ruleSet->format(numberToFormat, toInsertInto, _pos + this->pos, stat us); 626 ruleSet->format(numberToFormat, toInsertInto, _pos + this->pos, recu rsionCount, status);
655 } else if (numberFormat != NULL) { 627 } else if (numberFormat != NULL) {
656 UnicodeString temp; 628 UnicodeString temp;
657 numberFormat->format(numberToFormat, temp); 629 numberFormat->format(numberToFormat, temp);
658 toInsertInto.insert(_pos + this->pos, temp); 630 toInsertInto.insert(_pos + this->pos, temp);
659 } 631 }
660 } 632 }
661 } 633 }
662 634
663 635
664 //----------------------------------------------------------------------- 636 //-----------------------------------------------------------------------
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
772 tempResult = composeRuleValue(tempResult, baseValue); 744 tempResult = composeRuleValue(tempResult, baseValue);
773 result.setDouble(tempResult); 745 result.setDouble(tempResult);
774 return TRUE; 746 return TRUE;
775 // if the parse was UNsuccessful, return 0 747 // if the parse was UNsuccessful, return 0
776 } else { 748 } else {
777 result.setLong(0); 749 result.setLong(0);
778 return FALSE; 750 return FALSE;
779 } 751 }
780 } 752 }
781 753
782 UBool
783 NFSubstitution::isNullSubstitution() const {
784 return FALSE;
785 }
786
787 /** 754 /**
788 * Returns true if this is a modulus substitution. (We didn't do this 755 * Returns true if this is a modulus substitution. (We didn't do this
789 * with instanceof partially because it causes source files to 756 * with instanceof partially because it causes source files to
790 * proliferate and partially because we have to port this to C++.) 757 * proliferate and partially because we have to port this to C++.)
791 * @return true if this object is an instance of ModulusSubstitution 758 * @return true if this object is an instance of ModulusSubstitution
792 */ 759 */
793 UBool 760 UBool
794 NFSubstitution::isModulusSubstitution() const { 761 NFSubstitution::isModulusSubstitution() const {
795 return FALSE; 762 return FALSE;
796 } 763 }
797 764
798 //=================================================================== 765 //===================================================================
799 // SameValueSubstitution 766 // SameValueSubstitution
800 //=================================================================== 767 //===================================================================
801 768
802 /** 769 /**
803 * A substitution that passes the value passed to it through unchanged. 770 * A substitution that passes the value passed to it through unchanged.
804 * Represented by == in rule descriptions. 771 * Represented by == in rule descriptions.
805 */ 772 */
806 SameValueSubstitution::SameValueSubstitution(int32_t _pos, 773 SameValueSubstitution::SameValueSubstitution(int32_t _pos,
807 const NFRuleSet* _ruleSet, 774 const NFRuleSet* _ruleSet,
808 const RuleBasedNumberFormat* formatter,
809 const UnicodeString& description, 775 const UnicodeString& description,
810 UErrorCode& status) 776 UErrorCode& status)
811 : NFSubstitution(_pos, _ruleSet, formatter, description, status) 777 : NFSubstitution(_pos, _ruleSet, description, status)
812 { 778 {
813 if (0 == description.compare(gEqualsEquals, 2)) { 779 if (0 == description.compare(gEqualsEquals, 2)) {
814 // throw new IllegalArgumentException("== is not a legal token"); 780 // throw new IllegalArgumentException("== is not a legal token");
815 status = U_PARSE_ERROR; 781 status = U_PARSE_ERROR;
816 } 782 }
817 } 783 }
818 784
819 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(SameValueSubstitution) 785 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(SameValueSubstitution)
820 786
821 //=================================================================== 787 //===================================================================
(...skipping 15 matching lines...) Expand all
837 803
838 /** 804 /**
839 * A substitution that divides the number being formatted by the its rule's 805 * A substitution that divides the number being formatted by the its rule's
840 * divisor and formats the remainder. Represented by "&gt;&gt;" in a 806 * divisor and formats the remainder. Represented by "&gt;&gt;" in a
841 * regular rule. 807 * regular rule.
842 */ 808 */
843 ModulusSubstitution::ModulusSubstitution(int32_t _pos, 809 ModulusSubstitution::ModulusSubstitution(int32_t _pos,
844 double _divisor, 810 double _divisor,
845 const NFRule* predecessor, 811 const NFRule* predecessor,
846 const NFRuleSet* _ruleSet, 812 const NFRuleSet* _ruleSet,
847 const RuleBasedNumberFormat* formatter,
848 const UnicodeString& description, 813 const UnicodeString& description,
849 UErrorCode& status) 814 UErrorCode& status)
850 : NFSubstitution(_pos, _ruleSet, formatter, description, status) 815 : NFSubstitution(_pos, _ruleSet, description, status)
851 , divisor(_divisor) 816 , divisor(_divisor)
852 , ruleToUse(NULL) 817 , ruleToUse(NULL)
853 { 818 {
854 ldivisor = util64_fromDouble(_divisor); 819 ldivisor = util64_fromDouble(_divisor);
855 820
856 // the owning rule's divisor controls the behavior of this 821 // the owning rule's divisor controls the behavior of this
857 // substitution: rather than keeping a backpointer to the rule, 822 // substitution: rather than keeping a backpointer to the rule,
858 // we keep a copy of the divisor 823 // we keep a copy of the divisor
859 824
860 if (ldivisor == 0) { 825 if (ldivisor == 0) {
(...skipping 26 matching lines...) Expand all
887 852
888 /** 853 /**
889 * If this is a &gt;&gt;&gt; substitution, use ruleToUse to fill in 854 * If this is a &gt;&gt;&gt; substitution, use ruleToUse to fill in
890 * the substitution. Otherwise, just use the superclass function. 855 * the substitution. Otherwise, just use the superclass function.
891 * @param number The number being formatted 856 * @param number The number being formatted
892 * @toInsertInto The string to insert the result of this substitution 857 * @toInsertInto The string to insert the result of this substitution
893 * into 858 * into
894 * @param pos The position of the rule text in toInsertInto 859 * @param pos The position of the rule text in toInsertInto
895 */ 860 */
896 void 861 void
897 ModulusSubstitution::doSubstitution(int64_t number, UnicodeString& toInsertInto, int32_t _pos, UErrorCode& status) const 862 ModulusSubstitution::doSubstitution(int64_t number, UnicodeString& toInsertInto, int32_t _pos, int32_t recursionCount, UErrorCode& status) const
898 { 863 {
899 // if this isn't a >>> substitution, just use the inherited version 864 // if this isn't a >>> substitution, just use the inherited version
900 // of this function (which uses either a rule set or a DecimalFormat 865 // of this function (which uses either a rule set or a DecimalFormat
901 // to format its substitution value) 866 // to format its substitution value)
902 if (ruleToUse == NULL) { 867 if (ruleToUse == NULL) {
903 NFSubstitution::doSubstitution(number, toInsertInto, _pos, status); 868 NFSubstitution::doSubstitution(number, toInsertInto, _pos, recursionCoun t, status);
904 869
905 // a >>> substitution goes straight to a particular rule to 870 // a >>> substitution goes straight to a particular rule to
906 // format the substitution value 871 // format the substitution value
907 } else { 872 } else {
908 int64_t numberToFormat = transformNumber(number); 873 int64_t numberToFormat = transformNumber(number);
909 ruleToUse->doFormat(numberToFormat, toInsertInto, _pos + getPos(), statu s); 874 ruleToUse->doFormat(numberToFormat, toInsertInto, _pos + getPos(), recur sionCount, status);
910 } 875 }
911 } 876 }
912 877
913 /** 878 /**
914 * If this is a &gt;&gt;&gt; substitution, use ruleToUse to fill in 879 * If this is a &gt;&gt;&gt; substitution, use ruleToUse to fill in
915 * the substitution. Otherwise, just use the superclass function. 880 * the substitution. Otherwise, just use the superclass function.
916 * @param number The number being formatted 881 * @param number The number being formatted
917 * @toInsertInto The string to insert the result of this substitution 882 * @toInsertInto The string to insert the result of this substitution
918 * into 883 * into
919 * @param pos The position of the rule text in toInsertInto 884 * @param pos The position of the rule text in toInsertInto
920 */ 885 */
921 void 886 void
922 ModulusSubstitution::doSubstitution(double number, UnicodeString& toInsertInto, int32_t _pos, UErrorCode& status) const 887 ModulusSubstitution::doSubstitution(double number, UnicodeString& toInsertInto, int32_t _pos, int32_t recursionCount, UErrorCode& status) const
923 { 888 {
924 // if this isn't a >>> substitution, just use the inherited version 889 // if this isn't a >>> substitution, just use the inherited version
925 // of this function (which uses either a rule set or a DecimalFormat 890 // of this function (which uses either a rule set or a DecimalFormat
926 // to format its substitution value) 891 // to format its substitution value)
927 if (ruleToUse == NULL) { 892 if (ruleToUse == NULL) {
928 NFSubstitution::doSubstitution(number, toInsertInto, _pos, status); 893 NFSubstitution::doSubstitution(number, toInsertInto, _pos, recursionCoun t, status);
929 894
930 // a >>> substitution goes straight to a particular rule to 895 // a >>> substitution goes straight to a particular rule to
931 // format the substitution value 896 // format the substitution value
932 } else { 897 } else {
933 double numberToFormat = transformNumber(number); 898 double numberToFormat = transformNumber(number);
934 899
935 ruleToUse->doFormat(numberToFormat, toInsertInto, _pos + getPos(), statu s); 900 ruleToUse->doFormat(numberToFormat, toInsertInto, _pos + getPos(), recur sionCount, status);
936 } 901 }
937 } 902 }
938 903
939 //----------------------------------------------------------------------- 904 //-----------------------------------------------------------------------
940 // parsing 905 // parsing
941 //----------------------------------------------------------------------- 906 //-----------------------------------------------------------------------
942 907
943 /** 908 /**
944 * If this is a &gt;&gt;&gt; substitution, match only against ruleToUse. 909 * If this is a &gt;&gt;&gt; substitution, match only against ruleToUse.
945 * Otherwise, use the superclass function. 910 * Otherwise, use the superclass function.
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1013 //=================================================================== 978 //===================================================================
1014 979
1015 980
1016 /** 981 /**
1017 * Constructs a FractionalPartSubstitution. This object keeps a flag 982 * Constructs a FractionalPartSubstitution. This object keeps a flag
1018 * telling whether it should format by digits or not. In addition, 983 * telling whether it should format by digits or not. In addition,
1019 * it marks the rule set it calls (if any) as a fraction rule set. 984 * it marks the rule set it calls (if any) as a fraction rule set.
1020 */ 985 */
1021 FractionalPartSubstitution::FractionalPartSubstitution(int32_t _pos, 986 FractionalPartSubstitution::FractionalPartSubstitution(int32_t _pos,
1022 const NFRuleSet* _ruleSet, 987 const NFRuleSet* _ruleSet,
1023 const RuleBasedNumberFormat* formatter,
1024 const UnicodeString& description, 988 const UnicodeString& description,
1025 UErrorCode& status) 989 UErrorCode& status)
1026 : NFSubstitution(_pos, _ruleSet, formatter, description, status) 990 : NFSubstitution(_pos, _ruleSet, description, status)
1027 , byDigits(FALSE) 991 , byDigits(FALSE)
1028 , useSpaces(TRUE) 992 , useSpaces(TRUE)
1029 993
1030 { 994 {
1031 // akk, ruleSet can change in superclass constructor 995 // akk, ruleSet can change in superclass constructor
1032 if (0 == description.compare(gGreaterGreaterThan, 2) || 996 if (0 == description.compare(gGreaterGreaterThan, 2) ||
1033 0 == description.compare(gGreaterGreaterGreaterThan, 3) || 997 0 == description.compare(gGreaterGreaterGreaterThan, 3) ||
1034 _ruleSet == getRuleSet()) { 998 _ruleSet == getRuleSet()) {
1035 byDigits = TRUE; 999 byDigits = TRUE;
1036 if (0 == description.compare(gGreaterGreaterGreaterThan, 3)) { 1000 if (0 == description.compare(gGreaterGreaterGreaterThan, 3)) {
(...skipping 14 matching lines...) Expand all
1051 * at a time using the rule set containing this substitution. 1015 * at a time using the rule set containing this substitution.
1052 * Otherwise, uses the superclass function. 1016 * Otherwise, uses the superclass function.
1053 * @param number The number being formatted 1017 * @param number The number being formatted
1054 * @param toInsertInto The string to insert the result of formatting 1018 * @param toInsertInto The string to insert the result of formatting
1055 * the substitution into 1019 * the substitution into
1056 * @param pos The position of the owning rule's rule text in 1020 * @param pos The position of the owning rule's rule text in
1057 * toInsertInto 1021 * toInsertInto
1058 */ 1022 */
1059 void 1023 void
1060 FractionalPartSubstitution::doSubstitution(double number, UnicodeString& toInser tInto, 1024 FractionalPartSubstitution::doSubstitution(double number, UnicodeString& toInser tInto,
1061 int32_t _pos, UErrorCode& status) con st 1025 int32_t _pos, int32_t recursionCount, UErrorCode& status) const
1062 { 1026 {
1063 // if we're not in "byDigits" mode, just use the inherited 1027 // if we're not in "byDigits" mode, just use the inherited
1064 // doSubstitution() routine 1028 // doSubstitution() routine
1065 if (!byDigits) { 1029 if (!byDigits) {
1066 NFSubstitution::doSubstitution(number, toInsertInto, _pos, status); 1030 NFSubstitution::doSubstitution(number, toInsertInto, _pos, recursionCount, s tatus);
1067 1031
1068 // if we're in "byDigits" mode, transform the value into an integer 1032 // if we're in "byDigits" mode, transform the value into an integer
1069 // by moving the decimal point eight places to the right and 1033 // by moving the decimal point eight places to the right and
1070 // pulling digits off the right one at a time, formatting each digit 1034 // pulling digits off the right one at a time, formatting each digit
1071 // as an integer using this substitution's owning rule set 1035 // as an integer using this substitution's owning rule set
1072 // (this is slower, but more accurate, than doing it from the 1036 // (this is slower, but more accurate, than doing it from the
1073 // other end) 1037 // other end)
1074 } else { 1038 } else {
1075 // int32_t numberToFormat = (int32_t)uprv_round(transformNumber(num ber) * uprv_pow(10, kMaxDecimalDigits)); 1039 // int32_t numberToFormat = (int32_t)uprv_round(transformNumber(num ber) * uprv_pow(10, kMaxDecimalDigits));
1076 // // this flag keeps us from formatting trailing zeros. It starts 1040 // // this flag keeps us from formatting trailing zeros. It starts
(...skipping 21 matching lines...) Expand all
1098 for (int32_t didx = dl.getCount()-1; didx>=dl.getDecimalAt(); didx--) { 1062 for (int32_t didx = dl.getCount()-1; didx>=dl.getDecimalAt(); didx--) {
1099 // Loop iterates over fraction digits, starting with the LSD. 1063 // Loop iterates over fraction digits, starting with the LSD.
1100 // include both real digits from the number, and zeros 1064 // include both real digits from the number, and zeros
1101 // to the left of the MSD but to the right of the decimal point. 1065 // to the left of the MSD but to the right of the decimal point.
1102 if (pad && useSpaces) { 1066 if (pad && useSpaces) {
1103 toInsertInto.insert(_pos + getPos(), gSpace); 1067 toInsertInto.insert(_pos + getPos(), gSpace);
1104 } else { 1068 } else {
1105 pad = TRUE; 1069 pad = TRUE;
1106 } 1070 }
1107 int64_t digit = didx>=0 ? dl.getDigit(didx) - '0' : 0; 1071 int64_t digit = didx>=0 ? dl.getDigit(didx) - '0' : 0;
1108 getRuleSet()->format(digit, toInsertInto, _pos + getPos(), status); 1072 getRuleSet()->format(digit, toInsertInto, _pos + getPos(), recursionCount, status);
1109 } 1073 }
1110 1074
1111 if (!pad) { 1075 if (!pad) {
1112 // hack around lack of precision in digitlist. if we would end up with 1076 // hack around lack of precision in digitlist. if we would end up with
1113 // "foo point" make sure we add a " zero" to the end. 1077 // "foo point" make sure we add a " zero" to the end.
1114 getRuleSet()->format((int64_t)0, toInsertInto, _pos + getPos(), status); 1078 getRuleSet()->format((int64_t)0, toInsertInto, _pos + getPos(), recursionC ount, status);
1115 } 1079 }
1116 } 1080 }
1117 } 1081 }
1118 1082
1119 //----------------------------------------------------------------------- 1083 //-----------------------------------------------------------------------
1120 // parsing 1084 // parsing
1121 //----------------------------------------------------------------------- 1085 //-----------------------------------------------------------------------
1122 1086
1123 /** 1087 /**
1124 * If in "by digits" mode, parses the string as if it were a string 1088 * If in "by digits" mode, parses the string as if it were a string
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
1223 // AbsoluteValueSubstitution 1187 // AbsoluteValueSubstitution
1224 //=================================================================== 1188 //===================================================================
1225 1189
1226 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(AbsoluteValueSubstitution) 1190 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(AbsoluteValueSubstitution)
1227 1191
1228 //=================================================================== 1192 //===================================================================
1229 // NumeratorSubstitution 1193 // NumeratorSubstitution
1230 //=================================================================== 1194 //===================================================================
1231 1195
1232 void 1196 void
1233 NumeratorSubstitution::doSubstitution(double number, UnicodeString& toInsertInto , int32_t apos, UErrorCode& status) const { 1197 NumeratorSubstitution::doSubstitution(double number, UnicodeString& toInsertInto , int32_t apos, int32_t recursionCount, UErrorCode& status) const {
1234 // perform a transformation on the number being formatted that 1198 // perform a transformation on the number being formatted that
1235 // is dependent on the type of substitution this is 1199 // is dependent on the type of substitution this is
1236 1200
1237 double numberToFormat = transformNumber(number); 1201 double numberToFormat = transformNumber(number);
1238 int64_t longNF = util64_fromDouble(numberToFormat); 1202 int64_t longNF = util64_fromDouble(numberToFormat);
1239 1203
1240 const NFRuleSet* aruleSet = getRuleSet(); 1204 const NFRuleSet* aruleSet = getRuleSet();
1241 if (withZeros && aruleSet != NULL) { 1205 if (withZeros && aruleSet != NULL) {
1242 // if there are leading zeros in the decimal expansion then emit them 1206 // if there are leading zeros in the decimal expansion then emit them
1243 int64_t nf =longNF; 1207 int64_t nf =longNF;
1244 int32_t len = toInsertInto.length(); 1208 int32_t len = toInsertInto.length();
1245 while ((nf *= 10) < denominator) { 1209 while ((nf *= 10) < denominator) {
1246 toInsertInto.insert(apos + getPos(), gSpace); 1210 toInsertInto.insert(apos + getPos(), gSpace);
1247 aruleSet->format((int64_t)0, toInsertInto, apos + getPos(), status); 1211 aruleSet->format((int64_t)0, toInsertInto, apos + getPos(), recursio nCount, status);
1248 } 1212 }
1249 apos += toInsertInto.length() - len; 1213 apos += toInsertInto.length() - len;
1250 } 1214 }
1251 1215
1252 // if the result is an integer, from here on out we work in integer 1216 // if the result is an integer, from here on out we work in integer
1253 // space (saving time and memory and preserving accuracy) 1217 // space (saving time and memory and preserving accuracy)
1254 if (numberToFormat == longNF && aruleSet != NULL) { 1218 if (numberToFormat == longNF && aruleSet != NULL) {
1255 aruleSet->format(longNF, toInsertInto, apos + getPos(), status); 1219 aruleSet->format(longNF, toInsertInto, apos + getPos(), recursionCount, status);
1256 1220
1257 // if the result isn't an integer, then call either our rule set's 1221 // if the result isn't an integer, then call either our rule set's
1258 // format() method or our DecimalFormat's format() method to 1222 // format() method or our DecimalFormat's format() method to
1259 // format the result 1223 // format the result
1260 } else { 1224 } else {
1261 if (aruleSet != NULL) { 1225 if (aruleSet != NULL) {
1262 aruleSet->format(numberToFormat, toInsertInto, apos + getPos(), stat us); 1226 aruleSet->format(numberToFormat, toInsertInto, apos + getPos(), recu rsionCount, status);
1263 } else { 1227 } else {
1264 UnicodeString temp; 1228 UnicodeString temp;
1265 getNumberFormat()->format(numberToFormat, temp, status); 1229 getNumberFormat()->format(numberToFormat, temp, status);
1266 toInsertInto.insert(apos + getPos(), temp); 1230 toInsertInto.insert(apos + getPos(), temp);
1267 } 1231 }
1268 } 1232 }
1269 } 1233 }
1270 1234
1271 UBool 1235 UBool
1272 NumeratorSubstitution::doParse(const UnicodeString& text, 1236 NumeratorSubstitution::doParse(const UnicodeString& text,
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1344 NumeratorSubstitution::operator==(const NFSubstitution& rhs) const 1308 NumeratorSubstitution::operator==(const NFSubstitution& rhs) const
1345 { 1309 {
1346 return NFSubstitution::operator==(rhs) && 1310 return NFSubstitution::operator==(rhs) &&
1347 denominator == ((const NumeratorSubstitution*)&rhs)->denominator; 1311 denominator == ((const NumeratorSubstitution*)&rhs)->denominator;
1348 } 1312 }
1349 1313
1350 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(NumeratorSubstitution) 1314 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(NumeratorSubstitution)
1351 1315
1352 const UChar NumeratorSubstitution::LTLT[] = { 0x003c, 0x003c }; 1316 const UChar NumeratorSubstitution::LTLT[] = { 0x003c, 0x003c };
1353 1317
1354 //===================================================================
1355 // NullSubstitution
1356 //===================================================================
1357
1358 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(NullSubstitution)
1359
1360 U_NAMESPACE_END 1318 U_NAMESPACE_END
1361 1319
1362 /* U_HAVE_RBNF */ 1320 /* U_HAVE_RBNF */
1363 #endif 1321 #endif
1364 1322
OLDNEW
« no previous file with comments | « source/i18n/nfsubs.h ('k') | source/i18n/numfmt.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698