1 /*
2 * Copyright (c) 2021 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 #include "napi_storage_helper.h"
16
17 #include <linux/limits.h>
18
19 #include <string>
20
21 #include "js_logger.h"
22 #include "js_utils.h"
23 #include "napi_async_call.h"
24 #include "napi_storage.h"
25 #include "preferences.h"
26 #include "preferences_errno.h"
27 #include "securec.h"
28
29 using namespace OHOS::NativePreferences;
30 using namespace OHOS::PreferencesJsKit;
31
32 namespace OHOS {
33 namespace StorageJsKit {
34 struct HelperAysncContext : public BaseContext {
35 std::string path;
HelperAysncContextOHOS::StorageJsKit::HelperAysncContext36 HelperAysncContext()
37 {
38 }
~HelperAysncContextOHOS::StorageJsKit::HelperAysncContext39 virtual ~HelperAysncContext(){};
40 };
41
GetStorageSync(napi_env env,napi_callback_info info)42 napi_value GetStorageSync(napi_env env, napi_callback_info info)
43 {
44 size_t argc = 1;
45 napi_value args[1] = { 0 };
46 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
47 LOG_DEBUG("getPreferences %{public}zu", argc);
48 napi_value instance = nullptr;
49 NAPI_CALL(env, StorageProxy::NewInstance(env, args[0], &instance));
50 LOG_DEBUG("getPreferences end");
51 return instance;
52 }
53
ParseString(const napi_env & env,const napi_value & value,std::shared_ptr<HelperAysncContext> asyncContext)54 int ParseString(const napi_env &env, const napi_value &value, std::shared_ptr<HelperAysncContext> asyncContext)
55 {
56 if (asyncContext == nullptr) {
57 LOG_WARN("error input");
58 return ERR;
59 }
60 char *path = new (std::nothrow) char[PATH_MAX];
61 if (path == nullptr) {
62 LOG_ERROR("ParseString new failed, path is nullptr");
63 return ERR;
64 }
65 size_t pathLen = 0;
66 napi_get_value_string_utf8(env, value, path, PATH_MAX, &pathLen);
67 asyncContext->path = path;
68 delete[] path;
69 return OK;
70 }
71
GetStorage(napi_env env,napi_callback_info info)72 napi_value GetStorage(napi_env env, napi_callback_info info)
73 {
74 LOG_DEBUG("GetStorage start");
75 auto context = std::make_shared<HelperAysncContext>();
76 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> int {
77 std::shared_ptr<Error> paramNumError = std::make_shared<ParamNumError>("1 or 2");
78 PRE_CHECK_RETURN_CALL_RESULT(argc == 1 || argc == 2, context->SetError(paramNumError));
79 PRE_ASYNC_PARAM_CHECK_FUNCTION(ParseString(env, argv[0], context));
80 return OK;
81 };
82 auto exec = [context]() -> int {
83 int errCode = E_OK;
84 OHOS::NativePreferences::PreferencesHelper::GetPreferences(context->path, errCode);
85 LOG_DEBUG("GetPreferences return %{public}d", errCode);
86 return errCode;
87 };
88 auto output = [context](napi_env env, napi_value &result) -> int {
89 napi_value path = nullptr;
90 napi_create_string_utf8(env, context->path.c_str(), NAPI_AUTO_LENGTH, &path);
91 auto ret = StorageProxy::NewInstance(env, path, &result);
92 LOG_DEBUG("GetPreferences end.");
93 return (ret == napi_ok) ? OK : ERR;
94 };
95 context->SetAction(env, info, input, exec, output);
96
97 PRE_CHECK_RETURN_NULLPTR(context, context->error == nullptr || context->error->GetCode() == OK);
98 return AsyncCall::Call(env, context);
99 }
100
GetInputPath(napi_env env,napi_callback_info info,std::string & pathString)101 napi_status GetInputPath(napi_env env, napi_callback_info info, std::string &pathString)
102 {
103 size_t argc = 1;
104 napi_value args[1] = { 0 };
105 napi_status ret = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
106 if (ret != napi_ok) {
107 return ret;
108 }
109
110 napi_valuetype valueType;
111 ret = napi_typeof(env, args[0], &valueType);
112 if (ret != napi_ok || valueType != napi_string) {
113 return napi_invalid_arg;
114 }
115
116 char *path = new (std::nothrow) char[PATH_MAX];
117 if (path == nullptr) {
118 LOG_ERROR("GetInputPath new failed, path is nullptr");
119 return napi_arraybuffer_expected;
120 }
121 size_t pathLen = 0;
122 ret = napi_get_value_string_utf8(env, args[0], path, PATH_MAX, &pathLen);
123 pathString = path;
124 delete[] path;
125 return ret;
126 }
127
DeleteStorageSync(napi_env env,napi_callback_info info)128 napi_value DeleteStorageSync(napi_env env, napi_callback_info info)
129 {
130 std::string path;
131 napi_status ret = GetInputPath(env, info, path);
132 if (ret != napi_ok) {
133 napi_throw_error(env, nullptr, "Input path error");
134 return nullptr;
135 }
136 int errCode = PreferencesHelper::DeletePreferences(path);
137 if (errCode != E_OK) {
138 LOG_ERROR("deleteStorage failed %{public}d", errCode);
139 napi_throw_error(env, std::to_string(errCode).c_str(), "deleteStorage failed");
140 }
141 LOG_DEBUG("deleteStorage end");
142
143 return nullptr;
144 }
145
DeleteStorage(napi_env env,napi_callback_info info)146 napi_value DeleteStorage(napi_env env, napi_callback_info info)
147 {
148 LOG_DEBUG("DeletePreferences start");
149 auto context = std::make_shared<HelperAysncContext>();
150 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> int {
151 std::shared_ptr<Error> paramNumError = std::make_shared<ParamNumError>("1 or 2");
152 PRE_CHECK_RETURN_CALL_RESULT(argc == 1 || argc == 2, context->SetError(paramNumError));
153 PRE_ASYNC_PARAM_CHECK_FUNCTION(ParseString(env, argv[0], context));
154 return OK;
155 };
156 auto exec = [context]() -> int {
157 int errCode = PreferencesHelper::DeletePreferences(context->path);
158 LOG_DEBUG("DeletePreferences execfunction return %{public}d", errCode);
159 std::shared_ptr<Error> deleteError = std::make_shared<DeleteError>();
160 PRE_CHECK_RETURN_CALL_RESULT(errCode == E_OK, context->SetError(deleteError));
161
162 return (errCode == E_OK) ? OK : ERR;
163 };
164 auto output = [context](napi_env env, napi_value &result) -> int {
165 napi_status status = napi_get_undefined(env, &result);
166 LOG_DEBUG("DeletePreferences end.");
167 return (status == napi_ok) ? OK : ERR;
168 };
169 context->SetAction(env, info, input, exec, output);
170
171 PRE_CHECK_RETURN_NULLPTR(context, context->error == nullptr || context->error->GetCode() == OK);
172 return AsyncCall::Call(env, context);
173 }
174
RemoveStorageFromCacheSync(napi_env env,napi_callback_info info)175 napi_value RemoveStorageFromCacheSync(napi_env env, napi_callback_info info)
176 {
177 std::string path;
178 napi_status ret = GetInputPath(env, info, path);
179 if (ret != napi_ok) {
180 napi_throw_error(env, nullptr, "Input path error");
181 return nullptr;
182 }
183
184 int errCode = PreferencesHelper::RemovePreferencesFromCache(path);
185 if (errCode != E_OK) {
186 LOG_ERROR("removeStorageFromCache failed %{public}d", errCode);
187 napi_throw_error(env, std::to_string(errCode).c_str(), "removeStorageFromCache failed");
188 }
189 LOG_DEBUG("removeStorageFromCache end");
190
191 return nullptr;
192 }
193
RemoveStorageFromCache(napi_env env,napi_callback_info info)194 napi_value RemoveStorageFromCache(napi_env env, napi_callback_info info)
195 {
196 LOG_DEBUG("RemovePreferencesFromCache start");
197 auto context = std::make_shared<HelperAysncContext>();
198 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> int {
199 std::shared_ptr<Error> paramNumError = std::make_shared<ParamNumError>("1 or 2");
200 PRE_CHECK_RETURN_CALL_RESULT(argc == 1 || argc == 2, context->SetError(paramNumError));
201 PRE_ASYNC_PARAM_CHECK_FUNCTION(ParseString(env, argv[0], context));
202 return OK;
203 };
204 auto exec = [context]() -> int {
205 int errCode = PreferencesHelper::RemovePreferencesFromCache(context->path);
206 LOG_DEBUG("RemovePreferencesFromCache return %{public}d", errCode);
207 return (errCode == E_OK) ? OK : ERR;
208 };
209 auto output = [context](napi_env env, napi_value &result) -> int {
210 napi_status status = napi_get_undefined(env, &result);
211 LOG_DEBUG("RemovePreferencesFromCache end.");
212 return (status == napi_ok) ? OK : ERR;
213 };
214 context->SetAction(env, info, input, exec, output);
215
216 PRE_CHECK_RETURN_NULLPTR(context, context->error == nullptr || context->error->GetCode() == OK);
217 return AsyncCall::Call(env, context);
218 }
219
InitPreferenceHelper(napi_env env,napi_value exports)220 napi_value InitPreferenceHelper(napi_env env, napi_value exports)
221 {
222 napi_property_descriptor properties[] = {
223 DECLARE_NAPI_FUNCTION("getStorage", GetStorage),
224 DECLARE_NAPI_FUNCTION("getStorageSync", GetStorageSync),
225 DECLARE_NAPI_FUNCTION("deleteStorage", DeleteStorage),
226 DECLARE_NAPI_FUNCTION("deleteStorageSync", DeleteStorageSync),
227 DECLARE_NAPI_FUNCTION("removeStorageFromCache", RemoveStorageFromCache),
228 DECLARE_NAPI_FUNCTION("removeStorageFromCacheSync", RemoveStorageFromCacheSync),
229 DECLARE_NAPI_PROPERTY("MAX_KEY_LENGTH", JSUtils::Convert2JSValue(env, Preferences::MAX_KEY_LENGTH)),
230 DECLARE_NAPI_PROPERTY("MAX_VALUE_LENGTH", JSUtils::Convert2JSValue(env, Preferences::MAX_VALUE_LENGTH)),
231 };
232 NAPI_CALL(env, napi_define_properties(env, exports, sizeof(properties) / sizeof(*properties), properties));
233 return exports;
234 }
235 } // namespace StorageJsKit
236 } // namespace OHOS
237