java_lang_String.cc revision 90b936ddda63139ff46a6755c3b83ad6e4ab4ac5
1bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes/* 2bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes * Copyright (C) 2008 The Android Open Source Project 3bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes * 4bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 5bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes * you may not use this file except in compliance with the License. 6bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes * You may obtain a copy of the License at 7bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes * 8bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 9bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes * 10bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes * Unless required by applicable law or agreed to in writing, software 11bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 12bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes * See the License for the specific language governing permissions and 14bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes * limitations under the License. 15bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes */ 16bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes 17277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe#include "java_lang_String.h" 18277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe 1962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers#include "common_throws.h" 20bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes#include "jni_internal.h" 21848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao#include "mirror/array.h" 22848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao#include "mirror/object-inl.h" 23848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao#include "mirror/string.h" 24b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers#include "mirror/string-inl.h" 250795f23920ee9aabf28e45c63cd592dcccf00216Mathieu Chartier#include "scoped_fast_native_object_access-inl.h" 260795f23920ee9aabf28e45c63cd592dcccf00216Mathieu Chartier#include "scoped_thread_state_change-inl.h" 2764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers#include "ScopedLocalRef.h" 2890b936ddda63139ff46a6755c3b83ad6e4ab4ac5Andreas Gampe#include "verify_object.h" 29bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes 30bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughesnamespace art { 31bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes 32848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Haostatic jchar String_charAt(JNIEnv* env, jobject java_this, jint index) { 331eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers ScopedFastNativeObjectAccess soa(env); 340795f23920ee9aabf28e45c63cd592dcccf00216Mathieu Chartier return soa.Decode<mirror::String>(java_this)->CharAt(index); 35848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao} 36848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao 37848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Haostatic jint String_compareTo(JNIEnv* env, jobject java_this, jobject java_rhs) { 38848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao ScopedFastNativeObjectAccess soa(env); 39848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao if (UNLIKELY(java_rhs == nullptr)) { 400aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffray ThrowNullPointerException("rhs == null"); 41bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes return -1; 4264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else { 430795f23920ee9aabf28e45c63cd592dcccf00216Mathieu Chartier return soa.Decode<mirror::String>(java_this)->CompareTo( 441cc62e4ea24828fdb3f3da0b8603f0b107d09a04Mathieu Chartier soa.Decode<mirror::String>(java_rhs).Ptr()); 45848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao } 46848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao} 47848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao 48848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Haostatic jstring String_concat(JNIEnv* env, jobject java_this, jobject java_string_arg) { 49848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao ScopedFastNativeObjectAccess soa(env); 50848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao if (UNLIKELY(java_string_arg == nullptr)) { 51848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao ThrowNullPointerException("string arg == null"); 52848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao return nullptr; 53848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao } 54848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao StackHandleScope<2> hs(soa.Self()); 550795f23920ee9aabf28e45c63cd592dcccf00216Mathieu Chartier Handle<mirror::String> string_this(hs.NewHandle(soa.Decode<mirror::String>(java_this))); 560795f23920ee9aabf28e45c63cd592dcccf00216Mathieu Chartier Handle<mirror::String> string_arg(hs.NewHandle(soa.Decode<mirror::String>(java_string_arg))); 57848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao int32_t length_this = string_this->GetLength(); 58848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao int32_t length_arg = string_arg->GetLength(); 59848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao if (length_arg > 0 && length_this > 0) { 60bc5a795c0d486c84913d987cad5846ded840cea6Mathieu Chartier ObjPtr<mirror::String> result = 61bc5a795c0d486c84913d987cad5846ded840cea6Mathieu Chartier mirror::String::AllocFromStrings(soa.Self(), string_this, string_arg); 62848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao return soa.AddLocalReference<jstring>(result); 63bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes } 64848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao jobject string_original = (length_this == 0) ? java_string_arg : java_this; 65848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao return reinterpret_cast<jstring>(string_original); 66bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes} 67bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes 68529bfef6b3152fcf244e806ea6822ee96ff3eb4fElliott Hughesstatic jint String_fastIndexOf(JNIEnv* env, jobject java_this, jint ch, jint start) { 691eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers ScopedFastNativeObjectAccess soa(env); 70529bfef6b3152fcf244e806ea6822ee96ff3eb4fElliott Hughes // This method does not handle supplementary characters. They're dealt with in managed code. 71529bfef6b3152fcf244e806ea6822ee96ff3eb4fElliott Hughes DCHECK_LE(ch, 0xffff); 720795f23920ee9aabf28e45c63cd592dcccf00216Mathieu Chartier return soa.Decode<mirror::String>(java_this)->FastIndexOf(ch, start); 73848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao} 74bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes 75848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Haostatic jstring String_fastSubstring(JNIEnv* env, jobject java_this, jint start, jint length) { 76848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao ScopedFastNativeObjectAccess soa(env); 77848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao StackHandleScope<1> hs(soa.Self()); 780795f23920ee9aabf28e45c63cd592dcccf00216Mathieu Chartier Handle<mirror::String> string_this(hs.NewHandle(soa.Decode<mirror::String>(java_this))); 79848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator(); 80bc5a795c0d486c84913d987cad5846ded840cea6Mathieu Chartier ObjPtr<mirror::String> result = mirror::String::AllocFromString<true>(soa.Self(), 81bc5a795c0d486c84913d987cad5846ded840cea6Mathieu Chartier length, 82bc5a795c0d486c84913d987cad5846ded840cea6Mathieu Chartier string_this, 83bc5a795c0d486c84913d987cad5846ded840cea6Mathieu Chartier start, 84bc5a795c0d486c84913d987cad5846ded840cea6Mathieu Chartier allocator_type); 85848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao return soa.AddLocalReference<jstring>(result); 86bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes} 87bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes 88848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Haostatic void String_getCharsNoCheck(JNIEnv* env, jobject java_this, jint start, jint end, 89848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao jcharArray buffer, jint index) { 901eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers ScopedFastNativeObjectAccess soa(env); 91848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao StackHandleScope<1> hs(soa.Self()); 920795f23920ee9aabf28e45c63cd592dcccf00216Mathieu Chartier Handle<mirror::CharArray> char_array(hs.NewHandle(soa.Decode<mirror::CharArray>(buffer))); 930795f23920ee9aabf28e45c63cd592dcccf00216Mathieu Chartier soa.Decode<mirror::String>(java_this)->GetChars(start, end, char_array, index); 94848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao} 95848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao 96848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Haostatic jstring String_intern(JNIEnv* env, jobject java_this) { 97848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao ScopedFastNativeObjectAccess soa(env); 980795f23920ee9aabf28e45c63cd592dcccf00216Mathieu Chartier ObjPtr<mirror::String> result = soa.Decode<mirror::String>(java_this)->Intern(); 9900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.AddLocalReference<jstring>(result); 100bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes} 101bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes 102848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Haostatic void String_setCharAt(JNIEnv* env, jobject java_this, jint index, jchar c) { 103848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao ScopedFastNativeObjectAccess soa(env); 1040795f23920ee9aabf28e45c63cd592dcccf00216Mathieu Chartier soa.Decode<mirror::String>(java_this)->SetCharAt(index, c); 105848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao} 106848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao 107848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Haostatic jcharArray String_toCharArray(JNIEnv* env, jobject java_this) { 108848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao ScopedFastNativeObjectAccess soa(env); 1090795f23920ee9aabf28e45c63cd592dcccf00216Mathieu Chartier ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_this); 110848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao return soa.AddLocalReference<jcharArray>(s->ToCharArray(soa.Self())); 111848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao} 112848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao 1130512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic JNINativeMethod gMethods[] = { 114848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao NATIVE_METHOD(String, charAt, "!(I)C"), 1151eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers NATIVE_METHOD(String, compareTo, "!(Ljava/lang/String;)I"), 116848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao NATIVE_METHOD(String, concat, "!(Ljava/lang/String;)Ljava/lang/String;"), 1171eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers NATIVE_METHOD(String, fastIndexOf, "!(II)I"), 118848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao NATIVE_METHOD(String, fastSubstring, "!(II)Ljava/lang/String;"), 119848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao NATIVE_METHOD(String, getCharsNoCheck, "!(II[CI)V"), 1201eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers NATIVE_METHOD(String, intern, "!()Ljava/lang/String;"), 121848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao NATIVE_METHOD(String, setCharAt, "!(IC)V"), 122848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao NATIVE_METHOD(String, toCharArray, "!()[C"), 123bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes}; 124bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes 125bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughesvoid register_java_lang_String(JNIEnv* env) { 126eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes REGISTER_NATIVE_METHODS("java/lang/String"); 127bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes} 128bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes 129bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes} // namespace art 130