blob: d89ef1ecd9447f1b3ccc6c47c19384117c395e02 [file] [log] [blame]
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001/*
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 */
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070016#ifndef ART_RUNTIME_MIRROR_STRING_INL_H_
17#define ART_RUNTIME_MIRROR_STRING_INL_H_
18
Andreas Gampe46ee31b2016-12-14 10:11:49 -080019#include "string.h"
20
21#include "android-base/stringprintf.h"
22
David Sehrc431b9d2018-03-02 12:01:51 -080023#include "base/globals.h"
24#include "base/utils.h"
Andreas Gampefd63bbf2018-10-29 12:55:35 -070025#include "class-inl.h"
Vladimir Marko87f3fcb2016-04-28 15:52:11 +010026#include "common_throws.h"
David Sehr0225f8e2018-01-31 08:52:24 +000027#include "dex/utf.h"
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070028
29namespace art {
30namespace mirror {
31
Andreas Gampe542451c2016-07-26 09:02:02 -070032inline uint32_t String::ClassSize(PointerSize pointer_size) {
Alan Leung8f514ee2017-12-08 14:08:25 -080033#ifdef USE_D8_DESUGAR
34 // Two lambdas in CharSequence:
35 // lambda$chars$0$CharSequence
36 // lambda$codePoints$1$CharSequence
37 // which were virtual functions in standalone desugar, becomes
38 // direct functions with D8 desugaring.
39 uint32_t vtable_entries = Object::kVTableLength + 54;
40#else
Vladimir Marko92907f32017-02-20 14:08:30 +000041 uint32_t vtable_entries = Object::kVTableLength + 56;
Alan Leung8f514ee2017-12-08 14:08:25 -080042#endif
Narayan Kamath5d8fa8b2016-04-13 14:17:44 +010043 return Class::ComputeClassSize(true, vtable_entries, 0, 0, 0, 1, 2, pointer_size);
Mingyao Yang98d1cc82014-05-15 17:02:16 -070044}
45
Jeff Hao848f70a2014-01-15 13:49:50 -080046inline uint16_t String::CharAt(int32_t index) {
jessicahandojo3aaa37b2016-07-29 14:46:37 -070047 int32_t count = GetLength();
Jeff Hao848f70a2014-01-15 13:49:50 -080048 if (UNLIKELY((index < 0) || (index >= count))) {
Vladimir Marko87f3fcb2016-04-28 15:52:11 +010049 ThrowStringIndexOutOfBoundsException(index, count);
Jeff Hao848f70a2014-01-15 13:49:50 -080050 return 0;
51 }
jessicahandojo3aaa37b2016-07-29 14:46:37 -070052 if (IsCompressed()) {
53 return GetValueCompressed()[index];
54 } else {
55 return GetValue()[index];
56 }
57}
58
59template <typename MemoryType>
60int32_t String::FastIndexOf(MemoryType* chars, int32_t ch, int32_t start) {
61 const MemoryType* p = chars + start;
62 const MemoryType* end = chars + GetLength();
63 while (p < end) {
64 if (*p++ == ch) {
65 return (p - 1) - chars;
66 }
67 }
68 return -1;
Jeff Hao848f70a2014-01-15 13:49:50 -080069}
70
Mathieu Chartiercdfd39f2014-08-29 18:16:58 -070071inline int32_t String::GetHashCode() {
72 int32_t result = GetField32(OFFSET_OF_OBJECT_MEMBER(String, hash_code_));
73 if (UNLIKELY(result == 0)) {
74 result = ComputeHashCode();
75 }
jessicahandojo3aaa37b2016-07-29 14:46:37 -070076 if (kIsDebugBuild) {
77 if (IsCompressed()) {
78 DCHECK(result != 0 || ComputeUtf16Hash(GetValueCompressed(), GetLength()) == 0)
79 << ToModifiedUtf8() << " " << result;
80 } else {
81 DCHECK(result != 0 || ComputeUtf16Hash(GetValue(), GetLength()) == 0)
82 << ToModifiedUtf8() << " " << result;
83 }
84 }
Mathieu Chartiercdfd39f2014-08-29 18:16:58 -070085 return result;
86}
87
jessicahandojo3aaa37b2016-07-29 14:46:37 -070088template<typename MemoryType>
Vladimir Markoe39f14f2017-02-10 15:44:25 +000089inline bool String::AllASCII(const MemoryType* chars, const int length) {
Vladimir Marko16850ae2016-12-09 14:01:02 +000090 static_assert(std::is_unsigned<MemoryType>::value, "Expecting unsigned MemoryType");
jessicahandojo3aaa37b2016-07-29 14:46:37 -070091 for (int i = 0; i < length; ++i) {
Vladimir Marko92907f32017-02-20 14:08:30 +000092 if (!IsASCII(chars[i])) {
jessicahandojo3aaa37b2016-07-29 14:46:37 -070093 return false;
94 }
95 }
96 return true;
97}
98
Vladimir Markoe39f14f2017-02-10 15:44:25 +000099inline bool String::DexFileStringAllASCII(const char* chars, const int length) {
100 // For strings from the dex file we just need to check that
101 // the terminating character is at the right position.
102 DCHECK_EQ(AllASCII(reinterpret_cast<const uint8_t*>(chars), length), chars[length] == 0);
103 return chars[length] == 0;
104}
105
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700106} // namespace mirror
107} // namespace art
108
109#endif // ART_RUNTIME_MIRROR_STRING_INL_H_