1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "base/android/jni_string.h" 6 7 #include "base/android/jni_android.h" 8 #include "base/logging.h" 9 #include "base/strings/utf_string_conversions.h" 10 11 namespace { 12 13 // Internal version that does not use a scoped local pointer. 14 jstring ConvertUTF16ToJavaStringImpl(JNIEnv* env, 15 const base::StringPiece16& str) { 16 jstring result = env->NewString(str.data(), str.length()); 17 base::android::CheckException(env); 18 return result; 19 } 20 21 } 22 23 namespace base { 24 namespace android { 25 26 void ConvertJavaStringToUTF8(JNIEnv* env, jstring str, std::string* result) { 27 if (!str) { 28 LOG(WARNING) << "ConvertJavaStringToUTF8 called with null string."; 29 result->clear(); 30 return; 31 } 32 // JNI's GetStringUTFChars() returns strings in Java "modified" UTF8, so 33 // instead get the String in UTF16 and convert using chromium's conversion 34 // function that yields plain (non Java-modified) UTF8. 35 const jchar* chars = env->GetStringChars(str, NULL); 36 DCHECK(chars); 37 UTF16ToUTF8(chars, env->GetStringLength(str), result); 38 env->ReleaseStringChars(str, chars); 39 CheckException(env); 40 } 41 42 std::string ConvertJavaStringToUTF8(JNIEnv* env, jstring str) { 43 std::string result; 44 ConvertJavaStringToUTF8(env, str, &result); 45 return result; 46 } 47 48 std::string ConvertJavaStringToUTF8(const JavaRef<jstring>& str) { 49 return ConvertJavaStringToUTF8(AttachCurrentThread(), str.obj()); 50 } 51 52 ScopedJavaLocalRef<jstring> ConvertUTF8ToJavaString( 53 JNIEnv* env, 54 const base::StringPiece& str) { 55 // JNI's NewStringUTF expects "modified" UTF8 so instead create the string 56 // via our own UTF16 conversion utility. 57 // Further, Dalvik requires the string passed into NewStringUTF() to come from 58 // a trusted source. We can't guarantee that all UTF8 will be sanitized before 59 // it gets here, so constructing via UTF16 side-steps this issue. 60 // (Dalvik stores strings internally as UTF16 anyway, so there shouldn't be 61 // a significant performance hit by doing it this way). 62 return ScopedJavaLocalRef<jstring>(env, ConvertUTF16ToJavaStringImpl( 63 env, UTF8ToUTF16(str))); 64 } 65 66 void ConvertJavaStringToUTF16(JNIEnv* env, jstring str, string16* result) { 67 if (!str) { 68 LOG(WARNING) << "ConvertJavaStringToUTF16 called with null string."; 69 result->clear(); 70 return; 71 } 72 const jchar* chars = env->GetStringChars(str, NULL); 73 DCHECK(chars); 74 // GetStringChars isn't required to NULL-terminate the strings 75 // it returns, so the length must be explicitly checked. 76 result->assign(chars, env->GetStringLength(str)); 77 env->ReleaseStringChars(str, chars); 78 CheckException(env); 79 } 80 81 string16 ConvertJavaStringToUTF16(JNIEnv* env, jstring str) { 82 string16 result; 83 ConvertJavaStringToUTF16(env, str, &result); 84 return result; 85 } 86 87 string16 ConvertJavaStringToUTF16(const JavaRef<jstring>& str) { 88 return ConvertJavaStringToUTF16(AttachCurrentThread(), str.obj()); 89 } 90 91 ScopedJavaLocalRef<jstring> ConvertUTF16ToJavaString( 92 JNIEnv* env, 93 const base::StringPiece16& str) { 94 return ScopedJavaLocalRef<jstring>(env, 95 ConvertUTF16ToJavaStringImpl(env, str)); 96 } 97 98 } // namespace android 99 } // namespace base 100