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} 22 23namespace base { 24namespace android { 25 26void 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 42std::string ConvertJavaStringToUTF8(JNIEnv* env, jstring str) { 43 std::string result; 44 ConvertJavaStringToUTF8(env, str, &result); 45 return result; 46} 47 48std::string ConvertJavaStringToUTF8(const JavaRef<jstring>& str) { 49 return ConvertJavaStringToUTF8(AttachCurrentThread(), str.obj()); 50} 51 52ScopedJavaLocalRef<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 66void 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 81string16 ConvertJavaStringToUTF16(JNIEnv* env, jstring str) { 82 string16 result; 83 ConvertJavaStringToUTF16(env, str, &result); 84 return result; 85} 86 87string16 ConvertJavaStringToUTF16(const JavaRef<jstring>& str) { 88 return ConvertJavaStringToUTF16(AttachCurrentThread(), str.obj()); 89} 90 91ScopedJavaLocalRef<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