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_fs.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_fs_impl.h"
230e98b08fSopenharmony_ci
240e98b08fSopenharmony_cinamespace OHOS {
250e98b08fSopenharmony_cinamespace ACELite {
260e98b08fSopenharmony_cinamespace {
270e98b08fSopenharmony_cichar g_uriFullPath[FILE_NAME_MAX_LEN + 1] = {0};
280e98b08fSopenharmony_ciconst unsigned int PREFIX_LEN = strlen(FILE_PREFIX);
290e98b08fSopenharmony_ci
300e98b08fSopenharmony_cibool IsValidPath(const char* path)
310e98b08fSopenharmony_ci{
320e98b08fSopenharmony_ci    if (path == nullptr) {
330e98b08fSopenharmony_ci        return false;
340e98b08fSopenharmony_ci    }
350e98b08fSopenharmony_ci
360e98b08fSopenharmony_ci    size_t pathLen = strnlen(path, URI_NAME_MAX_LEN + 1);
370e98b08fSopenharmony_ci    if (pathLen > URI_NAME_MAX_LEN) {
380e98b08fSopenharmony_ci        return false;
390e98b08fSopenharmony_ci    }
400e98b08fSopenharmony_ci    if ((pathLen < PREFIX_LEN) || (strncmp(path, FILE_PREFIX, PREFIX_LEN) != 0)) {
410e98b08fSopenharmony_ci        return false;
420e98b08fSopenharmony_ci    }
430e98b08fSopenharmony_ci    if ((strstr(path, "/./") != nullptr) || (strstr(path, "/../") != nullptr)) {
440e98b08fSopenharmony_ci        return false;
450e98b08fSopenharmony_ci    }
460e98b08fSopenharmony_ci    if (strpbrk(path + PREFIX_LEN, "\"*+,:;<=>\?[]|\x7F")) {
470e98b08fSopenharmony_ci        return false;
480e98b08fSopenharmony_ci    }
490e98b08fSopenharmony_ci    return true;
500e98b08fSopenharmony_ci}
510e98b08fSopenharmony_ci
520e98b08fSopenharmony_ciint GetFullPath(const char* uri, char* fullPath, int len)
530e98b08fSopenharmony_ci{
540e98b08fSopenharmony_ci    if (!IsValidPath(uri) || (fullPath == nullptr)) {
550e98b08fSopenharmony_ci        return ERROR_CODE_PARAM;
560e98b08fSopenharmony_ci    }
570e98b08fSopenharmony_ci    const char* dataPath = GetDataPath();
580e98b08fSopenharmony_ci    if (dataPath == nullptr) {
590e98b08fSopenharmony_ci        return ERROR_CODE_PARAM;
600e98b08fSopenharmony_ci    }
610e98b08fSopenharmony_ci    if (memset_s(fullPath, len, 0x0, len) != EOK) {
620e98b08fSopenharmony_ci        return ERROR_CODE_GENERAL;
630e98b08fSopenharmony_ci    }
640e98b08fSopenharmony_ci    if (sprintf_s(fullPath, len, "%s%s", dataPath, uri + PREFIX_LEN) < 0) {
650e98b08fSopenharmony_ci        return ERROR_CODE_GENERAL;
660e98b08fSopenharmony_ci    }
670e98b08fSopenharmony_ci    return NATIVE_SUCCESS;
680e98b08fSopenharmony_ci}
690e98b08fSopenharmony_ci
700e98b08fSopenharmony_ciJSIValue ExecuteAsyncWork(const JSIValue thisVal, const JSIValue* args,
710e98b08fSopenharmony_ci    uint8_t argsNum, AsyncWorkHandler ExecuteFunc, bool flag = false)
720e98b08fSopenharmony_ci{
730e98b08fSopenharmony_ci    JSIValue undefValue = JSI::CreateUndefined();
740e98b08fSopenharmony_ci    if (!NativeapiCommon::IsValidJSIValue(args, argsNum)) {
750e98b08fSopenharmony_ci        return undefValue;
760e98b08fSopenharmony_ci    }
770e98b08fSopenharmony_ci    FuncParams* params = new(std::nothrow) FuncParams();
780e98b08fSopenharmony_ci    if (params == nullptr) {
790e98b08fSopenharmony_ci        return undefValue;
800e98b08fSopenharmony_ci    }
810e98b08fSopenharmony_ci    params->thisVal = JSI::AcquireValue(thisVal);
820e98b08fSopenharmony_ci    params->args = JSI::AcquireValue(args[0]);
830e98b08fSopenharmony_ci    params->flag = flag;
840e98b08fSopenharmony_ci    JsAsyncWork::DispatchAsyncWork(ExecuteFunc, reinterpret_cast<void *>(params));
850e98b08fSopenharmony_ci    return undefValue;
860e98b08fSopenharmony_ci}
870e98b08fSopenharmony_ci
880e98b08fSopenharmony_civoid ExecuteCopyFile(void* data)
890e98b08fSopenharmony_ci{
900e98b08fSopenharmony_ci    FuncParams* params = reinterpret_cast<FuncParams *>(data);
910e98b08fSopenharmony_ci    if (params == nullptr) {
920e98b08fSopenharmony_ci        return;
930e98b08fSopenharmony_ci    }
940e98b08fSopenharmony_ci    JSIValue args = params->args;
950e98b08fSopenharmony_ci    JSIValue thisVal = params->thisVal;
960e98b08fSopenharmony_ci    char* src = JSI::GetStringProperty(args, FILE_SOURCE_URI);
970e98b08fSopenharmony_ci    char* dest = JSI::GetStringProperty(args, FILE_DESTINATION_URI);
980e98b08fSopenharmony_ci    char* destFullPath = nullptr;
990e98b08fSopenharmony_ci    JSIValue result = JSI::CreateUndefined();
1000e98b08fSopenharmony_ci    int ret = GetFullPath(src, g_uriFullPath, sizeof(g_uriFullPath));
1010e98b08fSopenharmony_ci    JSI::ReleaseString(src);
1020e98b08fSopenharmony_ci    if (ret != NATIVE_SUCCESS) {
1030e98b08fSopenharmony_ci        NativeapiCommon::FailCallBack(thisVal, args, ret);
1040e98b08fSopenharmony_ci        goto EXIT;
1050e98b08fSopenharmony_ci    }
1060e98b08fSopenharmony_ci    destFullPath = reinterpret_cast<char *>(malloc(FILE_NAME_MAX_LEN + 1));
1070e98b08fSopenharmony_ci    if (destFullPath == nullptr) {
1080e98b08fSopenharmony_ci        NativeapiCommon::FailCallBack(thisVal, args, ERROR_CODE_GENERAL);
1090e98b08fSopenharmony_ci        goto EXIT;
1100e98b08fSopenharmony_ci    }
1110e98b08fSopenharmony_ci    ret = GetFullPath(dest, destFullPath, FILE_NAME_MAX_LEN + 1);
1120e98b08fSopenharmony_ci    if (ret != NATIVE_SUCCESS) {
1130e98b08fSopenharmony_ci        NativeapiCommon::FailCallBack(thisVal, args, ret);
1140e98b08fSopenharmony_ci        goto EXIT;
1150e98b08fSopenharmony_ci    }
1160e98b08fSopenharmony_ci    ret = CopyFileImpl(g_uriFullPath, destFullPath);
1170e98b08fSopenharmony_ci    if (ret != NATIVE_SUCCESS) {
1180e98b08fSopenharmony_ci        NativeapiCommon::FailCallBack(thisVal, args, ret);
1190e98b08fSopenharmony_ci        goto EXIT;
1200e98b08fSopenharmony_ci    }
1210e98b08fSopenharmony_ci    if (params->flag) {
1220e98b08fSopenharmony_ci        ret = DeleteFileImpl(g_uriFullPath);
1230e98b08fSopenharmony_ci    }
1240e98b08fSopenharmony_ci    if (ret != NATIVE_SUCCESS) {
1250e98b08fSopenharmony_ci        NativeapiCommon::FailCallBack(thisVal, args, ret);
1260e98b08fSopenharmony_ci        goto EXIT;
1270e98b08fSopenharmony_ci    }
1280e98b08fSopenharmony_ci    result = JSI::CreateString(dest);
1290e98b08fSopenharmony_ci    NativeapiCommon::SuccessCallBack(thisVal, args, result);
1300e98b08fSopenharmony_ciEXIT:
1310e98b08fSopenharmony_ci    JSI::ReleaseString(dest);
1320e98b08fSopenharmony_ci    free(destFullPath);
1330e98b08fSopenharmony_ci    JSI::ReleaseValueList(args, thisVal, result, ARGS_END);
1340e98b08fSopenharmony_ci    delete params;
1350e98b08fSopenharmony_ci}
1360e98b08fSopenharmony_ci
1370e98b08fSopenharmony_civoid ExecuteDeleteAccess(void* data)
1380e98b08fSopenharmony_ci{
1390e98b08fSopenharmony_ci    FuncParams* params = reinterpret_cast<FuncParams *>(data);
1400e98b08fSopenharmony_ci    if (params == nullptr) {
1410e98b08fSopenharmony_ci        return;
1420e98b08fSopenharmony_ci    }
1430e98b08fSopenharmony_ci    JSIValue args = params->args;
1440e98b08fSopenharmony_ci    JSIValue thisVal = params->thisVal;
1450e98b08fSopenharmony_ci    char* src = JSI::GetStringProperty(args, FILE_URI);
1460e98b08fSopenharmony_ci    int ret = GetFullPath(src, g_uriFullPath, sizeof(g_uriFullPath));
1470e98b08fSopenharmony_ci    JSI::ReleaseString(src);
1480e98b08fSopenharmony_ci    if (ret != NATIVE_SUCCESS) {
1490e98b08fSopenharmony_ci        NativeapiCommon::FailCallBack(thisVal, args, ret);
1500e98b08fSopenharmony_ci        goto EXIT;
1510e98b08fSopenharmony_ci    }
1520e98b08fSopenharmony_ci    if (params->flag) {
1530e98b08fSopenharmony_ci        ret = DeleteFileImpl(g_uriFullPath);
1540e98b08fSopenharmony_ci    } else {
1550e98b08fSopenharmony_ci        ret = AccessImpl(g_uriFullPath);
1560e98b08fSopenharmony_ci    }
1570e98b08fSopenharmony_ci    if (ret != NATIVE_SUCCESS) {
1580e98b08fSopenharmony_ci        NativeapiCommon::FailCallBack(thisVal, args, ret);
1590e98b08fSopenharmony_ci        goto EXIT;
1600e98b08fSopenharmony_ci    }
1610e98b08fSopenharmony_ci    NativeapiCommon::SuccessCallBack(thisVal, args, JSI::CreateUndefined());
1620e98b08fSopenharmony_ciEXIT:
1630e98b08fSopenharmony_ci    JSI::ReleaseValueList(args, thisVal, ARGS_END);
1640e98b08fSopenharmony_ci    delete params;
1650e98b08fSopenharmony_ci}
1660e98b08fSopenharmony_ci
1670e98b08fSopenharmony_ciint GetFileListInner(const char* path, const char* key, JSIValue& result)
1680e98b08fSopenharmony_ci{
1690e98b08fSopenharmony_ci    int fileNum = GetFileNum(g_uriFullPath);
1700e98b08fSopenharmony_ci    if (fileNum <= 0) {
1710e98b08fSopenharmony_ci        return fileNum;
1720e98b08fSopenharmony_ci    }
1730e98b08fSopenharmony_ci    FileMetaInfo* fileList = reinterpret_cast<FileMetaInfo *>(malloc(fileNum * sizeof(FileMetaInfo)));
1740e98b08fSopenharmony_ci    if (fileList == nullptr) {
1750e98b08fSopenharmony_ci        return ERROR_CODE_GENERAL;
1760e98b08fSopenharmony_ci    }
1770e98b08fSopenharmony_ci    if (memset_s(fileList, fileNum * sizeof(FileMetaInfo), 0x0, fileNum * sizeof(FileMetaInfo)) != EOK) {
1780e98b08fSopenharmony_ci        free(fileList);
1790e98b08fSopenharmony_ci        return ERROR_CODE_GENERAL;
1800e98b08fSopenharmony_ci    }
1810e98b08fSopenharmony_ci    int ret = GetFileListImpl(g_uriFullPath, fileList, fileNum);
1820e98b08fSopenharmony_ci    if (ret != NATIVE_SUCCESS) {
1830e98b08fSopenharmony_ci        free(fileList);
1840e98b08fSopenharmony_ci        return ret;
1850e98b08fSopenharmony_ci    }
1860e98b08fSopenharmony_ci    JSIValue arrayValue = JSI::CreateArray(fileNum);
1870e98b08fSopenharmony_ci    for (int i = 0; i < fileNum; i++) {
1880e98b08fSopenharmony_ci        JSIValue tmp = JSI::CreateObject();
1890e98b08fSopenharmony_ci        JSI::SetStringProperty(tmp, FILE_URI, fileList[i].fileName);
1900e98b08fSopenharmony_ci        JSI::SetNumberProperty(tmp, FILE_LENGTH, fileList[i].fileSize);
1910e98b08fSopenharmony_ci        JSI::SetNumberProperty(tmp, FILE_LAST_MODIFIED_TIME, fileList[i].fileMtime);
1920e98b08fSopenharmony_ci        JSI::SetStringProperty(tmp, FILE_TYPE, TYPE_FILE);
1930e98b08fSopenharmony_ci        if (S_ISDIR(fileList[i].fileMode)) {
1940e98b08fSopenharmony_ci            JSI::SetStringProperty(tmp, FILE_TYPE, TYPE_DIR);
1950e98b08fSopenharmony_ci        }
1960e98b08fSopenharmony_ci        JSI::SetPropertyByIndex(arrayValue, i, tmp);
1970e98b08fSopenharmony_ci        JSI::ReleaseValue(tmp);
1980e98b08fSopenharmony_ci    }
1990e98b08fSopenharmony_ci    free(fileList);
2000e98b08fSopenharmony_ci    JSI::SetNamedProperty(result, key, arrayValue);
2010e98b08fSopenharmony_ci    JSI::ReleaseValue(arrayValue);
2020e98b08fSopenharmony_ci    return NATIVE_SUCCESS;
2030e98b08fSopenharmony_ci}
2040e98b08fSopenharmony_ci
2050e98b08fSopenharmony_civoid ExecuteGetFileList(void* data)
2060e98b08fSopenharmony_ci{
2070e98b08fSopenharmony_ci    FuncParams* params = reinterpret_cast<FuncParams *>(data);
2080e98b08fSopenharmony_ci    if (params == nullptr) {
2090e98b08fSopenharmony_ci        return;
2100e98b08fSopenharmony_ci    }
2110e98b08fSopenharmony_ci    JSIValue args = params->args;
2120e98b08fSopenharmony_ci    JSIValue thisVal = params->thisVal;
2130e98b08fSopenharmony_ci    char* uri = JSI::GetStringProperty(args, FILE_URI);
2140e98b08fSopenharmony_ci    JSIValue result = JSI::CreateObject();
2150e98b08fSopenharmony_ci    int ret = GetFullPath(uri, g_uriFullPath, sizeof(g_uriFullPath));
2160e98b08fSopenharmony_ci    JSI::ReleaseString(uri);
2170e98b08fSopenharmony_ci    if (ret != NATIVE_SUCCESS) {
2180e98b08fSopenharmony_ci        NativeapiCommon::FailCallBack(thisVal, args, ret);
2190e98b08fSopenharmony_ci        goto EXIT;
2200e98b08fSopenharmony_ci    }
2210e98b08fSopenharmony_ci    if (params->flag) {
2220e98b08fSopenharmony_ci        ret = GetFileListInner(g_uriFullPath, FILE_LIST, result);
2230e98b08fSopenharmony_ci    } else {
2240e98b08fSopenharmony_ci        ret = GetFileListInner(g_uriFullPath, SUB_FILES, result);
2250e98b08fSopenharmony_ci    }
2260e98b08fSopenharmony_ci    if (ret != NATIVE_SUCCESS) {
2270e98b08fSopenharmony_ci        NativeapiCommon::FailCallBack(thisVal, args, ret);
2280e98b08fSopenharmony_ci        goto EXIT;
2290e98b08fSopenharmony_ci    }
2300e98b08fSopenharmony_ci    NativeapiCommon::SuccessCallBack(thisVal, args, result);
2310e98b08fSopenharmony_ciEXIT:
2320e98b08fSopenharmony_ci    JSI::ReleaseValueList(args, thisVal, result, ARGS_END);
2330e98b08fSopenharmony_ci    delete params;
2340e98b08fSopenharmony_ci}
2350e98b08fSopenharmony_ci
2360e98b08fSopenharmony_civoid ExecuteGetFileInfo(void* data)
2370e98b08fSopenharmony_ci{
2380e98b08fSopenharmony_ci    FuncParams* params = reinterpret_cast<FuncParams *>(data);
2390e98b08fSopenharmony_ci    if (params == nullptr) {
2400e98b08fSopenharmony_ci        return;
2410e98b08fSopenharmony_ci    }
2420e98b08fSopenharmony_ci    JSIValue args = params->args;
2430e98b08fSopenharmony_ci    JSIValue thisVal = params->thisVal;
2440e98b08fSopenharmony_ci    char* src = JSI::GetStringProperty(args, FILE_URI);
2450e98b08fSopenharmony_ci    bool recursive = JSI::GetBooleanProperty(args, RECURSIVE);
2460e98b08fSopenharmony_ci    struct stat info = {0};
2470e98b08fSopenharmony_ci    JSIValue result = JSI::CreateObject();
2480e98b08fSopenharmony_ci    int ret = GetFullPath(src, g_uriFullPath, sizeof(g_uriFullPath));
2490e98b08fSopenharmony_ci    if (ret != NATIVE_SUCCESS) {
2500e98b08fSopenharmony_ci        NativeapiCommon::FailCallBack(thisVal, args, ret);
2510e98b08fSopenharmony_ci        goto EXIT;
2520e98b08fSopenharmony_ci    }
2530e98b08fSopenharmony_ci    ret = StatImpl(g_uriFullPath, &info);
2540e98b08fSopenharmony_ci    if (ret != NATIVE_SUCCESS) {
2550e98b08fSopenharmony_ci        NativeapiCommon::FailCallBack(thisVal, args, ret);
2560e98b08fSopenharmony_ci        goto EXIT;
2570e98b08fSopenharmony_ci    }
2580e98b08fSopenharmony_ci    if (recursive && (S_ISDIR(info.st_mode))) {
2590e98b08fSopenharmony_ci        JSI::ReleaseString(src);
2600e98b08fSopenharmony_ci        ExecuteGetFileList(data);
2610e98b08fSopenharmony_ci        return;
2620e98b08fSopenharmony_ci    }
2630e98b08fSopenharmony_ci    JSI::SetStringProperty(result, FILE_URI, src);
2640e98b08fSopenharmony_ci    JSI::SetNumberProperty(result, FILE_LENGTH, info.st_size);
2650e98b08fSopenharmony_ci    JSI::SetNumberProperty(result, FILE_LAST_MODIFIED_TIME, info.st_mtime);
2660e98b08fSopenharmony_ci    JSI::SetStringProperty(result, FILE_TYPE, TYPE_FILE);
2670e98b08fSopenharmony_ci    if (S_ISDIR(info.st_mode)) {
2680e98b08fSopenharmony_ci        JSI::SetStringProperty(result, FILE_TYPE, TYPE_DIR);
2690e98b08fSopenharmony_ci    }
2700e98b08fSopenharmony_ci    NativeapiCommon::SuccessCallBack(thisVal, args, result);
2710e98b08fSopenharmony_ciEXIT:
2720e98b08fSopenharmony_ci    JSI::ReleaseString(src);
2730e98b08fSopenharmony_ci    JSI::ReleaseValueList(args, thisVal, result, ARGS_END);
2740e98b08fSopenharmony_ci    delete params;
2750e98b08fSopenharmony_ci}
2760e98b08fSopenharmony_ci
2770e98b08fSopenharmony_civoid ExecuteWriteTextFile(void* data)
2780e98b08fSopenharmony_ci{
2790e98b08fSopenharmony_ci    FuncParams* params = reinterpret_cast<FuncParams *>(data);
2800e98b08fSopenharmony_ci    if (params == nullptr) {
2810e98b08fSopenharmony_ci        return;
2820e98b08fSopenharmony_ci    }
2830e98b08fSopenharmony_ci    JSIValue args = params->args;
2840e98b08fSopenharmony_ci    JSIValue thisVal = params->thisVal;
2850e98b08fSopenharmony_ci    char* src = JSI::GetStringProperty(args, FILE_URI);
2860e98b08fSopenharmony_ci    char* text = JSI::GetStringProperty(args, TEXT);
2870e98b08fSopenharmony_ci    bool append = JSI::GetBooleanProperty(args, FILE_APPEND);
2880e98b08fSopenharmony_ci    int ret = GetFullPath(src, g_uriFullPath, sizeof(g_uriFullPath));
2890e98b08fSopenharmony_ci    JSI::ReleaseString(src);
2900e98b08fSopenharmony_ci    if ((text == nullptr) || (ret != NATIVE_SUCCESS)) {
2910e98b08fSopenharmony_ci        NativeapiCommon::FailCallBack(thisVal, args, ERROR_CODE_PARAM);
2920e98b08fSopenharmony_ci        goto EXIT;
2930e98b08fSopenharmony_ci    }
2940e98b08fSopenharmony_ci    ret = WriteTextFile(g_uriFullPath, text, strlen(text), append);
2950e98b08fSopenharmony_ci    if (ret != NATIVE_SUCCESS) {
2960e98b08fSopenharmony_ci        NativeapiCommon::FailCallBack(thisVal, args, ret);
2970e98b08fSopenharmony_ci        goto EXIT;
2980e98b08fSopenharmony_ci    }
2990e98b08fSopenharmony_ci    NativeapiCommon::SuccessCallBack(thisVal, args, JSI::CreateUndefined());
3000e98b08fSopenharmony_ciEXIT:
3010e98b08fSopenharmony_ci    JSI::ReleaseString(text);
3020e98b08fSopenharmony_ci    JSI::ReleaseValueList(args, thisVal, ARGS_END);
3030e98b08fSopenharmony_ci    delete params;
3040e98b08fSopenharmony_ci}
3050e98b08fSopenharmony_ci
3060e98b08fSopenharmony_ciint ReadTextInner(const char* src, int position, int length, JSIValue& result)
3070e98b08fSopenharmony_ci{
3080e98b08fSopenharmony_ci    if ((position < 0) || (length < 0)) {
3090e98b08fSopenharmony_ci        return ERROR_CODE_PARAM;
3100e98b08fSopenharmony_ci    }
3110e98b08fSopenharmony_ci    if (length == 0) {
3120e98b08fSopenharmony_ci        length = TEXT_MAX_READ_LEN;
3130e98b08fSopenharmony_ci    }
3140e98b08fSopenharmony_ci    int ret = GetFullPath(src, g_uriFullPath, sizeof(g_uriFullPath));
3150e98b08fSopenharmony_ci    if (ret != NATIVE_SUCCESS) {
3160e98b08fSopenharmony_ci        return ret;
3170e98b08fSopenharmony_ci    }
3180e98b08fSopenharmony_ci    struct stat info = {0};
3190e98b08fSopenharmony_ci    ret = StatImpl(g_uriFullPath, &info);
3200e98b08fSopenharmony_ci    if (ret != NATIVE_SUCCESS) {
3210e98b08fSopenharmony_ci        return ret;
3220e98b08fSopenharmony_ci    }
3230e98b08fSopenharmony_ci    size_t readLen = (info.st_size > length) ? length : info.st_size;
3240e98b08fSopenharmony_ci    if (readLen > TEXT_MAX_READ_LEN) {
3250e98b08fSopenharmony_ci        return ERROR_CODE_READ_TOO_LONG;
3260e98b08fSopenharmony_ci    }
3270e98b08fSopenharmony_ci    char* text = reinterpret_cast<char *>(malloc(readLen + 1));
3280e98b08fSopenharmony_ci    if (text == nullptr) {
3290e98b08fSopenharmony_ci        return ERROR_CODE_GENERAL;
3300e98b08fSopenharmony_ci    }
3310e98b08fSopenharmony_ci    size_t actualLen = 0;
3320e98b08fSopenharmony_ci    ret = ReadFileImpl(g_uriFullPath, text, readLen, position, &actualLen);
3330e98b08fSopenharmony_ci    if (ret != NATIVE_SUCCESS) {
3340e98b08fSopenharmony_ci        free(text);
3350e98b08fSopenharmony_ci        return ret;
3360e98b08fSopenharmony_ci    }
3370e98b08fSopenharmony_ci    text[actualLen] = '\0';
3380e98b08fSopenharmony_ci    JSI::SetStringProperty(result, TEXT, text);
3390e98b08fSopenharmony_ci    free(text);
3400e98b08fSopenharmony_ci    return NATIVE_SUCCESS;
3410e98b08fSopenharmony_ci}
3420e98b08fSopenharmony_ci
3430e98b08fSopenharmony_civoid ExecuteReadTextFile(void* data)
3440e98b08fSopenharmony_ci{
3450e98b08fSopenharmony_ci    FuncParams* params = reinterpret_cast<FuncParams *>(data);
3460e98b08fSopenharmony_ci    if (params == nullptr) {
3470e98b08fSopenharmony_ci        return;
3480e98b08fSopenharmony_ci    }
3490e98b08fSopenharmony_ci    JSIValue args = params->args;
3500e98b08fSopenharmony_ci    JSIValue thisVal = params->thisVal;
3510e98b08fSopenharmony_ci    char* src = JSI::GetStringProperty(args, FILE_URI);
3520e98b08fSopenharmony_ci    double position = JSI::GetNumberProperty(args, FILE_POSITION);
3530e98b08fSopenharmony_ci    double length = JSI::GetNumberProperty(args, FILE_LENGTH);
3540e98b08fSopenharmony_ci    JSIValue result = JSI::CreateObject();
3550e98b08fSopenharmony_ci    int ret = ReadTextInner(src, static_cast<int>(position), static_cast<int>(length), result);
3560e98b08fSopenharmony_ci    JSI::ReleaseString(src);
3570e98b08fSopenharmony_ci    if (ret == NATIVE_SUCCESS) {
3580e98b08fSopenharmony_ci        NativeapiCommon::SuccessCallBack(thisVal, args, result);
3590e98b08fSopenharmony_ci    } else {
3600e98b08fSopenharmony_ci        NativeapiCommon::FailCallBack(thisVal, args, ret);
3610e98b08fSopenharmony_ci    }
3620e98b08fSopenharmony_ci    JSI::ReleaseValueList(args, thisVal, result, ARGS_END);
3630e98b08fSopenharmony_ci    delete params;
3640e98b08fSopenharmony_ci}
3650e98b08fSopenharmony_ci
3660e98b08fSopenharmony_civoid ExecuteDirFunc(void* data)
3670e98b08fSopenharmony_ci{
3680e98b08fSopenharmony_ci    FuncParams* params = reinterpret_cast<FuncParams *>(data);
3690e98b08fSopenharmony_ci    if (params == nullptr) {
3700e98b08fSopenharmony_ci        return;
3710e98b08fSopenharmony_ci    }
3720e98b08fSopenharmony_ci    JSIValue args = params->args;
3730e98b08fSopenharmony_ci    JSIValue thisVal = params->thisVal;
3740e98b08fSopenharmony_ci    char* src = JSI::GetStringProperty(args, FILE_URI);
3750e98b08fSopenharmony_ci    int ret = GetFullPath(src, g_uriFullPath, sizeof(g_uriFullPath));
3760e98b08fSopenharmony_ci    JSI::ReleaseString(src);
3770e98b08fSopenharmony_ci    bool recursive = JSI::GetBooleanProperty(args, RECURSIVE);
3780e98b08fSopenharmony_ci    if (ret != NATIVE_SUCCESS) {
3790e98b08fSopenharmony_ci        NativeapiCommon::FailCallBack(thisVal, args, ret);
3800e98b08fSopenharmony_ci        goto EXIT;
3810e98b08fSopenharmony_ci    }
3820e98b08fSopenharmony_ci    if (params->flag) {
3830e98b08fSopenharmony_ci        ret = CreateDirImpl(g_uriFullPath, recursive);
3840e98b08fSopenharmony_ci    } else {
3850e98b08fSopenharmony_ci        ret = RemoveDirImpl(g_uriFullPath, recursive);
3860e98b08fSopenharmony_ci    }
3870e98b08fSopenharmony_ci    if (ret != NATIVE_SUCCESS) {
3880e98b08fSopenharmony_ci        NativeapiCommon::FailCallBack(thisVal, args, ret);
3890e98b08fSopenharmony_ci        goto EXIT;
3900e98b08fSopenharmony_ci    }
3910e98b08fSopenharmony_ci    NativeapiCommon::SuccessCallBack(thisVal, args, JSI::CreateUndefined());
3920e98b08fSopenharmony_ciEXIT:
3930e98b08fSopenharmony_ci    JSI::ReleaseValueList(args, thisVal, ARGS_END);
3940e98b08fSopenharmony_ci    delete params;
3950e98b08fSopenharmony_ci}
3960e98b08fSopenharmony_ci#if (JS_FWK_TYPEDARRAY == NATIVE_FEATURE_ON)
3970e98b08fSopenharmony_ciint ReadArrayFileInner(const char* path, size_t len, unsigned int position, JSIValue& result)
3980e98b08fSopenharmony_ci{
3990e98b08fSopenharmony_ci    struct stat info = {0};
4000e98b08fSopenharmony_ci    int ret = StatImpl(path, &info);
4010e98b08fSopenharmony_ci    if (ret != NATIVE_SUCCESS) {
4020e98b08fSopenharmony_ci        return ret;
4030e98b08fSopenharmony_ci    }
4040e98b08fSopenharmony_ci    void* text = malloc(info.st_size + 1);
4050e98b08fSopenharmony_ci    if (text == nullptr) {
4060e98b08fSopenharmony_ci        return ERROR_CODE_GENERAL;
4070e98b08fSopenharmony_ci    }
4080e98b08fSopenharmony_ci    size_t actualLen = 0;
4090e98b08fSopenharmony_ci    ret = ReadFileImpl(path, text, len, static_cast<int>(position), &actualLen);
4100e98b08fSopenharmony_ci    if (ret != NATIVE_SUCCESS) {
4110e98b08fSopenharmony_ci        free(text);
4120e98b08fSopenharmony_ci        return ret;
4130e98b08fSopenharmony_ci    }
4140e98b08fSopenharmony_ci    uint8_t* ptr = nullptr;
4150e98b08fSopenharmony_ci    JSIValue arrayBuffer = JSI::CreateArrayBuffer(actualLen, ptr);
4160e98b08fSopenharmony_ci    if (ptr == nullptr) {
4170e98b08fSopenharmony_ci        free(text);
4180e98b08fSopenharmony_ci        JSI::ReleaseValue(arrayBuffer);
4190e98b08fSopenharmony_ci        return ERROR_CODE_GENERAL;
4200e98b08fSopenharmony_ci    }
4210e98b08fSopenharmony_ci    ret = memcpy_s(ptr, actualLen, text, actualLen);
4220e98b08fSopenharmony_ci    free(text);
4230e98b08fSopenharmony_ci    if (ret != EOK) {
4240e98b08fSopenharmony_ci        JSI::ReleaseValue(arrayBuffer);
4250e98b08fSopenharmony_ci        return ERROR_CODE_GENERAL;
4260e98b08fSopenharmony_ci    }
4270e98b08fSopenharmony_ci    JSIValue typedArray = JSI::CreateTypedArray(TypedArrayType::JSI_UINT8_ARRAY, actualLen, arrayBuffer, 0);
4280e98b08fSopenharmony_ci    JSI::SetNamedProperty(result, FILE_BUFFER, typedArray);
4290e98b08fSopenharmony_ci    JSI::ReleaseValueList(typedArray, arrayBuffer, ARGS_END);
4300e98b08fSopenharmony_ci    return NATIVE_SUCCESS;
4310e98b08fSopenharmony_ci}
4320e98b08fSopenharmony_ci
4330e98b08fSopenharmony_civoid ExecuteReadArrayFile(void* data)
4340e98b08fSopenharmony_ci{
4350e98b08fSopenharmony_ci    FuncParams* params = reinterpret_cast<FuncParams *>(data);
4360e98b08fSopenharmony_ci    if (params == nullptr) {
4370e98b08fSopenharmony_ci        return;
4380e98b08fSopenharmony_ci    }
4390e98b08fSopenharmony_ci    JSIValue args = params->args;
4400e98b08fSopenharmony_ci    JSIValue thisVal = params->thisVal;
4410e98b08fSopenharmony_ci    char* src = JSI::GetStringProperty(args, FILE_URI);
4420e98b08fSopenharmony_ci    double position = JSI::GetNumberProperty(args, FILE_POSITION);
4430e98b08fSopenharmony_ci    double length = JSI::GetNumberProperty(args, FILE_LENGTH);
4440e98b08fSopenharmony_ci    JSIValue result = JSI::CreateObject();
4450e98b08fSopenharmony_ci    int ret = ERROR_CODE_PARAM;
4460e98b08fSopenharmony_ci    if ((position < 0) || (length < 0)) {
4470e98b08fSopenharmony_ci        JSI::ReleaseString(src);
4480e98b08fSopenharmony_ci        NativeapiCommon::FailCallBack(thisVal, args, ret);
4490e98b08fSopenharmony_ci        goto EXIT;
4500e98b08fSopenharmony_ci    }
4510e98b08fSopenharmony_ci    ret = GetFullPath(src, g_uriFullPath, sizeof(g_uriFullPath));
4520e98b08fSopenharmony_ci    JSI::ReleaseString(src);
4530e98b08fSopenharmony_ci    if (ret != NATIVE_SUCCESS) {
4540e98b08fSopenharmony_ci        NativeapiCommon::FailCallBack(thisVal, args, ret);
4550e98b08fSopenharmony_ci        goto EXIT;
4560e98b08fSopenharmony_ci    }
4570e98b08fSopenharmony_ci    ret = ReadArrayFileInner(g_uriFullPath, static_cast<int>(length), static_cast<int>(position), result);
4580e98b08fSopenharmony_ci    if (ret != NATIVE_SUCCESS) {
4590e98b08fSopenharmony_ci        NativeapiCommon::FailCallBack(thisVal, args, ret);
4600e98b08fSopenharmony_ci        goto EXIT;
4610e98b08fSopenharmony_ci    }
4620e98b08fSopenharmony_ci    NativeapiCommon::SuccessCallBack(thisVal, args, result);
4630e98b08fSopenharmony_ciEXIT:
4640e98b08fSopenharmony_ci    JSI::ReleaseValueList(args, thisVal, result, ARGS_END);
4650e98b08fSopenharmony_ci    delete params;
4660e98b08fSopenharmony_ci}
4670e98b08fSopenharmony_ci
4680e98b08fSopenharmony_civoid ExecuteWriteArrayFile(void* data)
4690e98b08fSopenharmony_ci{
4700e98b08fSopenharmony_ci    FuncParams* params = reinterpret_cast<FuncParams *>(data);
4710e98b08fSopenharmony_ci    if (params == nullptr) {
4720e98b08fSopenharmony_ci        return;
4730e98b08fSopenharmony_ci    }
4740e98b08fSopenharmony_ci    JSIValue args = params->args;
4750e98b08fSopenharmony_ci    JSIValue thisVal = params->thisVal;
4760e98b08fSopenharmony_ci    char* src = JSI::GetStringProperty(args, FILE_URI);
4770e98b08fSopenharmony_ci    int ret = GetFullPath(src, g_uriFullPath, sizeof(g_uriFullPath));
4780e98b08fSopenharmony_ci    JSI::ReleaseString(src);
4790e98b08fSopenharmony_ci    if (ret != NATIVE_SUCCESS) {
4800e98b08fSopenharmony_ci        NativeapiCommon::FailCallBack(thisVal, args, ret);
4810e98b08fSopenharmony_ci        JSI::ReleaseValueList(args, thisVal, ARGS_END);
4820e98b08fSopenharmony_ci        delete params;
4830e98b08fSopenharmony_ci        return;
4840e98b08fSopenharmony_ci    }
4850e98b08fSopenharmony_ci    JSIValue buffer = JSI::GetNamedProperty(args, FILE_BUFFER);
4860e98b08fSopenharmony_ci    double position = JSI::GetNumberProperty(args, FILE_POSITION);
4870e98b08fSopenharmony_ci    bool append = JSI::GetBooleanProperty(args, FILE_APPEND);
4880e98b08fSopenharmony_ci    TypedArrayType type = TypedArrayType::JSI_INVALID_ARRAY;
4890e98b08fSopenharmony_ci    size_t length = 0;
4900e98b08fSopenharmony_ci    JSIValue arrayBuffer = JSI::CreateUndefined();
4910e98b08fSopenharmony_ci    size_t byteOffset = 0;
4920e98b08fSopenharmony_ci    uint8_t* arrayPtr = JSI::GetTypedArrayInfo(buffer, type, length, arrayBuffer, byteOffset);
4930e98b08fSopenharmony_ci    ret = ERROR_CODE_PARAM;
4940e98b08fSopenharmony_ci    if ((position < 0) || (arrayPtr == nullptr) || (type != TypedArrayType::JSI_UINT8_ARRAY)) {
4950e98b08fSopenharmony_ci        JSI::ReleaseValueList(buffer, arrayBuffer, ARGS_END);
4960e98b08fSopenharmony_ci        NativeapiCommon::FailCallBack(thisVal, args, ERROR_CODE_PARAM);
4970e98b08fSopenharmony_ci        goto EXIT;
4980e98b08fSopenharmony_ci    }
4990e98b08fSopenharmony_ci    ret = WriteArrayFile(g_uriFullPath, arrayPtr, length, static_cast<int>(position), append);
5000e98b08fSopenharmony_ci    JSI::ReleaseValueList(buffer, arrayBuffer, ARGS_END);
5010e98b08fSopenharmony_ci    if (ret != NATIVE_SUCCESS) {
5020e98b08fSopenharmony_ci        NativeapiCommon::FailCallBack(thisVal, args, ret);
5030e98b08fSopenharmony_ci        goto EXIT;
5040e98b08fSopenharmony_ci    }
5050e98b08fSopenharmony_ci    NativeapiCommon::SuccessCallBack(thisVal, args, JSI::CreateUndefined());
5060e98b08fSopenharmony_ciEXIT:
5070e98b08fSopenharmony_ci    JSI::ReleaseValueList(args, thisVal, ARGS_END);
5080e98b08fSopenharmony_ci    delete params;
5090e98b08fSopenharmony_ci}
5100e98b08fSopenharmony_ci#endif
5110e98b08fSopenharmony_ci}
5120e98b08fSopenharmony_ci
5130e98b08fSopenharmony_civoid InitNativeApiFs(JSIValue exports)
5140e98b08fSopenharmony_ci{
5150e98b08fSopenharmony_ci    JSI::SetModuleAPI(exports, "move", NativeapiFs::MoveFile);
5160e98b08fSopenharmony_ci    JSI::SetModuleAPI(exports, "copy", NativeapiFs::CopyFile);
5170e98b08fSopenharmony_ci    JSI::SetModuleAPI(exports, "delete", NativeapiFs::DeleteFile);
5180e98b08fSopenharmony_ci    JSI::SetModuleAPI(exports, "list", NativeapiFs::GetFileList);
5190e98b08fSopenharmony_ci    JSI::SetModuleAPI(exports, "get", NativeapiFs::GetFileInfo);
5200e98b08fSopenharmony_ci    JSI::SetModuleAPI(exports, "readText", NativeapiFs::ReadTextFile);
5210e98b08fSopenharmony_ci    JSI::SetModuleAPI(exports, "writeText", NativeapiFs::WriteTextFile);
5220e98b08fSopenharmony_ci    JSI::SetModuleAPI(exports, "access", NativeapiFs::Access);
5230e98b08fSopenharmony_ci    JSI::SetModuleAPI(exports, "mkdir", NativeapiFs::CreateDir);
5240e98b08fSopenharmony_ci    JSI::SetModuleAPI(exports, "rmdir", NativeapiFs::RemoveDir);
5250e98b08fSopenharmony_ci
5260e98b08fSopenharmony_ci#if (JS_FWK_TYPEDARRAY == NATIVE_FEATURE_ON)
5270e98b08fSopenharmony_ci    JSI::SetModuleAPI(exports, "readArrayBuffer", NativeapiFs::ReadArrayFile);
5280e98b08fSopenharmony_ci    JSI::SetModuleAPI(exports, "writeArrayBuffer", NativeapiFs::WriteArrayFile);
5290e98b08fSopenharmony_ci#endif
5300e98b08fSopenharmony_ci}
5310e98b08fSopenharmony_ci
5320e98b08fSopenharmony_ciJSIValue NativeapiFs::MoveFile(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum)
5330e98b08fSopenharmony_ci{
5340e98b08fSopenharmony_ci    return ExecuteAsyncWork(thisVal, args, argsNum, ExecuteCopyFile, true);
5350e98b08fSopenharmony_ci}
5360e98b08fSopenharmony_ci
5370e98b08fSopenharmony_ciJSIValue NativeapiFs::CopyFile(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum)
5380e98b08fSopenharmony_ci{
5390e98b08fSopenharmony_ci    return ExecuteAsyncWork(thisVal, args, argsNum, ExecuteCopyFile);
5400e98b08fSopenharmony_ci}
5410e98b08fSopenharmony_ci
5420e98b08fSopenharmony_ciJSIValue NativeapiFs::DeleteFile(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum)
5430e98b08fSopenharmony_ci{
5440e98b08fSopenharmony_ci    return ExecuteAsyncWork(thisVal, args, argsNum, ExecuteDeleteAccess, true);
5450e98b08fSopenharmony_ci}
5460e98b08fSopenharmony_ci
5470e98b08fSopenharmony_ciJSIValue NativeapiFs::GetFileList(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum)
5480e98b08fSopenharmony_ci{
5490e98b08fSopenharmony_ci    return ExecuteAsyncWork(thisVal, args, argsNum, ExecuteGetFileList, true);
5500e98b08fSopenharmony_ci}
5510e98b08fSopenharmony_ci
5520e98b08fSopenharmony_ciJSIValue NativeapiFs::GetFileInfo(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum)
5530e98b08fSopenharmony_ci{
5540e98b08fSopenharmony_ci    return ExecuteAsyncWork(thisVal, args, argsNum, ExecuteGetFileInfo);
5550e98b08fSopenharmony_ci}
5560e98b08fSopenharmony_ci
5570e98b08fSopenharmony_ciJSIValue NativeapiFs::WriteTextFile(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum)
5580e98b08fSopenharmony_ci{
5590e98b08fSopenharmony_ci    return ExecuteAsyncWork(thisVal, args, argsNum, ExecuteWriteTextFile);
5600e98b08fSopenharmony_ci}
5610e98b08fSopenharmony_ci
5620e98b08fSopenharmony_ciJSIValue NativeapiFs::ReadTextFile(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum)
5630e98b08fSopenharmony_ci{
5640e98b08fSopenharmony_ci    return ExecuteAsyncWork(thisVal, args, argsNum, ExecuteReadTextFile);
5650e98b08fSopenharmony_ci}
5660e98b08fSopenharmony_ci
5670e98b08fSopenharmony_ciJSIValue NativeapiFs::Access(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum)
5680e98b08fSopenharmony_ci{
5690e98b08fSopenharmony_ci    return ExecuteAsyncWork(thisVal, args, argsNum, ExecuteDeleteAccess);
5700e98b08fSopenharmony_ci}
5710e98b08fSopenharmony_ci
5720e98b08fSopenharmony_ciJSIValue NativeapiFs::CreateDir(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum)
5730e98b08fSopenharmony_ci{
5740e98b08fSopenharmony_ci    return ExecuteAsyncWork(thisVal, args, argsNum, ExecuteDirFunc, true);
5750e98b08fSopenharmony_ci}
5760e98b08fSopenharmony_ci
5770e98b08fSopenharmony_ciJSIValue NativeapiFs::RemoveDir(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum)
5780e98b08fSopenharmony_ci{
5790e98b08fSopenharmony_ci    return ExecuteAsyncWork(thisVal, args, argsNum, ExecuteDirFunc);
5800e98b08fSopenharmony_ci}
5810e98b08fSopenharmony_ci
5820e98b08fSopenharmony_ci#if (JS_FWK_TYPEDARRAY == NATIVE_FEATURE_ON)
5830e98b08fSopenharmony_ciJSIValue NativeapiFs::ReadArrayFile(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum)
5840e98b08fSopenharmony_ci{
5850e98b08fSopenharmony_ci    return ExecuteAsyncWork(thisVal, args, argsNum, ExecuteReadArrayFile);
5860e98b08fSopenharmony_ci}
5870e98b08fSopenharmony_ci
5880e98b08fSopenharmony_ciJSIValue NativeapiFs::WriteArrayFile(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum)
5890e98b08fSopenharmony_ci{
5900e98b08fSopenharmony_ci    return ExecuteAsyncWork(thisVal, args, argsNum, ExecuteWriteArrayFile);
5910e98b08fSopenharmony_ci}
5920e98b08fSopenharmony_ci#endif
5930e98b08fSopenharmony_ci} // ACELite
5940e98b08fSopenharmony_ci} // OHOS
595