• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020 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 "nativeapi_kv.h"
17 #include <securec.h>
18 #include "ability_env.h"
19 #include "js_async_work.h"
20 #include "nativeapi_common.h"
21 #include "nativeapi_config.h"
22 #include "nativeapi_kv_impl.h"
23 
24 namespace OHOS {
25 namespace ACELite {
26 namespace {
27 char g_kvFullPath[FILE_NAME_MAX_LEN + 1] = {0};
28 
IsValidKey(const char * key)29 bool IsValidKey(const char* key)
30 {
31     if (key == nullptr) {
32         return false;
33     }
34     size_t keyLen = strnlen(key, KEY_MAX_LEN + 1);
35     if ((keyLen == 0) || (keyLen > KEY_MAX_LEN)) {
36         return false;
37     }
38     if (strpbrk(key, "/\\\"*+,:;<=>\?[]|\x7F")) {
39         return false;
40     }
41     return true;
42 }
43 
GetFullPath(const char * dataPath,const char * key)44 int GetFullPath(const char* dataPath, const char* key)
45 {
46     if (!IsValidKey(key) || (dataPath == nullptr)) {
47         return ERROR_CODE_PARAM;
48     }
49     if (memset_s(g_kvFullPath, sizeof(g_kvFullPath), 0x0, sizeof(g_kvFullPath)) != EOK) {
50         return ERROR_CODE_GENERAL;
51     }
52     if (sprintf_s(g_kvFullPath, sizeof(g_kvFullPath), "%s/%s/%s", dataPath, DEFAULT_FOLDER_PATH, key) < 0) {
53         return ERROR_CODE_GENERAL;
54     }
55     return NATIVE_SUCCESS;
56 }
57 
GetDefault(const JSIValue thisVal,const JSIValue args)58 void GetDefault(const JSIValue thisVal, const JSIValue args)
59 {
60     char* defaultValue = JSI::GetStringProperty(args, DEFAULT);
61     JSIValue result;
62     if (defaultValue == nullptr) {
63         result = JSI::CreateString("");
64     } else {
65         result = JSI::CreateString(defaultValue);
66     }
67     JSI::ReleaseString(defaultValue);
68     NativeapiCommon::SuccessCallBack(thisVal, args, result);
69     JSI::ReleaseValue(result);
70 }
71 
GetValueInner(const char * dataPath,const char * key,char * value)72 int GetValueInner(const char* dataPath, const char* key, char* value)
73 {
74     int ret = GetFullPath(dataPath, key);
75     if (ret != NATIVE_SUCCESS) {
76         return ret;
77     }
78     return GetValue(g_kvFullPath, value);
79 }
80 
SetValueInner(const char * dataPath,const char * key,const char * value)81 int SetValueInner(const char* dataPath, const char* key, const char* value)
82 {
83     int ret = GetFullPath(dataPath, key);
84     if (ret != NATIVE_SUCCESS) {
85         return ret;
86     }
87     return SetValue(g_kvFullPath, value);
88 }
89 
DeleteValueInner(const char * dataPath,const char * key)90 int DeleteValueInner(const char* dataPath, const char* key)
91 {
92     int ret = GetFullPath(dataPath, key);
93     if (ret != NATIVE_SUCCESS) {
94         return ret;
95     }
96     return DeleteValue(g_kvFullPath);
97 }
98 
ExecuteAsyncWork(const JSIValue thisVal,const JSIValue * args,uint8_t argsNum,AsyncWorkHandler ExecuteFunc,bool flag)99 JSIValue ExecuteAsyncWork(const JSIValue thisVal, const JSIValue* args,
100     uint8_t argsNum, AsyncWorkHandler ExecuteFunc, bool flag)
101 {
102     JSIValue undefValue = JSI::CreateUndefined();
103     if (!NativeapiCommon::IsValidJSIValue(args, argsNum)) {
104         return undefValue;
105     }
106     FuncParams* params = new FuncParams();
107     if (params == nullptr) {
108         return undefValue;
109     }
110     params->thisVal = JSI::AcquireValue(thisVal);
111     params->args = JSI::AcquireValue(args[0]);
112     params->flag = flag;
113     JsAsyncWork::DispatchAsyncWork(ExecuteFunc, reinterpret_cast<void *>(params));
114     return undefValue;
115 }
116 
ExecuteGet(void * data)117 void ExecuteGet(void* data)
118 {
119     FuncParams* params = reinterpret_cast<FuncParams *>(data);
120     if (params == nullptr) {
121         return;
122     }
123     JSIValue args = params->args;
124     JSIValue thisVal = params->thisVal;
125     char* key = JSI::GetStringProperty(args, KV_KEY);
126     const char* dataPath = GetDataPath();
127     JSIValue result = JSI::CreateUndefined();
128     int ret = ERROR_CODE_GENERAL;
129     char* value = reinterpret_cast<char *>(malloc(VALUE_MAX_LEN + 1));
130     if (value == nullptr) {
131         NativeapiCommon::FailCallBack(thisVal, args, ret);
132         goto EXIT;
133     }
134     ret = InitKv(dataPath);
135     if (ret != NATIVE_SUCCESS) {
136         NativeapiCommon::FailCallBack(thisVal, args, ret);
137         goto EXIT;
138     }
139     ret = GetValueInner(dataPath, key, value);
140     if (ret == ERROR_FR_NO_FILE) {
141         GetDefault(thisVal, args);
142         goto EXIT;
143     }
144     if (ret != NATIVE_SUCCESS) {
145         NativeapiCommon::FailCallBack(thisVal, args, ret);
146         goto EXIT;
147     }
148     result = JSI::CreateString(value);
149     NativeapiCommon::SuccessCallBack(thisVal, args, result);
150 EXIT:
151     free(value);
152     JSI::ReleaseString(key);
153     JSI::ReleaseValueList(args, thisVal, result, ARGS_END);
154     delete params;
155 }
156 
ExecuteSet(void * data)157 void ExecuteSet(void* data)
158 {
159     FuncParams* params = reinterpret_cast<FuncParams *>(data);
160     if (params == nullptr) {
161         return;
162     }
163     JSIValue args = params->args;
164     JSIValue thisVal = params->thisVal;
165     char* key = JSI::GetStringProperty(args, KV_KEY);
166     char* value = JSI::GetStringProperty(args, KV_VALUE);
167     const char* dataPath = GetDataPath();
168     int ret = InitKv(dataPath);
169     if (ret != NATIVE_SUCCESS) {
170         NativeapiCommon::FailCallBack(thisVal, args, ret);
171         goto EXIT;
172     }
173     if ((key == nullptr) || !strlen(key)) {
174         NativeapiCommon::FailCallBack(thisVal, args, ERROR_CODE_PARAM);
175         goto EXIT;
176     }
177     if ((value == nullptr) || !strlen(value)) {
178         DeleteValueInner(dataPath, key);
179         NativeapiCommon::SuccessCallBack(thisVal, args, JSI::CreateUndefined());
180         goto EXIT;
181     }
182     ret = SetValueInner(dataPath, key, value);
183     if (ret != NATIVE_SUCCESS) {
184         NativeapiCommon::FailCallBack(thisVal, args, ret);
185         goto EXIT;
186     }
187     NativeapiCommon::SuccessCallBack(thisVal, args, JSI::CreateUndefined());
188 EXIT:
189     JSI::ReleaseString(key);
190     JSI::ReleaseString(value);
191     JSI::ReleaseValueList(args, thisVal, ARGS_END);
192     delete params;
193 }
194 
ExecuteDelete(void * data)195 void ExecuteDelete(void* data)
196 {
197     FuncParams* params = reinterpret_cast<FuncParams *>(data);
198     if (params == nullptr) {
199         return;
200     }
201     JSIValue args = params->args;
202     JSIValue thisVal = params->thisVal;
203     const char* dataPath = GetDataPath();
204     int ret = InitKv(dataPath);
205     if (ret != NATIVE_SUCCESS) {
206         NativeapiCommon::FailCallBack(thisVal, args, ret);
207         JSI::ReleaseValueList(args, thisVal, ARGS_END);
208         delete params;
209         return;
210     }
211     char* key = JSI::GetStringProperty(args, KV_KEY);
212     ret = DeleteValueInner(dataPath, key);
213     JSI::ReleaseString(key);
214     if ((ret < 0) && (ret != ERROR_FR_NO_FILE)) {
215         NativeapiCommon::FailCallBack(thisVal, args, ret);
216         JSI::ReleaseValueList(args, thisVal, ARGS_END);
217         delete params;
218         return;
219     }
220     NativeapiCommon::SuccessCallBack(thisVal, args, JSI::CreateUndefined());
221     JSI::ReleaseValueList(args, thisVal, ARGS_END);
222     delete params;
223 }
224 
ExecuteClear(void * data)225 void ExecuteClear(void* data)
226 {
227     FuncParams* params = reinterpret_cast<FuncParams *>(data);
228     if (params == nullptr) {
229         return;
230     }
231     JSIValue args = params->args;
232     JSIValue thisVal = params->thisVal;
233     const char* dataPath = GetDataPath();
234     int ret = InitKv(dataPath);
235     if (ret != NATIVE_SUCCESS) {
236         NativeapiCommon::FailCallBack(thisVal, args, ret);
237         JSI::ReleaseValueList(args, thisVal, ARGS_END);
238         delete params;
239         return;
240     }
241     ret = ClearKVStore(dataPath);
242     if (ret != NATIVE_SUCCESS) {
243         NativeapiCommon::FailCallBack(thisVal, args, ret);
244         JSI::ReleaseValueList(args, thisVal, ARGS_END);
245         delete params;
246         return;
247     }
248     NativeapiCommon::SuccessCallBack(thisVal, args, JSI::CreateUndefined());
249     JSI::ReleaseValueList(args, thisVal, ARGS_END);
250     delete params;
251 }
252 }
253 
InitNativeApiKv(JSIValue exports)254 void InitNativeApiKv(JSIValue exports)
255 {
256     JSI::SetModuleAPI(exports, "get", NativeapiKv::Get);
257     JSI::SetModuleAPI(exports, "set", NativeapiKv::Set);
258     JSI::SetModuleAPI(exports, "delete", NativeapiKv::Delete);
259     JSI::SetModuleAPI(exports, "clear", NativeapiKv::Clear);
260 }
261 
Get(const JSIValue thisVal,const JSIValue * args,uint8_t argsNum)262 JSIValue NativeapiKv::Get(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum)
263 {
264     return ExecuteAsyncWork(thisVal, args, argsNum, ExecuteGet, false);
265 }
266 
Set(const JSIValue thisVal,const JSIValue * args,uint8_t argsNum)267 JSIValue NativeapiKv::Set(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum)
268 {
269     return ExecuteAsyncWork(thisVal, args, argsNum, ExecuteSet, false);
270 }
271 
Delete(const JSIValue thisVal,const JSIValue * args,uint8_t argsNum)272 JSIValue NativeapiKv::Delete(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum)
273 {
274     return ExecuteAsyncWork(thisVal, args, argsNum, ExecuteDelete, false);
275 }
276 
Clear(const JSIValue thisVal,const JSIValue * args,uint8_t argsNum)277 JSIValue NativeapiKv::Clear(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum)
278 {
279     JSIValue undefValue = JSI::CreateUndefined();
280     FuncParams* params = new FuncParams();
281     if (params == nullptr) {
282         return undefValue;
283     }
284     params->thisVal = JSI::AcquireValue(thisVal);
285     if (NativeapiCommon::IsValidJSIValue(args, argsNum)) {
286         params->args = JSI::AcquireValue(args[0]);
287     }
288     JsAsyncWork::DispatchAsyncWork(reinterpret_cast<AsyncWorkHandler>(ExecuteClear), reinterpret_cast<void *>(params));
289     return undefValue;
290 }
291 } // ACELite
292 } // OHOS
293