/* * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ #include #include #include #include #include "jni.h" #include "jni_util.h" static void getParent(const TCHAR *path, TCHAR *dest) { char* lastSlash = max(strrchr(path, '\\'), strrchr(path, '/')); if (lastSlash == NULL) { *dest = 0; return; } if (path != dest) strcpy(dest, path); *lastSlash = 0; } BOOL useNativeConverter(JNIEnv *env) { static BOOL initialized; static BOOL useNative; if (!initialized) { HMODULE jvm = GetModuleHandle("jvm"); useNative = FALSE; if (jvm != NULL) { TCHAR *jvmPath = NULL; int bufferSize = MAX_PATH; while (jvmPath == NULL) { DWORD result; jvmPath = malloc(bufferSize); if (jvmPath == NULL) return FALSE; result = GetModuleFileName(jvm, jvmPath, bufferSize); if (result == 0) return FALSE; if (result == bufferSize) { // didn't fit bufferSize += MAX_PATH; // increase buffer size, try again free(jvmPath); jvmPath = NULL; } } getParent(jvmPath, jvmPath); useNative = (!strcmp("kernel", jvmPath + strlen(jvmPath) - strlen("kernel"))); // true if jvm.dll lives in "kernel" if (useNative) setlocale(LC_ALL, ""); free(jvmPath); } initialized = TRUE; } return useNative; } jstring nativeNewStringPlatform(JNIEnv *env, const char *str) { static jmethodID String_char_constructor; if (useNativeConverter(env)) { // use native Unicode conversion so Kernel isn't required during // System.initProperties jcharArray chars = 0; wchar_t *utf16; int len; jstring result = NULL; if (getFastEncoding() == NO_ENCODING_YET) initializeEncoding(env); len = mbstowcs(NULL, str, strlen(str)); if (len == -1) return NULL; utf16 = calloc(len + 1, 2); if (mbstowcs(utf16, str, len) == -1) return NULL; chars = (*env)->NewCharArray(env, len); if (chars == NULL) return NULL; (*env)->SetCharArrayRegion(env, chars, 0, len, utf16); if (String_char_constructor == NULL) String_char_constructor = (*env)->GetMethodID(env, JNU_ClassString(env), "", "([C)V"); result = (*env)->NewObject(env, JNU_ClassString(env), String_char_constructor, chars); free(utf16); return result; } else return NULL; } char* nativeGetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy) { if (useNativeConverter(env)) { // use native Unicode conversion so Kernel isn't required during // System.initProperties char *result = NULL; size_t len; const jchar* utf16 = (*env)->GetStringChars(env, jstr, NULL); len = wcstombs(NULL, utf16, (*env)->GetStringLength(env, jstr) * 4) + 1; if (len == -1) return NULL; result = (char*) malloc(len); if (result != NULL) { if (wcstombs(result, utf16, len) == -1) return NULL; (*env)->ReleaseStringChars(env, jstr, utf16); if (isCopy) *isCopy = JNI_TRUE; } return result; } else return NULL; }