1:
37:
38: package ;
39:
40: import ;
41: import ;
42: import ;
43: import ;
44:
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50:
51:
56:
62: public class DecimalFormat extends NumberFormat
63: {
64:
65:
66: private int scanFix (String pattern, int index, FormatBuffer buf,
67: String patChars, DecimalFormatSymbols syms,
68: boolean is_suffix)
69: {
70: int len = pattern.length();
71: boolean quoteStarted = false;
72: buf.clear();
73:
74: boolean multiplierSet = false;
75: while (index < len)
76: {
77: char c = pattern.charAt(index);
78:
79: if (quoteStarted)
80: {
81: if (c == '\'')
82: quoteStarted = false;
83: else
84: buf.append(c);
85: index++;
86: continue;
87: }
88:
89: if (c == '\'' && index + 1 < len
90: && pattern.charAt(index + 1) == '\'')
91: {
92: buf.append(c);
93: index++;
94: }
95: else if (c == '\'')
96: {
97: quoteStarted = true;
98: }
99: else if (c == '\u00a4')
100: {
101:
102: buf.append(c);
103: }
104: else if (c == syms.getPercent())
105: {
106: if (multiplierSet)
107: throw new IllegalArgumentException ("multiplier already set " +
108: "- index: " + index);
109: multiplierSet = true;
110: multiplier = 100;
111: buf.append(c, NumberFormat.Field.PERCENT);
112: }
113: else if (c == syms.getPerMill())
114: {
115: if (multiplierSet)
116: throw new IllegalArgumentException ("multiplier already set " +
117: "- index: " + index);
118: multiplierSet = true;
119: multiplier = 1000;
120: buf.append(c, NumberFormat.Field.PERMILLE);
121: }
122: else if (patChars.indexOf(c) != -1)
123: {
124:
125: break;
126: }
127: else
128: {
129: buf.append(c);
130: }
131: index++;
132: }
133:
134: if (quoteStarted)
135: throw new IllegalArgumentException ("pattern is lacking a closing quote");
136:
137: return index;
138: }
139:
140:
141: private int scanFormat (String pattern, int index, String patChars,
142: DecimalFormatSymbols syms, boolean is_positive)
143: {
144: int max = pattern.length();
145:
146: int countSinceGroup = 0;
147: int zeroCount = 0;
148: boolean saw_group = false;
149:
150:
151:
152:
153: while (index < max)
154: {
155: char c = pattern.charAt(index);
156:
157: if (c == syms.getDigit())
158: {
159: if (zeroCount > 0)
160: throw new IllegalArgumentException ("digit mark following " +
161: "zero - index: " + index);
162: ++countSinceGroup;
163: }
164: else if (c == syms.getZeroDigit())
165: {
166: ++zeroCount;
167: ++countSinceGroup;
168: }
169: else if (c == syms.getGroupingSeparator())
170: {
171: countSinceGroup = 0;
172: saw_group = true;
173: }
174: else
175: break;
176:
177: ++index;
178: }
179:
180:
181: if (is_positive)
182: {
183: groupingUsed = saw_group;
184: groupingSize = (byte) countSinceGroup;
185: minimumIntegerDigits = zeroCount;
186: }
187:
188:
189: if (index == max || pattern.charAt(index) == syms.getGroupingSeparator())
190: {
191: if (is_positive)
192: decimalSeparatorAlwaysShown = false;
193: return index;
194: }
195:
196: if (pattern.charAt(index) == syms.getDecimalSeparator())
197: {
198: ++index;
199:
200:
201:
202:
203: int hashCount = 0;
204: zeroCount = 0;
205: while (index < max)
206: {
207: char c = pattern.charAt(index);
208: if (c == syms.getZeroDigit())
209: {
210: if (hashCount > 0)
211: throw new IllegalArgumentException ("zero mark " +
212: "following digit - index: " + index);
213: ++zeroCount;
214: }
215: else if (c == syms.getDigit())
216: {
217: ++hashCount;
218: }
219: else if (c != syms.getExponential()
220: && c != syms.getPatternSeparator()
221: && c != syms.getPercent()
222: && c != syms.getPerMill()
223: && patChars.indexOf(c) != -1)
224: throw new IllegalArgumentException ("unexpected special " +
225: "character - index: " + index);
226: else
227: break;
228:
229: ++index;
230: }
231:
232: if (is_positive)
233: {
234: maximumFractionDigits = hashCount + zeroCount;
235: minimumFractionDigits = zeroCount;
236: }
237:
238: if (index == max)
239: return index;
240: }
241:
242: if (pattern.charAt(index) == syms.getExponential())
243: {
244:
245:
246:
247: zeroCount = 0;
248: ++index;
249: while (index < max)
250: {
251: char c = pattern.charAt(index);
252: if (c == syms.getZeroDigit())
253: ++zeroCount;
254: else if (c == syms.getDigit())
255: {
256: if (zeroCount > 0)
257: throw new
258: IllegalArgumentException ("digit mark following zero " +
259: "in exponent - index: " +
260: index);
261: }
262: else if (patChars.indexOf(c) != -1)
263: throw new IllegalArgumentException ("unexpected special " +
264: "character - index: " +
265: index);
266: else
267: break;
268:
269: ++index;
270: }
271:
272: if (is_positive)
273: {
274: useExponentialNotation = true;
275: minExponentDigits = (byte) zeroCount;
276: }
277:
278: maximumIntegerDigits = groupingSize;
279: groupingSize = 0;
280: if (maximumIntegerDigits > minimumIntegerDigits && maximumIntegerDigits > 0)
281: {
282: minimumIntegerDigits = 1;
283: exponentRound = maximumIntegerDigits;
284: }
285: else
286: exponentRound = 1;
287: }
288:
289: return index;
290: }
291:
292:
293:
294: private String patternChars (DecimalFormatSymbols syms)
295: {
296: StringBuffer buf = new StringBuffer ();
297: buf.append(syms.getDecimalSeparator());
298: buf.append(syms.getDigit());
299: buf.append(syms.getExponential());
300: buf.append(syms.getGroupingSeparator());
301:
302:
303:
304:
305: buf.append(syms.getPatternSeparator());
306: buf.append(syms.getPercent());
307: buf.append(syms.getPerMill());
308: buf.append(syms.getZeroDigit());
309: buf.append('\u00a4');
310: return buf.toString();
311: }
312:
313: private void applyPatternWithSymbols(String pattern, DecimalFormatSymbols syms)
314: {
315:
316: negativePrefix = "";
317: negativeSuffix = "";
318: positivePrefix = "";
319: positiveSuffix = "";
320: decimalSeparatorAlwaysShown = false;
321: groupingSize = 0;
322: minExponentDigits = 0;
323: multiplier = 1;
324: useExponentialNotation = false;
325: groupingUsed = false;
326: maximumFractionDigits = 0;
327: maximumIntegerDigits = MAXIMUM_INTEGER_DIGITS;
328: minimumFractionDigits = 0;
329: minimumIntegerDigits = 1;
330:
331: AttributedFormatBuffer buf = new AttributedFormatBuffer ();
332: String patChars = patternChars (syms);
333:
334: int max = pattern.length();
335: int index = scanFix (pattern, 0, buf, patChars, syms, false);
336: buf.sync();
337: positivePrefix = buf.getBuffer().toString();
338: positivePrefixRanges = buf.getRanges();
339: positivePrefixAttrs = buf.getAttributes();
340:
341: index = scanFormat (pattern, index, patChars, syms, true);
342:
343: index = scanFix (pattern, index, buf, patChars, syms, true);
344: buf.sync();
345: positiveSuffix = buf.getBuffer().toString();
346: positiveSuffixRanges = buf.getRanges();
347: positiveSuffixAttrs = buf.getAttributes();
348:
349: if (index == pattern.length())
350: {
351:
352: negativePrefix = null;
353: negativeSuffix = null;
354: }
355: else
356: {
357: if (pattern.charAt(index) != syms.getPatternSeparator())
358: throw new IllegalArgumentException ("separator character " +
359: "expected - index: " + index);
360:
361: index = scanFix (pattern, index + 1, buf, patChars, syms, false);
362: buf.sync();
363: negativePrefix = buf.getBuffer().toString();
364: negativePrefixRanges = buf.getRanges();
365: negativePrefixAttrs = buf.getAttributes();
366:
367:
368:
369: index = scanFormat (pattern, index, patChars, syms, false);
370:
371: index = scanFix (pattern, index, buf, patChars, syms, true);
372: buf.sync();
373: negativeSuffix = buf.getBuffer().toString();
374: negativeSuffixRanges = buf.getRanges();
375: negativeSuffixAttrs = buf.getAttributes();
376:
377: if (index != pattern.length())
378: throw new IllegalArgumentException ("end of pattern expected " +
379: "- index: " + index);
380: }
381: }
382:
383: public void applyLocalizedPattern (String pattern)
384: {
385:
386:
387:
388:
389: applyPatternWithSymbols (pattern, symbols);
390: }
391:
392: public void applyPattern (String pattern)
393: {
394:
395:
396:
397:
398: applyPatternWithSymbols (pattern, nonLocalizedSymbols);
399: }
400:
401: public Object clone ()
402: {
403: DecimalFormat c = (DecimalFormat) super.clone ();
404: c.symbols = (DecimalFormatSymbols) symbols.clone ();
405: return c;
406: }
407:
408:
412: public DecimalFormat ()
413: {
414: this ("#,##0.###");
415: }
416:
417:
425: public DecimalFormat (String pattern)
426: {
427: this (pattern, new DecimalFormatSymbols ());
428: }
429:
430:
440: public DecimalFormat(String pattern, DecimalFormatSymbols symbols)
441: {
442: this.symbols = (DecimalFormatSymbols) symbols.clone();
443: applyPattern(pattern);
444: }
445:
446: private boolean equals(String s1, String s2)
447: {
448: if (s1 == null || s2 == null)
449: return s1 == s2;
450: return s1.equals(s2);
451: }
452:
453:
466: public boolean equals(Object obj)
467: {
468: if (! (obj instanceof DecimalFormat))
469: return false;
470: DecimalFormat dup = (DecimalFormat) obj;
471: return (decimalSeparatorAlwaysShown == dup.decimalSeparatorAlwaysShown
472: && groupingUsed == dup.groupingUsed
473: && groupingSize == dup.groupingSize
474: && multiplier == dup.multiplier
475: && useExponentialNotation == dup.useExponentialNotation
476: && minExponentDigits == dup.minExponentDigits
477: && minimumIntegerDigits == dup.minimumIntegerDigits
478: && maximumIntegerDigits == dup.maximumIntegerDigits
479: && minimumFractionDigits == dup.minimumFractionDigits
480: && maximumFractionDigits == dup.maximumFractionDigits
481: && equals(negativePrefix, dup.negativePrefix)
482: && equals(negativeSuffix, dup.negativeSuffix)
483: && equals(positivePrefix, dup.positivePrefix)
484: && equals(positiveSuffix, dup.positiveSuffix)
485: && symbols.equals(dup.symbols));
486: }
487:
488: private void formatInternal (double number, FormatBuffer dest,
489: FieldPosition fieldPos)
490: {
491:
492: if (Double.isNaN(number))
493: {
494: dest.append(symbols.getNaN());
495: if (fieldPos != null &&
496: (fieldPos.getField() == INTEGER_FIELD ||
497: fieldPos.getFieldAttribute() == NumberFormat.Field.INTEGER))
498: {
499: int index = dest.length();
500: fieldPos.setBeginIndex(index - symbols.getNaN().length());
501: fieldPos.setEndIndex(index);
502: }
503: return;
504: }
505:
506: boolean is_neg = number < 0;
507: if (is_neg)
508: {
509: if (negativePrefix != null)
510: {
511: dest.append(substituteCurrency(negativePrefix, number),
512: negativePrefixRanges, negativePrefixAttrs);
513: }
514: else
515: {
516: dest.append(symbols.getMinusSign(), NumberFormat.Field.SIGN);
517: dest.append(substituteCurrency(positivePrefix, number),
518: positivePrefixRanges, positivePrefixAttrs);
519: }
520: number = - number;
521: }
522: else
523: {
524: dest.append(substituteCurrency(positivePrefix, number),
525: positivePrefixRanges, positivePrefixAttrs);
526: }
527: int integerBeginIndex = dest.length();
528: int integerEndIndex = 0;
529: int zeroStart = symbols.getZeroDigit() - '0';
530:
531: if (Double.isInfinite (number))
532: {
533: dest.append(symbols.getInfinity());
534: integerEndIndex = dest.length();
535: }
536: else
537: {
538: number *= multiplier;
539:
540:
541: long exponent = 0;
542: double baseNumber;
543: if (useExponentialNotation)
544: {
545: exponent = (long) Math.floor (Math.log(number) / Math.log(10));
546: exponent = exponent - (exponent % exponentRound);
547: if (minimumIntegerDigits > 0)
548: exponent -= minimumIntegerDigits - 1;
549: baseNumber = (number / Math.pow(10.0, exponent));
550: }
551: else
552: baseNumber = number;
553:
554:
555: baseNumber += 5 * Math.pow(10.0, - maximumFractionDigits - 1);
556:
557: int index = dest.length();
558:
559: String intPart = Long.toString((long)Math.floor(baseNumber));
560: int count, groupPosition = intPart.length();
561:
562: dest.setDefaultAttribute(NumberFormat.Field.INTEGER);
563:
564: for (count = 0; count < minimumIntegerDigits-intPart.length(); count++)
565: dest.append(symbols.getZeroDigit());
566:
567: for (count = 0;
568: count < maximumIntegerDigits && count < intPart.length();
569: count++)
570: {
571: int dig = intPart.charAt(count);
572:
573:
574: if (groupingUsed && count > 0 && groupingSize != 0 && groupPosition % groupingSize == 0)
575: {
576: dest.append(symbols.getGroupingSeparator(), NumberFormat.Field.GROUPING_SEPARATOR);
577: dest.setDefaultAttribute(NumberFormat.Field.INTEGER);
578: }
579: dest.append((char) (zeroStart + dig));
580:
581: groupPosition--;
582: }
583: dest.setDefaultAttribute(null);
584:
585: integerEndIndex = dest.length();
586:
587: int decimal_index = integerEndIndex;
588: int consecutive_zeros = 0;
589: int total_digits = 0;
590:
591: int localMaximumFractionDigits = maximumFractionDigits;
592:
593: if (useExponentialNotation)
594: localMaximumFractionDigits += minimumIntegerDigits - count;
595:
596:
597: double fracPart = baseNumber - Math.floor(baseNumber);
598:
599: if ( ((fracPart != 0 || minimumFractionDigits > 0) && localMaximumFractionDigits > 0)
600: || decimalSeparatorAlwaysShown)
601: {
602: dest.append (symbols.getDecimalSeparator(), NumberFormat.Field.DECIMAL_SEPARATOR);
603: }
604:
605: int fraction_begin = dest.length();
606: dest.setDefaultAttribute(NumberFormat.Field.FRACTION);
607: for (count = 0;
608: count < localMaximumFractionDigits
609: && (fracPart != 0 || count < minimumFractionDigits);
610: ++count)
611: {
612: ++total_digits;
613: fracPart *= 10;
614: long dig = (long) fracPart;
615: if (dig == 0)
616: ++consecutive_zeros;
617: else
618: consecutive_zeros = 0;
619: dest.append((char) (symbols.getZeroDigit() + dig));
620:
621:
622: fracPart = fracPart - Math.floor (fracPart);
623: }
624:
625:
626:
627: int extra_zeros = Math.min (consecutive_zeros,
628: total_digits - minimumFractionDigits);
629: if (extra_zeros > 0)
630: {
631: dest.cutTail(extra_zeros);
632: total_digits -= extra_zeros;
633: if (total_digits == 0 && !decimalSeparatorAlwaysShown)
634: dest.cutTail(1);
635: }
636:
637: if (fieldPos != null && fieldPos.getField() == FRACTION_FIELD)
638: {
639: fieldPos.setBeginIndex(fraction_begin);
640: fieldPos.setEndIndex(dest.length());
641: }
642:
643:
644: if (useExponentialNotation)
645: {
646: dest.append(symbols.getExponential(), NumberFormat.Field.EXPONENT_SYMBOL);
647: if (exponent < 0)
648: {
649: dest.append (symbols.getMinusSign (), NumberFormat.Field.EXPONENT_SIGN);
650: exponent = - exponent;
651: }
652: index = dest.length();
653: dest.setDefaultAttribute(NumberFormat.Field.EXPONENT);
654: String exponentString = Long.toString ((long) exponent);
655:
656: for (count = 0; count < minExponentDigits-exponentString.length();
657: count++)
658: dest.append((char) symbols.getZeroDigit());
659:
660: for (count = 0;
661: count < exponentString.length();
662: ++count)
663: {
664: int dig = exponentString.charAt(count);
665: dest.append((char) (zeroStart + dig));
666: }
667: }
668: }
669:
670: if (fieldPos != null &&
671: (fieldPos.getField() == INTEGER_FIELD ||
672: fieldPos.getFieldAttribute() == NumberFormat.Field.INTEGER))
673: {
674: fieldPos.setBeginIndex(integerBeginIndex);
675: fieldPos.setEndIndex(integerEndIndex);
676: }
677:
678: if (is_neg && negativeSuffix != null)
679: {
680: dest.append(substituteCurrency(negativeSuffix, number),
681: negativeSuffixRanges, negativeSuffixAttrs);
682: }
683: else
684: {
685: dest.append(substituteCurrency(positiveSuffix, number),
686: positiveSuffixRanges, positiveSuffixAttrs);
687: }
688: }
689:
690: public StringBuffer format (double number, StringBuffer dest,
691: FieldPosition fieldPos)
692: {
693: formatInternal (number, new StringFormatBuffer(dest), fieldPos);
694: return dest;
695: }
696:
697: public AttributedCharacterIterator formatToCharacterIterator (Object value)
698: {
699: AttributedFormatBuffer sbuf = new AttributedFormatBuffer();
700:
701: if (value instanceof Number)
702: formatInternal(((Number) value).doubleValue(), sbuf, null);
703: else
704: throw new IllegalArgumentException
705: ("Cannot format given Object as a Number");
706:
707: sbuf.sync();
708: return new FormatCharacterIterator(sbuf.getBuffer().toString(),
709: sbuf.getRanges(),
710: sbuf.getAttributes());
711: }
712:
713: public StringBuffer format (long number, StringBuffer dest,
714: FieldPosition fieldPos)
715: {
716:
717: if (useExponentialNotation)
718: return format ((double) number, dest, fieldPos);
719:
720: boolean is_neg = number < 0;
721: if (is_neg)
722: {
723: if (negativePrefix != null)
724: dest.append(substituteCurrency(negativePrefix, number));
725: else
726: {
727: dest.append(symbols.getMinusSign());
728: dest.append(substituteCurrency(positivePrefix, number));
729: }
730: number = - number;
731: }
732: else
733: dest.append(substituteCurrency(positivePrefix, number));
734:
735: int integerBeginIndex = dest.length();
736: int index = dest.length();
737: int count = 0;
738:
739:
740: number *= multiplier;
741: while (count < maximumIntegerDigits
742: && (number > 0 || count < minimumIntegerDigits))
743: {
744: long dig = number % 10;
745: number /= 10;
746:
747:
748: if (dig < 0)
749: {
750: dig = - dig;
751: number = - number;
752: }
753:
754:
755: if (groupingUsed && count > 0 && groupingSize != 0 && count % groupingSize == 0)
756: dest.insert(index, symbols.getGroupingSeparator());
757:
758: dest.insert(index, (char) (symbols.getZeroDigit() + dig));
759:
760: ++count;
761: }
762:
763: if (fieldPos != null && fieldPos.getField() == INTEGER_FIELD)
764: {
765: fieldPos.setBeginIndex(integerBeginIndex);
766: fieldPos.setEndIndex(dest.length());
767: }
768:
769: if (decimalSeparatorAlwaysShown || minimumFractionDigits > 0)
770: {
771: dest.append(symbols.getDecimalSeparator());
772: if (fieldPos != null && fieldPos.getField() == FRACTION_FIELD)
773: {
774: fieldPos.setBeginIndex(dest.length());
775: fieldPos.setEndIndex(dest.length() + minimumFractionDigits);
776: }
777: }
778:
779: for (count = 0; count < minimumFractionDigits; ++count)
780: dest.append(symbols.getZeroDigit());
781:
782: dest.append((is_neg && negativeSuffix != null)
783: ? substituteCurrency(negativeSuffix, number)
784: : substituteCurrency(positiveSuffix, number));
785: return dest;
786: }
787:
788:
796: public Currency getCurrency()
797: {
798: return symbols.getCurrency();
799: }
800:
801:
806: public DecimalFormatSymbols getDecimalFormatSymbols()
807: {
808: return (DecimalFormatSymbols) symbols.clone();
809: }
810:
811: public int getGroupingSize ()
812: {
813: return groupingSize;
814: }
815:
816: public int getMultiplier ()
817: {
818: return multiplier;
819: }
820:
821: public String getNegativePrefix ()
822: {
823: return negativePrefix;
824: }
825:
826: public String getNegativeSuffix ()
827: {
828: return negativeSuffix;
829: }
830:
831: public String getPositivePrefix ()
832: {
833: return positivePrefix;
834: }
835:
836: public String getPositiveSuffix ()
837: {
838: return positiveSuffix;
839: }
840:
841:
846: public int hashCode()
847: {
848: return toPattern().hashCode();
849: }
850:
851: public boolean isDecimalSeparatorAlwaysShown ()
852: {
853: return decimalSeparatorAlwaysShown;
854: }
855:
856: public Number parse (String str, ParsePosition pos)
857: {
858:
866:
867: boolean is_neg = false;
868: int index = pos.getIndex();
869: StringBuffer int_buf = new StringBuffer ();
870:
871:
872:
873: boolean got_pos = str.startsWith(positivePrefix, index);
874: String np = (negativePrefix != null
875: ? negativePrefix
876: : positivePrefix + symbols.getMinusSign());
877: boolean got_neg = str.startsWith(np, index);
878:
879: if (got_pos && got_neg)
880: {
881:
882:
883:
884: if (np.length() > positivePrefix.length())
885: {
886: is_neg = true;
887: index += np.length();
888: }
889: else
890: index += positivePrefix.length();
891: }
892: else if (got_neg)
893: {
894: is_neg = true;
895: index += np.length();
896: }
897: else if (got_pos)
898: index += positivePrefix.length();
899: else
900: {
901: pos.setErrorIndex (index);
902: return null;
903: }
904:
905:
906:
907:
908:
909:
910: StringBuffer buf = int_buf;
911: StringBuffer frac_buf = null;
912: StringBuffer exp_buf = null;
913: int start_index = index;
914: int max = str.length();
915: int exp_index = -1;
916: int last = index + maximumIntegerDigits;
917:
918: if (maximumFractionDigits > 0)
919: last += maximumFractionDigits + 1;
920:
921: if (useExponentialNotation)
922: last += minExponentDigits + 1;
923:
924: if (last > 0 && max > last)
925: max = last;
926:
927: char zero = symbols.getZeroDigit();
928: int last_group = -1;
929: boolean int_part = true;
930: boolean exp_part = false;
931: for (; index < max; ++index)
932: {
933: char c = str.charAt(index);
934:
935:
936: if (groupingUsed && c == symbols.getGroupingSeparator())
937: {
938: if (last_group != -1
939: && groupingSize != 0
940: && (index - last_group) % groupingSize != 0)
941: {
942: pos.setErrorIndex(index);
943: return null;
944: }
945: last_group = index+1;
946: }
947: else if (c >= zero && c <= zero + 9)
948: {
949: buf.append((char) (c - zero + '0'));
950: }
951: else if (parseIntegerOnly)
952: break;
953: else if (c == symbols.getDecimalSeparator())
954: {
955: if (last_group != -1
956: && groupingSize != 0
957: && (index - last_group) % groupingSize != 0)
958: {
959: pos.setErrorIndex(index);
960: return null;
961: }
962: buf = frac_buf = new StringBuffer();
963: frac_buf.append('.');
964: int_part = false;
965: }
966: else if (c == symbols.getExponential())
967: {
968: buf = exp_buf = new StringBuffer();
969: int_part = false;
970: exp_part = true;
971: exp_index = index+1;
972: }
973: else if (exp_part
974: && (c == '+' || c == '-' || c == symbols.getMinusSign()))
975: {
976:
977: buf.append(c);
978: }
979: else
980: break;
981: }
982:
983: if (index == start_index)
984: {
985:
986: pos.setErrorIndex(index);
987: return null;
988: }
989:
990:
991:
992:
993: boolean got_pos_suf = str.startsWith(positiveSuffix, index);
994: String ns = (negativePrefix == null ? positiveSuffix : negativeSuffix);
995: boolean got_neg_suf = str.startsWith(ns, index);
996: if (is_neg)
997: {
998: if (! got_neg_suf)
999: {
1000: pos.setErrorIndex(index);
1001: return null;
1002: }
1003: }
1004: else if (got_pos && got_neg && got_neg_suf)
1005: {
1006: is_neg = true;
1007: }
1008: else if (got_pos != got_pos_suf && got_neg != got_neg_suf)
1009: {
1010: pos.setErrorIndex(index);
1011: return null;
1012: }
1013: else if (! got_pos_suf)
1014: {
1015: pos.setErrorIndex(index);
1016: return null;
1017: }
1018:
1019: String suffix = is_neg ? ns : positiveSuffix;
1020: long parsedMultiplier = 1;
1021: boolean use_long;
1022:
1023: if (is_neg)
1024: int_buf.insert(0, '-');
1025:
1026:
1027: if (exp_buf != null)
1028: {
1029: int exponent_value;
1030:
1031: try
1032: {
1033: exponent_value = Integer.parseInt(exp_buf.toString());
1034: }
1035: catch (NumberFormatException x1)
1036: {
1037: pos.setErrorIndex(exp_index);
1038: return null;
1039: }
1040:
1041: if (frac_buf == null)
1042: {
1043:
1044:
1045: for (int i = 0; i < exponent_value; i++)
1046: int_buf.append('0');
1047:
1048: use_long = true;
1049: }
1050: else
1051: {
1052: boolean long_sufficient;
1053:
1054: if (exponent_value < frac_buf.length()-1)
1055: {
1056: int lastNonNull = -1;
1057:
1060: for (int i = 1; i < frac_buf.length(); i++)
1061: if (frac_buf.charAt(i) != '0')
1062: lastNonNull = i;
1063:
1064: long_sufficient = (lastNonNull < 0 || lastNonNull <= exponent_value);
1065: }
1066: else
1067: long_sufficient = true;
1068:
1069: if (long_sufficient)
1070: {
1071: for (int i = 1; i < frac_buf.length() && i < exponent_value; i++)
1072: int_buf.append(frac_buf.charAt(i));
1073: for (int i = frac_buf.length()-1; i < exponent_value; i++)
1074: int_buf.append('0');
1075: use_long = true;
1076: }
1077: else
1078: {
1079:
1083: int_buf.append(frac_buf);
1084: int_buf.append('E');
1085: int_buf.append(exp_buf);
1086: use_long = false;
1087: }
1088: }
1089: }
1090: else
1091: {
1092: if (frac_buf != null)
1093: {
1094:
1095: int i;
1096: for (i = 1; i < frac_buf.length(); i++)
1097: if (frac_buf.charAt(i) != '0')
1098: break;
1099:
1100: if (i != frac_buf.length())
1101: {
1102: use_long = false;
1103: int_buf.append(frac_buf);
1104: }
1105: else
1106: use_long = true;
1107: }
1108: else
1109: use_long = true;
1110: }
1111:
1112: String t = int_buf.toString();
1113: Number result = null;
1114: if (use_long)
1115: {
1116: try
1117: {
1118: result = new Long (t);
1119: }
1120: catch (NumberFormatException x1)
1121: {
1122: }
1123: }
1124: else
1125: {
1126: try
1127: {
1128: result = new Double (t);
1129: }
1130: catch (NumberFormatException x2)
1131: {
1132: }
1133: }
1134: if (result == null)
1135: {
1136: pos.setErrorIndex(index);
1137: return null;
1138: }
1139:
1140: pos.setIndex(index + suffix.length());
1141:
1142: return result;
1143: }
1144:
1145:
1150: public void setCurrency(Currency currency)
1151: {
1152: symbols.setCurrency(currency);
1153: }
1154:
1155:
1161: public void setDecimalFormatSymbols(DecimalFormatSymbols newSymbols)
1162: {
1163: symbols = (DecimalFormatSymbols) newSymbols.clone();
1164: }
1165:
1166: public void setDecimalSeparatorAlwaysShown (boolean newValue)
1167: {
1168: decimalSeparatorAlwaysShown = newValue;
1169: }
1170:
1171: public void setGroupingSize (int groupSize)
1172: {
1173: groupingSize = (byte) groupSize;
1174: }
1175:
1176: public void setMaximumFractionDigits (int newValue)
1177: {
1178: super.setMaximumFractionDigits(Math.min(newValue, 340));
1179: }
1180:
1181: public void setMaximumIntegerDigits (int newValue)
1182: {
1183: super.setMaximumIntegerDigits(Math.min(newValue, 309));
1184: }
1185:
1186: public void setMinimumFractionDigits (int newValue)
1187: {
1188: super.setMinimumFractionDigits(Math.min(newValue, 340));
1189: }
1190:
1191: public void setMinimumIntegerDigits (int newValue)
1192: {
1193: super.setMinimumIntegerDigits(Math.min(newValue, 309));
1194: }
1195:
1196: public void setMultiplier (int newValue)
1197: {
1198: multiplier = newValue;
1199: }
1200:
1201: public void setNegativePrefix (String newValue)
1202: {
1203: negativePrefix = newValue;
1204: }
1205:
1206: public void setNegativeSuffix (String newValue)
1207: {
1208: negativeSuffix = newValue;
1209: }
1210:
1211: public void setPositivePrefix (String newValue)
1212: {
1213: positivePrefix = newValue;
1214: }
1215:
1216: public void setPositiveSuffix (String newValue)
1217: {
1218: positiveSuffix = newValue;
1219: }
1220:
1221: private void quoteFix(StringBuffer buf, String text, String patChars)
1222: {
1223: int len = text.length();
1224: for (int index = 0; index < len; ++index)
1225: {
1226: char c = text.charAt(index);
1227: if (patChars.indexOf(c) != -1)
1228: {
1229: buf.append('\'');
1230: buf.append(c);
1231: buf.append('\'');
1232: }
1233: else
1234: buf.append(c);
1235: }
1236: }
1237:
1238: private String computePattern(DecimalFormatSymbols syms)
1239: {
1240: StringBuffer mainPattern = new StringBuffer ();
1241:
1242:
1243:
1244: int total_digits = Math.max(minimumIntegerDigits,
1245: groupingUsed ? groupingSize + 1: groupingSize);
1246: for (int i = 0; i < total_digits - minimumIntegerDigits; ++i)
1247: mainPattern.append(syms.getDigit());
1248: for (int i = total_digits - minimumIntegerDigits; i < total_digits; ++i)
1249: mainPattern.append(syms.getZeroDigit());
1250:
1251: if (groupingUsed)
1252: mainPattern.insert(mainPattern.length() - groupingSize,
1253: syms.getGroupingSeparator());
1254:
1255: if (minimumFractionDigits > 0 || maximumFractionDigits > 0
1256: || decimalSeparatorAlwaysShown)
1257: mainPattern.append(syms.getDecimalSeparator());
1258: for (int i = 0; i < minimumFractionDigits; ++i)
1259: mainPattern.append(syms.getZeroDigit());
1260: for (int i = minimumFractionDigits; i < maximumFractionDigits; ++i)
1261: mainPattern.append(syms.getDigit());
1262: if (useExponentialNotation)
1263: {
1264: mainPattern.append(syms.getExponential());
1265: for (int i = 0; i < minExponentDigits; ++i)
1266: mainPattern.append(syms.getZeroDigit());
1267: if (minExponentDigits == 0)
1268: mainPattern.append(syms.getDigit());
1269: }
1270:
1271: String main = mainPattern.toString();
1272: String patChars = patternChars (syms);
1273: mainPattern.setLength(0);
1274:
1275: quoteFix (mainPattern, positivePrefix, patChars);
1276: mainPattern.append(main);
1277: quoteFix (mainPattern, positiveSuffix, patChars);
1278:
1279: if (negativePrefix != null)
1280: {
1281: quoteFix (mainPattern, negativePrefix, patChars);
1282: mainPattern.append(main);
1283: quoteFix (mainPattern, negativeSuffix, patChars);
1284: }
1285:
1286: return mainPattern.toString();
1287: }
1288:
1289: public String toLocalizedPattern ()
1290: {
1291: return computePattern (symbols);
1292: }
1293:
1294: public String toPattern ()
1295: {
1296: return computePattern (nonLocalizedSymbols);
1297: }
1298:
1299: private static final int MAXIMUM_INTEGER_DIGITS = 309;
1300:
1301:
1302: private boolean decimalSeparatorAlwaysShown;
1303: private byte groupingSize;
1304: private byte minExponentDigits;
1305: private int exponentRound;
1306: private int multiplier;
1307: private String negativePrefix;
1308: private String negativeSuffix;
1309: private String positivePrefix;
1310: private String positiveSuffix;
1311: private int[] negativePrefixRanges, positivePrefixRanges;
1312: private HashMap[] negativePrefixAttrs, positivePrefixAttrs;
1313: private int[] negativeSuffixRanges, positiveSuffixRanges;
1314: private HashMap[] negativeSuffixAttrs, positiveSuffixAttrs;
1315: private int serialVersionOnStream = 1;
1316: private DecimalFormatSymbols symbols;
1317: private boolean useExponentialNotation;
1318: private static final long serialVersionUID = 864413376551465018L;
1319:
1320: private void readObject(ObjectInputStream stream)
1321: throws IOException, ClassNotFoundException
1322: {
1323: stream.defaultReadObject();
1324: if (serialVersionOnStream < 1)
1325: {
1326: useExponentialNotation = false;
1327: serialVersionOnStream = 1;
1328: }
1329: }
1330:
1331:
1332:
1333: private static final DecimalFormatSymbols nonLocalizedSymbols
1334: = new DecimalFormatSymbols (Locale.US);
1335:
1336:
1362: private String substituteCurrency(String string, double number)
1363: {
1364: int index;
1365: int length;
1366: char currentChar;
1367: StringBuffer buf;
1368:
1369: index = 0;
1370: length = string.length();
1371: buf = new StringBuffer();
1372:
1373: while (index < length)
1374: {
1375: currentChar = string.charAt(index);
1376: if (string.charAt(index) == '\u00a4')
1377: {
1378: if ((index + 1) < length && string.charAt(index + 1) == '\u00a4')
1379: {
1380: buf.append(symbols.getInternationalCurrencySymbol());
1381: index += 2;
1382: }
1383: else
1384: {
1385: String symbol;
1386:
1387: symbol = symbols.getCurrencySymbol();
1388: if (symbol.startsWith("="))
1389: {
1390: String[] bounds;
1391: int[] boundValues;
1392: String[] boundSymbols;
1393:
1394: bounds = symbol.substring(1).split("\\|");
1395: boundValues = new int[3];
1396: boundSymbols = new String[3];
1397: for (int a = 0; a < 3; ++a)
1398: {
1399: String[] bound;
1400:
1401: bound = bounds[a].split("[#<]");
1402: boundValues[a] = Integer.parseInt(bound[0]);
1403: boundSymbols[a] = bound[1];
1404: }
1405: if (number <= boundValues[0])
1406: {
1407: buf.append(boundSymbols[0]);
1408: }
1409: else if (number >= boundValues[2])
1410: {
1411: buf.append(boundSymbols[2]);
1412: }
1413: else
1414: {
1415: buf.append(boundSymbols[1]);
1416: }
1417: ++index;
1418: }
1419: else
1420: {
1421: buf.append(symbol);
1422: ++index;
1423: }
1424: }
1425: }
1426: else
1427: {
1428: buf.append(string.charAt(index));
1429: ++index;
1430: }
1431: }
1432: return buf.toString();
1433: }
1434:
1435: }