• 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