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