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 10292907f3f7af106a9eeb341caba17f3770203f7fbVladimir Markostatic jstring String_doReplace(JNIEnv* env, jobject java_this, jchar old_c, jchar new_c) { 103848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao ScopedFastNativeObjectAccess soa(env); 1049e57abacecc683f50dd6c9870a32ee075eaf86a8Vladimir Marko StackHandleScope<1> hs(soa.Self()); 1059e57abacecc683f50dd6c9870a32ee075eaf86a8Vladimir Marko Handle<mirror::String> string = hs.NewHandle(soa.Decode<mirror::String>(java_this)); 1069e57abacecc683f50dd6c9870a32ee075eaf86a8Vladimir Marko ObjPtr<mirror::String> result = mirror::String::DoReplace(soa.Self(), string, old_c, new_c); 10792907f3f7af106a9eeb341caba17f3770203f7fbVladimir Marko return soa.AddLocalReference<jstring>(result); 108848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao} 109848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao 110848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Haostatic jcharArray String_toCharArray(JNIEnv* env, jobject java_this) { 111848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao ScopedFastNativeObjectAccess soa(env); 1120795f23920ee9aabf28e45c63cd592dcccf00216Mathieu Chartier ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_this); 113848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao return soa.AddLocalReference<jcharArray>(s->ToCharArray(soa.Self())); 114848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao} 115848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao 1160512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic JNINativeMethod gMethods[] = { 1173b6f440dbd066f03a737da6d292074f47b3fbc29Igor Murashkin FAST_NATIVE_METHOD(String, charAt, "(I)C"), 1183b6f440dbd066f03a737da6d292074f47b3fbc29Igor Murashkin FAST_NATIVE_METHOD(String, compareTo, "(Ljava/lang/String;)I"), 1193b6f440dbd066f03a737da6d292074f47b3fbc29Igor Murashkin FAST_NATIVE_METHOD(String, concat, "(Ljava/lang/String;)Ljava/lang/String;"), 1203b6f440dbd066f03a737da6d292074f47b3fbc29Igor Murashkin FAST_NATIVE_METHOD(String, doReplace, "(CC)Ljava/lang/String;"), 1213b6f440dbd066f03a737da6d292074f47b3fbc29Igor Murashkin FAST_NATIVE_METHOD(String, fastIndexOf, "(II)I"), 1223b6f440dbd066f03a737da6d292074f47b3fbc29Igor Murashkin FAST_NATIVE_METHOD(String, fastSubstring, "(II)Ljava/lang/String;"), 1233b6f440dbd066f03a737da6d292074f47b3fbc29Igor Murashkin FAST_NATIVE_METHOD(String, getCharsNoCheck, "(II[CI)V"), 1243b6f440dbd066f03a737da6d292074f47b3fbc29Igor Murashkin FAST_NATIVE_METHOD(String, intern, "()Ljava/lang/String;"), 1253b6f440dbd066f03a737da6d292074f47b3fbc29Igor Murashkin FAST_NATIVE_METHOD(String, toCharArray, "()[C"), 126bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes}; 127bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes 128bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughesvoid register_java_lang_String(JNIEnv* env) { 129eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes REGISTER_NATIVE_METHODS("java/lang/String"); 130bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes} 131bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes 132bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes} // namespace art 133