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 11namespace { 12 13// Internal version that does not use a scoped local pointer. 14jstring 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} // namespace 22 23namespace base { 24namespace android { 25 26void ConvertJavaStringToUTF8(JNIEnv* env, jstring str, std::string* result) { 27 DCHECK(str); 28 if (!str) { 29 LOG(WARNING) << "ConvertJavaStringToUTF8 called with null string."; 30 result->clear(); 31 return; 32 } 33 const jsize length = env->GetStringLength(str); 34 if (!length) { 35 result->clear(); 36 CheckException(env); 37 return; 38 } 39 // JNI's GetStringUTFChars() returns strings in Java "modified" UTF8, so 40 // instead get the String in UTF16 and convert using chromium's conversion 41 // function that yields plain (non Java-modified) UTF8. 42 const jchar* chars = env->GetStringChars(str, NULL); 43 DCHECK(chars); 44 UTF16ToUTF8(chars, length, result); 45 env->ReleaseStringChars(str, chars); 46 CheckException(env); 47} 48 49std::string ConvertJavaStringToUTF8(JNIEnv* env, jstring str) { 50 std::string result; 51 ConvertJavaStringToUTF8(env, str, &result); 52 return result; 53} 54 55std::string ConvertJavaStringToUTF8(const JavaRef<jstring>& str) { 56 return ConvertJavaStringToUTF8(AttachCurrentThread(), str.obj()); 57} 58 59std::string ConvertJavaStringToUTF8(JNIEnv* env, const JavaRef<jstring>& str) { 60 return ConvertJavaStringToUTF8(env, str.obj()); 61} 62 63ScopedJavaLocalRef<jstring> ConvertUTF8ToJavaString( 64 JNIEnv* env, 65 const base::StringPiece& str) { 66 // JNI's NewStringUTF expects "modified" UTF8 so instead create the string 67 // via our own UTF16 conversion utility. 68 // Further, Dalvik requires the string passed into NewStringUTF() to come from 69 // a trusted source. We can't guarantee that all UTF8 will be sanitized before 70 // it gets here, so constructing via UTF16 side-steps this issue. 71 // (Dalvik stores strings internally as UTF16 anyway, so there shouldn't be 72 // a significant performance hit by doing it this way). 73 return ScopedJavaLocalRef<jstring>(env, ConvertUTF16ToJavaStringImpl( 74 env, UTF8ToUTF16(str))); 75} 76 77void ConvertJavaStringToUTF16(JNIEnv* env, jstring str, string16* result) { 78 DCHECK(str); 79 if (!str) { 80 LOG(WARNING) << "ConvertJavaStringToUTF16 called with null string."; 81 result->clear(); 82 return; 83 } 84 const jsize length = env->GetStringLength(str); 85 if (!length) { 86 result->clear(); 87 CheckException(env); 88 return; 89 } 90 const jchar* chars = env->GetStringChars(str, NULL); 91 DCHECK(chars); 92 // GetStringChars isn't required to NULL-terminate the strings 93 // it returns, so the length must be explicitly checked. 94 result->assign(chars, length); 95 env->ReleaseStringChars(str, chars); 96 CheckException(env); 97} 98 99string16 ConvertJavaStringToUTF16(JNIEnv* env, jstring str) { 100 string16 result; 101 ConvertJavaStringToUTF16(env, str, &result); 102 return result; 103} 104 105string16 ConvertJavaStringToUTF16(const JavaRef<jstring>& str) { 106 return ConvertJavaStringToUTF16(AttachCurrentThread(), str.obj()); 107} 108 109string16 ConvertJavaStringToUTF16(JNIEnv* env, const JavaRef<jstring>& str) { 110 return ConvertJavaStringToUTF16(env, str.obj()); 111} 112 113ScopedJavaLocalRef<jstring> ConvertUTF16ToJavaString( 114 JNIEnv* env, 115 const base::StringPiece16& str) { 116 return ScopedJavaLocalRef<jstring>(env, 117 ConvertUTF16ToJavaStringImpl(env, str)); 118} 119 120} // namespace android 121} // namespace base 122