StandardPlural::Form QuantityFormatter::selectPlural(
            const Formattable &number,
            const NumberFormat &fmt,
            const PluralRules &rules,
            UnicodeString &formattedNumber,
            FieldPosition &pos,
            UErrorCode &status) {
    if (U_FAILURE(status)) {
        return StandardPlural::OTHER;
    }
    UnicodeString pluralKeyword;
    const DecimalFormat *decFmt = dynamic_cast<const DecimalFormat *>(&fmt);
    if (decFmt != NULL) {
        number::impl::DecimalQuantity dq;
        decFmt->formatToDecimalQuantity(number, dq, status);
        if (U_FAILURE(status)) {
            return StandardPlural::OTHER;
        }
        pluralKeyword = rules.select(dq);
        decFmt->format(number, formattedNumber, pos, status);
    } else {
        if (number.getType() == Formattable::kDouble) {
            pluralKeyword = rules.select(number.getDouble());
        } else if (number.getType() == Formattable::kLong) {
            pluralKeyword = rules.select(number.getLong());
        } else if (number.getType() == Formattable::kInt64) {
            pluralKeyword = rules.select((double) number.getInt64());
        } else {
            status = U_ILLEGAL_ARGUMENT_ERROR;
            return StandardPlural::OTHER;
        }
        fmt.format(number, formattedNumber, pos, status);
    }
    return StandardPlural::orOtherFromString(pluralKeyword);
}
static jobject NativeDecimalFormat_parse(JNIEnv* env, jclass, jlong addr, jstring text,
        jobject position, jboolean parseBigDecimal) {

    static jmethodID gPP_getIndex = env->GetMethodID(JniConstants::parsePositionClass, "getIndex", "()I");
    static jmethodID gPP_setIndex = env->GetMethodID(JniConstants::parsePositionClass, "setIndex", "(I)V");
    static jmethodID gPP_setErrorIndex = env->GetMethodID(JniConstants::parsePositionClass, "setErrorIndex", "(I)V");

    ScopedJavaUnicodeString src(env, text);
    if (!src.valid()) {
      return NULL;
    }

    // make sure the ParsePosition is valid. Actually icu4c would parse a number
    // correctly even if the parsePosition is set to -1, but since the RI fails
    // for that case we have to fail too
    int parsePos = env->CallIntMethod(position, gPP_getIndex, NULL);
    if (parsePos < 0 || parsePos > env->GetStringLength(text)) {
        return NULL;
    }

    Formattable res;
    ParsePosition pp(parsePos);
    DecimalFormat* fmt = toDecimalFormat(addr);
    fmt->parse(src.unicodeString(), res, pp);

    if (pp.getErrorIndex() == -1) {
        env->CallVoidMethod(position, gPP_setIndex, pp.getIndex());
    } else {
        env->CallVoidMethod(position, gPP_setErrorIndex, pp.getErrorIndex());
        return NULL;
    }

    if (parseBigDecimal) {
        UErrorCode status = U_ZERO_ERROR;
        StringPiece str = res.getDecimalNumber(status);
        if (U_SUCCESS(status)) {
            int len = str.length();
            const char* data = str.data();
            if (strncmp(data, "NaN", 3) == 0 ||
                strncmp(data, "Inf", 3) == 0 ||
                strncmp(data, "-Inf", 4) == 0) {
                double resultDouble = res.getDouble(status);
                return doubleValueOf(env, resultDouble);
            }
            return newBigDecimal(env, data, len);
        }
        return NULL;
    }

    switch (res.getType()) {
        case Formattable::kDouble: return doubleValueOf(env, res.getDouble());
        case Formattable::kLong:   return longValueOf(env, res.getLong());
        case Formattable::kInt64:  return longValueOf(env, res.getInt64());
        default:                   return NULL;
    }
}
U_CAPI int64_t U_EXPORT2
unum_parseInt64(    const   UNumberFormat*  fmt,
        const   UChar*          text,
        int32_t         textLength,
        int32_t         *parsePos /* 0 = start */,
        UErrorCode      *status)
{
    Formattable res;
    parseRes(res, fmt, text, textLength, parsePos, FALSE, status);
    return res.getInt64(*status);
}
示例#4
0
U_DRAFT int64_t U_EXPORT2
ufmt_getInt64(UFormattable *fmt, UErrorCode *status) {
  Formattable *obj = Formattable::fromUFormattable(fmt);
  return obj->getInt64(*status);
}
示例#5
0
void MessageFormatRegressionTest::Test4031438() 
{
    UErrorCode status = U_ZERO_ERROR;
    
    UnicodeString pattern1("Impossible {1} has occurred -- status code is {0} and message is {2}.");
    UnicodeString pattern2("Double '' Quotes {0} test and quoted '{1}' test plus 'other {2} stuff'.");

    MessageFormat *messageFormatter = new MessageFormat("", status);
    failure(status, "new MessageFormat");
    
    const UBool possibleDataError = TRUE;

    //try {
        logln("Apply with pattern : " + pattern1);
        messageFormatter->applyPattern(pattern1, status);
        failure(status, "messageFormat->applyPattern");
        //Object[] params = {new Integer(7)};
        Formattable params []= {
            Formattable((int32_t)7)
        };
        UnicodeString tempBuffer;
        FieldPosition pos(FieldPosition::DONT_CARE);
        tempBuffer = messageFormatter->format(params, 1, tempBuffer, pos, status);
        if(tempBuffer != "Impossible {1} has occurred -- status code is 7 and message is {2}." || failure(status, "MessageFormat::format"))
            dataerrln("Tests arguments < substitution failed");
        logln("Formatted with 7 : " + tempBuffer);
        ParsePosition pp(0);
        int32_t count = 0;
        Formattable *objs = messageFormatter->parse(tempBuffer, pp, count);
        //if(objs[7/*params.length*/] != NULL)
        //    errln("Parse failed with more than expected arguments");

        NumberFormat *fmt = 0;
        UnicodeString temp, temp1;
        
        for (int i = 0; i < count; i++) {
            
            // convert to string if not already
            Formattable obj = objs[i];
            temp.remove();
            if(obj.getType() == Formattable::kString)
                temp = obj.getString(temp);
            else {
                fmt = NumberFormat::createInstance(status);
                switch (obj.getType()) {
                case Formattable::kLong: fmt->format(obj.getLong(), temp); break;
                case Formattable::kInt64: fmt->format(obj.getInt64(), temp); break;
                case Formattable::kDouble: fmt->format(obj.getDouble(), temp); break;
                default: break;
                }
            }

            // convert to string if not already
            Formattable obj1 = params[i];
            temp1.remove();
            if(obj1.getType() == Formattable::kString)
                temp1 = obj1.getString(temp1);
            else {
                fmt = NumberFormat::createInstance(status);
                switch (obj1.getType()) {
                case Formattable::kLong: fmt->format(obj1.getLong(), temp1); break;
                case Formattable::kInt64: fmt->format(obj1.getInt64(), temp1); break;
                case Formattable::kDouble: fmt->format(obj1.getDouble(), temp1); break;
                default: break;
                }
            }

            //if (objs[i] != NULL && objs[i].getString(temp1) != params[i].getString(temp2)) {
            if (temp != temp1) {
                errln("Parse failed on object " + objs[i].getString(temp1) + " at index : " + i);
            }       
        }

        delete fmt;
        delete [] objs;

        // {sfb} does this apply?  no way to really pass a null Formattable, 
        // only a null array

        /*tempBuffer = messageFormatter->format(null, tempBuffer, FieldPosition(FieldPosition::DONT_CARE), status);
        if (tempBuffer != "Impossible {1} has occurred -- status code is {0} and message is {2}." || failure(status, "messageFormat->format"))
            errln("Tests with no arguments failed");
        logln("Formatted with null : " + tempBuffer);*/
        logln("Apply with pattern : " + pattern2);
        messageFormatter->applyPattern(pattern2, status);
        failure(status, "messageFormatter->applyPattern", possibleDataError);
        tempBuffer.remove();
        tempBuffer = messageFormatter->format(params, 1, tempBuffer, pos, status);
        if (tempBuffer != "Double ' Quotes 7 test and quoted {1} test plus other {2} stuff.")
            dataerrln("quote format test (w/ params) failed. - %s", u_errorName(status));
        logln("Formatted with params : " + tempBuffer);
        
        /*tempBuffer = messageFormatter->format(null);
        if (!tempBuffer.equals("Double ' Quotes {0} test and quoted {1} test plus other {2} stuff."))
            errln("quote format test (w/ null) failed.");
        logln("Formatted with null : " + tempBuffer);
        logln("toPattern : " + messageFormatter.toPattern());*/
    /*} catch (Exception foo) {
        errln("Exception when formatting in bug 4031438. "+foo.getMessage());
    }*/
        delete messageFormatter;
}
示例#6
0
static jobject parseRBNFImpl(JNIEnv *env, jclass clazz, jint addr, jstring text, 
        jobject position, jboolean lenient) {

    // LOGI("ENTER parseRBNFImpl");

    const char * parsePositionClassName = "java/text/ParsePosition";
    const char * longClassName = "java/lang/Long";
    const char * doubleClassName = "java/lang/Double";


    UErrorCode status = U_ZERO_ERROR;

    UNumberFormat *fmt = (UNumberFormat *)(int)addr;

    jchar *str = (UChar *)env->GetStringChars(text, NULL);
    int strlength = env->GetStringLength(text);

    jclass parsePositionClass = env->FindClass(parsePositionClassName);
    jclass longClass =  env->FindClass(longClassName);
    jclass doubleClass =  env->FindClass(doubleClassName);

    jmethodID getIndexMethodID = env->GetMethodID(parsePositionClass, 
            "getIndex", "()I");
    jmethodID setIndexMethodID = env->GetMethodID(parsePositionClass, 
            "setIndex", "(I)V");
    jmethodID setErrorIndexMethodID = env->GetMethodID(parsePositionClass, 
            "setErrorIndex", "(I)V");

    jmethodID longInitMethodID = env->GetMethodID(longClass, "<init>", "(J)V");
    jmethodID dblInitMethodID = env->GetMethodID(doubleClass, "<init>", "(D)V");

    int parsePos = env->CallIntMethod(position, getIndexMethodID, NULL);

    // make sure the ParsePosition is valid. Actually icu4c would parse a number 
    // correctly even if the parsePosition is set to -1, but since the RI fails 
    // for that case we have to fail too
    if(parsePos < 0 || parsePos > strlength) {
        return NULL;
    }

    Formattable res;

    const UnicodeString src((UChar*)str, strlength, strlength);
    ParsePosition pp;
    
    pp.setIndex(parsePos);
    
    if(lenient) {
        unum_setAttribute(fmt, UNUM_LENIENT_PARSE, JNI_TRUE);
    }
    
    ((const NumberFormat*)fmt)->parse(src, res, pp);

    if(lenient) {
        unum_setAttribute(fmt, UNUM_LENIENT_PARSE, JNI_FALSE);
    }
    
    env->ReleaseStringChars(text, str);

    if(pp.getErrorIndex() == -1) {
        parsePos = pp.getIndex();
    } else {
        env->CallVoidMethod(position, setErrorIndexMethodID, 
                (jint) pp.getErrorIndex());        
        return NULL;
    }

    Formattable::Type numType;
    numType = res.getType();
    UErrorCode fmtStatus;

    double resultDouble;
    long resultLong;
    int64_t resultInt64;

    switch(numType) {
        case Formattable::kDouble:
            resultDouble = res.getDouble();
            env->CallVoidMethod(position, setIndexMethodID, (jint) parsePos);
            return env->NewObject(doubleClass, dblInitMethodID, 
                    (jdouble) resultDouble);
        case Formattable::kLong:
            resultLong = res.getLong();
            env->CallVoidMethod(position, setIndexMethodID, (jint) parsePos);
            return env->NewObject(longClass, longInitMethodID, 
                    (jlong) resultLong);
        case Formattable::kInt64:
            resultInt64 = res.getInt64();
            env->CallVoidMethod(position, setIndexMethodID, (jint) parsePos);
            return env->NewObject(longClass, longInitMethodID, 
                    (jlong) resultInt64);
        default:
            break;
    }

    return NULL;
}