xref: /aosp_15_r20/frameworks/base/libs/androidfw/ResourceUtils.cpp (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
1*d57664e9SAndroid Build Coastguard Worker /*
2*d57664e9SAndroid Build Coastguard Worker  * Copyright (C) 2017 The Android Open Source Project
3*d57664e9SAndroid Build Coastguard Worker  *
4*d57664e9SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*d57664e9SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*d57664e9SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*d57664e9SAndroid Build Coastguard Worker  *
8*d57664e9SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*d57664e9SAndroid Build Coastguard Worker  *
10*d57664e9SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*d57664e9SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*d57664e9SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*d57664e9SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*d57664e9SAndroid Build Coastguard Worker  * limitations under the License.
15*d57664e9SAndroid Build Coastguard Worker  */
16*d57664e9SAndroid Build Coastguard Worker 
17*d57664e9SAndroid Build Coastguard Worker #include "androidfw/ResourceUtils.h"
18*d57664e9SAndroid Build Coastguard Worker 
19*d57664e9SAndroid Build Coastguard Worker namespace android {
20*d57664e9SAndroid Build Coastguard Worker 
ExtractResourceName(StringPiece str,StringPiece * out_package,StringPiece * out_type,StringPiece * out_entry)21*d57664e9SAndroid Build Coastguard Worker bool ExtractResourceName(StringPiece str, StringPiece* out_package, StringPiece* out_type,
22*d57664e9SAndroid Build Coastguard Worker                          StringPiece* out_entry) {
23*d57664e9SAndroid Build Coastguard Worker   *out_package = "";
24*d57664e9SAndroid Build Coastguard Worker   *out_type = "";
25*d57664e9SAndroid Build Coastguard Worker   bool has_package_separator = false;
26*d57664e9SAndroid Build Coastguard Worker   bool has_type_separator = false;
27*d57664e9SAndroid Build Coastguard Worker   const char* start = str.data();
28*d57664e9SAndroid Build Coastguard Worker   const char* end = start + str.size();
29*d57664e9SAndroid Build Coastguard Worker   if (start[0] == '@') {
30*d57664e9SAndroid Build Coastguard Worker       start++;
31*d57664e9SAndroid Build Coastguard Worker   }
32*d57664e9SAndroid Build Coastguard Worker   const char* current = start;
33*d57664e9SAndroid Build Coastguard Worker   while (current != end) {
34*d57664e9SAndroid Build Coastguard Worker     if (out_type->size() == 0 && *current == '/') {
35*d57664e9SAndroid Build Coastguard Worker       has_type_separator = true;
36*d57664e9SAndroid Build Coastguard Worker       *out_type = StringPiece(start, current - start);
37*d57664e9SAndroid Build Coastguard Worker       start = current + 1;
38*d57664e9SAndroid Build Coastguard Worker     } else if (out_package->size() == 0 && *current == ':') {
39*d57664e9SAndroid Build Coastguard Worker       has_package_separator = true;
40*d57664e9SAndroid Build Coastguard Worker       *out_package = StringPiece(start, current - start);
41*d57664e9SAndroid Build Coastguard Worker       start = current + 1;
42*d57664e9SAndroid Build Coastguard Worker     }
43*d57664e9SAndroid Build Coastguard Worker     current++;
44*d57664e9SAndroid Build Coastguard Worker   }
45*d57664e9SAndroid Build Coastguard Worker   *out_entry = StringPiece(start, end - start);
46*d57664e9SAndroid Build Coastguard Worker 
47*d57664e9SAndroid Build Coastguard Worker   return !(has_package_separator && out_package->empty()) &&
48*d57664e9SAndroid Build Coastguard Worker          !(has_type_separator && out_type->empty());
49*d57664e9SAndroid Build Coastguard Worker }
50*d57664e9SAndroid Build Coastguard Worker 
ToResourceName(const StringPoolRef & type_string_ref,const StringPoolRef & entry_string_ref,StringPiece package_name)51*d57664e9SAndroid Build Coastguard Worker base::expected<AssetManager2::ResourceName, NullOrIOError> ToResourceName(
52*d57664e9SAndroid Build Coastguard Worker     const StringPoolRef& type_string_ref, const StringPoolRef& entry_string_ref,
53*d57664e9SAndroid Build Coastguard Worker     StringPiece package_name) {
54*d57664e9SAndroid Build Coastguard Worker   AssetManager2::ResourceName name{
55*d57664e9SAndroid Build Coastguard Worker     .package = package_name.data(),
56*d57664e9SAndroid Build Coastguard Worker     .package_len = package_name.size(),
57*d57664e9SAndroid Build Coastguard Worker   };
58*d57664e9SAndroid Build Coastguard Worker 
59*d57664e9SAndroid Build Coastguard Worker   if (base::expected<StringPiece, NullOrIOError> type_str = type_string_ref.string8();
60*d57664e9SAndroid Build Coastguard Worker       type_str.ok()) {
61*d57664e9SAndroid Build Coastguard Worker     name.type = type_str->data();
62*d57664e9SAndroid Build Coastguard Worker     name.type_len = type_str->size();
63*d57664e9SAndroid Build Coastguard Worker   } else if (UNLIKELY(IsIOError(type_str))) {
64*d57664e9SAndroid Build Coastguard Worker     return base::unexpected(type_str.error());
65*d57664e9SAndroid Build Coastguard Worker   }
66*d57664e9SAndroid Build Coastguard Worker 
67*d57664e9SAndroid Build Coastguard Worker   if (name.type == nullptr) {
68*d57664e9SAndroid Build Coastguard Worker     if (base::expected<StringPiece16, NullOrIOError> type16_str = type_string_ref.string16();
69*d57664e9SAndroid Build Coastguard Worker         type16_str.ok()) {
70*d57664e9SAndroid Build Coastguard Worker       name.type16 = type16_str->data();
71*d57664e9SAndroid Build Coastguard Worker       name.type_len = type16_str->size();
72*d57664e9SAndroid Build Coastguard Worker     } else if (!type16_str.has_value()) {
73*d57664e9SAndroid Build Coastguard Worker       return base::unexpected(type16_str.error());
74*d57664e9SAndroid Build Coastguard Worker     }
75*d57664e9SAndroid Build Coastguard Worker   }
76*d57664e9SAndroid Build Coastguard Worker 
77*d57664e9SAndroid Build Coastguard Worker   if (base::expected<StringPiece, NullOrIOError> entry_str = entry_string_ref.string8();
78*d57664e9SAndroid Build Coastguard Worker       entry_str.ok()) {
79*d57664e9SAndroid Build Coastguard Worker     name.entry = entry_str->data();
80*d57664e9SAndroid Build Coastguard Worker     name.entry_len = entry_str->size();
81*d57664e9SAndroid Build Coastguard Worker   } else if (UNLIKELY(IsIOError(entry_str))) {
82*d57664e9SAndroid Build Coastguard Worker     return base::unexpected(entry_str.error());
83*d57664e9SAndroid Build Coastguard Worker   }
84*d57664e9SAndroid Build Coastguard Worker 
85*d57664e9SAndroid Build Coastguard Worker   if (name.entry == nullptr) {
86*d57664e9SAndroid Build Coastguard Worker     if (base::expected<StringPiece16, NullOrIOError> entry16_str = entry_string_ref.string16();
87*d57664e9SAndroid Build Coastguard Worker         entry16_str.ok()) {
88*d57664e9SAndroid Build Coastguard Worker       name.entry16 = entry16_str->data();
89*d57664e9SAndroid Build Coastguard Worker       name.entry_len = entry16_str->size();
90*d57664e9SAndroid Build Coastguard Worker     } else if (!entry16_str.has_value()) {
91*d57664e9SAndroid Build Coastguard Worker       return base::unexpected(entry16_str.error());
92*d57664e9SAndroid Build Coastguard Worker     }
93*d57664e9SAndroid Build Coastguard Worker   }
94*d57664e9SAndroid Build Coastguard Worker 
95*d57664e9SAndroid Build Coastguard Worker   return name;
96*d57664e9SAndroid Build Coastguard Worker }
97*d57664e9SAndroid Build Coastguard Worker 
ToFormattedResourceString(const AssetManager2::ResourceName & resource_name)98*d57664e9SAndroid Build Coastguard Worker std::string ToFormattedResourceString(const AssetManager2::ResourceName& resource_name) {
99*d57664e9SAndroid Build Coastguard Worker   std::string result;
100*d57664e9SAndroid Build Coastguard Worker   if (resource_name.package != nullptr) {
101*d57664e9SAndroid Build Coastguard Worker     result.append(resource_name.package, resource_name.package_len);
102*d57664e9SAndroid Build Coastguard Worker   }
103*d57664e9SAndroid Build Coastguard Worker 
104*d57664e9SAndroid Build Coastguard Worker   if (resource_name.type != nullptr || resource_name.type16 != nullptr) {
105*d57664e9SAndroid Build Coastguard Worker     if (!result.empty()) {
106*d57664e9SAndroid Build Coastguard Worker       result += ":";
107*d57664e9SAndroid Build Coastguard Worker     }
108*d57664e9SAndroid Build Coastguard Worker 
109*d57664e9SAndroid Build Coastguard Worker     if (resource_name.type != nullptr) {
110*d57664e9SAndroid Build Coastguard Worker       result.append(resource_name.type, resource_name.type_len);
111*d57664e9SAndroid Build Coastguard Worker     } else {
112*d57664e9SAndroid Build Coastguard Worker       result += util::Utf16ToUtf8(StringPiece16(resource_name.type16, resource_name.type_len));
113*d57664e9SAndroid Build Coastguard Worker     }
114*d57664e9SAndroid Build Coastguard Worker   }
115*d57664e9SAndroid Build Coastguard Worker 
116*d57664e9SAndroid Build Coastguard Worker   if (resource_name.entry != nullptr || resource_name.entry16 != nullptr) {
117*d57664e9SAndroid Build Coastguard Worker     if (!result.empty()) {
118*d57664e9SAndroid Build Coastguard Worker       result += "/";
119*d57664e9SAndroid Build Coastguard Worker     }
120*d57664e9SAndroid Build Coastguard Worker 
121*d57664e9SAndroid Build Coastguard Worker     if (resource_name.entry != nullptr) {
122*d57664e9SAndroid Build Coastguard Worker       result.append(resource_name.entry, resource_name.entry_len);
123*d57664e9SAndroid Build Coastguard Worker     } else {
124*d57664e9SAndroid Build Coastguard Worker       result += util::Utf16ToUtf8(StringPiece16(resource_name.entry16, resource_name.entry_len));
125*d57664e9SAndroid Build Coastguard Worker     }
126*d57664e9SAndroid Build Coastguard Worker   }
127*d57664e9SAndroid Build Coastguard Worker 
128*d57664e9SAndroid Build Coastguard Worker   return result;
129*d57664e9SAndroid Build Coastguard Worker }
130*d57664e9SAndroid Build Coastguard Worker 
131*d57664e9SAndroid Build Coastguard Worker }  // namespace android
132