• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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