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

Unified Diff: chrome/android/java/src/org/chromium/chrome/browser/payments/CurrencyStringFormatter.java

Issue 2629883004: [Payment Request] Update the CurrencyStringFormatter to call the native impl. (Closed)
Patch Set: Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/android/java/src/org/chromium/chrome/browser/payments/CurrencyStringFormatter.java
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/CurrencyStringFormatter.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/CurrencyStringFormatter.java
index 693bc0344b742c9794ad17fe36721f4bc8b314cb..4264224b4db573fdc749d57a4f3d06adc1c1e0a3 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/payments/CurrencyStringFormatter.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/CurrencyStringFormatter.java
@@ -4,22 +4,19 @@
package org.chromium.chrome.browser.payments;
-import java.text.DecimalFormatSymbols;
-import java.util.Currency;
+import org.chromium.base.annotations.JNINamespace;
+
import java.util.Locale;
-import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
- * Formatter for currency strings that can be too large to parse into numbers.
+ * Formatter for currency amounts.
* https://w3c.github.io/browser-payment-api/specs/paymentrequest.html#currencyamount
*/
+@JNINamespace("payments")
public class CurrencyStringFormatter {
- // Amount value pattern and capture group numbers.
+ // Amount value pattern.
private static final String AMOUNT_VALUE_PATTERN = "^(-?)([0-9]+)(\\.([0-9]+))?$";
- private static final int OPTIONAL_NEGATIVE_GROUP = 1;
- private static final int DIGITS_BETWEEN_NEGATIVE_AND_PERIOD_GROUP = 2;
- private static final int DIGITS_AFTER_PERIOD_GROUP = 4;
// Max currency code length. Maximum length of currency code can be at most 2048.
private static final int MAX_CURRENCY_CODE_LEN = 2048;
@@ -30,11 +27,6 @@ public class CurrencyStringFormatter {
// Unicode character for ellipsis.
private static final String ELLIPSIS = "\u2026";
- // Formatting constants.
- private static final int DIGIT_GROUPING_SIZE = 3;
-
- private final Pattern mAmountValuePattern;
-
/**
* The currency formatted for display. Currency can be any string of at most
* 2048 characters.Currency code more than 6 character is formatted to first
@@ -43,79 +35,35 @@ public class CurrencyStringFormatter {
public final String mFormattedCurrencyCode;
/**
- * The symbol for the currency specified on the bill. For example, the symbol for "USD" is "$".
- */
- private final String mCurrencySymbol;
-
- /**
- * The number of digits after the decimal separator for the currency specified on the bill. For
- * example, 2 for "USD" and 0 for "JPY".
- */
- private final int mDefaultFractionDigits;
-
- /**
- * The number grouping separator for the current locale. For example, "," in US. 3-digit groups
- * are assumed.
+ * Pointer to the native implementation.
*/
- private final char mGroupingSeparator;
+ private final long mCurrencyFormatterAndroid;
- /**
- * The monetary decimal separator for the current locale. For example, "." in US and "," in
- * France.
- */
- private final char mMonetaryDecimalSeparator;
+ private final Pattern mAmountValuePattern;
please use gerrit instead 2017/01/13 21:16:25 No longer used in this file, so can be deleted.
Mathieu 2017/01/13 22:27:01 Done.
/**
* Builds the formatter for the given currency code and the current user locale.
*
- * @param currencyCode The currency code. Most commonly, this follows ISO 4217 format: 3 upper
- * case ASCII letters. For example, "USD". Format is not restricted. Should
- * not be null.
+ * @param currencyCode The currency code. Most commonly, this follows ISO 4217 format: 3 upper
+ * case ASCII letters. For example, "USD". Format is not restricted. Should
+ * not be null.
+ * @param currencySystem URI specifying the ISO4217 currency code specification. See for
+ * details: https://w3c.github.io/browser-payment-api/#paymentcurrencyamount-dictionary
+ * Can be null, in which case "urn:iso:std:iso:4217" is assumed.
* @param userLocale User's current locale. Should not be null.
*/
- public CurrencyStringFormatter(String currencyCode, Locale userLocale) {
+ public CurrencyStringFormatter(String currencyCode, String currencySystem, Locale userLocale) {
please use gerrit instead 2017/01/13 21:16:24 @Nullable String currencySystem.
Mathieu 2017/01/13 22:27:01 Done.
assert currencyCode != null : "currencyCode should not be null";
assert userLocale != null : "userLocale should not be null";
- mAmountValuePattern = Pattern.compile(AMOUNT_VALUE_PATTERN);
+ // Note that this technically leaks the native object.
please use gerrit instead 2017/01/13 21:16:25 Is there a remedy for the leak?
Mathieu 2017/01/13 22:27:01 added destroy() (Calling nativeDestroy() which cal
+ mCurrencyFormatterAndroid = nativeInitCurrencyFormatterAndroid(
+ currencyCode, currencySystem == null ? "" : currencySystem, userLocale.toString());
+ mAmountValuePattern = Pattern.compile(AMOUNT_VALUE_PATTERN);
mFormattedCurrencyCode = currencyCode.length() <= MAX_CURRENCY_CHARS
please use gerrit instead 2017/01/13 21:16:25 Can we similarly format the currency code in C++?
Mathieu 2017/01/13 22:27:01 Sure thing, done
? currencyCode
: currencyCode.substring(0, MAX_CURRENCY_CHARS - 1) + ELLIPSIS;
-
- String currencySymbol;
- int defaultFractionDigits;
- try {
- Currency currency = Currency.getInstance(currencyCode);
- currencySymbol = currency.getSymbol();
- defaultFractionDigits = currency.getDefaultFractionDigits();
- } catch (IllegalArgumentException e) {
- // The spec does not limit the currencies to official ISO 4217 currency code list, which
- // is used by java.util.Currency. For example, "BTX" (bitcoin) is not an official ISO
- // 4217 currency code, but is allowed by the spec.
- currencySymbol = "";
- defaultFractionDigits = 0;
- }
-
- // If the prefix of the currency symbol matches the prefix of the currency code, remove the
- // matching prefix from the symbol. The UI already shows the currency code, so there's no
- // need to show duplicate information.
- String symbol = "";
- for (int i = 0; i < currencySymbol.length(); i++) {
- if (i >= currencyCode.length() || currencySymbol.charAt(i) != currencyCode.charAt(i)) {
- symbol = currencySymbol.substring(i);
- break;
- }
- }
- mCurrencySymbol = symbol;
-
- mDefaultFractionDigits = defaultFractionDigits;
-
- // Use the symbols from user's current locale. For example, use "," for decimal separator in
- // France, even if paying in "USD".
- DecimalFormatSymbols symbols = new DecimalFormatSymbols(userLocale);
- mGroupingSeparator = symbols.getGroupingSeparator();
- mMonetaryDecimalSeparator = symbols.getMonetaryDecimalSeparator();
}
/**
@@ -145,44 +93,22 @@ public class CurrencyStringFormatter {
/**
* Formats the currency string for display. Does not parse the string into a number, because it
- * might be too large. The number is formatted for the current locale and follows the symbol of
- * the currency code.
+ * might be too large. The number is formatted for the current locale and can include a
+ * currency symbol (e.g. $) anywhere in the string, but will not contain the currency code
+ * (e.g. USD/US). All spaces in the currency are unicode non-breaking space.
*
* @param amountValue The number to format. Should be in "^-?[0-9]+(\.[0-9]+)?$" format. Should
* not be null.
- * @return The currency symbol followed by a space and the formatted number.
+ * @return The amount formatted with the specified currency. See description for details.
*/
public String format(String amountValue) {
assert amountValue != null : "amountValue should not be null";
- Matcher m = mAmountValuePattern.matcher(amountValue);
-
- // Required to capture the groups.
- boolean matches = m.matches();
- assert matches;
-
- StringBuilder result = new StringBuilder(m.group(OPTIONAL_NEGATIVE_GROUP));
- result.append(mCurrencySymbol);
- int digitStart = result.length();
-
- result.append(m.group(DIGITS_BETWEEN_NEGATIVE_AND_PERIOD_GROUP));
- for (int i = result.length() - DIGIT_GROUPING_SIZE; i > digitStart;
- i -= DIGIT_GROUPING_SIZE) {
- result.insert(i, mGroupingSeparator);
- }
-
- String decimals = m.group(DIGITS_AFTER_PERIOD_GROUP);
- int numberOfDecimals = decimals == null ? 0 : decimals.length();
-
- if (numberOfDecimals > 0 || mDefaultFractionDigits > 0) {
- result.append(mMonetaryDecimalSeparator);
- if (null != decimals) result.append(decimals);
-
- for (int i = numberOfDecimals; i < mDefaultFractionDigits; i++) {
- result.append("0");
- }
- }
-
- return result.toString();
+ return nativeFormat(mCurrencyFormatterAndroid, amountValue);
}
+
+ private native long nativeInitCurrencyFormatterAndroid(
+ String currencyCode, String currencySystem, String localeName);
+ private native String nativeFormat(
+ long nativeCurrencyFormatterAndroid, String amountValue);
}

Powered by Google App Engine
This is Rietveld 408576698