decimfmt.cpp 112 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293
  1. // Copyright (C) 2016 and later: Unicode, Inc. and others.
  2. // License & terms of use: http://www.unicode.org/copyright.html
  3. /*
  4. *******************************************************************************
  5. * Copyright (C) 1997-2015, International Business Machines Corporation and *
  6. * others. All Rights Reserved. *
  7. *******************************************************************************
  8. *
  9. * File DECIMFMT.CPP
  10. *
  11. * Modification History:
  12. *
  13. * Date Name Description
  14. * 02/19/97 aliu Converted from java.
  15. * 03/20/97 clhuang Implemented with new APIs.
  16. * 03/31/97 aliu Moved isLONG_MIN to DigitList, and fixed it.
  17. * 04/3/97 aliu Rewrote parsing and formatting completely, and
  18. * cleaned up and debugged. Actually works now.
  19. * Implemented NAN and INF handling, for both parsing
  20. * and formatting. Extensive testing & debugging.
  21. * 04/10/97 aliu Modified to compile on AIX.
  22. * 04/16/97 aliu Rewrote to use DigitList, which has been resurrected.
  23. * Changed DigitCount to int per code review.
  24. * 07/09/97 helena Made ParsePosition into a class.
  25. * 08/26/97 aliu Extensive changes to applyPattern; completely
  26. * rewritten from the Java.
  27. * 09/09/97 aliu Ported over support for exponential formats.
  28. * 07/20/98 stephen JDK 1.2 sync up.
  29. * Various instances of '0' replaced with 'NULL'
  30. * Check for grouping size in subFormat()
  31. * Brought subParse() in line with Java 1.2
  32. * Added method appendAffix()
  33. * 08/24/1998 srl Removed Mutex calls. This is not a thread safe class!
  34. * 02/22/99 stephen Removed character literals for EBCDIC safety
  35. * 06/24/99 helena Integrated Alan's NF enhancements and Java2 bug fixes
  36. * 06/28/99 stephen Fixed bugs in toPattern().
  37. * 06/29/99 stephen Fixed operator= to copy fFormatWidth, fPad,
  38. * fPadPosition
  39. ********************************************************************************
  40. */
  41. #include "unicode/utypes.h"
  42. #if !UCONFIG_NO_FORMATTING
  43. #include "unicode/uniset.h"
  44. #include "unicode/currpinf.h"
  45. #include "unicode/plurrule.h"
  46. #include "unicode/utf16.h"
  47. #include "unicode/numsys.h"
  48. #include "unicode/localpointer.h"
  49. #include "uresimp.h"
  50. #include "ucurrimp.h"
  51. #include "charstr.h"
  52. #include "patternprops.h"
  53. #include "cstring.h"
  54. #include "uassert.h"
  55. #include "hash.h"
  56. #include "decfmtst.h"
  57. #include "plurrule_impl.h"
  58. #include "decimalformatpattern.h"
  59. #include "fmtableimp.h"
  60. #include "decimfmtimpl.h"
  61. #include "visibledigits.h"
  62. /*
  63. * On certain platforms, round is a macro defined in math.h
  64. * This undefine is to avoid conflict between the macro and
  65. * the function defined below.
  66. */
  67. #ifdef round
  68. #undef round
  69. #endif
  70. U_NAMESPACE_BEGIN
  71. #ifdef FMT_DEBUG
  72. #include <stdio.h>
  73. static void _debugout(const char *f, int l, const UnicodeString& s) {
  74. char buf[2000];
  75. s.extract((int32_t) 0, s.length(), buf, "utf-8");
  76. printf("%s:%d: %s\n", f,l, buf);
  77. }
  78. #define debugout(x) _debugout(__FILE__,__LINE__,x)
  79. #define debug(x) printf("%s:%d: %s\n", __FILE__,__LINE__, x);
  80. static const UnicodeString dbg_null("<NULL>","");
  81. #define DEREFSTR(x) ((x!=NULL)?(*x):(dbg_null))
  82. #else
  83. #define debugout(x)
  84. #define debug(x)
  85. #endif
  86. /* For currency parsing purose,
  87. * Need to remember all prefix patterns and suffix patterns of
  88. * every currency format pattern,
  89. * including the pattern of default currecny style
  90. * and plural currency style. And the patterns are set through applyPattern.
  91. */
  92. struct AffixPatternsForCurrency : public UMemory {
  93. // negative prefix pattern
  94. UnicodeString negPrefixPatternForCurrency;
  95. // negative suffix pattern
  96. UnicodeString negSuffixPatternForCurrency;
  97. // positive prefix pattern
  98. UnicodeString posPrefixPatternForCurrency;
  99. // positive suffix pattern
  100. UnicodeString posSuffixPatternForCurrency;
  101. int8_t patternType;
  102. AffixPatternsForCurrency(const UnicodeString& negPrefix,
  103. const UnicodeString& negSuffix,
  104. const UnicodeString& posPrefix,
  105. const UnicodeString& posSuffix,
  106. int8_t type) {
  107. negPrefixPatternForCurrency = negPrefix;
  108. negSuffixPatternForCurrency = negSuffix;
  109. posPrefixPatternForCurrency = posPrefix;
  110. posSuffixPatternForCurrency = posSuffix;
  111. patternType = type;
  112. }
  113. #ifdef FMT_DEBUG
  114. void dump() const {
  115. debugout( UnicodeString("AffixPatternsForCurrency( -=\"") +
  116. negPrefixPatternForCurrency + (UnicodeString)"\"/\"" +
  117. negSuffixPatternForCurrency + (UnicodeString)"\" +=\"" +
  118. posPrefixPatternForCurrency + (UnicodeString)"\"/\"" +
  119. posSuffixPatternForCurrency + (UnicodeString)"\" )");
  120. }
  121. #endif
  122. };
  123. /* affix for currency formatting when the currency sign in the pattern
  124. * equals to 3, such as the pattern contains 3 currency sign or
  125. * the formatter style is currency plural format style.
  126. */
  127. struct AffixesForCurrency : public UMemory {
  128. // negative prefix
  129. UnicodeString negPrefixForCurrency;
  130. // negative suffix
  131. UnicodeString negSuffixForCurrency;
  132. // positive prefix
  133. UnicodeString posPrefixForCurrency;
  134. // positive suffix
  135. UnicodeString posSuffixForCurrency;
  136. int32_t formatWidth;
  137. AffixesForCurrency(const UnicodeString& negPrefix,
  138. const UnicodeString& negSuffix,
  139. const UnicodeString& posPrefix,
  140. const UnicodeString& posSuffix) {
  141. negPrefixForCurrency = negPrefix;
  142. negSuffixForCurrency = negSuffix;
  143. posPrefixForCurrency = posPrefix;
  144. posSuffixForCurrency = posSuffix;
  145. }
  146. #ifdef FMT_DEBUG
  147. void dump() const {
  148. debugout( UnicodeString("AffixesForCurrency( -=\"") +
  149. negPrefixForCurrency + (UnicodeString)"\"/\"" +
  150. negSuffixForCurrency + (UnicodeString)"\" +=\"" +
  151. posPrefixForCurrency + (UnicodeString)"\"/\"" +
  152. posSuffixForCurrency + (UnicodeString)"\" )");
  153. }
  154. #endif
  155. };
  156. U_CDECL_BEGIN
  157. /**
  158. * @internal ICU 4.2
  159. */
  160. static UBool U_CALLCONV decimfmtAffixPatternValueComparator(UHashTok val1, UHashTok val2);
  161. static UBool
  162. U_CALLCONV decimfmtAffixPatternValueComparator(UHashTok val1, UHashTok val2) {
  163. const AffixPatternsForCurrency* affix_1 =
  164. (AffixPatternsForCurrency*)val1.pointer;
  165. const AffixPatternsForCurrency* affix_2 =
  166. (AffixPatternsForCurrency*)val2.pointer;
  167. return affix_1->negPrefixPatternForCurrency ==
  168. affix_2->negPrefixPatternForCurrency &&
  169. affix_1->negSuffixPatternForCurrency ==
  170. affix_2->negSuffixPatternForCurrency &&
  171. affix_1->posPrefixPatternForCurrency ==
  172. affix_2->posPrefixPatternForCurrency &&
  173. affix_1->posSuffixPatternForCurrency ==
  174. affix_2->posSuffixPatternForCurrency &&
  175. affix_1->patternType == affix_2->patternType;
  176. }
  177. U_CDECL_END
  178. // *****************************************************************************
  179. // class DecimalFormat
  180. // *****************************************************************************
  181. UOBJECT_DEFINE_RTTI_IMPLEMENTATION(DecimalFormat)
  182. // Constants for characters used in programmatic (unlocalized) patterns.
  183. #define kPatternZeroDigit ((UChar)0x0030) /*'0'*/
  184. #define kPatternSignificantDigit ((UChar)0x0040) /*'@'*/
  185. #define kPatternGroupingSeparator ((UChar)0x002C) /*','*/
  186. #define kPatternDecimalSeparator ((UChar)0x002E) /*'.'*/
  187. #define kPatternPerMill ((UChar)0x2030)
  188. #define kPatternPercent ((UChar)0x0025) /*'%'*/
  189. #define kPatternDigit ((UChar)0x0023) /*'#'*/
  190. #define kPatternSeparator ((UChar)0x003B) /*';'*/
  191. #define kPatternExponent ((UChar)0x0045) /*'E'*/
  192. #define kPatternPlus ((UChar)0x002B) /*'+'*/
  193. #define kPatternMinus ((UChar)0x002D) /*'-'*/
  194. #define kPatternPadEscape ((UChar)0x002A) /*'*'*/
  195. #define kQuote ((UChar)0x0027) /*'\''*/
  196. /**
  197. * The CURRENCY_SIGN is the standard Unicode symbol for currency. It
  198. * is used in patterns and substitued with either the currency symbol,
  199. * or if it is doubled, with the international currency symbol. If the
  200. * CURRENCY_SIGN is seen in a pattern, then the decimal separator is
  201. * replaced with the monetary decimal separator.
  202. */
  203. #define kCurrencySign ((UChar)0x00A4)
  204. #define kDefaultPad ((UChar)0x0020) /* */
  205. const int32_t DecimalFormat::kDoubleIntegerDigits = 309;
  206. const int32_t DecimalFormat::kDoubleFractionDigits = 340;
  207. const int32_t DecimalFormat::kMaxScientificIntegerDigits = 8;
  208. /**
  209. * These are the tags we expect to see in normal resource bundle files associated
  210. * with a locale.
  211. */
  212. const char DecimalFormat::fgNumberPatterns[]="NumberPatterns"; // Deprecated - not used
  213. static const char fgNumberElements[]="NumberElements";
  214. static const char fgLatn[]="latn";
  215. static const char fgPatterns[]="patterns";
  216. static const char fgDecimalFormat[]="decimalFormat";
  217. static const char fgCurrencyFormat[]="currencyFormat";
  218. inline int32_t _min(int32_t a, int32_t b) { return (a<b) ? a : b; }
  219. inline int32_t _max(int32_t a, int32_t b) { return (a<b) ? b : a; }
  220. //------------------------------------------------------------------------------
  221. // Constructs a DecimalFormat instance in the default locale.
  222. DecimalFormat::DecimalFormat(UErrorCode& status) {
  223. init();
  224. UParseError parseError;
  225. construct(status, parseError);
  226. }
  227. //------------------------------------------------------------------------------
  228. // Constructs a DecimalFormat instance with the specified number format
  229. // pattern in the default locale.
  230. DecimalFormat::DecimalFormat(const UnicodeString& pattern,
  231. UErrorCode& status) {
  232. init();
  233. UParseError parseError;
  234. construct(status, parseError, &pattern);
  235. }
  236. //------------------------------------------------------------------------------
  237. // Constructs a DecimalFormat instance with the specified number format
  238. // pattern and the number format symbols in the default locale. The
  239. // created instance owns the symbols.
  240. DecimalFormat::DecimalFormat(const UnicodeString& pattern,
  241. DecimalFormatSymbols* symbolsToAdopt,
  242. UErrorCode& status) {
  243. init();
  244. UParseError parseError;
  245. if (symbolsToAdopt == NULL)
  246. status = U_ILLEGAL_ARGUMENT_ERROR;
  247. construct(status, parseError, &pattern, symbolsToAdopt);
  248. }
  249. DecimalFormat::DecimalFormat( const UnicodeString& pattern,
  250. DecimalFormatSymbols* symbolsToAdopt,
  251. UParseError& parseErr,
  252. UErrorCode& status) {
  253. init();
  254. if (symbolsToAdopt == NULL)
  255. status = U_ILLEGAL_ARGUMENT_ERROR;
  256. construct(status,parseErr, &pattern, symbolsToAdopt);
  257. }
  258. //------------------------------------------------------------------------------
  259. // Constructs a DecimalFormat instance with the specified number format
  260. // pattern and the number format symbols in the default locale. The
  261. // created instance owns the clone of the symbols.
  262. DecimalFormat::DecimalFormat(const UnicodeString& pattern,
  263. const DecimalFormatSymbols& symbols,
  264. UErrorCode& status) {
  265. init();
  266. UParseError parseError;
  267. construct(status, parseError, &pattern, new DecimalFormatSymbols(symbols));
  268. }
  269. //------------------------------------------------------------------------------
  270. // Constructs a DecimalFormat instance with the specified number format
  271. // pattern, the number format symbols, and the number format style.
  272. // The created instance owns the clone of the symbols.
  273. DecimalFormat::DecimalFormat(const UnicodeString& pattern,
  274. DecimalFormatSymbols* symbolsToAdopt,
  275. UNumberFormatStyle style,
  276. UErrorCode& status) {
  277. init();
  278. fStyle = style;
  279. UParseError parseError;
  280. construct(status, parseError, &pattern, symbolsToAdopt);
  281. }
  282. //-----------------------------------------------------------------------------
  283. // Common DecimalFormat initialization.
  284. // Put all fields of an uninitialized object into a known state.
  285. // Common code, shared by all constructors.
  286. // Can not fail. Leave the object in good enough shape that the destructor
  287. // or assignment operator can run successfully.
  288. void
  289. DecimalFormat::init() {
  290. fBoolFlags.clear();
  291. fStyle = UNUM_DECIMAL;
  292. fAffixPatternsForCurrency = NULL;
  293. fCurrencyPluralInfo = NULL;
  294. #if UCONFIG_HAVE_PARSEALLINPUT
  295. fParseAllInput = UNUM_MAYBE;
  296. #endif
  297. fStaticSets = NULL;
  298. fImpl = NULL;
  299. }
  300. //------------------------------------------------------------------------------
  301. // Constructs a DecimalFormat instance with the specified number format
  302. // pattern and the number format symbols in the desired locale. The
  303. // created instance owns the symbols.
  304. void
  305. DecimalFormat::construct(UErrorCode& status,
  306. UParseError& parseErr,
  307. const UnicodeString* pattern,
  308. DecimalFormatSymbols* symbolsToAdopt)
  309. {
  310. LocalPointer<DecimalFormatSymbols> adoptedSymbols(symbolsToAdopt);
  311. if (U_FAILURE(status))
  312. return;
  313. if (adoptedSymbols.isNull())
  314. {
  315. adoptedSymbols.adoptInstead(
  316. new DecimalFormatSymbols(Locale::getDefault(), status));
  317. if (adoptedSymbols.isNull() && U_SUCCESS(status)) {
  318. status = U_MEMORY_ALLOCATION_ERROR;
  319. }
  320. if (U_FAILURE(status)) {
  321. return;
  322. }
  323. }
  324. fStaticSets = DecimalFormatStaticSets::getStaticSets(status);
  325. if (U_FAILURE(status)) {
  326. return;
  327. }
  328. UnicodeString str;
  329. // Uses the default locale's number format pattern if there isn't
  330. // one specified.
  331. if (pattern == NULL)
  332. {
  333. UErrorCode nsStatus = U_ZERO_ERROR;
  334. LocalPointer<NumberingSystem> ns(
  335. NumberingSystem::createInstance(nsStatus));
  336. if (U_FAILURE(nsStatus)) {
  337. status = nsStatus;
  338. return;
  339. }
  340. int32_t len = 0;
  341. UResourceBundle *top = ures_open(NULL, Locale::getDefault().getName(), &status);
  342. UResourceBundle *resource = ures_getByKeyWithFallback(top, fgNumberElements, NULL, &status);
  343. resource = ures_getByKeyWithFallback(resource, ns->getName(), resource, &status);
  344. resource = ures_getByKeyWithFallback(resource, fgPatterns, resource, &status);
  345. const UChar *resStr = ures_getStringByKeyWithFallback(resource, fgDecimalFormat, &len, &status);
  346. if ( status == U_MISSING_RESOURCE_ERROR && uprv_strcmp(fgLatn,ns->getName())) {
  347. status = U_ZERO_ERROR;
  348. resource = ures_getByKeyWithFallback(top, fgNumberElements, resource, &status);
  349. resource = ures_getByKeyWithFallback(resource, fgLatn, resource, &status);
  350. resource = ures_getByKeyWithFallback(resource, fgPatterns, resource, &status);
  351. resStr = ures_getStringByKeyWithFallback(resource, fgDecimalFormat, &len, &status);
  352. }
  353. str.setTo(TRUE, resStr, len);
  354. pattern = &str;
  355. ures_close(resource);
  356. ures_close(top);
  357. }
  358. fImpl = new DecimalFormatImpl(this, *pattern, adoptedSymbols.getAlias(), parseErr, status);
  359. if (fImpl) {
  360. adoptedSymbols.orphan();
  361. } else if (U_SUCCESS(status)) {
  362. status = U_MEMORY_ALLOCATION_ERROR;
  363. }
  364. if (U_FAILURE(status)) {
  365. return;
  366. }
  367. if (U_FAILURE(status))
  368. {
  369. return;
  370. }
  371. const UnicodeString* patternUsed;
  372. UnicodeString currencyPluralPatternForOther;
  373. // apply pattern
  374. if (fStyle == UNUM_CURRENCY_PLURAL) {
  375. fCurrencyPluralInfo = new CurrencyPluralInfo(fImpl->fSymbols->getLocale(), status);
  376. if (U_FAILURE(status)) {
  377. return;
  378. }
  379. // the pattern used in format is not fixed until formatting,
  380. // in which, the number is known and
  381. // will be used to pick the right pattern based on plural count.
  382. // Here, set the pattern as the pattern of plural count == "other".
  383. // For most locale, the patterns are probably the same for all
  384. // plural count. If not, the right pattern need to be re-applied
  385. // during format.
  386. fCurrencyPluralInfo->getCurrencyPluralPattern(UNICODE_STRING("other", 5), currencyPluralPatternForOther);
  387. // TODO(refactor): Revisit, we are setting the pattern twice.
  388. fImpl->applyPatternFavorCurrencyPrecision(
  389. currencyPluralPatternForOther, status);
  390. patternUsed = &currencyPluralPatternForOther;
  391. } else {
  392. patternUsed = pattern;
  393. }
  394. if (patternUsed->indexOf(kCurrencySign) != -1) {
  395. // initialize for currency, not only for plural format,
  396. // but also for mix parsing
  397. handleCurrencySignInPattern(status);
  398. }
  399. }
  400. void
  401. DecimalFormat::handleCurrencySignInPattern(UErrorCode& status) {
  402. // initialize for currency, not only for plural format,
  403. // but also for mix parsing
  404. if (U_FAILURE(status)) {
  405. return;
  406. }
  407. if (fCurrencyPluralInfo == NULL) {
  408. fCurrencyPluralInfo = new CurrencyPluralInfo(fImpl->fSymbols->getLocale(), status);
  409. if (U_FAILURE(status)) {
  410. return;
  411. }
  412. }
  413. // need it for mix parsing
  414. if (fAffixPatternsForCurrency == NULL) {
  415. setupCurrencyAffixPatterns(status);
  416. }
  417. }
  418. static void
  419. applyPatternWithNoSideEffects(
  420. const UnicodeString& pattern,
  421. UParseError& parseError,
  422. UnicodeString &negPrefix,
  423. UnicodeString &negSuffix,
  424. UnicodeString &posPrefix,
  425. UnicodeString &posSuffix,
  426. UErrorCode& status) {
  427. if (U_FAILURE(status))
  428. {
  429. return;
  430. }
  431. DecimalFormatPatternParser patternParser;
  432. DecimalFormatPattern out;
  433. patternParser.applyPatternWithoutExpandAffix(
  434. pattern,
  435. out,
  436. parseError,
  437. status);
  438. if (U_FAILURE(status)) {
  439. return;
  440. }
  441. negPrefix = out.fNegPrefixPattern;
  442. negSuffix = out.fNegSuffixPattern;
  443. posPrefix = out.fPosPrefixPattern;
  444. posSuffix = out.fPosSuffixPattern;
  445. }
  446. void
  447. DecimalFormat::setupCurrencyAffixPatterns(UErrorCode& status) {
  448. if (U_FAILURE(status)) {
  449. return;
  450. }
  451. UParseError parseErr;
  452. fAffixPatternsForCurrency = initHashForAffixPattern(status);
  453. if (U_FAILURE(status)) {
  454. return;
  455. }
  456. NumberingSystem *ns = NumberingSystem::createInstance(fImpl->fSymbols->getLocale(),status);
  457. if (U_FAILURE(status)) {
  458. return;
  459. }
  460. // Save the default currency patterns of this locale.
  461. // Here, chose onlyApplyPatternWithoutExpandAffix without
  462. // expanding the affix patterns into affixes.
  463. UnicodeString currencyPattern;
  464. UErrorCode error = U_ZERO_ERROR;
  465. UResourceBundle *resource = ures_open(NULL, fImpl->fSymbols->getLocale().getName(), &error);
  466. UResourceBundle *numElements = ures_getByKeyWithFallback(resource, fgNumberElements, NULL, &error);
  467. resource = ures_getByKeyWithFallback(numElements, ns->getName(), resource, &error);
  468. resource = ures_getByKeyWithFallback(resource, fgPatterns, resource, &error);
  469. int32_t patLen = 0;
  470. const UChar *patResStr = ures_getStringByKeyWithFallback(resource, fgCurrencyFormat, &patLen, &error);
  471. if ( error == U_MISSING_RESOURCE_ERROR && uprv_strcmp(ns->getName(),fgLatn)) {
  472. error = U_ZERO_ERROR;
  473. resource = ures_getByKeyWithFallback(numElements, fgLatn, resource, &error);
  474. resource = ures_getByKeyWithFallback(resource, fgPatterns, resource, &error);
  475. patResStr = ures_getStringByKeyWithFallback(resource, fgCurrencyFormat, &patLen, &error);
  476. }
  477. ures_close(numElements);
  478. ures_close(resource);
  479. delete ns;
  480. if (U_SUCCESS(error)) {
  481. UnicodeString negPrefix;
  482. UnicodeString negSuffix;
  483. UnicodeString posPrefix;
  484. UnicodeString posSuffix;
  485. applyPatternWithNoSideEffects(UnicodeString(patResStr, patLen),
  486. parseErr,
  487. negPrefix, negSuffix, posPrefix, posSuffix, status);
  488. AffixPatternsForCurrency* affixPtn = new AffixPatternsForCurrency(
  489. negPrefix,
  490. negSuffix,
  491. posPrefix,
  492. posSuffix,
  493. UCURR_SYMBOL_NAME);
  494. fAffixPatternsForCurrency->put(UNICODE_STRING("default", 7), affixPtn, status);
  495. }
  496. // save the unique currency plural patterns of this locale.
  497. Hashtable* pluralPtn = fCurrencyPluralInfo->fPluralCountToCurrencyUnitPattern;
  498. const UHashElement* element = NULL;
  499. int32_t pos = UHASH_FIRST;
  500. Hashtable pluralPatternSet;
  501. while ((element = pluralPtn->nextElement(pos)) != NULL) {
  502. const UHashTok valueTok = element->value;
  503. const UnicodeString* value = (UnicodeString*)valueTok.pointer;
  504. const UHashTok keyTok = element->key;
  505. const UnicodeString* key = (UnicodeString*)keyTok.pointer;
  506. if (pluralPatternSet.geti(*value) != 1) {
  507. UnicodeString negPrefix;
  508. UnicodeString negSuffix;
  509. UnicodeString posPrefix;
  510. UnicodeString posSuffix;
  511. pluralPatternSet.puti(*value, 1, status);
  512. applyPatternWithNoSideEffects(
  513. *value, parseErr,
  514. negPrefix, negSuffix, posPrefix, posSuffix, status);
  515. AffixPatternsForCurrency* affixPtn = new AffixPatternsForCurrency(
  516. negPrefix,
  517. negSuffix,
  518. posPrefix,
  519. posSuffix,
  520. UCURR_LONG_NAME);
  521. fAffixPatternsForCurrency->put(*key, affixPtn, status);
  522. }
  523. }
  524. }
  525. //------------------------------------------------------------------------------
  526. DecimalFormat::~DecimalFormat()
  527. {
  528. deleteHashForAffixPattern();
  529. delete fCurrencyPluralInfo;
  530. delete fImpl;
  531. }
  532. //------------------------------------------------------------------------------
  533. // copy constructor
  534. DecimalFormat::DecimalFormat(const DecimalFormat &source) :
  535. NumberFormat(source) {
  536. init();
  537. *this = source;
  538. }
  539. //------------------------------------------------------------------------------
  540. // assignment operator
  541. template <class T>
  542. static void _clone_ptr(T** pdest, const T* source) {
  543. delete *pdest;
  544. if (source == NULL) {
  545. *pdest = NULL;
  546. } else {
  547. *pdest = static_cast<T*>(source->clone());
  548. }
  549. }
  550. DecimalFormat&
  551. DecimalFormat::operator=(const DecimalFormat& rhs)
  552. {
  553. if(this != &rhs) {
  554. UErrorCode status = U_ZERO_ERROR;
  555. NumberFormat::operator=(rhs);
  556. if (fImpl == NULL) {
  557. fImpl = new DecimalFormatImpl(this, *rhs.fImpl, status);
  558. } else {
  559. fImpl->assign(*rhs.fImpl, status);
  560. }
  561. fStaticSets = DecimalFormatStaticSets::getStaticSets(status);
  562. fStyle = rhs.fStyle;
  563. _clone_ptr(&fCurrencyPluralInfo, rhs.fCurrencyPluralInfo);
  564. deleteHashForAffixPattern();
  565. if (rhs.fAffixPatternsForCurrency) {
  566. UErrorCode status = U_ZERO_ERROR;
  567. fAffixPatternsForCurrency = initHashForAffixPattern(status);
  568. copyHashForAffixPattern(rhs.fAffixPatternsForCurrency,
  569. fAffixPatternsForCurrency, status);
  570. }
  571. }
  572. return *this;
  573. }
  574. //------------------------------------------------------------------------------
  575. UBool
  576. DecimalFormat::operator==(const Format& that) const
  577. {
  578. if (this == &that)
  579. return TRUE;
  580. // NumberFormat::operator== guarantees this cast is safe
  581. const DecimalFormat* other = (DecimalFormat*)&that;
  582. return (
  583. NumberFormat::operator==(that) &&
  584. fBoolFlags.getAll() == other->fBoolFlags.getAll() &&
  585. *fImpl == *other->fImpl);
  586. }
  587. //------------------------------------------------------------------------------
  588. Format*
  589. DecimalFormat::clone() const
  590. {
  591. return new DecimalFormat(*this);
  592. }
  593. FixedDecimal
  594. DecimalFormat::getFixedDecimal(double number, UErrorCode &status) const {
  595. VisibleDigitsWithExponent digits;
  596. initVisibleDigitsWithExponent(number, digits, status);
  597. if (U_FAILURE(status)) {
  598. return FixedDecimal();
  599. }
  600. return FixedDecimal(digits.getMantissa());
  601. }
  602. VisibleDigitsWithExponent &
  603. DecimalFormat::initVisibleDigitsWithExponent(
  604. double number,
  605. VisibleDigitsWithExponent &digits,
  606. UErrorCode &status) const {
  607. return fImpl->initVisibleDigitsWithExponent(number, digits, status);
  608. }
  609. FixedDecimal
  610. DecimalFormat::getFixedDecimal(const Formattable &number, UErrorCode &status) const {
  611. VisibleDigitsWithExponent digits;
  612. initVisibleDigitsWithExponent(number, digits, status);
  613. if (U_FAILURE(status)) {
  614. return FixedDecimal();
  615. }
  616. return FixedDecimal(digits.getMantissa());
  617. }
  618. VisibleDigitsWithExponent &
  619. DecimalFormat::initVisibleDigitsWithExponent(
  620. const Formattable &number,
  621. VisibleDigitsWithExponent &digits,
  622. UErrorCode &status) const {
  623. if (U_FAILURE(status)) {
  624. return digits;
  625. }
  626. if (!number.isNumeric()) {
  627. status = U_ILLEGAL_ARGUMENT_ERROR;
  628. return digits;
  629. }
  630. DigitList *dl = number.getDigitList();
  631. if (dl != NULL) {
  632. DigitList dlCopy(*dl);
  633. return fImpl->initVisibleDigitsWithExponent(
  634. dlCopy, digits, status);
  635. }
  636. Formattable::Type type = number.getType();
  637. if (type == Formattable::kDouble || type == Formattable::kLong) {
  638. return fImpl->initVisibleDigitsWithExponent(
  639. number.getDouble(status), digits, status);
  640. }
  641. return fImpl->initVisibleDigitsWithExponent(
  642. number.getInt64(), digits, status);
  643. }
  644. // Create a fixed decimal from a DigitList.
  645. // The digit list may be modified.
  646. // Internal function only.
  647. FixedDecimal
  648. DecimalFormat::getFixedDecimal(DigitList &number, UErrorCode &status) const {
  649. VisibleDigitsWithExponent digits;
  650. initVisibleDigitsWithExponent(number, digits, status);
  651. if (U_FAILURE(status)) {
  652. return FixedDecimal();
  653. }
  654. return FixedDecimal(digits.getMantissa());
  655. }
  656. VisibleDigitsWithExponent &
  657. DecimalFormat::initVisibleDigitsWithExponent(
  658. DigitList &number,
  659. VisibleDigitsWithExponent &digits,
  660. UErrorCode &status) const {
  661. return fImpl->initVisibleDigitsWithExponent(
  662. number, digits, status);
  663. }
  664. //------------------------------------------------------------------------------
  665. UnicodeString&
  666. DecimalFormat::format(int32_t number,
  667. UnicodeString& appendTo,
  668. FieldPosition& fieldPosition) const
  669. {
  670. UErrorCode status = U_ZERO_ERROR;
  671. return fImpl->format(number, appendTo, fieldPosition, status);
  672. }
  673. UnicodeString&
  674. DecimalFormat::format(int32_t number,
  675. UnicodeString& appendTo,
  676. FieldPosition& fieldPosition,
  677. UErrorCode& status) const
  678. {
  679. return fImpl->format(number, appendTo, fieldPosition, status);
  680. }
  681. UnicodeString&
  682. DecimalFormat::format(int32_t number,
  683. UnicodeString& appendTo,
  684. FieldPositionIterator* posIter,
  685. UErrorCode& status) const
  686. {
  687. return fImpl->format(number, appendTo, posIter, status);
  688. }
  689. //------------------------------------------------------------------------------
  690. UnicodeString&
  691. DecimalFormat::format(int64_t number,
  692. UnicodeString& appendTo,
  693. FieldPosition& fieldPosition) const
  694. {
  695. UErrorCode status = U_ZERO_ERROR; /* ignored */
  696. return fImpl->format(number, appendTo, fieldPosition, status);
  697. }
  698. UnicodeString&
  699. DecimalFormat::format(int64_t number,
  700. UnicodeString& appendTo,
  701. FieldPosition& fieldPosition,
  702. UErrorCode& status) const
  703. {
  704. return fImpl->format(number, appendTo, fieldPosition, status);
  705. }
  706. UnicodeString&
  707. DecimalFormat::format(int64_t number,
  708. UnicodeString& appendTo,
  709. FieldPositionIterator* posIter,
  710. UErrorCode& status) const
  711. {
  712. return fImpl->format(number, appendTo, posIter, status);
  713. }
  714. //------------------------------------------------------------------------------
  715. UnicodeString&
  716. DecimalFormat::format( double number,
  717. UnicodeString& appendTo,
  718. FieldPosition& fieldPosition) const
  719. {
  720. UErrorCode status = U_ZERO_ERROR; /* ignored */
  721. return fImpl->format(number, appendTo, fieldPosition, status);
  722. }
  723. UnicodeString&
  724. DecimalFormat::format( double number,
  725. UnicodeString& appendTo,
  726. FieldPosition& fieldPosition,
  727. UErrorCode& status) const
  728. {
  729. return fImpl->format(number, appendTo, fieldPosition, status);
  730. }
  731. UnicodeString&
  732. DecimalFormat::format( double number,
  733. UnicodeString& appendTo,
  734. FieldPositionIterator* posIter,
  735. UErrorCode& status) const
  736. {
  737. return fImpl->format(number, appendTo, posIter, status);
  738. }
  739. //------------------------------------------------------------------------------
  740. UnicodeString&
  741. DecimalFormat::format(StringPiece number,
  742. UnicodeString &toAppendTo,
  743. FieldPositionIterator *posIter,
  744. UErrorCode &status) const
  745. {
  746. return fImpl->format(number, toAppendTo, posIter, status);
  747. }
  748. UnicodeString&
  749. DecimalFormat::format(const DigitList &number,
  750. UnicodeString &appendTo,
  751. FieldPositionIterator *posIter,
  752. UErrorCode &status) const {
  753. return fImpl->format(number, appendTo, posIter, status);
  754. }
  755. UnicodeString&
  756. DecimalFormat::format(const DigitList &number,
  757. UnicodeString& appendTo,
  758. FieldPosition& pos,
  759. UErrorCode &status) const {
  760. return fImpl->format(number, appendTo, pos, status);
  761. }
  762. UnicodeString&
  763. DecimalFormat::format(const VisibleDigitsWithExponent &number,
  764. UnicodeString &appendTo,
  765. FieldPositionIterator *posIter,
  766. UErrorCode &status) const {
  767. return fImpl->format(number, appendTo, posIter, status);
  768. }
  769. UnicodeString&
  770. DecimalFormat::format(const VisibleDigitsWithExponent &number,
  771. UnicodeString& appendTo,
  772. FieldPosition& pos,
  773. UErrorCode &status) const {
  774. return fImpl->format(number, appendTo, pos, status);
  775. }
  776. DigitList&
  777. DecimalFormat::_round(const DigitList& number, DigitList& adjustedNum, UBool& isNegative, UErrorCode& status) const {
  778. adjustedNum = number;
  779. fImpl->round(adjustedNum, status);
  780. isNegative = !adjustedNum.isPositive();
  781. return adjustedNum;
  782. }
  783. void
  784. DecimalFormat::parse(const UnicodeString& text,
  785. Formattable& result,
  786. ParsePosition& parsePosition) const {
  787. parse(text, result, parsePosition, NULL);
  788. }
  789. CurrencyAmount* DecimalFormat::parseCurrency(const UnicodeString& text,
  790. ParsePosition& pos) const {
  791. Formattable parseResult;
  792. int32_t start = pos.getIndex();
  793. UChar curbuf[4] = {};
  794. parse(text, parseResult, pos, curbuf);
  795. if (pos.getIndex() != start) {
  796. UErrorCode ec = U_ZERO_ERROR;
  797. LocalPointer<CurrencyAmount> currAmt(new CurrencyAmount(parseResult, curbuf, ec), ec);
  798. if (U_FAILURE(ec)) {
  799. pos.setIndex(start); // indicate failure
  800. } else {
  801. return currAmt.orphan();
  802. }
  803. }
  804. return NULL;
  805. }
  806. /**
  807. * Parses the given text as a number, optionally providing a currency amount.
  808. * @param text the string to parse
  809. * @param result output parameter for the numeric result.
  810. * @param parsePosition input-output position; on input, the
  811. * position within text to match; must have 0 <= pos.getIndex() <
  812. * text.length(); on output, the position after the last matched
  813. * character. If the parse fails, the position in unchanged upon
  814. * output.
  815. * @param currency if non-NULL, it should point to a 4-UChar buffer.
  816. * In this case the text is parsed as a currency format, and the
  817. * ISO 4217 code for the parsed currency is put into the buffer.
  818. * Otherwise the text is parsed as a non-currency format.
  819. */
  820. void DecimalFormat::parse(const UnicodeString& text,
  821. Formattable& result,
  822. ParsePosition& parsePosition,
  823. UChar* currency) const {
  824. int32_t startIdx, backup;
  825. int32_t i = startIdx = backup = parsePosition.getIndex();
  826. // clear any old contents in the result. In particular, clears any DigitList
  827. // that it may be holding.
  828. result.setLong(0);
  829. if (currency != NULL) {
  830. for (int32_t ci=0; ci<4; ci++) {
  831. currency[ci] = 0;
  832. }
  833. }
  834. // Handle NaN as a special case:
  835. int32_t formatWidth = fImpl->getOldFormatWidth();
  836. // Skip padding characters, if around prefix
  837. if (formatWidth > 0 && (
  838. fImpl->fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforePrefix ||
  839. fImpl->fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterPrefix)) {
  840. i = skipPadding(text, i);
  841. }
  842. if (isLenient()) {
  843. // skip any leading whitespace
  844. i = backup = skipUWhiteSpace(text, i);
  845. }
  846. // If the text is composed of the representation of NaN, returns NaN.length
  847. const UnicodeString *nan = &fImpl->getConstSymbol(DecimalFormatSymbols::kNaNSymbol);
  848. int32_t nanLen = (text.compare(i, nan->length(), *nan)
  849. ? 0 : nan->length());
  850. if (nanLen) {
  851. i += nanLen;
  852. if (formatWidth > 0 && (fImpl->fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforeSuffix || fImpl->fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterSuffix)) {
  853. i = skipPadding(text, i);
  854. }
  855. parsePosition.setIndex(i);
  856. result.setDouble(uprv_getNaN());
  857. return;
  858. }
  859. // NaN parse failed; start over
  860. i = backup;
  861. parsePosition.setIndex(i);
  862. // status is used to record whether a number is infinite.
  863. UBool status[fgStatusLength];
  864. DigitList *digits = result.getInternalDigitList(); // get one from the stack buffer
  865. if (digits == NULL) {
  866. return; // no way to report error from here.
  867. }
  868. if (fImpl->fMonetary) {
  869. if (!parseForCurrency(text, parsePosition, *digits,
  870. status, currency)) {
  871. return;
  872. }
  873. } else {
  874. if (!subparse(text,
  875. &fImpl->fAffixes.fNegativePrefix.getOtherVariant().toString(),
  876. &fImpl->fAffixes.fNegativeSuffix.getOtherVariant().toString(),
  877. &fImpl->fAffixes.fPositivePrefix.getOtherVariant().toString(),
  878. &fImpl->fAffixes.fPositiveSuffix.getOtherVariant().toString(),
  879. FALSE, UCURR_SYMBOL_NAME,
  880. parsePosition, *digits, status, currency)) {
  881. debug("!subparse(...) - rewind");
  882. parsePosition.setIndex(startIdx);
  883. return;
  884. }
  885. }
  886. // Handle infinity
  887. if (status[fgStatusInfinite]) {
  888. double inf = uprv_getInfinity();
  889. result.setDouble(digits->isPositive() ? inf : -inf);
  890. // TODO: set the dl to infinity, and let it fall into the code below.
  891. }
  892. else {
  893. if (!fImpl->fMultiplier.isZero()) {
  894. UErrorCode ec = U_ZERO_ERROR;
  895. digits->div(fImpl->fMultiplier, ec);
  896. }
  897. if (fImpl->fScale != 0) {
  898. DigitList ten;
  899. ten.set((int32_t)10);
  900. if (fImpl->fScale > 0) {
  901. for (int32_t i = fImpl->fScale; i > 0; i--) {
  902. UErrorCode ec = U_ZERO_ERROR;
  903. digits->div(ten,ec);
  904. }
  905. } else {
  906. for (int32_t i = fImpl->fScale; i < 0; i++) {
  907. UErrorCode ec = U_ZERO_ERROR;
  908. digits->mult(ten,ec);
  909. }
  910. }
  911. }
  912. // Negative zero special case:
  913. // if parsing integerOnly, change to +0, which goes into an int32 in a Formattable.
  914. // if not parsing integerOnly, leave as -0, which a double can represent.
  915. if (digits->isZero() && !digits->isPositive() && isParseIntegerOnly()) {
  916. digits->setPositive(TRUE);
  917. }
  918. result.adoptDigitList(digits);
  919. }
  920. }
  921. UBool
  922. DecimalFormat::parseForCurrency(const UnicodeString& text,
  923. ParsePosition& parsePosition,
  924. DigitList& digits,
  925. UBool* status,
  926. UChar* currency) const {
  927. UnicodeString positivePrefix;
  928. UnicodeString positiveSuffix;
  929. UnicodeString negativePrefix;
  930. UnicodeString negativeSuffix;
  931. fImpl->fPositivePrefixPattern.toString(positivePrefix);
  932. fImpl->fPositiveSuffixPattern.toString(positiveSuffix);
  933. fImpl->fNegativePrefixPattern.toString(negativePrefix);
  934. fImpl->fNegativeSuffixPattern.toString(negativeSuffix);
  935. int origPos = parsePosition.getIndex();
  936. int maxPosIndex = origPos;
  937. int maxErrorPos = -1;
  938. // First, parse against current pattern.
  939. // Since current pattern could be set by applyPattern(),
  940. // it could be an arbitrary pattern, and it may not be the one
  941. // defined in current locale.
  942. UBool tmpStatus[fgStatusLength];
  943. ParsePosition tmpPos(origPos);
  944. DigitList tmpDigitList;
  945. UBool found;
  946. if (fStyle == UNUM_CURRENCY_PLURAL) {
  947. found = subparse(text,
  948. &negativePrefix, &negativeSuffix,
  949. &positivePrefix, &positiveSuffix,
  950. TRUE, UCURR_LONG_NAME,
  951. tmpPos, tmpDigitList, tmpStatus, currency);
  952. } else {
  953. found = subparse(text,
  954. &negativePrefix, &negativeSuffix,
  955. &positivePrefix, &positiveSuffix,
  956. TRUE, UCURR_SYMBOL_NAME,
  957. tmpPos, tmpDigitList, tmpStatus, currency);
  958. }
  959. if (found) {
  960. if (tmpPos.getIndex() > maxPosIndex) {
  961. maxPosIndex = tmpPos.getIndex();
  962. for (int32_t i = 0; i < fgStatusLength; ++i) {
  963. status[i] = tmpStatus[i];
  964. }
  965. digits = tmpDigitList;
  966. }
  967. } else {
  968. maxErrorPos = tmpPos.getErrorIndex();
  969. }
  970. // Then, parse against affix patterns.
  971. // Those are currency patterns and currency plural patterns.
  972. int32_t pos = UHASH_FIRST;
  973. const UHashElement* element = NULL;
  974. while ( (element = fAffixPatternsForCurrency->nextElement(pos)) != NULL ) {
  975. const UHashTok valueTok = element->value;
  976. const AffixPatternsForCurrency* affixPtn = (AffixPatternsForCurrency*)valueTok.pointer;
  977. UBool tmpStatus[fgStatusLength];
  978. ParsePosition tmpPos(origPos);
  979. DigitList tmpDigitList;
  980. #ifdef FMT_DEBUG
  981. debug("trying affix for currency..");
  982. affixPtn->dump();
  983. #endif
  984. UBool result = subparse(text,
  985. &affixPtn->negPrefixPatternForCurrency,
  986. &affixPtn->negSuffixPatternForCurrency,
  987. &affixPtn->posPrefixPatternForCurrency,
  988. &affixPtn->posSuffixPatternForCurrency,
  989. TRUE, affixPtn->patternType,
  990. tmpPos, tmpDigitList, tmpStatus, currency);
  991. if (result) {
  992. found = true;
  993. if (tmpPos.getIndex() > maxPosIndex) {
  994. maxPosIndex = tmpPos.getIndex();
  995. for (int32_t i = 0; i < fgStatusLength; ++i) {
  996. status[i] = tmpStatus[i];
  997. }
  998. digits = tmpDigitList;
  999. }
  1000. } else {
  1001. maxErrorPos = (tmpPos.getErrorIndex() > maxErrorPos) ?
  1002. tmpPos.getErrorIndex() : maxErrorPos;
  1003. }
  1004. }
  1005. // Finally, parse against simple affix to find the match.
  1006. // For example, in TestMonster suite,
  1007. // if the to-be-parsed text is "-\u00A40,00".
  1008. // complexAffixCompare will not find match,
  1009. // since there is no ISO code matches "\u00A4",
  1010. // and the parse stops at "\u00A4".
  1011. // We will just use simple affix comparison (look for exact match)
  1012. // to pass it.
  1013. //
  1014. // TODO: We should parse against simple affix first when
  1015. // output currency is not requested. After the complex currency
  1016. // parsing implementation was introduced, the default currency
  1017. // instance parsing slowed down because of the new code flow.
  1018. // I filed #10312 - Yoshito
  1019. UBool tmpStatus_2[fgStatusLength];
  1020. ParsePosition tmpPos_2(origPos);
  1021. DigitList tmpDigitList_2;
  1022. // Disable complex currency parsing and try it again.
  1023. UBool result = subparse(text,
  1024. &fImpl->fAffixes.fNegativePrefix.getOtherVariant().toString(),
  1025. &fImpl->fAffixes.fNegativeSuffix.getOtherVariant().toString(),
  1026. &fImpl->fAffixes.fPositivePrefix.getOtherVariant().toString(),
  1027. &fImpl->fAffixes.fPositiveSuffix.getOtherVariant().toString(),
  1028. FALSE /* disable complex currency parsing */, UCURR_SYMBOL_NAME,
  1029. tmpPos_2, tmpDigitList_2, tmpStatus_2,
  1030. currency);
  1031. if (result) {
  1032. if (tmpPos_2.getIndex() > maxPosIndex) {
  1033. maxPosIndex = tmpPos_2.getIndex();
  1034. for (int32_t i = 0; i < fgStatusLength; ++i) {
  1035. status[i] = tmpStatus_2[i];
  1036. }
  1037. digits = tmpDigitList_2;
  1038. }
  1039. found = true;
  1040. } else {
  1041. maxErrorPos = (tmpPos_2.getErrorIndex() > maxErrorPos) ?
  1042. tmpPos_2.getErrorIndex() : maxErrorPos;
  1043. }
  1044. if (!found) {
  1045. //parsePosition.setIndex(origPos);
  1046. parsePosition.setErrorIndex(maxErrorPos);
  1047. } else {
  1048. parsePosition.setIndex(maxPosIndex);
  1049. parsePosition.setErrorIndex(-1);
  1050. }
  1051. return found;
  1052. }
  1053. /**
  1054. * Parse the given text into a number. The text is parsed beginning at
  1055. * parsePosition, until an unparseable character is seen.
  1056. * @param text the string to parse.
  1057. * @param negPrefix negative prefix.
  1058. * @param negSuffix negative suffix.
  1059. * @param posPrefix positive prefix.
  1060. * @param posSuffix positive suffix.
  1061. * @param complexCurrencyParsing whether it is complex currency parsing or not.
  1062. * @param type the currency type to parse against, LONG_NAME only or not.
  1063. * @param parsePosition The position at which to being parsing. Upon
  1064. * return, the first unparsed character.
  1065. * @param digits the DigitList to set to the parsed value.
  1066. * @param status output param containing boolean status flags indicating
  1067. * whether the value was infinite and whether it was positive.
  1068. * @param currency return value for parsed currency, for generic
  1069. * currency parsing mode, or NULL for normal parsing. In generic
  1070. * currency parsing mode, any currency is parsed, not just the
  1071. * currency that this formatter is set to.
  1072. */
  1073. UBool DecimalFormat::subparse(const UnicodeString& text,
  1074. const UnicodeString* negPrefix,
  1075. const UnicodeString* negSuffix,
  1076. const UnicodeString* posPrefix,
  1077. const UnicodeString* posSuffix,
  1078. UBool complexCurrencyParsing,
  1079. int8_t type,
  1080. ParsePosition& parsePosition,
  1081. DigitList& digits, UBool* status,
  1082. UChar* currency) const
  1083. {
  1084. // The parsing process builds up the number as char string, in the neutral format that
  1085. // will be acceptable to the decNumber library, then at the end passes that string
  1086. // off for conversion to a decNumber.
  1087. UErrorCode err = U_ZERO_ERROR;
  1088. CharString parsedNum;
  1089. digits.setToZero();
  1090. int32_t position = parsePosition.getIndex();
  1091. int32_t oldStart = position;
  1092. int32_t textLength = text.length(); // One less pointer to follow
  1093. UBool strictParse = !isLenient();
  1094. UChar32 zero = fImpl->getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0);
  1095. const UnicodeString *groupingString = &fImpl->getConstSymbol(
  1096. !fImpl->fMonetary ?
  1097. DecimalFormatSymbols::kGroupingSeparatorSymbol : DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol);
  1098. UChar32 groupingChar = groupingString->char32At(0);
  1099. int32_t groupingStringLength = groupingString->length();
  1100. int32_t groupingCharLength = U16_LENGTH(groupingChar);
  1101. UBool groupingUsed = isGroupingUsed();
  1102. #ifdef FMT_DEBUG
  1103. UChar dbgbuf[300];
  1104. UnicodeString s(dbgbuf,0,300);;
  1105. s.append((UnicodeString)"PARSE \"").append(text.tempSubString(position)).append((UnicodeString)"\" " );
  1106. #define DBGAPPD(x) if(x) { s.append(UnicodeString(#x "=")); if(x->isEmpty()) { s.append(UnicodeString("<empty>")); } else { s.append(*x); } s.append(UnicodeString(" ")); } else { s.append(UnicodeString(#x "=NULL ")); }
  1107. DBGAPPD(negPrefix);
  1108. DBGAPPD(negSuffix);
  1109. DBGAPPD(posPrefix);
  1110. DBGAPPD(posSuffix);
  1111. debugout(s);
  1112. #endif
  1113. UBool fastParseOk = false; /* TRUE iff fast parse is OK */
  1114. // UBool fastParseHadDecimal = FALSE; /* true if fast parse saw a decimal point. */
  1115. if((fImpl->isParseFastpath()) && !fImpl->fMonetary &&
  1116. text.length()>0 &&
  1117. text.length()<32 &&
  1118. (posPrefix==NULL||posPrefix->isEmpty()) &&
  1119. (posSuffix==NULL||posSuffix->isEmpty()) &&
  1120. // (negPrefix==NULL||negPrefix->isEmpty()) &&
  1121. // (negSuffix==NULL||(negSuffix->isEmpty()) ) &&
  1122. TRUE) { // optimized path
  1123. int j=position;
  1124. int l=text.length();
  1125. int digitCount=0;
  1126. UChar32 ch = text.char32At(j);
  1127. const UnicodeString *decimalString = &fImpl->getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol);
  1128. UChar32 decimalChar = 0;
  1129. UBool intOnly = FALSE;
  1130. UChar32 lookForGroup = (groupingUsed&&intOnly&&strictParse)?groupingChar:0;
  1131. int32_t decimalCount = decimalString->countChar32(0,3);
  1132. if(isParseIntegerOnly()) {
  1133. decimalChar = 0; // not allowed
  1134. intOnly = TRUE; // Don't look for decimals.
  1135. } else if(decimalCount==1) {
  1136. decimalChar = decimalString->char32At(0); // Look for this decimal
  1137. } else if(decimalCount==0) {
  1138. decimalChar=0; // NO decimal set
  1139. } else {
  1140. j=l+1;//Set counter to end of line, so that we break. Unknown decimal situation.
  1141. }
  1142. #ifdef FMT_DEBUG
  1143. printf("Preparing to do fastpath parse: decimalChar=U+%04X, groupingChar=U+%04X, first ch=U+%04X intOnly=%c strictParse=%c\n",
  1144. decimalChar, groupingChar, ch,
  1145. (intOnly)?'y':'n',
  1146. (strictParse)?'y':'n');
  1147. #endif
  1148. if(ch==0x002D) { // '-'
  1149. j=l+1;//=break - negative number.
  1150. /*
  1151. parsedNum.append('-',err);
  1152. j+=U16_LENGTH(ch);
  1153. if(j<l) ch = text.char32At(j);
  1154. */
  1155. } else {
  1156. parsedNum.append('+',err);
  1157. }
  1158. while(j<l) {
  1159. int32_t digit = ch - zero;
  1160. if(digit >=0 && digit <= 9) {
  1161. parsedNum.append((char)(digit + '0'), err);
  1162. if((digitCount>0) || digit!=0 || j==(l-1)) {
  1163. digitCount++;
  1164. }
  1165. } else if(ch == 0) { // break out
  1166. digitCount=-1;
  1167. break;
  1168. } else if(ch == decimalChar) {
  1169. parsedNum.append((char)('.'), err);
  1170. decimalChar=0; // no more decimals.
  1171. // fastParseHadDecimal=TRUE;
  1172. } else if(ch == lookForGroup) {
  1173. // ignore grouping char. No decimals, so it has to be an ignorable grouping sep
  1174. } else if(intOnly && (lookForGroup!=0) && !u_isdigit(ch)) {
  1175. // parsing integer only and can fall through
  1176. } else {
  1177. digitCount=-1; // fail - fall through to slow parse
  1178. break;
  1179. }
  1180. j+=U16_LENGTH(ch);
  1181. ch = text.char32At(j); // for next
  1182. }
  1183. if(
  1184. ((j==l)||intOnly) // end OR only parsing integer
  1185. && (digitCount>0)) { // and have at least one digit
  1186. fastParseOk=true; // Fast parse OK!
  1187. #ifdef SKIP_OPT
  1188. debug("SKIP_OPT");
  1189. /* for testing, try it the slow way. also */
  1190. fastParseOk=false;
  1191. parsedNum.clear();
  1192. #else
  1193. parsePosition.setIndex(position=j);
  1194. status[fgStatusInfinite]=false;
  1195. #endif
  1196. } else {
  1197. // was not OK. reset, retry
  1198. #ifdef FMT_DEBUG
  1199. printf("Fall through: j=%d, l=%d, digitCount=%d\n", j, l, digitCount);
  1200. #endif
  1201. parsedNum.clear();
  1202. }
  1203. } else {
  1204. #ifdef FMT_DEBUG
  1205. printf("Could not fastpath parse. ");
  1206. printf("text.length()=%d ", text.length());
  1207. printf("posPrefix=%p posSuffix=%p ", posPrefix, posSuffix);
  1208. printf("\n");
  1209. #endif
  1210. }
  1211. UnicodeString formatPattern;
  1212. toPattern(formatPattern);
  1213. if(!fastParseOk
  1214. #if UCONFIG_HAVE_PARSEALLINPUT
  1215. && fParseAllInput!=UNUM_YES
  1216. #endif
  1217. )
  1218. {
  1219. int32_t formatWidth = fImpl->getOldFormatWidth();
  1220. // Match padding before prefix
  1221. if (formatWidth > 0 && fImpl->fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforePrefix) {
  1222. position = skipPadding(text, position);
  1223. }
  1224. // Match positive and negative prefixes; prefer longest match.
  1225. int32_t posMatch = compareAffix(text, position, FALSE, TRUE, posPrefix, complexCurrencyParsing, type, currency);
  1226. int32_t negMatch = compareAffix(text, position, TRUE, TRUE, negPrefix, complexCurrencyParsing, type, currency);
  1227. if (posMatch >= 0 && negMatch >= 0) {
  1228. if (posMatch > negMatch) {
  1229. negMatch = -1;
  1230. } else if (negMatch > posMatch) {
  1231. posMatch = -1;
  1232. }
  1233. }
  1234. if (posMatch >= 0) {
  1235. position += posMatch;
  1236. parsedNum.append('+', err);
  1237. } else if (negMatch >= 0) {
  1238. position += negMatch;
  1239. parsedNum.append('-', err);
  1240. } else if (strictParse){
  1241. parsePosition.setErrorIndex(position);
  1242. return FALSE;
  1243. } else {
  1244. // Temporary set positive. This might be changed after checking suffix
  1245. parsedNum.append('+', err);
  1246. }
  1247. // Match padding before prefix
  1248. if (formatWidth > 0 && fImpl->fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterPrefix) {
  1249. position = skipPadding(text, position);
  1250. }
  1251. if (! strictParse) {
  1252. position = skipUWhiteSpace(text, position);
  1253. }
  1254. // process digits or Inf, find decimal position
  1255. const UnicodeString *inf = &fImpl->getConstSymbol(DecimalFormatSymbols::kInfinitySymbol);
  1256. int32_t infLen = (text.compare(position, inf->length(), *inf)
  1257. ? 0 : inf->length());
  1258. position += infLen; // infLen is non-zero when it does equal to infinity
  1259. status[fgStatusInfinite] = infLen != 0;
  1260. if (infLen != 0) {
  1261. parsedNum.append("Infinity", err);
  1262. } else {
  1263. // We now have a string of digits, possibly with grouping symbols,
  1264. // and decimal points. We want to process these into a DigitList.
  1265. // We don't want to put a bunch of leading zeros into the DigitList
  1266. // though, so we keep track of the location of the decimal point,
  1267. // put only significant digits into the DigitList, and adjust the
  1268. // exponent as needed.
  1269. UBool strictFail = FALSE; // did we exit with a strict parse failure?
  1270. int32_t lastGroup = -1; // where did we last see a grouping separator?
  1271. int32_t digitStart = position;
  1272. int32_t gs2 = fImpl->fEffGrouping.fGrouping2 == 0 ? fImpl->fEffGrouping.fGrouping : fImpl->fEffGrouping.fGrouping2;
  1273. const UnicodeString *decimalString;
  1274. if (fImpl->fMonetary) {
  1275. decimalString = &fImpl->getConstSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol);
  1276. } else {
  1277. decimalString = &fImpl->getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol);
  1278. }
  1279. UChar32 decimalChar = decimalString->char32At(0);
  1280. int32_t decimalStringLength = decimalString->length();
  1281. int32_t decimalCharLength = U16_LENGTH(decimalChar);
  1282. UBool sawDecimal = FALSE;
  1283. UChar32 sawDecimalChar = 0xFFFF;
  1284. UBool sawGrouping = FALSE;
  1285. UChar32 sawGroupingChar = 0xFFFF;
  1286. UBool sawDigit = FALSE;
  1287. int32_t backup = -1;
  1288. int32_t digit;
  1289. // equivalent grouping and decimal support
  1290. const UnicodeSet *decimalSet = NULL;
  1291. const UnicodeSet *groupingSet = NULL;
  1292. if (decimalCharLength == decimalStringLength) {
  1293. decimalSet = DecimalFormatStaticSets::getSimilarDecimals(decimalChar, strictParse);
  1294. }
  1295. if (groupingCharLength == groupingStringLength) {
  1296. if (strictParse) {
  1297. groupingSet = fStaticSets->fStrictDefaultGroupingSeparators;
  1298. } else {
  1299. groupingSet = fStaticSets->fDefaultGroupingSeparators;
  1300. }
  1301. }
  1302. // We need to test groupingChar and decimalChar separately from groupingSet and decimalSet, if the sets are even initialized.
  1303. // If sawDecimal is TRUE, only consider sawDecimalChar and NOT decimalSet
  1304. // If a character matches decimalSet, don't consider it to be a member of the groupingSet.
  1305. // We have to track digitCount ourselves, because digits.fCount will
  1306. // pin when the maximum allowable digits is reached.
  1307. int32_t digitCount = 0;
  1308. int32_t integerDigitCount = 0;
  1309. for (; position < textLength; )
  1310. {
  1311. UChar32 ch = text.char32At(position);
  1312. /* We recognize all digit ranges, not only the Latin digit range
  1313. * '0'..'9'. We do so by using the Character.digit() method,
  1314. * which converts a valid Unicode digit to the range 0..9.
  1315. *
  1316. * The character 'ch' may be a digit. If so, place its value
  1317. * from 0 to 9 in 'digit'. First try using the locale digit,
  1318. * which may or MAY NOT be a standard Unicode digit range. If
  1319. * this fails, try using the standard Unicode digit ranges by
  1320. * calling Character.digit(). If this also fails, digit will
  1321. * have a value outside the range 0..9.
  1322. */
  1323. digit = ch - zero;
  1324. if (digit < 0 || digit > 9)
  1325. {
  1326. digit = u_charDigitValue(ch);
  1327. }
  1328. // As a last resort, look through the localized digits if the zero digit
  1329. // is not a "standard" Unicode digit.
  1330. if ( (digit < 0 || digit > 9) && u_charDigitValue(zero) != 0) {
  1331. digit = 0;
  1332. if ( fImpl->getConstSymbol((DecimalFormatSymbols::ENumberFormatSymbol)(DecimalFormatSymbols::kZeroDigitSymbol)).char32At(0) == ch ) {
  1333. break;
  1334. }
  1335. for (digit = 1 ; digit < 10 ; digit++ ) {
  1336. if ( fImpl->getConstSymbol((DecimalFormatSymbols::ENumberFormatSymbol)(DecimalFormatSymbols::kOneDigitSymbol+digit-1)).char32At(0) == ch ) {
  1337. break;
  1338. }
  1339. }
  1340. }
  1341. if (digit >= 0 && digit <= 9)
  1342. {
  1343. if (strictParse && backup != -1) {
  1344. // comma followed by digit, so group before comma is a
  1345. // secondary group. If there was a group separator
  1346. // before that, the group must == the secondary group
  1347. // length, else it can be <= the the secondary group
  1348. // length.
  1349. if ((lastGroup != -1 && backup - lastGroup - 1 != gs2) ||
  1350. (lastGroup == -1 && position - digitStart - 1 > gs2)) {
  1351. strictFail = TRUE;
  1352. break;
  1353. }
  1354. lastGroup = backup;
  1355. }
  1356. // Cancel out backup setting (see grouping handler below)
  1357. backup = -1;
  1358. sawDigit = TRUE;
  1359. // Note: this will append leading zeros
  1360. parsedNum.append((char)(digit + '0'), err);
  1361. // count any digit that's not a leading zero
  1362. if (digit > 0 || digitCount > 0 || sawDecimal) {
  1363. digitCount += 1;
  1364. // count any integer digit that's not a leading zero
  1365. if (! sawDecimal) {
  1366. integerDigitCount += 1;
  1367. }
  1368. }
  1369. position += U16_LENGTH(ch);
  1370. }
  1371. else if (groupingStringLength > 0 &&
  1372. matchGrouping(groupingChar, sawGrouping, sawGroupingChar, groupingSet,
  1373. decimalChar, decimalSet,
  1374. ch) && groupingUsed)
  1375. {
  1376. if (sawDecimal) {
  1377. break;
  1378. }
  1379. if (strictParse) {
  1380. if ((!sawDigit || backup != -1)) {
  1381. // leading group, or two group separators in a row
  1382. strictFail = TRUE;
  1383. break;
  1384. }
  1385. }
  1386. // Ignore grouping characters, if we are using them, but require
  1387. // that they be followed by a digit. Otherwise we backup and
  1388. // reprocess them.
  1389. backup = position;
  1390. position += groupingStringLength;
  1391. sawGrouping=TRUE;
  1392. // Once we see a grouping character, we only accept that grouping character from then on.
  1393. sawGroupingChar=ch;
  1394. }
  1395. else if (matchDecimal(decimalChar,sawDecimal,sawDecimalChar, decimalSet, ch))
  1396. {
  1397. if (strictParse) {
  1398. if (backup != -1 ||
  1399. (lastGroup != -1 && position - lastGroup != fImpl->fEffGrouping.fGrouping + 1)) {
  1400. strictFail = TRUE;
  1401. break;
  1402. }
  1403. }
  1404. // If we're only parsing integers, or if we ALREADY saw the
  1405. // decimal, then don't parse this one.
  1406. if (isParseIntegerOnly() || sawDecimal) {
  1407. break;
  1408. }
  1409. parsedNum.append('.', err);
  1410. position += decimalStringLength;
  1411. sawDecimal = TRUE;
  1412. // Once we see a decimal character, we only accept that decimal character from then on.
  1413. sawDecimalChar=ch;
  1414. // decimalSet is considered to consist of (ch,ch)
  1415. }
  1416. else {
  1417. if(!fBoolFlags.contains(UNUM_PARSE_NO_EXPONENT) || // don't parse if this is set unless..
  1418. isScientificNotation()) { // .. it's an exponent format - ignore setting and parse anyways
  1419. const UnicodeString *tmp;
  1420. tmp = &fImpl->getConstSymbol(DecimalFormatSymbols::kExponentialSymbol);
  1421. // TODO: CASE
  1422. if (!text.caseCompare(position, tmp->length(), *tmp, U_FOLD_CASE_DEFAULT)) // error code is set below if !sawDigit
  1423. {
  1424. // Parse sign, if present
  1425. int32_t pos = position + tmp->length();
  1426. char exponentSign = '+';
  1427. if (pos < textLength)
  1428. {
  1429. tmp = &fImpl->getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol);
  1430. if (!text.compare(pos, tmp->length(), *tmp))
  1431. {
  1432. pos += tmp->length();
  1433. }
  1434. else {
  1435. tmp = &fImpl->getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol);
  1436. if (!text.compare(pos, tmp->length(), *tmp))
  1437. {
  1438. exponentSign = '-';
  1439. pos += tmp->length();
  1440. }
  1441. }
  1442. }
  1443. UBool sawExponentDigit = FALSE;
  1444. while (pos < textLength) {
  1445. ch = text[(int32_t)pos];
  1446. digit = ch - zero;
  1447. if (digit < 0 || digit > 9) {
  1448. digit = u_charDigitValue(ch);
  1449. }
  1450. if (0 <= digit && digit <= 9) {
  1451. if (!sawExponentDigit) {
  1452. parsedNum.append('E', err);
  1453. parsedNum.append(exponentSign, err);
  1454. sawExponentDigit = TRUE;
  1455. }
  1456. ++pos;
  1457. parsedNum.append((char)(digit + '0'), err);
  1458. } else {
  1459. break;
  1460. }
  1461. }
  1462. if (sawExponentDigit) {
  1463. position = pos; // Advance past the exponent
  1464. }
  1465. break; // Whether we fail or succeed, we exit this loop
  1466. } else {
  1467. break;
  1468. }
  1469. } else { // not parsing exponent
  1470. break;
  1471. }
  1472. }
  1473. }
  1474. // if we didn't see a decimal and it is required, check to see if the pattern had one
  1475. if(!sawDecimal && isDecimalPatternMatchRequired())
  1476. {
  1477. if(formatPattern.indexOf(kPatternDecimalSeparator) != -1)
  1478. {
  1479. parsePosition.setIndex(oldStart);
  1480. parsePosition.setErrorIndex(position);
  1481. debug("decimal point match required fail!");
  1482. return FALSE;
  1483. }
  1484. }
  1485. if (backup != -1)
  1486. {
  1487. position = backup;
  1488. }
  1489. if (strictParse && !sawDecimal) {
  1490. if (lastGroup != -1 && position - lastGroup != fImpl->fEffGrouping.fGrouping + 1) {
  1491. strictFail = TRUE;
  1492. }
  1493. }
  1494. if (strictFail) {
  1495. // only set with strictParse and a grouping separator error
  1496. parsePosition.setIndex(oldStart);
  1497. parsePosition.setErrorIndex(position);
  1498. debug("strictFail!");
  1499. return FALSE;
  1500. }
  1501. // If there was no decimal point we have an integer
  1502. // If none of the text string was recognized. For example, parse
  1503. // "x" with pattern "#0.00" (return index and error index both 0)
  1504. // parse "$" with pattern "$#0.00". (return index 0 and error index
  1505. // 1).
  1506. if (!sawDigit && digitCount == 0) {
  1507. #ifdef FMT_DEBUG
  1508. debug("none of text rec");
  1509. printf("position=%d\n",position);
  1510. #endif
  1511. parsePosition.setIndex(oldStart);
  1512. parsePosition.setErrorIndex(oldStart);
  1513. return FALSE;
  1514. }
  1515. }
  1516. // Match padding before suffix
  1517. if (formatWidth > 0 && fImpl->fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforeSuffix) {
  1518. position = skipPadding(text, position);
  1519. }
  1520. int32_t posSuffixMatch = -1, negSuffixMatch = -1;
  1521. // Match positive and negative suffixes; prefer longest match.
  1522. if (posMatch >= 0 || (!strictParse && negMatch < 0)) {
  1523. posSuffixMatch = compareAffix(text, position, FALSE, FALSE, posSuffix, complexCurrencyParsing, type, currency);
  1524. }
  1525. if (negMatch >= 0) {
  1526. negSuffixMatch = compareAffix(text, position, TRUE, FALSE, negSuffix, complexCurrencyParsing, type, currency);
  1527. }
  1528. if (posSuffixMatch >= 0 && negSuffixMatch >= 0) {
  1529. if (posSuffixMatch > negSuffixMatch) {
  1530. negSuffixMatch = -1;
  1531. } else if (negSuffixMatch > posSuffixMatch) {
  1532. posSuffixMatch = -1;
  1533. }
  1534. }
  1535. // Fail if neither or both
  1536. if (strictParse && ((posSuffixMatch >= 0) == (negSuffixMatch >= 0))) {
  1537. parsePosition.setErrorIndex(position);
  1538. debug("neither or both");
  1539. return FALSE;
  1540. }
  1541. position += (posSuffixMatch >= 0 ? posSuffixMatch : (negSuffixMatch >= 0 ? negSuffixMatch : 0));
  1542. // Match padding before suffix
  1543. if (formatWidth > 0 && fImpl->fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterSuffix) {
  1544. position = skipPadding(text, position);
  1545. }
  1546. parsePosition.setIndex(position);
  1547. parsedNum.data()[0] = (posSuffixMatch >= 0 || (!strictParse && negMatch < 0 && negSuffixMatch < 0)) ? '+' : '-';
  1548. #ifdef FMT_DEBUG
  1549. printf("PP -> %d, SLOW = [%s]! pp=%d, os=%d, err=%s\n", position, parsedNum.data(), parsePosition.getIndex(),oldStart,u_errorName(err));
  1550. #endif
  1551. } /* end SLOW parse */
  1552. if(parsePosition.getIndex() == oldStart)
  1553. {
  1554. #ifdef FMT_DEBUG
  1555. printf(" PP didnt move, err\n");
  1556. #endif
  1557. parsePosition.setErrorIndex(position);
  1558. return FALSE;
  1559. }
  1560. #if UCONFIG_HAVE_PARSEALLINPUT
  1561. else if (fParseAllInput==UNUM_YES&&parsePosition.getIndex()!=textLength)
  1562. {
  1563. #ifdef FMT_DEBUG
  1564. printf(" PP didnt consume all (UNUM_YES), err\n");
  1565. #endif
  1566. parsePosition.setErrorIndex(position);
  1567. return FALSE;
  1568. }
  1569. #endif
  1570. // uint32_t bits = (fastParseOk?kFastpathOk:0) |
  1571. // (fastParseHadDecimal?0:kNoDecimal);
  1572. //printf("FPOK=%d, FPHD=%d, bits=%08X\n", fastParseOk, fastParseHadDecimal, bits);
  1573. digits.set(parsedNum.toStringPiece(),
  1574. err,
  1575. 0//bits
  1576. );
  1577. if (U_FAILURE(err)) {
  1578. #ifdef FMT_DEBUG
  1579. printf(" err setting %s\n", u_errorName(err));
  1580. #endif
  1581. parsePosition.setErrorIndex(position);
  1582. return FALSE;
  1583. }
  1584. // check if we missed a required decimal point
  1585. if(fastParseOk && isDecimalPatternMatchRequired())
  1586. {
  1587. if(formatPattern.indexOf(kPatternDecimalSeparator) != -1)
  1588. {
  1589. parsePosition.setIndex(oldStart);
  1590. parsePosition.setErrorIndex(position);
  1591. debug("decimal point match required fail!");
  1592. return FALSE;
  1593. }
  1594. }
  1595. return TRUE;
  1596. }
  1597. /**
  1598. * Starting at position, advance past a run of pad characters, if any.
  1599. * Return the index of the first character after position that is not a pad
  1600. * character. Result is >= position.
  1601. */
  1602. int32_t DecimalFormat::skipPadding(const UnicodeString& text, int32_t position) const {
  1603. int32_t padLen = U16_LENGTH(fImpl->fAffixes.fPadChar);
  1604. while (position < text.length() &&
  1605. text.char32At(position) == fImpl->fAffixes.fPadChar) {
  1606. position += padLen;
  1607. }
  1608. return position;
  1609. }
  1610. /**
  1611. * Return the length matched by the given affix, or -1 if none.
  1612. * Runs of white space in the affix, match runs of white space in
  1613. * the input. Pattern white space and input white space are
  1614. * determined differently; see code.
  1615. * @param text input text
  1616. * @param pos offset into input at which to begin matching
  1617. * @param isNegative
  1618. * @param isPrefix
  1619. * @param affixPat affix pattern used for currency affix comparison.
  1620. * @param complexCurrencyParsing whether it is currency parsing or not
  1621. * @param type the currency type to parse against, LONG_NAME only or not.
  1622. * @param currency return value for parsed currency, for generic
  1623. * currency parsing mode, or null for normal parsing. In generic
  1624. * currency parsing mode, any currency is parsed, not just the
  1625. * currency that this formatter is set to.
  1626. * @return length of input that matches, or -1 if match failure
  1627. */
  1628. int32_t DecimalFormat::compareAffix(const UnicodeString& text,
  1629. int32_t pos,
  1630. UBool isNegative,
  1631. UBool isPrefix,
  1632. const UnicodeString* affixPat,
  1633. UBool complexCurrencyParsing,
  1634. int8_t type,
  1635. UChar* currency) const
  1636. {
  1637. const UnicodeString *patternToCompare;
  1638. if (currency != NULL ||
  1639. (fImpl->fMonetary && complexCurrencyParsing)) {
  1640. if (affixPat != NULL) {
  1641. return compareComplexAffix(*affixPat, text, pos, type, currency);
  1642. }
  1643. }
  1644. if (isNegative) {
  1645. if (isPrefix) {
  1646. patternToCompare = &fImpl->fAffixes.fNegativePrefix.getOtherVariant().toString();
  1647. }
  1648. else {
  1649. patternToCompare = &fImpl->fAffixes.fNegativeSuffix.getOtherVariant().toString();
  1650. }
  1651. }
  1652. else {
  1653. if (isPrefix) {
  1654. patternToCompare = &fImpl->fAffixes.fPositivePrefix.getOtherVariant().toString();
  1655. }
  1656. else {
  1657. patternToCompare = &fImpl->fAffixes.fPositiveSuffix.getOtherVariant().toString();
  1658. }
  1659. }
  1660. return compareSimpleAffix(*patternToCompare, text, pos, isLenient());
  1661. }
  1662. UBool DecimalFormat::equalWithSignCompatibility(UChar32 lhs, UChar32 rhs) const {
  1663. if (lhs == rhs) {
  1664. return TRUE;
  1665. }
  1666. U_ASSERT(fStaticSets != NULL); // should already be loaded
  1667. const UnicodeSet *minusSigns = fStaticSets->fMinusSigns;
  1668. const UnicodeSet *plusSigns = fStaticSets->fPlusSigns;
  1669. return (minusSigns->contains(lhs) && minusSigns->contains(rhs)) ||
  1670. (plusSigns->contains(lhs) && plusSigns->contains(rhs));
  1671. }
  1672. // check for LRM 0x200E, RLM 0x200F, ALM 0x061C
  1673. #define IS_BIDI_MARK(c) (c==0x200E || c==0x200F || c==0x061C)
  1674. #define TRIM_BUFLEN 32
  1675. UnicodeString& DecimalFormat::trimMarksFromAffix(const UnicodeString& affix, UnicodeString& trimmedAffix) {
  1676. UChar trimBuf[TRIM_BUFLEN];
  1677. int32_t affixLen = affix.length();
  1678. int32_t affixPos, trimLen = 0;
  1679. for (affixPos = 0; affixPos < affixLen; affixPos++) {
  1680. UChar c = affix.charAt(affixPos);
  1681. if (!IS_BIDI_MARK(c)) {
  1682. if (trimLen < TRIM_BUFLEN) {
  1683. trimBuf[trimLen++] = c;
  1684. } else {
  1685. trimLen = 0;
  1686. break;
  1687. }
  1688. }
  1689. }
  1690. return (trimLen > 0)? trimmedAffix.setTo(trimBuf, trimLen): trimmedAffix.setTo(affix);
  1691. }
  1692. /**
  1693. * Return the length matched by the given affix, or -1 if none.
  1694. * Runs of white space in the affix, match runs of white space in
  1695. * the input. Pattern white space and input white space are
  1696. * determined differently; see code.
  1697. * @param affix pattern string, taken as a literal
  1698. * @param input input text
  1699. * @param pos offset into input at which to begin matching
  1700. * @return length of input that matches, or -1 if match failure
  1701. */
  1702. int32_t DecimalFormat::compareSimpleAffix(const UnicodeString& affix,
  1703. const UnicodeString& input,
  1704. int32_t pos,
  1705. UBool lenient) const {
  1706. int32_t start = pos;
  1707. UnicodeString trimmedAffix;
  1708. // For more efficiency we should keep lazily-created trimmed affixes around in
  1709. // instance variables instead of trimming each time they are used (the next step)
  1710. trimMarksFromAffix(affix, trimmedAffix);
  1711. UChar32 affixChar = trimmedAffix.char32At(0);
  1712. int32_t affixLength = trimmedAffix.length();
  1713. int32_t inputLength = input.length();
  1714. int32_t affixCharLength = U16_LENGTH(affixChar);
  1715. UnicodeSet *affixSet;
  1716. UErrorCode status = U_ZERO_ERROR;
  1717. U_ASSERT(fStaticSets != NULL); // should already be loaded
  1718. if (U_FAILURE(status)) {
  1719. return -1;
  1720. }
  1721. if (!lenient) {
  1722. affixSet = fStaticSets->fStrictDashEquivalents;
  1723. // If the trimmedAffix is exactly one character long and that character
  1724. // is in the dash set and the very next input character is also
  1725. // in the dash set, return a match.
  1726. if (affixCharLength == affixLength && affixSet->contains(affixChar)) {
  1727. UChar32 ic = input.char32At(pos);
  1728. if (affixSet->contains(ic)) {
  1729. pos += U16_LENGTH(ic);
  1730. pos = skipBidiMarks(input, pos); // skip any trailing bidi marks
  1731. return pos - start;
  1732. }
  1733. }
  1734. for (int32_t i = 0; i < affixLength; ) {
  1735. UChar32 c = trimmedAffix.char32At(i);
  1736. int32_t len = U16_LENGTH(c);
  1737. if (PatternProps::isWhiteSpace(c)) {
  1738. // We may have a pattern like: \u200F \u0020
  1739. // and input text like: \u200F \u0020
  1740. // Note that U+200F and U+0020 are Pattern_White_Space but only
  1741. // U+0020 is UWhiteSpace. So we have to first do a direct
  1742. // match of the run of Pattern_White_Space in the pattern,
  1743. // then match any extra characters.
  1744. UBool literalMatch = FALSE;
  1745. while (pos < inputLength) {
  1746. UChar32 ic = input.char32At(pos);
  1747. if (ic == c) {
  1748. literalMatch = TRUE;
  1749. i += len;
  1750. pos += len;
  1751. if (i == affixLength) {
  1752. break;
  1753. }
  1754. c = trimmedAffix.char32At(i);
  1755. len = U16_LENGTH(c);
  1756. if (!PatternProps::isWhiteSpace(c)) {
  1757. break;
  1758. }
  1759. } else if (IS_BIDI_MARK(ic)) {
  1760. pos ++; // just skip over this input text
  1761. } else {
  1762. break;
  1763. }
  1764. }
  1765. // Advance over run in pattern
  1766. i = skipPatternWhiteSpace(trimmedAffix, i);
  1767. // Advance over run in input text
  1768. // Must see at least one white space char in input,
  1769. // unless we've already matched some characters literally.
  1770. int32_t s = pos;
  1771. pos = skipUWhiteSpace(input, pos);
  1772. if (pos == s && !literalMatch) {
  1773. return -1;
  1774. }
  1775. // If we skip UWhiteSpace in the input text, we need to skip it in the pattern.
  1776. // Otherwise, the previous lines may have skipped over text (such as U+00A0) that
  1777. // is also in the trimmedAffix.
  1778. i = skipUWhiteSpace(trimmedAffix, i);
  1779. } else {
  1780. UBool match = FALSE;
  1781. while (pos < inputLength) {
  1782. UChar32 ic = input.char32At(pos);
  1783. if (!match && ic == c) {
  1784. i += len;
  1785. pos += len;
  1786. match = TRUE;
  1787. } else if (IS_BIDI_MARK(ic)) {
  1788. pos++; // just skip over this input text
  1789. } else {
  1790. break;
  1791. }
  1792. }
  1793. if (!match) {
  1794. return -1;
  1795. }
  1796. }
  1797. }
  1798. } else {
  1799. UBool match = FALSE;
  1800. affixSet = fStaticSets->fDashEquivalents;
  1801. if (affixCharLength == affixLength && affixSet->contains(affixChar)) {
  1802. pos = skipUWhiteSpaceAndMarks(input, pos);
  1803. UChar32 ic = input.char32At(pos);
  1804. if (affixSet->contains(ic)) {
  1805. pos += U16_LENGTH(ic);
  1806. pos = skipBidiMarks(input, pos);
  1807. return pos - start;
  1808. }
  1809. }
  1810. for (int32_t i = 0; i < affixLength; )
  1811. {
  1812. //i = skipRuleWhiteSpace(trimmedAffix, i);
  1813. i = skipUWhiteSpace(trimmedAffix, i);
  1814. pos = skipUWhiteSpaceAndMarks(input, pos);
  1815. if (i >= affixLength || pos >= inputLength) {
  1816. break;
  1817. }
  1818. UChar32 c = trimmedAffix.char32At(i);
  1819. UChar32 ic = input.char32At(pos);
  1820. if (!equalWithSignCompatibility(ic, c)) {
  1821. return -1;
  1822. }
  1823. match = TRUE;
  1824. i += U16_LENGTH(c);
  1825. pos += U16_LENGTH(ic);
  1826. pos = skipBidiMarks(input, pos);
  1827. }
  1828. if (affixLength > 0 && ! match) {
  1829. return -1;
  1830. }
  1831. }
  1832. return pos - start;
  1833. }
  1834. /**
  1835. * Skip over a run of zero or more Pattern_White_Space characters at
  1836. * pos in text.
  1837. */
  1838. int32_t DecimalFormat::skipPatternWhiteSpace(const UnicodeString& text, int32_t pos) {
  1839. const UChar* s = text.getBuffer();
  1840. return (int32_t)(PatternProps::skipWhiteSpace(s + pos, text.length() - pos) - s);
  1841. }
  1842. /**
  1843. * Skip over a run of zero or more isUWhiteSpace() characters at pos
  1844. * in text.
  1845. */
  1846. int32_t DecimalFormat::skipUWhiteSpace(const UnicodeString& text, int32_t pos) {
  1847. while (pos < text.length()) {
  1848. UChar32 c = text.char32At(pos);
  1849. if (!u_isUWhiteSpace(c)) {
  1850. break;
  1851. }
  1852. pos += U16_LENGTH(c);
  1853. }
  1854. return pos;
  1855. }
  1856. /**
  1857. * Skip over a run of zero or more isUWhiteSpace() characters or bidi marks at pos
  1858. * in text.
  1859. */
  1860. int32_t DecimalFormat::skipUWhiteSpaceAndMarks(const UnicodeString& text, int32_t pos) {
  1861. while (pos < text.length()) {
  1862. UChar32 c = text.char32At(pos);
  1863. if (!u_isUWhiteSpace(c) && !IS_BIDI_MARK(c)) { // u_isUWhiteSpace doesn't include LRM,RLM,ALM
  1864. break;
  1865. }
  1866. pos += U16_LENGTH(c);
  1867. }
  1868. return pos;
  1869. }
  1870. /**
  1871. * Skip over a run of zero or more bidi marks at pos in text.
  1872. */
  1873. int32_t DecimalFormat::skipBidiMarks(const UnicodeString& text, int32_t pos) {
  1874. while (pos < text.length()) {
  1875. UChar c = text.charAt(pos);
  1876. if (!IS_BIDI_MARK(c)) {
  1877. break;
  1878. }
  1879. pos++;
  1880. }
  1881. return pos;
  1882. }
  1883. /**
  1884. * Return the length matched by the given affix, or -1 if none.
  1885. * @param affixPat pattern string
  1886. * @param input input text
  1887. * @param pos offset into input at which to begin matching
  1888. * @param type the currency type to parse against, LONG_NAME only or not.
  1889. * @param currency return value for parsed currency, for generic
  1890. * currency parsing mode, or null for normal parsing. In generic
  1891. * currency parsing mode, any currency is parsed, not just the
  1892. * currency that this formatter is set to.
  1893. * @return length of input that matches, or -1 if match failure
  1894. */
  1895. int32_t DecimalFormat::compareComplexAffix(const UnicodeString& affixPat,
  1896. const UnicodeString& text,
  1897. int32_t pos,
  1898. int8_t type,
  1899. UChar* currency) const
  1900. {
  1901. int32_t start = pos;
  1902. U_ASSERT(currency != NULL || fImpl->fMonetary);
  1903. for (int32_t i=0;
  1904. i<affixPat.length() && pos >= 0; ) {
  1905. UChar32 c = affixPat.char32At(i);
  1906. i += U16_LENGTH(c);
  1907. if (c == kQuote) {
  1908. U_ASSERT(i <= affixPat.length());
  1909. c = affixPat.char32At(i);
  1910. i += U16_LENGTH(c);
  1911. const UnicodeString* affix = NULL;
  1912. switch (c) {
  1913. case kCurrencySign: {
  1914. // since the currency names in choice format is saved
  1915. // the same way as other currency names,
  1916. // do not need to do currency choice parsing here.
  1917. // the general currency parsing parse against all names,
  1918. // including names in choice format.
  1919. UBool intl = i<affixPat.length() &&
  1920. affixPat.char32At(i) == kCurrencySign;
  1921. if (intl) {
  1922. ++i;
  1923. }
  1924. UBool plural = i<affixPat.length() &&
  1925. affixPat.char32At(i) == kCurrencySign;
  1926. if (plural) {
  1927. ++i;
  1928. intl = FALSE;
  1929. }
  1930. // Parse generic currency -- anything for which we
  1931. // have a display name, or any 3-letter ISO code.
  1932. // Try to parse display name for our locale; first
  1933. // determine our locale.
  1934. const char* loc = fCurrencyPluralInfo->getLocale().getName();
  1935. ParsePosition ppos(pos);
  1936. UChar curr[4];
  1937. UErrorCode ec = U_ZERO_ERROR;
  1938. // Delegate parse of display name => ISO code to Currency
  1939. uprv_parseCurrency(loc, text, ppos, type, curr, ec);
  1940. // If parse succeeds, populate currency[0]
  1941. if (U_SUCCESS(ec) && ppos.getIndex() != pos) {
  1942. if (currency) {
  1943. u_strcpy(currency, curr);
  1944. } else {
  1945. // The formatter is currency-style but the client has not requested
  1946. // the value of the parsed currency. In this case, if that value does
  1947. // not match the formatter's current value, then the parse fails.
  1948. UChar effectiveCurr[4];
  1949. getEffectiveCurrency(effectiveCurr, ec);
  1950. if ( U_FAILURE(ec) || u_strncmp(curr,effectiveCurr,4) != 0 ) {
  1951. pos = -1;
  1952. continue;
  1953. }
  1954. }
  1955. pos = ppos.getIndex();
  1956. } else if (!isLenient()){
  1957. pos = -1;
  1958. }
  1959. continue;
  1960. }
  1961. case kPatternPercent:
  1962. affix = &fImpl->getConstSymbol(DecimalFormatSymbols::kPercentSymbol);
  1963. break;
  1964. case kPatternPerMill:
  1965. affix = &fImpl->getConstSymbol(DecimalFormatSymbols::kPerMillSymbol);
  1966. break;
  1967. case kPatternPlus:
  1968. affix = &fImpl->getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol);
  1969. break;
  1970. case kPatternMinus:
  1971. affix = &fImpl->getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol);
  1972. break;
  1973. default:
  1974. // fall through to affix!=0 test, which will fail
  1975. break;
  1976. }
  1977. if (affix != NULL) {
  1978. pos = match(text, pos, *affix);
  1979. continue;
  1980. }
  1981. }
  1982. pos = match(text, pos, c);
  1983. if (PatternProps::isWhiteSpace(c)) {
  1984. i = skipPatternWhiteSpace(affixPat, i);
  1985. }
  1986. }
  1987. return pos - start;
  1988. }
  1989. /**
  1990. * Match a single character at text[pos] and return the index of the
  1991. * next character upon success. Return -1 on failure. If
  1992. * ch is a Pattern_White_Space then match a run of white space in text.
  1993. */
  1994. int32_t DecimalFormat::match(const UnicodeString& text, int32_t pos, UChar32 ch) {
  1995. if (PatternProps::isWhiteSpace(ch)) {
  1996. // Advance over run of white space in input text
  1997. // Must see at least one white space char in input
  1998. int32_t s = pos;
  1999. pos = skipPatternWhiteSpace(text, pos);
  2000. if (pos == s) {
  2001. return -1;
  2002. }
  2003. return pos;
  2004. }
  2005. return (pos >= 0 && text.char32At(pos) == ch) ?
  2006. (pos + U16_LENGTH(ch)) : -1;
  2007. }
  2008. /**
  2009. * Match a string at text[pos] and return the index of the next
  2010. * character upon success. Return -1 on failure. Match a run of
  2011. * white space in str with a run of white space in text.
  2012. */
  2013. int32_t DecimalFormat::match(const UnicodeString& text, int32_t pos, const UnicodeString& str) {
  2014. for (int32_t i=0; i<str.length() && pos >= 0; ) {
  2015. UChar32 ch = str.char32At(i);
  2016. i += U16_LENGTH(ch);
  2017. if (PatternProps::isWhiteSpace(ch)) {
  2018. i = skipPatternWhiteSpace(str, i);
  2019. }
  2020. pos = match(text, pos, ch);
  2021. }
  2022. return pos;
  2023. }
  2024. UBool DecimalFormat::matchSymbol(const UnicodeString &text, int32_t position, int32_t length, const UnicodeString &symbol,
  2025. UnicodeSet *sset, UChar32 schar)
  2026. {
  2027. if (sset != NULL) {
  2028. return sset->contains(schar);
  2029. }
  2030. return text.compare(position, length, symbol) == 0;
  2031. }
  2032. UBool DecimalFormat::matchDecimal(UChar32 symbolChar,
  2033. UBool sawDecimal, UChar32 sawDecimalChar,
  2034. const UnicodeSet *sset, UChar32 schar) {
  2035. if(sawDecimal) {
  2036. return schar==sawDecimalChar;
  2037. } else if(schar==symbolChar) {
  2038. return TRUE;
  2039. } else if(sset!=NULL) {
  2040. return sset->contains(schar);
  2041. } else {
  2042. return FALSE;
  2043. }
  2044. }
  2045. UBool DecimalFormat::matchGrouping(UChar32 groupingChar,
  2046. UBool sawGrouping, UChar32 sawGroupingChar,
  2047. const UnicodeSet *sset,
  2048. UChar32 /*decimalChar*/, const UnicodeSet *decimalSet,
  2049. UChar32 schar) {
  2050. if(sawGrouping) {
  2051. return schar==sawGroupingChar; // previously found
  2052. } else if(schar==groupingChar) {
  2053. return TRUE; // char from symbols
  2054. } else if(sset!=NULL) {
  2055. return sset->contains(schar) && // in groupingSet but...
  2056. ((decimalSet==NULL) || !decimalSet->contains(schar)); // Exclude decimalSet from groupingSet
  2057. } else {
  2058. return FALSE;
  2059. }
  2060. }
  2061. //------------------------------------------------------------------------------
  2062. // Gets the pointer to the localized decimal format symbols
  2063. const DecimalFormatSymbols*
  2064. DecimalFormat::getDecimalFormatSymbols() const
  2065. {
  2066. return &fImpl->getDecimalFormatSymbols();
  2067. }
  2068. //------------------------------------------------------------------------------
  2069. // De-owning the current localized symbols and adopt the new symbols.
  2070. void
  2071. DecimalFormat::adoptDecimalFormatSymbols(DecimalFormatSymbols* symbolsToAdopt)
  2072. {
  2073. if (symbolsToAdopt == NULL) {
  2074. return; // do not allow caller to set fSymbols to NULL
  2075. }
  2076. fImpl->adoptDecimalFormatSymbols(symbolsToAdopt);
  2077. }
  2078. //------------------------------------------------------------------------------
  2079. // Setting the symbols is equlivalent to adopting a newly created localized
  2080. // symbols.
  2081. void
  2082. DecimalFormat::setDecimalFormatSymbols(const DecimalFormatSymbols& symbols)
  2083. {
  2084. adoptDecimalFormatSymbols(new DecimalFormatSymbols(symbols));
  2085. }
  2086. const CurrencyPluralInfo*
  2087. DecimalFormat::getCurrencyPluralInfo(void) const
  2088. {
  2089. return fCurrencyPluralInfo;
  2090. }
  2091. void
  2092. DecimalFormat::adoptCurrencyPluralInfo(CurrencyPluralInfo* toAdopt)
  2093. {
  2094. if (toAdopt != NULL) {
  2095. delete fCurrencyPluralInfo;
  2096. fCurrencyPluralInfo = toAdopt;
  2097. // re-set currency affix patterns and currency affixes.
  2098. if (fImpl->fMonetary) {
  2099. UErrorCode status = U_ZERO_ERROR;
  2100. if (fAffixPatternsForCurrency) {
  2101. deleteHashForAffixPattern();
  2102. }
  2103. setupCurrencyAffixPatterns(status);
  2104. }
  2105. }
  2106. }
  2107. void
  2108. DecimalFormat::setCurrencyPluralInfo(const CurrencyPluralInfo& info)
  2109. {
  2110. adoptCurrencyPluralInfo(info.clone());
  2111. }
  2112. //------------------------------------------------------------------------------
  2113. // Gets the positive prefix of the number pattern.
  2114. UnicodeString&
  2115. DecimalFormat::getPositivePrefix(UnicodeString& result) const
  2116. {
  2117. return fImpl->getPositivePrefix(result);
  2118. }
  2119. //------------------------------------------------------------------------------
  2120. // Sets the positive prefix of the number pattern.
  2121. void
  2122. DecimalFormat::setPositivePrefix(const UnicodeString& newValue)
  2123. {
  2124. fImpl->setPositivePrefix(newValue);
  2125. }
  2126. //------------------------------------------------------------------------------
  2127. // Gets the negative prefix of the number pattern.
  2128. UnicodeString&
  2129. DecimalFormat::getNegativePrefix(UnicodeString& result) const
  2130. {
  2131. return fImpl->getNegativePrefix(result);
  2132. }
  2133. //------------------------------------------------------------------------------
  2134. // Gets the negative prefix of the number pattern.
  2135. void
  2136. DecimalFormat::setNegativePrefix(const UnicodeString& newValue)
  2137. {
  2138. fImpl->setNegativePrefix(newValue);
  2139. }
  2140. //------------------------------------------------------------------------------
  2141. // Gets the positive suffix of the number pattern.
  2142. UnicodeString&
  2143. DecimalFormat::getPositiveSuffix(UnicodeString& result) const
  2144. {
  2145. return fImpl->getPositiveSuffix(result);
  2146. }
  2147. //------------------------------------------------------------------------------
  2148. // Sets the positive suffix of the number pattern.
  2149. void
  2150. DecimalFormat::setPositiveSuffix(const UnicodeString& newValue)
  2151. {
  2152. fImpl->setPositiveSuffix(newValue);
  2153. }
  2154. //------------------------------------------------------------------------------
  2155. // Gets the negative suffix of the number pattern.
  2156. UnicodeString&
  2157. DecimalFormat::getNegativeSuffix(UnicodeString& result) const
  2158. {
  2159. return fImpl->getNegativeSuffix(result);
  2160. }
  2161. //------------------------------------------------------------------------------
  2162. // Sets the negative suffix of the number pattern.
  2163. void
  2164. DecimalFormat::setNegativeSuffix(const UnicodeString& newValue)
  2165. {
  2166. fImpl->setNegativeSuffix(newValue);
  2167. }
  2168. //------------------------------------------------------------------------------
  2169. // Gets the multiplier of the number pattern.
  2170. // Multipliers are stored as decimal numbers (DigitLists) because that
  2171. // is the most convenient for muliplying or dividing the numbers to be formatted.
  2172. // A NULL multiplier implies one, and the scaling operations are skipped.
  2173. int32_t
  2174. DecimalFormat::getMultiplier() const
  2175. {
  2176. return fImpl->getMultiplier();
  2177. }
  2178. //------------------------------------------------------------------------------
  2179. // Sets the multiplier of the number pattern.
  2180. void
  2181. DecimalFormat::setMultiplier(int32_t newValue)
  2182. {
  2183. fImpl->setMultiplier(newValue);
  2184. }
  2185. /**
  2186. * Get the rounding increment.
  2187. * @return A positive rounding increment, or 0.0 if rounding
  2188. * is not in effect.
  2189. * @see #setRoundingIncrement
  2190. * @see #getRoundingMode
  2191. * @see #setRoundingMode
  2192. */
  2193. double DecimalFormat::getRoundingIncrement() const {
  2194. return fImpl->getRoundingIncrement();
  2195. }
  2196. /**
  2197. * Set the rounding increment. This method also controls whether
  2198. * rounding is enabled.
  2199. * @param newValue A positive rounding increment, or 0.0 to disable rounding.
  2200. * Negative increments are equivalent to 0.0.
  2201. * @see #getRoundingIncrement
  2202. * @see #getRoundingMode
  2203. * @see #setRoundingMode
  2204. */
  2205. void DecimalFormat::setRoundingIncrement(double newValue) {
  2206. fImpl->setRoundingIncrement(newValue);
  2207. }
  2208. /**
  2209. * Get the rounding mode.
  2210. * @return A rounding mode
  2211. * @see #setRoundingIncrement
  2212. * @see #getRoundingIncrement
  2213. * @see #setRoundingMode
  2214. */
  2215. DecimalFormat::ERoundingMode DecimalFormat::getRoundingMode() const {
  2216. return fImpl->getRoundingMode();
  2217. }
  2218. /**
  2219. * Set the rounding mode. This has no effect unless the rounding
  2220. * increment is greater than zero.
  2221. * @param roundingMode A rounding mode
  2222. * @see #setRoundingIncrement
  2223. * @see #getRoundingIncrement
  2224. * @see #getRoundingMode
  2225. */
  2226. void DecimalFormat::setRoundingMode(ERoundingMode roundingMode) {
  2227. fImpl->setRoundingMode(roundingMode);
  2228. }
  2229. /**
  2230. * Get the width to which the output of <code>format()</code> is padded.
  2231. * @return the format width, or zero if no padding is in effect
  2232. * @see #setFormatWidth
  2233. * @see #getPadCharacter
  2234. * @see #setPadCharacter
  2235. * @see #getPadPosition
  2236. * @see #setPadPosition
  2237. */
  2238. int32_t DecimalFormat::getFormatWidth() const {
  2239. return fImpl->getFormatWidth();
  2240. }
  2241. /**
  2242. * Set the width to which the output of <code>format()</code> is padded.
  2243. * This method also controls whether padding is enabled.
  2244. * @param width the width to which to pad the result of
  2245. * <code>format()</code>, or zero to disable padding. A negative
  2246. * width is equivalent to 0.
  2247. * @see #getFormatWidth
  2248. * @see #getPadCharacter
  2249. * @see #setPadCharacter
  2250. * @see #getPadPosition
  2251. * @see #setPadPosition
  2252. */
  2253. void DecimalFormat::setFormatWidth(int32_t width) {
  2254. int32_t formatWidth = (width > 0) ? width : 0;
  2255. fImpl->setFormatWidth(formatWidth);
  2256. }
  2257. UnicodeString DecimalFormat::getPadCharacterString() const {
  2258. return UnicodeString(fImpl->getPadCharacter());
  2259. }
  2260. void DecimalFormat::setPadCharacter(const UnicodeString &padChar) {
  2261. UChar pad;
  2262. if (padChar.length() > 0) {
  2263. pad = padChar.char32At(0);
  2264. }
  2265. else {
  2266. pad = kDefaultPad;
  2267. }
  2268. fImpl->setPadCharacter(pad);
  2269. }
  2270. static DecimalFormat::EPadPosition fromPadPosition(DigitAffixesAndPadding::EPadPosition padPos) {
  2271. switch (padPos) {
  2272. case DigitAffixesAndPadding::kPadBeforePrefix:
  2273. return DecimalFormat::kPadBeforePrefix;
  2274. case DigitAffixesAndPadding::kPadAfterPrefix:
  2275. return DecimalFormat::kPadAfterPrefix;
  2276. case DigitAffixesAndPadding::kPadBeforeSuffix:
  2277. return DecimalFormat::kPadBeforeSuffix;
  2278. case DigitAffixesAndPadding::kPadAfterSuffix:
  2279. return DecimalFormat::kPadAfterSuffix;
  2280. default:
  2281. U_ASSERT(FALSE);
  2282. break;
  2283. }
  2284. return DecimalFormat::kPadBeforePrefix;
  2285. }
  2286. /**
  2287. * Get the position at which padding will take place. This is the location
  2288. * at which padding will be inserted if the result of <code>format()</code>
  2289. * is shorter than the format width.
  2290. * @return the pad position, one of <code>kPadBeforePrefix</code>,
  2291. * <code>kPadAfterPrefix</code>, <code>kPadBeforeSuffix</code>, or
  2292. * <code>kPadAfterSuffix</code>.
  2293. * @see #setFormatWidth
  2294. * @see #getFormatWidth
  2295. * @see #setPadCharacter
  2296. * @see #getPadCharacter
  2297. * @see #setPadPosition
  2298. * @see #kPadBeforePrefix
  2299. * @see #kPadAfterPrefix
  2300. * @see #kPadBeforeSuffix
  2301. * @see #kPadAfterSuffix
  2302. */
  2303. DecimalFormat::EPadPosition DecimalFormat::getPadPosition() const {
  2304. return fromPadPosition(fImpl->getPadPosition());
  2305. }
  2306. static DigitAffixesAndPadding::EPadPosition toPadPosition(DecimalFormat::EPadPosition padPos) {
  2307. switch (padPos) {
  2308. case DecimalFormat::kPadBeforePrefix:
  2309. return DigitAffixesAndPadding::kPadBeforePrefix;
  2310. case DecimalFormat::kPadAfterPrefix:
  2311. return DigitAffixesAndPadding::kPadAfterPrefix;
  2312. case DecimalFormat::kPadBeforeSuffix:
  2313. return DigitAffixesAndPadding::kPadBeforeSuffix;
  2314. case DecimalFormat::kPadAfterSuffix:
  2315. return DigitAffixesAndPadding::kPadAfterSuffix;
  2316. default:
  2317. U_ASSERT(FALSE);
  2318. break;
  2319. }
  2320. return DigitAffixesAndPadding::kPadBeforePrefix;
  2321. }
  2322. /**
  2323. * <strong><font face=helvetica color=red>NEW</font></strong>
  2324. * Set the position at which padding will take place. This is the location
  2325. * at which padding will be inserted if the result of <code>format()</code>
  2326. * is shorter than the format width. This has no effect unless padding is
  2327. * enabled.
  2328. * @param padPos the pad position, one of <code>kPadBeforePrefix</code>,
  2329. * <code>kPadAfterPrefix</code>, <code>kPadBeforeSuffix</code>, or
  2330. * <code>kPadAfterSuffix</code>.
  2331. * @see #setFormatWidth
  2332. * @see #getFormatWidth
  2333. * @see #setPadCharacter
  2334. * @see #getPadCharacter
  2335. * @see #getPadPosition
  2336. * @see #kPadBeforePrefix
  2337. * @see #kPadAfterPrefix
  2338. * @see #kPadBeforeSuffix
  2339. * @see #kPadAfterSuffix
  2340. */
  2341. void DecimalFormat::setPadPosition(EPadPosition padPos) {
  2342. fImpl->setPadPosition(toPadPosition(padPos));
  2343. }
  2344. /**
  2345. * Return whether or not scientific notation is used.
  2346. * @return TRUE if this object formats and parses scientific notation
  2347. * @see #setScientificNotation
  2348. * @see #getMinimumExponentDigits
  2349. * @see #setMinimumExponentDigits
  2350. * @see #isExponentSignAlwaysShown
  2351. * @see #setExponentSignAlwaysShown
  2352. */
  2353. UBool DecimalFormat::isScientificNotation() const {
  2354. return fImpl->isScientificNotation();
  2355. }
  2356. /**
  2357. * Set whether or not scientific notation is used.
  2358. * @param useScientific TRUE if this object formats and parses scientific
  2359. * notation
  2360. * @see #isScientificNotation
  2361. * @see #getMinimumExponentDigits
  2362. * @see #setMinimumExponentDigits
  2363. * @see #isExponentSignAlwaysShown
  2364. * @see #setExponentSignAlwaysShown
  2365. */
  2366. void DecimalFormat::setScientificNotation(UBool useScientific) {
  2367. fImpl->setScientificNotation(useScientific);
  2368. }
  2369. /**
  2370. * Return the minimum exponent digits that will be shown.
  2371. * @return the minimum exponent digits that will be shown
  2372. * @see #setScientificNotation
  2373. * @see #isScientificNotation
  2374. * @see #setMinimumExponentDigits
  2375. * @see #isExponentSignAlwaysShown
  2376. * @see #setExponentSignAlwaysShown
  2377. */
  2378. int8_t DecimalFormat::getMinimumExponentDigits() const {
  2379. return fImpl->getMinimumExponentDigits();
  2380. }
  2381. /**
  2382. * Set the minimum exponent digits that will be shown. This has no
  2383. * effect unless scientific notation is in use.
  2384. * @param minExpDig a value >= 1 indicating the fewest exponent digits
  2385. * that will be shown. Values less than 1 will be treated as 1.
  2386. * @see #setScientificNotation
  2387. * @see #isScientificNotation
  2388. * @see #getMinimumExponentDigits
  2389. * @see #isExponentSignAlwaysShown
  2390. * @see #setExponentSignAlwaysShown
  2391. */
  2392. void DecimalFormat::setMinimumExponentDigits(int8_t minExpDig) {
  2393. int32_t minExponentDigits = (int8_t)((minExpDig > 0) ? minExpDig : 1);
  2394. fImpl->setMinimumExponentDigits(minExponentDigits);
  2395. }
  2396. /**
  2397. * Return whether the exponent sign is always shown.
  2398. * @return TRUE if the exponent is always prefixed with either the
  2399. * localized minus sign or the localized plus sign, false if only negative
  2400. * exponents are prefixed with the localized minus sign.
  2401. * @see #setScientificNotation
  2402. * @see #isScientificNotation
  2403. * @see #setMinimumExponentDigits
  2404. * @see #getMinimumExponentDigits
  2405. * @see #setExponentSignAlwaysShown
  2406. */
  2407. UBool DecimalFormat::isExponentSignAlwaysShown() const {
  2408. return fImpl->isExponentSignAlwaysShown();
  2409. }
  2410. /**
  2411. * Set whether the exponent sign is always shown. This has no effect
  2412. * unless scientific notation is in use.
  2413. * @param expSignAlways TRUE if the exponent is always prefixed with either
  2414. * the localized minus sign or the localized plus sign, false if only
  2415. * negative exponents are prefixed with the localized minus sign.
  2416. * @see #setScientificNotation
  2417. * @see #isScientificNotation
  2418. * @see #setMinimumExponentDigits
  2419. * @see #getMinimumExponentDigits
  2420. * @see #isExponentSignAlwaysShown
  2421. */
  2422. void DecimalFormat::setExponentSignAlwaysShown(UBool expSignAlways) {
  2423. fImpl->setExponentSignAlwaysShown(expSignAlways);
  2424. }
  2425. //------------------------------------------------------------------------------
  2426. // Gets the grouping size of the number pattern. For example, thousand or 10
  2427. // thousand groupings.
  2428. int32_t
  2429. DecimalFormat::getGroupingSize() const
  2430. {
  2431. return fImpl->getGroupingSize();
  2432. }
  2433. //------------------------------------------------------------------------------
  2434. // Gets the grouping size of the number pattern.
  2435. void
  2436. DecimalFormat::setGroupingSize(int32_t newValue)
  2437. {
  2438. fImpl->setGroupingSize(newValue);
  2439. }
  2440. //------------------------------------------------------------------------------
  2441. int32_t
  2442. DecimalFormat::getSecondaryGroupingSize() const
  2443. {
  2444. return fImpl->getSecondaryGroupingSize();
  2445. }
  2446. //------------------------------------------------------------------------------
  2447. void
  2448. DecimalFormat::setSecondaryGroupingSize(int32_t newValue)
  2449. {
  2450. fImpl->setSecondaryGroupingSize(newValue);
  2451. }
  2452. //------------------------------------------------------------------------------
  2453. int32_t
  2454. DecimalFormat::getMinimumGroupingDigits() const
  2455. {
  2456. return fImpl->getMinimumGroupingDigits();
  2457. }
  2458. //------------------------------------------------------------------------------
  2459. void
  2460. DecimalFormat::setMinimumGroupingDigits(int32_t newValue)
  2461. {
  2462. fImpl->setMinimumGroupingDigits(newValue);
  2463. }
  2464. //------------------------------------------------------------------------------
  2465. // Checks if to show the decimal separator.
  2466. UBool
  2467. DecimalFormat::isDecimalSeparatorAlwaysShown() const
  2468. {
  2469. return fImpl->isDecimalSeparatorAlwaysShown();
  2470. }
  2471. //------------------------------------------------------------------------------
  2472. // Sets to always show the decimal separator.
  2473. void
  2474. DecimalFormat::setDecimalSeparatorAlwaysShown(UBool newValue)
  2475. {
  2476. fImpl->setDecimalSeparatorAlwaysShown(newValue);
  2477. }
  2478. //------------------------------------------------------------------------------
  2479. // Checks if decimal point pattern match is required
  2480. UBool
  2481. DecimalFormat::isDecimalPatternMatchRequired(void) const
  2482. {
  2483. return fBoolFlags.contains(UNUM_PARSE_DECIMAL_MARK_REQUIRED);
  2484. }
  2485. //------------------------------------------------------------------------------
  2486. // Checks if decimal point pattern match is required
  2487. void
  2488. DecimalFormat::setDecimalPatternMatchRequired(UBool newValue)
  2489. {
  2490. fBoolFlags.set(UNUM_PARSE_DECIMAL_MARK_REQUIRED, newValue);
  2491. }
  2492. //------------------------------------------------------------------------------
  2493. // Emits the pattern of this DecimalFormat instance.
  2494. UnicodeString&
  2495. DecimalFormat::toPattern(UnicodeString& result) const
  2496. {
  2497. return fImpl->toPattern(result);
  2498. }
  2499. //------------------------------------------------------------------------------
  2500. // Emits the localized pattern this DecimalFormat instance.
  2501. UnicodeString&
  2502. DecimalFormat::toLocalizedPattern(UnicodeString& result) const
  2503. {
  2504. // toLocalizedPattern is deprecated, so we just make it the same as
  2505. // toPattern.
  2506. return fImpl->toPattern(result);
  2507. }
  2508. //------------------------------------------------------------------------------
  2509. void
  2510. DecimalFormat::applyPattern(const UnicodeString& pattern, UErrorCode& status)
  2511. {
  2512. if (pattern.indexOf(kCurrencySign) != -1) {
  2513. handleCurrencySignInPattern(status);
  2514. }
  2515. fImpl->applyPattern(pattern, status);
  2516. }
  2517. //------------------------------------------------------------------------------
  2518. void
  2519. DecimalFormat::applyPattern(const UnicodeString& pattern,
  2520. UParseError& parseError,
  2521. UErrorCode& status)
  2522. {
  2523. if (pattern.indexOf(kCurrencySign) != -1) {
  2524. handleCurrencySignInPattern(status);
  2525. }
  2526. fImpl->applyPattern(pattern, parseError, status);
  2527. }
  2528. //------------------------------------------------------------------------------
  2529. void
  2530. DecimalFormat::applyLocalizedPattern(const UnicodeString& pattern, UErrorCode& status)
  2531. {
  2532. if (pattern.indexOf(kCurrencySign) != -1) {
  2533. handleCurrencySignInPattern(status);
  2534. }
  2535. fImpl->applyLocalizedPattern(pattern, status);
  2536. }
  2537. //------------------------------------------------------------------------------
  2538. void
  2539. DecimalFormat::applyLocalizedPattern(const UnicodeString& pattern,
  2540. UParseError& parseError,
  2541. UErrorCode& status)
  2542. {
  2543. if (pattern.indexOf(kCurrencySign) != -1) {
  2544. handleCurrencySignInPattern(status);
  2545. }
  2546. fImpl->applyLocalizedPattern(pattern, parseError, status);
  2547. }
  2548. //------------------------------------------------------------------------------
  2549. /**
  2550. * Sets the maximum number of digits allowed in the integer portion of a
  2551. * number.
  2552. * @see NumberFormat#setMaximumIntegerDigits
  2553. */
  2554. void DecimalFormat::setMaximumIntegerDigits(int32_t newValue) {
  2555. newValue = _min(newValue, gDefaultMaxIntegerDigits);
  2556. NumberFormat::setMaximumIntegerDigits(newValue);
  2557. fImpl->updatePrecision();
  2558. }
  2559. /**
  2560. * Sets the minimum number of digits allowed in the integer portion of a
  2561. * number. This override limits the integer digit count to 309.
  2562. * @see NumberFormat#setMinimumIntegerDigits
  2563. */
  2564. void DecimalFormat::setMinimumIntegerDigits(int32_t newValue) {
  2565. newValue = _min(newValue, kDoubleIntegerDigits);
  2566. NumberFormat::setMinimumIntegerDigits(newValue);
  2567. fImpl->updatePrecision();
  2568. }
  2569. /**
  2570. * Sets the maximum number of digits allowed in the fraction portion of a
  2571. * number. This override limits the fraction digit count to 340.
  2572. * @see NumberFormat#setMaximumFractionDigits
  2573. */
  2574. void DecimalFormat::setMaximumFractionDigits(int32_t newValue) {
  2575. newValue = _min(newValue, kDoubleFractionDigits);
  2576. NumberFormat::setMaximumFractionDigits(newValue);
  2577. fImpl->updatePrecision();
  2578. }
  2579. /**
  2580. * Sets the minimum number of digits allowed in the fraction portion of a
  2581. * number. This override limits the fraction digit count to 340.
  2582. * @see NumberFormat#setMinimumFractionDigits
  2583. */
  2584. void DecimalFormat::setMinimumFractionDigits(int32_t newValue) {
  2585. newValue = _min(newValue, kDoubleFractionDigits);
  2586. NumberFormat::setMinimumFractionDigits(newValue);
  2587. fImpl->updatePrecision();
  2588. }
  2589. int32_t DecimalFormat::getMinimumSignificantDigits() const {
  2590. return fImpl->getMinimumSignificantDigits();
  2591. }
  2592. int32_t DecimalFormat::getMaximumSignificantDigits() const {
  2593. return fImpl->getMaximumSignificantDigits();
  2594. }
  2595. void DecimalFormat::setMinimumSignificantDigits(int32_t min) {
  2596. if (min < 1) {
  2597. min = 1;
  2598. }
  2599. // pin max sig dig to >= min
  2600. int32_t max = _max(fImpl->fMaxSigDigits, min);
  2601. fImpl->setMinMaxSignificantDigits(min, max);
  2602. }
  2603. void DecimalFormat::setMaximumSignificantDigits(int32_t max) {
  2604. if (max < 1) {
  2605. max = 1;
  2606. }
  2607. // pin min sig dig to 1..max
  2608. U_ASSERT(fImpl->fMinSigDigits >= 1);
  2609. int32_t min = _min(fImpl->fMinSigDigits, max);
  2610. fImpl->setMinMaxSignificantDigits(min, max);
  2611. }
  2612. UBool DecimalFormat::areSignificantDigitsUsed() const {
  2613. return fImpl->areSignificantDigitsUsed();
  2614. }
  2615. void DecimalFormat::setSignificantDigitsUsed(UBool useSignificantDigits) {
  2616. fImpl->setSignificantDigitsUsed(useSignificantDigits);
  2617. }
  2618. void DecimalFormat::setCurrency(const UChar* theCurrency, UErrorCode& ec) {
  2619. // set the currency before compute affixes to get the right currency names
  2620. NumberFormat::setCurrency(theCurrency, ec);
  2621. fImpl->updateCurrency(ec);
  2622. }
  2623. void DecimalFormat::setCurrencyUsage(UCurrencyUsage newContext, UErrorCode* ec){
  2624. fImpl->setCurrencyUsage(newContext, *ec);
  2625. }
  2626. UCurrencyUsage DecimalFormat::getCurrencyUsage() const {
  2627. return fImpl->getCurrencyUsage();
  2628. }
  2629. // Deprecated variant with no UErrorCode parameter
  2630. void DecimalFormat::setCurrency(const UChar* theCurrency) {
  2631. UErrorCode ec = U_ZERO_ERROR;
  2632. setCurrency(theCurrency, ec);
  2633. }
  2634. void DecimalFormat::getEffectiveCurrency(UChar* result, UErrorCode& ec) const {
  2635. if (fImpl->fSymbols == NULL) {
  2636. ec = U_MEMORY_ALLOCATION_ERROR;
  2637. return;
  2638. }
  2639. ec = U_ZERO_ERROR;
  2640. const UChar* c = getCurrency();
  2641. if (*c == 0) {
  2642. const UnicodeString &intl =
  2643. fImpl->getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol);
  2644. c = intl.getBuffer(); // ok for intl to go out of scope
  2645. }
  2646. u_strncpy(result, c, 3);
  2647. result[3] = 0;
  2648. }
  2649. Hashtable*
  2650. DecimalFormat::initHashForAffixPattern(UErrorCode& status) {
  2651. if ( U_FAILURE(status) ) {
  2652. return NULL;
  2653. }
  2654. Hashtable* hTable;
  2655. if ( (hTable = new Hashtable(TRUE, status)) == NULL ) {
  2656. status = U_MEMORY_ALLOCATION_ERROR;
  2657. return NULL;
  2658. }
  2659. if ( U_FAILURE(status) ) {
  2660. delete hTable;
  2661. return NULL;
  2662. }
  2663. hTable->setValueComparator(decimfmtAffixPatternValueComparator);
  2664. return hTable;
  2665. }
  2666. void
  2667. DecimalFormat::deleteHashForAffixPattern()
  2668. {
  2669. if ( fAffixPatternsForCurrency == NULL ) {
  2670. return;
  2671. }
  2672. int32_t pos = UHASH_FIRST;
  2673. const UHashElement* element = NULL;
  2674. while ( (element = fAffixPatternsForCurrency->nextElement(pos)) != NULL ) {
  2675. const UHashTok valueTok = element->value;
  2676. const AffixPatternsForCurrency* value = (AffixPatternsForCurrency*)valueTok.pointer;
  2677. delete value;
  2678. }
  2679. delete fAffixPatternsForCurrency;
  2680. fAffixPatternsForCurrency = NULL;
  2681. }
  2682. void
  2683. DecimalFormat::copyHashForAffixPattern(const Hashtable* source,
  2684. Hashtable* target,
  2685. UErrorCode& status) {
  2686. if ( U_FAILURE(status) ) {
  2687. return;
  2688. }
  2689. int32_t pos = UHASH_FIRST;
  2690. const UHashElement* element = NULL;
  2691. if ( source ) {
  2692. while ( (element = source->nextElement(pos)) != NULL ) {
  2693. const UHashTok keyTok = element->key;
  2694. const UnicodeString* key = (UnicodeString*)keyTok.pointer;
  2695. const UHashTok valueTok = element->value;
  2696. const AffixPatternsForCurrency* value = (AffixPatternsForCurrency*)valueTok.pointer;
  2697. AffixPatternsForCurrency* copy = new AffixPatternsForCurrency(
  2698. value->negPrefixPatternForCurrency,
  2699. value->negSuffixPatternForCurrency,
  2700. value->posPrefixPatternForCurrency,
  2701. value->posSuffixPatternForCurrency,
  2702. value->patternType);
  2703. target->put(UnicodeString(*key), copy, status);
  2704. if ( U_FAILURE(status) ) {
  2705. return;
  2706. }
  2707. }
  2708. }
  2709. }
  2710. void
  2711. DecimalFormat::setGroupingUsed(UBool newValue) {
  2712. NumberFormat::setGroupingUsed(newValue);
  2713. fImpl->updateGrouping();
  2714. }
  2715. void
  2716. DecimalFormat::setParseIntegerOnly(UBool newValue) {
  2717. NumberFormat::setParseIntegerOnly(newValue);
  2718. }
  2719. void
  2720. DecimalFormat::setContext(UDisplayContext value, UErrorCode& status) {
  2721. NumberFormat::setContext(value, status);
  2722. }
  2723. DecimalFormat& DecimalFormat::setAttribute( UNumberFormatAttribute attr,
  2724. int32_t newValue,
  2725. UErrorCode &status) {
  2726. if(U_FAILURE(status)) return *this;
  2727. switch(attr) {
  2728. case UNUM_LENIENT_PARSE:
  2729. setLenient(newValue!=0);
  2730. break;
  2731. case UNUM_PARSE_INT_ONLY:
  2732. setParseIntegerOnly(newValue!=0);
  2733. break;
  2734. case UNUM_GROUPING_USED:
  2735. setGroupingUsed(newValue!=0);
  2736. break;
  2737. case UNUM_DECIMAL_ALWAYS_SHOWN:
  2738. setDecimalSeparatorAlwaysShown(newValue!=0);
  2739. break;
  2740. case UNUM_MAX_INTEGER_DIGITS:
  2741. setMaximumIntegerDigits(newValue);
  2742. break;
  2743. case UNUM_MIN_INTEGER_DIGITS:
  2744. setMinimumIntegerDigits(newValue);
  2745. break;
  2746. case UNUM_INTEGER_DIGITS:
  2747. setMinimumIntegerDigits(newValue);
  2748. setMaximumIntegerDigits(newValue);
  2749. break;
  2750. case UNUM_MAX_FRACTION_DIGITS:
  2751. setMaximumFractionDigits(newValue);
  2752. break;
  2753. case UNUM_MIN_FRACTION_DIGITS:
  2754. setMinimumFractionDigits(newValue);
  2755. break;
  2756. case UNUM_FRACTION_DIGITS:
  2757. setMinimumFractionDigits(newValue);
  2758. setMaximumFractionDigits(newValue);
  2759. break;
  2760. case UNUM_SIGNIFICANT_DIGITS_USED:
  2761. setSignificantDigitsUsed(newValue!=0);
  2762. break;
  2763. case UNUM_MAX_SIGNIFICANT_DIGITS:
  2764. setMaximumSignificantDigits(newValue);
  2765. break;
  2766. case UNUM_MIN_SIGNIFICANT_DIGITS:
  2767. setMinimumSignificantDigits(newValue);
  2768. break;
  2769. case UNUM_MULTIPLIER:
  2770. setMultiplier(newValue);
  2771. break;
  2772. case UNUM_GROUPING_SIZE:
  2773. setGroupingSize(newValue);
  2774. break;
  2775. case UNUM_ROUNDING_MODE:
  2776. setRoundingMode((DecimalFormat::ERoundingMode)newValue);
  2777. break;
  2778. case UNUM_FORMAT_WIDTH:
  2779. setFormatWidth(newValue);
  2780. break;
  2781. case UNUM_PADDING_POSITION:
  2782. /** The position at which padding will take place. */
  2783. setPadPosition((DecimalFormat::EPadPosition)newValue);
  2784. break;
  2785. case UNUM_SECONDARY_GROUPING_SIZE:
  2786. setSecondaryGroupingSize(newValue);
  2787. break;
  2788. #if UCONFIG_HAVE_PARSEALLINPUT
  2789. case UNUM_PARSE_ALL_INPUT:
  2790. setParseAllInput((UNumberFormatAttributeValue)newValue);
  2791. break;
  2792. #endif
  2793. /* These are stored in fBoolFlags */
  2794. case UNUM_PARSE_NO_EXPONENT:
  2795. case UNUM_FORMAT_FAIL_IF_MORE_THAN_MAX_DIGITS:
  2796. case UNUM_PARSE_DECIMAL_MARK_REQUIRED:
  2797. if(!fBoolFlags.isValidValue(newValue)) {
  2798. status = U_ILLEGAL_ARGUMENT_ERROR;
  2799. } else {
  2800. if (attr == UNUM_FORMAT_FAIL_IF_MORE_THAN_MAX_DIGITS) {
  2801. fImpl->setFailIfMoreThanMaxDigits((UBool) newValue);
  2802. }
  2803. fBoolFlags.set(attr, newValue);
  2804. }
  2805. break;
  2806. case UNUM_SCALE:
  2807. fImpl->setScale(newValue);
  2808. break;
  2809. case UNUM_CURRENCY_USAGE:
  2810. setCurrencyUsage((UCurrencyUsage)newValue, &status);
  2811. break;
  2812. case UNUM_MINIMUM_GROUPING_DIGITS:
  2813. setMinimumGroupingDigits(newValue);
  2814. break;
  2815. default:
  2816. status = U_UNSUPPORTED_ERROR;
  2817. break;
  2818. }
  2819. return *this;
  2820. }
  2821. int32_t DecimalFormat::getAttribute( UNumberFormatAttribute attr,
  2822. UErrorCode &status ) const {
  2823. if(U_FAILURE(status)) return -1;
  2824. switch(attr) {
  2825. case UNUM_LENIENT_PARSE:
  2826. return isLenient();
  2827. case UNUM_PARSE_INT_ONLY:
  2828. return isParseIntegerOnly();
  2829. case UNUM_GROUPING_USED:
  2830. return isGroupingUsed();
  2831. case UNUM_DECIMAL_ALWAYS_SHOWN:
  2832. return isDecimalSeparatorAlwaysShown();
  2833. case UNUM_MAX_INTEGER_DIGITS:
  2834. return getMaximumIntegerDigits();
  2835. case UNUM_MIN_INTEGER_DIGITS:
  2836. return getMinimumIntegerDigits();
  2837. case UNUM_INTEGER_DIGITS:
  2838. // TBD: what should this return?
  2839. return getMinimumIntegerDigits();
  2840. case UNUM_MAX_FRACTION_DIGITS:
  2841. return getMaximumFractionDigits();
  2842. case UNUM_MIN_FRACTION_DIGITS:
  2843. return getMinimumFractionDigits();
  2844. case UNUM_FRACTION_DIGITS:
  2845. // TBD: what should this return?
  2846. return getMinimumFractionDigits();
  2847. case UNUM_SIGNIFICANT_DIGITS_USED:
  2848. return areSignificantDigitsUsed();
  2849. case UNUM_MAX_SIGNIFICANT_DIGITS:
  2850. return getMaximumSignificantDigits();
  2851. case UNUM_MIN_SIGNIFICANT_DIGITS:
  2852. return getMinimumSignificantDigits();
  2853. case UNUM_MULTIPLIER:
  2854. return getMultiplier();
  2855. case UNUM_GROUPING_SIZE:
  2856. return getGroupingSize();
  2857. case UNUM_ROUNDING_MODE:
  2858. return getRoundingMode();
  2859. case UNUM_FORMAT_WIDTH:
  2860. return getFormatWidth();
  2861. case UNUM_PADDING_POSITION:
  2862. return getPadPosition();
  2863. case UNUM_SECONDARY_GROUPING_SIZE:
  2864. return getSecondaryGroupingSize();
  2865. /* These are stored in fBoolFlags */
  2866. case UNUM_PARSE_NO_EXPONENT:
  2867. case UNUM_FORMAT_FAIL_IF_MORE_THAN_MAX_DIGITS:
  2868. case UNUM_PARSE_DECIMAL_MARK_REQUIRED:
  2869. return fBoolFlags.get(attr);
  2870. case UNUM_SCALE:
  2871. return fImpl->fScale;
  2872. case UNUM_CURRENCY_USAGE:
  2873. return fImpl->getCurrencyUsage();
  2874. case UNUM_MINIMUM_GROUPING_DIGITS:
  2875. return getMinimumGroupingDigits();
  2876. default:
  2877. status = U_UNSUPPORTED_ERROR;
  2878. break;
  2879. }
  2880. return -1; /* undefined */
  2881. }
  2882. #if UCONFIG_HAVE_PARSEALLINPUT
  2883. void DecimalFormat::setParseAllInput(UNumberFormatAttributeValue value) {
  2884. fParseAllInput = value;
  2885. }
  2886. #endif
  2887. U_NAMESPACE_END
  2888. #endif /* #if !UCONFIG_NO_FORMATTING */
  2889. //eof