• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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