diff options
-rw-r--r-- | icu/src/main/native/DecimalFormatInterface.cpp | 55 | ||||
-rw-r--r-- | icu/src/main/native/RBNFInterface.cpp | 76 | ||||
-rw-r--r-- | icu/src/main/native/RegExInterface.cpp | 18 | ||||
-rw-r--r-- | sql/src/main/native/sqlite_jni.c | 25 | ||||
-rw-r--r-- | xml/src/main/native/org_apache_harmony_xml_ExpatParser.cpp | 26 |
5 files changed, 66 insertions, 134 deletions
diff --git a/icu/src/main/native/DecimalFormatInterface.cpp b/icu/src/main/native/DecimalFormatInterface.cpp index 7e37d6c..d2bacb8 100644 --- a/icu/src/main/native/DecimalFormatInterface.cpp +++ b/icu/src/main/native/DecimalFormatInterface.cpp @@ -671,28 +671,12 @@ static jstring formatDigitList(JNIEnv *env, jclass clazz, jint addr, jstring val static jobject parse(JNIEnv *env, jclass clazz, jint addr, jstring text, jobject position) { - - const char * textUTF = env->GetStringUTFChars(text, NULL); - env->ReleaseStringUTFChars(text, textUTF); - - const char * parsePositionClassName = "java/text/ParsePosition"; - const char * longClassName = "java/lang/Long"; - const char * doubleClassName = "java/lang/Double"; - const char * bigDecimalClassName = "java/math/BigDecimal"; - const char * bigIntegerClassName = "java/math/BigInteger"; - - 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); - jclass bigDecimalClass = env->FindClass(bigDecimalClassName); - jclass bigIntegerClass = env->FindClass(bigIntegerClassName); + // TODO: cache these? + jclass parsePositionClass = env->FindClass("java/text/ParsePosition"); + jclass longClass = env->FindClass("java/lang/Long"); + jclass doubleClass = env->FindClass("java/lang/Double"); + jclass bigDecimalClass = env->FindClass("java/math/BigDecimal"); + jclass bigIntegerClass = env->FindClass("java/math/BigInteger"); jmethodID getIndexMethodID = env->GetMethodID(parsePositionClass, "getIndex", "()I"); @@ -707,27 +691,26 @@ static jobject parse(JNIEnv *env, jclass clazz, jint addr, jstring text, jmethodID bigIntegerInitMethodID = env->GetMethodID(bigIntegerClass, "<init>", "(Ljava/lang/String;)V"); jmethodID doubleValueMethodID = env->GetMethodID(bigDecimalClass, "doubleValue", "()D"); - bool resultAssigned; - 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 + int parsePos = env->CallIntMethod(position, getIndexMethodID, NULL); + const int strlength = env->GetStringLength(text); if(parsePos < 0 || parsePos > strlength) { return NULL; } - - Formattable res; - - const UnicodeString src((UChar*)str, strlength, strlength); + ParsePosition pp; - pp.setIndex(parsePos); DigitList digits; - + + UNumberFormat *fmt = (UNumberFormat *)(int)addr; + Formattable res; + bool resultAssigned; + jchar *str = (UChar *)env->GetStringChars(text, NULL); + const UnicodeString src((UChar*)str, strlength, strlength); ((const DecimalFormat*)fmt)->parse(src, resultAssigned, res, pp, FALSE, digits); - env->ReleaseStringChars(text, str); if(pp.getErrorIndex() == -1) { @@ -738,20 +721,14 @@ static jobject parse(JNIEnv *env, jclass clazz, jint addr, jstring text, return NULL; } - Formattable::Type numType; - numType = res.getType(); + Formattable::Type numType = res.getType(); UErrorCode fmtStatus; double resultDouble; long resultLong; int64_t resultInt64; - UnicodeString resultString; jstring resultStr; - int resLength; - const char * resultUTF; jobject resultObject1, resultObject2; - jdouble doubleTest; - jchar * result; if (resultAssigned) { diff --git a/icu/src/main/native/RBNFInterface.cpp b/icu/src/main/native/RBNFInterface.cpp index d9bf460..62e0cb4 100644 --- a/icu/src/main/native/RBNFInterface.cpp +++ b/icu/src/main/native/RBNFInterface.cpp @@ -265,22 +265,11 @@ 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); + + // TODO: cache these? + jclass parsePositionClass = env->FindClass("java/text/ParsePosition"); + jclass longClass = env->FindClass("java/lang/Long"); + jclass doubleClass = env->FindClass("java/lang/Double"); jmethodID getIndexMethodID = env->GetMethodID(parsePositionClass, "getIndex", "()I"); @@ -292,22 +281,25 @@ static jobject parseRBNFImpl(JNIEnv *env, jclass clazz, jint addr, jstring text, 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 + int parsePos = env->CallIntMethod(position, getIndexMethodID, NULL); + const int strlength = env->GetStringLength(text); if(parsePos < 0 || parsePos > strlength) { return NULL; } - + Formattable res; - + + jchar *str = (UChar *)env->GetStringChars(text, NULL); + const UnicodeString src((UChar*)str, strlength, strlength); ParsePosition pp; pp.setIndex(parsePos); + UNumberFormat *fmt = (UNumberFormat *)(int)addr; if(lenient) { unum_setAttribute(fmt, UNUM_LENIENT_PARSE, JNI_TRUE); } @@ -328,35 +320,23 @@ static jobject parseRBNFImpl(JNIEnv *env, jclass clazz, jint addr, jstring text, 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; + Formattable::Type numType = res.getType(); + if (numType == Formattable::kDouble) { + double resultDouble = res.getDouble(); + env->CallVoidMethod(position, setIndexMethodID, (jint) parsePos); + return env->NewObject(doubleClass, dblInitMethodID, + (jdouble) resultDouble); + } else if (numType == Formattable::kLong) { + long resultLong = res.getLong(); + env->CallVoidMethod(position, setIndexMethodID, (jint) parsePos); + return env->NewObject(longClass, longInitMethodID, (jlong) resultLong); + } else if (numType == Formattable::kInt64) { + int64_t resultInt64 = res.getInt64(); + env->CallVoidMethod(position, setIndexMethodID, (jint) parsePos); + return env->NewObject(longClass, longInitMethodID, (jlong) resultInt64); + } else { + return NULL; } - - return NULL; } static JNINativeMethod gMethods[] = { diff --git a/icu/src/main/native/RegExInterface.cpp b/icu/src/main/native/RegExInterface.cpp index afa5cc4..0ca3d06 100644 --- a/icu/src/main/native/RegExInterface.cpp +++ b/icu/src/main/native/RegExInterface.cpp @@ -32,12 +32,12 @@ static jchar EMPTY_STRING = 0; * character data it refers to (but does not have a copy of), so we can * manage memory properly. */ -typedef struct RegExDataStruct { +struct RegExData { // A pointer to the ICU regular expression URegularExpression* regex; // A pointer to (a copy of) the input text that *we* manage jchar* text; -} RegExData; +}; static void throwPatternSyntaxException(JNIEnv* env, UErrorCode status, jstring pattern, UParseError error) @@ -63,8 +63,8 @@ static void _close(JNIEnv* env, jclass clazz, RegExData* data) uregex_close(data->regex); } - if (data->text != NULL && data->text != &EMPTY_STRING) { - free(data->text); + if (data->text != &EMPTY_STRING) { + delete[] data->text; } free(data); @@ -125,8 +125,8 @@ static void setText(JNIEnv* env, jclass clazz, RegExData* data, jstring text) return; } - if (data->text != NULL && data->text != &EMPTY_STRING) { - free(data->text); + if (data->text != &EMPTY_STRING) { + delete[] data->text; data->text = NULL; } @@ -134,11 +134,9 @@ static void setText(JNIEnv* env, jclass clazz, RegExData* data, jstring text) if (textLen == 0) { data->text = &EMPTY_STRING; } else { - jchar const * textRaw = env->GetStringChars(text, NULL); - data->text = (jchar*)malloc((textLen + 1) * sizeof(jchar)); - memcpy(data->text, textRaw, textLen * sizeof(jchar)); + data->text = new jchar[textLen + 1]; + env->GetStringRegion(text, 0, textLen, data->text); data->text[textLen] = 0; - env->ReleaseStringChars(text, textRaw); } uregex_setText(data->regex, data->text, textLen, &status); diff --git a/sql/src/main/native/sqlite_jni.c b/sql/src/main/native/sqlite_jni.c index 4923869..44c16f3 100644 --- a/sql/src/main/native/sqlite_jni.c +++ b/sql/src/main/native/sqlite_jni.c @@ -331,16 +331,10 @@ trans2iso(JNIEnv *env, int haveutf, jstring enc, jstring src, dest->result = 0; dest->tofree = 0; if (haveutf) { - const char *utf = (*env)->GetStringUTFChars(env, src, 0); - - if (!utf) { - return dest->result; - } - dest->tofree = malloc(strlen(utf) + 1); - dest->result = dest->tofree; - strcpy(dest->result, utf); - (*env)->ReleaseStringUTFChars(env, src, utf); - return dest->result; + const jsize utfLength = (*env)->GetStringUTFLength(env, src); + dest->result = dest->tofree = malloc(utfLength + 1); + (*env)->GetStringUTFRegion(env, src, 0, utfLength, dest->result); + return dest->result; } if (enc) { bytes = (*env)->CallObjectMethod(env, src, @@ -3674,19 +3668,16 @@ Java_SQLite_Stmt_bind__ILjava_lang_String_2(JNIEnv *env, jobject obj, return; } if (val) { - len = (*env)->GetStringLength(env, val); + const jsize charCount = (*env)->GetStringLength(env, val); + len = charCount * sizeof(jchar); if (len > 0) { - const jchar *ch; - - len *= sizeof (jchar); data = sqlite3_malloc(len); if (!data) { throwoom(env, "unable to get blob parameter"); return; } - ch = (*env)->GetStringChars(env, val, 0); - memcpy(data, ch, len); - (*env)->ReleaseStringChars(env, val, ch); + + (*env)->GetStringRegion(env, val, 0, charCount, (jchar*) data); ret = sqlite3_bind_text16((sqlite3_stmt *) v->vm, pos, data, len, sqlite3_free); } else { diff --git a/xml/src/main/native/org_apache_harmony_xml_ExpatParser.cpp b/xml/src/main/native/org_apache_harmony_xml_ExpatParser.cpp index 40a4116..6132107 100644 --- a/xml/src/main/native/org_apache_harmony_xml_ExpatParser.cpp +++ b/xml/src/main/native/org_apache_harmony_xml_ExpatParser.cpp @@ -105,16 +105,7 @@ static jclass stringClass; static jstring emptyString; /** - * Throws a NullPointerException. - * - * @param msg exception message - */ -static void throw_NullPointerException(JNIEnv* env, const char* msg) { - jniThrowException(env, "java/lang/NullPointerException", msg); -} - -/** - * Throw a NullPointerException. + * Throws OutOfMemoryError. */ static void throw_OutOfMemoryError(JNIEnv* env) { jniThrowException(env, "java/lang/OutOfMemoryError", "Out of memory."); @@ -1308,26 +1299,21 @@ static jint getAttributeIndex(JNIEnv* env, jobject clazz, return getAttributeIndexForQName( env, clazz, attributePointer, localName); } - int localNameLength = env->GetStringUTFLength(localName); // Create string in the same format used by Expat: "uri|localName" + // TODO: do we have a guarantee that uriLength and localNameLength are small? char concatenated[uriLength + localNameLength + 2]; // Append uri. - const char* uriBytes = env->GetStringUTFChars(uri, NULL); - if (uriBytes == NULL) return -1; - strcpy(concatenated, uriBytes); - env->ReleaseStringUTFChars(uri, uriBytes); + env->GetStringUTFRegion(uri, 0, uriLength, concatenated); - // Separarator. + // Separator. concatenated[uriLength] = '|'; // Append local name. - const char* localNameBytes = env->GetStringUTFChars(localName, NULL); - if (localNameBytes == NULL) return -1; - strcpy(concatenated + uriLength + 1, localNameBytes); - env->ReleaseStringUTFChars(localName, localNameBytes); + env->GetStringUTFRegion(localName, 0, localNameLength, + concatenated + uriLength + 1); return findAttributeByName(attributes, concatenated); } |