jni_string.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/android/jni_string.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/android/jni_android.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/utf_string_conversions.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Internal version that does not use a scoped local pointer. 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)jstring ConvertUTF16ToJavaStringImpl(JNIEnv* env, 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::StringPiece16& str) { 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) jstring result = env->NewString(str.data(), str.length()); 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::android::CheckException(env); 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace android { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string ConvertJavaStringToUTF8(JNIEnv* env, jstring str) { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // JNI's GetStringUTFChars() returns strings in Java-modified UTF8, so we 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // instead get the String in UTF16 and convert using our own utility function. 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return UTF16ToUTF8(ConvertJavaStringToUTF16(env, str)); 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string ConvertJavaStringToUTF8(const JavaRef<jstring>& str) { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ConvertJavaStringToUTF8(AttachCurrentThread(), str.obj()); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScopedJavaLocalRef<jstring> ConvertUTF8ToJavaString( 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) JNIEnv* env, 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::StringPiece& str) { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // JNI's NewStringUTF expects "modified" UTF8 so instead create the string 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // via our own UTF16 conversion utility. 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Further, Dalvik requires the string passed into NewStringUTF() to come from 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a trusted source. We can't guarantee that all UTF8 will be sanitized before 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it gets here, so constructing via UTF16 side-steps this issue. 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (Dalvik stores strings internally as UTF16 anyway, so there shouldn't be 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a significant performance hit by doing it this way). 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ScopedJavaLocalRef<jstring>(env, ConvertUTF16ToJavaStringImpl( 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) env, UTF8ToUTF16(str))); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string16 ConvertJavaStringToUTF16(JNIEnv* env, jstring str) { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!str) { 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << " ConvertJavaStringToUTF16 called with null string."; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return string16(); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const jchar* chars = env->GetStringChars(str, NULL); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(chars); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // GetStringChars isn't required to NULL-terminate the strings 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it returns, so the length must be explicitly checked. 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16 result(chars, env->GetStringLength(str)); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) env->ReleaseStringChars(str, chars); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckException(env); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string16 ConvertJavaStringToUTF16(const JavaRef<jstring>& str) { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ConvertJavaStringToUTF16(AttachCurrentThread(), str.obj()); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScopedJavaLocalRef<jstring> ConvertUTF16ToJavaString( 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) JNIEnv* env, 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::StringPiece16& str) { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ScopedJavaLocalRef<jstring>(env, 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConvertUTF16ToJavaStringImpl(env, str)); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace android 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace base 78