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 HIDDEN { 29 namespace mirror { 30 ClassSize(PointerSize pointer_size)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 + 70; 39 #else 40 uint32_t vtable_entries = Object::kVTableLength + 72; 41 #endif 42 return Class::ComputeClassSize(true, vtable_entries, 3, 0, 0, 1, 3, pointer_size); 43 } 44 CharAt(int32_t index)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> FastIndexOf(MemoryType * chars,int32_t ch,int32_t start)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 template <typename MemoryType> LastIndexOf(MemoryType * chars,int32_t ch,int32_t from_index)71 int32_t String::LastIndexOf(MemoryType* chars, int32_t ch, int32_t from_index) { 72 DCHECK_LT(from_index, GetLength()); 73 const MemoryType* start = chars; 74 const MemoryType* p = chars + from_index; 75 while (p >= start) { 76 if (*p == ch) { 77 return p - chars; 78 } 79 p--; 80 } 81 return -1; 82 } 83 ComputeHashCode()84 inline int32_t String::ComputeHashCode() { 85 uint32_t hash = IsCompressed() 86 ? ComputeUtf16Hash(GetValueCompressed(), GetLength()) 87 : ComputeUtf16Hash(GetValue(), GetLength()); 88 return static_cast<int32_t>(hash); 89 } 90 GetHashCode()91 inline int32_t String::GetHashCode() { 92 int32_t result = GetStoredHashCode(); 93 if (UNLIKELY(result == 0)) { 94 result = ComputeAndSetHashCode(); 95 } 96 DCHECK_IMPLIES(result == 0, ComputeHashCode() == 0) << ToModifiedUtf8(); 97 return result; 98 } 99 GetModifiedUtf8Length()100 inline int32_t String::GetModifiedUtf8Length() { 101 if (IsCompressed()) { 102 return GetLength(); 103 } else { 104 return CountModifiedUtf8BytesInUtf16(GetValue(), GetLength()); 105 } 106 } 107 108 template<typename MemoryType> AllASCII(const MemoryType * chars,const int length)109 inline bool String::AllASCII(const MemoryType* chars, const int length) { 110 static_assert(std::is_unsigned<MemoryType>::value, "Expecting unsigned MemoryType"); 111 for (int i = 0; i < length; ++i) { 112 if (!IsASCII(chars[i])) { 113 return false; 114 } 115 } 116 return true; 117 } 118 DexFileStringAllASCII(const char * chars,const int length)119 inline bool String::DexFileStringAllASCII(const char* chars, const int length) { 120 // For strings from the dex file we just need to check that 121 // the terminating character is at the right position. 122 DCHECK_EQ(AllASCII(reinterpret_cast<const uint8_t*>(chars), length), chars[length] == 0); 123 return chars[length] == 0; 124 } 125 126 } // namespace mirror 127 } // namespace art 128 129 #endif // ART_RUNTIME_MIRROR_STRING_INL_H_ 130