From 9cb89d78930c6ff1f18ab5e3eea393a47e9fff4d Mon Sep 17 00:00:00 2001 From: The Android Open Source Project Date: Fri, 13 Feb 2009 12:57:48 -0800 Subject: auto import from //branches/cupcake/...@131421 --- .../java/com/ibm/icu4jni/text/DecimalFormat.java | 127 ++++++++++++--------- icu/src/main/native/DecimalFormatInterface.cpp | 84 ++++++++------ 2 files changed, 121 insertions(+), 90 deletions(-) (limited to 'icu/src/main') 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 #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; } -- cgit v1.1