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