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 "stat_wrapper.h"
17
18 #include <iostream>
19 #include <string_view>
20 #include <string>
21
22 #include "ani_signature.h"
23 #include "error_handler.h"
24 #include "filemgmt_libhilog.h"
25 #include "type_converter.h"
26
27 namespace OHOS {
28 namespace FileManagement {
29 namespace ModuleFileIO {
30 namespace ANI {
31 using namespace std;
32 using namespace OHOS::FileManagement::ModuleFileIO;
33 using namespace OHOS::FileManagement::ModuleFileIO::ANI::AniSignature;
34
SetNumProperty(ani_env * env,const ani_class & cls,ani_object & object,const char * name,ani_double & value)35 static ani_status SetNumProperty(
36 ani_env *env, const ani_class &cls, ani_object &object, const char *name, ani_double &value)
37 {
38 ani_method setter;
39 ani_status ret;
40 if ((ret = env->Class_FindMethod(cls, name, nullptr, &setter)) != ANI_OK) {
41 HILOGE("Class_FindMethod Fail %{private}s, err: %{private}d", name, ret);
42 return ret;
43 }
44
45 return env->Object_CallMethod_Void(object, setter, value);
46 }
47
SetBigIntProperty(ani_env * env,const ani_class & statCls,ani_object & statObject,const char * name,ani_double & value)48 static ani_status SetBigIntProperty(
49 ani_env *env, const ani_class &statCls, ani_object &statObject, const char *name, ani_double &value)
50 {
51 ani_object object = {};
52 auto classDesc = BuiltInTypes::BigInt::classDesc.c_str();
53 ani_class cls;
54 ani_status ret;
55
56 if ((ret = env->FindClass(classDesc, &cls)) != ANI_OK) {
57 HILOGE("Not found %{private}s, err: %{private}d", classDesc, ret);
58 return ret;
59 }
60
61 auto ctorDesc = BuiltInTypes::BigInt::ctorDesc.c_str();
62 auto ctorSig = BuiltInTypes::BigInt::ctorSig.c_str();
63 ani_method ctor;
64 if (ANI_OK != env->Class_FindMethod(cls, ctorDesc, ctorSig, &ctor)) {
65 HILOGE("Not found ctor, err: %{private}d", ret);
66 return ret;
67 }
68
69 if ((ret = env->Object_New(cls, ctor, &object, value)) != ANI_OK) {
70 HILOGE("New BigIntProperty Fail, err: %{private}d", ret);
71 return ret;
72 }
73
74 ani_method setter;
75 if ((ret = env->Class_FindMethod(statCls, name, nullptr, &setter)) != ANI_OK) {
76 HILOGE("Class_FindMethod Fail %{private}s, err: %{private}d", name, ret);
77 return ret;
78 }
79
80 return env->Object_CallMethod_Void(statObject, setter, object);
81 }
82
GetLocationEnumIndex(ani_env * env,const Location & value)83 static ani_enum_item GetLocationEnumIndex(ani_env *env, const Location &value)
84 {
85 ani_enum enumType;
86 auto classDesc = FS::LocationType::classDesc.c_str();
87 ani_status ret = env->FindEnum(classDesc, &enumType);
88 if (ret != ANI_OK) {
89 HILOGE("FindEnum %{private}s failed, err: %{private}d", classDesc, ret);
90 return nullptr;
91 }
92
93 size_t valueAsSizeT = static_cast<size_t>(value);
94 if (valueAsSizeT < 1) {
95 HILOGE("Invalid Location value: %{private}zu", valueAsSizeT);
96 return nullptr;
97 }
98
99 size_t index = valueAsSizeT - 1;
100
101 ani_enum_item enumItem;
102 ret = env->Enum_GetEnumItemByIndex(enumType, index, &enumItem);
103 if (ret != ANI_OK) {
104 HILOGE("Enum_GetEnumItemByIndex failed, index: %{private}zu, err: %{private}d", index, ret);
105 return nullptr;
106 }
107 return enumItem;
108 }
109
SetEnumLocation(ani_env * env,const ani_class & cls,ani_object & object,const char * name,const Location & value)110 static ani_status SetEnumLocation(
111 ani_env *env, const ani_class &cls, ani_object &object, const char *name, const Location &value)
112 {
113 ani_method setter;
114 ani_status ret;
115 if ((ret = env->Class_FindMethod(cls, name, nullptr, &setter)) != ANI_OK) {
116 HILOGE("Class_FindMethod Fail %{private}s, err: %{private}d", name, ret);
117 return ret;
118 }
119
120 return env->Object_CallMethod_Void(object, setter, GetLocationEnumIndex(env, value));
121 }
122
123 const static string MODE_SETTER = Builder::BuildSetterName("mode");
124 const static string UID_SETTER = Builder::BuildSetterName("uid");
125 const static string GID_SETTER = Builder::BuildSetterName("gid");
126 const static string SIZE_SETTER = Builder::BuildSetterName("size");
127 const static string ATIME_SETTER = Builder::BuildSetterName("atime");
128 const static string MTIME_SETTER = Builder::BuildSetterName("mtime");
129 const static string CTIME_SETTER = Builder::BuildSetterName("ctime");
130 const static string INO_SETTER = Builder::BuildSetterName("ino");
131 const static string ATIME_NS_SETTER = Builder::BuildSetterName("atimeNs");
132 const static string MTIME_NS_SETTER = Builder::BuildSetterName("mtimeNs");
133 const static string CTIME_NS_SETTER = Builder::BuildSetterName("ctimeNs");
134 const static string LOCATION_SETTER = Builder::BuildSetterName("location");
135
SetProperties(ani_env * env,const ani_class & cls,ani_object & statObject,FsStat * fsStat)136 static ani_status SetProperties(ani_env *env, const ani_class &cls, ani_object &statObject, FsStat *fsStat)
137 {
138 ani_status ret;
139
140 vector<pair<string_view, ani_double>> numProperties = {
141 { MODE_SETTER, ani_double(static_cast<double>(fsStat->GetMode())) },
142 { UID_SETTER, ani_double(static_cast<double>(fsStat->GetUid())) },
143 { GID_SETTER, ani_double(static_cast<double>(fsStat->GetGid())) },
144 { SIZE_SETTER, ani_double(static_cast<double>(fsStat->GetSize())) },
145 { ATIME_SETTER, ani_double(static_cast<double>(fsStat->GetAtime())) },
146 { MTIME_SETTER, ani_double(static_cast<double>(fsStat->GetMtime())) },
147 { CTIME_SETTER, ani_double(static_cast<double>(fsStat->GetCtime())) },
148 };
149 for (auto iter : numProperties) {
150 auto key = iter.first.data();
151 auto value = iter.second;
152 ret = SetNumProperty(env, cls, statObject, key, value);
153 if (ret != ANI_OK) {
154 HILOGE("Object_CallMethod_Void Fail %{private}s, err: %{private}d", key, ret);
155 return ret;
156 }
157 }
158
159 vector<pair<string_view, ani_double>> bigIntProperties = {
160 { INO_SETTER, ani_double(static_cast<double>(fsStat->GetIno())) },
161 { ATIME_NS_SETTER, ani_double(static_cast<double>(fsStat->GetAtimeNs())) },
162 { MTIME_NS_SETTER, ani_double(static_cast<double>(fsStat->GetMtimeNs())) },
163 { CTIME_NS_SETTER, ani_double(static_cast<double>(fsStat->GetCtimeNs())) },
164 };
165 for (auto iter : bigIntProperties) {
166 auto key = iter.first.data();
167 auto value = iter.second;
168 ret = SetBigIntProperty(env, cls, statObject, key, value);
169 if (ret != ANI_OK) {
170 HILOGE("Object_CallMethod_Void Fail %{private}s, err: %{private}d", key, ret);
171 return ret;
172 }
173 }
174
175 #if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM)
176 auto key = LOCATION_SETTER.c_str();
177 if ((ret = SetEnumLocation(env, cls, statObject, key, static_cast<Location>(fsStat->GetLocation()))) != ANI_OK) {
178 HILOGE("Object_CallMethod_Void Fail %{private}s, err: %{private}d", key, ret);
179 return ret;
180 }
181 #endif
182
183 return ANI_OK;
184 }
185
Wrap(ani_env * env,FsStat * fsStat)186 ani_object StatWrapper::Wrap(ani_env *env, FsStat *fsStat)
187 {
188 if (fsStat == nullptr) {
189 HILOGE("FsStat pointer is null!");
190 return nullptr;
191 }
192 auto classDesc = FS::StatInner::classDesc.c_str();
193 ani_object statObject = {};
194 ani_class cls;
195 ani_status ret;
196
197 if ((ret = env->FindClass(classDesc, &cls)) != ANI_OK) {
198 HILOGE("Not found %{private}s, err: %{private}d", classDesc, ret);
199 return nullptr;
200 }
201
202 auto ctorDesc = FS::StatInner::ctorDesc.c_str();
203 auto ctorSig = FS::StatInner::ctorSig.c_str();
204 ani_method ctor;
205 if (ANI_OK != env->Class_FindMethod(cls, ctorDesc, ctorSig, &ctor)) {
206 HILOGE("Not found ctor, err: %{private}d", ret);
207 return nullptr;
208 }
209
210 if ((ret = env->Object_New(cls, ctor, &statObject, reinterpret_cast<ani_long>(fsStat))) != ANI_OK) {
211 HILOGE("New StatInner Fail, err: %{private}d", ret);
212 return nullptr;
213 }
214
215 if ((ret = SetProperties(env, cls, statObject, fsStat)) != ANI_OK) {
216 HILOGE("SetProperties Fail, err: %{private}d", ret);
217 return nullptr;
218 }
219
220 return statObject;
221 }
222
Unwrap(ani_env * env,ani_object object)223 FsStat *StatWrapper::Unwrap(ani_env *env, ani_object object)
224 {
225 ani_long fsStat;
226 auto ret = env->Object_GetFieldByName_Long(object, "nativeStat", &fsStat);
227 if (ret != ANI_OK) {
228 HILOGE("Unwrap fsStat err: %{private}d", ret);
229 return nullptr;
230 }
231 return reinterpret_cast<FsStat *>(fsStat);
232 }
233 } // namespace ANI
234 } // namespace ModuleFileIO
235 } // namespace FileManagement
236 } // namespace OHOS
237