diff options
Diffstat (limited to 'luni/src/main/native')
34 files changed, 824 insertions, 1008 deletions
diff --git a/luni/src/main/native/IcuUtilities.cpp b/luni/src/main/native/IcuUtilities.cpp index 7ce2168..98648a5 100644 --- a/luni/src/main/native/IcuUtilities.cpp +++ b/luni/src/main/native/IcuUtilities.cpp @@ -22,13 +22,12 @@ #include "JniException.h" #include "ScopedLocalRef.h" #include "ScopedUtfChars.h" -#include "UniquePtr.h" #include "cutils/log.h" #include "unicode/strenum.h" #include "unicode/uloc.h" #include "unicode/ustring.h" -jobjectArray fromStringEnumeration(JNIEnv* env, UErrorCode& status, const char* provider, StringEnumeration* se) { +jobjectArray fromStringEnumeration(JNIEnv* env, UErrorCode& status, const char* provider, icu::StringEnumeration* se) { if (maybeThrowIcuException(env, provider, status)) { return NULL; } @@ -40,7 +39,7 @@ jobjectArray fromStringEnumeration(JNIEnv* env, UErrorCode& status, const char* jobjectArray result = env->NewObjectArray(count, JniConstants::stringClass, NULL); for (int32_t i = 0; i < count; ++i) { - const UnicodeString* string = se->snext(status); + const icu::UnicodeString* string = se->snext(status); if (maybeThrowIcuException(env, "StringEnumeration::snext", status)) { return NULL; } diff --git a/luni/src/main/native/IcuUtilities.h b/luni/src/main/native/IcuUtilities.h index 737379e..c64de30 100644 --- a/luni/src/main/native/IcuUtilities.h +++ b/luni/src/main/native/IcuUtilities.h @@ -17,14 +17,11 @@ #ifndef ICU_UTILITIES_H_included #define ICU_UTILITIES_H_included -#undef U_HAVE_STD_STRING -#define U_HAVE_STD_STRING 1 // For UnicodeString::toUTF8String(std::string&). - #include "jni.h" #include "ustrenum.h" // For UStringEnumeration. #include "unicode/utypes.h" // For UErrorCode. -extern jobjectArray fromStringEnumeration(JNIEnv* env, UErrorCode& status, const char* provider, StringEnumeration*); +extern jobjectArray fromStringEnumeration(JNIEnv* env, UErrorCode& status, const char* provider, icu::StringEnumeration*); bool maybeThrowIcuException(JNIEnv* env, const char* function, UErrorCode error); #endif // ICU_UTILITIES_H_included diff --git a/luni/src/main/native/Portability.h b/luni/src/main/native/Portability.h index 1520311..5900cb0 100644 --- a/luni/src/main/native/Portability.h +++ b/luni/src/main/native/Portability.h @@ -65,7 +65,7 @@ static inline int mincore(void* addr, size_t length, unsigned char* vec) { #include <sys/param.h> #include <sys/mount.h> -#else // defined(__APPLE__) +#else // Bionic or glibc. @@ -73,15 +73,33 @@ static inline int mincore(void* addr, size_t length, unsigned char* vec) { #include <sys/sendfile.h> #include <sys/statvfs.h> -#endif // defined(__APPLE__) +#endif -#if !defined(__BIONIC__) #include <netdb.h> -#include "../../bionic/libc/dns/include/resolv_netid.h" -inline int android_getaddrinfofornet(const char *hostname, const char *servname, - const struct addrinfo *hints, unsigned /*netid*/, unsigned /*mark*/, struct addrinfo **res) { +#if defined(__BIONIC__) +extern "C" int android_getaddrinfofornet(const char*, const char*, const struct addrinfo*, unsigned, unsigned, struct addrinfo**); +#else +static inline int android_getaddrinfofornet(const char* hostname, const char* servname, + const struct addrinfo* hints, unsigned /*netid*/, unsigned /*mark*/, struct addrinfo** res) { return getaddrinfo(hostname, servname, hints, res); } -#endif // !defined(__BIONIC__) +#endif + +#if defined(__GLIBC__) && !defined(__LP64__) + +#include <unistd.h> + +// 32 bit GLIBC hardcodes a "long int" as the return type for +// TEMP_FAILURE_RETRY so the return value here gets truncated for +// functions that return 64 bit types. +#undef TEMP_FAILURE_RETRY +#define TEMP_FAILURE_RETRY(exp) ({ \ + __typeof__(exp) _rc; \ + do { \ + _rc = (exp); \ + } while (_rc == -1 && errno == EINTR); \ + _rc; }) + +#endif // __GLIBC__ && !__LP64__ #endif // PORTABILITY_H_included diff --git a/luni/src/main/native/Register.cpp b/luni/src/main/native/Register.cpp index 6a2c939..0f2d0ad 100644 --- a/luni/src/main/native/Register.cpp +++ b/luni/src/main/native/Register.cpp @@ -48,7 +48,6 @@ jint JNI_OnLoad(JavaVM* vm, void*) { REGISTER(register_java_lang_System); REGISTER(register_java_math_NativeBN); REGISTER(register_java_nio_ByteOrder); - REGISTER(register_java_nio_charset_Charsets); REGISTER(register_java_text_Bidi); REGISTER(register_java_util_jar_StrictJarFile); REGISTER(register_java_util_regex_Matcher); @@ -58,9 +57,7 @@ jint JNI_OnLoad(JavaVM* vm, void*) { REGISTER(register_java_util_zip_Deflater); REGISTER(register_java_util_zip_Inflater); REGISTER(register_libcore_icu_AlphabeticIndex); - REGISTER(register_libcore_icu_DateIntervalFormat); REGISTER(register_libcore_icu_ICU); - REGISTER(register_libcore_icu_NativeBreakIterator); REGISTER(register_libcore_icu_NativeCollation); REGISTER(register_libcore_icu_NativeConverter); REGISTER(register_libcore_icu_NativeDecimalFormat); @@ -72,6 +69,7 @@ jint JNI_OnLoad(JavaVM* vm, void*) { REGISTER(register_libcore_io_AsynchronousCloseMonitor); REGISTER(register_libcore_io_Memory); REGISTER(register_libcore_io_Posix); + REGISTER(register_libcore_util_CharsetUtils); REGISTER(register_org_apache_harmony_dalvik_NativeTestTarget); REGISTER(register_org_apache_harmony_xml_ExpatParser); REGISTER(register_sun_misc_Unsafe); diff --git a/luni/src/main/native/ZipUtilities.cpp b/luni/src/main/native/ZipUtilities.cpp index 745b3b1..b7d2209 100644 --- a/luni/src/main/native/ZipUtilities.cpp +++ b/luni/src/main/native/ZipUtilities.cpp @@ -15,9 +15,10 @@ * limitations under the License. */ +#include <memory> + #include "JniConstants.h" #include "JniException.h" -#include "UniquePtr.h" #include "ZipUtilities.h" void throwExceptionForZlibError(JNIEnv* env, const char* exceptionClassName, int error, @@ -31,7 +32,7 @@ void throwExceptionForZlibError(JNIEnv* env, const char* exceptionClassName, int } } -NativeZipStream::NativeZipStream() : input(NULL), inCap(0), mDict(NULL) { +NativeZipStream::NativeZipStream() : inCap(0), totalIn(0), totalOut(0) { // Let zlib use its default allocator. stream.opaque = Z_NULL; stream.zalloc = Z_NULL; @@ -43,7 +44,7 @@ NativeZipStream::~NativeZipStream() { void NativeZipStream::setDictionary(JNIEnv* env, jbyteArray javaDictionary, int off, int len, bool inflate) { - UniquePtr<jbyte[]> dictionaryBytes(new jbyte[len]); + std::unique_ptr<jbyte[]> dictionaryBytes(new jbyte[len]); if (dictionaryBytes.get() == NULL) { jniThrowOutOfMemoryError(env, NULL); return; diff --git a/luni/src/main/native/ZipUtilities.h b/luni/src/main/native/ZipUtilities.h index fe0f977..50111a5 100644 --- a/luni/src/main/native/ZipUtilities.h +++ b/luni/src/main/native/ZipUtilities.h @@ -18,15 +18,18 @@ #ifndef ZIP_UTILITIES_H_included #define ZIP_UTILITIES_H_included -#include "UniquePtr.h" +#include <cstdint> +#include <memory> #include "jni.h" #include "zlib.h" class NativeZipStream { public: - UniquePtr<jbyte[]> input; + std::unique_ptr<jbyte[]> input; int inCap; z_stream stream; + uint64_t totalIn; + uint64_t totalOut; NativeZipStream(); ~NativeZipStream(); @@ -34,7 +37,7 @@ public: void setInput(JNIEnv* env, jbyteArray buf, jint off, jint len); private: - UniquePtr<jbyte[]> mDict; + std::unique_ptr<jbyte[]> mDict; // Disallow copy and assignment. NativeZipStream(const NativeZipStream&); diff --git a/luni/src/main/native/android_system_OsConstants.cpp b/luni/src/main/native/android_system_OsConstants.cpp index 92212b9..a9031f4 100644 --- a/luni/src/main/native/android_system_OsConstants.cpp +++ b/luni/src/main/native/android_system_OsConstants.cpp @@ -38,6 +38,9 @@ #include <sys/wait.h> #include <unistd.h> +#include <net/if_arp.h> +#include <linux/if_ether.h> + // After the others because these are not necessarily self-contained in glibc. #ifndef __APPLE__ #include <linux/if_addr.h> @@ -58,6 +61,8 @@ static void initConstant(JNIEnv* env, jclass c, const char* fieldName, int value static void OsConstants_initConstants(JNIEnv* env, jclass c) { initConstant(env, c, "AF_INET", AF_INET); initConstant(env, c, "AF_INET6", AF_INET6); + initConstant(env, c, "AF_PACKET", AF_PACKET); + initConstant(env, c, "AF_NETLINK", AF_NETLINK); initConstant(env, c, "AF_UNIX", AF_UNIX); initConstant(env, c, "AF_UNSPEC", AF_UNSPEC); initConstant(env, c, "AI_ADDRCONFIG", AI_ADDRCONFIG); @@ -69,6 +74,8 @@ static void OsConstants_initConstants(JNIEnv* env, jclass c) { #endif initConstant(env, c, "AI_PASSIVE", AI_PASSIVE); initConstant(env, c, "AI_V4MAPPED", AI_V4MAPPED); + initConstant(env, c, "ARPHRD_ETHER", ARPHRD_ETHER); + initConstant(env, c, "ARPHRD_LOOPBACK", ARPHRD_LOOPBACK); #if defined(CAP_LAST_CAP) initConstant(env, c, "CAP_AUDIT_CONTROL", CAP_AUDIT_CONTROL); initConstant(env, c, "CAP_AUDIT_WRITE", CAP_AUDIT_WRITE); @@ -196,6 +203,9 @@ static void OsConstants_initConstants(JNIEnv* env, jclass c) { initConstant(env, c, "ESPIPE", ESPIPE); initConstant(env, c, "ESRCH", ESRCH); initConstant(env, c, "ESTALE", ESTALE); + initConstant(env, c, "ETH_P_ARP", ETH_P_ARP); + initConstant(env, c, "ETH_P_IP", ETH_P_IP); + initConstant(env, c, "ETH_P_IPV6", ETH_P_IPV6); initConstant(env, c, "ETIME", ETIME); initConstant(env, c, "ETIMEDOUT", ETIMEDOUT); initConstant(env, c, "ETXTBSY", ETXTBSY); @@ -355,6 +365,7 @@ static void OsConstants_initConstants(JNIEnv* env, jclass c) { initConstant(env, c, "MS_ASYNC", MS_ASYNC); initConstant(env, c, "MS_INVALIDATE", MS_INVALIDATE); initConstant(env, c, "MS_SYNC", MS_SYNC); + initConstant(env, c, "NETLINK_ROUTE", NETLINK_ROUTE); initConstant(env, c, "NI_DGRAM", NI_DGRAM); initConstant(env, c, "NI_NAMEREQD", NI_NAMEREQD); initConstant(env, c, "NI_NOFQDN", NI_NOFQDN); @@ -362,6 +373,7 @@ static void OsConstants_initConstants(JNIEnv* env, jclass c) { initConstant(env, c, "NI_NUMERICSERV", NI_NUMERICSERV); initConstant(env, c, "O_ACCMODE", O_ACCMODE); initConstant(env, c, "O_APPEND", O_APPEND); + initConstant(env, c, "O_CLOEXEC", O_CLOEXEC); initConstant(env, c, "O_CREAT", O_CREAT); initConstant(env, c, "O_EXCL", O_EXCL); initConstant(env, c, "O_NOCTTY", O_NOCTTY); @@ -406,6 +418,19 @@ static void OsConstants_initConstants(JNIEnv* env, jclass c) { initConstant(env, c, "RT_SCOPE_NOWHERE", RT_SCOPE_NOWHERE); initConstant(env, c, "RT_SCOPE_SITE", RT_SCOPE_SITE); initConstant(env, c, "RT_SCOPE_UNIVERSE", RT_SCOPE_UNIVERSE); + initConstant(env, c, "RTMGRP_IPV4_IFADDR", RTMGRP_IPV4_IFADDR); + initConstant(env, c, "RTMGRP_IPV4_MROUTE", RTMGRP_IPV4_MROUTE); + initConstant(env, c, "RTMGRP_IPV4_ROUTE", RTMGRP_IPV4_ROUTE); + initConstant(env, c, "RTMGRP_IPV4_RULE", RTMGRP_IPV4_RULE); + initConstant(env, c, "RTMGRP_IPV6_IFADDR", RTMGRP_IPV6_IFADDR); + initConstant(env, c, "RTMGRP_IPV6_IFINFO", RTMGRP_IPV6_IFINFO); + initConstant(env, c, "RTMGRP_IPV6_MROUTE", RTMGRP_IPV6_MROUTE); + initConstant(env, c, "RTMGRP_IPV6_PREFIX", RTMGRP_IPV6_PREFIX); + initConstant(env, c, "RTMGRP_IPV6_ROUTE", RTMGRP_IPV6_ROUTE); + initConstant(env, c, "RTMGRP_LINK", RTMGRP_LINK); + initConstant(env, c, "RTMGRP_NEIGH", RTMGRP_NEIGH); + initConstant(env, c, "RTMGRP_NOTIFY", RTMGRP_NOTIFY); + initConstant(env, c, "RTMGRP_TC", RTMGRP_TC); #endif initConstant(env, c, "SEEK_CUR", SEEK_CUR); initConstant(env, c, "SEEK_END", SEEK_END); @@ -490,6 +515,15 @@ static void OsConstants_initConstants(JNIEnv* env, jclass c) { initConstant(env, c, "STDERR_FILENO", STDERR_FILENO); initConstant(env, c, "STDIN_FILENO", STDIN_FILENO); initConstant(env, c, "STDOUT_FILENO", STDOUT_FILENO); + initConstant(env, c, "ST_MANDLOCK", ST_MANDLOCK); + initConstant(env, c, "ST_NOATIME", ST_NOATIME); + initConstant(env, c, "ST_NODEV", ST_NODEV); + initConstant(env, c, "ST_NODIRATIME", ST_NODIRATIME); + initConstant(env, c, "ST_NOEXEC", ST_NOEXEC); + initConstant(env, c, "ST_NOSUID", ST_NOSUID); + initConstant(env, c, "ST_RDONLY", ST_RDONLY); + initConstant(env, c, "ST_RELATIME", ST_RELATIME); + initConstant(env, c, "ST_SYNCHRONOUS", ST_SYNCHRONOUS); initConstant(env, c, "S_IFBLK", S_IFBLK); initConstant(env, c, "S_IFCHR", S_IFCHR); initConstant(env, c, "S_IFDIR", S_IFDIR); diff --git a/luni/src/main/native/java_lang_StrictMath.cpp b/luni/src/main/native/java_lang_StrictMath.cpp index cfe375e..e8c6dfb 100644 --- a/luni/src/main/native/java_lang_StrictMath.cpp +++ b/luni/src/main/native/java_lang_StrictMath.cpp @@ -34,26 +34,6 @@ static jdouble StrictMath_tan(JNIEnv*, jclass, jdouble a) { return ieee_tan(a); } -static jdouble StrictMath_asin(JNIEnv*, jclass, jdouble a) { - return ieee_asin(a); -} - -static jdouble StrictMath_acos(JNIEnv*, jclass, jdouble a) { - return ieee_acos(a); -} - -static jdouble StrictMath_atan(JNIEnv*, jclass, jdouble a) { - return ieee_atan(a); -} - -static jdouble StrictMath_exp(JNIEnv*, jclass, jdouble a) { - return ieee_exp(a); -} - -static jdouble StrictMath_log(JNIEnv*, jclass, jdouble a) { - return ieee_log(a); -} - static jdouble StrictMath_sqrt(JNIEnv*, jclass, jdouble a) { return ieee_sqrt(a); } @@ -74,75 +54,30 @@ static jdouble StrictMath_rint(JNIEnv*, jclass, jdouble a) { return ieee_rint(a); } -static jdouble StrictMath_atan2(JNIEnv*, jclass, jdouble a, jdouble b) { - return ieee_atan2(a, b); -} - static jdouble StrictMath_pow(JNIEnv*, jclass, jdouble a, jdouble b) { return ieee_pow(a,b); } -static jdouble StrictMath_sinh(JNIEnv*, jclass, jdouble a) { - return ieee_sinh(a); -} - -static jdouble StrictMath_tanh(JNIEnv*, jclass, jdouble a) { - return ieee_tanh(a); -} - -static jdouble StrictMath_cosh(JNIEnv*, jclass, jdouble a) { - return ieee_cosh(a); -} - -static jdouble StrictMath_log10(JNIEnv*, jclass, jdouble a) { - return ieee_log10(a); -} - -static jdouble StrictMath_cbrt(JNIEnv*, jclass, jdouble a) { - return ieee_cbrt(a); -} - -static jdouble StrictMath_expm1(JNIEnv*, jclass, jdouble a) { - return ieee_expm1(a); -} - static jdouble StrictMath_hypot(JNIEnv*, jclass, jdouble a, jdouble b) { return ieee_hypot(a, b); } -static jdouble StrictMath_log1p(JNIEnv*, jclass, jdouble a) { - return ieee_log1p(a); -} - static jdouble StrictMath_nextafter(JNIEnv*, jclass, jdouble a, jdouble b) { return ieee_nextafter(a, b); } static JNINativeMethod gMethods[] = { NATIVE_METHOD(StrictMath, IEEEremainder, "!(DD)D"), - NATIVE_METHOD(StrictMath, acos, "!(D)D"), - NATIVE_METHOD(StrictMath, asin, "!(D)D"), - NATIVE_METHOD(StrictMath, atan, "!(D)D"), - NATIVE_METHOD(StrictMath, atan2, "!(DD)D"), - NATIVE_METHOD(StrictMath, cbrt, "!(D)D"), NATIVE_METHOD(StrictMath, ceil, "!(D)D"), NATIVE_METHOD(StrictMath, cos, "!(D)D"), - NATIVE_METHOD(StrictMath, cosh, "!(D)D"), - NATIVE_METHOD(StrictMath, exp, "!(D)D"), - NATIVE_METHOD(StrictMath, expm1, "!(D)D"), NATIVE_METHOD(StrictMath, floor, "!(D)D"), NATIVE_METHOD(StrictMath, hypot, "!(DD)D"), - NATIVE_METHOD(StrictMath, log, "!(D)D"), - NATIVE_METHOD(StrictMath, log10, "!(D)D"), - NATIVE_METHOD(StrictMath, log1p, "!(D)D"), NATIVE_METHOD(StrictMath, nextafter, "!(DD)D"), NATIVE_METHOD(StrictMath, pow, "!(DD)D"), NATIVE_METHOD(StrictMath, rint, "!(D)D"), NATIVE_METHOD(StrictMath, sin, "!(D)D"), - NATIVE_METHOD(StrictMath, sinh, "!(D)D"), NATIVE_METHOD(StrictMath, sqrt, "!(D)D"), NATIVE_METHOD(StrictMath, tan, "!(D)D"), - NATIVE_METHOD(StrictMath, tanh, "!(D)D"), }; void register_java_lang_StrictMath(JNIEnv* env) { jniRegisterNativeMethods(env, "java/lang/StrictMath", gMethods, NELEM(gMethods)); diff --git a/luni/src/main/native/java_lang_StringToReal.cpp b/luni/src/main/native/java_lang_StringToReal.cpp index 108f939..d1902af 100644 --- a/luni/src/main/native/java_lang_StringToReal.cpp +++ b/luni/src/main/native/java_lang_StringToReal.cpp @@ -25,9 +25,6 @@ #include "cbigint.h" /* ************************* Defines ************************* */ -#if defined(__linux__) || defined(__APPLE__) -#define USE_LL -#endif #define LOW_I32_FROM_VAR(u64) LOW_I32_FROM_LONG64(u64) #define LOW_I32_FROM_PTR(u64ptr) LOW_I32_FROM_LONG64_PTR(u64ptr) @@ -38,69 +35,13 @@ #define DEFAULT_DOUBLE_WIDTH MAX_DOUBLE_ACCURACY_WIDTH -#if defined(USE_LL) #define DOUBLE_INFINITE_LONGBITS (0x7FF0000000000000LL) -#else -#if defined(USE_L) -#define DOUBLE_INFINITE_LONGBITS (0x7FF0000000000000L) -#else -#define DOUBLE_INFINITE_LONGBITS (0x7FF0000000000000) -#endif /* USE_L */ -#endif /* USE_LL */ #define DOUBLE_MINIMUM_LONGBITS (0x1) -#if defined(USE_LL) #define DOUBLE_MANTISSA_MASK (0x000FFFFFFFFFFFFFLL) #define DOUBLE_EXPONENT_MASK (0x7FF0000000000000LL) #define DOUBLE_NORMAL_MASK (0x0010000000000000LL) -#else -#if defined(USE_L) -#define DOUBLE_MANTISSA_MASK (0x000FFFFFFFFFFFFFL) -#define DOUBLE_EXPONENT_MASK (0x7FF0000000000000L) -#define DOUBLE_NORMAL_MASK (0x0010000000000000L) -#else -#define DOUBLE_MANTISSA_MASK (0x000FFFFFFFFFFFFF) -#define DOUBLE_EXPONENT_MASK (0x7FF0000000000000) -#define DOUBLE_NORMAL_MASK (0x0010000000000000) -#endif /* USE_L */ -#endif /* USE_LL */ - -/* Keep a count of the number of times we decrement and increment to - * approximate the double, and attempt to detect the case where we - * could potentially toggle back and forth between decrementing and - * incrementing. It is possible for us to be stuck in the loop when - * incrementing by one or decrementing by one may exceed or stay below - * the value that we are looking for. In this case, just break out of - * the loop if we toggle between incrementing and decrementing for more - * than twice. - */ -#define INCREMENT_DOUBLE(_x, _decCount, _incCount) \ - { \ - ++DOUBLE_TO_LONGBITS(_x); \ - _incCount++; \ - if( (_incCount > 2) && (_decCount > 2) ) { \ - if( _decCount > _incCount ) { \ - DOUBLE_TO_LONGBITS(_x) += _decCount - _incCount; \ - } else if( _incCount > _decCount ) { \ - DOUBLE_TO_LONGBITS(_x) -= _incCount - _decCount; \ - } \ - break; \ - } \ - } -#define DECREMENT_DOUBLE(_x, _decCount, _incCount) \ - { \ - --DOUBLE_TO_LONGBITS(_x); \ - _decCount++; \ - if( (_incCount > 2) && (_decCount > 2) ) { \ - if( _decCount > _incCount ) { \ - DOUBLE_TO_LONGBITS(_x) += _decCount - _incCount; \ - } else if( _incCount > _decCount ) { \ - DOUBLE_TO_LONGBITS(_x) -= _incCount - _decCount; \ - } \ - break; \ - } \ - } #define allocateU64(x, n) if (!((x) = reinterpret_cast<uint64_t*>(malloc((n) * sizeof(uint64_t))))) goto OutOfMemory; @@ -248,7 +189,6 @@ static jdouble createDouble(JNIEnv* env, const char* s, jint e) { } return result; - } static jdouble createDouble1(JNIEnv* env, uint64_t* f, int32_t length, jint e) { @@ -310,7 +250,6 @@ static jdouble createDouble1(JNIEnv* env, uint64_t* f, int32_t length, jint e) { first and let it fall to zero if need be. */ if (result == 0.0) - DOUBLE_TO_LONGBITS (result) = DOUBLE_MINIMUM_LONGBITS; return doubleAlgorithm (env, f, length, e, result); @@ -323,15 +262,6 @@ static jdouble createDouble1(JNIEnv* env, uint64_t* f, int32_t length, jint e) { * Clinger, Proceedings of the ACM SIGPLAN '90 Conference on * Programming Language Design and Implementation, June 20-22, * 1990, pp. 92-101. - * - * There is a possibility that the function will end up in an endless - * loop if the given approximating floating-point number (a very small - * floating-point whose value is very close to zero) straddles between - * two approximating integer values. We modified the algorithm slightly - * to detect the case where it oscillates back and forth between - * incrementing and decrementing the floating-point approximation. It - * is currently set such that if the oscillation occurs more than twice - * then return the original approximation. */ static jdouble doubleAlgorithm(JNIEnv* env, uint64_t* f, int32_t length, jint e, jdouble z) { uint64_t m; @@ -340,11 +270,10 @@ static jdouble doubleAlgorithm(JNIEnv* env, uint64_t* f, int32_t length, jint e, uint64_t* y; uint64_t* D; uint64_t* D2; - int32_t xLength, yLength, DLength, D2Length, decApproxCount, incApproxCount; + int32_t xLength, yLength, DLength, D2Length; x = y = D = D2 = 0; xLength = yLength = DLength = D2Length = 0; - decApproxCount = incApproxCount = 0; do { @@ -443,12 +372,13 @@ static jdouble doubleAlgorithm(JNIEnv* env, uint64_t* f, int32_t length, jint e, comparison2 = compareHighPrecision (D2, D2Length, y, yLength); if (comparison2 < 0) { - if (comparison < 0 && m == DOUBLE_NORMAL_MASK) + if (comparison < 0 && m == DOUBLE_NORMAL_MASK + && DOUBLE_TO_LONGBITS(z) != DOUBLE_NORMAL_MASK) { simpleShiftLeftHighPrecision (D2, D2Length, 1); if (compareHighPrecision (D2, D2Length, y, yLength) > 0) { - DECREMENT_DOUBLE (z, decApproxCount, incApproxCount); + --DOUBLE_TO_LONGBITS (z); } else { @@ -466,7 +396,7 @@ static jdouble doubleAlgorithm(JNIEnv* env, uint64_t* f, int32_t length, jint e, { if (comparison < 0 && m == DOUBLE_NORMAL_MASK) { - DECREMENT_DOUBLE (z, decApproxCount, incApproxCount); + --DOUBLE_TO_LONGBITS (z); } else { @@ -475,24 +405,24 @@ static jdouble doubleAlgorithm(JNIEnv* env, uint64_t* f, int32_t length, jint e, } else if (comparison < 0) { - DECREMENT_DOUBLE (z, decApproxCount, incApproxCount); + --DOUBLE_TO_LONGBITS (z); break; } else { - INCREMENT_DOUBLE (z, decApproxCount, incApproxCount); + ++DOUBLE_TO_LONGBITS (z); break; } } else if (comparison < 0) { - DECREMENT_DOUBLE (z, decApproxCount, incApproxCount); + --DOUBLE_TO_LONGBITS (z); } else { if (DOUBLE_TO_LONGBITS (z) == DOUBLE_INFINITE_LONGBITS) break; - INCREMENT_DOUBLE (z, decApproxCount, incApproxCount); + ++DOUBLE_TO_LONGBITS (z); } } while (1); @@ -547,42 +477,6 @@ static const uint32_t float_tens[] = { #define FLOAT_EXPONENT_MASK (0x7F800000) #define FLOAT_NORMAL_MASK (0x00800000) -/* Keep a count of the number of times we decrement and increment to - * approximate the double, and attempt to detect the case where we - * could potentially toggle back and forth between decrementing and - * incrementing. It is possible for us to be stuck in the loop when - * incrementing by one or decrementing by one may exceed or stay below - * the value that we are looking for. In this case, just break out of - * the loop if we toggle between incrementing and decrementing for more - * than twice. - */ -#define INCREMENT_FLOAT(_x, _decCount, _incCount) \ - { \ - ++FLOAT_TO_INTBITS(_x); \ - _incCount++; \ - if( (_incCount > 2) && (_decCount > 2) ) { \ - if( _decCount > _incCount ) { \ - FLOAT_TO_INTBITS(_x) += _decCount - _incCount; \ - } else if( _incCount > _decCount ) { \ - FLOAT_TO_INTBITS(_x) -= _incCount - _decCount; \ - } \ - break; \ - } \ - } -#define DECREMENT_FLOAT(_x, _decCount, _incCount) \ - { \ - --FLOAT_TO_INTBITS(_x); \ - _decCount++; \ - if( (_incCount > 2) && (_decCount > 2) ) { \ - if( _decCount > _incCount ) { \ - FLOAT_TO_INTBITS(_x) += _decCount - _incCount; \ - } else if( _incCount > _decCount ) { \ - FLOAT_TO_INTBITS(_x) -= _incCount - _decCount; \ - } \ - break; \ - } \ - } - static jfloat createFloat(JNIEnv* env, const char* s, jint e) { /* assumes s is a null terminated string with at least one * character in it */ @@ -682,7 +576,6 @@ static jfloat createFloat(JNIEnv* env, const char* s, jint e) { } return result; - } static jfloat createFloat1 (JNIEnv* env, uint64_t* f, int32_t length, jint e) { @@ -796,15 +689,6 @@ static jfloat createFloat1 (JNIEnv* env, uint64_t* f, int32_t length, jint e) { * Clinger, Proceedings of the ACM SIGPLAN '90 Conference on * Programming Language Design and Implementation, June 20-22, * 1990, pp. 92-101. - * - * There is a possibility that the function will end up in an endless - * loop if the given approximating floating-point number (a very small - * floating-point whose value is very close to zero) straddles between - * two approximating integer values. We modified the algorithm slightly - * to detect the case where it oscillates back and forth between - * incrementing and decrementing the floating-point approximation. It - * is currently set such that if the oscillation occurs more than twice - * then return the original approximation. */ static jfloat floatAlgorithm(JNIEnv* env, uint64_t* f, int32_t length, jint e, jfloat z) { uint64_t m; @@ -814,11 +698,9 @@ static jfloat floatAlgorithm(JNIEnv* env, uint64_t* f, int32_t length, jint e, j uint64_t* D; uint64_t* D2; int32_t xLength, yLength, DLength, D2Length; - int32_t decApproxCount, incApproxCount; x = y = D = D2 = 0; xLength = yLength = DLength = D2Length = 0; - decApproxCount = incApproxCount = 0; do { @@ -917,12 +799,13 @@ static jfloat floatAlgorithm(JNIEnv* env, uint64_t* f, int32_t length, jint e, j comparison2 = compareHighPrecision (D2, D2Length, y, yLength); if (comparison2 < 0) { - if (comparison < 0 && m == FLOAT_NORMAL_MASK) + if (comparison < 0 && m == FLOAT_NORMAL_MASK + && FLOAT_TO_INTBITS(z) != FLOAT_NORMAL_MASK) { simpleShiftLeftHighPrecision (D2, D2Length, 1); if (compareHighPrecision (D2, D2Length, y, yLength) > 0) { - DECREMENT_FLOAT (z, decApproxCount, incApproxCount); + --FLOAT_TO_INTBITS (z); } else { @@ -940,7 +823,7 @@ static jfloat floatAlgorithm(JNIEnv* env, uint64_t* f, int32_t length, jint e, j { if (comparison < 0 && m == FLOAT_NORMAL_MASK) { - DECREMENT_FLOAT (z, decApproxCount, incApproxCount); + --FLOAT_TO_INTBITS (z); } else { @@ -949,24 +832,24 @@ static jfloat floatAlgorithm(JNIEnv* env, uint64_t* f, int32_t length, jint e, j } else if (comparison < 0) { - DECREMENT_FLOAT (z, decApproxCount, incApproxCount); + --FLOAT_TO_INTBITS (z); break; } else { - INCREMENT_FLOAT (z, decApproxCount, incApproxCount); + ++FLOAT_TO_INTBITS (z); break; } } else if (comparison < 0) { - DECREMENT_FLOAT (z, decApproxCount, incApproxCount); + --FLOAT_TO_INTBITS (z); } else { if (FLOAT_TO_INTBITS (z) == FLOAT_EXPONENT_MASK) break; - INCREMENT_FLOAT (z, decApproxCount, incApproxCount); + ++FLOAT_TO_INTBITS (z); } } while (1); diff --git a/luni/src/main/native/java_lang_System.cpp b/luni/src/main/native/java_lang_System.cpp index 944c0c3..306adab 100644 --- a/luni/src/main/native/java_lang_System.cpp +++ b/luni/src/main/native/java_lang_System.cpp @@ -84,7 +84,11 @@ static jobjectArray System_specialProperties(JNIEnv* env, jclass) { properties.push_back(std::string("user.dir=") + getcwd(path, sizeof(path))); properties.push_back("android.zlib.version=" ZLIB_VERSION); +#if defined(OPENSSL_IS_BORINGSSL) + properties.push_back("android.openssl.version=BoringSSL"); +#else properties.push_back("android.openssl.version=" OPENSSL_VERSION_TEXT); +#endif const char* library_path = getenv("LD_LIBRARY_PATH"); #if defined(HAVE_ANDROID_OS) @@ -109,33 +113,20 @@ static jlong System_currentTimeMillis(JNIEnv*, jclass) { } static jlong System_nanoTime(JNIEnv*, jclass) { -#if defined(HAVE_POSIX_CLOCKS) +#if defined(__linux__) timespec now; clock_gettime(CLOCK_MONOTONIC, &now); return now.tv_sec * 1000000000LL + now.tv_nsec; -#else +#else // __APPLE__ timeval now; gettimeofday(&now, NULL); return static_cast<jlong>(now.tv_sec) * 1000000000LL + now.tv_usec * 1000LL; #endif } -static jstring System_mapLibraryName(JNIEnv* env, jclass, jstring javaName) { - ScopedUtfChars name(env, javaName); - if (name.c_str() == NULL) { - return NULL; - } - char* mappedName = NULL; - asprintf(&mappedName, OS_SHARED_LIB_FORMAT_STR, name.c_str()); - jstring result = env->NewStringUTF(mappedName); - free(mappedName); - return result; -} - static JNINativeMethod gMethods[] = { NATIVE_METHOD(System, currentTimeMillis, "!()J"), NATIVE_METHOD(System, log, "(CLjava/lang/String;Ljava/lang/Throwable;)V"), - NATIVE_METHOD(System, mapLibraryName, "(Ljava/lang/String;)Ljava/lang/String;"), NATIVE_METHOD(System, nanoTime, "!()J"), NATIVE_METHOD(System, setFieldImpl, "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)V"), NATIVE_METHOD(System, specialProperties, "()[Ljava/lang/String;"), diff --git a/luni/src/main/native/java_math_NativeBN.cpp b/luni/src/main/native/java_math_NativeBN.cpp index be87ea6..7e77e23 100644 --- a/luni/src/main/native/java_math_NativeBN.cpp +++ b/luni/src/main/native/java_math_NativeBN.cpp @@ -21,19 +21,31 @@ #include "JniException.h" #include "ScopedPrimitiveArray.h" #include "ScopedUtfChars.h" -#include "UniquePtr.h" #include "jni.h" #include <openssl/bn.h> #include <openssl/crypto.h> #include <openssl/err.h> #include <stdio.h> +#include <memory> + +#if defined(OPENSSL_IS_BORINGSSL) +/* BoringSSL no longer exports |bn_check_top|. */ +static void bn_check_top(const BIGNUM* bn) { + /* This asserts that |bn->top| (which contains the number of elements of + * |bn->d| that are valid) is minimal. In other words, that there aren't + * superfluous zeros. */ + if (bn != NULL && bn->top != 0 && bn->d[bn->top-1] == 0) { + abort(); + } +} +#endif struct BN_CTX_Deleter { void operator()(BN_CTX* p) const { BN_CTX_free(p); } }; -typedef UniquePtr<BN_CTX, BN_CTX_Deleter> Unique_BN_CTX; +typedef std::unique_ptr<BN_CTX, BN_CTX_Deleter> Unique_BN_CTX; static BIGNUM* toBigNum(jlong address) { return reinterpret_cast<BIGNUM*>(static_cast<uintptr_t>(address)); @@ -109,28 +121,32 @@ static void NativeBN_BN_copy(JNIEnv* env, jclass, jlong to, jlong from) { } static void NativeBN_putULongInt(JNIEnv* env, jclass, jlong a0, jlong java_dw, jboolean neg) { - if (!oneValidHandle(env, a0)) return; + if (!oneValidHandle(env, a0)) return; - uint64_t dw = java_dw; + uint64_t dw = java_dw; + BIGNUM* a = toBigNum(a0); + int ok; - // cf. litEndInts2bn: - BIGNUM* a = toBigNum(a0); - bn_check_top(a); - if (bn_wexpand(a, 8/BN_BYTES) != NULL) { -#ifdef __LP64__ + static_assert(sizeof(dw) == sizeof(BN_ULONG) || + sizeof(dw) == 2*sizeof(BN_ULONG), "Unknown BN configuration"); + + if (sizeof(dw) == sizeof(BN_ULONG)) { + ok = BN_set_word(a, dw); + } else if (sizeof(dw) == 2 * sizeof(BN_ULONG)) { + ok = (bn_wexpand(a, 2) != NULL); + if (ok) { a->d[0] = dw; -#else - unsigned int hi = dw >> 32; // This shifts without sign extension. - int lo = (int)dw; // This truncates implicitly. - a->d[0] = lo; - a->d[1] = hi; -#endif - a->top = 8 / BN_BYTES; - a->neg = neg; + a->d[1] = dw >> 32; + a->top = 2; bn_correct_top(a); - } else { - throwExceptionIfNecessary(env); } + } + + BN_set_negative(a, neg); + + if (!ok) { + throwExceptionIfNecessary(env); + } } static void NativeBN_putLongInt(JNIEnv* env, jclass cls, jlong a, jlong dw) { @@ -240,25 +256,25 @@ static void negBigEndianBytes2bn(JNIEnv*, jclass, const unsigned char* bytes, in bn_check_top(ret); // FIXME: assert bytesLen > 0 - int wLen = (bytesLen + BN_BYTES - 1) / BN_BYTES; + int wLen = (bytesLen + sizeof(BN_ULONG) - 1) / sizeof(BN_ULONG); int firstNonzeroDigit = -2; if (bn_wexpand(ret, wLen) != NULL) { BN_ULONG* d = ret->d; BN_ULONG di; ret->top = wLen; - int highBytes = bytesLen % BN_BYTES; + int highBytes = bytesLen % sizeof(BN_ULONG); int k = bytesLen; // Put bytes to the int array starting from the end of the byte array int i = 0; while (k > highBytes) { - k -= BN_BYTES; + k -= sizeof(BN_ULONG); di = BYTES2ULONG(bytes, k); if (di != 0) { d[i] = -di; firstNonzeroDigit = i; i++; while (k > highBytes) { - k -= BN_BYTES; + k -= sizeof(BN_ULONG); d[i] = ~BYTES2ULONG(bytes, k); i++; } @@ -394,7 +410,7 @@ static jintArray NativeBN_bn2litEndInts(JNIEnv* env, jclass, jlong a0) { if (wLen == 0) { return NULL; } - jintArray result = env->NewIntArray(wLen * BN_BYTES/sizeof(unsigned int)); + jintArray result = env->NewIntArray(wLen * sizeof(BN_ULONG)/sizeof(unsigned int)); if (result == NULL) { return NULL; } @@ -445,7 +461,7 @@ static int NativeBN_bitLength(JNIEnv* env, jclass, jlong a0) { do { i--; } while (!((i < 0) || (d[i] != 0))); if (i < 0) msd--; // Only if all lower significant digits are 0 we decrement the most significant one. } - return (wLen - 1) * BN_BYTES * 8 + BN_num_bits_word(msd); + return (wLen - 1) * sizeof(BN_ULONG) * 8 + BN_num_bits_word(msd); } static jboolean NativeBN_BN_is_bit_set(JNIEnv* env, jclass, jlong a, int n) { diff --git a/luni/src/main/native/java_text_Bidi.cpp b/luni/src/main/native/java_text_Bidi.cpp index d9ef35d..6a3e751 100644 --- a/luni/src/main/native/java_text_Bidi.cpp +++ b/luni/src/main/native/java_text_Bidi.cpp @@ -22,14 +22,14 @@ #include "JniConstants.h" #include "JniException.h" #include "ScopedPrimitiveArray.h" -#include "UniquePtr.h" #include "unicode/ubidi.h" #include <stdlib.h> #include <string.h> +#include <memory> struct BiDiData { - BiDiData(UBiDi* biDi) : mBiDi(biDi), mEmbeddingLevels(NULL) { + BiDiData(UBiDi* biDi) : mBiDi(biDi) { } ~BiDiData() { @@ -50,7 +50,7 @@ struct BiDiData { private: UBiDi* mBiDi; - UniquePtr<jbyte[]> mEmbeddingLevels; + std::unique_ptr<jbyte[]> mEmbeddingLevels; // Disallow copy and assignment. BiDiData(const BiDiData&); @@ -98,7 +98,7 @@ static jlong Bidi_ubidi_setLine(JNIEnv* env, jclass, jlong ptr, jint start, jint if (maybeThrowIcuException(env, "ubidi_openSized", status)) { return 0; } - UniquePtr<BiDiData> lineData(new BiDiData(sized)); + std::unique_ptr<BiDiData> lineData(new BiDiData(sized)); ubidi_setLine(uBiDi(ptr), start, limit, lineData->uBiDi(), &status); maybeThrowIcuException(env, "ubidi_setLine", status); return reinterpret_cast<uintptr_t>(lineData.release()); @@ -168,7 +168,7 @@ static jintArray Bidi_ubidi_reorderVisual(JNIEnv* env, jclass, jbyteArray javaLe const UBiDiLevel* levels = reinterpret_cast<const UBiDiLevel*>(levelBytes.get()); - UniquePtr<int[]> indexMap(new int[length]); + std::unique_ptr<int[]> indexMap(new int[length]); ubidi_reorderVisual(levels, length, &indexMap[0]); jintArray result = env->NewIntArray(length); diff --git a/luni/src/main/native/java_util_jar_StrictJarFile.cpp b/luni/src/main/native/java_util_jar_StrictJarFile.cpp index efcc74c..82547bd 100644 --- a/luni/src/main/native/java_util_jar_StrictJarFile.cpp +++ b/luni/src/main/native/java_util_jar_StrictJarFile.cpp @@ -17,49 +17,26 @@ #define LOG_TAG "StrictJarFile" +#include <memory> #include <string> #include "JNIHelp.h" #include "JniConstants.h" #include "ScopedLocalRef.h" #include "ScopedUtfChars.h" -#include "UniquePtr.h" #include "jni.h" #include "ziparchive/zip_archive.h" #include "cutils/log.h" +// The method ID for ZipEntry.<init>(String,String,JJJIII[BJJ) +static jmethodID zipEntryCtor; + static void throwIoException(JNIEnv* env, const int32_t errorCode) { jniThrowException(env, "java/io/IOException", ErrorCodeString(errorCode)); } -// Constructs a string out of |name| with the default charset (UTF-8 on android). -// We prefer this to JNI's NewStringUTF because the string constructor will -// replace unmappable and malformed bytes instead of throwing. See b/18584205 -// -// Returns |NULL| iff. we couldn't allocate the string object or its constructor -// arguments. -// -// TODO: switch back to NewStringUTF after libziparchive is modified to reject -// files whose names aren't valid UTF-8. -static jobject constructString(JNIEnv* env, const char* name, const uint16_t nameLength) { - jbyteArray javaNameBytes = env->NewByteArray(nameLength); - if (javaNameBytes == NULL) { - return NULL; - } - env->SetByteArrayRegion(javaNameBytes, 0, nameLength, reinterpret_cast<const jbyte*>(name)); - - ScopedLocalRef<jclass> stringClass(env, env->FindClass("java/lang/String")); - const jmethodID stringCtor = env->GetMethodID(stringClass.get(), "<init>", "([B)V"); - return env->NewObject(stringClass.get(), stringCtor, javaNameBytes); -} - -static jobject newZipEntry(JNIEnv* env, const ZipEntry& entry, const jobject entryName, - const uint16_t nameLength) { - ScopedLocalRef<jclass> zipEntryClass(env, env->FindClass("java/util/zip/ZipEntry")); - const jmethodID zipEntryCtor = env->GetMethodID(zipEntryClass.get(), "<init>", - "(Ljava/lang/String;Ljava/lang/String;JJJIII[BIJJ)V"); - - return env->NewObject(zipEntryClass.get(), +static jobject newZipEntry(JNIEnv* env, const ZipEntry& entry, jstring entryName) { + return env->NewObject(JniConstants::zipEntryClass, zipEntryCtor, entryName, NULL, // comment @@ -70,16 +47,10 @@ static jobject newZipEntry(JNIEnv* env, const ZipEntry& entry, const jobject ent static_cast<jint>(0), // time static_cast<jint>(0), // modData NULL, // byte[] extra - static_cast<jint>(nameLength), static_cast<jlong>(-1), // local header offset static_cast<jlong>(entry.offset)); } -static jobject newZipEntry(JNIEnv* env, const ZipEntry& entry, const char* name, - const uint16_t nameLength) { - return newZipEntry(env, entry, constructString(env, name, nameLength), nameLength); -} - static jlong StrictJarFile_nativeOpenJarFile(JNIEnv* env, jobject, jstring fileName) { ScopedUtfChars fileChars(env, fileName); if (fileChars.c_str() == NULL) { @@ -98,25 +69,20 @@ static jlong StrictJarFile_nativeOpenJarFile(JNIEnv* env, jobject, jstring fileN class IterationHandle { public: - IterationHandle(const char* prefix) : - cookie_(NULL), prefix_(strdup(prefix)) { + IterationHandle() : + cookie_(NULL) { } void** CookieAddress() { return &cookie_; } - const char* Prefix() const { - return prefix_; - } - ~IterationHandle() { - free(prefix_); + EndIteration(cookie_); } private: void* cookie_; - char* prefix_; }; @@ -127,14 +93,15 @@ static jlong StrictJarFile_nativeStartIteration(JNIEnv* env, jobject, jlong nati return static_cast<jlong>(-1); } - IterationHandle* handle = new IterationHandle(prefixChars.c_str()); + IterationHandle* handle = new IterationHandle(); int32_t error = 0; if (prefixChars.size() == 0) { error = StartIteration(reinterpret_cast<ZipArchiveHandle>(nativeHandle), handle->CookieAddress(), NULL); } else { + ZipEntryName entry_name(prefixChars.c_str()); error = StartIteration(reinterpret_cast<ZipArchiveHandle>(nativeHandle), - handle->CookieAddress(), handle->Prefix()); + handle->CookieAddress(), &entry_name); } if (error) { @@ -156,11 +123,12 @@ static jobject StrictJarFile_nativeNextEntry(JNIEnv* env, jobject, jlong iterati return NULL; } - UniquePtr<char[]> entryNameCString(new char[entryName.name_length + 1]); + std::unique_ptr<char[]> entryNameCString(new char[entryName.name_length + 1]); memcpy(entryNameCString.get(), entryName.name, entryName.name_length); entryNameCString[entryName.name_length] = '\0'; + ScopedLocalRef<jstring> entryNameString(env, env->NewStringUTF(entryNameCString.get())); - return newZipEntry(env, data, entryNameCString.get(), entryName.name_length); + return newZipEntry(env, data, entryNameString.get()); } static jobject StrictJarFile_nativeFindEntry(JNIEnv* env, jobject, jlong nativeHandle, @@ -172,12 +140,12 @@ static jobject StrictJarFile_nativeFindEntry(JNIEnv* env, jobject, jlong nativeH ZipEntry data; const int32_t error = FindEntry(reinterpret_cast<ZipArchiveHandle>(nativeHandle), - entryNameChars.c_str(), &data); + ZipEntryName(entryNameChars.c_str()), &data); if (error) { return NULL; } - return newZipEntry(env, data, entryName, entryNameChars.size()); + return newZipEntry(env, data, entryName); } static void StrictJarFile_nativeClose(JNIEnv*, jobject, jlong nativeHandle) { @@ -194,4 +162,8 @@ static JNINativeMethod gMethods[] = { void register_java_util_jar_StrictJarFile(JNIEnv* env) { jniRegisterNativeMethods(env, "java/util/jar/StrictJarFile", gMethods, NELEM(gMethods)); + + zipEntryCtor = env->GetMethodID(JniConstants::zipEntryClass, "<init>", + "(Ljava/lang/String;Ljava/lang/String;JJJIII[BJJ)V"); + LOG_ALWAYS_FATAL_IF(zipEntryCtor == NULL, "Unable to find ZipEntry.<init>"); } diff --git a/luni/src/main/native/java_util_regex_Matcher.cpp b/luni/src/main/native/java_util_regex_Matcher.cpp index 2e5259e..35d014c 100644 --- a/luni/src/main/native/java_util_regex_Matcher.cpp +++ b/luni/src/main/native/java_util_regex_Matcher.cpp @@ -23,15 +23,14 @@ #include "JniConstants.h" #include "JniException.h" #include "ScopedPrimitiveArray.h" -#include "UniquePtr.h" #include "jni.h" #include "unicode/parseerr.h" #include "unicode/regex.h" // ICU documentation: http://icu-project.org/apiref/icu4c/classRegexMatcher.html -static RegexMatcher* toRegexMatcher(jlong address) { - return reinterpret_cast<RegexMatcher*>(static_cast<uintptr_t>(address)); +static icu::RegexMatcher* toRegexMatcher(jlong address) { + return reinterpret_cast<icu::RegexMatcher*>(static_cast<uintptr_t>(address)); } /** @@ -75,7 +74,7 @@ public: maybeThrowIcuException(mEnv, "utext_close", mStatus); } - RegexMatcher* operator->() { + icu::RegexMatcher* operator->() { return mMatcher; } @@ -107,7 +106,7 @@ private: JNIEnv* mEnv; jstring mJavaInput; - RegexMatcher* mMatcher; + icu::RegexMatcher* mMatcher; const jchar* mChars; UErrorCode mStatus; UText* mUText; @@ -171,9 +170,9 @@ static jint Matcher_matchesImpl(JNIEnv* env, jclass, jlong addr, jstring javaTex } static jlong Matcher_openImpl(JNIEnv* env, jclass, jlong patternAddr) { - RegexPattern* pattern = reinterpret_cast<RegexPattern*>(static_cast<uintptr_t>(patternAddr)); + icu::RegexPattern* pattern = reinterpret_cast<icu::RegexPattern*>(static_cast<uintptr_t>(patternAddr)); UErrorCode status = U_ZERO_ERROR; - RegexMatcher* result = pattern->matcher(status); + icu::RegexMatcher* result = pattern->matcher(status); maybeThrowIcuException(env, "RegexPattern::matcher", status); return reinterpret_cast<uintptr_t>(result); } diff --git a/luni/src/main/native/java_util_regex_Pattern.cpp b/luni/src/main/native/java_util_regex_Pattern.cpp index 1a99d0a..f2c07dc 100644 --- a/luni/src/main/native/java_util_regex_Pattern.cpp +++ b/luni/src/main/native/java_util_regex_Pattern.cpp @@ -27,8 +27,8 @@ // ICU documentation: http://icu-project.org/apiref/icu4c/classRegexPattern.html -static RegexPattern* toRegexPattern(jlong addr) { - return reinterpret_cast<RegexPattern*>(static_cast<uintptr_t>(addr)); +static icu::RegexPattern* toRegexPattern(jlong addr) { + return reinterpret_cast<icu::RegexPattern*>(static_cast<uintptr_t>(addr)); } static const char* regexDetailMessage(UErrorCode status) { @@ -86,8 +86,8 @@ static jlong Pattern_compileImpl(JNIEnv* env, jclass, jstring javaRegex, jint fl if (!regex.valid()) { return 0; } - UnicodeString& regexString(regex.unicodeString()); - RegexPattern* result = RegexPattern::compile(regexString, flags, error, status); + icu::UnicodeString& regexString(regex.unicodeString()); + icu::RegexPattern* result = icu::RegexPattern::compile(regexString, flags, error, status); if (!U_SUCCESS(status)) { throwPatternSyntaxException(env, status, javaRegex, error); } diff --git a/luni/src/main/native/java_util_zip_Deflater.cpp b/luni/src/main/native/java_util_zip_Deflater.cpp index 1afd36e..d963824 100644 --- a/luni/src/main/native/java_util_zip_Deflater.cpp +++ b/luni/src/main/native/java_util_zip_Deflater.cpp @@ -28,11 +28,11 @@ static void Deflater_setDictionaryImpl(JNIEnv* env, jobject, jbyteArray dict, in } static jlong Deflater_getTotalInImpl(JNIEnv*, jobject, jlong handle) { - return toNativeZipStream(handle)->stream.total_in; + return toNativeZipStream(handle)->totalIn; } static jlong Deflater_getTotalOutImpl(JNIEnv*, jobject, jlong handle) { - return toNativeZipStream(handle)->stream.total_out; + return toNativeZipStream(handle)->totalOut; } static jint Deflater_getAdlerImpl(JNIEnv*, jobject, jlong handle) { @@ -40,7 +40,7 @@ static jint Deflater_getAdlerImpl(JNIEnv*, jobject, jlong handle) { } static jlong Deflater_createStream(JNIEnv * env, jobject, jint level, jint strategy, jboolean noHeader) { - UniquePtr<NativeZipStream> jstream(new NativeZipStream); + std::unique_ptr<NativeZipStream> jstream(new NativeZipStream); if (jstream.get() == NULL) { jniThrowOutOfMemoryError(env, NULL); return -1; @@ -101,6 +101,9 @@ static jint Deflater_deflateImpl(JNIEnv* env, jobject recv, jbyteArray buf, int jint bytesRead = stream->stream.next_in - initialNextIn; jint bytesWritten = stream->stream.next_out - initialNextOut; + stream->totalIn += bytesRead; + stream->totalOut += bytesWritten; + static jfieldID inReadField = env->GetFieldID(JniConstants::deflaterClass, "inRead", "I"); jint inReadValue = env->GetIntField(recv, inReadField); inReadValue += bytesRead; @@ -116,6 +119,8 @@ static void Deflater_endImpl(JNIEnv*, jobject, jlong handle) { static void Deflater_resetImpl(JNIEnv* env, jobject, jlong handle) { NativeZipStream* stream = toNativeZipStream(handle); + stream->totalIn = 0; + stream->totalOut = 0; int err = deflateReset(&stream->stream); if (err != Z_OK) { throwExceptionForZlibError(env, "java/lang/IllegalArgumentException", err, stream); diff --git a/luni/src/main/native/java_util_zip_Inflater.cpp b/luni/src/main/native/java_util_zip_Inflater.cpp index ca3ee09..f0878ff 100644 --- a/luni/src/main/native/java_util_zip_Inflater.cpp +++ b/luni/src/main/native/java_util_zip_Inflater.cpp @@ -25,7 +25,7 @@ #include <errno.h> static jlong Inflater_createStream(JNIEnv* env, jobject, jboolean noHeader) { - UniquePtr<NativeZipStream> jstream(new NativeZipStream); + std::unique_ptr<NativeZipStream> jstream(new NativeZipStream); if (jstream.get() == NULL) { jniThrowOutOfMemoryError(env, NULL); return -1; @@ -122,6 +122,9 @@ static jint Inflater_inflateImpl(JNIEnv* env, jobject recv, jbyteArray buf, int jint bytesRead = stream->stream.next_in - initialNextIn; jint bytesWritten = stream->stream.next_out - initialNextOut; + stream->totalIn += bytesRead; + stream->totalOut += bytesWritten; + static jfieldID inReadField = env->GetFieldID(JniConstants::inflaterClass, "inRead", "I"); jint inReadValue = env->GetIntField(recv, inReadField); inReadValue += bytesRead; @@ -145,6 +148,8 @@ static void Inflater_setDictionaryImpl(JNIEnv* env, jobject, jbyteArray dict, in static void Inflater_resetImpl(JNIEnv* env, jobject, jlong handle) { NativeZipStream* stream = toNativeZipStream(handle); + stream->totalIn = 0; + stream->totalOut = 0; int err = inflateReset(&stream->stream); if (err != Z_OK) { throwExceptionForZlibError(env, "java/lang/IllegalArgumentException", err, stream); @@ -152,11 +157,11 @@ static void Inflater_resetImpl(JNIEnv* env, jobject, jlong handle) { } static jlong Inflater_getTotalOutImpl(JNIEnv*, jobject, jlong handle) { - return toNativeZipStream(handle)->stream.total_out; + return toNativeZipStream(handle)->totalOut; } static jlong Inflater_getTotalInImpl(JNIEnv*, jobject, jlong handle) { - return toNativeZipStream(handle)->stream.total_in; + return toNativeZipStream(handle)->totalIn; } static JNINativeMethod gMethods[] = { diff --git a/luni/src/main/native/libcore_icu_AlphabeticIndex.cpp b/luni/src/main/native/libcore_icu_AlphabeticIndex.cpp index e0638bd..acc247b 100644 --- a/luni/src/main/native/libcore_icu_AlphabeticIndex.cpp +++ b/luni/src/main/native/libcore_icu_AlphabeticIndex.cpp @@ -25,8 +25,8 @@ #include "unicode/alphaindex.h" #include "unicode/uniset.h" -static AlphabeticIndex* fromPeer(jlong peer) { - return reinterpret_cast<AlphabeticIndex*>(static_cast<uintptr_t>(peer)); +static icu::AlphabeticIndex* fromPeer(jlong peer) { + return reinterpret_cast<icu::AlphabeticIndex*>(static_cast<uintptr_t>(peer)); } static jlong AlphabeticIndex_create(JNIEnv* env, jclass, jstring javaLocaleName) { @@ -35,7 +35,7 @@ static jlong AlphabeticIndex_create(JNIEnv* env, jclass, jstring javaLocaleName) if (!icuLocale.valid()) { return 0; } - AlphabeticIndex* ai = new AlphabeticIndex(icuLocale.locale(), status); + icu::AlphabeticIndex* ai = new icu::AlphabeticIndex(icuLocale.locale(), status); if (maybeThrowIcuException(env, "AlphabeticIndex", status)) { return 0; } @@ -47,19 +47,19 @@ static void AlphabeticIndex_destroy(JNIEnv*, jclass, jlong peer) { } static jint AlphabeticIndex_getMaxLabelCount(JNIEnv*, jclass, jlong peer) { - AlphabeticIndex* ai = fromPeer(peer); + icu::AlphabeticIndex* ai = fromPeer(peer); return ai->getMaxLabelCount(); } static void AlphabeticIndex_setMaxLabelCount(JNIEnv* env, jclass, jlong peer, jint count) { - AlphabeticIndex* ai = fromPeer(peer); + icu::AlphabeticIndex* ai = fromPeer(peer); UErrorCode status = U_ZERO_ERROR; ai->setMaxLabelCount(count, status); maybeThrowIcuException(env, "AlphabeticIndex::setMaxLabelCount", status); } static void AlphabeticIndex_addLabels(JNIEnv* env, jclass, jlong peer, jstring javaLocaleName) { - AlphabeticIndex* ai = fromPeer(peer); + icu::AlphabeticIndex* ai = fromPeer(peer); ScopedIcuLocale icuLocale(env, javaLocaleName); if (!icuLocale.valid()) { return; @@ -71,14 +71,14 @@ static void AlphabeticIndex_addLabels(JNIEnv* env, jclass, jlong peer, jstring j static void AlphabeticIndex_addLabelRange(JNIEnv* env, jclass, jlong peer, jint codePointStart, jint codePointEnd) { - AlphabeticIndex* ai = fromPeer(peer); + icu::AlphabeticIndex* ai = fromPeer(peer); UErrorCode status = U_ZERO_ERROR; - ai->addLabels(UnicodeSet(codePointStart, codePointEnd), status); + ai->addLabels(icu::UnicodeSet(codePointStart, codePointEnd), status); maybeThrowIcuException(env, "AlphabeticIndex::addLabels", status); } static jint AlphabeticIndex_getBucketCount(JNIEnv* env, jclass, jlong peer) { - AlphabeticIndex* ai = fromPeer(peer); + icu::AlphabeticIndex* ai = fromPeer(peer); UErrorCode status = U_ZERO_ERROR; jint result = ai->getBucketCount(status); if (maybeThrowIcuException(env, "AlphabeticIndex::getBucketCount", status)) { @@ -88,7 +88,7 @@ static jint AlphabeticIndex_getBucketCount(JNIEnv* env, jclass, jlong peer) { } static jint AlphabeticIndex_getBucketIndex(JNIEnv* env, jclass, jlong peer, jstring javaString) { - AlphabeticIndex* ai = fromPeer(peer); + icu::AlphabeticIndex* ai = fromPeer(peer); ScopedJavaUnicodeString string(env, javaString); if (!string.valid()) { return -1; @@ -108,7 +108,7 @@ static jstring AlphabeticIndex_getBucketLabel(JNIEnv* env, jclass, jlong peer, j } // Iterate to the nth bucket. - AlphabeticIndex* ai = fromPeer(peer); + icu::AlphabeticIndex* ai = fromPeer(peer); UErrorCode status = U_ZERO_ERROR; ai->resetBucketIterator(status); if (maybeThrowIcuException(env, "AlphabeticIndex::resetBucketIterator", status)) { @@ -129,31 +129,31 @@ static jstring AlphabeticIndex_getBucketLabel(JNIEnv* env, jclass, jlong peer, j return env->NewStringUTF(""); } - const UnicodeString& label(ai->getBucketLabel()); + const icu::UnicodeString& label(ai->getBucketLabel()); return env->NewString(label.getBuffer(), label.length()); } static jlong AlphabeticIndex_buildImmutableIndex(JNIEnv* env, jclass, jlong peer) { - AlphabeticIndex* ai = fromPeer(peer); + icu::AlphabeticIndex* ai = fromPeer(peer); UErrorCode status = U_ZERO_ERROR; - AlphabeticIndex::ImmutableIndex* ii = ai->buildImmutableIndex(status); + icu::AlphabeticIndex::ImmutableIndex* ii = ai->buildImmutableIndex(status); if (maybeThrowIcuException(env, "AlphabeticIndex::buildImmutableIndex", status)) { return 0; } return reinterpret_cast<uintptr_t>(ii); } -static AlphabeticIndex::ImmutableIndex* immutableIndexFromPeer(jlong peer) { - return reinterpret_cast<AlphabeticIndex::ImmutableIndex*>(static_cast<uintptr_t>(peer)); +static icu::AlphabeticIndex::ImmutableIndex* immutableIndexFromPeer(jlong peer) { + return reinterpret_cast<icu::AlphabeticIndex::ImmutableIndex*>(static_cast<uintptr_t>(peer)); } static jint ImmutableIndex_getBucketCount(JNIEnv*, jclass, jlong peer) { - AlphabeticIndex::ImmutableIndex* ii = immutableIndexFromPeer(peer); + icu::AlphabeticIndex::ImmutableIndex* ii = immutableIndexFromPeer(peer); return ii->getBucketCount(); } static jint ImmutableIndex_getBucketIndex(JNIEnv* env, jclass, jlong peer, jstring javaString) { - AlphabeticIndex::ImmutableIndex* ii = immutableIndexFromPeer(peer); + icu::AlphabeticIndex::ImmutableIndex* ii = immutableIndexFromPeer(peer); ScopedJavaUnicodeString string(env, javaString); if (!string.valid()) { return -1; @@ -167,8 +167,8 @@ static jint ImmutableIndex_getBucketIndex(JNIEnv* env, jclass, jlong peer, jstri } static jstring ImmutableIndex_getBucketLabel(JNIEnv* env, jclass, jlong peer, jint index) { - AlphabeticIndex::ImmutableIndex* ii = immutableIndexFromPeer(peer); - const AlphabeticIndex::Bucket* bucket = ii->getBucket(index); + icu::AlphabeticIndex::ImmutableIndex* ii = immutableIndexFromPeer(peer); + const icu::AlphabeticIndex::Bucket* bucket = ii->getBucket(index); if (bucket == NULL) { jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", "Invalid index: %d", index); return NULL; @@ -179,7 +179,7 @@ static jstring ImmutableIndex_getBucketLabel(JNIEnv* env, jclass, jlong peer, ji return env->NewStringUTF(""); } - const UnicodeString& label(bucket->getLabel()); + const icu::UnicodeString& label(bucket->getLabel()); return env->NewString(label.getBuffer(), label.length()); } diff --git a/luni/src/main/native/libcore_icu_DateIntervalFormat.cpp b/luni/src/main/native/libcore_icu_DateIntervalFormat.cpp deleted file mode 100644 index a3258c1..0000000 --- a/luni/src/main/native/libcore_icu_DateIntervalFormat.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "DateIntervalFormat" - -#include "IcuUtilities.h" -#include "JniConstants.h" -#include "ScopedIcuLocale.h" -#include "ScopedJavaUnicodeString.h" -#include "UniquePtr.h" -#include "cutils/log.h" -#include "unicode/dtitvfmt.h" - -static jlong DateIntervalFormat_createDateIntervalFormat(JNIEnv* env, jclass, jstring javaSkeleton, jstring javaLocaleName, jstring javaTzName) { - ScopedIcuLocale icuLocale(env, javaLocaleName); - if (!icuLocale.valid()) { - return 0; - } - - ScopedJavaUnicodeString skeletonHolder(env, javaSkeleton); - if (!skeletonHolder.valid()) { - return 0; - } - - UErrorCode status = U_ZERO_ERROR; - DateIntervalFormat* formatter(DateIntervalFormat::createInstance(skeletonHolder.unicodeString(), icuLocale.locale(), status)); - if (maybeThrowIcuException(env, "DateIntervalFormat::createInstance", status)) { - return 0; - } - - ScopedJavaUnicodeString tzNameHolder(env, javaTzName); - if (!tzNameHolder.valid()) { - return 0; - } - formatter->adoptTimeZone(TimeZone::createTimeZone(tzNameHolder.unicodeString())); - - return reinterpret_cast<uintptr_t>(formatter); -} - -static void DateIntervalFormat_destroyDateIntervalFormat(JNIEnv*, jclass, jlong address) { - delete reinterpret_cast<DateIntervalFormat*>(address); -} - -static jstring DateIntervalFormat_formatDateInterval(JNIEnv* env, jclass, jlong address, jlong fromDate, jlong toDate) { - DateIntervalFormat* formatter(reinterpret_cast<DateIntervalFormat*>(address)); - DateInterval date_interval(fromDate, toDate); - - UnicodeString s; - FieldPosition pos = 0; - UErrorCode status = U_ZERO_ERROR; - formatter->format(&date_interval, s, pos, status); - if (maybeThrowIcuException(env, "DateIntervalFormat::format", status)) { - return NULL; - } - - return env->NewString(s.getBuffer(), s.length()); -} - -static JNINativeMethod gMethods[] = { - NATIVE_METHOD(DateIntervalFormat, createDateIntervalFormat, "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)J"), - NATIVE_METHOD(DateIntervalFormat, destroyDateIntervalFormat, "(J)V"), - NATIVE_METHOD(DateIntervalFormat, formatDateInterval, "(JJJ)Ljava/lang/String;"), -}; -void register_libcore_icu_DateIntervalFormat(JNIEnv* env) { - jniRegisterNativeMethods(env, "libcore/icu/DateIntervalFormat", gMethods, NELEM(gMethods)); -} diff --git a/luni/src/main/native/libcore_icu_ICU.cpp b/luni/src/main/native/libcore_icu_ICU.cpp index d27b11d..0e744b7 100644 --- a/luni/src/main/native/libcore_icu_ICU.cpp +++ b/luni/src/main/native/libcore_icu_ICU.cpp @@ -25,7 +25,6 @@ #include "ScopedJavaUnicodeString.h" #include "ScopedLocalRef.h" #include "ScopedUtfChars.h" -#include "UniquePtr.h" #include "cutils/log.h" #include "toStringArray.h" #include "unicode/brkiter.h" @@ -39,6 +38,7 @@ #include "unicode/locid.h" #include "unicode/numfmt.h" #include "unicode/strenum.h" +#include "unicode/timezone.h" #include "unicode/ubrk.h" #include "unicode/ucal.h" #include "unicode/uclean.h" @@ -62,15 +62,9 @@ #include <sys/types.h> #include <time.h> #include <unistd.h> +#include <memory> #include <vector> -// TODO: put this in a header file and use it everywhere! -// DISALLOW_COPY_AND_ASSIGN disallows the copy and operator= functions. -// It goes in the private: declarations in a class. -#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ - TypeName(const TypeName&); \ - void operator=(const TypeName&) - class ScopedResourceBundle { public: ScopedResourceBundle(UResourceBundle* bundle) : bundle_(bundle) { @@ -121,7 +115,7 @@ static jint ICU_getCurrencyFractionDigits(JNIEnv* env, jclass, jstring javaCurre if (!currencyCode.valid()) { return 0; } - UnicodeString icuCurrencyCode(currencyCode.unicodeString()); + icu::UnicodeString icuCurrencyCode(currencyCode.unicodeString()); UErrorCode status = U_ZERO_ERROR; return ucurr_getDefaultFractionDigits(icuCurrencyCode.getTerminatedBuffer(), &status); } @@ -131,7 +125,7 @@ static jint ICU_getCurrencyNumericCode(JNIEnv* env, jclass, jstring javaCurrency if (!currencyCode.valid()) { return 0; } - UnicodeString icuCurrencyCode(currencyCode.unicodeString()); + icu::UnicodeString icuCurrencyCode(currencyCode.unicodeString()); return ucurr_getNumericCode(icuCurrencyCode.getTerminatedBuffer()); } @@ -187,7 +181,7 @@ static jstring getCurrencyName(JNIEnv* env, jstring javaLanguageTag, jstring jav if (!currencyCode.valid()) { return NULL; } - UnicodeString icuCurrencyCode(currencyCode.unicodeString()); + icu::UnicodeString icuCurrencyCode(currencyCode.unicodeString()); UErrorCode status = U_ZERO_ERROR; UBool isChoiceFormat = false; int32_t charCount; @@ -228,7 +222,7 @@ static jstring ICU_getDisplayCountryNative(JNIEnv* env, jclass, jstring javaTarg return NULL; } - UnicodeString str; + icu::UnicodeString str; icuTargetLocale.locale().getDisplayCountry(icuLocale.locale(), str); return env->NewString(str.getBuffer(), str.length()); } @@ -243,7 +237,7 @@ static jstring ICU_getDisplayLanguageNative(JNIEnv* env, jclass, jstring javaTar return NULL; } - UnicodeString str; + icu::UnicodeString str; icuTargetLocale.locale().getDisplayLanguage(icuLocale.locale(), str); return env->NewString(str.getBuffer(), str.length()); } @@ -258,7 +252,7 @@ static jstring ICU_getDisplayScriptNative(JNIEnv* env, jclass, jstring javaTarge return NULL; } - UnicodeString str; + icu::UnicodeString str; icuTargetLocale.locale().getDisplayScript(icuLocale.locale(), str); return env->NewString(str.getBuffer(), str.length()); } @@ -273,7 +267,7 @@ static jstring ICU_getDisplayVariantNative(JNIEnv* env, jclass, jstring javaTarg return NULL; } - UnicodeString str; + icu::UnicodeString str; icuTargetLocale.locale().getDisplayVariant(icuLocale.locale(), str); return env->NewString(str.getBuffer(), str.length()); } @@ -295,11 +289,11 @@ static jstring ICU_getISO3Language(JNIEnv* env, jclass, jstring javaLanguageTag) } static jobjectArray ICU_getISOCountriesNative(JNIEnv* env, jclass) { - return toStringArray(env, Locale::getISOCountries()); + return toStringArray(env, icu::Locale::getISOCountries()); } static jobjectArray ICU_getISOLanguagesNative(JNIEnv* env, jclass) { - return toStringArray(env, Locale::getISOLanguages()); + return toStringArray(env, icu::Locale::getISOLanguages()); } static jobjectArray ICU_getAvailableLocalesNative(JNIEnv* env, jclass) { @@ -343,7 +337,7 @@ static void setStringArrayField(JNIEnv* env, jobject obj, const char* fieldName, env->SetObjectField(obj, fid, value); } -static void setStringArrayField(JNIEnv* env, jobject obj, const char* fieldName, const UnicodeString* valueArray, int32_t size) { +static void setStringArrayField(JNIEnv* env, jobject obj, const char* fieldName, const icu::UnicodeString* valueArray, int32_t size) { ScopedLocalRef<jobjectArray> result(env, env->NewObjectArray(size, JniConstants::stringClass, NULL)); for (int32_t i = 0; i < size ; i++) { ScopedLocalRef<jstring> s(env, env->NewString(valueArray[i].getBuffer(),valueArray[i].length())); @@ -369,7 +363,7 @@ static void setStringField(JNIEnv* env, jobject obj, const char* fieldName, URes } } -static void setCharField(JNIEnv* env, jobject obj, const char* fieldName, const UnicodeString& value) { +static void setCharField(JNIEnv* env, jobject obj, const char* fieldName, const icu::UnicodeString& value) { if (value.length() == 0) { return; } @@ -377,43 +371,43 @@ static void setCharField(JNIEnv* env, jobject obj, const char* fieldName, const env->SetCharField(obj, fid, value.charAt(0)); } -static void setStringField(JNIEnv* env, jobject obj, const char* fieldName, const UnicodeString& value) { +static void setStringField(JNIEnv* env, jobject obj, const char* fieldName, const icu::UnicodeString& value) { const UChar* chars = value.getBuffer(); setStringField(env, obj, fieldName, env->NewString(chars, value.length())); } -static void setNumberPatterns(JNIEnv* env, jobject obj, Locale& locale) { +static void setNumberPatterns(JNIEnv* env, jobject obj, icu::Locale& locale) { UErrorCode status = U_ZERO_ERROR; - UnicodeString pattern; - UniquePtr<DecimalFormat> fmt(static_cast<DecimalFormat*>(NumberFormat::createInstance(locale, UNUM_CURRENCY, status))); + icu::UnicodeString pattern; + std::unique_ptr<icu::DecimalFormat> fmt(static_cast<icu::DecimalFormat*>(icu::NumberFormat::createInstance(locale, UNUM_CURRENCY, status))); pattern = fmt->toPattern(pattern.remove()); setStringField(env, obj, "currencyPattern", pattern); - fmt.reset(static_cast<DecimalFormat*>(NumberFormat::createInstance(locale, UNUM_DECIMAL, status))); + fmt.reset(static_cast<icu::DecimalFormat*>(icu::NumberFormat::createInstance(locale, UNUM_DECIMAL, status))); pattern = fmt->toPattern(pattern.remove()); setStringField(env, obj, "numberPattern", pattern); - fmt.reset(static_cast<DecimalFormat*>(NumberFormat::createInstance(locale, UNUM_PERCENT, status))); + fmt.reset(static_cast<icu::DecimalFormat*>(icu::NumberFormat::createInstance(locale, UNUM_PERCENT, status))); pattern = fmt->toPattern(pattern.remove()); setStringField(env, obj, "percentPattern", pattern); } -static void setDecimalFormatSymbolsData(JNIEnv* env, jobject obj, Locale& locale) { +static void setDecimalFormatSymbolsData(JNIEnv* env, jobject obj, icu::Locale& locale) { UErrorCode status = U_ZERO_ERROR; - DecimalFormatSymbols dfs(locale, status); + icu::DecimalFormatSymbols dfs(locale, status); - setCharField(env, obj, "decimalSeparator", dfs.getSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol)); - setCharField(env, obj, "groupingSeparator", dfs.getSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol)); - setCharField(env, obj, "patternSeparator", dfs.getSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol)); - setStringField(env, obj, "percent", dfs.getSymbol(DecimalFormatSymbols::kPercentSymbol)); - setCharField(env, obj, "perMill", dfs.getSymbol(DecimalFormatSymbols::kPerMillSymbol)); - setCharField(env, obj, "monetarySeparator", dfs.getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol)); - setStringField(env, obj, "minusSign", dfs.getSymbol(DecimalFormatSymbols:: kMinusSignSymbol)); - setStringField(env, obj, "exponentSeparator", dfs.getSymbol(DecimalFormatSymbols::kExponentialSymbol)); - setStringField(env, obj, "infinity", dfs.getSymbol(DecimalFormatSymbols::kInfinitySymbol)); - setStringField(env, obj, "NaN", dfs.getSymbol(DecimalFormatSymbols::kNaNSymbol)); - setCharField(env, obj, "zeroDigit", dfs.getSymbol(DecimalFormatSymbols::kZeroDigitSymbol)); + setCharField(env, obj, "decimalSeparator", dfs.getSymbol(icu::DecimalFormatSymbols::kDecimalSeparatorSymbol)); + setCharField(env, obj, "groupingSeparator", dfs.getSymbol(icu::DecimalFormatSymbols::kGroupingSeparatorSymbol)); + setCharField(env, obj, "patternSeparator", dfs.getSymbol(icu::DecimalFormatSymbols::kPatternSeparatorSymbol)); + setStringField(env, obj, "percent", dfs.getSymbol(icu::DecimalFormatSymbols::kPercentSymbol)); + setCharField(env, obj, "perMill", dfs.getSymbol(icu::DecimalFormatSymbols::kPerMillSymbol)); + setCharField(env, obj, "monetarySeparator", dfs.getSymbol(icu::DecimalFormatSymbols::kMonetarySeparatorSymbol)); + setStringField(env, obj, "minusSign", dfs.getSymbol(icu::DecimalFormatSymbols:: kMinusSignSymbol)); + setStringField(env, obj, "exponentSeparator", dfs.getSymbol(icu::DecimalFormatSymbols::kExponentialSymbol)); + setStringField(env, obj, "infinity", dfs.getSymbol(icu::DecimalFormatSymbols::kInfinitySymbol)); + setStringField(env, obj, "NaN", dfs.getSymbol(icu::DecimalFormatSymbols::kNaNSymbol)); + setCharField(env, obj, "zeroDigit", dfs.getSymbol(icu::DecimalFormatSymbols::kZeroDigitSymbol)); } @@ -502,7 +496,7 @@ static bool getDateTimePatterns(JNIEnv* env, jobject localeData, const char* loc return true; } -static bool getYesterdayTodayAndTomorrow(JNIEnv* env, jobject localeData, const Locale& locale, const char* locale_name) { +static bool getYesterdayTodayAndTomorrow(JNIEnv* env, jobject localeData, const icu::Locale& locale, const char* locale_name) { UErrorCode status = U_ZERO_ERROR; ScopedResourceBundle root(ures_open(NULL, locale_name, &status)); ScopedResourceBundle fields(ures_getByKey(root.get(), "fields", NULL, &status)); @@ -512,16 +506,16 @@ static bool getYesterdayTodayAndTomorrow(JNIEnv* env, jobject localeData, const return false; } - UnicodeString yesterday(ures_getUnicodeStringByKey(relative.get(), "-1", &status)); - UnicodeString today(ures_getUnicodeStringByKey(relative.get(), "0", &status)); - UnicodeString tomorrow(ures_getUnicodeStringByKey(relative.get(), "1", &status)); + icu::UnicodeString yesterday(icu::ures_getUnicodeStringByKey(relative.get(), "-1", &status)); + icu::UnicodeString today(icu::ures_getUnicodeStringByKey(relative.get(), "0", &status)); + icu::UnicodeString tomorrow(icu::ures_getUnicodeStringByKey(relative.get(), "1", &status)); if (U_FAILURE(status)) { ALOGE("Error getting yesterday/today/tomorrow for %s: %s", locale_name, u_errorName(status)); return false; } // We title-case the strings so they have consistent capitalization (http://b/14493853). - UniquePtr<BreakIterator> brk(BreakIterator::createSentenceInstance(locale, status)); + std::unique_ptr<icu::BreakIterator> brk(icu::BreakIterator::createSentenceInstance(locale, status)); if (U_FAILURE(status)) { ALOGE("Error getting yesterday/today/tomorrow break iterator for %s: %s", locale_name, u_errorName(status)); return false; @@ -591,7 +585,7 @@ static jboolean ICU_initLocaleDataNative(JNIEnv* env, jclass, jstring javaLangua } status = U_ZERO_ERROR; - UniquePtr<Calendar> cal(Calendar::createInstance(icuLocale.locale(), status)); + std::unique_ptr<icu::Calendar> cal(icu::Calendar::createInstance(icuLocale.locale(), status)); if (U_FAILURE(status)) { return JNI_FALSE; } @@ -601,54 +595,54 @@ static jboolean ICU_initLocaleDataNative(JNIEnv* env, jclass, jstring javaLangua // Get DateFormatSymbols. status = U_ZERO_ERROR; - DateFormatSymbols dateFormatSym(icuLocale.locale(), status); + icu::DateFormatSymbols dateFormatSym(icuLocale.locale(), status); if (U_FAILURE(status)) { return JNI_FALSE; } // Get AM/PM and BC/AD. int32_t count = 0; - const UnicodeString* amPmStrs = dateFormatSym.getAmPmStrings(count); + const icu::UnicodeString* amPmStrs = dateFormatSym.getAmPmStrings(count); setStringArrayField(env, localeData, "amPm", amPmStrs, count); - const UnicodeString* erasStrs = dateFormatSym.getEras(count); + const icu::UnicodeString* erasStrs = dateFormatSym.getEras(count); setStringArrayField(env, localeData, "eras", erasStrs, count); - const UnicodeString* longMonthNames = - dateFormatSym.getMonths(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE); + const icu::UnicodeString* longMonthNames = + dateFormatSym.getMonths(count, icu::DateFormatSymbols::FORMAT, icu::DateFormatSymbols::WIDE); setStringArrayField(env, localeData, "longMonthNames", longMonthNames, count); - const UnicodeString* shortMonthNames = - dateFormatSym.getMonths(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED); + const icu::UnicodeString* shortMonthNames = + dateFormatSym.getMonths(count, icu::DateFormatSymbols::FORMAT, icu::DateFormatSymbols::ABBREVIATED); setStringArrayField(env, localeData, "shortMonthNames", shortMonthNames, count); - const UnicodeString* tinyMonthNames = - dateFormatSym.getMonths(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW); + const icu::UnicodeString* tinyMonthNames = + dateFormatSym.getMonths(count, icu::DateFormatSymbols::FORMAT, icu::DateFormatSymbols::NARROW); setStringArrayField(env, localeData, "tinyMonthNames", tinyMonthNames, count); - const UnicodeString* longWeekdayNames = - dateFormatSym.getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE); + const icu::UnicodeString* longWeekdayNames = + dateFormatSym.getWeekdays(count, icu::DateFormatSymbols::FORMAT, icu::DateFormatSymbols::WIDE); setStringArrayField(env, localeData, "longWeekdayNames", longWeekdayNames, count); - const UnicodeString* shortWeekdayNames = - dateFormatSym.getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED); + const icu::UnicodeString* shortWeekdayNames = + dateFormatSym.getWeekdays(count, icu::DateFormatSymbols::FORMAT, icu::DateFormatSymbols::ABBREVIATED); setStringArrayField(env, localeData, "shortWeekdayNames", shortWeekdayNames, count); - const UnicodeString* tinyWeekdayNames = - dateFormatSym.getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW); + const icu::UnicodeString* tinyWeekdayNames = + dateFormatSym.getWeekdays(count, icu::DateFormatSymbols::FORMAT, icu::DateFormatSymbols::NARROW); setStringArrayField(env, localeData, "tinyWeekdayNames", tinyWeekdayNames, count); - const UnicodeString* longStandAloneMonthNames = - dateFormatSym.getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE); + const icu::UnicodeString* longStandAloneMonthNames = + dateFormatSym.getMonths(count, icu::DateFormatSymbols::STANDALONE, icu::DateFormatSymbols::WIDE); setStringArrayField(env, localeData, "longStandAloneMonthNames", longStandAloneMonthNames, count); - const UnicodeString* shortStandAloneMonthNames = - dateFormatSym.getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED); + const icu::UnicodeString* shortStandAloneMonthNames = + dateFormatSym.getMonths(count, icu::DateFormatSymbols::STANDALONE, icu::DateFormatSymbols::ABBREVIATED); setStringArrayField(env, localeData, "shortStandAloneMonthNames", shortStandAloneMonthNames, count); - const UnicodeString* tinyStandAloneMonthNames = - dateFormatSym.getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW); + const icu::UnicodeString* tinyStandAloneMonthNames = + dateFormatSym.getMonths(count, icu::DateFormatSymbols::STANDALONE, icu::DateFormatSymbols::NARROW); setStringArrayField(env, localeData, "tinyStandAloneMonthNames", tinyStandAloneMonthNames, count); - const UnicodeString* longStandAloneWeekdayNames = - dateFormatSym.getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE); + const icu::UnicodeString* longStandAloneWeekdayNames = + dateFormatSym.getWeekdays(count, icu::DateFormatSymbols::STANDALONE, icu::DateFormatSymbols::WIDE); setStringArrayField(env, localeData, "longStandAloneWeekdayNames", longStandAloneWeekdayNames, count); - const UnicodeString* shortStandAloneWeekdayNames = - dateFormatSym.getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED); + const icu::UnicodeString* shortStandAloneWeekdayNames = + dateFormatSym.getWeekdays(count, icu::DateFormatSymbols::STANDALONE, icu::DateFormatSymbols::ABBREVIATED); setStringArrayField(env, localeData, "shortStandAloneWeekdayNames", shortStandAloneWeekdayNames, count); - const UnicodeString* tinyStandAloneWeekdayNames = - dateFormatSym.getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW); + const icu::UnicodeString* tinyStandAloneWeekdayNames = + dateFormatSym.getWeekdays(count, icu::DateFormatSymbols::STANDALONE, icu::DateFormatSymbols::NARROW); setStringArrayField(env, localeData, "tinyStandAloneWeekdayNames", tinyStandAloneWeekdayNames, count); status = U_ZERO_ERROR; @@ -687,8 +681,8 @@ static jstring ICU_toLowerCase(JNIEnv* env, jclass, jstring javaString, jstring if (!icuLocale.valid()) { return NULL; } - UnicodeString& s(scopedString.unicodeString()); - UnicodeString original(s); + icu::UnicodeString& s(scopedString.unicodeString()); + icu::UnicodeString original(s); s.toLower(icuLocale.locale()); return s == original ? javaString : env->NewString(s.getBuffer(), s.length()); } @@ -702,8 +696,8 @@ static jstring ICU_toUpperCase(JNIEnv* env, jclass, jstring javaString, jstring if (!icuLocale.valid()) { return NULL; } - UnicodeString& s(scopedString.unicodeString()); - UnicodeString original(s); + icu::UnicodeString& s(scopedString.unicodeString()); + icu::UnicodeString original(s); s.toUpper(icuLocale.locale()); return s == original ? javaString : env->NewString(s.getBuffer(), s.length()); } @@ -733,9 +727,18 @@ static jstring ICU_getUnicodeVersion(JNIEnv* env, jclass) { return versionString(env, unicodeVersion); } +static jstring ICU_getTZDataVersion(JNIEnv* env, jclass) { + UErrorCode status = U_ZERO_ERROR; + const char* version = icu::TimeZone::getTZDataVersion(status); + if (maybeThrowIcuException(env, "icu::TimeZone::getTZDataVersion", status)) { + return NULL; + } + return env->NewStringUTF(version); +} + static jobject ICU_getAvailableCurrencyCodes(JNIEnv* env, jclass) { UErrorCode status = U_ZERO_ERROR; - UStringEnumeration e(ucurr_openISOCurrencies(UCURR_COMMON|UCURR_NON_DEPRECATED, &status)); + icu::UStringEnumeration e(ucurr_openISOCurrencies(UCURR_COMMON|UCURR_NON_DEPRECATED, &status)); return fromStringEnumeration(env, status, "ucurr_openISOCurrencies", &e); } @@ -746,7 +749,7 @@ static jstring ICU_getBestDateTimePatternNative(JNIEnv* env, jclass, jstring jav } UErrorCode status = U_ZERO_ERROR; - UniquePtr<DateTimePatternGenerator> generator(DateTimePatternGenerator::createInstance(icuLocale.locale(), status)); + std::unique_ptr<icu::DateTimePatternGenerator> generator(icu::DateTimePatternGenerator::createInstance(icuLocale.locale(), status)); if (maybeThrowIcuException(env, "DateTimePatternGenerator::createInstance", status)) { return NULL; } @@ -755,7 +758,7 @@ static jstring ICU_getBestDateTimePatternNative(JNIEnv* env, jclass, jstring jav if (!skeletonHolder.valid()) { return NULL; } - UnicodeString result(generator->getBestPattern(skeletonHolder.unicodeString(), status)); + icu::UnicodeString result(generator->getBestPattern(skeletonHolder.unicodeString(), status)); if (maybeThrowIcuException(env, "DateTimePatternGenerator::getBestPattern", status)) { return NULL; } @@ -770,12 +773,12 @@ static void ICU_setDefaultLocale(JNIEnv* env, jclass, jstring javaLanguageTag) { } UErrorCode status = U_ZERO_ERROR; - Locale::setDefault(icuLocale.locale(), status); + icu::Locale::setDefault(icuLocale.locale(), status); maybeThrowIcuException(env, "Locale::setDefault", status); } static jstring ICU_getDefaultLocale(JNIEnv* env, jclass) { - return env->NewStringUTF(Locale::getDefault().getName()); + return env->NewStringUTF(icu::Locale::getDefault().getName()); } static JNINativeMethod gMethods[] = { @@ -805,28 +808,25 @@ static JNINativeMethod gMethods[] = { NATIVE_METHOD(ICU, getISOLanguagesNative, "()[Ljava/lang/String;"), NATIVE_METHOD(ICU, getIcuVersion, "()Ljava/lang/String;"), NATIVE_METHOD(ICU, getScript, "(Ljava/lang/String;)Ljava/lang/String;"), + NATIVE_METHOD(ICU, getTZDataVersion, "()Ljava/lang/String;"), NATIVE_METHOD(ICU, getUnicodeVersion, "()Ljava/lang/String;"), NATIVE_METHOD(ICU, initLocaleDataNative, "(Ljava/lang/String;Llibcore/icu/LocaleData;)Z"), NATIVE_METHOD(ICU, setDefaultLocale, "(Ljava/lang/String;)V"), NATIVE_METHOD(ICU, toLowerCase, "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"), NATIVE_METHOD(ICU, toUpperCase, "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"), }; -void register_libcore_icu_ICU(JNIEnv* env) { - std::string path; - path = u_getDataDirectory(); - path += "/"; - path += U_ICUDATA_NAME; - path += ".dat"; - - #define FAIL_WITH_STRERROR(s) \ - ALOGE("Couldn't " s " '%s': %s", path.c_str(), strerror(errno)); \ - abort(); - #define MAYBE_FAIL_WITH_ICU_ERROR(s) \ - if (status != U_ZERO_ERROR) {\ - ALOGE("Couldn't initialize ICU (" s "): %s (%s)", u_errorName(status), path.c_str()); \ - abort(); \ - } +#define FAIL_WITH_STRERROR(s) \ + ALOGE("Couldn't " s " '%s': %s", path.c_str(), strerror(errno)); \ + return FALSE; + +#define MAYBE_FAIL_WITH_ICU_ERROR(s) \ + if (status != U_ZERO_ERROR) {\ + ALOGE("Couldn't initialize ICU (" s "): %s (%s)", u_errorName(status), path.c_str()); \ + return FALSE; \ + } + +static bool mapIcuData(const std::string& path) { // Open the file and get its length. ScopedFd fd(open(path.c_str(), O_RDONLY)); if (fd.get() == -1) { @@ -848,18 +848,66 @@ void register_libcore_icu_ICU(JNIEnv* env) { FAIL_WITH_STRERROR("madvise(MADV_RANDOM)"); } - // Tell ICU to use our memory-mapped data. UErrorCode status = U_ZERO_ERROR; + + // Tell ICU to use our memory-mapped data. udata_setCommonData(data, &status); MAYBE_FAIL_WITH_ICU_ERROR("udata_setCommonData"); + + return TRUE; +} + +void register_libcore_icu_ICU(JNIEnv* env) { + // Check the timezone override file exists. If it does, map it first so we use it in preference + // to the one that shipped with the device. + const char* dataPathPrefix = getenv("ANDROID_DATA"); + if (dataPathPrefix == NULL) { + ALOGE("ANDROID_DATA environment variable not set"); \ + abort(); + } + + UErrorCode status = U_ZERO_ERROR; // Tell ICU it can *only* use our memory-mapped data. udata_setFileAccess(UDATA_NO_FILES, &status); - MAYBE_FAIL_WITH_ICU_ERROR("udata_setFileAccess"); + if (status != U_ZERO_ERROR) { + ALOGE("Couldn't initialize ICU (s_setFileAccess): %s", u_errorName(status)); + abort(); + } + + // Map in optional TZ data files. + std::string dataPath; + dataPath = dataPathPrefix; + dataPath += "/misc/zoneinfo/current/icu/icu_tzdata.dat"; + + struct stat sb; + if (stat(dataPath.c_str(), &sb) == 0) { + ALOGD("Timezone override file found: %s", dataPath.c_str()); + if (!mapIcuData(dataPath)) { + ALOGW("TZ override file %s exists but could not be loaded. Skipping.", dataPath.c_str()); + } + } else { + ALOGD("No timezone override file found: %s", dataPath.c_str()); + } + + // Use the ICU data files that shipped with the device for everything else. + std::string systemPath; + systemPath = u_getDataDirectory(); + systemPath += "/"; + systemPath += U_ICUDATA_NAME; + systemPath += ".dat"; + + if (!mapIcuData(systemPath)) { + abort(); + } // Failures to find the ICU data tend to be somewhat obscure because ICU loads its data on first // use, which can be anywhere. Force initialization up front so we can report a nice clear error // and bail. u_init(&status); - MAYBE_FAIL_WITH_ICU_ERROR("u_init"); + if (status != U_ZERO_ERROR) {\ + ALOGE("Couldn't initialize ICU (u_init): %s", u_errorName(status)); + abort(); + } + jniRegisterNativeMethods(env, "libcore/icu/ICU", gMethods, NELEM(gMethods)); } diff --git a/luni/src/main/native/libcore_icu_NativeBreakIterator.cpp b/luni/src/main/native/libcore_icu_NativeBreakIterator.cpp deleted file mode 100644 index ef0c2a9..0000000 --- a/luni/src/main/native/libcore_icu_NativeBreakIterator.cpp +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "NativeBreakIterator" - -#include "IcuUtilities.h" -#include "JNIHelp.h" -#include "JniConstants.h" -#include "JniException.h" -#include "ScopedIcuLocale.h" -#include "ScopedUtfChars.h" -#include "unicode/brkiter.h" -#include "unicode/putil.h" -#include <stdlib.h> - -// ICU documentation: http://icu-project.org/apiref/icu4c/classBreakIterator.html - -static BreakIterator* toBreakIterator(jlong address) { - return reinterpret_cast<BreakIterator*>(static_cast<uintptr_t>(address)); -} - -/** - * We use ICU4C's BreakIterator class, but our input is on the Java heap and potentially moving - * around between calls. This wrapper class ensures that our RegexMatcher is always pointing at - * the current location of the char[]. Earlier versions of Android simply copied the data to the - * native heap, but that's wasteful and hides allocations from the garbage collector. - */ -class BreakIteratorAccessor { - public: - BreakIteratorAccessor(JNIEnv* env, jlong address, jstring javaInput, bool reset) { - init(env, address); - mJavaInput = javaInput; - - if (mJavaInput == NULL) { - return; - } - - mChars = env->GetStringChars(mJavaInput, NULL); - if (mChars == NULL) { - return; - } - - mUText = utext_openUChars(NULL, mChars, env->GetStringLength(mJavaInput), &mStatus); - if (mUText == NULL) { - return; - } - - if (reset) { - mBreakIterator->setText(mUText, mStatus); - } else { - mBreakIterator->refreshInputText(mUText, mStatus); - } - } - - BreakIteratorAccessor(JNIEnv* env, jlong address) { - init(env, address); - } - - ~BreakIteratorAccessor() { - utext_close(mUText); - if (mJavaInput) { - mEnv->ReleaseStringChars(mJavaInput, mChars); - } - maybeThrowIcuException(mEnv, "utext_close", mStatus); - } - - BreakIterator* operator->() { - return mBreakIterator; - } - - UErrorCode& status() { - return mStatus; - } - - private: - void init(JNIEnv* env, jlong address) { - mEnv = env; - mJavaInput = NULL; - mBreakIterator = toBreakIterator(address); - mChars = NULL; - mStatus = U_ZERO_ERROR; - mUText = NULL; - } - - JNIEnv* mEnv; - jstring mJavaInput; - BreakIterator* mBreakIterator; - const jchar* mChars; - UErrorCode mStatus; - UText* mUText; - - // Disallow copy and assignment. - BreakIteratorAccessor(const BreakIteratorAccessor&); - void operator=(const BreakIteratorAccessor&); -}; - -#define MAKE_BREAK_ITERATOR_INSTANCE(F) \ - ScopedIcuLocale icuLocale(env, javaLocaleName); \ - if (!icuLocale.valid()) { \ - return 0; \ - } \ - UErrorCode status = U_ZERO_ERROR; \ - BreakIterator* it = F(icuLocale.locale(), status); \ - if (maybeThrowIcuException(env, "ubrk_open", status)) { \ - return 0; \ - } \ - return reinterpret_cast<uintptr_t>(it) - -static jlong NativeBreakIterator_cloneImpl(JNIEnv* env, jclass, jlong address) { - BreakIteratorAccessor it(env, address); - return reinterpret_cast<uintptr_t>(it->clone()); -} - -static void NativeBreakIterator_closeImpl(JNIEnv*, jclass, jlong address) { - delete toBreakIterator(address); -} - -static jint NativeBreakIterator_currentImpl(JNIEnv* env, jclass, jlong address, jstring javaInput) { - BreakIteratorAccessor it(env, address, javaInput, false); - return it->current(); -} - -static jint NativeBreakIterator_firstImpl(JNIEnv* env, jclass, jlong address, jstring javaInput) { - BreakIteratorAccessor it(env, address, javaInput, false); - return it->first(); -} - -static jint NativeBreakIterator_followingImpl(JNIEnv* env, jclass, jlong address, jstring javaInput, jint offset) { - BreakIteratorAccessor it(env, address, javaInput, false); - return it->following(offset); -} - -static jlong NativeBreakIterator_getCharacterInstanceImpl(JNIEnv* env, jclass, jstring javaLocaleName) { - MAKE_BREAK_ITERATOR_INSTANCE(BreakIterator::createCharacterInstance); -} - -static jlong NativeBreakIterator_getLineInstanceImpl(JNIEnv* env, jclass, jstring javaLocaleName) { - MAKE_BREAK_ITERATOR_INSTANCE(BreakIterator::createLineInstance); -} - -static jlong NativeBreakIterator_getSentenceInstanceImpl(JNIEnv* env, jclass, jstring javaLocaleName) { - MAKE_BREAK_ITERATOR_INSTANCE(BreakIterator::createSentenceInstance); -} - -static jlong NativeBreakIterator_getWordInstanceImpl(JNIEnv* env, jclass, jstring javaLocaleName) { - MAKE_BREAK_ITERATOR_INSTANCE(BreakIterator::createWordInstance); -} - -static jboolean NativeBreakIterator_isBoundaryImpl(JNIEnv* env, jclass, jlong address, jstring javaInput, jint offset) { - BreakIteratorAccessor it(env, address, javaInput, false); - return it->isBoundary(offset); -} - -static jint NativeBreakIterator_lastImpl(JNIEnv* env, jclass, jlong address, jstring javaInput) { - BreakIteratorAccessor it(env, address, javaInput, false); - return it->last(); -} - -static jint NativeBreakIterator_nextImpl(JNIEnv* env, jclass, jlong address, jstring javaInput, jint n) { - BreakIteratorAccessor it(env, address, javaInput, false); - if (n < 0) { - while (n++ < -1) { - it->previous(); - } - return it->previous(); - } else if (n == 0) { - return it->current(); - } else { - while (n-- > 1) { - it->next(); - } - return it->next(); - } - return -1; -} - -static jint NativeBreakIterator_precedingImpl(JNIEnv* env, jclass, jlong address, jstring javaInput, jint offset) { - BreakIteratorAccessor it(env, address, javaInput, false); - return it->preceding(offset); -} - -static jint NativeBreakIterator_previousImpl(JNIEnv* env, jclass, jlong address, jstring javaInput) { - BreakIteratorAccessor it(env, address, javaInput, false); - return it->previous(); -} - -static void NativeBreakIterator_setTextImpl(JNIEnv* env, jclass, jlong address, jstring javaInput) { - BreakIteratorAccessor it(env, address, javaInput, true); -} - -static JNINativeMethod gMethods[] = { - NATIVE_METHOD(NativeBreakIterator, cloneImpl, "(J)J"), - NATIVE_METHOD(NativeBreakIterator, closeImpl, "(J)V"), - NATIVE_METHOD(NativeBreakIterator, currentImpl, "(JLjava/lang/String;)I"), - NATIVE_METHOD(NativeBreakIterator, firstImpl, "(JLjava/lang/String;)I"), - NATIVE_METHOD(NativeBreakIterator, followingImpl, "(JLjava/lang/String;I)I"), - NATIVE_METHOD(NativeBreakIterator, getCharacterInstanceImpl, "(Ljava/lang/String;)J"), - NATIVE_METHOD(NativeBreakIterator, getLineInstanceImpl, "(Ljava/lang/String;)J"), - NATIVE_METHOD(NativeBreakIterator, getSentenceInstanceImpl, "(Ljava/lang/String;)J"), - NATIVE_METHOD(NativeBreakIterator, getWordInstanceImpl, "(Ljava/lang/String;)J"), - NATIVE_METHOD(NativeBreakIterator, isBoundaryImpl, "(JLjava/lang/String;I)Z"), - NATIVE_METHOD(NativeBreakIterator, lastImpl, "(JLjava/lang/String;)I"), - NATIVE_METHOD(NativeBreakIterator, nextImpl, "(JLjava/lang/String;I)I"), - NATIVE_METHOD(NativeBreakIterator, precedingImpl, "(JLjava/lang/String;I)I"), - NATIVE_METHOD(NativeBreakIterator, previousImpl, "(JLjava/lang/String;)I"), - NATIVE_METHOD(NativeBreakIterator, setTextImpl, "(JLjava/lang/String;)V"), -}; -void register_libcore_icu_NativeBreakIterator(JNIEnv* env) { - jniRegisterNativeMethods(env, "libcore/icu/NativeBreakIterator", gMethods, NELEM(gMethods)); -} diff --git a/luni/src/main/native/libcore_icu_NativeCollation.cpp b/luni/src/main/native/libcore_icu_NativeCollation.cpp index 4ce42ec..f27d72e 100644 --- a/luni/src/main/native/libcore_icu_NativeCollation.cpp +++ b/luni/src/main/native/libcore_icu_NativeCollation.cpp @@ -15,10 +15,10 @@ #include "JniException.h" #include "ScopedStringChars.h" #include "ScopedUtfChars.h" -#include "UniquePtr.h" #include "unicode/ucol.h" #include "unicode/ucoleitr.h" #include <cutils/log.h> +#include <memory> // Manages a UCollationElements instance along with the jchar // array it is iterating over. The associated array can be unpinned @@ -124,7 +124,7 @@ static jlong NativeCollation_getCollationElementIterator(JNIEnv* env, jclass, jl return -1; } - UniquePtr<CollationElements> ce(new CollationElements); + std::unique_ptr<CollationElements> ce(new CollationElements); UErrorCode status = ce->start(env, javaSource, toCollator(address)); maybeThrowIcuException(env, "ucol_openElements", status); if (status == U_ZERO_ERROR) { @@ -156,7 +156,7 @@ static jbyteArray NativeCollation_getSortKey(JNIEnv* env, jclass, jlong address, const UCollator* collator = toCollator(address); // The buffer size prevents reallocation for most strings. uint8_t byteArray[128]; - UniquePtr<uint8_t[]> largerByteArray; + std::unique_ptr<uint8_t[]> largerByteArray; uint8_t* usedByteArray = byteArray; size_t byteArraySize = ucol_getSortKey(collator, source.get(), source.size(), usedByteArray, sizeof(byteArray) - 1); if (byteArraySize > sizeof(byteArray) - 1) { diff --git a/luni/src/main/native/libcore_icu_NativeConverter.cpp b/luni/src/main/native/libcore_icu_NativeConverter.cpp index 8dd439a..355cc78 100644 --- a/luni/src/main/native/libcore_icu_NativeConverter.cpp +++ b/luni/src/main/native/libcore_icu_NativeConverter.cpp @@ -23,7 +23,6 @@ #include "ScopedPrimitiveArray.h" #include "ScopedStringChars.h" #include "ScopedUtfChars.h" -#include "UniquePtr.h" #include "cutils/log.h" #include "toStringArray.h" #include "unicode/ucnv.h" @@ -32,6 +31,7 @@ #include "unicode/ustring.h" #include "unicode/utypes.h" +#include <memory> #include <vector> #include <stdlib.h> @@ -64,7 +64,7 @@ static UConverter* toUConverter(jlong address) { static bool collectStandardNames(JNIEnv* env, const char* canonicalName, const char* standard, std::vector<std::string>& result) { UErrorCode status = U_ZERO_ERROR; - UStringEnumeration e(ucnv_openStandardNames(canonicalName, standard, &status)); + icu::UStringEnumeration e(ucnv_openStandardNames(canonicalName, standard, &status)); if (maybeThrowIcuException(env, "ucnv_openStandardNames", status)) { return false; } @@ -75,7 +75,7 @@ static bool collectStandardNames(JNIEnv* env, const char* canonicalName, const c } for (int32_t i = 0; i < count; ++i) { - const UnicodeString* string = e.snext(status); + const icu::UnicodeString* string = e.snext(status); if (maybeThrowIcuException(env, "StringEnumeration::snext", status)) { return false; } @@ -104,7 +104,7 @@ static const char* getICUCanonicalName(const char* name) { } else if (strstr(name, "x-") == name) { // Check if the converter can be opened with the name given. error = U_ZERO_ERROR; - LocalUConverterPointer cnv(ucnv_open(name + 2, &error)); + icu::LocalUConverterPointer cnv(ucnv_open(name + 2, &error)); if (U_SUCCESS(error)) { return name + 2; } @@ -150,7 +150,7 @@ static jstring getJavaCanonicalName(JNIEnv* env, const char* icuCanonicalName) { if (name == NULL) { name = icuCanonicalName; } - UniquePtr<char[]> result(new char[2 + strlen(name) + 1]); + std::unique_ptr<char[]> result(new char[2 + strlen(name) + 1]); strcpy(&result[0], "x-"); strcat(&result[0], name); return env->NewStringUTF(&result[0]); @@ -537,12 +537,12 @@ static jboolean NativeConverter_contains(JNIEnv* env, jclass, jstring name1, jst } UErrorCode errorCode = U_ZERO_ERROR; - LocalUConverterPointer converter1(ucnv_open(name1Chars.c_str(), &errorCode)); - UnicodeSet set1; + icu::LocalUConverterPointer converter1(ucnv_open(name1Chars.c_str(), &errorCode)); + icu::UnicodeSet set1; ucnv_getUnicodeSet(&*converter1, set1.toUSet(), UCNV_ROUNDTRIP_SET, &errorCode); - LocalUConverterPointer converter2(ucnv_open(name2Chars.c_str(), &errorCode)); - UnicodeSet set2; + icu::LocalUConverterPointer converter2(ucnv_open(name2Chars.c_str(), &errorCode)); + icu::UnicodeSet set2; ucnv_getUnicodeSet(&*converter2, set2.toUSet(), UCNV_ROUNDTRIP_SET, &errorCode); return U_SUCCESS(errorCode) && set1.containsAll(set2); @@ -570,7 +570,7 @@ static jobject NativeConverter_charsetForName(JNIEnv* env, jclass, jstring chars { // ICU doesn't offer any "isSupported", so we just open and immediately close. UErrorCode error = U_ZERO_ERROR; - LocalUConverterPointer cnv(ucnv_open(icuCanonicalName, &error)); + icu::LocalUConverterPointer cnv(ucnv_open(icuCanonicalName, &error)); if (!U_SUCCESS(error)) { return NULL; } diff --git a/luni/src/main/native/libcore_icu_NativeDecimalFormat.cpp b/luni/src/main/native/libcore_icu_NativeDecimalFormat.cpp index 8e440e9..8c4a411 100644 --- a/luni/src/main/native/libcore_icu_NativeDecimalFormat.cpp +++ b/luni/src/main/native/libcore_icu_NativeDecimalFormat.cpp @@ -19,6 +19,7 @@ #include <stdlib.h> #include <string.h> +#include <memory> #include <vector> #include "cutils/log.h" @@ -36,18 +37,17 @@ #include "unicode/numfmt.h" #include "unicode/unum.h" #include "unicode/ustring.h" -#include "UniquePtr.h" #include "valueOf.h" -static DecimalFormat* toDecimalFormat(jlong addr) { - return reinterpret_cast<DecimalFormat*>(static_cast<uintptr_t>(addr)); +static icu::DecimalFormat* toDecimalFormat(jlong addr) { + return reinterpret_cast<icu::DecimalFormat*>(static_cast<uintptr_t>(addr)); } static UNumberFormat* toUNumberFormat(jlong addr) { return reinterpret_cast<UNumberFormat*>(static_cast<uintptr_t>(addr)); } -static DecimalFormatSymbols* makeDecimalFormatSymbols(JNIEnv* env, +static icu::DecimalFormatSymbols* makeDecimalFormatSymbols(JNIEnv* env, jstring currencySymbol0, jchar decimalSeparator, jchar digit, jstring exponentSeparator0, jchar groupingSeparator0, jstring infinity0, jstring internationalCurrencySymbol0, jstring minusSign0, @@ -60,36 +60,41 @@ static DecimalFormatSymbols* makeDecimalFormatSymbols(JNIEnv* env, ScopedJavaUnicodeString nan(env, nan0); ScopedJavaUnicodeString minusSign(env, minusSign0); ScopedJavaUnicodeString percent(env, percent0); - UnicodeString groupingSeparator(groupingSeparator0); - - DecimalFormatSymbols* result = new DecimalFormatSymbols; - result->setSymbol(DecimalFormatSymbols::kCurrencySymbol, currencySymbol.unicodeString()); - result->setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol, UnicodeString(decimalSeparator)); - result->setSymbol(DecimalFormatSymbols::kDigitSymbol, UnicodeString(digit)); - result->setSymbol(DecimalFormatSymbols::kExponentialSymbol, exponentSeparator.unicodeString()); - result->setSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol, groupingSeparator); - result->setSymbol(DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol, groupingSeparator); - result->setSymbol(DecimalFormatSymbols::kInfinitySymbol, infinity.unicodeString()); - result->setSymbol(DecimalFormatSymbols::kIntlCurrencySymbol, internationalCurrencySymbol.unicodeString()); - result->setSymbol(DecimalFormatSymbols::kMinusSignSymbol, minusSign.unicodeString()); - result->setSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol, UnicodeString(monetaryDecimalSeparator)); - result->setSymbol(DecimalFormatSymbols::kNaNSymbol, nan.unicodeString()); - result->setSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol, UnicodeString(patternSeparator)); - result->setSymbol(DecimalFormatSymbols::kPercentSymbol, percent.unicodeString()); - result->setSymbol(DecimalFormatSymbols::kPerMillSymbol, UnicodeString(perMill)); + icu::UnicodeString groupingSeparator(groupingSeparator0); + + UErrorCode status = U_ZERO_ERROR; + std::unique_ptr<icu::DecimalFormatSymbols> result(icu::DecimalFormatSymbols::createWithLastResortData(status)); + if (maybeThrowIcuException(env, "DecimalFormatSymbols::createWithLastResortData", status)) { + return NULL; + } + + result->setSymbol(icu::DecimalFormatSymbols::kCurrencySymbol, currencySymbol.unicodeString()); + result->setSymbol(icu::DecimalFormatSymbols::kDecimalSeparatorSymbol, icu::UnicodeString(decimalSeparator)); + result->setSymbol(icu::DecimalFormatSymbols::kDigitSymbol, icu::UnicodeString(digit)); + result->setSymbol(icu::DecimalFormatSymbols::kExponentialSymbol, exponentSeparator.unicodeString()); + result->setSymbol(icu::DecimalFormatSymbols::kGroupingSeparatorSymbol, groupingSeparator); + result->setSymbol(icu::DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol, groupingSeparator); + result->setSymbol(icu::DecimalFormatSymbols::kInfinitySymbol, infinity.unicodeString()); + result->setSymbol(icu::DecimalFormatSymbols::kIntlCurrencySymbol, internationalCurrencySymbol.unicodeString()); + result->setSymbol(icu::DecimalFormatSymbols::kMinusSignSymbol, minusSign.unicodeString()); + result->setSymbol(icu::DecimalFormatSymbols::kMonetarySeparatorSymbol, icu::UnicodeString(monetaryDecimalSeparator)); + result->setSymbol(icu::DecimalFormatSymbols::kNaNSymbol, nan.unicodeString()); + result->setSymbol(icu::DecimalFormatSymbols::kPatternSeparatorSymbol, icu::UnicodeString(patternSeparator)); + result->setSymbol(icu::DecimalFormatSymbols::kPercentSymbol, percent.unicodeString()); + result->setSymbol(icu::DecimalFormatSymbols::kPerMillSymbol, icu::UnicodeString(perMill)); // java.text.DecimalFormatSymbols just uses a zero digit, // but ICU >= 4.6 has a field for each decimal digit. - result->setSymbol(DecimalFormatSymbols::kZeroDigitSymbol, UnicodeString(zeroDigit + 0)); - result->setSymbol(DecimalFormatSymbols::kOneDigitSymbol, UnicodeString(zeroDigit + 1)); - result->setSymbol(DecimalFormatSymbols::kTwoDigitSymbol, UnicodeString(zeroDigit + 2)); - result->setSymbol(DecimalFormatSymbols::kThreeDigitSymbol, UnicodeString(zeroDigit + 3)); - result->setSymbol(DecimalFormatSymbols::kFourDigitSymbol, UnicodeString(zeroDigit + 4)); - result->setSymbol(DecimalFormatSymbols::kFiveDigitSymbol, UnicodeString(zeroDigit + 5)); - result->setSymbol(DecimalFormatSymbols::kSixDigitSymbol, UnicodeString(zeroDigit + 6)); - result->setSymbol(DecimalFormatSymbols::kSevenDigitSymbol, UnicodeString(zeroDigit + 7)); - result->setSymbol(DecimalFormatSymbols::kEightDigitSymbol, UnicodeString(zeroDigit + 8)); - result->setSymbol(DecimalFormatSymbols::kNineDigitSymbol, UnicodeString(zeroDigit + 9)); - return result; + result->setSymbol(icu::DecimalFormatSymbols::kZeroDigitSymbol, icu::UnicodeString(zeroDigit + 0)); + result->setSymbol(icu::DecimalFormatSymbols::kOneDigitSymbol, icu::UnicodeString(zeroDigit + 1)); + result->setSymbol(icu::DecimalFormatSymbols::kTwoDigitSymbol, icu::UnicodeString(zeroDigit + 2)); + result->setSymbol(icu::DecimalFormatSymbols::kThreeDigitSymbol, icu::UnicodeString(zeroDigit + 3)); + result->setSymbol(icu::DecimalFormatSymbols::kFourDigitSymbol, icu::UnicodeString(zeroDigit + 4)); + result->setSymbol(icu::DecimalFormatSymbols::kFiveDigitSymbol, icu::UnicodeString(zeroDigit + 5)); + result->setSymbol(icu::DecimalFormatSymbols::kSixDigitSymbol, icu::UnicodeString(zeroDigit + 6)); + result->setSymbol(icu::DecimalFormatSymbols::kSevenDigitSymbol, icu::UnicodeString(zeroDigit + 7)); + result->setSymbol(icu::DecimalFormatSymbols::kEightDigitSymbol, icu::UnicodeString(zeroDigit + 8)); + result->setSymbol(icu::DecimalFormatSymbols::kNineDigitSymbol, icu::UnicodeString(zeroDigit + 9)); + return result.release(); } static void NativeDecimalFormat_setDecimalFormatSymbols(JNIEnv* env, jclass, jlong addr, @@ -98,7 +103,7 @@ static void NativeDecimalFormat_setDecimalFormatSymbols(JNIEnv* env, jclass, jlo jstring internationalCurrencySymbol, jstring minusSign, jchar monetaryDecimalSeparator, jstring nan, jchar patternSeparator, jstring percent, jchar perMill, jchar zeroDigit) { - DecimalFormatSymbols* symbols = makeDecimalFormatSymbols(env, + icu::DecimalFormatSymbols* symbols = makeDecimalFormatSymbols(env, currencySymbol, decimalSeparator, digit, exponentSeparator, groupingSeparator, infinity, internationalCurrencySymbol, minusSign, monetaryDecimalSeparator, nan, patternSeparator, percent, perMill, @@ -118,12 +123,12 @@ static jlong NativeDecimalFormat_open(JNIEnv* env, jclass, jstring pattern0, if (!pattern.valid()) { return 0; } - DecimalFormatSymbols* symbols = makeDecimalFormatSymbols(env, + icu::DecimalFormatSymbols* symbols = makeDecimalFormatSymbols(env, currencySymbol, decimalSeparator, digit, exponentSeparator, groupingSeparator, infinity, internationalCurrencySymbol, minusSign, monetaryDecimalSeparator, nan, patternSeparator, percent, perMill, zeroDigit); - DecimalFormat* fmt = new DecimalFormat(pattern.unicodeString(), symbols, parseError, status); + icu::DecimalFormat* fmt = new icu::DecimalFormat(pattern.unicodeString(), symbols, parseError, status); if (fmt == NULL) { delete symbols; } @@ -136,8 +141,8 @@ static void NativeDecimalFormat_close(JNIEnv*, jclass, jlong addr) { } static void NativeDecimalFormat_setRoundingMode(JNIEnv*, jclass, jlong addr, jint mode, jdouble increment) { - DecimalFormat* fmt = toDecimalFormat(addr); - fmt->setRoundingMode(static_cast<DecimalFormat::ERoundingMode>(mode)); + icu::DecimalFormat* fmt = toDecimalFormat(addr); + fmt->setRoundingMode(static_cast<icu::DecimalFormat::ERoundingMode>(mode)); fmt->setRoundingIncrement(increment); } @@ -179,7 +184,7 @@ static jstring NativeDecimalFormat_getTextAttribute(JNIEnv* env, jclass, jlong a UNumberFormatTextAttribute attr = static_cast<UNumberFormatTextAttribute>(javaAttr); // Find out how long the result will be... - UniquePtr<UChar[]> chars; + std::unique_ptr<UChar[]> chars; uint32_t charCount = 0; uint32_t desiredCount = unum_getTextAttribute(fmt, attr, chars.get(), charCount, &status); if (status == U_BUFFER_OVERFLOW_ERROR) { @@ -197,7 +202,7 @@ static void NativeDecimalFormat_applyPatternImpl(JNIEnv* env, jclass, jlong addr if (!pattern.valid()) { return; } - DecimalFormat* fmt = toDecimalFormat(addr); + icu::DecimalFormat* fmt = toDecimalFormat(addr); UErrorCode status = U_ZERO_ERROR; const char* function; if (localized) { @@ -211,8 +216,8 @@ static void NativeDecimalFormat_applyPatternImpl(JNIEnv* env, jclass, jlong addr } static jstring NativeDecimalFormat_toPatternImpl(JNIEnv* env, jclass, jlong addr, jboolean localized) { - DecimalFormat* fmt = toDecimalFormat(addr); - UnicodeString pattern; + icu::DecimalFormat* fmt = toDecimalFormat(addr); + icu::UnicodeString pattern; if (localized) { fmt->toLocalizedPattern(pattern); } else { @@ -221,12 +226,12 @@ static jstring NativeDecimalFormat_toPatternImpl(JNIEnv* env, jclass, jlong addr return env->NewString(pattern.getBuffer(), pattern.length()); } -static jcharArray formatResult(JNIEnv* env, const UnicodeString& s, FieldPositionIterator* fpi, jobject javaFieldPositionIterator) { +static jcharArray formatResult(JNIEnv* env, const icu::UnicodeString& s, icu::FieldPositionIterator* fpi, jobject javaFieldPositionIterator) { static jmethodID gFPI_setData = env->GetMethodID(JniConstants::fieldPositionIteratorClass, "setData", "([I)V"); if (fpi != NULL) { std::vector<int32_t> data; - FieldPosition fp; + icu::FieldPosition fp; while (fpi->next(fp)) { data.push_back(fp.getField()); data.push_back(fp.getBeginIndex()); @@ -258,10 +263,10 @@ static jcharArray formatResult(JNIEnv* env, const UnicodeString& s, FieldPositio template <typename T> static jcharArray format(JNIEnv* env, jlong addr, jobject javaFieldPositionIterator, T value) { UErrorCode status = U_ZERO_ERROR; - UnicodeString s; - DecimalFormat* fmt = toDecimalFormat(addr); - FieldPositionIterator nativeFieldPositionIterator; - FieldPositionIterator* fpi = javaFieldPositionIterator ? &nativeFieldPositionIterator : NULL; + icu::UnicodeString s; + icu::DecimalFormat* fmt = toDecimalFormat(addr); + icu::FieldPositionIterator nativeFieldPositionIterator; + icu::FieldPositionIterator* fpi = javaFieldPositionIterator ? &nativeFieldPositionIterator : NULL; fmt->format(value, s, fpi, status); if (maybeThrowIcuException(env, "DecimalFormat::format", status)) { return NULL; @@ -282,7 +287,7 @@ static jcharArray NativeDecimalFormat_formatDigitList(JNIEnv* env, jclass, jlong if (chars.c_str() == NULL) { return NULL; } - StringPiece sp(chars.c_str()); + icu::StringPiece sp(chars.c_str()); return format(env, addr, javaFieldPositionIterator, sp); } @@ -293,7 +298,7 @@ static jobject newBigDecimal(JNIEnv* env, const char* value, jsize len) { // value is a UTF-8 string of invariant characters, but isn't guaranteed to be // null-terminated. NewStringUTF requires a terminated UTF-8 string. So we copy the // data to jchars using UnicodeString, and call NewString instead. - UnicodeString tmp(value, len, UnicodeString::kInvariant); + icu::UnicodeString tmp(value, len, icu::UnicodeString::kInvariant); jobject str = env->NewString(tmp.getBuffer(), tmp.length()); return env->NewObject(JniConstants::bigDecimalClass, gBigDecimal_init, str); } @@ -318,9 +323,9 @@ static jobject NativeDecimalFormat_parse(JNIEnv* env, jclass, jlong addr, jstrin return NULL; } - Formattable res; - ParsePosition pp(parsePos); - DecimalFormat* fmt = toDecimalFormat(addr); + icu::Formattable res; + icu::ParsePosition pp(parsePos); + icu::DecimalFormat* fmt = toDecimalFormat(addr); fmt->parse(src.unicodeString(), res, pp); if (pp.getErrorIndex() == -1) { @@ -332,7 +337,7 @@ static jobject NativeDecimalFormat_parse(JNIEnv* env, jclass, jlong addr, jstrin if (parseBigDecimal) { UErrorCode status = U_ZERO_ERROR; - StringPiece str = res.getDecimalNumber(status); + icu::StringPiece str = res.getDecimalNumber(status); if (U_SUCCESS(status)) { int len = str.length(); const char* data = str.data(); @@ -348,15 +353,15 @@ static jobject NativeDecimalFormat_parse(JNIEnv* env, jclass, jlong addr, jstrin } 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()); + case icu::Formattable::kDouble: return doubleValueOf(env, res.getDouble()); + case icu::Formattable::kLong: return longValueOf(env, res.getLong()); + case icu::Formattable::kInt64: return longValueOf(env, res.getInt64()); default: return NULL; } } static jlong NativeDecimalFormat_cloneImpl(JNIEnv*, jclass, jlong addr) { - DecimalFormat* fmt = toDecimalFormat(addr); + icu::DecimalFormat* fmt = toDecimalFormat(addr); return reinterpret_cast<uintptr_t>(fmt->clone()); } diff --git a/luni/src/main/native/libcore_icu_NativeIDN.cpp b/luni/src/main/native/libcore_icu_NativeIDN.cpp index 16a6e1c..43f3ce5 100644 --- a/luni/src/main/native/libcore_icu_NativeIDN.cpp +++ b/luni/src/main/native/libcore_icu_NativeIDN.cpp @@ -39,9 +39,18 @@ static jstring NativeIDN_convertImpl(JNIEnv* env, jclass, jstring javaSrc, jint } UChar dst[256]; UErrorCode status = U_ZERO_ERROR; + + // We're stuck implementing IDNA-2003 for now since that's what we specify. + // + // TODO: Change our spec to IDNA-2008 + UTS-46 compatibility processing if + // it's safe enough. +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" size_t resultLength = toAscii ? uidna_IDNToASCII(src.get(), src.size(), &dst[0], sizeof(dst), flags, NULL, &status) : uidna_IDNToUnicode(src.get(), src.size(), &dst[0], sizeof(dst), flags, NULL, &status); +#pragma GCC diagnostic pop + if (U_FAILURE(status)) { jniThrowException(env, "java/lang/IllegalArgumentException", u_errorName(status)); return NULL; diff --git a/luni/src/main/native/libcore_icu_NativeNormalizer.cpp b/luni/src/main/native/libcore_icu_NativeNormalizer.cpp index 8ae42d9..2d5e282 100644 --- a/luni/src/main/native/libcore_icu_NativeNormalizer.cpp +++ b/luni/src/main/native/libcore_icu_NativeNormalizer.cpp @@ -30,8 +30,8 @@ static jstring NativeNormalizer_normalizeImpl(JNIEnv* env, jclass, jstring s, ji } UNormalizationMode mode = static_cast<UNormalizationMode>(intMode); UErrorCode status = U_ZERO_ERROR; - UnicodeString dst; - Normalizer::normalize(src.unicodeString(), mode, 0, dst, status); + icu::UnicodeString dst; + icu::Normalizer::normalize(src.unicodeString(), mode, 0, dst, status); maybeThrowIcuException(env, "Normalizer::normalize", status); return dst.isBogus() ? NULL : env->NewString(dst.getBuffer(), dst.length()); } @@ -43,7 +43,7 @@ static jboolean NativeNormalizer_isNormalizedImpl(JNIEnv* env, jclass, jstring s } UNormalizationMode mode = static_cast<UNormalizationMode>(intMode); UErrorCode status = U_ZERO_ERROR; - UBool result = Normalizer::isNormalized(src.unicodeString(), mode, status); + UBool result = icu::Normalizer::isNormalized(src.unicodeString(), mode, status); maybeThrowIcuException(env, "Normalizer::isNormalized", status); return result; } diff --git a/luni/src/main/native/libcore_icu_NativePluralRules.cpp b/luni/src/main/native/libcore_icu_NativePluralRules.cpp index 8910a8c..f278485 100644 --- a/luni/src/main/native/libcore_icu_NativePluralRules.cpp +++ b/luni/src/main/native/libcore_icu_NativePluralRules.cpp @@ -25,8 +25,8 @@ #include <string> -static PluralRules* toPluralRules(jlong address) { - return reinterpret_cast<PluralRules*>(static_cast<uintptr_t>(address)); +static icu::PluralRules* toPluralRules(jlong address) { + return reinterpret_cast<icu::PluralRules*>(static_cast<uintptr_t>(address)); } static void NativePluralRules_finalizeImpl(JNIEnv*, jclass, jlong address) { @@ -48,15 +48,15 @@ static jlong NativePluralRules_forLocaleImpl(JNIEnv* env, jclass, jstring javaLo localeName[1] = 'i'; } - Locale locale = Locale::createFromName(localeName.c_str()); + icu::Locale locale = icu::Locale::createFromName(localeName.c_str()); UErrorCode status = U_ZERO_ERROR; - PluralRules* result = PluralRules::forLocale(locale, status); + icu::PluralRules* result = icu::PluralRules::forLocale(locale, status); maybeThrowIcuException(env, "PluralRules::forLocale", status); return reinterpret_cast<uintptr_t>(result); } static jint NativePluralRules_quantityForIntImpl(JNIEnv*, jclass, jlong address, jint value) { - UnicodeString keyword = toPluralRules(address)->select(value); + icu::UnicodeString keyword = toPluralRules(address)->select(value); if (keyword == "zero") { return 0; } else if (keyword == "one") { diff --git a/luni/src/main/native/libcore_icu_TimeZoneNames.cpp b/luni/src/main/native/libcore_icu_TimeZoneNames.cpp index a7c9098..d30e7a3 100644 --- a/luni/src/main/native/libcore_icu_TimeZoneNames.cpp +++ b/luni/src/main/native/libcore_icu_TimeZoneNames.cpp @@ -16,6 +16,8 @@ #define LOG_TAG "TimeZoneNames" +#include <memory> + #include "IcuUtilities.h" #include "JNIHelp.h" #include "JniConstants.h" @@ -24,32 +26,31 @@ #include "ScopedJavaUnicodeString.h" #include "ScopedLocalRef.h" #include "ScopedUtfChars.h" -#include "UniquePtr.h" #include "unicode/calendar.h" #include "unicode/timezone.h" #include "unicode/tznames.h" -static bool isUtc(const UnicodeString& id) { - static const UnicodeString kEtcUct("Etc/UCT", 7, US_INV); - static const UnicodeString kEtcUtc("Etc/UTC", 7, US_INV); - static const UnicodeString kEtcUniversal("Etc/Universal", 13, US_INV); - static const UnicodeString kEtcZulu("Etc/Zulu", 8, US_INV); +static bool isUtc(const icu::UnicodeString& id) { + static const icu::UnicodeString kEtcUct("Etc/UCT", 7, US_INV); + static const icu::UnicodeString kEtcUtc("Etc/UTC", 7, US_INV); + static const icu::UnicodeString kEtcUniversal("Etc/Universal", 13, US_INV); + static const icu::UnicodeString kEtcZulu("Etc/Zulu", 8, US_INV); - static const UnicodeString kUct("UCT", 3, US_INV); - static const UnicodeString kUtc("UTC", 3, US_INV); - static const UnicodeString kUniversal("Universal", 9, US_INV); - static const UnicodeString kZulu("Zulu", 4, US_INV); + static const icu::UnicodeString kUct("UCT", 3, US_INV); + static const icu::UnicodeString kUtc("UTC", 3, US_INV); + static const icu::UnicodeString kUniversal("Universal", 9, US_INV); + static const icu::UnicodeString kZulu("Zulu", 4, US_INV); return id == kEtcUct || id == kEtcUtc || id == kEtcUniversal || id == kEtcZulu || id == kUct || id == kUtc || id == kUniversal || id == kZulu; } -static bool setStringArrayElement(JNIEnv* env, jobjectArray array, int i, const UnicodeString& s) { +static bool setStringArrayElement(JNIEnv* env, jobjectArray array, int i, const icu::UnicodeString& s) { // Fill in whatever we got. We don't use the display names if they're "GMT[+-]xx:xx" // because icu4c doesn't use the up-to-date time zone transition data, so it gets these // wrong. TimeZone.getDisplayName creates accurate names on demand. // TODO: investigate whether it's worth doing that work once in the Java wrapper instead of on-demand. - static const UnicodeString kGmt("GMT", 3, US_INV); + static const icu::UnicodeString kGmt("GMT", 3, US_INV); if (!s.isBogus() && !s.startsWith(kGmt)) { ScopedLocalRef<jstring> javaString(env, env->NewString(s.getBuffer(), s.length())); if (javaString.get() == NULL) { @@ -67,14 +68,14 @@ static void TimeZoneNames_fillZoneStrings(JNIEnv* env, jclass, jstring javaLocal } UErrorCode status = U_ZERO_ERROR; - UniquePtr<TimeZoneNames> names(TimeZoneNames::createInstance(icuLocale.locale(), status)); + std::unique_ptr<icu::TimeZoneNames> names(icu::TimeZoneNames::createInstance(icuLocale.locale(), status)); if (maybeThrowIcuException(env, "TimeZoneNames::createInstance", status)) { return; } - const UDate now(Calendar::getNow()); + const UDate now(icu::Calendar::getNow()); - static const UnicodeString kUtc("UTC", 3, US_INV); + static const icu::UnicodeString kUtc("UTC", 3, US_INV); size_t id_count = env->GetArrayLength(result); for (size_t i = 0; i < id_count; ++i) { @@ -87,13 +88,13 @@ static void TimeZoneNames_fillZoneStrings(JNIEnv* env, jclass, jstring javaLocal return; } - UnicodeString long_std; + icu::UnicodeString long_std; names->getDisplayName(zone_id.unicodeString(), UTZNM_LONG_STANDARD, now, long_std); - UnicodeString short_std; + icu::UnicodeString short_std; names->getDisplayName(zone_id.unicodeString(), UTZNM_SHORT_STANDARD, now, short_std); - UnicodeString long_dst; + icu::UnicodeString long_dst; names->getDisplayName(zone_id.unicodeString(), UTZNM_LONG_DAYLIGHT, now, long_dst); - UnicodeString short_dst; + icu::UnicodeString short_dst; names->getDisplayName(zone_id.unicodeString(), UTZNM_SHORT_DAYLIGHT, now, short_dst); if (isUtc(zone_id.unicodeString())) { @@ -123,7 +124,7 @@ static jstring TimeZoneNames_getExemplarLocation(JNIEnv* env, jclass, jstring ja } UErrorCode status = U_ZERO_ERROR; - UniquePtr<TimeZoneNames> names(TimeZoneNames::createInstance(icuLocale.locale(), status)); + std::unique_ptr<icu::TimeZoneNames> names(icu::TimeZoneNames::createInstance(icuLocale.locale(), status)); if (maybeThrowIcuException(env, "TimeZoneNames::createInstance", status)) { return NULL; } @@ -133,8 +134,8 @@ static jstring TimeZoneNames_getExemplarLocation(JNIEnv* env, jclass, jstring ja return NULL; } - UnicodeString s; - const UDate now(Calendar::getNow()); + icu::UnicodeString s; + const UDate now(icu::Calendar::getNow()); names->getDisplayName(tz.unicodeString(), UTZNM_EXEMPLAR_LOCATION, now, s); return env->NewString(s.getBuffer(), s.length()); } diff --git a/luni/src/main/native/libcore_icu_Transliterator.cpp b/luni/src/main/native/libcore_icu_Transliterator.cpp index 0c52053..ae21565 100644 --- a/luni/src/main/native/libcore_icu_Transliterator.cpp +++ b/luni/src/main/native/libcore_icu_Transliterator.cpp @@ -23,8 +23,8 @@ #include "ScopedJavaUnicodeString.h" #include "unicode/translit.h" -static Transliterator* fromPeer(jlong peer) { - return reinterpret_cast<Transliterator*>(static_cast<uintptr_t>(peer)); +static icu::Transliterator* fromPeer(jlong peer) { + return reinterpret_cast<icu::Transliterator*>(static_cast<uintptr_t>(peer)); } static jlong Transliterator_create(JNIEnv* env, jclass, jstring javaId) { @@ -33,7 +33,7 @@ static jlong Transliterator_create(JNIEnv* env, jclass, jstring javaId) { return 0; } UErrorCode status = U_ZERO_ERROR; - Transliterator* t = Transliterator::createInstance(id.unicodeString(), UTRANS_FORWARD, status); + icu::Transliterator* t = icu::Transliterator::createInstance(id.unicodeString(), UTRANS_FORWARD, status); if (maybeThrowIcuException(env, "Transliterator::createInstance", status)) { return 0; } @@ -46,18 +46,18 @@ static void Transliterator_destroy(JNIEnv*, jclass, jlong peer) { static jobjectArray Transliterator_getAvailableIDs(JNIEnv* env, jclass) { UErrorCode status = U_ZERO_ERROR; - StringEnumeration* e = Transliterator::getAvailableIDs(status); + icu::StringEnumeration* e = icu::Transliterator::getAvailableIDs(status); return fromStringEnumeration(env, status, "Transliterator::getAvailableIDs", e); } static jstring Transliterator_transliterate(JNIEnv* env, jclass, jlong peer, jstring javaString) { - Transliterator* t = fromPeer(peer); + icu::Transliterator* t = fromPeer(peer); ScopedJavaUnicodeString string(env, javaString); if (!string.valid()) { return NULL; } - UnicodeString& s(string.unicodeString()); + icu::UnicodeString& s(string.unicodeString()); t->transliterate(s); return env->NewString(s.getBuffer(), s.length()); } diff --git a/luni/src/main/native/libcore_io_Memory.cpp b/luni/src/main/native/libcore_io_Memory.cpp index 9edbfb8..5122a6c 100644 --- a/luni/src/main/native/libcore_io_Memory.cpp +++ b/luni/src/main/native/libcore_io_Memory.cpp @@ -21,32 +21,12 @@ #include "Portability.h" #include "ScopedBytes.h" #include "ScopedPrimitiveArray.h" -#include "UniquePtr.h" #include <errno.h> #include <stdlib.h> #include <string.h> #include <sys/mman.h> -#if defined(__arm__) -// 32-bit ARM has load/store alignment restrictions for longs. -#define LONG_ALIGNMENT_MASK 0x3 -#define INT_ALIGNMENT_MASK 0x0 -#define SHORT_ALIGNMENT_MASK 0x0 -#elif defined(__mips__) -// MIPS has load/store alignment restrictions for longs, ints and shorts. -#define LONG_ALIGNMENT_MASK 0x7 -#define INT_ALIGNMENT_MASK 0x3 -#define SHORT_ALIGNMENT_MASK 0x1 -#elif defined(__aarch64__) || defined(__i386__) || defined(__x86_64__) -// These architectures can load anything at any alignment. -#define LONG_ALIGNMENT_MASK 0x0 -#define INT_ALIGNMENT_MASK 0x0 -#define SHORT_ALIGNMENT_MASK 0x0 -#else -#error unknown load/store alignment restrictions for this architecture -#endif - // Use packed structures for access to unaligned data on targets with alignment restrictions. // The compiler will generate appropriate code to access these structures without // generating alignment exceptions. @@ -82,63 +62,31 @@ static inline void swapShorts(jshort* dstShorts, const jshort* srcShorts, size_t // Do 32-bit swaps as long as possible... jint* dst = reinterpret_cast<jint*>(dstShorts); const jint* src = reinterpret_cast<const jint*>(srcShorts); - - if ((reinterpret_cast<uintptr_t>(dst) & INT_ALIGNMENT_MASK) == 0 && - (reinterpret_cast<uintptr_t>(src) & INT_ALIGNMENT_MASK) == 0) { - for (size_t i = 0; i < count / 2; ++i) { - jint v = *src++; - *dst++ = bswap_2x16(v); - } - // ...with one last 16-bit swap if necessary. - if ((count % 2) != 0) { - jshort v = *reinterpret_cast<const jshort*>(src); - *reinterpret_cast<jshort*>(dst) = bswap_16(v); - } - } else { - for (size_t i = 0; i < count / 2; ++i) { - jint v = get_unaligned<jint>(src++); - put_unaligned<jint>(dst++, bswap_2x16(v)); - } - if ((count % 2) != 0) { - jshort v = get_unaligned<jshort>(reinterpret_cast<const jshort*>(src)); - put_unaligned<jshort>(reinterpret_cast<jshort*>(dst), bswap_16(v)); - } + for (size_t i = 0; i < count / 2; ++i) { + jint v = get_unaligned<jint>(src++); + put_unaligned<jint>(dst++, bswap_2x16(v)); + } + if ((count % 2) != 0) { + jshort v = get_unaligned<jshort>(reinterpret_cast<const jshort*>(src)); + put_unaligned<jshort>(reinterpret_cast<jshort*>(dst), bswap_16(v)); } } static inline void swapInts(jint* dstInts, const jint* srcInts, size_t count) { - if ((reinterpret_cast<uintptr_t>(dstInts) & INT_ALIGNMENT_MASK) == 0 && - (reinterpret_cast<uintptr_t>(srcInts) & INT_ALIGNMENT_MASK) == 0) { - for (size_t i = 0; i < count; ++i) { - jint v = *srcInts++; - *dstInts++ = bswap_32(v); - } - } else { - for (size_t i = 0; i < count; ++i) { - jint v = get_unaligned<int>(srcInts++); - put_unaligned<jint>(dstInts++, bswap_32(v)); - } + for (size_t i = 0; i < count; ++i) { + jint v = get_unaligned<int>(srcInts++); + put_unaligned<jint>(dstInts++, bswap_32(v)); } } static inline void swapLongs(jlong* dstLongs, const jlong* srcLongs, size_t count) { jint* dst = reinterpret_cast<jint*>(dstLongs); const jint* src = reinterpret_cast<const jint*>(srcLongs); - if ((reinterpret_cast<uintptr_t>(dstLongs) & INT_ALIGNMENT_MASK) == 0 && - (reinterpret_cast<uintptr_t>(srcLongs) & INT_ALIGNMENT_MASK) == 0) { - for (size_t i = 0; i < count; ++i) { - jint v1 = *src++; - jint v2 = *src++; - *dst++ = bswap_32(v2); - *dst++ = bswap_32(v1); - } - } else { - for (size_t i = 0; i < count; ++i) { - jint v1 = get_unaligned<jint>(src++); - jint v2 = get_unaligned<jint>(src++); - put_unaligned<jint>(dst++, bswap_32(v2)); - put_unaligned<jint>(dst++, bswap_32(v1)); - } + for (size_t i = 0; i < count; ++i) { + jint v1 = get_unaligned<jint>(src++); + jint v2 = get_unaligned<jint>(src++); + put_unaligned<jint>(dst++, bswap_32(v2)); + put_unaligned<jint>(dst++, bswap_32(v1)); } } @@ -260,39 +208,27 @@ static void Memory_pokeShortArray(JNIEnv* env, jclass, jlong dstAddress, jshortA } static jshort Memory_peekShortNative(JNIEnv*, jclass, jlong srcAddress) { - return *cast<const jshort*>(srcAddress); + return get_unaligned<jshort>(cast<const jshort*>(srcAddress)); } static void Memory_pokeShortNative(JNIEnv*, jclass, jlong dstAddress, jshort value) { - *cast<jshort*>(dstAddress) = value; + put_unaligned<jshort>(cast<jshort*>(dstAddress), value); } static jint Memory_peekIntNative(JNIEnv*, jclass, jlong srcAddress) { - return *cast<const jint*>(srcAddress); + return get_unaligned<jint>(cast<const jint*>(srcAddress)); } static void Memory_pokeIntNative(JNIEnv*, jclass, jlong dstAddress, jint value) { - *cast<jint*>(dstAddress) = value; + put_unaligned<jint>(cast<jint*>(dstAddress), value); } static jlong Memory_peekLongNative(JNIEnv*, jclass, jlong srcAddress) { - jlong result; - const jlong* src = cast<const jlong*>(srcAddress); - if ((srcAddress & LONG_ALIGNMENT_MASK) == 0) { - result = *src; - } else { - result = get_unaligned<jlong>(src); - } - return result; + return get_unaligned<jlong>(cast<const jlong*>(srcAddress)); } static void Memory_pokeLongNative(JNIEnv*, jclass, jlong dstAddress, jlong value) { - jlong* dst = cast<jlong*>(dstAddress); - if ((dstAddress & LONG_ALIGNMENT_MASK) == 0) { - *dst = value; - } else { - put_unaligned<jlong>(dst, value); - } + put_unaligned<jlong>(cast<jlong*>(dstAddress), value); } static void unsafeBulkCopy(jbyte* dst, const jbyte* src, jint byteCount, diff --git a/luni/src/main/native/libcore_io_Posix.cpp b/luni/src/main/native/libcore_io_Posix.cpp index 7e9b22e..f6af483 100644 --- a/luni/src/main/native/libcore_io_Posix.cpp +++ b/luni/src/main/native/libcore_io_Posix.cpp @@ -25,20 +25,20 @@ #include "NetworkUtilities.h" #include "Portability.h" #include "readlink.h" -#include "../../bionic/libc/dns/include/resolv_netid.h" // For android_getaddrinfofornet. #include "ScopedBytes.h" #include "ScopedLocalRef.h" #include "ScopedPrimitiveArray.h" #include "ScopedUtfChars.h" #include "toStringArray.h" -#include "UniquePtr.h" #include <arpa/inet.h> #include <errno.h> #include <fcntl.h> +#include <linux/rtnetlink.h> #include <net/if.h> #include <netdb.h> #include <netinet/in.h> +#include <netpacket/packet.h> #include <poll.h> #include <pwd.h> #include <signal.h> @@ -61,7 +61,7 @@ #include <sys/wait.h> #include <termios.h> #include <unistd.h> - +#include <memory> #ifndef __unused #define __unused __attribute__((__unused__)) @@ -79,6 +79,52 @@ struct addrinfo_deleter { } }; +static bool isIPv4MappedAddress(const sockaddr *sa) { + const sockaddr_in6 *sin6 = reinterpret_cast<const sockaddr_in6*>(sa); + return sa != NULL && sa->sa_family == AF_INET6 && + (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr) || + IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)); // We map 0.0.0.0 to ::, so :: is mapped. +} + +/** + * Perform a socket operation that specifies an IP address, possibly falling back from specifying + * the address as an IPv4-mapped IPv6 address in a struct sockaddr_in6 to specifying it as an IPv4 + * address in a struct sockaddr_in. + * + * This is needed because all sockets created by the java.net APIs are IPv6 sockets, and on those + * sockets, IPv4 operations use IPv4-mapped addresses stored in a struct sockaddr_in6. But sockets + * created using Posix.socket(AF_INET, ...) are IPv4 sockets and only support operations using IPv4 + * socket addresses structures. + */ +#define NET_IPV4_FALLBACK(jni_env, return_type, syscall_name, java_fd, java_addr, port, null_addr_ok, args...) ({ \ + return_type _rc = -1; \ + do { \ + sockaddr_storage _ss; \ + socklen_t _salen; \ + if (java_addr == NULL && null_addr_ok) { \ + /* No IP address specified (e.g., sendto() on a connected socket). */ \ + _salen = 0; \ + } else if (!inetAddressToSockaddr(jni_env, java_addr, port, _ss, _salen)) { \ + /* Invalid socket address, return -1. inetAddressToSockaddr has already thrown. */ \ + break; \ + } \ + sockaddr* _sa = _salen ? reinterpret_cast<sockaddr*>(&_ss) : NULL; \ + /* inetAddressToSockaddr always returns an IPv6 sockaddr. Assume that java_fd was created \ + * by Java API calls, which always create IPv6 socket fds, and pass it in as is. */ \ + _rc = NET_FAILURE_RETRY(jni_env, return_type, syscall_name, java_fd, ##args, _sa, _salen); \ + if (_rc == -1 && errno == EAFNOSUPPORT && _salen && isIPv4MappedAddress(_sa)) { \ + /* We passed in an IPv4 address in an IPv6 sockaddr and the kernel told us that we got \ + * the address family wrong. Pass in the same address in an IPv4 sockaddr. */ \ + jni_env->ExceptionClear(); \ + if (!inetAddressToSockaddrVerbatim(jni_env, java_addr, port, _ss, _salen)) { \ + break; \ + } \ + _sa = reinterpret_cast<sockaddr*>(&_ss); \ + _rc = NET_FAILURE_RETRY(jni_env, return_type, syscall_name, java_fd, ##args, _sa, _salen); \ + } \ + } while (0); \ + _rc; }) \ + /** * Used to retry networking system calls that can be interrupted with a signal. Unlike * TEMP_FAILURE_RETRY, this also handles the case where @@ -150,6 +196,9 @@ struct addrinfo_deleter { } while (_rc == -1); /* && _syscallErrno == EINTR && !_wasSignaled */ \ _rc; }) +#define NULL_ADDR_OK true +#define NULL_ADDR_FORBIDDEN false + static void throwException(JNIEnv* env, jclass exceptionClass, jmethodID ctor3, jmethodID ctor2, const char* functionName, int error) { jthrowable cause = NULL; @@ -268,14 +317,43 @@ private: }; static jobject makeSocketAddress(JNIEnv* env, const sockaddr_storage& ss) { - jint port; - jobject inetAddress = sockaddrToInetAddress(env, ss, &port); - if (inetAddress == NULL) { - return NULL; - } - static jmethodID ctor = env->GetMethodID(JniConstants::inetSocketAddressClass, "<init>", - "(Ljava/net/InetAddress;I)V"); - return env->NewObject(JniConstants::inetSocketAddressClass, ctor, inetAddress, port); + if (ss.ss_family == AF_INET || ss.ss_family == AF_INET6 || ss.ss_family == AF_UNIX) { + jint port; + jobject inetAddress = sockaddrToInetAddress(env, ss, &port); + if (inetAddress == NULL) { + return NULL; // Exception already thrown. + } + static jmethodID ctor = env->GetMethodID(JniConstants::inetSocketAddressClass, + "<init>", "(Ljava/net/InetAddress;I)V"); + return env->NewObject(JniConstants::inetSocketAddressClass, ctor, inetAddress, port); + } else if (ss.ss_family == AF_NETLINK) { + const struct sockaddr_nl* nl_addr = reinterpret_cast<const struct sockaddr_nl*>(&ss); + static jmethodID ctor = env->GetMethodID(JniConstants::netlinkSocketAddressClass, + "<init>", "(II)V"); + return env->NewObject(JniConstants::netlinkSocketAddressClass, ctor, + static_cast<jint>(nl_addr->nl_pid), + static_cast<jint>(nl_addr->nl_groups)); + } else if (ss.ss_family == AF_PACKET) { + const struct sockaddr_ll* sll = reinterpret_cast<const struct sockaddr_ll*>(&ss); + static jmethodID ctor = env->GetMethodID(JniConstants::packetSocketAddressClass, + "<init>", "(SISB[B)V"); + ScopedLocalRef<jbyteArray> byteArray(env, env->NewByteArray(sll->sll_halen)); + if (byteArray.get() == NULL) { + return NULL; + } + env->SetByteArrayRegion(byteArray.get(), 0, sll->sll_halen, + reinterpret_cast<const jbyte*>(sll->sll_addr)); + jobject packetSocketAddress = env->NewObject(JniConstants::packetSocketAddressClass, ctor, + static_cast<jshort>(ntohs(sll->sll_protocol)), + static_cast<jint>(sll->sll_ifindex), + static_cast<jshort>(sll->sll_hatype), + static_cast<jbyte>(sll->sll_pkttype), + byteArray.get()); + return packetSocketAddress; + } + jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", "unsupported ss_family: %d", + ss.ss_family); + return NULL; } static jobject makeStructPasswd(JNIEnv* env, const struct passwd& pw) { @@ -386,6 +464,93 @@ static bool fillInetSocketAddress(JNIEnv* env, jint rc, jobject javaInetSocketAd return true; } +static void javaInetSocketAddressToInetAddressAndPort( + JNIEnv* env, jobject javaInetSocketAddress, jobject& javaInetAddress, jint& port) { + static jfieldID addressFid = env->GetFieldID( + JniConstants::inetSocketAddressClass, "addr", "Ljava/net/InetAddress;"); + static jfieldID portFid = env->GetFieldID(JniConstants::inetSocketAddressClass, "port", "I"); + javaInetAddress = env->GetObjectField(javaInetSocketAddress, addressFid); + port = env->GetIntField(javaInetSocketAddress, portFid); +} + +static bool javaInetSocketAddressToSockaddr( + JNIEnv* env, jobject javaSocketAddress, sockaddr_storage& ss, socklen_t& sa_len) { + jobject javaInetAddress; + jint port; + javaInetSocketAddressToInetAddressAndPort(env, javaSocketAddress, javaInetAddress, port); + return inetAddressToSockaddr(env, javaInetAddress, port, ss, sa_len); +} + +static bool javaNetlinkSocketAddressToSockaddr( + JNIEnv* env, jobject javaSocketAddress, sockaddr_storage& ss, socklen_t& sa_len) { + static jfieldID nlPidFid = env->GetFieldID( + JniConstants::netlinkSocketAddressClass, "nlPortId", "I"); + static jfieldID nlGroupsFid = env->GetFieldID( + JniConstants::netlinkSocketAddressClass, "nlGroupsMask", "I"); + + sockaddr_nl *nlAddr = reinterpret_cast<sockaddr_nl *>(&ss); + nlAddr->nl_family = AF_NETLINK; + nlAddr->nl_pid = env->GetIntField(javaSocketAddress, nlPidFid); + nlAddr->nl_groups = env->GetIntField(javaSocketAddress, nlGroupsFid); + sa_len = sizeof(sockaddr_nl); + return true; +} + +static bool javaPacketSocketAddressToSockaddr( + JNIEnv* env, jobject javaSocketAddress, sockaddr_storage& ss, socklen_t& sa_len) { + static jfieldID protocolFid = env->GetFieldID( + JniConstants::packetSocketAddressClass, "sll_protocol", "S"); + static jfieldID ifindexFid = env->GetFieldID( + JniConstants::packetSocketAddressClass, "sll_ifindex", "I"); + static jfieldID hatypeFid = env->GetFieldID( + JniConstants::packetSocketAddressClass, "sll_hatype", "S"); + static jfieldID pkttypeFid = env->GetFieldID( + JniConstants::packetSocketAddressClass, "sll_pkttype", "B"); + static jfieldID addrFid = env->GetFieldID( + JniConstants::packetSocketAddressClass, "sll_addr", "[B"); + + sockaddr_ll *sll = reinterpret_cast<sockaddr_ll *>(&ss); + sll->sll_family = AF_PACKET; + sll->sll_protocol = htons(env->GetShortField(javaSocketAddress, protocolFid)); + sll->sll_ifindex = env->GetIntField(javaSocketAddress, ifindexFid); + sll->sll_hatype = env->GetShortField(javaSocketAddress, hatypeFid); + sll->sll_pkttype = env->GetByteField(javaSocketAddress, pkttypeFid); + + jbyteArray sllAddr = (jbyteArray) env->GetObjectField(javaSocketAddress, addrFid); + if (sllAddr == NULL) { + sll->sll_halen = 0; + memset(&sll->sll_addr, 0, sizeof(sll->sll_addr)); + } else { + jsize len = env->GetArrayLength(sllAddr); + if ((size_t) len > sizeof(sll->sll_addr)) { + len = sizeof(sll->sll_addr); + } + sll->sll_halen = len; + env->GetByteArrayRegion(sllAddr, 0, len, (jbyte*) sll->sll_addr); + } + sa_len = sizeof(sockaddr_ll); + return true; +} + +static bool javaSocketAddressToSockaddr( + JNIEnv* env, jobject javaSocketAddress, sockaddr_storage& ss, socklen_t& sa_len) { + if (javaSocketAddress == NULL) { + jniThrowNullPointerException(env, NULL); + return false; + } + + if (env->IsInstanceOf(javaSocketAddress, JniConstants::netlinkSocketAddressClass)) { + return javaNetlinkSocketAddressToSockaddr(env, javaSocketAddress, ss, sa_len); + } else if (env->IsInstanceOf(javaSocketAddress, JniConstants::inetSocketAddressClass)) { + return javaInetSocketAddressToSockaddr(env, javaSocketAddress, ss, sa_len); + } else if (env->IsInstanceOf(javaSocketAddress, JniConstants::packetSocketAddressClass)) { + return javaPacketSocketAddressToSockaddr(env, javaSocketAddress, ss, sa_len); + } + jniThrowException(env, "java/lang/UnsupportedOperationException", + "unsupported SocketAddress subclass"); + return false; +} + static jobject doStat(JNIEnv* env, jstring javaPath, bool isLstat) { ScopedUtfChars path(env, javaPath); if (path.c_str() == NULL) { @@ -446,7 +611,7 @@ private: } JNIEnv* mEnv; - UniquePtr<char[]> mBuffer; + std::unique_ptr<char[]> mBuffer; size_t mBufferSize; struct passwd mPwd; struct passwd* mResult; @@ -479,11 +644,18 @@ static jboolean Posix_access(JNIEnv* env, jobject, jstring javaPath, jint mode) } static void Posix_bind(JNIEnv* env, jobject, jobject javaFd, jobject javaAddress, jint port) { + // We don't need the return value because we'll already have thrown. + (void) NET_IPV4_FALLBACK(env, int, bind, javaFd, javaAddress, port, NULL_ADDR_FORBIDDEN); +} + +static void Posix_bindSocketAddress( + JNIEnv* env, jobject, jobject javaFd, jobject javaSocketAddress) { sockaddr_storage ss; socklen_t sa_len; - if (!inetAddressToSockaddr(env, javaAddress, port, ss, sa_len)) { - return; + if (!javaSocketAddressToSockaddr(env, javaSocketAddress, ss, sa_len)) { + return; // Exception already thrown. } + const sockaddr* sa = reinterpret_cast<const sockaddr*>(&ss); // We don't need the return value because we'll already have thrown. (void) NET_FAILURE_RETRY(env, int, bind, javaFd, sa, sa_len); @@ -518,11 +690,17 @@ static void Posix_close(JNIEnv* env, jobject, jobject javaFd) { } static void Posix_connect(JNIEnv* env, jobject, jobject javaFd, jobject javaAddress, jint port) { + (void) NET_IPV4_FALLBACK(env, int, connect, javaFd, javaAddress, port, NULL_ADDR_FORBIDDEN); +} + +static void Posix_connectSocketAddress( + JNIEnv* env, jobject, jobject javaFd, jobject javaSocketAddress) { sockaddr_storage ss; socklen_t sa_len; - if (!inetAddressToSockaddr(env, javaAddress, port, ss, sa_len)) { - return; + if (!javaSocketAddressToSockaddr(env, javaSocketAddress, ss, sa_len)) { + return; // Exception already thrown. } + const sockaddr* sa = reinterpret_cast<const sockaddr*>(&ss); // We don't need the return value because we'll already have thrown. (void) NET_FAILURE_RETRY(env, int, connect, javaFd, sa, sa_len); @@ -553,7 +731,7 @@ static void Posix_execve(JNIEnv* env, jobject, jstring javaFilename, jobjectArra ExecStrings argv(env, javaArgv); ExecStrings envp(env, javaEnvp); - execve(path.c_str(), argv.get(), envp.get()); + TEMP_FAILURE_RETRY(execve(path.c_str(), argv.get(), envp.get())); throwErrnoException(env, "execve"); } @@ -565,7 +743,7 @@ static void Posix_execv(JNIEnv* env, jobject, jstring javaFilename, jobjectArray } ExecStrings argv(env, javaArgv); - execv(path.c_str(), argv.get()); + TEMP_FAILURE_RETRY(execv(path.c_str(), argv.get())); throwErrnoException(env, "execv"); } @@ -580,16 +758,6 @@ static void Posix_fchown(JNIEnv* env, jobject, jobject javaFd, jint uid, jint gi throwIfMinusOne(env, "fchown", TEMP_FAILURE_RETRY(fchown(fd, uid, gid))); } -static jint Posix_fcntlVoid(JNIEnv* env, jobject, jobject javaFd, jint cmd) { - int fd = jniGetFDFromFileDescriptor(env, javaFd); - return throwIfMinusOne(env, "fcntl", TEMP_FAILURE_RETRY(fcntl(fd, cmd))); -} - -static jint Posix_fcntlLong(JNIEnv* env, jobject, jobject javaFd, jint cmd, jlong arg) { - int fd = jniGetFDFromFileDescriptor(env, javaFd); - return throwIfMinusOne(env, "fcntl", TEMP_FAILURE_RETRY(fcntl(fd, cmd, arg))); -} - static jint Posix_fcntlFlock(JNIEnv* env, jobject, jobject javaFd, jint cmd, jobject javaFlock) { static jfieldID typeFid = env->GetFieldID(JniConstants::structFlockClass, "l_type", "S"); static jfieldID whenceFid = env->GetFieldID(JniConstants::structFlockClass, "l_whence", "S"); @@ -616,6 +784,16 @@ static jint Posix_fcntlFlock(JNIEnv* env, jobject, jobject javaFd, jint cmd, job return rc; } +static jint Posix_fcntlInt(JNIEnv* env, jobject, jobject javaFd, jint cmd, jint arg) { + int fd = jniGetFDFromFileDescriptor(env, javaFd); + return throwIfMinusOne(env, "fcntl", TEMP_FAILURE_RETRY(fcntl(fd, cmd, arg))); +} + +static jint Posix_fcntlVoid(JNIEnv* env, jobject, jobject javaFd, jint cmd) { + int fd = jniGetFDFromFileDescriptor(env, javaFd); + return throwIfMinusOne(env, "fcntl", TEMP_FAILURE_RETRY(fcntl(fd, cmd))); +} + static void Posix_fdatasync(JNIEnv* env, jobject, jobject javaFd) { int fd = jniGetFDFromFileDescriptor(env, javaFd); throwIfMinusOne(env, "fdatasync", TEMP_FAILURE_RETRY(fdatasync(fd))); @@ -679,7 +857,7 @@ static jobjectArray Posix_android_getaddrinfo(JNIEnv* env, jobject, jstring java addrinfo* addressList = NULL; errno = 0; int rc = android_getaddrinfofornet(node.c_str(), NULL, &hints, netId, 0, &addressList); - UniquePtr<addrinfo, addrinfo_deleter> addressListDeleter(addressList); + std::unique_ptr<addrinfo, addrinfo_deleter> addressListDeleter(addressList); if (rc != 0) { throwGaiException(env, "android_getaddrinfo", rc); return NULL; @@ -765,12 +943,16 @@ static jobject Posix_getpeername(JNIEnv* env, jobject, jobject javaFd) { return doGetSockName(env, javaFd, false); } +static jint Posix_getpgid(JNIEnv* env, jobject, jint pid) { + return throwIfMinusOne(env, "getpgid", TEMP_FAILURE_RETRY(getpgid(pid))); +} + static jint Posix_getpid(JNIEnv*, jobject) { - return getpid(); + return TEMP_FAILURE_RETRY(getpid()); } static jint Posix_getppid(JNIEnv*, jobject) { - return getppid(); + return TEMP_FAILURE_RETRY(getppid()); } static jobject Posix_getpwnam(JNIEnv* env, jobject, jstring javaName) { @@ -868,8 +1050,9 @@ static jint Posix_gettid(JNIEnv* env __unused, jobject) { return 0; } return static_cast<jint>(owner); +#elif defined(__BIONIC__) + return TEMP_FAILURE_RETRY(gettid()); #else - // Neither bionic nor glibc exposes gettid(2). return syscall(__NR_gettid); #endif } @@ -1036,9 +1219,13 @@ static jobject Posix_open(JNIEnv* env, jobject, jstring javaPath, jint flags, ji return fd != -1 ? jniCreateFileDescriptor(env, fd) : NULL; } -static jobjectArray Posix_pipe(JNIEnv* env, jobject) { +static jobjectArray Posix_pipe2(JNIEnv* env, jobject, jint flags __unused) { +#ifdef __APPLE__ + jniThrowException(env, "java/lang/UnsupportedOperationException", "no pipe2 on Mac OS"); + return NULL; +#else int fds[2]; - throwIfMinusOne(env, "pipe", TEMP_FAILURE_RETRY(pipe(&fds[0]))); + throwIfMinusOne(env, "pipe2", TEMP_FAILURE_RETRY(pipe2(&fds[0], flags))); jobjectArray result = env->NewObjectArray(2, JniConstants::fileDescriptorClass, NULL); if (result == NULL) { return NULL; @@ -1054,6 +1241,7 @@ static jobjectArray Posix_pipe(JNIEnv* env, jobject) { } } return result; +#endif } static jint Posix_poll(JNIEnv* env, jobject, jobjectArray javaStructs, jint timeoutMs) { @@ -1063,7 +1251,7 @@ static jint Posix_poll(JNIEnv* env, jobject, jobjectArray javaStructs, jint time // Turn the Java android.system.StructPollfd[] into a C++ struct pollfd[]. size_t arrayLength = env->GetArrayLength(javaStructs); - UniquePtr<struct pollfd[]> fds(new struct pollfd[arrayLength]); + std::unique_ptr<struct pollfd[]> fds(new struct pollfd[arrayLength]); memset(fds.get(), 0, sizeof(struct pollfd) * arrayLength); size_t count = 0; // Some trailing array elements may be irrelevant. (See below.) for (size_t i = 0; i < arrayLength; ++i) { @@ -1084,7 +1272,40 @@ static jint Posix_poll(JNIEnv* env, jobject, jobjectArray javaStructs, jint time for (size_t i = 0; i < count; ++i) { monitors.push_back(new AsynchronousCloseMonitor(fds[i].fd)); } - int rc = poll(fds.get(), count, timeoutMs); + + int rc; + while (true) { + timespec before; + clock_gettime(CLOCK_MONOTONIC, &before); + + rc = poll(fds.get(), count, timeoutMs); + if (rc >= 0 || errno != EINTR) { + break; + } + + // We got EINTR. Work out how much of the original timeout is still left. + if (timeoutMs > 0) { + timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + + timespec diff; + diff.tv_sec = now.tv_sec - before.tv_sec; + diff.tv_nsec = now.tv_nsec - before.tv_nsec; + if (diff.tv_nsec < 0) { + --diff.tv_sec; + diff.tv_nsec += 1000000000; + } + + jint diffMs = diff.tv_sec * 1000 + diff.tv_nsec / 1000000; + if (diffMs >= timeoutMs) { + rc = 0; // We have less than 1ms left anyway, so just time out. + break; + } + + timeoutMs -= diffMs; + } + } + for (size_t i = 0; i < monitors.size(); ++i) { delete monitors[i]; } @@ -1111,7 +1332,8 @@ static void Posix_posix_fallocate(JNIEnv* env, jobject, jobject javaFd __unused, "fallocate doesn't exist on a Mac"); #else int fd = jniGetFDFromFileDescriptor(env, javaFd); - errno = TEMP_FAILURE_RETRY(posix_fallocate64(fd, offset, length)); + while ((errno = posix_fallocate64(fd, offset, length)) == EINTR) { + } if (errno != 0) { throwErrnoException(env, "posix_fallocate"); } @@ -1124,9 +1346,11 @@ static jint Posix_prctl(JNIEnv* env, jobject, jint option __unused, jlong arg2 _ jniThrowException(env, "java/lang/UnsupportedOperationException", "prctl doesn't exist on a Mac"); return 0; #else - int result = prctl(static_cast<int>(option), - static_cast<unsigned long>(arg2), static_cast<unsigned long>(arg3), - static_cast<unsigned long>(arg4), static_cast<unsigned long>(arg5)); + int result = TEMP_FAILURE_RETRY(prctl(static_cast<int>(option), + static_cast<unsigned long>(arg2), + static_cast<unsigned long>(arg3), + static_cast<unsigned long>(arg4), + static_cast<unsigned long>(arg5))); return throwIfMinusOne(env, "prctl", result); #endif } @@ -1235,13 +1459,35 @@ static jint Posix_sendtoBytes(JNIEnv* env, jobject, jobject javaFd, jobject java if (bytes.get() == NULL) { return -1; } + + return NET_IPV4_FALLBACK(env, ssize_t, sendto, javaFd, javaInetAddress, port, + NULL_ADDR_OK, bytes.get() + byteOffset, byteCount, flags); +} + +static jint Posix_sendtoBytesSocketAddress(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount, jint flags, jobject javaSocketAddress) { + if (env->IsInstanceOf(javaSocketAddress, JniConstants::inetSocketAddressClass)) { + // Use the InetAddress version so we get the benefit of NET_IPV4_FALLBACK. + jobject javaInetAddress; + jint port; + javaInetSocketAddressToInetAddressAndPort(env, javaSocketAddress, javaInetAddress, port); + return Posix_sendtoBytes(env, NULL, javaFd, javaBytes, byteOffset, byteCount, flags, + javaInetAddress, port); + } + + ScopedBytesRO bytes(env, javaBytes); + if (bytes.get() == NULL) { + return -1; + } + sockaddr_storage ss; - socklen_t sa_len = 0; - if (javaInetAddress != NULL && !inetAddressToSockaddr(env, javaInetAddress, port, ss, sa_len)) { + socklen_t sa_len; + if (!javaSocketAddressToSockaddr(env, javaSocketAddress, ss, sa_len)) { return -1; } - const sockaddr* to = (javaInetAddress != NULL) ? reinterpret_cast<const sockaddr*>(&ss) : NULL; - return NET_FAILURE_RETRY(env, ssize_t, sendto, javaFd, bytes.get() + byteOffset, byteCount, flags, to, sa_len); + + const sockaddr* sa = reinterpret_cast<const sockaddr*>(&ss); + // We don't need the return value because we'll already have thrown. + return NET_FAILURE_RETRY(env, ssize_t, sendto, javaFd, bytes.get() + byteOffset, byteCount, flags, sa, sa_len); } static void Posix_setegid(JNIEnv* env, jobject, jint egid) { @@ -1268,6 +1514,18 @@ static void Posix_setgid(JNIEnv* env, jobject, jint gid) { throwIfMinusOne(env, "setgid", TEMP_FAILURE_RETRY(setgid(gid))); } +static void Posix_setpgid(JNIEnv* env, jobject, jint pid, int pgid) { + throwIfMinusOne(env, "setpgid", TEMP_FAILURE_RETRY(setpgid(pid, pgid))); +} + +static void Posix_setregid(JNIEnv* env, jobject, jint rgid, int egid) { + throwIfMinusOne(env, "setregid", TEMP_FAILURE_RETRY(setregid(rgid, egid))); +} + +static void Posix_setreuid(JNIEnv* env, jobject, jint ruid, int euid) { + throwIfMinusOne(env, "setreuid", TEMP_FAILURE_RETRY(setreuid(ruid, euid))); +} + static jint Posix_setsid(JNIEnv* env, jobject) { return throwIfMinusOne(env, "setsid", TEMP_FAILURE_RETRY(setsid())); } @@ -1412,6 +1670,9 @@ static void Posix_shutdown(JNIEnv* env, jobject, jobject javaFd, jint how) { } static jobject Posix_socket(JNIEnv* env, jobject, jint domain, jint type, jint protocol) { + if (domain == AF_PACKET) { + protocol = htons(protocol); // Packet sockets specify the protocol in host byte order. + } int fd = throwIfMinusOne(env, "socket", TEMP_FAILURE_RETRY(socket(domain, type, protocol))); return fd != -1 ? jniCreateFileDescriptor(env, fd) : NULL; } @@ -1531,15 +1792,20 @@ static jint Posix_writev(JNIEnv* env, jobject, jobject javaFd, jobjectArray buff return IO_FAILURE_RETRY(env, ssize_t, writev, javaFd, ioVec.get(), ioVec.size()); } +#define NATIVE_METHOD_OVERLOAD(className, functionName, signature, variant) \ + { #functionName, signature, reinterpret_cast<void*>(className ## _ ## functionName ## variant) } + static JNINativeMethod gMethods[] = { NATIVE_METHOD(Posix, accept, "(Ljava/io/FileDescriptor;Ljava/net/InetSocketAddress;)Ljava/io/FileDescriptor;"), NATIVE_METHOD(Posix, access, "(Ljava/lang/String;I)Z"), NATIVE_METHOD(Posix, android_getaddrinfo, "(Ljava/lang/String;Landroid/system/StructAddrinfo;I)[Ljava/net/InetAddress;"), NATIVE_METHOD(Posix, bind, "(Ljava/io/FileDescriptor;Ljava/net/InetAddress;I)V"), + NATIVE_METHOD_OVERLOAD(Posix, bind, "(Ljava/io/FileDescriptor;Ljava/net/SocketAddress;)V", SocketAddress), NATIVE_METHOD(Posix, chmod, "(Ljava/lang/String;I)V"), NATIVE_METHOD(Posix, chown, "(Ljava/lang/String;II)V"), NATIVE_METHOD(Posix, close, "(Ljava/io/FileDescriptor;)V"), NATIVE_METHOD(Posix, connect, "(Ljava/io/FileDescriptor;Ljava/net/InetAddress;I)V"), + NATIVE_METHOD_OVERLOAD(Posix, connect, "(Ljava/io/FileDescriptor;Ljava/net/SocketAddress;)V", SocketAddress), NATIVE_METHOD(Posix, dup, "(Ljava/io/FileDescriptor;)Ljava/io/FileDescriptor;"), NATIVE_METHOD(Posix, dup2, "(Ljava/io/FileDescriptor;I)Ljava/io/FileDescriptor;"), NATIVE_METHOD(Posix, environ, "()[Ljava/lang/String;"), @@ -1547,9 +1813,9 @@ static JNINativeMethod gMethods[] = { NATIVE_METHOD(Posix, execve, "(Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;)V"), NATIVE_METHOD(Posix, fchmod, "(Ljava/io/FileDescriptor;I)V"), NATIVE_METHOD(Posix, fchown, "(Ljava/io/FileDescriptor;II)V"), - NATIVE_METHOD(Posix, fcntlVoid, "(Ljava/io/FileDescriptor;I)I"), - NATIVE_METHOD(Posix, fcntlLong, "(Ljava/io/FileDescriptor;IJ)I"), NATIVE_METHOD(Posix, fcntlFlock, "(Ljava/io/FileDescriptor;ILandroid/system/StructFlock;)I"), + NATIVE_METHOD(Posix, fcntlInt, "(Ljava/io/FileDescriptor;II)I"), + NATIVE_METHOD(Posix, fcntlVoid, "(Ljava/io/FileDescriptor;I)I"), NATIVE_METHOD(Posix, fdatasync, "(Ljava/io/FileDescriptor;)V"), NATIVE_METHOD(Posix, fstat, "(Ljava/io/FileDescriptor;)Landroid/system/StructStat;"), NATIVE_METHOD(Posix, fstatvfs, "(Ljava/io/FileDescriptor;)Landroid/system/StructStatVfs;"), @@ -1562,6 +1828,7 @@ static JNINativeMethod gMethods[] = { NATIVE_METHOD(Posix, getenv, "(Ljava/lang/String;)Ljava/lang/String;"), NATIVE_METHOD(Posix, getnameinfo, "(Ljava/net/InetAddress;I)Ljava/lang/String;"), NATIVE_METHOD(Posix, getpeername, "(Ljava/io/FileDescriptor;)Ljava/net/SocketAddress;"), + NATIVE_METHOD(Posix, getpgid, "(I)I"), NATIVE_METHOD(Posix, getpid, "()I"), NATIVE_METHOD(Posix, getppid, "()I"), NATIVE_METHOD(Posix, getpwnam, "(Ljava/lang/String;)Landroid/system/StructPasswd;"), @@ -1595,7 +1862,7 @@ static JNINativeMethod gMethods[] = { NATIVE_METHOD(Posix, munlock, "(JJ)V"), NATIVE_METHOD(Posix, munmap, "(JJ)V"), NATIVE_METHOD(Posix, open, "(Ljava/lang/String;II)Ljava/io/FileDescriptor;"), - NATIVE_METHOD(Posix, pipe, "()[Ljava/io/FileDescriptor;"), + NATIVE_METHOD(Posix, pipe2, "(I)[Ljava/io/FileDescriptor;"), NATIVE_METHOD(Posix, poll, "([Landroid/system/StructPollfd;I)I"), NATIVE_METHOD(Posix, posix_fallocate, "(Ljava/io/FileDescriptor;JJ)V"), NATIVE_METHOD(Posix, prctl, "(IJJJJ)I"), @@ -1609,10 +1876,14 @@ static JNINativeMethod gMethods[] = { NATIVE_METHOD(Posix, rename, "(Ljava/lang/String;Ljava/lang/String;)V"), NATIVE_METHOD(Posix, sendfile, "(Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;Landroid/util/MutableLong;J)J"), NATIVE_METHOD(Posix, sendtoBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIILjava/net/InetAddress;I)I"), + NATIVE_METHOD_OVERLOAD(Posix, sendtoBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIILjava/net/SocketAddress;)I", SocketAddress), NATIVE_METHOD(Posix, setegid, "(I)V"), NATIVE_METHOD(Posix, setenv, "(Ljava/lang/String;Ljava/lang/String;Z)V"), NATIVE_METHOD(Posix, seteuid, "(I)V"), NATIVE_METHOD(Posix, setgid, "(I)V"), + NATIVE_METHOD(Posix, setpgid, "(II)V"), + NATIVE_METHOD(Posix, setregid, "(II)V"), + NATIVE_METHOD(Posix, setreuid, "(II)V"), NATIVE_METHOD(Posix, setsid, "()I"), NATIVE_METHOD(Posix, setsockoptByte, "(Ljava/io/FileDescriptor;III)V"), NATIVE_METHOD(Posix, setsockoptIfreq, "(Ljava/io/FileDescriptor;IILjava/lang/String;)V"), diff --git a/luni/src/main/native/java_nio_charset_Charsets.cpp b/luni/src/main/native/libcore_util_CharsetUtils.cpp index a49ba22..57c8172 100644 --- a/luni/src/main/native/java_nio_charset_Charsets.cpp +++ b/luni/src/main/native/libcore_util_CharsetUtils.cpp @@ -245,6 +245,6 @@ static JNINativeMethod gMethods[] = { NATIVE_METHOD(Charsets, toIsoLatin1Bytes, "([CII)[B"), NATIVE_METHOD(Charsets, toUtf8Bytes, "([CII)[B"), }; -void register_java_nio_charset_Charsets(JNIEnv* env) { - jniRegisterNativeMethods(env, "java/nio/charset/Charsets", gMethods, NELEM(gMethods)); +void register_libcore_util_CharsetUtils(JNIEnv* env) { + jniRegisterNativeMethods(env, "libcore/util/CharsetUtils", gMethods, NELEM(gMethods)); } diff --git a/luni/src/main/native/org_apache_harmony_xml_ExpatParser.cpp b/luni/src/main/native/org_apache_harmony_xml_ExpatParser.cpp index 2ea8806..48defc1 100644 --- a/luni/src/main/native/org_apache_harmony_xml_ExpatParser.cpp +++ b/luni/src/main/native/org_apache_harmony_xml_ExpatParser.cpp @@ -24,11 +24,12 @@ #include "ScopedPrimitiveArray.h" #include "ScopedStringChars.h" #include "ScopedUtfChars.h" -#include "UniquePtr.h" #include "jni.h" #include "cutils/log.h" #include "unicode/unistr.h" +#include <memory> + #include <string.h> #include <libexpat/expat.h> @@ -253,7 +254,7 @@ static int hashString(const char* s) { */ static InternedString* newInternedString(JNIEnv* env, const char* bytes, int hash) { // Allocate a new wrapper. - UniquePtr<InternedString> wrapper(new InternedString); + std::unique_ptr<InternedString> wrapper(new InternedString); if (wrapper.get() == NULL) { jniThrowOutOfMemoryError(env, NULL); return NULL; @@ -439,7 +440,7 @@ static size_t fillBuffer(ParsingContext* parsingContext, const char* utf8, int b return -1; } UErrorCode status = U_ZERO_ERROR; - UnicodeString utf16(UnicodeString::fromUTF8(StringPiece(utf8, byteCount))); + icu::UnicodeString utf16(icu::UnicodeString::fromUTF8(icu::StringPiece(utf8, byteCount))); return utf16.extract(chars.get(), byteCount, status); } @@ -962,7 +963,7 @@ static void notationDecl(void* data, const char* name, const char* /*base*/, con static jlong ExpatParser_initialize(JNIEnv* env, jobject object, jstring javaEncoding, jboolean processNamespaces) { // Allocate parsing context. - UniquePtr<ParsingContext> context(new ParsingContext(object)); + std::unique_ptr<ParsingContext> context(new ParsingContext(object)); if (context.get() == NULL) { jniThrowOutOfMemoryError(env, NULL); return 0; diff --git a/luni/src/main/native/sub.mk b/luni/src/main/native/sub.mk index 079ecd2..a90c683 100644 --- a/luni/src/main/native/sub.mk +++ b/luni/src/main/native/sub.mk @@ -28,7 +28,6 @@ LOCAL_SRC_FILES := \ java_lang_System.cpp \ java_math_NativeBN.cpp \ java_nio_ByteOrder.cpp \ - java_nio_charset_Charsets.cpp \ java_text_Bidi.cpp \ java_util_jar_StrictJarFile.cpp \ java_util_regex_Matcher.cpp \ @@ -38,9 +37,7 @@ LOCAL_SRC_FILES := \ java_util_zip_Deflater.cpp \ java_util_zip_Inflater.cpp \ libcore_icu_AlphabeticIndex.cpp \ - libcore_icu_DateIntervalFormat.cpp \ libcore_icu_ICU.cpp \ - libcore_icu_NativeBreakIterator.cpp \ libcore_icu_NativeCollation.cpp \ libcore_icu_NativeConverter.cpp \ libcore_icu_NativeDecimalFormat.cpp \ @@ -52,18 +49,12 @@ LOCAL_SRC_FILES := \ libcore_io_AsynchronousCloseMonitor.cpp \ libcore_io_Memory.cpp \ libcore_io_Posix.cpp \ + libcore_util_CharsetUtils.cpp \ org_apache_harmony_xml_ExpatParser.cpp \ readlink.cpp \ sun_misc_Unsafe.cpp \ valueOf.cpp \ -LOCAL_C_INCLUDES += \ - external/icu/icu4c/source/common \ - external/icu/icu4c/source/i18n \ - external/openssl/include \ - external/zlib \ - system/core/include \ - LOCAL_STATIC_LIBRARIES += \ libfdlibm \ |