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