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 "log_print.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) {
77 PRE_CHECK_RETURN_VOID_SET(argc == 1, std::make_shared<ParamNumError>("1 or 2"));
78 PRE_CHECK_RETURN_VOID(ParseString(env, argv[0], context) == OK);
79 };
80 auto exec = [context]() -> int {
81 int errCode = E_OK;
82 OHOS::NativePreferences::PreferencesHelper::GetPreferences(context->path, errCode);
83 LOG_DEBUG("GetPreferences return %{public}d", errCode);
84 return errCode;
85 };
86 auto output = [context](napi_env env, napi_value &result) {
87 napi_value path = nullptr;
88 napi_create_string_utf8(env, context->path.c_str(), NAPI_AUTO_LENGTH, &path);
89 auto ret = StorageProxy::NewInstance(env, path, &result);
90 PRE_CHECK_RETURN_VOID_SET(ret == napi_ok, std::make_shared<InnerError>(E_ERROR));
91 LOG_DEBUG("GetPreferences end.");
92 };
93 context->SetAction(env, info, input, exec, output);
94
95 PRE_CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK);
96 return AsyncCall::Call(env, context);
97 }
98
GetInputPath(napi_env env,napi_callback_info info,std::string & pathString)99 napi_status GetInputPath(napi_env env, napi_callback_info info, std::string &pathString)
100 {
101 size_t argc = 1;
102 napi_value args[1] = { 0 };
103 napi_status ret = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
104 if (ret != napi_ok) {
105 return ret;
106 }
107
108 napi_valuetype valueType;
109 ret = napi_typeof(env, args[0], &valueType);
110 if (ret != napi_ok || valueType != napi_string) {
111 return napi_invalid_arg;
112 }
113
114 char *path = new (std::nothrow) char[PATH_MAX];
115 if (path == nullptr) {
116 LOG_ERROR("GetInputPath new failed, path is nullptr");
117 return napi_arraybuffer_expected;
118 }
119 size_t pathLen = 0;
120 ret = napi_get_value_string_utf8(env, args[0], path, PATH_MAX, &pathLen);
121 pathString = path;
122 delete[] path;
123 return ret;
124 }
125
DeleteStorageSync(napi_env env,napi_callback_info info)126 napi_value DeleteStorageSync(napi_env env, napi_callback_info info)
127 {
128 std::string path;
129 napi_status ret = GetInputPath(env, info, path);
130 if (ret != napi_ok) {
131 napi_throw_error(env, nullptr, "Input path error");
132 return nullptr;
133 }
134 int errCode = PreferencesHelper::DeletePreferences(path);
135 if (errCode != E_OK) {
136 LOG_ERROR("deleteStorage failed %{public}d", errCode);
137 napi_throw_error(env, std::to_string(errCode).c_str(), "deleteStorage failed");
138 }
139 LOG_DEBUG("deleteStorage end");
140
141 return nullptr;
142 }
143
DeleteStorage(napi_env env,napi_callback_info info)144 napi_value DeleteStorage(napi_env env, napi_callback_info info)
145 {
146 LOG_DEBUG("DeletePreferences start");
147 auto context = std::make_shared<HelperAysncContext>();
148 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) {
149 PRE_CHECK_RETURN_VOID_SET(argc == 1, std::make_shared<ParamNumError>("1 or 2"));
150 PRE_CHECK_RETURN_VOID(ParseString(env, argv[0], context) == OK);
151 };
152 auto exec = [context]() -> int {
153 int errCode = PreferencesHelper::DeletePreferences(context->path);
154 LOG_DEBUG("DeletePreferences execfunction return %{public}d", errCode);
155 PRE_CHECK_RETURN_ERR_SET(errCode == E_OK, std::make_shared<InnerError>(errCode));
156 return OK;
157 };
158 auto output = [context](napi_env env, napi_value &result) {
159 napi_status status = napi_get_undefined(env, &result);
160 PRE_CHECK_RETURN_VOID_SET(status == napi_ok, std::make_shared<InnerError>(E_ERROR));
161 LOG_DEBUG("DeletePreferences end.");
162 };
163 context->SetAction(env, info, input, exec, output);
164
165 PRE_CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK);
166 return AsyncCall::Call(env, context);
167 }
168
RemoveStorageFromCacheSync(napi_env env,napi_callback_info info)169 napi_value RemoveStorageFromCacheSync(napi_env env, napi_callback_info info)
170 {
171 std::string path;
172 napi_status ret = GetInputPath(env, info, path);
173 if (ret != napi_ok) {
174 napi_throw_error(env, nullptr, "Input path error");
175 return nullptr;
176 }
177
178 int errCode = PreferencesHelper::RemovePreferencesFromCache(path);
179 if (errCode != E_OK) {
180 LOG_ERROR("removeStorageFromCache failed %{public}d", errCode);
181 napi_throw_error(env, std::to_string(errCode).c_str(), "removeStorageFromCache failed");
182 }
183 LOG_DEBUG("removeStorageFromCache end");
184
185 return nullptr;
186 }
187
RemoveStorageFromCache(napi_env env,napi_callback_info info)188 napi_value RemoveStorageFromCache(napi_env env, napi_callback_info info)
189 {
190 LOG_DEBUG("RemovePreferencesFromCache start");
191 auto context = std::make_shared<HelperAysncContext>();
192 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) {
193 PRE_CHECK_RETURN_VOID_SET(argc == 1, std::make_shared<ParamNumError>("1 or 2"));
194 PRE_CHECK_RETURN_VOID(ParseString(env, argv[0], context) == OK);
195 };
196 auto exec = [context]() -> int {
197 int errCode = PreferencesHelper::RemovePreferencesFromCache(context->path);
198 LOG_DEBUG("RemovePreferencesFromCache return %{public}d", errCode);
199 return (errCode == E_OK) ? OK : ERR;
200 };
201 auto output = [context](napi_env env, napi_value &result) {
202 napi_status status = napi_get_undefined(env, &result);
203 PRE_CHECK_RETURN_VOID_SET(status == napi_ok, std::make_shared<InnerError>(E_ERROR));
204 LOG_DEBUG("RemovePreferencesFromCache end.");
205 };
206 context->SetAction(env, info, input, exec, output);
207
208 PRE_CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK);
209 return AsyncCall::Call(env, context);
210 }
211
InitPreferenceHelper(napi_env env,napi_value exports)212 napi_value InitPreferenceHelper(napi_env env, napi_value exports)
213 {
214 napi_property_descriptor properties[] = {
215 DECLARE_NAPI_FUNCTION("getStorage", GetStorage),
216 DECLARE_NAPI_FUNCTION("getStorageSync", GetStorageSync),
217 DECLARE_NAPI_FUNCTION("deleteStorage", DeleteStorage),
218 DECLARE_NAPI_FUNCTION("deleteStorageSync", DeleteStorageSync),
219 DECLARE_NAPI_FUNCTION("removeStorageFromCache", RemoveStorageFromCache),
220 DECLARE_NAPI_FUNCTION("removeStorageFromCacheSync", RemoveStorageFromCacheSync),
221 DECLARE_NAPI_PROPERTY("MAX_KEY_LENGTH", JSUtils::Convert2JSValue(env, Preferences::MAX_KEY_LENGTH)),
222 DECLARE_NAPI_PROPERTY("MAX_VALUE_LENGTH", JSUtils::Convert2JSValue(env, Preferences::MAX_VALUE_LENGTH)),
223 };
224 NAPI_CALL(env, napi_define_properties(env, exports, sizeof(properties) / sizeof(*properties), properties));
225 return exports;
226 }
227 } // namespace StorageJsKit
228 } // namespace OHOS
229