• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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 
17 #ifndef ART_RUNTIME_NATIVE_STRING_ARRAY_UTILS_H_
18 #define ART_RUNTIME_NATIVE_STRING_ARRAY_UTILS_H_
19 
20 #include "base/locks.h"
21 #include "class_root-inl.h"
22 #include "handle_scope-inl.h"
23 #include "mirror/object_array-alloc-inl.h"
24 #include "mirror/string.h"
25 
26 namespace art {
27 
28 namespace detail {
29 
GetStringCStr(const char * str)30 inline const char* GetStringCStr(const char* str) { return str; }
GetStringCStr(const std::string & str)31 inline const char* GetStringCStr(const std::string& str) { return str.c_str(); }
32 
33 }  // namespace detail
34 
35 template <typename Container>
CreateStringArray(Thread * self,size_t size,const Container & entries)36 ObjPtr<mirror::ObjectArray<mirror::String>> CreateStringArray(
37     Thread* self, size_t size, const Container& entries) REQUIRES_SHARED(Locks::mutator_lock_) {
38   StackHandleScope<1u> hs(self);
39   Handle<mirror::ObjectArray<mirror::String>> array = hs.NewHandle(
40       mirror::ObjectArray<mirror::String>::Alloc(
41           self, GetClassRoot<mirror::ObjectArray<mirror::String>>(), size));
42   if (array == nullptr) {
43     DCHECK(self->IsExceptionPending());
44     return nullptr;
45   }
46   // Note: If the container's iterator returns a `std::string` by value, the `auto&&`
47   // binds as a const reference and extends the lifetime of the temporary object.
48   size_t pos = 0u;
49   for (auto&& entry : entries) {
50     ObjPtr<mirror::String> oentry =
51         mirror::String::AllocFromModifiedUtf8(self, detail::GetStringCStr(entry));
52     if (oentry == nullptr) {
53       DCHECK(self->IsExceptionPending());
54       return nullptr;
55     }
56     // We're initializing a newly allocated array object, so we do not need to record that under
57     // a transaction. If the transaction is aborted, the whole object shall be unreachable.
58     DCHECK_LT(pos, size);
59     array->SetWithoutChecks</*kTransactionActive=*/ false, /*kCheckTransaction=*/ false>(
60         pos, oentry);
61     ++pos;
62   }
63   DCHECK_EQ(pos, size);
64   return array.Get();
65 }
66 
67 template <typename Container>
CreateStringArray(Thread * self,const Container & entries)68 ObjPtr<mirror::ObjectArray<mirror::String>> CreateStringArray(
69     Thread* self, const Container& entries) REQUIRES_SHARED(Locks::mutator_lock_) {
70   return CreateStringArray(self, entries.size(), entries);
71 }
72 
CreateStringArray(Thread * self,std::initializer_list<const char * > entries)73 inline ObjPtr<mirror::ObjectArray<mirror::String>> CreateStringArray(
74     Thread* self, std::initializer_list<const char*> entries)
75     REQUIRES_SHARED(Locks::mutator_lock_) {
76   return CreateStringArray<std::initializer_list<const char*>>(self, entries);
77 }
78 
79 }  // namespace art
80 
81 #endif  // ART_RUNTIME_NATIVE_STRING_ARRAY_UTILS_H_
82