Path: blob/master/src/java.desktop/macosx/native/libosxapp/JNIUtilities.m
66644 views
/*1* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425#include "JNIUtilities.h"2627NSString* JavaStringToNSString(JNIEnv *env, jstring jstr) {28if (jstr == NULL) {29return NULL;30}31jsize len = (*env)->GetStringLength(env, jstr);32const jchar *chars = (*env)->GetStringChars(env, jstr, NULL);33if (chars == NULL) {34return NULL;35}36NSString *result = [NSString stringWithCharacters:(UniChar *)chars length:len];37(*env)->ReleaseStringChars(env, jstr, chars);38return result;39}4041jstring NSStringToJavaString(JNIEnv* env, NSString *str) {42if (str == NULL) {43return NULL;44}45jsize len = [str length];46unichar *buffer = (unichar*)calloc(len, sizeof(unichar));47if (buffer == NULL) {48return NULL;49}50NSRange crange = NSMakeRange(0, len);51[str getCharacters:buffer range:crange];52jstring jStr = (*env)->NewString(env, buffer, len);53free(buffer);54CHECK_EXCEPTION();55return jStr;56}5758/*59* These next conversion functions are for file system paths.60* The NSString needs to be in de-composed UTF-16 format for the Apple file system61* The Java String needs to be in pre-composed UTF-16 format for display by Java.62* https://developer.apple.com/library/archive/qa/qa1235/_index.html63* has some information on this.64*/6566/*67* Returns an NSString in decomposed UTF16 format that is compatible with HFS's68* expectation of the UTF16 format for file system paths.69*70* Example string: "/Users/Amélie/"71*72* Java's UTF16 string is "/ U s e r s / A m \351 l i e /"73* macOS UTF16 string suitable for HFS is "/ U s e r s / A m e \314 \201 l i e /"74*75* There is no direct API that takes in NSString UTF16 encoded by Java76* and produces NSString UTF16 for HFS, so we first need to decompose it77* into chars (suitable for low level C file APIs), and only then78* create NSString representation of this decomposition back into UTF16 string.79*80* https://developer.apple.com/documentation/foundation/nsstring/1414559-filesystemrepresentation?language=objc81* describes how to get a file system representation as a char* from an NSString82* and then using FileManager (!) convert it to an NSString.83* But we want an NSString.84* So the steps are85* 1) Convert to NSString86* 2) call [NSString fileSystemRepresentation] which gives us a char*87* 3) Convert the returned char* to an NSString using FileManager (is there a better way?)88*/89NSString* NormalizedPathNSStringFromJavaString(JNIEnv *env, jstring pathStr) {90if (pathStr == NULL) {91return nil;92}93NSString *nsStr = JavaStringToNSString(env, pathStr);94if (nsStr == NULL) {95return nil;96}97const char* chs = [nsStr fileSystemRepresentation];98int len = strlen(chs);99NSString* result = [[NSFileManager defaultManager]100stringWithFileSystemRepresentation:chs length:len];101return result;102}103104/*105* Given what is (potentially) a de-composed NSString, convert it to pre-composed106* Then convert it into a Java String.107*/108jstring NormalizedPathJavaStringFromNSString(JNIEnv* env, NSString *str) {109if (str == nil) {110return NULL;111}112NSString *normStr = [str precomposedStringWithCanonicalMapping];113return NSStringToJavaString(env, normStr);114}115116117