1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #ifndef ART_RUNTIME_MIRROR_STRING_INL_H_ 17 #define ART_RUNTIME_MIRROR_STRING_INL_H_ 18 19 #include "string.h" 20 21 #include "android-base/stringprintf.h" 22 23 #include "class-inl.h" 24 #include "common_throws.h" 25 #include "dex/utf.h" 26 #include "runtime_globals.h" 27 28 namespace art { 29 namespace mirror { 30 31 inline uint32_t String::ClassSize(PointerSize pointer_size) { 32 #ifdef USE_D8_DESUGAR 33 // Two lambdas in CharSequence: 34 // lambda$chars$0$CharSequence 35 // lambda$codePoints$1$CharSequence 36 // which were virtual functions in standalone desugar, becomes 37 // direct functions with D8 desugaring. 38 uint32_t vtable_entries = Object::kVTableLength + 54; 39 #else 40 uint32_t vtable_entries = Object::kVTableLength + 56; 41 #endif 42 return Class::ComputeClassSize(true, vtable_entries, 0, 0, 0, 1, 2, pointer_size); 43 } 44 45 inline uint16_t String::CharAt(int32_t index) { 46 int32_t count = GetLength(); 47 if (UNLIKELY((index < 0) || (index >= count))) { 48 ThrowStringIndexOutOfBoundsException(index, count); 49 return 0; 50 } 51 if (IsCompressed()) { 52 return GetValueCompressed()[index]; 53 } else { 54 return GetValue()[index]; 55 } 56 } 57 58 template <typename MemoryType> 59 int32_t String::FastIndexOf(MemoryType* chars, int32_t ch, int32_t start) { 60 const MemoryType* p = chars + start; 61 const MemoryType* end = chars + GetLength(); 62 while (p < end) { 63 if (*p++ == ch) { 64 return (p - 1) - chars; 65 } 66 } 67 return -1; 68 } 69 70 inline int32_t String::GetHashCode() { 71 int32_t result = GetField32(OFFSET_OF_OBJECT_MEMBER(String, hash_code_)); 72 if (UNLIKELY(result == 0)) { 73 result = ComputeHashCode(); 74 } 75 if (kIsDebugBuild) { 76 if (IsCompressed()) { 77 DCHECK(result != 0 || ComputeUtf16Hash(GetValueCompressed(), GetLength()) == 0) 78 << ToModifiedUtf8() << " " << result; 79 } else { 80 DCHECK(result != 0 || ComputeUtf16Hash(GetValue(), GetLength()) == 0) 81 << ToModifiedUtf8() << " " << result; 82 } 83 } 84 return result; 85 } 86 87 inline int32_t String::GetUtfLength() { 88 if (IsCompressed()) { 89 return GetLength(); 90 } else { 91 return CountUtf8Bytes(GetValue(), GetLength()); 92 } 93 } 94 95 template<typename MemoryType> 96 inline bool String::AllASCII(const MemoryType* chars, const int length) { 97 static_assert(std::is_unsigned<MemoryType>::value, "Expecting unsigned MemoryType"); 98 for (int i = 0; i < length; ++i) { 99 if (!IsASCII(chars[i])) { 100 return false; 101 } 102 } 103 return true; 104 } 105 106 inline bool String::DexFileStringAllASCII(const char* chars, const int length) { 107 // For strings from the dex file we just need to check that 108 // the terminating character is at the right position. 109 DCHECK_EQ(AllASCII(reinterpret_cast<const uint8_t*>(chars), length), chars[length] == 0); 110 return chars[length] == 0; 111 } 112 113 } // namespace mirror 114 } // namespace art 115 116 #endif // ART_RUNTIME_MIRROR_STRING_INL_H_ 117