use of android.icu.util.Currency in project j2objc by google.
the class NumberFormat method getEffectiveCurrency.
/**
* Returns the currency in effect for this formatter. Subclasses
* should override this method as needed. Unlike getCurrency(),
* this method should never return null.
* @return a non-null Currency
* @deprecated This API is ICU internal only.
* @hide original deprecated declaration
* @hide draft / provisional / internal are hidden on Android
*/
@Deprecated
protected Currency getEffectiveCurrency() {
Currency c = getCurrency();
if (c == null) {
ULocale uloc = getLocale(ULocale.VALID_LOCALE);
if (uloc == null) {
uloc = ULocale.getDefault(Category.FORMAT);
}
c = Currency.getInstance(uloc);
}
return c;
}
use of android.icu.util.Currency in project j2objc by google.
the class NumberFormat method format.
/**
* <strong>[icu]</strong> Formats a CurrencyAmount. Specialization of format.
* @see java.text.Format#format(Object, StringBuffer, FieldPosition)
*/
public StringBuffer format(CurrencyAmount currAmt, StringBuffer toAppendTo, FieldPosition pos) {
// Default implementation -- subclasses may override
synchronized (this) {
Currency save = getCurrency(), curr = currAmt.getCurrency();
boolean same = curr.equals(save);
if (!same)
setCurrency(curr);
format(currAmt.getNumber(), toAppendTo, pos);
if (!same)
setCurrency(save);
}
return toAppendTo;
}
use of android.icu.util.Currency in project j2objc by google.
the class DecimalFormat method applyPatternWithoutExpandAffix.
private void applyPatternWithoutExpandAffix(String pattern, boolean localized) {
// '0'
char zeroDigit = PATTERN_ZERO_DIGIT;
// '@'
char sigDigit = PATTERN_SIGNIFICANT_DIGIT;
char groupingSeparator = PATTERN_GROUPING_SEPARATOR;
char decimalSeparator = PATTERN_DECIMAL_SEPARATOR;
char percent = PATTERN_PERCENT;
char perMill = PATTERN_PER_MILLE;
// '#'
char digit = PATTERN_DIGIT;
char separator = PATTERN_SEPARATOR;
String exponent = String.valueOf(PATTERN_EXPONENT);
char plus = PATTERN_PLUS_SIGN;
char padEscape = PATTERN_PAD_ESCAPE;
// Bug 4212072 [Richard/GCL]
char minus = PATTERN_MINUS_SIGN;
if (localized) {
zeroDigit = symbols.getZeroDigit();
sigDigit = symbols.getSignificantDigit();
groupingSeparator = symbols.getGroupingSeparator();
decimalSeparator = symbols.getDecimalSeparator();
percent = symbols.getPercent();
perMill = symbols.getPerMill();
digit = symbols.getDigit();
separator = symbols.getPatternSeparator();
exponent = symbols.getExponentSeparator();
plus = symbols.getPlusSign();
padEscape = symbols.getPadEscape();
// Bug 4212072 [Richard/GCL]
minus = symbols.getMinusSign();
}
char nineDigit = (char) (zeroDigit + 9);
boolean gotNegative = false;
int pos = 0;
// pattern.
for (int part = 0; part < 2 && pos < pattern.length(); ++part) {
// The subpart ranges from 0 to 4: 0=pattern proper, 1=prefix, 2=suffix,
// 3=prefix in quote, 4=suffix in quote. Subpart 0 is between the prefix and
// suffix, and consists of pattern characters. In the prefix and suffix,
// percent, permille, and currency symbols are recognized and translated.
int subpart = 1, sub0Start = 0, sub0Limit = 0, sub2Limit = 0;
// It's important that we don't change any fields of this object
// prematurely. We set the following variables for the multiplier, grouping,
// etc., and then only change the actual object fields if everything parses
// correctly. This also lets us register the data from part 0 and ignore the
// part 1, except for the prefix and suffix.
StringBuilder prefix = new StringBuilder();
StringBuilder suffix = new StringBuilder();
int decimalPos = -1;
int multpl = 1;
int digitLeftCount = 0, zeroDigitCount = 0, digitRightCount = 0, sigDigitCount = 0;
byte groupingCount = -1;
byte groupingCount2 = -1;
int padPos = -1;
char padChar = 0;
int incrementPos = -1;
long incrementVal = 0;
byte expDigits = -1;
boolean expSignAlways = false;
int currencySignCnt = 0;
// The affix is either the prefix or the suffix.
StringBuilder affix = prefix;
int start = pos;
PARTLOOP: for (; pos < pattern.length(); ++pos) {
char ch = pattern.charAt(pos);
switch(subpart) {
case // Pattern proper subpart (between prefix & suffix)
0:
// decimal point, then there should be no right digits.
if (ch == digit) {
if (zeroDigitCount > 0 || sigDigitCount > 0) {
++digitRightCount;
} else {
++digitLeftCount;
}
if (groupingCount >= 0 && decimalPos < 0) {
++groupingCount;
}
} else if ((ch >= zeroDigit && ch <= nineDigit) || ch == sigDigit) {
if (digitRightCount > 0) {
patternError("Unexpected '" + ch + '\'', pattern);
}
if (ch == sigDigit) {
++sigDigitCount;
} else {
++zeroDigitCount;
if (ch != zeroDigit) {
int p = digitLeftCount + zeroDigitCount + digitRightCount;
if (incrementPos >= 0) {
while (incrementPos < p) {
incrementVal *= 10;
++incrementPos;
}
} else {
incrementPos = p;
}
incrementVal += ch - zeroDigit;
}
}
if (groupingCount >= 0 && decimalPos < 0) {
++groupingCount;
}
} else if (ch == groupingSeparator) {
// == QUOTE) [Richard/GCL]
if (ch == QUOTE && (pos + 1) < pattern.length()) {
char after = pattern.charAt(pos + 1);
if (!(after == digit || (after >= zeroDigit && after <= nineDigit))) {
// we have the first quote in 'do' or o''clock.
if (after == QUOTE) {
++pos;
// Fall through to append(ch)
} else {
if (groupingCount < 0) {
// quoted prefix subpart
subpart = 3;
} else {
// Transition to suffix subpart
// suffix subpart
subpart = 2;
affix = suffix;
sub0Limit = pos--;
}
continue;
}
}
}
if (decimalPos >= 0) {
patternError("Grouping separator after decimal", pattern);
}
groupingCount2 = groupingCount;
groupingCount = 0;
} else if (ch == decimalSeparator) {
if (decimalPos >= 0) {
patternError("Multiple decimal separators", pattern);
}
// Intentionally incorporate the digitRightCount, even though it
// is illegal for this to be > 0 at this point. We check pattern
// syntax below.
decimalPos = digitLeftCount + zeroDigitCount + digitRightCount;
} else {
if (pattern.regionMatches(pos, exponent, 0, exponent.length())) {
if (expDigits >= 0) {
patternError("Multiple exponential symbols", pattern);
}
if (groupingCount >= 0) {
patternError("Grouping separator in exponential", pattern);
}
pos += exponent.length();
// Check for positive prefix
if (pos < pattern.length() && pattern.charAt(pos) == plus) {
expSignAlways = true;
++pos;
}
// Use lookahead to parse out the exponential part of the
// pattern, then jump into suffix subpart.
expDigits = 0;
while (pos < pattern.length() && pattern.charAt(pos) == zeroDigit) {
++expDigits;
++pos;
}
// 3. Require at least one exponent pattern digit
if (((digitLeftCount + zeroDigitCount) < 1 && (sigDigitCount + digitRightCount) < 1) || (sigDigitCount > 0 && digitLeftCount > 0) || expDigits < 1) {
patternError("Malformed exponential", pattern);
}
}
// Transition to suffix subpart
// suffix subpart
subpart = 2;
affix = suffix;
// backup: for() will increment
sub0Limit = pos--;
continue;
}
break;
// Prefix subpart
case 1:
case // Suffix subpart
2:
// are in the prefix; otherwise they are illegal if unquoted.
if (ch == digit || ch == groupingSeparator || ch == decimalSeparator || (ch >= zeroDigit && ch <= nineDigit) || ch == sigDigit) {
// next subpart if we are in the prefix
if (subpart == 1) {
// prefix subpart
// pattern proper subpart
subpart = 0;
// Reprocess this character
sub0Start = pos--;
continue;
} else if (ch == QUOTE) {
// the first quote in 'do' or o''clock.
if ((pos + 1) < pattern.length() && pattern.charAt(pos + 1) == QUOTE) {
++pos;
affix.append(ch);
} else {
// open quote
subpart += 2;
}
continue;
}
patternError("Unquoted special character '" + ch + '\'', pattern);
} else if (ch == CURRENCY_SIGN) {
// Use lookahead to determine if the currency sign is
// doubled or not.
boolean doubled = (pos + 1) < pattern.length() && pattern.charAt(pos + 1) == CURRENCY_SIGN;
// StirngBuffer) [Richard/GCL]
if (doubled) {
// Skip over the doubled character
++pos;
// append two: one here, one below
affix.append(ch);
if ((pos + 1) < pattern.length() && pattern.charAt(pos + 1) == CURRENCY_SIGN) {
// Skip over the tripled character
++pos;
// append again
affix.append(ch);
currencySignCnt = CURRENCY_SIGN_COUNT_IN_PLURAL_FORMAT;
} else {
currencySignCnt = CURRENCY_SIGN_COUNT_IN_ISO_FORMAT;
}
} else {
currencySignCnt = CURRENCY_SIGN_COUNT_IN_SYMBOL_FORMAT;
}
// Fall through to append(ch)
} else if (ch == QUOTE) {
// first quote in 'do' or o''clock.
if ((pos + 1) < pattern.length() && pattern.charAt(pos + 1) == QUOTE) {
++pos;
// append two: one here, one below
affix.append(ch);
} else {
// open quote
subpart += 2;
}
// Fall through to append(ch)
} else if (ch == separator) {
// separators in the second pattern (part == 1).
if (subpart == 1 || part == 1) {
patternError("Unquoted special character '" + ch + '\'', pattern);
}
sub2Limit = pos++;
// Go to next part
break PARTLOOP;
} else if (ch == percent || ch == perMill) {
// Next handle characters which are appended directly.
if (multpl != 1) {
patternError("Too many percent/permille characters", pattern);
}
multpl = (ch == percent) ? 100 : 1000;
// Convert to non-localized pattern
ch = (ch == percent) ? PATTERN_PERCENT : PATTERN_PER_MILLE;
// Fall through to append(ch)
} else if (ch == minus) {
// Convert to non-localized pattern
ch = PATTERN_MINUS_SIGN;
// Fall through to append(ch)
} else if (ch == padEscape) {
if (padPos >= 0) {
patternError("Multiple pad specifiers", pattern);
}
if ((pos + 1) == pattern.length()) {
patternError("Invalid pad specifier", pattern);
}
// Advance past pad char
padPos = pos++;
padChar = pattern.charAt(pos);
continue;
}
affix.append(ch);
break;
// Prefix subpart, in quote
case 3:
case // Suffix subpart, in quote
4:
// in 'do' or 'don''t'.
if (ch == QUOTE) {
if ((pos + 1) < pattern.length() && pattern.charAt(pos + 1) == QUOTE) {
++pos;
affix.append(ch);
} else {
// close quote
subpart -= 2;
}
// Fall through to append(ch)
}
// NOTE: In ICU 2.2 there was code here to parse quoted percent and
// permille characters _within quotes_ and give them special
// meaning. This is incorrect, since quoted characters are literals
// without special meaning.
affix.append(ch);
break;
}
}
if (subpart == 3 || subpart == 4) {
patternError("Unterminated quote", pattern);
}
if (sub0Limit == 0) {
sub0Limit = pattern.length();
}
if (sub2Limit == 0) {
sub2Limit = pattern.length();
}
// though that's what it really is, semantically).
if (zeroDigitCount == 0 && sigDigitCount == 0 && digitLeftCount > 0 && decimalPos >= 0) {
// Handle "###.###" and "###." and ".###"
int n = decimalPos;
if (n == 0)
// Handle ".###"
++n;
digitRightCount = digitLeftCount - n;
digitLeftCount = n - 1;
zeroDigitCount = 1;
}
// Do syntax checking on the digits, decimal points, and quotes.
if ((decimalPos < 0 && digitRightCount > 0 && sigDigitCount == 0) || (decimalPos >= 0 && (sigDigitCount > 0 || decimalPos < digitLeftCount || decimalPos > (digitLeftCount + zeroDigitCount))) || groupingCount == 0 || groupingCount2 == 0 || (sigDigitCount > 0 && zeroDigitCount > 0) || subpart > 2) {
// subpart > 2 == unmatched quote
patternError("Malformed pattern", pattern);
}
// Make sure pad is at legal position before or after affix.
if (padPos >= 0) {
if (padPos == start) {
padPos = PAD_BEFORE_PREFIX;
} else if (padPos + 2 == sub0Start) {
padPos = PAD_AFTER_PREFIX;
} else if (padPos == sub0Limit) {
padPos = PAD_BEFORE_SUFFIX;
} else if (padPos + 2 == sub2Limit) {
padPos = PAD_AFTER_SUFFIX;
} else {
patternError("Illegal pad position", pattern);
}
}
if (part == 0) {
// Set negative affixes temporarily to match the positive
// affixes. Fix this up later after processing both parts.
// Bug 4212072 To meet the need of expandAffix(String, StirngBuffer)
// [Richard/GCL]
posPrefixPattern = negPrefixPattern = prefix.toString();
posSuffixPattern = negSuffixPattern = suffix.toString();
useExponentialNotation = (expDigits >= 0);
if (useExponentialNotation) {
minExponentDigits = expDigits;
exponentSignAlwaysShown = expSignAlways;
}
int digitTotalCount = digitLeftCount + zeroDigitCount + digitRightCount;
// The effectiveDecimalPos is the position the decimal is at or would be
// at if there is no decimal. Note that if decimalPos<0, then
// digitTotalCount == digitLeftCount + zeroDigitCount.
int effectiveDecimalPos = decimalPos >= 0 ? decimalPos : digitTotalCount;
boolean useSigDig = (sigDigitCount > 0);
setSignificantDigitsUsed(useSigDig);
if (useSigDig) {
setMinimumSignificantDigits(sigDigitCount);
setMaximumSignificantDigits(sigDigitCount + digitRightCount);
} else {
int minInt = effectiveDecimalPos - digitLeftCount;
setMinimumIntegerDigits(minInt);
// Upper limit on integer and fraction digits for a Java double
// [Richard/GCL]
setMaximumIntegerDigits(useExponentialNotation ? digitLeftCount + minInt : DOUBLE_INTEGER_DIGITS);
_setMaximumFractionDigits(decimalPos >= 0 ? (digitTotalCount - decimalPos) : 0);
setMinimumFractionDigits(decimalPos >= 0 ? (digitLeftCount + zeroDigitCount - decimalPos) : 0);
}
setGroupingUsed(groupingCount > 0);
this.groupingSize = (groupingCount > 0) ? groupingCount : 0;
this.groupingSize2 = (groupingCount2 > 0 && groupingCount2 != groupingCount) ? groupingCount2 : 0;
this.multiplier = multpl;
setDecimalSeparatorAlwaysShown(decimalPos == 0 || decimalPos == digitTotalCount);
if (padPos >= 0) {
padPosition = padPos;
// to be fixed up below
formatWidth = sub0Limit - sub0Start;
pad = padChar;
} else {
formatWidth = 0;
}
if (incrementVal != 0) {
// BigDecimal scale cannot be negative (even though this makes perfect
// sense), so we need to handle this.
int scale = incrementPos - effectiveDecimalPos;
roundingIncrementICU = BigDecimal.valueOf(incrementVal, scale > 0 ? scale : 0);
if (scale < 0) {
roundingIncrementICU = roundingIncrementICU.movePointRight(-scale);
}
roundingMode = BigDecimal.ROUND_HALF_EVEN;
} else {
setRoundingIncrement((BigDecimal) null);
}
// Update currency sign count for the new pattern
currencySignCount = currencySignCnt;
} else {
// Bug 4212072 To meet the need of expandAffix(String, StirngBuffer)
// [Richard/GCL]
negPrefixPattern = prefix.toString();
negSuffixPattern = suffix.toString();
gotNegative = true;
}
}
// Bug 4140009 Process the empty pattern [Richard/GCL]
if (pattern.length() == 0) {
posPrefixPattern = posSuffixPattern = "";
setMinimumIntegerDigits(0);
setMaximumIntegerDigits(DOUBLE_INTEGER_DIGITS);
setMinimumFractionDigits(0);
_setMaximumFractionDigits(DOUBLE_FRACTION_DIGITS);
}
if (!gotNegative || (negPrefixPattern.equals(posPrefixPattern) && negSuffixPattern.equals(posSuffixPattern))) {
negSuffixPattern = posSuffixPattern;
negPrefixPattern = PATTERN_MINUS_SIGN + posPrefixPattern;
}
setLocale(null, null);
// save the pattern
formatPattern = pattern;
// special handlings for currency instance
if (currencySignCount != CURRENCY_SIGN_COUNT_ZERO) {
// reset rounding increment and max/min fractional digits
// by the currency
Currency theCurrency = getCurrency();
if (theCurrency != null) {
setRoundingIncrement(theCurrency.getRoundingIncrement(currencyUsage));
int d = theCurrency.getDefaultFractionDigits(currencyUsage);
setMinimumFractionDigits(d);
_setMaximumFractionDigits(d);
}
// initialize currencyPluralInfo if needed
if (currencySignCount == CURRENCY_SIGN_COUNT_IN_PLURAL_FORMAT && currencyPluralInfo == null) {
currencyPluralInfo = new CurrencyPluralInfo(symbols.getULocale());
}
}
resetActualRounding();
}
use of android.icu.util.Currency in project j2objc by google.
the class CompactDecimalFormat method format.
/* INTERNALS */
private StringBuffer format(double number, Currency curr, StringBuffer toAppendTo, FieldPosition pos) {
if (curr != null && style == CompactStyle.LONG) {
throw new UnsupportedOperationException("CompactDecimalFormat does not support LONG style for currency.");
}
// Compute the scaled amount, prefix, and suffix appropriate for the number's magnitude.
Output<Unit> currencyUnit = new Output<Unit>();
Amount amount = toAmount(number, curr, currencyUnit);
Unit unit = amount.getUnit();
// Note that currencyUnit is a remnant. In almost all cases, it will be null.
StringBuffer prefix = new StringBuffer();
StringBuffer suffix = new StringBuffer();
if (currencyUnit.value != null) {
currencyUnit.value.writePrefix(prefix);
}
unit.writePrefix(prefix);
unit.writeSuffix(suffix);
if (currencyUnit.value != null) {
currencyUnit.value.writeSuffix(suffix);
}
if (curr == null) {
// Prevent locking when not formatting a currency number.
toAppendTo.append(escape(prefix.toString()));
super.format(amount.getQty(), toAppendTo, pos);
toAppendTo.append(escape(suffix.toString()));
} else {
// This has to be synchronized since this information is held in the state of the DecimalFormat object.
synchronized (this) {
String originalPattern = this.toPattern();
Currency originalCurrency = this.getCurrency();
StringBuffer newPattern = new StringBuffer();
// Write prefixes and suffixes to the pattern. Note that we have to apply it to both halves of a
// positive/negative format (separated by ';')
int semicolonPos = originalPattern.indexOf(';');
newPattern.append(prefix);
if (semicolonPos != -1) {
newPattern.append(originalPattern, 0, semicolonPos);
newPattern.append(suffix);
newPattern.append(';');
newPattern.append(prefix);
}
newPattern.append(originalPattern, semicolonPos + 1, originalPattern.length());
newPattern.append(suffix);
// Overwrite the pattern and currency.
setCurrency(curr);
applyPattern(newPattern.toString());
// Actually perform the formatting.
super.format(amount.getQty(), toAppendTo, pos);
// Reset the pattern and currency.
setCurrency(originalCurrency);
applyPattern(originalPattern);
}
}
return toAppendTo;
}
use of android.icu.util.Currency in project j2objc by google.
the class NumberFormatTest method Test6816.
@Test
public void Test6816() {
Currency cur1 = Currency.getInstance(new Locale("und", "PH"));
NumberFormat nfmt = NumberFormat.getCurrencyInstance(new Locale("und", "PH"));
DecimalFormatSymbols decsym = ((DecimalFormat) nfmt).getDecimalFormatSymbols();
Currency cur2 = decsym.getCurrency();
if (!cur1.getCurrencyCode().equals("PHP") || !cur2.getCurrencyCode().equals("PHP")) {
errln("FAIL: Currencies should match PHP: cur1 = " + cur1.getCurrencyCode() + "; cur2 = " + cur2.getCurrencyCode());
}
}
Aggregations