summaryrefslogtreecommitdiffstats
path: root/icu/src/main
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-02-13 12:57:48 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-02-13 12:57:48 -0800
commit9cb89d78930c6ff1f18ab5e3eea393a47e9fff4d (patch)
treee03c4748ec34c1ace469c8f00ef6ee403aeb4966 /icu/src/main
parentb7926325a1c1a370c84c81db80372f59af240a53 (diff)
downloadlibcore-9cb89d78930c6ff1f18ab5e3eea393a47e9fff4d.zip
libcore-9cb89d78930c6ff1f18ab5e3eea393a47e9fff4d.tar.gz
libcore-9cb89d78930c6ff1f18ab5e3eea393a47e9fff4d.tar.bz2
auto import from //branches/cupcake/...@131421
Diffstat (limited to 'icu/src/main')
-rw-r--r--icu/src/main/java/com/ibm/icu4jni/text/DecimalFormat.java127
-rw-r--r--icu/src/main/native/DecimalFormatInterface.cpp84
2 files changed, 121 insertions, 90 deletions
diff --git a/icu/src/main/java/com/ibm/icu4jni/text/DecimalFormat.java b/icu/src/main/java/com/ibm/icu4jni/text/DecimalFormat.java
index ddd4062..5bee1fd 100644
--- a/icu/src/main/java/com/ibm/icu4jni/text/DecimalFormat.java
+++ b/icu/src/main/java/com/ibm/icu4jni/text/DecimalFormat.java
@@ -31,12 +31,12 @@ import java.util.Currency;
import java.util.Locale;
public class DecimalFormat extends NumberFormat {
-
+
private int addr;
-
+
private DecimalFormatSymbols symbols;
-
- // fix to be icu4j conform (harmony wants this field to exist)
+
+ // fix to be icu4j conform (harmony wants this field to exist)
// for serialization of java.text.DecimalFormat
@SuppressWarnings("unused")
private boolean useExponentialNotation = false;
@@ -47,7 +47,7 @@ public class DecimalFormat extends NumberFormat {
private boolean negSuffNull;
private boolean posPrefNull;
private boolean posSuffNull;
-
+
public DecimalFormat(String pattern, DecimalFormatSymbols icuSymbols) {
this.addr = icuSymbols.getAddr();
this.symbols = icuSymbols;
@@ -58,7 +58,7 @@ public class DecimalFormat extends NumberFormat {
public int hashCode() {
return super.hashCode() * 37 + this.getPositivePrefix().hashCode();
}
-
+
@Override
public Object clone() {
String pat = this.toPattern();
@@ -73,7 +73,7 @@ public class DecimalFormat extends NumberFormat {
newdf.setGroupingSize(this.getGroupingSize());
return newdf;
}
-
+
@Override
public boolean equals(Object object) {
if (object == this) {
@@ -87,10 +87,10 @@ public class DecimalFormat extends NumberFormat {
if(obj.addr == this.addr) {
return true;
}
-
+
boolean result = super.equals(object);
-
+
result &= obj.toPattern().equals(this.toPattern());
result &= obj.isDecimalSeparatorAlwaysShown() == this.isDecimalSeparatorAlwaysShown();
result &= obj.getGroupingSize() == this.getGroupingSize();
@@ -114,34 +114,37 @@ public class DecimalFormat extends NumberFormat {
result &= thisCurr == null;
}
result &= obj.getDecimalFormatSymbols().equals(this.getDecimalFormatSymbols());
-
+
return result;
}
@Override
public StringBuffer format(Object value, StringBuffer buffer, FieldPosition field) {
-
+
if(!(value instanceof Number)) {
throw new IllegalArgumentException();
}
if(buffer == null || field == null) {
throw new NullPointerException();
}
-
+
String fieldType = getFieldType(field.getFieldAttribute());
-
+
Number number = (Number) value;
-
+
if(number instanceof BigInteger) {
BigInteger valBigInteger = (BigInteger) number;
- String result = NativeDecimalFormat.format(this.addr,
+ String result = NativeDecimalFormat.format(this.addr,
valBigInteger.toString(10), field, fieldType, null, 0);
return buffer.append(result);
} else if(number instanceof BigDecimal) {
BigDecimal valBigDecimal = (BigDecimal) number;
- String result = NativeDecimalFormat.format(this.addr,
- valBigDecimal.unscaledValue().toString(10), field,
- fieldType, null, valBigDecimal.scale());
+ StringBuilder val = new StringBuilder();
+ val.append(valBigDecimal.unscaledValue().toString(10));
+ int scale = valBigDecimal.scale();
+ scale = makeScalePositive(scale, val);
+ String result = NativeDecimalFormat.format(this.addr,
+ val.toString(), field, fieldType, null, scale);
return buffer.append(result);
} else {
double dv = number.doubleValue();
@@ -151,7 +154,7 @@ public class DecimalFormat extends NumberFormat {
fieldType, null);
return buffer.append(result);
}
- String result = NativeDecimalFormat.format(this.addr, dv, field,
+ String result = NativeDecimalFormat.format(this.addr, dv, field,
fieldType, null);
return buffer.append(result);
}
@@ -163,14 +166,14 @@ public class DecimalFormat extends NumberFormat {
if(buffer == null || field == null) {
throw new NullPointerException();
}
-
+
String fieldType = getFieldType(field.getFieldAttribute());
-
- String result = NativeDecimalFormat.format(this.addr, value, field,
+
+ String result = NativeDecimalFormat.format(this.addr, value, field,
fieldType, null);
-
+
buffer.append(result.toCharArray(), 0, result.length());
-
+
return buffer;
}
@@ -180,14 +183,14 @@ public class DecimalFormat extends NumberFormat {
if(buffer == null || field == null) {
throw new NullPointerException();
}
-
+
String fieldType = getFieldType(field.getFieldAttribute());
-
- String result = NativeDecimalFormat.format(this.addr, value, field,
+
+ String result = NativeDecimalFormat.format(this.addr, value, field,
fieldType, null);
-
+
buffer.append(result.toCharArray(), 0, result.length());
-
+
return buffer;
}
@@ -223,16 +226,19 @@ public class DecimalFormat extends NumberFormat {
Number number = (Number) object;
String text = null;
StringBuffer attributes = new StringBuffer();
-
+
if(number instanceof BigInteger) {
BigInteger valBigInteger = (BigInteger) number;
- text = NativeDecimalFormat.format(this.addr,
+ text = NativeDecimalFormat.format(this.addr,
valBigInteger.toString(10), null, null, attributes, 0);
} else if(number instanceof BigDecimal) {
BigDecimal valBigDecimal = (BigDecimal) number;
- text = NativeDecimalFormat.format(this.addr,
- valBigDecimal.unscaledValue().toString(10), null,null,
- attributes, valBigDecimal.scale());
+ StringBuilder val = new StringBuilder();
+ val.append(valBigDecimal.unscaledValue().toString(10));
+ int scale = valBigDecimal.scale();
+ scale = makeScalePositive(scale, val);
+ text = NativeDecimalFormat.format(this.addr, val.toString(), null,
+ null, attributes, scale);
} else {
double dv = number.doubleValue();
long lv = number.longValue();
@@ -240,11 +246,11 @@ public class DecimalFormat extends NumberFormat {
text = NativeDecimalFormat.format(this.addr, lv, null,
null, attributes);
} else {
- text = NativeDecimalFormat.format(this.addr, dv, null,
+ text = NativeDecimalFormat.format(this.addr, dv, null,
null, attributes);
}
}
-
+
AttributedString as = new AttributedString(text.toString());
String[] attrs = attributes.toString().split(";");
@@ -258,11 +264,22 @@ public class DecimalFormat extends NumberFormat {
as.addAttribute(attribute, attribute, Integer.parseInt(attrs[3*i+1]),
Integer.parseInt(attrs[3*i+2]));
}
-
+
// return the CharacterIterator from AttributedString
return as.getIterator();
}
+ private int makeScalePositive(int scale, StringBuilder val) {
+ if (scale < 0) {
+ scale = -scale;
+ for (int i = scale; i > 0; i--) {
+ val.append('0');
+ }
+ scale = 0;
+ }
+ return scale;
+ }
+
public String toLocalizedPattern() {
return NativeDecimalFormat.toPatternImpl(this.addr, true);
}
@@ -275,30 +292,30 @@ public class DecimalFormat extends NumberFormat {
public Number parse(String string, ParsePosition position) {
return NativeDecimalFormat.parse(addr, string, position);
}
-
+
// start getter and setter
@Override
public int getMaximumFractionDigits() {
- return NativeDecimalFormat.getAttribute(this .addr,
+ return NativeDecimalFormat.getAttribute(this .addr,
UNumberFormatAttribute.UNUM_MAX_FRACTION_DIGITS.ordinal());
}
@Override
public int getMaximumIntegerDigits() {
- return NativeDecimalFormat.getAttribute(this .addr,
+ return NativeDecimalFormat.getAttribute(this .addr,
UNumberFormatAttribute.UNUM_MAX_INTEGER_DIGITS.ordinal());
}
@Override
public int getMinimumFractionDigits() {
- return NativeDecimalFormat.getAttribute(this .addr,
+ return NativeDecimalFormat.getAttribute(this .addr,
UNumberFormatAttribute.UNUM_MIN_FRACTION_DIGITS.ordinal());
}
@Override
public int getMinimumIntegerDigits() {
- return NativeDecimalFormat.getAttribute(this .addr,
+ return NativeDecimalFormat.getAttribute(this .addr,
UNumberFormatAttribute.UNUM_MIN_INTEGER_DIGITS.ordinal());
}
@@ -308,12 +325,12 @@ public class DecimalFormat extends NumberFormat {
}
public int getGroupingSize() {
- return NativeDecimalFormat.getAttribute(this.addr,
+ return NativeDecimalFormat.getAttribute(this.addr,
UNumberFormatAttribute.UNUM_GROUPING_SIZE.ordinal());
}
public int getMultiplier() {
- return NativeDecimalFormat.getAttribute(this.addr,
+ return NativeDecimalFormat.getAttribute(this.addr,
UNumberFormatAttribute.UNUM_MULTIPLIER.ordinal());
}
@@ -321,7 +338,7 @@ public class DecimalFormat extends NumberFormat {
if (negPrefNull) {
return null;
}
- return NativeDecimalFormat.getTextAttribute(this.addr,
+ return NativeDecimalFormat.getTextAttribute(this.addr,
UNumberFormatTextAttribute.UNUM_NEGATIVE_PREFIX.ordinal());
}
@@ -329,7 +346,7 @@ public class DecimalFormat extends NumberFormat {
if (negSuffNull) {
return null;
}
- return NativeDecimalFormat.getTextAttribute(this.addr,
+ return NativeDecimalFormat.getTextAttribute(this.addr,
UNumberFormatTextAttribute.UNUM_NEGATIVE_SUFFIX.ordinal());
}
@@ -337,7 +354,7 @@ public class DecimalFormat extends NumberFormat {
if (posPrefNull) {
return null;
}
- return NativeDecimalFormat.getTextAttribute(this.addr,
+ return NativeDecimalFormat.getTextAttribute(this.addr,
UNumberFormatTextAttribute.UNUM_POSITIVE_PREFIX.ordinal());
}
@@ -345,24 +362,24 @@ public class DecimalFormat extends NumberFormat {
if (posSuffNull) {
return null;
}
- return NativeDecimalFormat.getTextAttribute(this.addr,
+ return NativeDecimalFormat.getTextAttribute(this.addr,
UNumberFormatTextAttribute.UNUM_POSITIVE_SUFFIX.ordinal());
}
public boolean isDecimalSeparatorAlwaysShown() {
- return NativeDecimalFormat.getAttribute(this.addr,
+ return NativeDecimalFormat.getAttribute(this.addr,
UNumberFormatAttribute.UNUM_DECIMAL_ALWAYS_SHOWN.ordinal()) != 0;
}
@Override
public boolean isParseIntegerOnly() {
- return NativeDecimalFormat.getAttribute(this.addr,
+ return NativeDecimalFormat.getAttribute(this.addr,
UNumberFormatAttribute.UNUM_PARSE_INT_ONLY.ordinal()) != 0;
}
@Override
public boolean isGroupingUsed() {
- return NativeDecimalFormat.getAttribute(this.addr,
+ return NativeDecimalFormat.getAttribute(this.addr,
UNumberFormatAttribute.UNUM_GROUPING_USED.ordinal()) != 0;
}
@@ -376,7 +393,7 @@ public class DecimalFormat extends NumberFormat {
public void setDecimalSeparatorAlwaysShown(boolean value) {
int i = value ? -1 : 0;
- NativeDecimalFormat.setAttribute(this.addr,
+ NativeDecimalFormat.setAttribute(this.addr,
UNumberFormatAttribute.UNUM_DECIMAL_ALWAYS_SHOWN.ordinal(), i);
}
@@ -465,10 +482,10 @@ public class DecimalFormat extends NumberFormat {
@Override
public void setParseIntegerOnly(boolean value) {
int i = value ? -1 : 0;
- NativeDecimalFormat.setAttribute(this.addr,
+ NativeDecimalFormat.setAttribute(this.addr,
UNumberFormatAttribute.UNUM_PARSE_INT_ONLY.ordinal(), i);
}
-
+
static protected String getFieldType(Format.Field field) {
if(field == null) {
return null;
@@ -508,7 +525,7 @@ public class DecimalFormat extends NumberFormat {
}
return null;
}
-
+
protected Format.Field getField(String type) {
if(type.equals("")) {
return null;
diff --git a/icu/src/main/native/DecimalFormatInterface.cpp b/icu/src/main/native/DecimalFormatInterface.cpp
index 243efeb..fb5cf9f 100644
--- a/icu/src/main/native/DecimalFormatInterface.cpp
+++ b/icu/src/main/native/DecimalFormatInterface.cpp
@@ -28,6 +28,8 @@
#include <string.h>
#include "cutils/log.h"
+#define LOG_TAG "DecimalFormatInterface"
+
static UBool icuError(JNIEnv *env, UErrorCode errorcode)
{
const char *emsg = u_errorName(errorcode);
@@ -499,26 +501,18 @@ static jstring formatDouble(JNIEnv *env, jclass clazz, jint addr, jdouble value,
return resulting;
}
-
+
static jstring formatDigitList(JNIEnv *env, jclass clazz, jint addr, jstring value,
jobject field, jstring fieldType, jobject attributes, jint scale) {
- //const char * valueUTF = env->GetStringUTFChars(value, NULL);
- //LOGI("ENTER formatDigitList: %s", valueUTF);
- //env->ReleaseStringUTFChars(value, valueUTF);
-
- // prepare the classes and method ids
- const char * fieldPositionClassName = "java/text/FieldPosition";
- const char * stringBufferClassName = "java/lang/StringBuffer";
- jclass fieldPositionClass = env->FindClass(fieldPositionClassName);
- jclass stringBufferClass = env->FindClass(stringBufferClassName);
- jmethodID setBeginIndexMethodID = env->GetMethodID(fieldPositionClass,
- "setBeginIndex", "(I)V");
- jmethodID setEndIndexMethodID = env->GetMethodID(fieldPositionClass,
- "setEndIndex", "(I)V");
- jmethodID appendMethodID = env->GetMethodID(stringBufferClass,
- "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
+ // const char * valueUTF = env->GetStringUTFChars(value, NULL);
+ // LOGI("ENTER formatDigitList: %s, scale: %d", valueUTF, scale);
+ // env->ReleaseStringUTFChars(value, valueUTF);
+ if (scale < 0) {
+ icuError(env, U_ILLEGAL_ARGUMENT_ERROR);
+ return NULL;
+ }
const char * fieldName = NULL;
if(fieldType != NULL) {
@@ -527,21 +521,22 @@ static jstring formatDigitList(JNIEnv *env, jclass clazz, jint addr, jstring val
uint32_t reslenneeded;
- jboolean isInteger = (scale == 0);
+ bool isInteger = (scale == 0);
// prepare digit list
const char *digits = env->GetStringUTFChars(value, NULL);
+
// length must be string lengt + 2 because there's an additional
// character in front of the string ("+" or "-") and a \0 at the end
- DigitList *digitList = new DigitList(strlen(digits) + 2);
- digitList->fCount = strlen(digits);
- strcpy(digitList->fDigits, digits);
+ DigitList digitList(strlen(digits) + 2);
+ digitList.fCount = strlen(digits);
+ strcpy(digitList.fDigits, digits);
env->ReleaseStringUTFChars(value, digits);
- digitList->fDecimalAt = digitList->fCount - scale;
- digitList->fIsPositive = (*digits != '-');
- digitList->fRoundingMode = DecimalFormat::kRoundHalfUp;
+ digitList.fDecimalAt = digitList.fCount - scale;
+ digitList.fIsPositive = (*digits != '-');
+ digitList.fRoundingMode = DecimalFormat::kRoundHalfUp;
UChar *result = NULL;
@@ -560,32 +555,35 @@ static jstring formatDigitList(JNIEnv *env, jclass clazz, jint addr, jstring val
DecimalFormat *fmt = (DecimalFormat *)(int)addr;
- UnicodeString *res = new UnicodeString();
+ UnicodeString res;
- fmt->subformat(*res, fp, attrBuffer, *digitList, isInteger);
- delete digitList;
+ fmt->subformat(res, fp, attrBuffer, digitList, isInteger);
- reslenneeded = res->extract(NULL, 0, status);
+ reslenneeded = res.extract(NULL, 0, status);
if(status==U_BUFFER_OVERFLOW_ERROR) {
status=U_ZERO_ERROR;
result = (UChar*)malloc(sizeof(UChar) * (reslenneeded + 1));
- res->extract(result, reslenneeded + 1, status);
+ res.extract(result, reslenneeded + 1, status);
if (icuError(env, status) != FALSE) {
+ if(fieldType != NULL) {
+ env->ReleaseStringUTFChars(fieldType, fieldName);
+ }
free(result);
free(attrBuffer->buffer);
free(attrBuffer);
- delete(res);
return NULL;
}
} else {
+ if(fieldType != NULL) {
+ env->ReleaseStringUTFChars(fieldType, fieldName);
+ }
free(attrBuffer->buffer);
free(attrBuffer);
- delete(res);
return NULL;
}
@@ -595,6 +593,12 @@ static jstring formatDigitList(JNIEnv *env, jclass clazz, jint addr, jstring val
// check if we want to get all attributes
if(attributes != NULL) {
+ // prepare the classes and method ids
+ const char * stringBufferClassName = "java/lang/StringBuffer";
+ jclass stringBufferClass = env->FindClass(stringBufferClassName);
+ jmethodID appendMethodID = env->GetMethodID(stringBufferClass,
+ "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
+
jstring attrString = env->NewStringUTF(attrBuffer->buffer + 1); // cut off the leading ';'
env->CallObjectMethod(attributes, appendMethodID, attrString);
}
@@ -612,6 +616,18 @@ static jstring formatDigitList(JNIEnv *env, jclass clazz, jint addr, jstring val
}
if(resattr != NULL && strcmp(resattr, fieldName) == 0) {
+
+ // prepare the classes and method ids
+ const char * fieldPositionClassName =
+ "java/text/FieldPosition";
+ jclass fieldPositionClass = env->FindClass(
+ fieldPositionClassName);
+ jmethodID setBeginIndexMethodID = env->GetMethodID(
+ fieldPositionClass, "setBeginIndex", "(I)V");
+ jmethodID setEndIndexMethodID = env->GetMethodID(
+ fieldPositionClass, "setEndIndex", "(I)V");
+
+
resattr = strtok(NULL, delimiter);
begin = (int) strtol(resattr, NULL, 10);
resattr = strtok(NULL, delimiter);
@@ -632,11 +648,9 @@ static jstring formatDigitList(JNIEnv *env, jclass clazz, jint addr, jstring val
free(attrBuffer->buffer);
free(attrBuffer);
free(result);
- delete(res);
-
- //const char * resultUTF = env->GetStringUTFChars(resulting, NULL);
- //LOGI("RETURN formatDigitList: %s", resultUTF);
- //env->ReleaseStringUTFChars(resulting, resultUTF);
+ // const char * resultUTF = env->GetStringUTFChars(resulting, NULL);
+ // LOGI("RETURN formatDigitList: %s", resultUTF);
+ // env->ReleaseStringUTFChars(resulting, resultUTF);
return resulting;
}