OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 ">>" in a | 806 * divisor and formats the remainder. Represented by ">>" 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 Loading... |
887 | 852 |
888 /** | 853 /** |
889 * If this is a >>> substitution, use ruleToUse to fill in | 854 * If this is a >>> 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 >>> substitution, use ruleToUse to fill in | 879 * If this is a >>> 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 >>> substitution, match only against ruleToUse. | 909 * If this is a >>> 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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |