1 /*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "ability.h"
17 #include "ani_resource_parser.h"
18 #include "ani_text_utils.h"
19
20 namespace OHOS::Text::ANI {
21 namespace {
AniToStdVectorString(ani_env * env,ani_array array)22 std::vector<std::string> AniToStdVectorString(ani_env* env, ani_array array)
23 {
24 std::vector<std::string> result;
25
26 ani_size length;
27 ani_status ret = env->Array_GetLength(array, &length);
28 if (ret != ANI_OK) {
29 return result;
30 }
31 for (ani_size i = 0; i < length; i++) {
32 ani_ref aniString = nullptr;
33 ret = env->Array_Get_Ref(reinterpret_cast<ani_array_ref>(array), i, &aniString);
34 if (ret != ANI_OK) {
35 TEXT_LOGE("Failed to get array element %{public}zu", i);
36 continue;
37 }
38 std::string utf8Str;
39 ret = AniTextUtils::AniToStdStringUtf8(env, reinterpret_cast<ani_string>(aniString), utf8Str);
40 if (ret != ANI_OK) {
41 TEXT_LOGE("Failed to get str %{public}zu", i);
42 continue;
43 }
44 result.push_back(utf8Str);
45 }
46
47 return result;
48 }
49 } // namespace
50
ParseResource(ani_env * env,ani_object obj)51 AniResource AniResourceParser::ParseResource(ani_env* env, ani_object obj)
52 {
53 AniResource result;
54 ani_double aniId{0};
55 ani_ref aniBundleName{nullptr};
56 ani_ref aniModuleName{nullptr};
57 ani_ref aniParams{nullptr};
58 ani_double aniType{0};
59 env->Object_GetPropertyByName_Double(obj, "id", &aniId);
60 env->Object_GetPropertyByName_Ref(obj, "bundleName", &aniBundleName);
61 env->Object_GetPropertyByName_Ref(obj, "moduleName", &aniModuleName);
62 env->Object_GetPropertyByName_Ref(obj, "params", &aniParams);
63 env->Object_GetPropertyByName_Double(obj, "type", &aniType);
64
65 result.type = static_cast<int32_t>(aniType);
66 result.id = static_cast<int32_t>(aniId);
67 if (aniBundleName != nullptr) {
68 AniTextUtils::AniToStdStringUtf8(env, reinterpret_cast<ani_string>(aniBundleName), result.bundleName);
69 }
70 if (aniModuleName != nullptr) {
71 AniTextUtils::AniToStdStringUtf8(env, reinterpret_cast<ani_string>(aniModuleName), result.moduleName);
72 }
73 if (aniParams != nullptr) {
74 result.params = AniToStdVectorString(env, reinterpret_cast<ani_array>(aniParams));
75 }
76
77 return result;
78 }
79
ResolveResource(const AniResource & resource,size_t & dataLen,std::unique_ptr<uint8_t[]> & data)80 bool AniResourceParser::ResolveResource(const AniResource& resource, size_t& dataLen, std::unique_ptr<uint8_t[]>& data)
81 {
82 auto context = AbilityRuntime::ApplicationContext::GetApplicationContext();
83 TEXT_ERROR_CHECK(context != nullptr, return false, "Failed to get application context");
84 auto resourceManager = context->GetResourceManager();
85 TEXT_ERROR_CHECK(resourceManager != nullptr, return false, "Failed to get resource manager");
86
87 if (resource.type == static_cast<int32_t>(Global::Resource::ResType::STRING)) {
88 std::string rPath;
89 if (resource.id < 0 && !resource.params.empty() && !resource.params[0].empty()) {
90 rPath = resource.params[0];
91 } else {
92 uint32_t state =
93 static_cast<uint32_t>(resourceManager->GetStringById(static_cast<uint32_t>(resource.id), rPath));
94 if (state >= static_cast<uint32_t>(Global::Resource::RState::ERROR)) {
95 return false;
96 }
97 if (!AniTextUtils::SplitAbsoluteFontPath(rPath) || !AniTextUtils::ReadFile(rPath, dataLen, data)) {
98 return false;
99 }
100 }
101 } else if (resource.type == static_cast<int32_t>(Global::Resource::ResType::RAW)) {
102 if (resource.params.empty()) {
103 return false;
104 }
105
106 uint32_t state = resourceManager->GetRawFileFromHap(resource.params[0], dataLen, data);
107 if (state >= static_cast<uint32_t>(Global::Resource::RState::ERROR)) {
108 return false;
109 }
110 } else {
111 TEXT_LOGE("Unsupported resource type");
112 }
113
114 return true;
115 }
116 } // namespace OHOS::Text::ANI
117