10e98b08fSopenharmony_ci/* 20e98b08fSopenharmony_ci * Copyright (c) 2020 Huawei Device Co., Ltd. 30e98b08fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 40e98b08fSopenharmony_ci * you may not use this file except in compliance with the License. 50e98b08fSopenharmony_ci * You may obtain a copy of the License at 60e98b08fSopenharmony_ci * 70e98b08fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 80e98b08fSopenharmony_ci * 90e98b08fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 100e98b08fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 110e98b08fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 120e98b08fSopenharmony_ci * See the License for the specific language governing permissions and 130e98b08fSopenharmony_ci * limitations under the License. 140e98b08fSopenharmony_ci */ 150e98b08fSopenharmony_ci 160e98b08fSopenharmony_ci#include "nativeapi_kv.h" 170e98b08fSopenharmony_ci#include <securec.h> 180e98b08fSopenharmony_ci#include <new> 190e98b08fSopenharmony_ci#include "ability_env.h" 200e98b08fSopenharmony_ci#include "js_async_work.h" 210e98b08fSopenharmony_ci#include "nativeapi_common.h" 220e98b08fSopenharmony_ci#include "nativeapi_config.h" 230e98b08fSopenharmony_ci#include "nativeapi_kv_impl.h" 240e98b08fSopenharmony_ci 250e98b08fSopenharmony_cinamespace OHOS { 260e98b08fSopenharmony_cinamespace ACELite { 270e98b08fSopenharmony_cinamespace { 280e98b08fSopenharmony_cichar g_kvFullPath[FILE_NAME_MAX_LEN + 1] = {0}; 290e98b08fSopenharmony_ci 300e98b08fSopenharmony_cibool IsValidKey(const char* key) 310e98b08fSopenharmony_ci{ 320e98b08fSopenharmony_ci if (key == nullptr) { 330e98b08fSopenharmony_ci return false; 340e98b08fSopenharmony_ci } 350e98b08fSopenharmony_ci size_t keyLen = strnlen(key, KEY_MAX_LEN + 1); 360e98b08fSopenharmony_ci if ((keyLen == 0) || (keyLen > KEY_MAX_LEN)) { 370e98b08fSopenharmony_ci return false; 380e98b08fSopenharmony_ci } 390e98b08fSopenharmony_ci if (strpbrk(key, "/\\\"*+,:;<=>\?[]|\x7F")) { 400e98b08fSopenharmony_ci return false; 410e98b08fSopenharmony_ci } 420e98b08fSopenharmony_ci return true; 430e98b08fSopenharmony_ci} 440e98b08fSopenharmony_ci 450e98b08fSopenharmony_ciint GetFullPath(const char* dataPath, const char* key) 460e98b08fSopenharmony_ci{ 470e98b08fSopenharmony_ci if (!IsValidKey(key) || (dataPath == nullptr)) { 480e98b08fSopenharmony_ci return ERROR_CODE_PARAM; 490e98b08fSopenharmony_ci } 500e98b08fSopenharmony_ci if (memset_s(g_kvFullPath, sizeof(g_kvFullPath), 0x0, sizeof(g_kvFullPath)) != EOK) { 510e98b08fSopenharmony_ci return ERROR_CODE_GENERAL; 520e98b08fSopenharmony_ci } 530e98b08fSopenharmony_ci if (sprintf_s(g_kvFullPath, sizeof(g_kvFullPath), "%s/%s/%s", dataPath, DEFAULT_FOLDER_PATH, key) < 0) { 540e98b08fSopenharmony_ci return ERROR_CODE_GENERAL; 550e98b08fSopenharmony_ci } 560e98b08fSopenharmony_ci return NATIVE_SUCCESS; 570e98b08fSopenharmony_ci} 580e98b08fSopenharmony_ci 590e98b08fSopenharmony_civoid GetDefault(const JSIValue thisVal, const JSIValue args) 600e98b08fSopenharmony_ci{ 610e98b08fSopenharmony_ci char* defaultValue = JSI::GetStringProperty(args, DEFAULT); 620e98b08fSopenharmony_ci JSIValue result; 630e98b08fSopenharmony_ci if (defaultValue == nullptr) { 640e98b08fSopenharmony_ci result = JSI::CreateString(""); 650e98b08fSopenharmony_ci } else { 660e98b08fSopenharmony_ci result = JSI::CreateString(defaultValue); 670e98b08fSopenharmony_ci } 680e98b08fSopenharmony_ci JSI::ReleaseString(defaultValue); 690e98b08fSopenharmony_ci NativeapiCommon::SuccessCallBack(thisVal, args, result); 700e98b08fSopenharmony_ci JSI::ReleaseValue(result); 710e98b08fSopenharmony_ci} 720e98b08fSopenharmony_ci 730e98b08fSopenharmony_ciint GetValueInner(const char* dataPath, const char* key, char* value) 740e98b08fSopenharmony_ci{ 750e98b08fSopenharmony_ci int ret = GetFullPath(dataPath, key); 760e98b08fSopenharmony_ci if (ret != NATIVE_SUCCESS) { 770e98b08fSopenharmony_ci return ret; 780e98b08fSopenharmony_ci } 790e98b08fSopenharmony_ci return GetValue(g_kvFullPath, value); 800e98b08fSopenharmony_ci} 810e98b08fSopenharmony_ci 820e98b08fSopenharmony_ciint SetValueInner(const char* dataPath, const char* key, const char* value) 830e98b08fSopenharmony_ci{ 840e98b08fSopenharmony_ci int ret = GetFullPath(dataPath, key); 850e98b08fSopenharmony_ci if (ret != NATIVE_SUCCESS) { 860e98b08fSopenharmony_ci return ret; 870e98b08fSopenharmony_ci } 880e98b08fSopenharmony_ci return SetValue(g_kvFullPath, value); 890e98b08fSopenharmony_ci} 900e98b08fSopenharmony_ci 910e98b08fSopenharmony_ciint DeleteValueInner(const char* dataPath, const char* key) 920e98b08fSopenharmony_ci{ 930e98b08fSopenharmony_ci int ret = GetFullPath(dataPath, key); 940e98b08fSopenharmony_ci if (ret != NATIVE_SUCCESS) { 950e98b08fSopenharmony_ci return ret; 960e98b08fSopenharmony_ci } 970e98b08fSopenharmony_ci return DeleteValue(g_kvFullPath); 980e98b08fSopenharmony_ci} 990e98b08fSopenharmony_ci 1000e98b08fSopenharmony_ciJSIValue ExecuteAsyncWork(const JSIValue thisVal, const JSIValue* args, 1010e98b08fSopenharmony_ci uint8_t argsNum, AsyncWorkHandler ExecuteFunc, bool flag) 1020e98b08fSopenharmony_ci{ 1030e98b08fSopenharmony_ci JSIValue undefValue = JSI::CreateUndefined(); 1040e98b08fSopenharmony_ci if (!NativeapiCommon::IsValidJSIValue(args, argsNum)) { 1050e98b08fSopenharmony_ci return undefValue; 1060e98b08fSopenharmony_ci } 1070e98b08fSopenharmony_ci FuncParams* params = new(std::nothrow) FuncParams(); 1080e98b08fSopenharmony_ci if (params == nullptr) { 1090e98b08fSopenharmony_ci return undefValue; 1100e98b08fSopenharmony_ci } 1110e98b08fSopenharmony_ci params->thisVal = JSI::AcquireValue(thisVal); 1120e98b08fSopenharmony_ci params->args = JSI::AcquireValue(args[0]); 1130e98b08fSopenharmony_ci params->flag = flag; 1140e98b08fSopenharmony_ci JsAsyncWork::DispatchAsyncWork(ExecuteFunc, reinterpret_cast<void *>(params)); 1150e98b08fSopenharmony_ci return undefValue; 1160e98b08fSopenharmony_ci} 1170e98b08fSopenharmony_ci 1180e98b08fSopenharmony_civoid ExecuteGet(void* data) 1190e98b08fSopenharmony_ci{ 1200e98b08fSopenharmony_ci FuncParams* params = reinterpret_cast<FuncParams *>(data); 1210e98b08fSopenharmony_ci if (params == nullptr) { 1220e98b08fSopenharmony_ci return; 1230e98b08fSopenharmony_ci } 1240e98b08fSopenharmony_ci JSIValue args = params->args; 1250e98b08fSopenharmony_ci JSIValue thisVal = params->thisVal; 1260e98b08fSopenharmony_ci char* key = JSI::GetStringProperty(args, KV_KEY); 1270e98b08fSopenharmony_ci const char* dataPath = GetDataPath(); 1280e98b08fSopenharmony_ci JSIValue result = JSI::CreateUndefined(); 1290e98b08fSopenharmony_ci int ret = ERROR_CODE_GENERAL; 1300e98b08fSopenharmony_ci char* value = reinterpret_cast<char *>(malloc(VALUE_MAX_LEN + 1)); 1310e98b08fSopenharmony_ci if (value == nullptr) { 1320e98b08fSopenharmony_ci NativeapiCommon::FailCallBack(thisVal, args, ret); 1330e98b08fSopenharmony_ci goto EXIT; 1340e98b08fSopenharmony_ci } 1350e98b08fSopenharmony_ci ret = InitKv(dataPath); 1360e98b08fSopenharmony_ci if (ret != NATIVE_SUCCESS) { 1370e98b08fSopenharmony_ci NativeapiCommon::FailCallBack(thisVal, args, ret); 1380e98b08fSopenharmony_ci goto EXIT; 1390e98b08fSopenharmony_ci } 1400e98b08fSopenharmony_ci ret = GetValueInner(dataPath, key, value); 1410e98b08fSopenharmony_ci if (ret == ERROR_FR_NO_FILE) { 1420e98b08fSopenharmony_ci GetDefault(thisVal, args); 1430e98b08fSopenharmony_ci goto EXIT; 1440e98b08fSopenharmony_ci } 1450e98b08fSopenharmony_ci if (ret != NATIVE_SUCCESS) { 1460e98b08fSopenharmony_ci NativeapiCommon::FailCallBack(thisVal, args, ret); 1470e98b08fSopenharmony_ci goto EXIT; 1480e98b08fSopenharmony_ci } 1490e98b08fSopenharmony_ci result = JSI::CreateString(value); 1500e98b08fSopenharmony_ci NativeapiCommon::SuccessCallBack(thisVal, args, result); 1510e98b08fSopenharmony_ciEXIT: 1520e98b08fSopenharmony_ci free(value); 1530e98b08fSopenharmony_ci JSI::ReleaseString(key); 1540e98b08fSopenharmony_ci JSI::ReleaseValueList(args, thisVal, result, ARGS_END); 1550e98b08fSopenharmony_ci delete params; 1560e98b08fSopenharmony_ci} 1570e98b08fSopenharmony_ci 1580e98b08fSopenharmony_civoid ExecuteSet(void* data) 1590e98b08fSopenharmony_ci{ 1600e98b08fSopenharmony_ci FuncParams* params = reinterpret_cast<FuncParams *>(data); 1610e98b08fSopenharmony_ci if (params == nullptr) { 1620e98b08fSopenharmony_ci return; 1630e98b08fSopenharmony_ci } 1640e98b08fSopenharmony_ci JSIValue args = params->args; 1650e98b08fSopenharmony_ci JSIValue thisVal = params->thisVal; 1660e98b08fSopenharmony_ci char* key = JSI::GetStringProperty(args, KV_KEY); 1670e98b08fSopenharmony_ci char* value = JSI::GetStringProperty(args, KV_VALUE); 1680e98b08fSopenharmony_ci const char* dataPath = GetDataPath(); 1690e98b08fSopenharmony_ci int ret = InitKv(dataPath); 1700e98b08fSopenharmony_ci if (ret != NATIVE_SUCCESS) { 1710e98b08fSopenharmony_ci NativeapiCommon::FailCallBack(thisVal, args, ret); 1720e98b08fSopenharmony_ci goto EXIT; 1730e98b08fSopenharmony_ci } 1740e98b08fSopenharmony_ci if ((key == nullptr) || !strlen(key)) { 1750e98b08fSopenharmony_ci NativeapiCommon::FailCallBack(thisVal, args, ERROR_CODE_PARAM); 1760e98b08fSopenharmony_ci goto EXIT; 1770e98b08fSopenharmony_ci } 1780e98b08fSopenharmony_ci if ((value == nullptr) || !strlen(value)) { 1790e98b08fSopenharmony_ci DeleteValueInner(dataPath, key); 1800e98b08fSopenharmony_ci NativeapiCommon::SuccessCallBack(thisVal, args, JSI::CreateUndefined()); 1810e98b08fSopenharmony_ci goto EXIT; 1820e98b08fSopenharmony_ci } 1830e98b08fSopenharmony_ci ret = SetValueInner(dataPath, key, value); 1840e98b08fSopenharmony_ci if (ret != NATIVE_SUCCESS) { 1850e98b08fSopenharmony_ci NativeapiCommon::FailCallBack(thisVal, args, ret); 1860e98b08fSopenharmony_ci goto EXIT; 1870e98b08fSopenharmony_ci } 1880e98b08fSopenharmony_ci NativeapiCommon::SuccessCallBack(thisVal, args, JSI::CreateUndefined()); 1890e98b08fSopenharmony_ciEXIT: 1900e98b08fSopenharmony_ci JSI::ReleaseString(key); 1910e98b08fSopenharmony_ci JSI::ReleaseString(value); 1920e98b08fSopenharmony_ci JSI::ReleaseValueList(args, thisVal, ARGS_END); 1930e98b08fSopenharmony_ci delete params; 1940e98b08fSopenharmony_ci} 1950e98b08fSopenharmony_ci 1960e98b08fSopenharmony_civoid ExecuteDelete(void* data) 1970e98b08fSopenharmony_ci{ 1980e98b08fSopenharmony_ci FuncParams* params = reinterpret_cast<FuncParams *>(data); 1990e98b08fSopenharmony_ci if (params == nullptr) { 2000e98b08fSopenharmony_ci return; 2010e98b08fSopenharmony_ci } 2020e98b08fSopenharmony_ci JSIValue args = params->args; 2030e98b08fSopenharmony_ci JSIValue thisVal = params->thisVal; 2040e98b08fSopenharmony_ci const char* dataPath = GetDataPath(); 2050e98b08fSopenharmony_ci int ret = InitKv(dataPath); 2060e98b08fSopenharmony_ci if (ret != NATIVE_SUCCESS) { 2070e98b08fSopenharmony_ci NativeapiCommon::FailCallBack(thisVal, args, ret); 2080e98b08fSopenharmony_ci JSI::ReleaseValueList(args, thisVal, ARGS_END); 2090e98b08fSopenharmony_ci delete params; 2100e98b08fSopenharmony_ci return; 2110e98b08fSopenharmony_ci } 2120e98b08fSopenharmony_ci char* key = JSI::GetStringProperty(args, KV_KEY); 2130e98b08fSopenharmony_ci ret = DeleteValueInner(dataPath, key); 2140e98b08fSopenharmony_ci JSI::ReleaseString(key); 2150e98b08fSopenharmony_ci if ((ret < 0) && (ret != ERROR_FR_NO_FILE)) { 2160e98b08fSopenharmony_ci NativeapiCommon::FailCallBack(thisVal, args, ret); 2170e98b08fSopenharmony_ci JSI::ReleaseValueList(args, thisVal, ARGS_END); 2180e98b08fSopenharmony_ci delete params; 2190e98b08fSopenharmony_ci return; 2200e98b08fSopenharmony_ci } 2210e98b08fSopenharmony_ci NativeapiCommon::SuccessCallBack(thisVal, args, JSI::CreateUndefined()); 2220e98b08fSopenharmony_ci JSI::ReleaseValueList(args, thisVal, ARGS_END); 2230e98b08fSopenharmony_ci delete params; 2240e98b08fSopenharmony_ci} 2250e98b08fSopenharmony_ci 2260e98b08fSopenharmony_civoid ExecuteClear(void* data) 2270e98b08fSopenharmony_ci{ 2280e98b08fSopenharmony_ci FuncParams* params = reinterpret_cast<FuncParams *>(data); 2290e98b08fSopenharmony_ci if (params == nullptr) { 2300e98b08fSopenharmony_ci return; 2310e98b08fSopenharmony_ci } 2320e98b08fSopenharmony_ci JSIValue args = params->args; 2330e98b08fSopenharmony_ci JSIValue thisVal = params->thisVal; 2340e98b08fSopenharmony_ci const char* dataPath = GetDataPath(); 2350e98b08fSopenharmony_ci int ret = InitKv(dataPath); 2360e98b08fSopenharmony_ci if (ret != NATIVE_SUCCESS) { 2370e98b08fSopenharmony_ci NativeapiCommon::FailCallBack(thisVal, args, ret); 2380e98b08fSopenharmony_ci JSI::ReleaseValueList(args, thisVal, ARGS_END); 2390e98b08fSopenharmony_ci delete params; 2400e98b08fSopenharmony_ci return; 2410e98b08fSopenharmony_ci } 2420e98b08fSopenharmony_ci ret = ClearKVStore(dataPath); 2430e98b08fSopenharmony_ci if (ret != NATIVE_SUCCESS) { 2440e98b08fSopenharmony_ci NativeapiCommon::FailCallBack(thisVal, args, ret); 2450e98b08fSopenharmony_ci JSI::ReleaseValueList(args, thisVal, ARGS_END); 2460e98b08fSopenharmony_ci delete params; 2470e98b08fSopenharmony_ci return; 2480e98b08fSopenharmony_ci } 2490e98b08fSopenharmony_ci NativeapiCommon::SuccessCallBack(thisVal, args, JSI::CreateUndefined()); 2500e98b08fSopenharmony_ci JSI::ReleaseValueList(args, thisVal, ARGS_END); 2510e98b08fSopenharmony_ci delete params; 2520e98b08fSopenharmony_ci} 2530e98b08fSopenharmony_ci} 2540e98b08fSopenharmony_ci 2550e98b08fSopenharmony_civoid InitNativeApiKv(JSIValue exports) 2560e98b08fSopenharmony_ci{ 2570e98b08fSopenharmony_ci JSI::SetModuleAPI(exports, "get", NativeapiKv::Get); 2580e98b08fSopenharmony_ci JSI::SetModuleAPI(exports, "set", NativeapiKv::Set); 2590e98b08fSopenharmony_ci JSI::SetModuleAPI(exports, "delete", NativeapiKv::Delete); 2600e98b08fSopenharmony_ci JSI::SetModuleAPI(exports, "clear", NativeapiKv::Clear); 2610e98b08fSopenharmony_ci} 2620e98b08fSopenharmony_ci 2630e98b08fSopenharmony_ciJSIValue NativeapiKv::Get(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum) 2640e98b08fSopenharmony_ci{ 2650e98b08fSopenharmony_ci return ExecuteAsyncWork(thisVal, args, argsNum, ExecuteGet, false); 2660e98b08fSopenharmony_ci} 2670e98b08fSopenharmony_ci 2680e98b08fSopenharmony_ciJSIValue NativeapiKv::Set(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum) 2690e98b08fSopenharmony_ci{ 2700e98b08fSopenharmony_ci return ExecuteAsyncWork(thisVal, args, argsNum, ExecuteSet, false); 2710e98b08fSopenharmony_ci} 2720e98b08fSopenharmony_ci 2730e98b08fSopenharmony_ciJSIValue NativeapiKv::Delete(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum) 2740e98b08fSopenharmony_ci{ 2750e98b08fSopenharmony_ci return ExecuteAsyncWork(thisVal, args, argsNum, ExecuteDelete, false); 2760e98b08fSopenharmony_ci} 2770e98b08fSopenharmony_ci 2780e98b08fSopenharmony_ciJSIValue NativeapiKv::Clear(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum) 2790e98b08fSopenharmony_ci{ 2800e98b08fSopenharmony_ci JSIValue undefValue = JSI::CreateUndefined(); 2810e98b08fSopenharmony_ci FuncParams* params = new(std::nothrow) FuncParams(); 2820e98b08fSopenharmony_ci if (params == nullptr) { 2830e98b08fSopenharmony_ci return undefValue; 2840e98b08fSopenharmony_ci } 2850e98b08fSopenharmony_ci params->thisVal = JSI::AcquireValue(thisVal); 2860e98b08fSopenharmony_ci if (NativeapiCommon::IsValidJSIValue(args, argsNum)) { 2870e98b08fSopenharmony_ci params->args = JSI::AcquireValue(args[0]); 2880e98b08fSopenharmony_ci } 2890e98b08fSopenharmony_ci JsAsyncWork::DispatchAsyncWork(reinterpret_cast<AsyncWorkHandler>(ExecuteClear), reinterpret_cast<void *>(params)); 2900e98b08fSopenharmony_ci return undefValue; 2910e98b08fSopenharmony_ci} 2920e98b08fSopenharmony_ci} // ACELite 2930e98b08fSopenharmony_ci} // OHOS 294